gauss_rate_ipn#

class brainpy.state.gauss_rate_ipn(in_size, tau=Quantity(10., 'ms'), lambda_=1.0, sigma=0.0, mu=0.0, g=1.0, 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 gauss_rate_ipn nonlinear rate neuron with input noise.

Implements a stochastic rate-based neuron with Gaussian gain function and input noise, matching NEST’s gauss_rate_ipn model. The dynamics combine passive decay, mean drive, network input (processed through a Gaussian nonlinearity), and additive Brownian noise.

1. Model equations

The stochastic differential equation governing the rate dynamics is:

\[\tau\,dX(t)= \left[-\lambda X(t)+\mu+I_{\mathrm{net}}(t)\right]dt +\left[\sqrt{\tau}\,\sigma\right]dW(t),\]

where \(W(t)\) is a standard Wiener process and \(I_{\mathrm{net}}(t)\) is the effective network input after applying the Gaussian gain function \(\phi(h)\):

\[\phi(h)=g\exp\left(-\frac{(h-\mu)^2}{2\sigma^2}\right).\]

The gain function produces a bell-shaped response centered at \(\mu\) with width controlled by \(\sigma\) and amplitude scaled by \(g\).

2. NEST parameter coupling (critical implementation detail)

NEST’s gauss_rate_ipn model uses the same parameter names mu and sigma for two distinct purposes:

  1. SDE parameters: mu is the mean drive in the drift term; sigma scales the diffusion coefficient (input noise strength).

  2. Gain-function parameters: mu is the Gaussian center (location of peak response); sigma is the Gaussian width (standard deviation of the bell curve).

This implementation preserves NEST’s dual-role design. Consequently:

  • The default sigma=0.0 from NEST (no input noise) is retained.

  • When sigma=0, the gain function becomes undefined at h=mu (0/0 form), potentially producing NaN values, matching NEST behavior.

  • Both roles share the same parameter instance, so changes affect both the SDE noise term and the gain-function shape.

3. Update ordering (matching NEST ``rate_neuron_ipn_impl.h``)

Per simulation step of duration dt:

  1. Store outgoing delayed value: Current rate becomes delayed_rate.

  2. Draw noise sample: Compute noise = sigma * xi where xi ~ N(0,1).

  3. Propagate intrinsic dynamics: Apply stochastic exponential Euler (reduces to Euler-Maruyama when lambda=0):

    \[X_{\mathrm{new}} = e^{-\lambda h/\tau}X_{\mathrm{prev}} + \frac{1-e^{-\lambda h/\tau}}{\lambda}(\mu + \mu_{\mathrm{ext}}) + \sqrt{\frac{1-e^{-2\lambda h/\tau}}{2\lambda}}\,\sigma\xi,\]

    where \(h=dt\) and special handling applies when lambda=0.

  4. Drain delayed queues: Retrieve and sum delayed excitatory/inhibitory contributions scheduled for the current step.

  5. Process instantaneous events: Parse and accumulate instant_rate_events and zero-delay entries from delayed_rate_events.

  6. Apply Gaussian gain function:

    • linear_summation=True: Sum all network inputs, then apply \(\phi\).

    • linear_summation=False: Apply \(\phi\) to each event value before summation (nonlinearity applied during event buffering).

  7. Include multiplicative coupling (if enabled): Scale excitatory/inhibitory branches by state-dependent factors (trivially 1.0 for this model).

  8. Apply rectification (if enabled): Clamp rate >= rectify_rate.

  9. Store outgoing instantaneous value: Updated rate becomes instant_rate for immediate event transmission.

4. Assumptions and constraints

Mathematical validity:

  • tau > 0 (time constant must be positive).

  • lambda >= 0 (passive decay rate must be non-negative).

  • sigma >= 0 (noise/gain width cannot be negative).

  • When sigma=0, the gain function is undefined at h=mu, matching NEST’s potential NaN generation.

Event semantics:

  • Events are specified as (rate, weight) tuples, (rate, weight, delay_steps) triples, (rate, weight, delay_steps, multiplicity) 4-tuples, or dicts with 'rate', 'weight', 'delay_steps', 'multiplicity' keys.

  • instant_rate_events must have delay_steps=0 (enforced with exception).

  • delayed_rate_events support integer delay_steps >= 0.

  • Negative weights create inhibitory contributions (sign-based routing).

5. Computational implications

Integration method: Stochastic exponential Euler is exact for linear drift with additive noise (Ornstein-Uhlenbeck process) but approximate when network input is present. Accuracy degrades if dt is not sufficiently small relative to tau/lambda.

Delay queue management: Each delayed event is stored in a dictionary keyed by target step index. Memory scales with the number of active delayed events. Unbounded delays can lead to memory growth.

Gaussian evaluation: Computing \(\exp(-(h-\mu)^2/(2\sigma^2))\) per event (when linear_summation=False) or per step (when linear_summation=True) is vectorized via NumPy. For sigma=0, evaluations at h=mu produce NaN.

Parameters:
  • in_size (Size) – Population shape specification. Determines self.varshape and the shape of state variables rate, noise, etc. Can be an integer (1D population) or tuple of integers (multi-dimensional population).

  • tau (Quantity[ms], optional) – Time constant \(\tau\) of rate dynamics. Must be positive. Controls the temporal scale of both drift and diffusion terms. Default 10 ms.

  • lambda (float, optional) – Passive decay rate \(\lambda \ge 0\). When lambda=0, dynamics reduce to driftless Brownian motion with external drive. Larger values produce stronger relaxation toward the mean drive. Default 1.0.

  • sigma (float, optional) –

    Shared dual-role parameter (matching NEST):

    1. Diffusion coefficient: Scales input noise as \(\sqrt{\tau}\sigma dW(t)\).

    2. Gaussian width: Standard deviation of the gain function \(\phi(h)\).

    Must be non-negative. NEST default 0.0 (no noise, but gain function becomes undefined at h=mu). Default 0.0.

  • mu (float, optional) –

    Shared dual-role parameter (matching NEST):

    1. Mean drive: Constant drift term in the SDE.

    2. Gaussian center: Location of peak response in \(\phi(h)\).

    Default 0.0.

  • g (float, optional) – Gain amplitude parameter. Scales the maximum value of the Gaussian nonlinearity \(\phi(h)\). When g=1, peak response is 1.0 at h=mu. Default 1.0.

  • mult_coupling (bool, optional) – Enable multiplicative coupling (state-dependent input scaling). For gauss_rate_ipn, the coupling factors are trivially 1.0 (no effect), but the parameter is retained for NEST API compatibility. Default False.

  • linear_summation (bool, optional) –

    NEST switch controlling where the Gaussian nonlinearity is applied:

    • True (default): Sum all network inputs first, then apply \(\phi\) to the total. Results in \(\phi(\sum h_i w_i)\).

    • False: Apply \(\phi\) to each event’s rate value during buffering, then sum the transformed contributions. Results in \(\sum \phi(h_i) w_i\).

    Default True.

  • rectify_rate (float, optional) – Lower bound for output clamping when rectify_output=True. Must be non-negative. Default 0.0.

  • rectify_output (bool, optional) – If True, apply rectification rate = max(rate, rectify_rate) after all updates. Prevents negative firing rates. Default False.

  • rate_initializer (Callable, optional) – Initializer for the rate state variable. Called with (shape, batch_size) to produce initial firing rates. Default braintools.init.Constant(0.0).

  • noise_initializer (Callable, optional) – Initializer for the noise state variable (stores last noise sample). Default braintools.init.Constant(0.0).

  • name (str or None, optional) – Module identifier. Default None.

Parameter Mapping

Table 21 Parameter mapping to NEST and model symbols#

Parameter

Default

Math symbol

Semantics / NEST correspondence

tau

10 ms

\(\tau\)

Time constant of rate dynamics (NEST: tau).

lambda_

1.0

\(\lambda\)

Passive decay rate (NEST: lambda in template parameters).

sigma

0.0

\(\sigma\)

Dual role: input-noise scale in SDE and Gaussian width in \(\phi(h)\) (NEST: sigma).

mu

0.0

\(\mu\)

Dual role: mean drive in SDE and Gaussian center in \(\phi(h)\) (NEST: mu).

g

1.0

\(g\)

Gain amplitude of Gaussian nonlinearity (NEST: g in template nonlinearity).

rectify_rate

0.0

\(r_{\mathrm{min}}\)

Lower bound for output rectification (NEST: rectify_rate).

rectify_output

False

Enable output clamping to \(\ge r_{\mathrm{min}}\) (NEST: rectify_output).

linear_summation

True

Apply \(\phi\) to sum (True) vs. per-event (False) (NEST: linear_summation).

mult_coupling

False

Enable multiplicative coupling (no-op for this model, NEST compatibility only).

rate#

Current firing rate of shape self.varshape. Updated each step.

Type:

brainstate.ShortTermState

noise#

Last noise sample \(\sigma\xi\) of shape self.varshape.

Type:

brainstate.ShortTermState

instant_rate#

Copy of rate after update, used for zero-delay event transmission.

Type:

brainstate.ShortTermState

delayed_rate#

Copy of rate before update, used for non-zero delay event transmission.

Type:

brainstate.ShortTermState

Notes

Runtime event semantics:

  • instant_rate_events: Applied in the current step with zero delay. Format: scalar, (rate, weight), (rate, weight, 0), (rate, weight, 0, multiplicity), or dict with keys 'rate', 'weight', 'delay_steps' (must be 0), 'multiplicity'.

  • delayed_rate_events: Scheduled for future delivery based on delay_steps. Format: same as above, but delay_steps can be any non-negative integer.

  • x: External current input (additive to mu), summed via sum_current_inputs(x, rate).

Failure modes:

  • NaN generation: When sigma=0 and network input h exactly equals mu, the Gaussian \(\phi(h) = g \exp(0/0)\) is undefined. NEST also produces NaN in this case.

  • Non-increasing ``amplitude_times``: Raises ValueError during construction if delay queues are misconfigured (internal logic error).

  • Invalid event delays: instant_rate_events with non-zero delay_steps raise ValueError. Negative delays in delayed_rate_events also raise ValueError.

Relationship to other models:

  • gauss_rate_ipn is the NEST input-noise template instantiated with Gaussian nonlinearities. The base template rate_neuron_ipn supports arbitrary input nonlinearities and multiplicative-coupling functions.

  • gauss_rate_opn is the output-noise variant (noise added after nonlinearity).

  • For linear gain (g * h), use lin_rate_ipn instead.

Examples

Minimal usage with default parameters:

>>> import brainpy_state as bpst
>>> import saiunit as u
>>> import brainstate
>>> brainstate.environ.set_dt(0.1 * u.ms)
>>> neuron = bpst.gauss_rate_ipn(in_size=100)
>>> neuron.init_all_states()
>>> # Simulate 10 steps with no input
>>> for _ in range(10):
...     rate = neuron.update()

With network events and external drive:

>>> neuron = bpst.gauss_rate_ipn(
...     in_size=50,
...     tau=20.0 * u.ms,
...     lambda_=1.5,
...     sigma=0.5,
...     mu=0.0,
...     g=2.0,
...     linear_summation=True,
...     rectify_output=True,
...     rectify_rate=0.0,
... )
>>> neuron.init_all_states()
>>> # Apply instantaneous rate input and delayed event
>>> rate = neuron.update(
...     x=1.0,  # external drive
...     instant_rate_events=(0.5, 1.0),  # (rate, weight)
...     delayed_rate_events=(1.0, 2.0, 5),  # (rate, weight, delay_steps)
... )

References

init_state(**kwargs)[source]#

Initialize all state variables and internal delay queues.

Creates and initializes firing rate, noise, and auxiliary state variables required for event-driven simulation with delayed transmission.

Parameters:

**kwargs – Unused compatibility parameters accepted by the base-state API.

Notes

This method initializes:

  • self.rate: Current firing rate, initialized via rate_initializer.

  • self.noise: Last noise sample, initialized via noise_initializer.

  • self.instant_rate: Copy of rate for zero-delay transmission.

  • self.delayed_rate: Copy of rate for delayed transmission.

  • self._step_count: Internal step counter (int64 scalar).

  • self._delayed_ex_queue: Dictionary {step_idx: excitatory_contribution} for delayed excitatory events.

  • self._delayed_in_queue: Dictionary {step_idx: inhibitory_contribution} for delayed inhibitory events.

All queues are empty at initialization. The step counter starts at 0.

Examples

>>> neuron = bpst.gauss_rate_ipn(in_size=100)
>>> neuron.init_state()
>>> neuron.rate.value.shape
(100,)
property receptor_types#

Dictionary mapping receptor port names to integer indices.

Returns:

{'RATE': 0} — single receptor type for rate-based input.

Return type:

dict

Notes

NEST uses receptor types to distinguish synaptic input channels (e.g., AMPA, NMDA, GABA). For gauss_rate_ipn, only one generic 'RATE' receptor is defined. This is used for NEST API compatibility but has no functional effect in this implementation (excitatory/inhibitory routing is based on weight sign, not receptor type).

property recordables#

List of state variable names that can be recorded during simulation.

Returns:

['rate', 'noise'] — firing rate and noise sample state variables.

Return type:

list of str

Notes

These names correspond to attributes that can be monitored by recording devices or logged during simulation. Accessing neuron.rate.value and neuron.noise.value retrieves the current values.

update(x=0.0, instant_rate_events=None, delayed_rate_events=None, noise=None)[source]#

Advance dynamics by one time step using stochastic exponential Euler.

Implements the complete NEST gauss_rate_ipn update cycle: store delayed output, draw noise, integrate SDE, process events, apply Gaussian nonlinearity, and update firing rate.

Parameters:
  • x (ArrayLike, optional) – External additive drive (current input), broadcast to self.varshape. Added to mu in the drift term. Can be scalar, array-like, or have saiunit units (automatically converted). Default 0.0.

  • instant_rate_events (scalar, tuple, list of tuples, or None, optional) –

    Rate events applied in the current step with zero delay. Each event can be:

    • Scalar: Interpreted as (value, weight=1.0).

    • (rate, weight): Rate value and synaptic weight.

    • (rate, weight, delay_steps): Must have delay_steps=0 (raises ValueError otherwise).

    • (rate, weight, delay_steps, multiplicity): 4-tuple with multiplicity factor.

    • Dict with keys 'rate', 'weight', 'delay_steps', 'multiplicity'.

    Weights are signed: positive for excitatory, negative for inhibitory. Default None (no events).

  • delayed_rate_events (scalar, tuple, list of tuples, or None, optional) – Rate events scheduled for future delivery based on delay_steps. Format is the same as instant_rate_events, but delay_steps can be any non-negative integer. Zero-delay events are applied immediately. Negative delays raise ValueError. Default None.

  • noise (ArrayLike or None, optional) – Optional external noise sample \(\xi\) to use instead of drawing from \(N(0,1)\). Must be broadcast-compatible with self.varshape. When None, standard normal noise is drawn internally. Useful for reproducible testing. Default None.

Returns:

rate_new – Updated firing rate of shape matching self.rate.value.shape, after applying all dynamics, network input, Gaussian nonlinearity, multiplicative coupling, and optional rectification.

Return type:

ndarray

Raises:

ValueError

  • If any instant_rate_events entry specifies non-zero delay_steps. - If any delayed_rate_events entry has negative delay_steps.

Notes

Integration method: Stochastic exponential Euler for the linear part of the SDE, with network input and Gaussian nonlinearity applied as an additive perturbation scaled by the integration factor P2.

Update propagation coefficients:

  • P1 = exp(-lambda * dt / tau): State persistence factor.

  • P2 = (1 - exp(-lambda * dt / tau)) / lambda: Input integration factor (reduces to dt / tau when lambda=0).

  • input_noise_factor = sqrt((1 - exp(-2*lambda*dt/tau)) / (2*lambda)): Diffusion coefficient (reduces to sqrt(dt / tau) when lambda=0).

Gaussian nonlinearity application:

  • linear_summation=True: Compute phi(sum(excitatory) + sum(inhibitory)).

  • linear_summation=False: Each event’s rate is transformed during buffering, so summed values already include phi applied per event.

Multiplicative coupling: For gauss_rate_ipn, factors H_ex and H_in are trivially 1.0 (no-op), but the code path is present for NEST compatibility.

Rectification: If rectify_output=True, the final rate is clamped to max(rate_new, rectify_rate).

State side effects: Updates self.rate, self.noise, self.delayed_rate, self.instant_rate, self._step_count, and modifies delay queues self._delayed_ex_queue and self._delayed_in_queue.