ode_expeuler_step#
- class braintools.quad.ode_expeuler_step(f, y, t, *args, **kwargs)#
One-step Exponential Euler method for ODEs with linearized drift.
The drift
fis linearized around the current state via its diagonal JacobianA = \partial f / \partial yand the linear part is integrated exactly over one step:\[y_{n+1} = y_n + \Delta t\, \varphi(\Delta t\, A)\, f(y_n, t_n), \qquad \varphi(z) = \frac{e^{z} - 1}{z}.\]For a scalar linear ODE
dy/dt = A ythe method is exact. If the stateyhas unit[X], the driftf(y, t)must have unit[X]/[T].- Parameters:
f (
Callable[[PyTree,float|Quantity,...],PyTree]) – Drift functionf(y, t, *args)used in the exponential update.y (
Array|ndarray|bool|number|bool|int|float|complex|Quantity) – Current state. Must have a floating dtype (float16/32/64 or bfloat16).t (
Array|ndarray|bool|number|bool|int|float|complex|Quantity) – Current time.*args – Additional positional arguments forwarded to
f.
- Returns:
The updated state
y_{n+1}.- Return type:
ArrayLike
- Raises:
ValueError – If
ydoes not have a floating dtype.
See also
ode_euler_stepExplicit (forward) Euler step.
sde_expeuler_stepExponential Euler step for SDEs.
Examples
>>> import brainstate >>> import brainunit as u >>> from braintools.quad import ode_expeuler_step >>> def fun(x, t): ... return -x >>> with brainstate.environ.context(dt=0.1): ... x_next = ode_expeuler_step(fun, 1.0, 0.0) >>> float(x_next) # exp(-0.1) 0.904837429523468 >>> with brainstate.environ.context(dt=0.1 * u.ms): ... v_next = ode_expeuler_step(lambda v, t: -v / (10.0 * u.ms), ... -65.0 * u.mV, 0.0 * u.ms)