iaf_psc_alpha_ps#
- class brainpy.state.iaf_psc_alpha_ps(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_alpha_pswith precise spike timing.Description
iaf_psc_alpha_psis a current-based leaky integrate-and-fire neuron with alpha-shaped excitatory/inhibitory postsynaptic currents (PSCs), fixed absolute refractoriness, and off-grid spike/event timing. The implementation matches NESTmodels/iaf_psc_alpha_ps.{h,cpp}semantics: event-driven mini-step splitting inside each globaldtinterval, exact linear propagators for alpha states, and bisection-based sub-step threshold-time localization.1. Continuous-Time Model and Alpha Current State-Space
Define \(U = V_m - E_L\) and \(I_\mathrm{syn}=I_\mathrm{ex}+I_\mathrm{in}\). Subthreshold dynamics are
\[\frac{dU}{dt} = -\frac{U}{\tau_m} + \frac{I_\mathrm{syn} + I_e + y_\mathrm{in}}{C_m}.\]For each channel \(X\in\{\mathrm{ex},\mathrm{in}\}\), alpha PSCs use a two-state system:
\[\frac{d\,dI_X}{dt} = -\frac{dI_X}{\tau_{\mathrm{syn},X}}, \qquad \frac{dI_X}{dt} = dI_X - \frac{I_X}{\tau_{\mathrm{syn},X}}.\]This realizes normalized kernel
\[i_X(t) = \frac{e}{\tau_{\mathrm{syn},X}} t e^{-t/\tau_{\mathrm{syn},X}} \Theta(t),\]so a spike weight \(w\) (pA) is injected into derivative states as \(dI_\mathrm{ex}\leftarrow dI_\mathrm{ex}+\frac{e}{\tau_{\mathrm{syn,ex}}}w\) for \(w\ge 0\) and \(dI_\mathrm{in}\leftarrow dI_\mathrm{in}+\frac{e}{\tau_{\mathrm{syn,in}}}w\) for \(w<0\) (inhibitory channel stays negative by sign convention).
2. Exact Mini-Step Propagation and Precise Threshold Crossing
For each local interval \(\Delta t\) between two ordered event offsets, the code uses exact closed-form updates:
\[dI_X(t+\Delta t) = e^{-\Delta t/\tau_{\mathrm{syn},X}} dI_X(t),\]\[I_X(t+\Delta t) = e^{-\Delta t/\tau_{\mathrm{syn},X}} \big(I_X(t) + \Delta t\, dI_X(t)\big),\]\[U(t+\Delta t) = U(t) + \left(e^{-\Delta t/\tau_m}-1\right)U(t) + P_{30}(I_e+y_\mathrm{in}) + \sum_X \left(P_{31,X} dI_X(t) + P_{32,X} I_X(t)\right),\]with \(P_{30}=\tau_m(1-e^{-\Delta t/\tau_m})/C_m\) and \(P_{31,X}, P_{32,X}\) evaluated by
iaf_psc_alpha._alpha_propagator_p31_p32()(including stable handling near \(\tau_m\approx\tau_{\mathrm{syn},X}\)).If \(U\) crosses \(U_{th}=V_{th}-E_L\) inside a mini-step, the crossing time solves \(f(\delta)=U(\delta)-U_{th}=0\) using bounded bisection (64 iterations), producing off-grid spike offset
spike_off = dt - (local_time + delta).3. Event Ordering, Refractory Pseudo-Event, and Timing Convention
Off-grid events are sorted by
offsetin descending order, whereoffsetis measured from the right boundary of the current step (\(0\) at step end, \(dt\) at step start). Each neuron can also insert a refractory-release pseudo-event at storedlast_spike_offsetwhenstep_idx + 1 - last_spike_step == ceil(t_ref / dt).On spike emission:
membrane state is reset to
V_reset,refractory flag is set,
last_spike_step,last_spike_offset,last_spike_timeare updated with precise sub-step timing.
4. Assumptions, Constraints, and Computational Implications
Construction constraints enforce
C_m > 0,tau_m > 0,tau_syn_ex > 0,tau_syn_in > 0, andV_reset < V_th.If
V_minis set,V_reset >= V_minis required.Runtime requires
ceil(t_ref / dt) >= 1; otherwise update fails.xis ring-buffered current input: values supplied at stepnare consumed asy_inputin stepn+1.Update is vectorized over
self.varshapeusing array operations. WithKwithin-step events, cost is \(O(|\mathrm{varshape}| \cdot K)\), plus root-search work when threshold is crossed.
- Parameters:
in_size (
Size) – Population shape specification. All model parameters are broadcast toself.varshapederived fromin_size.E_L (
ArrayLike, optional) – Resting potential \(E_L\) in mV. Scalar or array-like broadcastable toself.varshape. Default is-70. * u.mV.C_m (
ArrayLike, optional) – Membrane capacitance \(C_m\) in pF. Must be strictly positive after broadcasting toself.varshape. Default is250. * u.pF.tau_m (
ArrayLike, optional) – Membrane time constant \(\tau_m\) in ms. Must be strictly positive. Default is10. * u.ms.t_ref (
ArrayLike, optional) – Absolute refractory time \(t_{ref}\) in ms. Converted at runtime to grid steps viaceil(t_ref / dt). Must yield at least one step. 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. Must satisfyV_reset < V_thelementwise. Default is-70. * u.mV.tau_syn_ex (
ArrayLike, optional) – Excitatory alpha time constant \(\tau_{\mathrm{syn,ex}}\) in ms. Strictly positive. Default is2. * u.ms.tau_syn_in (
ArrayLike, optional) – Inhibitory alpha time constant \(\tau_{\mathrm{syn,in}}\) in ms. Strictly positive. Default is2. * u.ms.I_e (
ArrayLike, optional) – Constant external current \(I_e\) in pA, broadcastable toself.varshape. Added in each mini-step membrane update. Default is0. * u.pA.V_min (
ArrayLikeorNone, optional) – Optional lower voltage clamp \(V_{min}\) in mV. When provided, membrane candidates are clipped bymax(V, V_min)before threshold tests.Nonedisables clipping. Default isNone.V_initializer (
Callable, optional) – Initializer for membrane stateVused ininit_state(). Must return values unit-compatible with mV. Default isbraintools.init.Constant(-70. * u.mV).spk_fun (
Callable, optional) – Surrogate spike function used byget_spike()and returned byupdate(). It receives normalized threshold distance and returns a spike-like array broadcastable to neuron shape. Default isbraintools.surrogate.ReluGrad().spk_reset (
str, optional) – Reset policy passed toNeuron.'hard'matches NEST hard-reset behavior. Default is'hard'.ref_var (
bool, optional) – IfTrue, creates exposed stateself.refractorymirroringself.is_refractoryfor inspection. Default isFalse.
Parameter Mapping
Table 5 Parameter mapping to model symbols# Parameter
Type / shape / unit
Default
Math symbol
Semantics
in_sizeSize; scalar/tuplerequired
–
Defines population shape
self.varshape.E_LArrayLike, broadcastable to
self.varshape(mV)-70. * u.mV\(E_L\)
Resting potential; membrane offset origin.
C_mArrayLike, broadcastable (pF),
> 0250. * u.pF\(C_m\)
Membrane capacitance in all propagators.
tau_mArrayLike, broadcastable (ms),
> 010. * u.ms\(\tau_m\)
Membrane leak time constant.
t_refArrayLike, broadcastable (ms), runtime
ceil(t_ref/dt) >= 12. * 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 reset levels.
tau_syn_exandtau_syn_inArrayLike, broadcastable (ms), each
> 02. * u.ms\(\tau_{\mathrm{syn,ex}}\), \(\tau_{\mathrm{syn,in}}\)
Alpha PSC decay constants.
I_eArrayLike, broadcastable (pA)
0. * u.pA\(I_e\)
Constant injected current.
V_minArrayLike broadcastable (mV) or
NoneNone\(V_{min}\)
Optional lower membrane bound.
V_initializerCallable returning mV-compatible values
Constant(-70. * u.mV)–
Initial membrane state initializer.
spk_funCallable
ReluGrad()–
Surrogate spike output nonlinearity.
spk_resetstr
'hard'–
Reset mode inherited from base
Neuron.ref_varbool
False–
Allocate exposed
refractorymirror state.namestr | None
None–
Optional node name.
- Raises:
ValueError – If parameter constraints are violated (for example
C_m <= 0,tau_m <= 0,tau_syn_ex <= 0,tau_syn_in <= 0,V_reset >= V_th,V_reset < V_min), if refractory duration in steps is below one, or if anyspike_eventsoffset is outside[0, dt].TypeError – If supplied quantities are not unit-compatible with expected units (mV, ms, pA, pF) during conversion.
KeyError – If simulation context keys such as
tordtare missing whenupdate()is called.AttributeError – If
update()is called beforeinit_state()creates required states (for exampleVor synaptic buffers).
Notes
spike_eventsaccepts(offset, weight)tuples or{'offset': ..., 'weight': ...}dicts. Offsets are in ms and measured from the right step boundary (NEST convention).Positive event weights update the excitatory derivative state; negative event weights update inhibitory derivative state.
The implementation computes all internal propagators in
float64NumPy space and writes back BrainUnit states afterward.last_spike_timestores precise absolute spike time in ms and is stop-gradient wrapped.
Examples
>>> import brainpy >>> import brainstate >>> import saiunit as u >>> with brainstate.environ.context(dt=0.1 * u.ms): ... neu = brainpy.state.iaf_psc_alpha_ps(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_ps(in_size=1) ... neu.init_state() ... ev = [{'offset': 0.08 * u.ms, 'weight': 120.0 * u.pA}] ... with brainstate.environ.context(t=0.0 * u.ms): ... _ = neu.update(spike_events=ev)
References
- 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 - V_reset)).- 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'), spike_events=None)[source]#
Advance one simulation step with optional precise within-step events.
- Parameters:
x (
ArrayLike, optional) – Continuous external current in pA for the current global step. Value is accumulated throughsum_current_inputs()and written toself.y_inputfor use in the next step (one-step buffering). Scalar or array-like broadcastable toself.V.value.shape. Default is0. * u.pA.spike_events (
Iterable[tuple[Any,Any] | dict[str,Any]]orNone, optional) – Optional off-grid spike events within thisdtstep. Each item is either(offset, weight)or{'offset': ..., 'weight': ...}, whereoffsetis in ms from the right step edge andweightis in pA.offsetmust satisfy0 <= offset <= dt. Positive weights target excitatory alpha derivative state; negative weights target inhibitory alpha derivative state.Nonemeans no extra within-step events. On-grid delta inputs collected fromsum_delta_inputs()are still included atoffset=0.
- Returns:
out – Spike output from
get_spike()with shapeself.V.value.shape. Values are surrogate spikes fromself.spk_funevaluated on threshold-scaled membrane potential after precise-time integration and event handling.- Return type:
jax.Array- Raises:
ValueError – If computed refractory steps satisfy
ceil(t_ref / dt) < 1or if any event offset is outside[0, dt].KeyError – If simulation context values
tordtare missing.TypeError – If provided quantities are not unit-compatible with ms/pA during conversion of
xorspike_events.AttributeError – If called before required states are initialized via
init_state().