tanh_rate_opn#

class brainpy.state.tanh_rate_opn(in_size, tau=Quantity(10., 'ms'), sigma=1.0, mu=0.0, g=1.0, theta=0.0, mult_coupling=False, linear_summation=True, rate_initializer=Constant(value=0.0), noise_initializer=Constant(value=0.0), noisy_rate_initializer=Constant(value=0.0), name=None)#

NEST-compatible tanh_rate_opn nonlinear rate neuron with output noise.

Deterministic rate model with output-coupled additive noise and hyperbolic-tangent nonlinearity applied to network inputs, matching NEST’s rate_neuron_opn template instantiated with tanh_rate gain function.

1. Model equations

The internal state \(X(t)\) evolves deterministically

\[\tau\frac{dX(t)}{dt}=-X(t)+\mu+\phi(\cdot),\]

where the input nonlinearity is

\[\phi(h)=\tanh(g(h-\theta)).\]

The observed rate includes white noise added at the output:

\[X_\mathrm{noisy}(t)=X(t)+\sqrt{\frac{\tau}{h}}\sigma\xi(t),\]

with \(\xi(t) \sim \mathcal{N}(0,1)\) and \(h=dt\) the simulation step size. The noise is scaled by \(\sqrt{\tau/h}\) so that its variance is independent of the step size, matching NEST’s implementation.

2. Numerical integration

Deterministic exponential Euler integration:

\[\begin{split}P_1 &= \exp(-h / \tau), \\ P_2 &= 1 - P_1, \\ X_{n+1} &= P_1 X_n + P_2 \left[\mu + \phi(\cdot)\right].\end{split}\]

The noisy rate for outgoing communication is computed as

\[X_{\mathrm{noisy},n} = X_n + \sqrt{\frac{\tau}{h}} \sigma \xi_n.\]

3. Update ordering (matching NEST ``rate_neuron_opn`` with tanh)

Each simulation step proceeds as follows:

  1. Draw noise = sigma * xi from the standard normal distribution.

  2. Build noisy_rate from the current rate by adding scaled noise.

  3. Store noisy_rate as delayed outgoing value (for delayed connections).

  4. Propagate deterministic intrinsic dynamics with exponential Euler.

  5. Add event-driven input contributions:

    • linear_summation=True: apply tanh to summed branch inputs.

    • linear_summation=False: apply tanh per event before summation.

  6. Store noisy_rate as instantaneous outgoing value (for instant connections).

4. Timing semantics, assumptions, and constraints

  • Noise is added to the output only (internal state \(X\) remains deterministic).

  • Noise variance is independent of step size \(h\) due to \(\sqrt{\tau/h}\) scaling.

  • Multiplicative coupling factors are fixed to 1 for tanh_rate models (mult_coupling has no effect; kept for NEST API compatibility).

  • Unlike input-noise models, there is no rectification option for output-noise models.

5. Computational implications

Per update() call:

  • Random number generation: \(O(\prod \mathrm{varshape})\).

  • Exponential operations for \(P_1, P_2\) (single exp call).

  • Event processing is linear in number of events per step.

  • Broadcasting parameters and inputs over self.varshape.

Parameters:
  • in_size (Size) – Population shape specification consumed by brainstate.nn.Dynamics. Determines output rate array shape.

  • tau (ArrayLike, optional) – Time constant \(\tau\) of rate dynamics. Must be positive. Accepts scalar or array broadcast to self.varshape. Unitful values are converted to ms; unitless are interpreted as ms. Default 10.0 * u.ms.

  • sigma (ArrayLike, optional) – Output noise scale (dimensionless). Must be non-negative. Scales the Gaussian white noise added to the output. Broadcast to self.varshape. Default 1.0.

  • mu (ArrayLike, optional) – Mean drive \(\mu\) (dimensionless). Constant additive input. Broadcast to self.varshape. Default 0.0.

  • g (ArrayLike, optional) – Gain of tanh nonlinearity (dimensionless). Controls steepness of tanh. Broadcast to self.varshape. Default 1.0.

  • theta (ArrayLike, optional) – Threshold (horizontal shift) of tanh nonlinearity (dimensionless). Shifts the input \(h\) before applying tanh. Broadcast to self.varshape. Default 0.0.

  • mult_coupling (bool, optional) – Kept for NEST compatibility. For tanh_rate models, multiplicative coupling factors are identically 1, so this switch has no effect. Default False.

  • linear_summation (bool, optional) – Controls nonlinearity application order. If True, sum inputs then apply tanh. If False, apply tanh per event then sum weighted results. Default True.

  • rate_initializer (Callable, optional) – Initializer for state variable rate. Called as rate_initializer(self.varshape, batch_size) in init_state(). Default braintools.init.Constant(0.0).

  • noise_initializer (Callable, optional) – Initializer for state variable noise (recording). Default braintools.init.Constant(0.0).

  • noisy_rate_initializer (Callable, optional) – Initializer for state variable noisy_rate (output with noise). Default braintools.init.Constant(0.0).

  • name (str or None, optional) – Module name passed to brainstate.nn.Dynamics.

Parameter Mapping

Table 20 Parameter mapping to model symbols#

Parameter

Default

Math symbol

Semantics

tau

10.0 * u.ms

\(\tau\)

Time constant of rate dynamics (ms).

sigma

1.0

\(\sigma\)

Output noise scale (dimensionless, >= 0).

mu

0.0

\(\mu\)

Constant mean drive (dimensionless).

g

1.0

\(g\)

Gain of tanh nonlinearity (dimensionless).

theta

0.0

\(\theta\)

Horizontal shift of tanh nonlinearity (dimensionless).

Raises:
  • ValueError – If tau <= 0 or sigma < 0.

  • ValueError – If instant_rate_events specify non-zero delay_steps, or if delayed_rate_events specify negative delay_steps.

See also

tanh_rate_ipn

Input-noise variant of tanh_rate.

sigmoid_rate_opn

Sigmoid nonlinearity with output noise.

lin_rate_opn

Linear (identity) nonlinearity with output noise.

gauss_rate_opn

Gaussian nonlinearity with output noise.

Notes

Runtime events:

  • instant_rate_events : applied in the current step (delay_steps=0).

  • delayed_rate_events : scheduled with integer delay_steps >= 0.

Event format supports dict or tuple (identical to tanh_rate_ipn):

  • Dict: {'rate': value, 'weight': w, 'delay_steps': d, 'multiplicity': m}

  • Tuple: (rate, weight), (rate, weight, delay_steps), or (rate, weight, delay_steps, multiplicity)

References

Examples

>>> import brainpy
>>> import brainstate
>>> import saiunit as u
>>> import jax.numpy as jnp
>>> with brainstate.environ.context(dt=0.1 * u.ms):
...     net = brainpy.state.tanh_rate_opn(
...         in_size=10,
...         tau=10.0 * u.ms,
...         sigma=0.5,
...         mu=0.0,
...         g=1.0,
...         theta=0.0,
...     )
...     net.init_all_states()
...     rate = net.update(x=0.1)
...     _ = rate.shape  # (10,)
...     _ = net.noisy_rate.value.shape  # (10,)
init_state(**kwargs)[source]#

Initialize state variables and internal buffers.

Create rate, noise, noisy_rate, instant_rate, delayed_rate, and step counter states. Initialize delay queues.

Parameters:

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

Notes

State variables are initialized from rate_initializer, noise_initializer, and noisy_rate_initializer. Both instant_rate and delayed_rate are initialized as copies of noisy_rate.

property receptor_types#

Mapping of receptor type names to indices.

Returns:

{'RATE': 0} for rate-based connections.

Return type:

dict

property recordables#

List of recordable state variables.

Returns:

['rate', 'noise', 'noisy_rate'].

Return type:

list of str

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

Advance rate dynamics by one simulation step.

Execute deterministic exponential Euler integration, add output noise, process delayed and instant events, and apply tanh nonlinearity.

Parameters:
  • x (ArrayLike, optional) – External current input (dimensionless). Broadcast to state shape and summed with mu. Default 0.0.

  • instant_rate_events (list or None, optional) – Rate events to apply in the current step (delay_steps=0). Each event can be dict, tuple, or scalar. Default None.

  • delayed_rate_events (list or None, optional) – Rate events to schedule with integer delays (delay_steps >= 0). Default None.

  • noise (ArrayLike or None, optional) – Custom noise samples \(\xi\) drawn from \(\mathcal{N}(0,1)\). If None, random samples are drawn internally. Useful for reproducibility or testing. Default None.

Returns:

rate – Updated deterministic rate values with shape self.varshape (float64). Note: the communicated output is noisy_rate, not rate.

Return type:

ndarray

Notes

Update sequence:

  1. Draw noise (or use provided noise).

  2. Compute noisy_rate from current rate by adding scaled noise: \(X_{\mathrm{noisy}} = X + \sqrt{\tau/h} \sigma \xi\).

  3. Store noisy_rate as delayed outgoing value.

  4. Drain queued delayed inputs scheduled for this step.

  5. Schedule new delayed events and accumulate zero-delay events.

  6. Accumulate instant events and split delta inputs by sign.

  7. Compute deterministic exponential Euler step: \(X_{n+1} = P_1 X_n + P_2 [\mu + \phi(\cdot)]\).

  8. Apply tanh nonlinearity to summed inputs (if linear_summation=True) or use pre-transformed per-event values (if False).

  9. Store noisy_rate as instantaneous outgoing value.

  10. Update state variables and increment step counter.