iaf_psc_alpha#
- class brainpy.state.iaf_psc_alpha(in_size, E_L=Quantity(-70., "mV"), C_m=Quantity(250., "pF"), tau_m=Quantity(10., "ms"), t_ref=Quantity(2., "ms"), V_th=Quantity(-55., "mV"), V_reset=Quantity(-70., "mV"), tau_syn_ex=Quantity(2., "ms"), tau_syn_in=Quantity(2., "ms"), I_e=Quantity(0., "pA"), V_min=None, V_initializer=Constant(value=-70. mV), spk_fun=ReluGrad(alpha=0.3, width=1.0), spk_reset='hard', ref_var=False, name=None)#
NEST-compatible
iaf_psc_alphaneuron model.Description
iaf_psc_alphais a current-based leaky integrate-and-fire neuron with hard threshold/reset, fixed absolute refractory period, and alpha-shaped excitatory/inhibitory current kernels. The implementation mirrors NESTmodels/iaf_psc_alpha.{h,cpp}update order and propagator formulas.1. Continuous-Time Dynamics
The membrane dynamics are
\[\frac{dV_m}{dt} = -\frac{V_m - E_L}{\tau_m} + \frac{I_\text{syn} + I_e}{C_m}\]with \(I_\text{syn} = I_{\text{syn,ex}} + I_{\text{syn,in}}\).
Each alpha current channel is represented by a two-state linear system:
\[\frac{d\,dI_X}{dt} = -\frac{dI_X}{\tau_{\text{syn},X}}, \qquad \frac{dI_X}{dt} = dI_X - \frac{I_X}{\tau_{\text{syn},X}}, \quad X \in \{\mathrm{ex}, \mathrm{in}\}.\]This is equivalent to the normalized alpha kernel
\[i_X(t) = \frac{e}{\tau_{\text{syn},X}}\, t\, e^{-t/\tau_{\text{syn},X}} \Theta(t),\]which peaks at 1 when \(t=\tau_{\text{syn},X}\). Incoming spike weight \(w\) (pA) is split by sign so \(w_+=\max(w,0)\) drives excitatory state and \(w_-=\min(w,0)\) drives inhibitory state.
2. Exact Discrete Propagator and NEST Update Order
For fixed step \(h=dt\), exact linear propagation is applied to \(y_3=V_m-E_L\), synaptic states, and a one-step delayed current buffer \(y_0\):
\[dI_{X,n+1} = P_{11,X}\, dI_{X,n} + \frac{e}{\tau_{\text{syn},X}} w_{X,n},\]\[I_{X,n+1} = P_{21,X}\, dI_{X,n} + P_{22,X}\, I_{X,n},\]\[y_{3,n+1} = y_{3,n} + \big(e^{-h/\tau_m}-1\big) y_{3,n} + P_{30}(y_{0,n} + I_e) + \sum_{X \in \{\mathrm{ex},\mathrm{in}\}} \left(P_{31,X} dI_{X,n} + P_{32,X} I_{X,n}\right).\]Here \(P_{11,X}=P_{22,X}=e^{-h/\tau_{\text{syn},X}}\), \(P_{21,X}=h\,e^{-h/\tau_{\text{syn},X}}\), and \(P_{30}=\tau_m(1-e^{-h/\tau_m})/C_m\).
Internal state (NEST notation):
\(y_0\) – buffered external current for next step,
\(dI_{ex}, I_{ex}\) and \(dI_{in}, I_{in}\) – alpha-kernel states,
\(y_3 = V_m - E_L\),
\(r\) – refractory countdown in grid steps.
Per-step update order:
Update membrane potential if not refractory.
Update synaptic alpha states.
Add arriving spike input to \(dI_{ex}\) / \(dI_{in}\).
Perform threshold test, reset, refractory assignment, spike emission.
Store buffered external current for the next step.
3. Near-Singular Regime :math:`tau_m approx tau_{text{syn}}`
Direct formulas for \(P_{31}\) and \(P_{32}\) contain divisions by \((\tau_m-\tau_{\text{syn}})\), which are ill-conditioned near equality. The helper
_alpha_propagator_p31_p32()follows NEST’sIAFPropagatorAlphabehavior and switches to stable limits:\[P_{32}^{\mathrm{sing}} = \frac{h}{C_m} e^{-h/\tau_m}, \qquad P_{31}^{\mathrm{sing}} = \frac{h^2}{2C_m} e^{-h/\tau_m},\]preventing cancellation/underflow artifacts around \(\tau_m=\tau_{\text{syn}}\).
4. Assumptions, Constraints, and Computational Implications
C_m > 0,tau_m > 0,tau_syn_ex > 0,tau_syn_in > 0,t_ref >= 0, andV_reset < V_thare enforced at construction.update(x=...)uses one-step delayed current buffering (NEST ring-buffer semantics): current provided at stepncontributes at stepn+1throughy0.The update path is vectorized over
self.varshapeand performs \(O(\prod \mathrm{varshape})\) floating-point work per call.Internal coefficient math is in
float64via NumPy conversion, while exposed states remain in BrainUnit quantities.
- Parameters:
in_size (
Size) – Population shape specification. All per-neuron parameters are broadcast toself.varshapederived fromin_size.E_L (
ArrayLike, optional) – Resting potential \(E_L\) in mV; scalar or array broadcastable toself.varshape. Default is-70. * u.mV.C_m (
ArrayLike, optional) – Membrane capacitance \(C_m\) in pF; broadcastable toself.varshapeand strictly positive. Default is250. * u.pF.tau_m (
ArrayLike, optional) – Membrane time constant \(\tau_m\) in ms; broadcastable and strictly positive. Default is10. * u.ms.t_ref (
ArrayLike, optional) – Absolute refractory period \(t_{ref}\) in ms; broadcastable and nonnegative. Converted to integer step counts byceil(t_ref / dt). Default is2. * u.ms.V_th (
ArrayLike, optional) – Spike threshold \(V_{th}\) in mV; broadcastable toself.varshape. Default is-55. * u.mV.V_reset (
ArrayLike, optional) – Reset potential \(V_{reset}\) in mV; broadcastable and must satisfyV_reset < V_thelementwise. Default is-70. * u.mV.tau_syn_ex (
ArrayLike, optional) – Excitatory alpha time constant \(\tau_{\text{syn,ex}}\) in ms; broadcastable and strictly positive. Default is2. * u.ms.tau_syn_in (
ArrayLike, optional) – Inhibitory alpha time constant \(\tau_{\text{syn,in}}\) in ms; broadcastable and strictly positive. Default is2. * u.ms.I_e (
ArrayLike, optional) – Constant injected current \(I_e\) in pA; scalar or array broadcastable toself.varshape. Default is0. * u.pA.V_min (
ArrayLikeorNone, optional) – Optional lower voltage clamp \(V_{min}\) in mV. When provided, membrane candidate update is clipped withmax(V, V_min)before thresholding.Nonedisables clipping. Default isNone.V_initializer (
Callable, optional) – Initializer for membrane stateV. Called byinit_state(). Default isbraintools.init.Constant(-70. * u.mV).spk_fun (
Callable, optional) – Surrogate spike nonlinearity used byget_spike(). Default isbraintools.surrogate.ReluGrad().spk_reset (
str, optional) – Reset policy inherited fromNeuron.'hard'matches NEST hard reset semantics. Default is'hard'.ref_var (
bool, optional) – IfTrue, allocates boolean stateself.refractoryfor external inspection of refractory condition. Default isFalse.
Parameter Mapping
Table 3 Parameter mapping to model symbols# Parameter
Type / shape / unit
Default
Math symbol
Semantics
in_sizeSize; scalar/tuplerequired
–
Defines neuron population shape
self.varshape.E_LArrayLike, broadcastable to
self.varshape(mV)-70. * u.mV\(E_L\)
Resting membrane potential.
C_mArrayLike, broadcastable (pF),
> 0250. * u.pF\(C_m\)
Membrane capacitance used in subthreshold integration.
tau_mArrayLike, broadcastable (ms),
> 010. * u.ms\(\tau_m\)
Leak time constant in membrane propagator.
t_refArrayLike, broadcastable (ms),
>= 02. * u.ms\(t_{ref}\)
Absolute refractory duration.
V_thandV_resetArrayLike, broadcastable (mV), with
V_reset < V_th-55. * u.mV,-70. * u.mV\(V_{th}\), \(V_{reset}\)
Threshold and post-spike reset levels.
tau_syn_exandtau_syn_inArrayLike, broadcastable (ms), each
> 02. * u.ms\(\tau_{\text{syn,ex}}\), \(\tau_{\text{syn,in}}\)
Alpha kernel time constants for excitatory/inhibitory currents.
I_eArrayLike, broadcastable (pA)
0. * u.pA\(I_e\)
Constant external current added every step.
V_minArrayLike broadcastable (mV) or
NoneNone\(V_{min}\)
Optional lower bound on membrane candidate update.
V_initializerCallable
Constant(-70. * u.mV)–
Initializer used for membrane state
V.spk_funCallable
ReluGrad()–
Surrogate spike function returned by
update().spk_resetstr
'hard'–
Reset mode inherited from
Neuron.ref_varbool
False–
Allocate boolean state
self.refractorywhen enabled.namestr | None
None–
Optional node name.
- Raises:
ValueError – If parameter constraints are violated:
C_m <= 0,tau_m <= 0,tau_syn_ex <= 0,tau_syn_in <= 0,t_ref < 0, orV_reset >= V_th.TypeError – If provided quantities are not unit-compatible with expected units (mV, ms, pF, pA) during conversion/broadcasting.
KeyError – At runtime, if required simulation context entries (for example
tordt) are missing whenupdate()is called.AttributeError – If
update()is called beforeinit_state()creates required state holders.
Notes
State variables are
V,I_syn_ex,I_syn_in,dI_syn_ex,dI_syn_in,y0,refractory_step_count, andlast_spike_time.refractoryis added only whenref_var=True.Spike weights from
sum_delta_inputsare interpreted in pA: positive values are excitatory and negative values are inhibitory.update(x=...)storesxintoy0for the next step, matching NEST current-event buffering semantics.
Examples
>>> import brainpy >>> import brainstate >>> import saiunit as u >>> with brainstate.environ.context(dt=0.1 * u.ms): ... neu = brainpy.state.iaf_psc_alpha(in_size=(2,), I_e=220.0 * u.pA) ... neu.init_state() ... with brainstate.environ.context(t=1.0 * u.ms): ... spk = neu.update() ... _ = spk.shape
>>> import brainpy >>> import brainstate >>> import saiunit as u >>> with brainstate.environ.context(dt=0.1 * u.ms): ... neu = brainpy.state.iaf_psc_alpha(in_size=1, tau_syn_ex=1.5 * u.ms) ... neu.init_state() ... with brainstate.environ.context(t=0.0 * u.ms): ... _ = neu.update(x=200.0 * u.pA) ... with brainstate.environ.context(t=0.1 * u.ms): ... spk_next = neu.update() ... _ = spk_next
References
- init_state(**kwargs)[source]#
Initialize runtime states for membrane, synapses, and refractoriness.
- Parameters:
**kwargs – Unused compatibility parameters accepted by the base-state API.
- Raises:
ValueError – If initializers cannot broadcast to
self.varshape.TypeError – If initializer outputs are incompatible with expected unit/array conversions for voltage, current, or integer refractory states.
- update(x=Quantity(0., 'pA'))[source]#
Advance the neuron by one simulation step.
- Parameters:
x (
ArrayLike, optional) – Continuous current input in pA for this step.xis accumulated throughsum_current_inputs()and stored iny0for use on the next call (one-step delayed buffering).- Returns:
out – Spike output tensor from
get_spike(), shapeself.V.value.shape. On threshold crossings,v_outis nudged above threshold by1e-12mV-equivalent to preserve positive surrogate activation.- Return type:
jax.Array- Raises:
KeyError – If simulation context does not provide
tordt.AttributeError – If required states are missing because
init_state()was not called.TypeError – If
xor stored states are not unit-compatible with expected pA / mV conversions.