archimedes.odeint¶
- archimedes.odeint(func: Callable, t_span: tuple[float, float], x0: ArrayLike, method: str = 'cvodes', t_eval: NDArray | None = None, atol: float = 1e-06, rtol: float = 0.001, args: Sequence[Any] | None = None, static_argnames: str | Sequence[str] = (), **options) ArrayLike ¶
Integrate a system of ordinary differential equations.
Solves the initial value problem defined by the ODE system:
\[\dot{x} = f(t, x, \theta)\]from
t=t_span[0]
tot=t_span[1]
with initial conditionsx0
.- Parameters:
func (callable) – Right-hand side of the ODE system. The calling signature is
func(t, x, *args)
, wheret
is a scalar andx
is an ndarray with shape(n,)
. func must return an array with shape(n,)
.t_span (tuple of float) – Interval of integration
(t0, tf)
.x0 (array_like) – Initial state.
method (str, optional) – Integration method to use. Default is
"cvodes"
, which uses the SUNDIALS CVODES solver (suitable for both stiff and non-stiff systems).t_eval (array_like or None, optional) – Times at which to store the computed solution. If
None
, the solver only returns the final state.atol (float, optional) – Absolute tolerance for the solver. Default is
1e-6
.rtol (float, optional) – Relative tolerance for the solver. Default is
1e-3
.args (tuple, optional) – Additional arguments to pass to the ODE function.
static_argnames (tuple of str, optional) – Names of arguments to func that should be treated as static (not traced symbolically).
**options (dict) – Additional options to pass to the CasADi integrator.
- Returns:
If
t_eval
is None, the state at the final timet_span[1]
. Ift_eval
is provided, an array containing the solution evaluated att_eval
with shape(n, len(t_eval))
.- Return type:
array_like
Notes
The underlying SUNDIALS solvers use adaptive step size control to balance accuracy and computational efficiency. However, unlike SciPy’s
solve_ivp
function and many other ODE solver interfaces, it is not possible to output the solution at the times actually used by the solver (or to create a “dense” output using an interpolant). This is because of the requirement that all input and output arrays be a fixed size in order to construct the symbolic graph. The solution at output times specified byt_eval
is computed by interpolating the solution at the times used by the solver.The ODE solver is specified by the
method
argument. The default is"cvodes"
, which uses the SUNDIALS CVODES solver and is suitable for both stiff and non-stiff systems. This is the recommended choice for most applications.See the CasADi documentation for a complete list of available configuration options to pass to the
options
argument.Conceptual model: This function is a wrapper around the :py:func:
integrator
function that creates and immediately calls an ODE solver for the given initial conditions and parameters. It provides a simple interface similar to SciPy’ssolve_ivp
but leverages CasADi’s efficient symbolic implementation and interface to SUNDIALS solvers.Unlike
integrator()
, which creates a reusable solver function,odeint
performs a single solve operation. If you need to solve the same ODE system repeatedly with different initial conditions or parameters, it’s more efficient to create anintegrator
function once and reuse it.Limitations:
Only scalar and vector states are supported (shapes like
(n,)
or(n,1)
)For tree-structured states, currently the user must define a wrapper function to flatten and reconstruct the tree structure
Examples
>>> import numpy as np >>> import archimedes as arc >>> import matplotlib.pyplot as plt >>> >>> # Example 1: Simple harmonic oscillator >>> def f(t, y): >>> return np.array([y[1], -y[0]], like=y) # y'' = -y >>> >>> t_span = (0, 10) >>> y0 = np.array([1.0, 0.0]) # Initial displacement and velocity >>> ts = np.linspace(*t_span, 100) >>> >>> # Solve ODE >>> ys = arc.odeint(f, t_span, y0, t_eval=ts) >>> >>> plt.figure() >>> plt.plot(ts, ys[0, :], label='position') >>> plt.plot(ts, ys[1, :], label='velocity') >>> plt.legend() >>> plt.show() >>> >>> # Example 2: Parametrized dynamics >>> def pendulum(t, y, g, L): >>> theta, omega = y >>> return np.array([omega, -(g/L) * np.sin(theta)]) >>> >>> y0 = np.array([np.pi/6, 0.0]) # 30 degrees initial angle >>> t_span = (0, 5) >>> ys = arc.odeint(pendulum, t_span, y0, args=(9.81, 1.0))
See also
integrator
Create a reusable ODE solver function
scipy.integrate.solve_ivp
SciPy’s ODE solver interface