iaf_chxk_2008#
- class brainpy.state.iaf_chxk_2008(in_size, V_th=Quantity(-45., "mV"), g_L=Quantity(100., "nS"), C_m=Quantity(1000., "pF"), E_ex=Quantity(20., "mV"), E_in=Quantity(-90., "mV"), E_L=Quantity(-60., "mV"), tau_syn_ex=Quantity(1., "ms"), tau_syn_in=Quantity(1., "ms"), I_e=Quantity(0., "pA"), tau_ahp=Quantity(0.5, "ms"), E_ahp=Quantity(-95., "mV"), g_ahp=Quantity(443.8, "nS"), ahp_bug=False, gsl_error_tol=0.001, V_initializer=Constant(value=-60. mV), g_ex_initializer=Constant(value=0. nS), g_in_initializer=Constant(value=0. nS), g_ahp_initializer=Constant(value=0. nS), spk_fun=ReluGrad(alpha=0.3, width=1.0), spk_reset='hard', name=None)#
NEST-compatible
iaf_chxk_2008with alpha synapses and precise AHP timing.Description
iaf_chxk_2008is a conductance-based leaky integrate-and-fire neuron with alpha-function excitatory/inhibitory synaptic conductances and a spike-triggered after-hyperpolarization (AHP) conductance, developed for modeling retina-LGN transmission (Casti et al., 2008). The implementation follows NESTmodels/iaf_chxk_2008.{h,cpp}semantics: adaptive RKF45 integration, threshold crossing from below, precise in-step spike timing via linear interpolation, spike-triggered AHP kicks with exact sub-step decay, and optionalahp_bugmode that reproduces the historical single-AHP behavior from the original Fortran code.1. Membrane and conductance dynamics
Let \(V_m\) be membrane potential (mV), \(g_\mathrm{ex}\), \(g_\mathrm{in}\), \(g_\mathrm{ahp,state}\) be conductance states (nS), and \(I_\mathrm{stim}\) be the one-step buffered external current (pA). Subthreshold dynamics are
\[\frac{dV_m}{dt} = \frac{-I_\mathrm{leak} - I_{\mathrm{syn,ex}} - I_{\mathrm{syn,in}} - I_\mathrm{ahp} + I_e + I_\mathrm{stim}}{C_m},\]where
\[I_\mathrm{leak} = g_L (V_m - E_L), \quad I_{\mathrm{syn,ex}} = g_\mathrm{ex}(V_m - E_\mathrm{ex}),\]\[I_{\mathrm{syn,in}} = g_\mathrm{in}(V_m - E_\mathrm{in}), \quad I_\mathrm{ahp} = g_\mathrm{ahp,state}(V_m - E_\mathrm{ahp}).\]Each conductance channel (excitatory, inhibitory, AHP) evolves as an alpha-function state pair \((dg, g_\mathrm{state})\):
\[\frac{d\,dg}{dt} = -\frac{dg}{\tau}, \qquad \frac{dg_\mathrm{state}}{dt} = dg - \frac{g_\mathrm{state}}{\tau}.\]Incoming spike weights (nS) are interpreted with sign convention: positive weights drive excitatory channel, negative weights (absolute value) drive inhibitory channel. Jumps are applied to \(dg\) with NEST normalization:
\[dg_\mathrm{ex} \leftarrow dg_\mathrm{ex} + \frac{e}{\tau_\mathrm{ex}} w_+, \qquad dg_\mathrm{in} \leftarrow dg_\mathrm{in} + \frac{e}{\tau_\mathrm{in}} |w_-|.\]2. Precise output spike timing and AHP kick
A spike is emitted only on threshold crossing from below:
\[V_m(t_k^-) < V_{th} \;\wedge\; V_m(t_k^+) \ge V_{th}.\]When a crossing is detected, the precise in-step spike time is computed by linear interpolation. Let \(dt_\mathrm{spike}\) be the duration from spike time to step end:
\[dt_\mathrm{spike} = h \frac{V_m(t_k^+) - V_{th}}{V_m(t_k^+) - V_m(t_k^-)},\]where \(h\) is the step size. The AHP alpha is initialized at spike time and decayed forward to step end:
\[\Delta dg_\mathrm{ahp} = \frac{g_\mathrm{ahp} e}{\tau_\mathrm{ahp}} \exp\!\left(-\frac{dt_\mathrm{spike}}{\tau_\mathrm{ahp}}\right),\]\[\Delta g_\mathrm{ahp,state} = \Delta dg_\mathrm{ahp}\, dt_\mathrm{spike}.\]If
ahp_bug=True, these values replace the current AHP state (single AHP mode); otherwise they are added (multiple AHP accumulation).3. Numerical integration via RKF45
The seven coupled ODEs (\(V_m\), three \(dg\) states, three \(g_\mathrm{state}\) variables) are integrated using Runge-Kutta-Fehlberg 4(5) with adaptive step size control. Local truncation error is estimated by comparing 4th and 5th order solutions and step size is adjusted to keep error below
gsl_error_tol. Minimum step size is_MIN_H = 1e-8ms and iteration limit is_MAX_ITERS = 10000per global step.4. Update order matching NEST semantics
Each simulation step follows NEST ordering:
Integrate all ODE states over \([t, t+dt]\) via RKF45.
Check threshold crossing from below; if crossed, compute precise spike time and apply AHP kick at that time (with
ahp_bugmode if enabled).Apply arriving signed spike weights to \(dg_\mathrm{ex}\) and \(dg_\mathrm{in}\) after integration completes.
Store incoming continuous current
xinto bufferedI_stimfor next step (NEST current-event timing convention).
5. Assumptions, constraints, and failure modes
Parameters are scalar or broadcastable to
self.varshape.Construction-time constraints enforce
C_m > 0,tau_syn_ex > 0,tau_syn_in > 0,tau_ahp > 0.No explicit reset or refractory period: neuron can spike repeatedly if voltage remains above threshold.
Adaptive integration can fail if
_MAX_ITERSis exceeded; in practice this is rare with reasonable parameter values.Continuous input
xpassed toupdate()is delayed by one step viaI_stim(ring-buffer semantics), while spike events are applied after ODE integration.Per-step complexity is \(O(|\mathrm{state}| \cdot K_\mathrm{iter})\) where \(K_\mathrm{iter}\) is the number of RKF45 substeps (typically 1-5 per global step).
- Parameters:
in_size (
Size) – Population shape specification. Model parameters and states are broadcast toself.varshapederived fromin_size.V_th (
ArrayLike, optional) – Spike threshold voltage \(V_{th}\) in mV, broadcastable toself.varshape. Default is-45. * u.mV.g_L (
ArrayLike, optional) – Leak conductance \(g_L\) in nS, broadcastable toself.varshape. Default is100. * u.nS.C_m (
ArrayLike, optional) – Membrane capacitance \(C_m\) in pF, broadcastable toself.varshape. Must be strictly positive elementwise. Default is1000. * u.pF.E_ex (
ArrayLike, optional) – Excitatory reversal potential \(E_\mathrm{ex}\) in mV, broadcastable toself.varshape. Default is20. * u.mV.E_in (
ArrayLike, optional) – Inhibitory reversal potential \(E_\mathrm{in}\) in mV, broadcastable toself.varshape. Default is-90. * u.mV.E_L (
ArrayLike, optional) – Resting potential \(E_L\) in mV, broadcastable toself.varshape. Default is-60. * u.mV.tau_syn_ex (
ArrayLike, optional) – Excitatory alpha time constant \(\tau_\mathrm{ex}\) in ms, broadcastable toself.varshape. Must be strictly positive elementwise. Default is1. * u.ms.tau_syn_in (
ArrayLike, optional) – Inhibitory alpha time constant \(\tau_\mathrm{in}\) in ms, broadcastable toself.varshape. Must be strictly positive elementwise. Default is1. * u.ms.I_e (
ArrayLike, optional) – Constant external current \(I_e\) in pA, broadcastable toself.varshape. Added in each integration substep. Default is0. * u.pA.tau_ahp (
ArrayLike, optional) – AHP alpha time constant \(\tau_\mathrm{ahp}\) in ms, broadcastable toself.varshape. Must be strictly positive elementwise. Default is0.5 * u.ms.E_ahp (
ArrayLike, optional) – AHP reversal potential \(E_\mathrm{ahp}\) in mV, broadcastable toself.varshape. Default is-95. * u.mV.g_ahp (
ArrayLike, optional) – AHP kick conductance scale \(g_\mathrm{ahp}\) in nS, broadcastable toself.varshape. Controls magnitude of AHP alpha initialized at each spike. Default is443.8 * u.nS.ahp_bug (
ArrayLike, optional) – Boolean flag (broadcastable toself.varshape) enabling historical single-AHP bug mode. IfTrue, each spike replaces existing AHP state with new AHP kick. IfFalse, AHP kicks accumulate. Default isFalse.gsl_error_tol (
ArrayLike, optional) – Unitless local RKF45 error tolerance, broadcastable and strictly positive. Default is1e-3.V_initializer (
Callable, optional) – Initializer used byinit_state()for membrane potentialV. Must return mV-compatible values with shape compatible withself.varshape. Default isbraintools.init.Constant(-60. * u.mV).g_ex_initializer (
Callable, optional) – Initializer for excitatory conductance stateg_ex(nS). Default isbraintools.init.Constant(0. * u.nS).g_in_initializer (
Callable, optional) – Initializer for inhibitory conductance stateg_in(nS). Default isbraintools.init.Constant(0. * u.nS).g_ahp_initializer (
Callable, optional) – Initializer for AHP conductance stateg_ahp_state(nS). Default isbraintools.init.Constant(0. * u.nS).spk_fun (
Callable, optional) – Surrogate spike function used byget_spike()andupdate(). Receives normalized threshold distance tensor. Default isbraintools.surrogate.ReluGrad().spk_reset (
str, optional) – Reset policy forwarded toNeuron.'hard'matches NEST behavior. Default is'hard'.
Parameter Mapping
Table 12 Parameter mapping to model symbols# Parameter
Type / shape / unit
Default
Math symbol
Semantics
in_sizeSize; scalar/tuplerequired
–
Defines
self.varshapefor parameter/state broadcasting.V_thArrayLike, broadcastable to
self.varshape(mV)-45. * u.mV\(V_{th}\)
Spike threshold voltage.
g_LArrayLike, broadcastable (nS)
100. * u.nS\(g_L\)
Leak conductance.
C_mArrayLike, broadcastable (pF),
> 01000. * u.pF\(C_m\)
Membrane capacitance.
E_exArrayLike, broadcastable (mV)
20. * u.mV\(E_\mathrm{ex}\)
Excitatory reversal potential.
E_inArrayLike, broadcastable (mV)
-90. * u.mV\(E_\mathrm{in}\)
Inhibitory reversal potential.
E_LArrayLike, broadcastable (mV)
-60. * u.mV\(E_L\)
Resting potential.
tau_syn_exArrayLike, broadcastable (ms),
> 01. * u.ms\(\tau_\mathrm{ex}\)
Excitatory alpha time constant.
tau_syn_inArrayLike, broadcastable (ms),
> 01. * u.ms\(\tau_\mathrm{in}\)
Inhibitory alpha time constant.
I_eArrayLike, broadcastable (pA)
0. * u.pA\(I_e\)
Constant external current.
tau_ahpArrayLike, broadcastable (ms),
> 00.5 * u.ms\(\tau_\mathrm{ahp}\)
AHP alpha time constant.
E_ahpArrayLike, broadcastable (mV)
-95. * u.mV\(E_\mathrm{ahp}\)
AHP reversal potential.
g_ahpArrayLike, broadcastable (nS)
443.8 * u.nS\(g_\mathrm{ahp}\)
AHP kick conductance scale.
ahp_bugArrayLike broadcastable bool
False–
Enable single-AHP historical bug mode.
gsl_error_tolArrayLike, broadcastable, unitless,
> 01e-3–
Local absolute tolerance for the embedded RKF45 error estimate.
V_initializerCallable returning mV-compatible values
Constant(-60. * u.mV)–
Initializes membrane state
V.g_ex_initializerCallable returning nS-compatible values
Constant(0. * u.nS)–
Initializes excitatory conductance.
g_in_initializerCallable returning nS-compatible values
Constant(0. * u.nS)–
Initializes inhibitory conductance.
g_ahp_initializerCallable returning nS-compatible values
Constant(0. * u.nS)–
Initializes AHP conductance state.
spk_funCallable
ReluGrad()–
Surrogate spike output nonlinearity.
spk_resetstr
'hard'–
Reset mode inherited from base
Neuron.namestr | None
None–
Optional node name.
- Raises:
ValueError – If validated constraints fail (non-positive capacitance, non-positive time constants, non-positive gsl_error_tol).
TypeError – If provided arguments are incompatible with expected units/callables (mV, pA, pF, ms, nS).
KeyError – If simulation context values
tand/ordtare missing whenupdate()is called.AttributeError – If
update()is called beforeinit_state()creates required runtime states.
- V#
Membrane potential state in mV.
- Type:
HiddenState
- dg_ex#
Excitatory conductance rate-of-change state (nS/ms).
- Type:
ShortTermState
- g_ex#
Excitatory conductance state in nS.
- Type:
HiddenState
- dg_in#
Inhibitory conductance rate-of-change state (nS/ms).
- Type:
ShortTermState
- g_in#
Inhibitory conductance state in nS.
- Type:
HiddenState
- dg_ahp#
AHP conductance rate-of-change state (nS/ms).
- Type:
ShortTermState
- g_ahp_state#
AHP conductance state in nS.
- Type:
HiddenState
- I_stim#
One-step buffered external current in pA.
- Type:
ShortTermState
- integration_step#
Adaptive RKF45 step size hint in ms.
- Type:
ShortTermState
- last_spike_time#
Absolute precise spike time in ms.
- Type:
ShortTermState
Notes
The model has no explicit membrane reset or refractory state: after crossing threshold, voltage continues to evolve and can spike again.
Continuous input
xpassed toupdate()is buffered and affects the next step (NEST current-event timing).Like NEST, this model provides precise output spike timing via linear interpolation but does not process off-grid spike-input offsets.
RKF45 integration is performed via the adaptive integrator and written back into BrainUnit states at step end.
ahp_bug=Truereproduces the original Fortran behavior where only one AHP is tracked; this is primarily for validation against legacy code.
Examples
Create a single neuron with default parameters and simulate:
>>> import brainstate as bs >>> import saiunit as u >>> import brainpy.state as bps >>> neuron = bps.iaf_chxk_2008(1) >>> with bs.environ.context(dt=0.1 * u.ms): ... neuron.init_state() ... spike = neuron.update(100. * u.pA) # buffered to next step
Inspect AHP kick behavior after spike:
>>> neuron.V.value # check membrane potential >>> neuron.g_ahp_state.value # check AHP conductance state
Recordables
V_m,g_ex,g_in,g_ahp,I_syn_ex,I_syn_in,I_ahpReferences
- get_spike(V=None)[source]#
Evaluate surrogate spike output from membrane voltage.
- Parameters:
V (
ArrayLike, optional) – Voltage values with shape broadcastable toself.varshapeand units compatible with mV. IfNone, uses current stateself.V.value.- Returns:
Surrogate spike activation produced by
spk_fun((V - V_th) / |V_th - E_L|).- Return type:
ArrayLike
- init_state(**kwargs)[source]#
Initialize persistent and short-term state variables.
- Parameters:
**kwargs – Unused compatibility parameters accepted by the base-state API.
- Raises:
ValueError – If an initializer cannot be broadcast to requested shape.
TypeError – If initializer outputs have incompatible units/dtypes for the corresponding state variables.
- update(x=Quantity(0., 'pA'), w_ex=None, w_in=None)[source]#
Advance the neuron by one simulation step.
- Parameters:
x (
ArrayLike, optional) – Continuous external current input in pA, broadcastable toself.varshape. This value is stored intoI_stimand applied at the next simulation step (one-step delay).w_ex (
ArrayLikeorNone, optional) – Excitatory synaptic weight increment (nS) to add todg_exafter integration, scaled bye/tau_syn_ex. WhenNone(default), the value is read from registered delta inputs with label'w_ex'. Provide an explicit array for JIT-compatible (for_loop) usage.w_in (
ArrayLikeorNone, optional) – Inhibitory synaptic weight increment (nS), analogous tow_exbut fordg_inwith label'w_in'.
- Returns:
Binary spike tensor with dtype
jnp.float64and shapeself.V.value.shape. A value of1.0indicates a threshold crossing from below during the integrated interval \((t, t+dt]\).- Return type:
jax.Array
Notes
Integration uses an adaptive RKF45 loop. Spike detection and AHP kicks follow NEST semantics: crossing is checked at the global step level (comparing V before and after the full integration), and the AHP state is updated post-integration using linear interpolation of the spike time. Synaptic inputs (
w_ex,w_in) are applied after integration.