braincell.quad.backward_euler_step#
- braincell.quad.backward_euler_step(target, *args, excluded_paths=())[source]#
Advance one step with the linearised backward (implicit) Euler method.
Backward Euler discretises an ODE \(dy/dt = f(t, y)\) as
\[y_{n+1} = y_n + \Delta t \, f(t_{n+1}, y_{n+1}),\]which is implicit in \(y_{n+1}\). Rather than running a Newton solver to convergence (see
implicit_euler_step()for that variant), this routine takes a single Newton step from a local Jacobian:\[J = \frac{\partial f}{\partial y}\bigg|_{y_n}, \qquad (I - \Delta t \, J)\, \Delta y = \Delta t \, f(t_n, y_n), \qquad y_{n+1} = y_n + \Delta y.\]The result is the so-called Rosenbrock / linearly implicit Euler update — first-order accurate, \(L\)-stable, and considerably cheaper than full Newton because the Jacobian is built once per step and the linear system is solved by a batched
jax.scipy.linalg.solve(). It is the recommended choice formedium-stiff Hodgkin-Huxley models when matrix-exponential schemes such as
exp_euler_step()are too expensive.- Parameters:
target (
DiffEqModule) – The module whose differential states are to be advanced. Must be anHHTypedNeuron(single compartment or multi-compartment).*args – Extra positional arguments forwarded to
target’spre_integral(),compute_derivative(), andpost_integral()hooks.
- Returns:
target’s differential states are updated in place.- Return type:
None
- Raises:
AssertionError – Raised inside
apply_standard_solver_step()if target is not aDiffEqModule.
See also
implicit_euler_stepFull Newton iteration on the same residual.
exp_euler_stepMatrix-exponential exponential Euler step.
Notes
The current time and step size are read from the active
brainstate.environcontext. State leaves are stacked along thelast axis (
merging='stack') before the linear solve.Examples
>>> import brainstate >>> import brainunit as u >>> from braincell.quad import backward_euler_step >>> with brainstate.environ.context(t=0. * u.ms, dt=0.025 * u.ms): ... backward_euler_step(my_neuron, input_current)