iaf_psc_exp_htum#

class brainpy.state.iaf_psc_exp_htum(in_size, E_L=Quantity(-70., "mV"), C_m=Quantity(250., "pF"), tau_m=Quantity(10., "ms"), t_ref_abs=Quantity(2., "ms"), t_ref_tot=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_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_exp_htum neuron model.

Description

iaf_psc_exp_htum is a current-based leaky integrate-and-fire neuron with exponential excitatory/inhibitory PSCs and two refractory clocks: an absolute refractory period and a longer (or equal) total refractory period. The implementation matches NEST iaf_psc_exp_htum semantics: membrane integration is disabled during absolute refractory, while threshold crossing is disabled during total refractory.

1. Continuous-Time Dynamics

For membrane potential \(V_m\) and resting potential \(E_L\), subthreshold dynamics are:

\[\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 a one-step delayed buffered continuous current. Synaptic currents follow first-order exponential decay:

\[\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}}}.\]

2. Exact Discrete-Time Propagation and Dual Refractory Gating

With \(h=dt\) (ms), the implementation uses exact linear propagators:

\[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 propagator_exp() (from _utils) handles the numerically delicate \(\tau_{\mathrm{syn}} \approx \tau_m\) case.

Let \(V_{\mathrm{rel}} = V_m - E_L\) and \(\theta = V_{th} - E_L\). The candidate voltage 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}).\]

Dual refractory counters are stored as integer step counts:

  • \(r_{\mathrm{abs}} = \lceil t_{\mathrm{ref,abs}} / dt \rceil\)

  • \(r_{\mathrm{tot}} = \lceil t_{\mathrm{ref,tot}} / dt \rceil\)

Integration is applied only where r_abs == 0. Spiking is allowed only where r_tot == 0 and \(V_{\mathrm{rel}} \ge \theta\). On spike: voltage resets to V_reset, r_abs and r_tot are reloaded from their ceiling-converted refractory durations, and last_spike_time is set to t + dt (NEST-aligned grid timing).

3. Step Ordering and NEST Timing Equivalence

Per simulation step:

  1. Compute membrane candidate only for neurons outside absolute refractory.

  2. Decrement absolute refractory counters for clamped neurons.

  3. Decay synaptic currents and add arriving delta spikes: positive weights to excitatory channel, negative to inhibitory channel.

  4. Apply threshold test only for neurons outside total refractory.

  5. On spike, apply reset and set both refractory counters.

  6. Decrement total refractory counters for non-spiking refractory neurons.

  7. Buffer continuous current input i_0 for use at the next step.

This ordering preserves NEST’s one-step delayed current-event handling and supports mixed per-neuron parameterization via broadcasted arrays.

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_abs > 0, t_ref_tot > 0, and t_ref_tot >= t_ref_abs.

  • Refractory durations are discretized by ceil; effective refractory lengths are therefore quantized in units of dt.

  • Coefficient evaluation is vectorized in float64 NumPy and scales as \(O(\prod \mathrm{varshape})\) per step.

  • i_0 buffering implies current passed at step n contributes to membrane integration at step n+1, not immediately.

Parameters:
  • in_size (Size) – Population shape specification. Per-neuron parameters are initialized and broadcast to self.varshape.

  • E_L (ArrayLike, optional) – Resting potential \(E_L\) in mV; scalar or array broadcastable to self.varshape. Default is -70. * u.mV.

  • C_m (ArrayLike, optional) – Membrane capacitance \(C_m\) in pF; broadcastable and strictly positive. Default is 250. * u.pF.

  • tau_m (ArrayLike, optional) – Membrane time constant \(\tau_m\) in ms; broadcastable and strictly positive. Default is 10. * u.ms.

  • t_ref_abs (ArrayLike, optional) – Absolute refractory duration in ms; broadcastable and strictly positive. Converted to integer step count by ceil(t_ref_abs / dt). Default is 2. * u.ms.

  • t_ref_tot (ArrayLike, optional) – Total refractory duration in ms; broadcastable and strictly positive, with t_ref_tot >= t_ref_abs elementwise. Converted by ceil(t_ref_tot / dt). Default is 2. * u.ms.

  • V_th (ArrayLike, optional) – Threshold potential \(V_{th}\) in mV; scalar or array broadcastable to self.varshape. Default is -55. * u.mV.

  • V_reset (ArrayLike, optional) – Reset potential \(V_{reset}\) in mV; broadcastable and must satisfy V_reset < V_th elementwise. Default is -70. * u.mV.

  • tau_syn_ex (ArrayLike, optional) – Excitatory PSC decay constant \(\tau_{\mathrm{syn,ex}}\) in ms; broadcastable and strictly positive. Default is 2. * u.ms.

  • tau_syn_in (ArrayLike, optional) – Inhibitory PSC decay constant \(\tau_{\mathrm{syn,in}}\) in ms; broadcastable and strictly positive. Default is 2. * u.ms.

  • I_e (ArrayLike, optional) – Constant external injected current \(I_e\) in pA; scalar or array broadcastable to self.varshape. Default is 0. * u.pA.

  • V_initializer (Callable, optional) – Initializer callable consumed by init_state() for self.V. It must return values compatible with mV units and neuron shape. Default is braintools.init.Constant(-70. * u.mV).

  • spk_fun (Callable, optional) – Surrogate spike nonlinearity applied by get_spike() to a scaled voltage distance from threshold. Default is braintools.surrogate.ReluGrad().

  • spk_reset (str, optional) – Reset mode used by Neuron; 'hard' matches reset semantics used by this model. Default is 'hard'.

  • ref_var (bool, optional) – If True, allocates self.refractory (boolean short-term state) mirroring refractory_tot_step_count > 0. Default is False.

  • name (str or None, optional) – Optional node name.

Parameter Mapping

Table 8 Parameter mapping to model symbols#

Parameter

Type / shape / unit

Default

Math symbol

Semantics

in_size

Size; scalar or tuple-like

required

Defines population shape self.varshape.

E_L

ArrayLike, broadcastable to self.varshape (mV)

-70. * u.mV

\(E_L\)

Resting membrane potential.

C_m

ArrayLike, broadcastable (pF), > 0

250. * u.pF

\(C_m\)

Membrane capacitance.

tau_m

ArrayLike, broadcastable (ms), > 0

10. * u.ms

\(\tau_m\)

Leak time constant.

t_ref_abs

ArrayLike, broadcastable (ms), > 0

2. * u.ms

\(t_{\mathrm{ref,abs}}\)

Absolute membrane clamp duration; quantized to ceil(t_ref_abs / dt) steps.

t_ref_tot

ArrayLike, broadcastable (ms), > 0, >= t_ref_abs elementwise

2. * u.ms

\(t_{\mathrm{ref,tot}}\)

Total spike-suppression duration; quantized to ceil(t_ref_tot / dt) steps.

V_th

ArrayLike, broadcastable (mV)

-55. * u.mV

\(V_{th}\)

Spike threshold potential.

V_reset

ArrayLike, broadcastable (mV), < V_th elementwise

-70. * u.mV

\(V_{reset}\)

Post-spike reset potential.

tau_syn_ex

ArrayLike, broadcastable (ms), > 0

2. * u.ms

\(\tau_{\mathrm{syn,ex}}\)

Excitatory exponential synaptic decay constant.

tau_syn_in

ArrayLike, broadcastable (ms), > 0

2. * u.ms

\(\tau_{\mathrm{syn,in}}\)

Inhibitory exponential synaptic decay constant.

I_e

ArrayLike, broadcastable (pA)

0. * u.pA

\(I_e\)

Constant injected current.

V_initializer

Callable returning values compatible with neuron shape (mV)

Constant(-70. * u.mV)

Initial value generator for membrane potential state.

spk_fun

Callable

ReluGrad()

Surrogate spike output transform.

spk_reset

str (typically 'hard')

'hard'

Reset mode passed to base class.

ref_var

bool

False

Enables explicit boolean refractory flag state.

name

str or None

None

Optional instance name.

Raises:

ValueError – Raised during construction if any hard model constraint is violated: V_reset >= V_th, nonpositive C_m/tau_m/synaptic time constants, nonpositive t_ref_abs/t_ref_tot, or t_ref_abs > t_ref_tot.

Examples

>>> import brainstate
>>> import saiunit as u
>>> from brainpy_state._nest.iaf_psc_exp_htum import iaf_psc_exp_htum
>>> brainstate.environ.set(dt=0.1 * u.ms, t=0.0 * u.ms)
>>> neu = iaf_psc_exp_htum(
...     in_size=(2,),
...     I_e=200. * u.pA,
...     t_ref_abs=1.0 * u.ms,
...     t_ref_tot=2.0 * u.ms,
... )
>>> neu.init_state()
>>> out = neu.update(x=0. * u.pA)
>>> out.shape
(2,)
get_spike(V=None)[source]#

Compute surrogate spike output from membrane voltage.

Scales the membrane potential relative to the threshold/reset gap and passes the result through the configured surrogate nonlinearity self.spk_fun, enabling gradient-based optimisation through spike-generation events.

Parameters:

V (ArrayLike or None, optional) – Membrane potential in mV. If None, uses the current value of self.V.value. Shape must be broadcastable to the neuron state shape. Default is None.

Returns:

spike – Surrogate spike values with the same shape as V (or self.V.value if V is None). For hard thresholding, non-zero values indicate a spike event at this step.

Return type:

ArrayLike

Notes

The scaling is

\[v_{\mathrm{scaled}} = \frac{V - V_{th}}{V_{th} - V_{reset}},\]

which places the threshold at \(v_{\mathrm{scaled}} = 0\) and the reset at \(v_{\mathrm{scaled}} = -1\). The surrogate function spk_fun (e.g., ReluGrad) is then applied element-wise.

init_state(**kwargs)[source]#

Allocate and initialise all dynamic state variables.

Creates HiddenState and ShortTermState fields required by update(). All counters are zero-initialised; last_spike_time is set to -1e7 * u.ms (effectively never spiked).

Parameters:

**kwargs – Absorbed for API compatibility with the base-class signature.

Notes

After this call the following state attributes exist:

  • self.V (HiddenState, mV) — membrane potential, shape varshape.

  • self.i_syn_ex / self.i_syn_in (ShortTermState, pA) — exponential excitatory and inhibitory synaptic current buffers.

  • self.i_0 (ShortTermState, pA) — one-step delayed continuous current buffer.

  • self.refractory_abs_step_count / self.refractory_tot_step_count (ShortTermState, int32) — remaining absolute and total refractory step counters.

  • self.last_spike_time (ShortTermState, ms) — time of most recent spike per neuron; initialised to -1e7 ms.

  • self.refractory (ShortTermState, bool) — present only when ref_var=True; mirrors refractory_tot_step_count > 0.

update(x=Quantity(0., 'pA'))[source]#

Advance the neuron state by one simulation step.

Parameters:

x (ArrayLike, optional) – Continuous current input at the current step in pA. Accepted as a scalar or array broadcastable to the membrane state shape. This value is buffered into i_0 and used for membrane integration on the next call (one-step delay), matching NEST current-event timing. Default is 0. * u.pA.

Returns:

out – Surrogate spike output from get_spike(), with shape equal to the neuron state shape (or batched state shape after init_state()). Values correspond to threshold events detected at this step under total refractory gating.

Return type:

jax.Array

Raises:
  • AttributeError – If called before init_state() has created required state fields (V, synaptic buffers, refractory counters).

  • ValueError – If input x or internal arrays cannot be broadcast to the state shape, or if upstream state/input values carry incompatible units for conversion to mV/pA/ms.