threshold_lin_rate_ipn#
- class brainpy.state.threshold_lin_rate_ipn(in_size, tau=Quantity(10., 'ms'), lambda_=1.0, sigma=1.0, mu=0.0, g=1.0, theta=0.0, alpha=inf, mult_coupling=False, linear_summation=True, rectify_rate=0.0, rectify_output=False, rate_initializer=Constant(value=0.0), noise_initializer=Constant(value=0.0), name=None)#
NEST-compatible input-noise threshold-linear rate neuron.
Implements the NEST
threshold_lin_rate_ipnmodel, an input-noise rate neuron with threshold-linear gain function. This model provides a piecewise-linear activation with lower and upper saturation bounds, commonly used for modeling neural populations with firing rate constraints and additive stochastic drive.Mathematical Description
1. Continuous-Time Stochastic Dynamics
The rate state \(X(t)\) evolves according to the Langevin equation:
\[\tau\,dX(t) = [-\lambda X(t) + \mu + I_\mathrm{net}(t)]\,dt + \sqrt{\tau}\,\sigma\,dW(t),\]where:
\(\tau > 0\) is the time constant (ms).
\(\lambda \ge 0\) is the passive decay rate (dimensionless). Controls exponential relaxation; \(\lambda=0\) yields driftless diffusion.
\(\mu\) is the mean drive (dimensionless, external constant input).
\(\sigma \ge 0\) is the input-noise strength (dimensionless).
\(W(t)\) is a standard Wiener process.
\(I_\mathrm{net}(t)\) is the network input (see below).
2. Threshold-Linear Gain Function
The input nonlinearity \(\phi(h)\) is a threshold-linear function with saturation:
\[\phi(h) = \min(\max(g(h-\theta), 0), \alpha),\]where:
\(g > 0\) is the gain slope (dimensionless).
\(\theta\) is the activation threshold (dimensionless).
\(\alpha > 0\) is the saturation level (dimensionless).
This function is zero for \(h < \theta\), linear with slope \(g\) for \(\theta \le h < \theta + \alpha/g\), and saturates at \(\alpha\) for \(h \ge \theta + \alpha/g\).
3. Network Input Structure
The network input \(I_\mathrm{net}(t)\) is computed according to:
\[I_\mathrm{net}(t) = \phi(I_\mathrm{ex}(t) + I_\mathrm{in}(t)) \quad\text{(if linear\_summation=True)},\]or:
\[I_\mathrm{net}(t) = \phi(I_\mathrm{ex}(t)) + \phi(I_\mathrm{in}(t)) \quad\text{(if linear\_summation=False)},\]where \(I_\mathrm{ex}(t)\) and \(I_\mathrm{in}(t)\) are excitatory and inhibitory branches (sign-separated by event weight).
Note: Unlike the base
rate_neuron_ipnmodel, multiplicative coupling \(H_\mathrm{ex}(X)\), \(H_\mathrm{in}(X)\) is not supported for threshold-linear neurons in NEST. Themult_couplingparameter is accepted for API compatibility but has no effect on dynamics (coupling factors are constant 1.0).4. Discrete-Time Integration (Stochastic Exponential Euler)
For time step \(h=dt\) (in ms), the model uses exact Ornstein-Uhlenbeck integration for the linear part:
\[X_{n+1} = P_1 X_n + P_2 (\mu + I_\mathrm{net,n}) + N\,\xi_n,\]where \(\xi_n\sim\mathcal{N}(0,1)\) is standard Gaussian noise.
For \(\lambda > 0\):
\[P_1 = \exp\left(-\frac{\lambda h}{\tau}\right), \quad P_2 = \frac{1-P_1}{\lambda}, \quad N = \sigma\sqrt{\frac{1-P_1^2}{2\lambda}}.\]For \(\lambda = 0\) (Euler-Maruyama):
\[P_1=1, \quad P_2=\frac{h}{\tau}, \quad N=\sigma\sqrt{\frac{h}{\tau}}.\]5. Update Ordering (Matching NEST ``rate_neuron_ipn_impl.h``)
Per simulation step:
Store outgoing delayed value: current
rateis recorded asdelayed_rate.Draw noise: sample \(\xi_n\sim\mathcal{N}(0,1)\), compute \(\mathrm{noise}_n=\sigma\,\xi_n\).
Propagate intrinsic dynamics: apply stochastic exponential Euler to \(X_n\) with external drive and noise.
Read event buffers: drain delayed events arriving at current step; accumulate instantaneous events.
Apply network input with threshold-linear gain:
linear_summation=True: nonlinearity applied to summed branch input during update: \(I_\mathrm{net}=\phi(I_\mathrm{ex}+I_\mathrm{in})\).linear_summation=False: nonlinearity applied per event during buffering: \(I_\mathrm{net}=\phi(I_\mathrm{ex})+\phi(I_\mathrm{in})\).
Rectification (optional): if
rectify_output=True, clamp \(X_{n+1}\gets\max(X_{n+1},\,\mathrm{rectify\_rate})\).Update state variables:
rate,noise,delayed_rate,instant_rate,_step_count.
6. Numerical Stability and Computational Complexity
Construction enforces \(\tau>0\), \(\lambda\ge 0\), \(\sigma\ge 0\), \(\mathrm{rectify\_rate}\ge 0\).
The threshold-linear gain is evaluated using
np.minimumandnp.maximumfor numerically stable clipping.Per-call cost is \(O(\prod\mathrm{varshape})\) with vectorized NumPy operations in float64.
The exponential Euler scheme is numerically stable for all \(h>0\).
- Parameters:
in_size (
Size) – Population shape (tuple or int). All per-neuron parameters are broadcast toself.varshape.tau (
ArrayLike, optional) – Time constant \(\tau\) (ms). Scalar or array broadcastable toself.varshape. Must be \(>0\). Default:10.0 * u.ms.lambda (
ArrayLike, optional) – Passive decay rate \(\lambda\) (dimensionless). Scalar or array broadcastable toself.varshape. Must be \(\ge 0\). Controls exponential relaxation (\(\lambda=0\) yields driftless diffusion). Default:1.0.sigma (
ArrayLike, optional) – Input-noise scale \(\sigma\) (dimensionless). Scalar or array broadcastable toself.varshape. Must be \(\ge 0\). Default:1.0.mu (
ArrayLike, optional) – Mean drive \(\mu\) (dimensionless). Scalar or array broadcastable toself.varshape. External constant input to the rate dynamics. Default:0.0.g (
ArrayLike, optional) – Gain slope \(g\) (dimensionless) for the threshold-linear function \(\phi(h)=\min(\max(g(h-\theta),0),\alpha)\). Scalar or array broadcastable toself.varshape. Default:1.0.theta (
ArrayLike, optional) – Activation threshold \(\theta\) (dimensionless). The gain function is zero for \(h<\theta\). Scalar or array broadcastable toself.varshape. Default:0.0.alpha (
ArrayLike, optional) – Saturation level \(\alpha\) (dimensionless). The gain function saturates at \(\alpha\) for large inputs. Scalar or array broadcastable toself.varshape. Default:np.inf(no saturation).mult_coupling (
bool, optional) – API compatibility flag. Has no effect on dynamics for threshold-linear neurons (multiplicative coupling factors are constant 1.0). Default:False.linear_summation (
bool, optional) – Controls where the threshold-linear gain is applied. IfTrue, the gain is applied to the sum of excitatory and inhibitory inputs. IfFalse, the gain is applied separately to each input branch (matching NEST event semantics). Default:True.rectify_rate (
ArrayLike, optional) – Lower bound \(X_\mathrm{min}\) for the rate whenrectify_output=True(dimensionless). Scalar or array broadcastable toself.varshape. Must be \(\ge 0\). Default:0.0.rectify_output (
bool, optional) – IfTrue, clamp the rate output to \(X\ge\mathrm{rectify\_rate}\) after each update step. Default:False.rate_initializer (
Callable, optional) – Initializer for theratestate variable \(X_0\). Callable compatible withbraintools.initAPI. Default:braintools.init.Constant(0.0).noise_initializer (
Callable, optional) – Initializer for thenoisestate variable (records last noise sample \(\sigma\,\xi_{n-1}\)). Callable compatible withbraintools.initAPI. Default:braintools.init.Constant(0.0).name (
strorNone, optional) – Module name for identification in hierarchies. IfNone, an auto-generated name is used. Default:None.
Parameter Mapping
The following table maps NEST
threshold_lin_rate_ipnparameters to brainpy.state equivalents:NEST Parameter
brainpy.state
Default
tautau10 ms
lambdalambda_1.0
sigmasigma1.0
mumu0.0
g(gain slope)g1.0
theta(threshold)theta0.0
alpha(saturation)alphainf
mult_couplingmult_coupling(no effect)False
linear_summationlinear_summationTrue
rectify_raterectify_rate0.0
rectify_outputrectify_outputFalse
- rate#
Current rate state \(X_n\) (float64 array of shape
self.varshapeor(batch_size,) + self.varshape).- Type:
brainstate.ShortTermState
- noise#
Last noise sample \(\sigma\,\xi_{n-1}\) (float64 array, same shape as
rate).- Type:
brainstate.ShortTermState
- instant_rate#
Rate value after instantaneous event application (float64 array, same shape as
rate).- Type:
brainstate.ShortTermState
- delayed_rate#
Rate value before current update, used for delayed projections (float64 array, same shape as
rate).- Type:
brainstate.ShortTermState
- _step_count#
Internal step counter for delayed event scheduling (int64 scalar).
- Type:
brainstate.ShortTermState
- _delayed_ex_queue#
Internal queue mapping
step_idxto accumulated excitatory delayed events.- Type:
- _delayed_in_queue#
Internal queue mapping
step_idxto accumulated inhibitory delayed events.- Type:
- Raises:
ValueError – If
tau <= 0,lambda_ < 0,sigma < 0, orrectify_rate < 0.ValueError – If
instant_rate_eventscontain non-zerodelay_steps.ValueError – If
delayed_rate_eventscontain negativedelay_steps.ValueError – If event tuples have length other than 2, 3, or 4.
Notes
Runtime Event Semantics
instant_rate_events: Applied in the current step without delay. Each event can be:A scalar (treated as
ratevalue withweight=1.0).A tuple
(rate, weight)or(rate, weight, delay_steps)or(rate, weight, delay_steps, multiplicity).A dict with keys
'rate'/'coeff'/'value','weight','delay_steps'/'delay','multiplicity'.
delayed_rate_events: Scheduled with integerdelay_steps(units of simulation time step). Same format asinstant_rate_events.Sign convention: events with
weight >= 0contribute to the excitatory branch; events withweight < 0contribute to the inhibitory branch.For
linear_summation=False, event values are transformed by the threshold-linear gain during buffering (matching NEST event handlers).
Comparison to Other Rate Neuron Variants
rate_neuron_ipn: Uses linear or custom gain function with optional multiplicative coupling.threshold_lin_rate_ipnis a special case with fixed threshold-linear gain and no multiplicative coupling.threshold_lin_rate_opn: Output-noise variant (noise applied after nonlinearity) vs. input noise (applied before dynamics propagation).
Failure Modes
No automatic failure handling. Negative time constants, decay rates, or noise parameters are caught at construction by
_validate_parameters.Invalid event formats raise
ValueErrorduring update.Numerical instability is unlikely due to exact OU integration and stable clipping operations, but extreme parameter combinations (very large \(\sigma\), very small \(\tau\)) may lead to rate explosions without
rectify_output=True.
Examples
Example 1: Minimal threshold-linear rate neuron with external drive.
>>> import brainpy.state as bst >>> import saiunit as u >>> model = bst.threshold_lin_rate_ipn( ... in_size=10, tau=20*u.ms, sigma=0.5, g=2.0, theta=1.0 ... ) >>> model.init_all_states(batch_size=1) >>> rate = model(x=0.5) # external drive >>> print(rate.shape) (1, 10)
Example 2: Saturating threshold-linear neuron with rectification.
>>> model = bst.threshold_lin_rate_ipn( ... in_size=5, ... tau=10*u.ms, ... lambda_=2.0, ... g=1.0, theta=0.5, alpha=5.0, ... rectify_rate=0.0, rectify_output=True ... ) >>> model.init_all_states()
Example 3: Update with instantaneous and delayed events.
>>> model = bst.threshold_lin_rate_ipn(in_size=3, tau=10*u.ms, sigma=0.1) >>> model.init_all_states() >>> instant_event = {'rate': 2.0, 'weight': 0.1} >>> delayed_event = {'rate': 1.5, 'weight': -0.05, 'delay_steps': 3} >>> rate = model.update( ... x=0.2, ... instant_rate_events=instant_event, ... delayed_rate_events=delayed_event ... )
References
See also
threshold_lin_rate_opnOutput-noise variant of the threshold-linear rate neuron.
rate_neuron_ipnGeneral input-noise rate neuron with custom gain functions.
lin_rateDeterministic linear rate neuron (
sigma=0, no threshold).
- init_state(**kwargs)[source]#
Initialize all state variables for simulation.
- Parameters:
**kwargs – Unused compatibility parameters accepted by the base-state API.
Notes
This method initializes:
rate: Current rate state \(X_n\).noise: Last noise sample \(\sigma\,\xi_{n-1}\).instant_rate: Rate after instantaneous event application.delayed_rate: Rate before current update (for delayed projections)._step_count: Internal step counter for delay scheduling._delayed_ex_queue,_delayed_in_queue: Delay queues.
All state arrays are initialized as float64 NumPy arrays using the provided initializers.
- property receptor_types#
Receptor type dictionary for projection compatibility.
- Returns:
{'RATE': 0}. Rate neurons have a single unified receptor port for all rate-based inputs. Excitatory vs. inhibitory separation is handled internally via event weight signs.- Return type:
dict[str,int]
Notes
This property is used by projection objects to validate connection targets. Unlike spiking neurons with separate AMPA/GABA receptor ports, rate neurons use sign-based branch routing (
weight >= 0→ excitatory branch,weight < 0→ inhibitory branch).
- property recordables#
List of state variable names that can be recorded during simulation.
- Returns:
['rate', 'noise']. Theratevariable records the current rate state \(X_n\), andnoiserecords the last noise sample \(\sigma\,\xi_{n-1}\).- Return type:
Notes
These variables can be accessed via recording tools in BrainPy for post-simulation analysis of rate dynamics and noise contributions.
- update(x=0.0, instant_rate_events=None, delayed_rate_events=None, noise=None)[source]#
Perform one simulation step of stochastic threshold-linear rate dynamics.
- Parameters:
x (
ArrayLike, optional) – External drive (scalar or array broadcastable toself.varshape). Added tomuas constant forcing. Default is0.0.instant_rate_events (
None,dict,tuple,list, oriterable, optional) – Instantaneous rate events applied in the current step without delay. See class docstring for event format. Default isNone.delayed_rate_events (
None,dict,tuple,list, oriterable, optional) – Delayed rate events scheduled with integerdelay_steps(units of simulation time step). See class docstring for event format. Default isNone.noise (
ArrayLike, optional) – Externally supplied noise sample \(\xi_n\) (scalar or array broadcastable to state shape). IfNone(default), draws \(\xi_n\sim\mathcal{N}(0,1)\) internally.
- Returns:
rate_new – Updated rate state \(X_{n+1}\) (float64 array of shape
self.rate.value.shape).- Return type:
np.ndarray
Notes
Update algorithm:
Collect input contributions:
Delayed events arriving at current step (from internal queues).
Newly scheduled delayed events with
delay_steps=0.Instantaneous events.
Delta inputs (sign-separated into excitatory/inhibitory).
Current inputs via
sum_current_inputs(x, rate).
Compute propagator coefficients:
For \(\lambda>0\):
\[P_1 = \exp(-\lambda h/\tau), \quad P_2 = (1-P_1)/\lambda, \quad N = \sigma\sqrt{(1-P_1^2)/(2\lambda)}.\]For \(\lambda=0\): \(P_1=1\), \(P_2=h/\tau\), \(N=\sigma\sqrt{h/\tau}\).
Propagate intrinsic dynamics:
\[X' = P_1 X_n + P_2(\mu + \mu_\mathrm{ext}) + N\,\xi_n.\]Apply network input with threshold-linear gain:
linear_summation=True: \(X' \gets X' + P_2\,\phi(I_\mathrm{ex}+I_\mathrm{in})\).linear_summation=False: \(X' \gets X' + P_2\,[\phi(I_\mathrm{ex})+\phi(I_\mathrm{in})]\).
where \(\phi(h)=\min(\max(g(h-\theta),0),\alpha)\).
Apply optional output rectification: \(X_{n+1}\gets\max(X',\,\mathrm{rectify\_rate})\).
Update state variables:
rate,noise,delayed_rate,instant_rate,_step_count.
Numerical stability: The threshold-linear gain uses
np.minimumandnp.maximumfor stable clipping. The exponential Euler scheme usesnp.expm1for numerically stable evaluation of \(1-e^{-x}\) and handles the \(\lambda=0\) limit explicitly.Failure modes: No automatic failure handling. Negative time constants, decay rates, or noise parameters are caught at construction by
_validate_parameters. Invalid event formats raiseValueError.