iaf_psc_exp#
- class brainpy.state.iaf_psc_exp(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"), rho=Quantity(0.01, "Hz"), delta=Quantity(0., "mV"), 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_expneuron model.Description
iaf_psc_expis a current-based leaky integrate-and-fire neuron with hard reset, fixed absolute refractory period, and exponential excitatory and inhibitory postsynaptic currents. The implementation follows NESTmodels/iaf_psc_exp.{h,cpp}update order, including one-step buffered current input and receptor-1 filtered current handling.1. Continuous-Time Dynamics
The subthreshold membrane equation is
\[\frac{dV_m}{dt} = -\frac{V_m - E_L}{\tau_m} + \frac{I_{\mathrm{syn,ex}} + I_{\mathrm{syn,in}} + I_e + I_0}{C_m}\]where \(I_0\) is the buffered current from the previous simulation step. Synaptic currents decay exponentially:
\[\frac{dI_{\mathrm{syn,ex}}}{dt} = -\frac{I_{\mathrm{syn,ex}}}{\tau_{\mathrm{syn,ex}}} \qquad \frac{dI_{\mathrm{syn,in}}}{dt} = -\frac{I_{\mathrm{syn,in}}}{\tau_{\mathrm{syn,in}}}.\]NEST also defines a second current receptor \(I_1\) that is filtered through the excitatory kernel; this is exposed via
update(x_filtered=...).2. Exact Step Propagator and NEST Update Ordering
For time step \(h = dt\) (in ms), exact exponentials are used for all linear sub-systems:
\[P_{11,\mathrm{ex}} = e^{-h/\tau_{\mathrm{syn,ex}}}, \quad P_{11,\mathrm{in}} = e^{-h/\tau_{\mathrm{syn,in}}}, \quad P_{22} = e^{-h/\tau_m},\]\[P_{20} = \frac{\tau_m}{C_m}(1 - P_{22}),\]\[P_{21}(\tau_{\mathrm{syn}}) = \frac{\tau_{\mathrm{syn}}\tau_m}{C_m(\tau_m - \tau_{\mathrm{syn}})} \left(e^{-h/\tau_m} - e^{-h/\tau_{\mathrm{syn}}}\right),\]where \(P_{21}\) is evaluated numerically stably by
propagator_exp(). Let \(V_\mathrm{rel} = V_m - E_L\). The candidate membrane update is\[V_{\mathrm{rel},n+1} = P_{22} V_{\mathrm{rel},n} + P_{21,\mathrm{ex}} I_{\mathrm{syn,ex},n} + P_{21,\mathrm{in}} I_{\mathrm{syn,in},n} + P_{20}(I_e + I_{0,n}).\]Per-step update order is:
Update membrane potential if not refractory.
Decay synaptic currents.
Add filtered-current contribution to excitatory synaptic current.
Add arriving spikes (positive -> excitatory, negative -> inhibitory).
Threshold test, reset and refractory assignment.
Store buffered currents for next step.
3. Escape-Noise Threshold Dynamics
Deterministic thresholding is used when \(\delta < 10^{-10}\): \(V_{\mathrm{rel}} \ge \theta\), where \(\theta = V_{th} - E_L\).
For \(\delta > 0\), the model uses an exponential hazard:
\[\phi(V) = \rho \exp\!\left(\frac{V_{\mathrm{rel}} - \theta}{\delta}\right),\]and spikes with step probability \(p = \phi(V)\,h\times10^{-3}\) because \(\phi\) is in
1/swhilehis in ms. Stochastic decisions usenumpy.random.random.4. Stability Constraints and Computational Implications
Construction enforces
V_reset < V_th,C_m > 0,tau_m > 0,tau_syn_ex > 0,tau_syn_in > 0,t_ref >= 0,rho >= 0, anddelta >= 0.propagator_exp()uses a singular fallback \((h/C_m)\exp(-h/\tau_m)\) whentau_synis numerically close totau_m, avoiding cancellation in \((e^{-h/\tau_m} - e^{-h/\tau_{\mathrm{syn}}})/(\tau_m - \tau_{\mathrm{syn}})\).Per-call cost is \(O(\prod \mathrm{varshape})\) with vectorized NumPy operations in
float64for coefficient evaluation.Buffered current semantics match NEST ring-buffer timing:
x/x_filteredsupplied at stepnare stored and consumed at stepn+1.
- 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 and 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 steps 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) – Post-spike reset potential \(V_{reset}\) in mV; broadcastable and must satisfyV_reset < V_thelementwise. Default is-70. * u.mV.tau_syn_ex (
ArrayLike, optional) – Excitatory synaptic decay constant \(\tau_{\mathrm{syn,ex}}\) in ms; broadcastable and strictly positive. Default is2. * u.ms.tau_syn_in (
ArrayLike, optional) – Inhibitory synaptic decay constant \(\tau_{\mathrm{syn,in}}\) in ms; broadcastable and strictly positive. Default is2. * u.ms.I_e (
ArrayLike, optional) – Constant external injected current \(I_e\) in pA; scalar or array broadcastable toself.varshape. Default is0. * u.pA.rho (
ArrayLike, optional) – Escape-noise base firing intensity \(\rho\) in1/s; broadcastable and nonnegative. Used only in stochastic mode (delta > 0). Default is0.01 / u.second.delta (
ArrayLike, optional) – Escape-noise soft-threshold width \(\delta\) in mV; broadcastable and nonnegative.delta == 0reproduces deterministic thresholding. Default is0. * u.mV.V_initializer (
Callable, optional) – Initializer for membrane stateVused 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 reset behavior. Default is'hard'.ref_var (
bool, optional) – IfTrue, allocatesself.refractory(boolean array) for external inspection of the refractory state. Default isFalse.name (
strorNone, optional) – Optional node name passed to the parent module. Default isNone.
Parameter Mapping
Table 6 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 in voltage integration.
tau_mArrayLike, broadcastable (ms),
> 010. * u.ms\(\tau_m\)
Membrane leak time constant.
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 voltages.
tau_syn_exandtau_syn_inArrayLike, broadcastable (ms), each
> 02. * u.ms\(\tau_{\mathrm{syn,ex}}\), \(\tau_{\mathrm{syn,in}}\)
Exponential PSC decay constants.
I_eArrayLike, broadcastable (pA)
0. * u.pA\(I_e\)
Constant current injected every step.
rhoanddeltaArrayLike, broadcastable;
rhoin1/s,deltain mV, both>= 00.01 / u.second,0. * u.mV\(\rho\), \(\delta\)
Escape-noise hazard parameters.
V_initializerCallable
Constant(-70. * u.mV)–
Initializer for membrane state
V.spk_funCallable
ReluGrad()–
Surrogate function used for output spikes.
spk_resetstr(typically'hard')'hard'–
Reset behavior selection in base class.
ref_varboolFalse–
Enables explicit boolean refractory state variable.
namestrorNoneNone–
Optional instance name.
- Raises:
ValueError – Raised at construction when any validated constraint is violated:
V_reset >= V_th, nonpositiveC_m/tau_m/synaptic time constants, negativet_ref, negativerho, or negativedelta.
- V#
Membrane potential in mV; shape
self.varshape.- Type:
brainstate.HiddenState
- i_syn_ex#
Excitatory synaptic current in pA.
- Type:
brainstate.ShortTermState
- i_syn_in#
Inhibitory synaptic current in pA.
- Type:
brainstate.ShortTermState
- i_0#
Buffered receptor-0 current (pA) applied on the next simulation step.
- Type:
brainstate.ShortTermState
- i_1#
Buffered receptor-1 current (pA) filtered through the excitatory exponential kernel on the next simulation step.
- Type:
brainstate.ShortTermState
- refractory_step_count#
Integer countdown of remaining refractory steps (
jnp.int32).- Type:
brainstate.ShortTermState
- last_spike_time#
Simulation time of the most recent spike (ms).
- Type:
brainstate.ShortTermState
- refractory#
Boolean refractory mask; only present when
ref_var=True.- Type:
brainstate.ShortTermState
Notes
This implementation uses exact (analytical) integration of the linear subthreshold ODE via pre-computed propagator coefficients, matching NEST’s update precision for fixed-step simulation.
Continuous current input
xis combined withI_eand any additional current sources registered viasum_current_inputs(); the combined value is buffered one step (NEST ring-buffer semantics).Delta spike inputs from
sum_delta_inputs()are split by sign: positive weights incrementi_syn_ex; negative weights incrementi_syn_in.The stochastic escape-noise mode (
delta > 0) usesnumpy.random.randomand is therefore not JIT-compilable via JAX. Usedelta=0for fully differentiable, JIT-compatible runs.
Examples
>>> import brainstate >>> import saiunit as u >>> from brainpy_state._nest.iaf_psc_exp import iaf_psc_exp >>> with brainstate.environ.context(dt=0.1 * u.ms): ... neu = iaf_psc_exp(in_size=(3,), I_e=250. * u.pA, delta=0. * u.mV) ... neu.init_state() ... with brainstate.environ.context(t=0.0 * u.ms): ... out = neu.update(x=0. * u.pA, x_filtered=0. * u.pA) ... _ = out.shape
>>> import brainstate >>> import saiunit as u >>> from brainpy_state._nest.iaf_psc_exp import iaf_psc_exp >>> with brainstate.environ.context(dt=0.1 * u.ms): ... neu = iaf_psc_exp( ... in_size=10, ... tau_syn_ex=2.0 * u.ms, ... tau_syn_in=5.0 * u.ms, ... ref_var=True, ... ) ... neu.init_state() ... with brainstate.environ.context(t=0.0 * u.ms): ... spk = neu.update(x=300.0 * u.pA) ... _ = spk.shape
References
See also
iaf_psc_deltaLIF neuron with delta-function PSCs (voltage-jump synapses)
iaf_cond_expLIF neuron with exponential conductance synapses
LIFLeaky integrate-and-fire (brainpy parameterization)
LIFRefLeaky integrate-and-fire with explicit refractory tracking
- get_spike(V=None)[source]#
Evaluate surrogate spike activation for a voltage tensor.
Scales the voltage relative to threshold and reset to compute a dimensionless argument passed to the surrogate nonlinearity
self.spk_fun:\[\text{out} = \mathrm{spk\_fun}\!\left( \frac{V - V_{th}}{V_{th} - V_{reset}} \right).\]- Parameters:
V (
ArrayLikeorNone, optional) – Membrane voltage in mV, broadcast-compatible withself.varshape. IfNone,self.V.valueis used.- Returns:
out – Surrogate spike output from
self.spk_funwith the same shape asV(orself.V.valuewhenVisNone).- Return type:
- Raises:
TypeError – If
Vcannot participate in arithmetic with membrane parameters due to incompatible dtype or unit.
- init_state(**kwargs)[source]#
Initialize membrane potential and all synaptic/refractory states.
- Parameters:
**kwargs (
Any) – Unused compatibility arguments.- Raises:
ValueError – If
V_initializeroutput cannot be broadcast to the target state shape.TypeError – If initializer values are incompatible with required numeric/unit conversions.
- update(x=Quantity(0., 'pA'), x_filtered=Quantity(0., 'pA'))[source]#
Advance the neuron state by one simulation step.
- Parameters:
x (
ArrayLike, optional) – Current input in pA for receptor-0 (standard current port). Scalar or array broadcastable toself.varshape. The value is buffered (stored inself.i_0) and applied in the next step, matching NEST ring-buffer semantics. Default is0. * u.pA.x_filtered (
ArrayLike, optional) – Current input in pA for receptor-1. Buffered inself.i_1and injected through excitatory exponential filtering at the next update step via(1 - P_{11,\mathrm{ex}}) \times i_1. Scalar or array broadcastable toself.varshape. Default is0. * u.pA.
- Returns:
out – Surrogate spike output from
get_spike()with shapeself.V.value.shape. For neurons that fire this step, the voltage argument toget_spike()is nudged \(\theta + E_L + 10^{-12}\,\text{mV}\) (above threshold) to ensure a positive surrogate activation is returned even after the hard voltage reset.- Return type:
jax.Array- Raises:
KeyError – If the simulation environment context does not supply
tordt.AttributeError – If state variables are missing because
init_state()has not been called beforeupdate.TypeError – If input/state values are not unit-compatible with expected pA/mV arithmetic.
ValueError – If provided inputs cannot be broadcast to the internal state shape.