braincell.quad.ind_exp_euler_step#
- braincell.quad.ind_exp_euler_step(target, *args, excluded_paths=())[source]#
Advance each
DiffEqStateindependently with exponential Euler.This is the decoupled sibling of
exp_euler_step(). Instead of building one global Jacobian over the full state vector, the routine iterates over everyDiffEqState\(y^{(k)}\) in target and treats the others as frozen at their current values, fitting the local linearization\[\frac{d y^{(k)}}{dt} \approx \lambda^{(k)} y^{(k)} + b^{(k)}\]via
brainstate.transform.vector_grad()and applying the component-wise exponential Euler update\[y^{(k)}_{n+1} = y^{(k)}_n + \Delta t \, \varphi_1\!\left(\Delta t \, \lambda^{(k)}\right) f^{(k)}(t_n, y_n),\]using
brainunit.math.exprel()to evaluate \(\varphi_1(z) = (e^{z} - 1)/z\) accurately near \(z = 0\).The trade-off compared with
exp_euler_step():exp_euler_step()is more accurate when states are tightly coupled, because it builds the full \(M \times M\) Jacobian and uses a true matrix exponential.ind_exp_euler_step()is much cheaper for large state vectors and is the right choice when each variable is mostly self-coupled (the typical pattern for HH-style gating variables and ion concentrations) and especially when the voltage equation is being solved by a separate solver (seestaggered_step()).
- Parameters:
target (
DiffEqModule) – The module whoseDiffEqStateleaves will be advanced.*args – Extra positional arguments forwarded to
target’spre_integral(),compute_derivative(), andpost_integral()hooks.excluded_paths (tuple of tuple, optional) – Iterable of state paths to skip. Each entry is a tuple of attribute names identifying a
DiffEqStateinside target’s state graph. The classic use isexcluded_paths=[('V',)]fromstaggered_step(), which leaves the membrane voltage untouched so the upstream cable solve is preserved.
- Returns:
Differential states are updated in place; auxiliary (non-DiffEq) states are written from the trace captured during the first Jacobian evaluation.
- Return type:
None
- Raises:
AssertionError – If target is not a
DiffEqModule, or if it has noDiffEqStateleaves.ValueError – If a state value uses an unsupported (non-floating) dtype, or if an unknown state appears in the trace.
See also
exp_euler_stepCoupled (full-Jacobian) exponential Euler.
staggered_stepOperator-splitting scheme that combines DHS for the voltage equation with this routine for everything else.
Notes
The current time and step size are read from the active
brainstate.environcontext.Examples
>>> import brainstate >>> import brainunit as u >>> from braincell.quad import ind_exp_euler_step >>> with brainstate.environ.context(t=0. * u.ms, dt=0.025 * u.ms): ... ind_exp_euler_step( ... my_cell, input_current, ... excluded_paths=[('V',)], ... )