iaf_psc_delta#
- class brainpy.state.iaf_psc_delta(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"), 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', refractory_input=False, ref_var=False, name=None)#
NEST-compatible
iaf_psc_deltaneuron model.Description
iaf_psc_deltais a current-based leaky integrate-and-fire neuron with hard threshold/reset, absolute refractory period, and delta-shaped synaptic events represented as instantaneous membrane-voltage jumps (weights in mV). The implementation follows the NEST modeliaf_psc_deltaupdate semantics, including refractory handling and step-wise exact subthreshold propagation.1. Continuous-Time Dynamics and Exact Per-Step Propagator
The membrane dynamics are
\[\frac{dV_\text{m}}{dt} = -\frac{V_{\text{m}} - E_\text{L}}{\tau_{\text{m}}} + \dot{\Delta}_{\text{syn}} + \frac{I_{\text{syn}} + I_\text{e}}{C_{\text{m}}}\]where \(I_\text{syn}\) is the sum of continuous current inputs and \(\dot{\Delta}_{\text{syn}}\) captures impulse-like jumps from delta synapses.
For fixed simulation step \(h=dt\) and piecewise-constant current \(I_k\), exact integration of the linear subthreshold ODE yields
\[V_{k+1}^{\mathrm{cand}} = E_L + (V_k - E_L)e^{-h/\tau_m} + \frac{\tau_m}{C_m}\left(I_k + I_e\right)\left(1 - e^{-h/\tau_m}\right),\]which is implemented directly in
update(). This is equivalent to the propagator formulation used in NEST for this linear system.2. Spike Condition, Reset, and Refractory Countdown
After adding delta-input jump \(\Delta_{\text{syn},k}\), a spike is emitted at step end if the post-update potential crosses threshold:
\[V_k^{\mathrm{post}} \ge V_{th}.\]On spike:
\[V \leftarrow V_{reset}, \qquad r \leftarrow \left\lceil \frac{t_{ref}}{dt} \right\rceil,\]where \(r\) is the integer refractory-step counter. While \(r > 0\), the membrane is clamped (no subthreshold integration is committed), then \(r\) decrements by one each simulation step.
3. Delta Synapses, Voltage Jumps, and Charge Interpretation
The change in membrane potential due to synaptic inputs can be formulated as:
\[\dot{\Delta}_{\text{syn}}(t) = \sum_{j} w_j \sum_k \delta(t-t_j^k-d_j) \;,\]where \(j\) indexes either excitatory (\(w_j > 0\)) or inhibitory (\(w_j < 0\)) presynaptic neurons, \(k\) indexes the spike times of neuron \(j\), \(d_j\) is the delay from neuron \(j\), and \(\delta\) is the Dirac delta distribution. This implies that the jump in voltage upon a single synaptic input spike is
\[\Delta_{\text{syn}} = w \;,\]where \(w\) is synaptic weight in mV. Positive weights are excitatory and negative weights are inhibitory.
The change in voltage caused by the synaptic input can be interpreted as being caused by individual post-synaptic currents (PSCs) given by
\[i_{\text{syn}}(t) = C_{\text{m}} \cdot w \cdot \delta(t) \;.\]As a consequence, the total charge \(q\) transferred by a single PSC is
\[q = \int_0^{\infty} i_{\text{syn}}(t)\, dt = C_{\text{m}} \cdot w \;.\]4. Assumptions, Constraints, and Computational Implications
The model assumes unit-compatible parameters and broadcast-compatible shapes against
self.varshape.V_minis optional; when provided, candidate voltage is clipped withmax(V, V_min)before threshold evaluation.Per-step compute is \(O(\prod \mathrm{varshape})\) with vectorized elementwise operations.
refractory_input=Falsediscards delta events that arrive during refractory clamping, whilerefractory_input=Truestores a decayed contribution that is released when refractoriness ends.
Note
This implementation uses exact integration for subthreshold dynamics and NEST-compatible conversion of refractory duration to grid steps via
ceil(t_ref / dt).- Parameters:
in_size (
Size) – Population shape specification. All 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.varshape. Expected positive for physical behavior. Default is250. * u.pF.tau_m (
ArrayLike, optional) – Membrane time constant \(\tau_m\) in ms; broadcastable toself.varshape. Expected positive. Default is10. * u.ms.t_ref (
ArrayLike, optional) – Absolute refractory duration \(t_{ref}\) in ms. Converted to integer simulation steps usingceil(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 toself.varshape. Default is-70. * u.mV.I_e (
ArrayLike, optional) – Constant external current \(I_e\) in pA; scalar or array broadcastable toself.varshape. Default is0. * u.pA.V_min (
ArrayLikeorNone, optional) – Optional lower membrane bound \(V_{min}\) in mV. IfNone, no lower clipping is applied. Default isNone.V_initializer (
Callable, optional) – Initializer for membrane stateVininit_state(). Output must be shape-compatible withself.varshape(and optional batch prefix). Default isbraintools.init.Constant(-70. * u.mV).spk_fun (
Callable, optional) – Surrogate spike function used byget_spike(). Default isbraintools.surrogate.ReluGrad().spk_reset (
str, optional) – Reset policy inherited fromNeuron.'hard'reproduces NEST hard reset behavior. Default is'hard'.refractory_input (
bool, optional) – IfFalse, delta inputs during refractory are ignored. IfTrue, refractory-arriving delta jumps are accumulated inrefractory_spike_bufferand applied after refractory release. Default isFalse.ref_var (
bool, optional) – IfTrue, allocate boolean refractory stateself.refractoryfor inspection. Default isFalse.
Parameter Mapping
Table 1 Parameter mapping to model symbols# Parameter
Type / shape / unit
Default
Math symbol
Semantics
in_sizeSize; scalar/tuplerequired
–
Defines population/state shape
self.varshape.E_LArrayLike, broadcastable to
self.varshape(mV)-70. * u.mV\(E_L\)
Resting membrane potential.
C_mArrayLike, broadcastable (pF)
250. * u.pF\(C_m\)
Membrane capacitance in subthreshold propagator.
tau_mArrayLike, broadcastable (ms)
10. * u.ms\(\tau_m\)
Membrane leak time constant.
t_refArrayLike, broadcastable (ms), step-converted by
ceil2. * u.ms\(t_{ref}\)
Absolute refractory duration.
V_thandV_resetArrayLike, broadcastable (mV)
-55. * u.mV,-70. * u.mV\(V_{th}\), \(V_{reset}\)
Threshold and reset voltages.
I_eArrayLike, broadcastable (pA)
0. * u.pA\(I_e\)
Constant injected current.
V_minArrayLike broadcastable (mV) or
NoneNone\(V_{min}\)
Optional lower clamp before threshold test.
V_initializerCallable
Constant(-70. * u.mV)–
Initializes membrane state
V.spk_funCallable
ReluGrad()–
Surrogate spike output function.
spk_resetstr
'hard'–
Reset mode inherited from base neuron class.
refractory_inputbool
False–
Controls refractory-period treatment of delta inputs.
ref_varbool
False–
Enables persistent refractory boolean state.
namestr | None
None–
Optional node identifier.
- Raises:
ValueError – If parameter initialization or broadcasting fails (for example due to incompatible array shape in
braintools.init.param).TypeError – If provided values are not compatible with expected units/types (mV, ms, pF, pA, or callable initializers/spike functions).
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 variables.
- V#
Membrane potential.
- Type:
HiddenState
- last_spike_time#
Time of the last spike, used to implement the refractory period.
- Type:
ShortTermState
- refractory#
Neuron refractory state (only present if
ref_var=True).- Type:
HiddenState
Notes
State variables are
V,last_spike_time,refractory_step_count, andrefractory_spike_buffer.refractoryexists only whenref_var=True.Continuous current input
xis combined withI_ethroughsum_current_inputs()in the same simulation step.Delta events from
sum_delta_inputs()are interpreted in mV and added as instantaneous voltage jumps.
Examples
>>> import brainpy >>> import brainstate >>> import saiunit as u >>> with brainstate.environ.context(dt=0.1 * u.ms): ... neu = brainpy.state.iaf_psc_delta(in_size=10, t_ref=2.0 * u.ms) ... neu.init_state() ... with brainstate.environ.context(t=0.0 * u.ms): ... spk = neu.update(x=500.0 * u.pA) ... _ = spk.shape
>>> import brainpy >>> import brainstate >>> import saiunit as u >>> with brainstate.environ.context(dt=0.1 * u.ms): ... neu = brainpy.state.iaf_psc_delta(in_size=(2,), V_min=-80.0 * u.mV) ... neu.init_state() ... with brainstate.environ.context(t=0.0 * u.ms): ... _ = neu.update(x=120.0 * u.pA)
References
See also
- get_spike(V=None)[source]#
Evaluate surrogate spike activation for a voltage tensor.
- Parameters:
V (
ArrayLikeorNone, optional) – Membrane voltage input in mV, broadcast-compatible withself.varshape. IfNone, the method usesself.V.value.- 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/unit.
- init_state(**kwargs)[source]#
Initialize membrane and refractory runtime states.
- Parameters:
**kwargs – Unused compatibility parameters accepted by the base-state API.
- Raises:
ValueError – If initializer outputs cannot be broadcast to target state shape.
TypeError – If initializer values are incompatible with required numeric/unit conversions.
- update(x=Quantity(0., 'pA'))[source]#
Advance the neuron by one simulation step.
- Parameters:
x (
ArrayLike, optional) – External current input in pA for this step. It is combined withI_eand additional current sources fromsum_current_inputs().- Returns:
out – Surrogate spike output from
get_spike()with shapeself.V.value.shape. The returned spike signal is computed from pre-reset post-threshold voltagev_post.- Return type:
jax.Array- Raises:
KeyError – If simulation context does not provide required entries
tordt.AttributeError – If required states are missing because
init_state()has not been called.TypeError – If input/state values are not unit-compatible with expected pA/mV arithmetic.