rate_connection_delayed#

class brainpy.state.rate_connection_delayed(weight=1.0, delay_steps=1, name=None)#

NEST-compatible rate_connection_delayed connection model.

Implements connection-level semantics for delayed rate connections following NEST’s rate_connection_delayed model. This class represents a synapse that transmits rate signals with a configurable delay, supporting secondary event propagation for rate-based network simulations.

Unlike rate_connection_instantaneous, this model enforces a minimum delay of one simulation step and supports delayed secondary events through coefficient arrays.

Parameters:
  • weight (float or array-like, optional) – Connection gain/strength applied to transmitted rate signals. Must be scalar. Default: 1.0.

  • delay_steps (int or array-like, optional) – Transmission delay in discrete simulation steps. Must be integer-valued and >= 1. Default: 1.

  • name (str or None, optional) – Optional name identifier for this connection instance. Default: None.

weight#

Connection gain (validated scalar).

Type:

float

delay_steps#

Delay in simulation steps (validated >= 1).

Type:

int

name#

Instance name.

Type:

str or None

HAS_DELAY#

Class attribute, always True (this model enforces delay).

Type:

bool

SUPPORTS_WFR#

Class attribute, always False (waveform relaxation not supported).

Type:

bool

Parameter Mapping

The following table maps NEST parameters to this implementation:

NEST Parameter

brainpy.state

Notes

weight

weight

Connection gain (scalar float)

delay

delay_steps

Delay in steps (integer >= 1)

has_delay

HAS_DELAY

Always True (class attribute)

supports_wfr

SUPPORTS_WFR

Always False (class attribute)

Mathematical Description

1. Connection Model

A rate_connection_delayed synapse transmits a rate signal \(r_\text{pre}(t)\) from a presynaptic neuron to a postsynaptic neuron with delay \(d\) and weight \(w\):

\[r_\text{post}(t) = w \cdot r_\text{pre}(t - d)\]

In discrete-time simulation with step size \(\Delta t\), the delay is quantized to an integer number of steps:

\[d_\text{steps} = \left\lceil \frac{d}{\Delta t} \right\rceil, \quad d_\text{steps} \geq 1\]

2. Secondary Event Handling

NEST rate neurons support secondary events for implicit integration schemes. A secondary event carries a coefficient array \(\{c_0, c_1, \ldots, c_{n-1}\}\) representing contributions at multiple time lags.

The receiver maps each coefficient \(c_i\) to a target buffer slot:

\[\text{target\_slot} = (d_\text{steps} - d_\text{min}) + i\]

where \(d_\text{min}\) is the minimum delay in the network. This ensures that coefficients are applied to the correct future time steps.

3. Event Payload Structure

A delayed rate event contains:

  • rate: Scalar rate value or coefficient array

  • weight: Connection weight

  • delay_steps: Integer delay

  • multiplicity: Optional scaling factor for probabilistic connections

The method coeffarray_to_step_events() expands a coefficient array into individual per-step events, each with the appropriate delay offset.

Implementation Notes

Delay Validation

This model enforces delay_steps >= 1 to comply with NEST semantics. Attempting to set delay_steps = 0 raises a ValueError. For instantaneous (zero-delay) connections, use rate_connection_instantaneous instead.

Unit Handling

All parameters accept saiunit.Quantity objects or plain numeric values. If a Quantity is provided, its mantissa is extracted. Internally, values are stored as dimensionless floats or integers.

Compatibility with NEST

  • NEST stores delays in time units (ms), while this implementation uses discrete steps to match BrainPy’s event system.

  • The set_status method accepts both delay and delay_steps as aliases for backward compatibility.

  • Secondary event expansion follows NEST’s buffer indexing logic exactly.

Raises:
  • ValueError – If weight or delay_steps is not scalar, or if delay_steps < 1.

  • ValueError – If delay and delay_steps are both provided in set_status with conflicting values.

  • ValueError – If coefficient array is empty or delay is less than min_delay_steps in coeffarray_to_step_events.

See also

rate_connection_instantaneous

Zero-delay rate connection model (NEST equivalent)

rate_neuron_ipn

Input rate neuron (delayed event receiver)

rate_neuron_opn

Output rate neuron (delayed event receiver)

References

Examples

Basic Usage

Create a delayed connection with weight 2.0 and 3-step delay:

>>> import brainpy.state as bst
>>> conn = bst.rate_connection_delayed(weight=2.0, delay_steps=3)
>>> conn.get_status()
{'weight': 2.0, 'delay_steps': 3, 'delay': 3, 'has_delay': True, 'supports_wfr': False}

Creating Rate Events

Transmit a rate signal with the connection’s parameters:

>>> event = conn.to_rate_event(rate=5.0, multiplicity=1.0)
>>> event
{'rate': 5.0, 'weight': 2.0, 'delay_steps': 3, 'multiplicity': 1.0}

Secondary Event Expansion

Map a coefficient array to per-step events (e.g., for implicit integration):

>>> coeffs = [0.5, 1.0, 0.3]  # Three lag coefficients
>>> events = conn.coeffarray_to_step_events(coeffs, min_delay_steps=1)
>>> len(events)
3
>>> events[0]
{'rate': 0.5, 'weight': 2.0, 'delay_steps': 2, 'multiplicity': 1.0}
>>> events[1]
{'rate': 1.0, 'weight': 2.0, 'delay_steps': 3, 'multiplicity': 1.0}
>>> events[2]
{'rate': 0.3, 'weight': 2.0, 'delay_steps': 4, 'multiplicity': 1.0}

Dynamic Parameter Updates

Update connection parameters at runtime:

>>> conn.set_status(weight=1.5, delay_steps=5)
>>> conn.get('weight')
1.5
>>> conn.get('delay_steps')
5

Using with Rate Neurons

Typical usage in a rate-based network (conceptual example):

>>> import brainpy.state as bst
>>> import saiunit as u
>>> # Create rate neurons (assuming rate_neuron_ipn exists)
>>> pre = bst.rate_neuron_ipn(size=10, tau=10.0*u.ms)
>>> post = bst.rate_neuron_ipn(size=5, tau=10.0*u.ms)
>>> # Define delayed connections
>>> conns = [bst.rate_connection_delayed(weight=w, delay_steps=d)
...          for w, d in zip([0.8, 1.2, 0.5], [2, 3, 1])]
>>> # Transmit events during simulation
>>> for conn in conns:
...     event = conn.to_rate_event(pre.rate, multiplicity=1.0)
...     # post.handle_delayed_event(event)  # Receiver-side logic
coeffarray_to_step_events(coeffarray, min_delay_steps=1, multiplicity=1.0)[source]#

Map lag-indexed coefficient array to per-step delayed-rate events.

Expands a coefficient array representing multiple time lags into individual per-step rate events, following NEST’s delayed-rate receiver buffer indexing. Each coefficient \(c_i\) is mapped to an event with delay offset \((d - d_{\text{min}}) + i\), where \(d\) is the connection delay and \(d_{\text{min}}\) is the minimum network delay.

This method is used to distribute secondary event coefficients across future time steps for implicit integration schemes.

Parameters:
  • coeffarray (array-like) – 1D array of coefficients, shape (n,). Each element represents a rate contribution at a successive time lag. Must be non-empty. Accepts saiunit.Quantity (mantissa will be extracted).

  • min_delay_steps (int or array-like, optional) – Minimum delay in the network (in simulation steps). Used to compute the base delay offset. Must be integer-valued scalar >= 1. Default: 1.

  • multiplicity (float or array-like, optional) – Scaling factor for all events. Must be scalar. Default: 1.0.

Returns:

List of event dictionaries, one per coefficient. Each event has keys:

  • 'rate' (float): Coefficient value.

  • 'weight' (float): Connection weight.

  • 'delay_steps' (int): Computed delay = (self.delay_steps - min_delay_steps) + i.

  • 'multiplicity' (float): Scaling factor.

Length of list equals len(coeffarray).

Return type:

list of dict

Raises:
  • ValueError – If coeffarray is empty.

  • ValueError – If self.delay_steps < min_delay_steps (would produce negative delay).

  • ValueError – If min_delay_steps or multiplicity is not scalar, or if min_delay_steps < 1.

Notes

NEST Buffer Indexing

NEST rate neurons with delayed connections use a ring buffer indexed by:

\[\text{buffer\_slot} = (d - d_{\text{min}}) + i\]

where \(d\) is the connection delay, \(d_{\text{min}}\) is the minimum delay, and \(i\) is the coefficient index. This ensures that coefficients are applied to the correct future time steps during implicit integration.

Example Calculation

Suppose self.delay_steps = 5, min_delay_steps = 2, and coeffarray = [0.5, 1.0, 0.3]:

  • Coefficient 0 (0.5): delay_steps = (5 - 2) + 0 = 3

  • Coefficient 1 (1.0): delay_steps = (5 - 2) + 1 = 4

  • Coefficient 2 (0.3): delay_steps = (5 - 2) + 2 = 5

See also

prepare_secondary_event

Create secondary event with coefficient array.

to_rate_event

Create single-rate event.

Examples

Basic usage with 3 coefficients:

>>> conn = rate_connection_delayed(weight=2.0, delay_steps=5)
>>> coeffs = [0.5, 1.0, 0.3]
>>> events = conn.coeffarray_to_step_events(coeffs, min_delay_steps=2)
>>> len(events)
3
>>> events[0]
{'rate': 0.5, 'weight': 2.0, 'delay_steps': 3, 'multiplicity': 1.0}
>>> events[1]
{'rate': 1.0, 'weight': 2.0, 'delay_steps': 4, 'multiplicity': 1.0}
>>> events[2]
{'rate': 0.3, 'weight': 2.0, 'delay_steps': 5, 'multiplicity': 1.0}

Error when connection delay is less than minimum delay:

>>> conn = rate_connection_delayed(weight=1.0, delay_steps=1)
>>> conn.coeffarray_to_step_events([0.5, 1.0], min_delay_steps=3)
Traceback (most recent call last):
    ...
ValueError: delay_steps must be >= min_delay_steps.

Using with multiplicity scaling:

>>> conn = rate_connection_delayed(weight=1.0, delay_steps=3)
>>> events = conn.coeffarray_to_step_events([0.5, 1.0], min_delay_steps=1, multiplicity=0.8)
>>> events[0]['multiplicity']
0.8
get(key='status')[source]#

Retrieve a specific parameter or full status dictionary.

Parameters:

key (str, optional) – Parameter name to retrieve. Special value 'status' returns full status dictionary. Supported keys: 'status', 'weight', 'delay', 'delay_steps', 'has_delay', 'supports_wfr'. Default: 'status'.

Returns:

If key == 'status', returns full status dictionary. Otherwise, returns the requested parameter value.

Return type:

dict or scalar

Raises:

KeyError – If key is not a recognized parameter name.

Examples

>>> conn = rate_connection_delayed(weight=2.0, delay_steps=3)
>>> conn.get('weight')
2.0
>>> conn.get('delay_steps')
3
>>> conn.get('status')
{'weight': 2.0, 'delay_steps': 3, ...}
get_status()[source]#

Retrieve all connection parameters as a dictionary.

Follows NEST’s GetStatus API convention.

Returns:

Dictionary with keys:

  • 'weight' (float): Connection gain.

  • 'delay_steps' (int): Delay in simulation steps.

  • 'delay' (int): Alias for delay_steps (NEST compatibility).

  • 'has_delay' (bool): Always True.

  • 'supports_wfr' (bool): Always False.

Return type:

dict

Examples

>>> conn = rate_connection_delayed(weight=1.5, delay_steps=2)
>>> status = conn.get_status()
>>> status['weight']
1.5
>>> status['delay']
2
prepare_secondary_event(coeffarray)[source]#

Create a delayed secondary-event payload.

Secondary events are used in implicit integration schemes for rate neurons. The coefficient array represents contributions at multiple time lags.

Parameters:

coeffarray (array-like) – 1D array of coefficients, shape (n,), representing rate contributions at n consecutive time lags. Must be non-empty. Accepts saiunit.Quantity (mantissa will be extracted).

Returns:

Event payload with keys:

  • 'coeffarray' (ndarray): Validated coefficient array, shape (n,), dtype float64.

  • 'weight' (float): Connection weight.

  • 'delay_steps' (int): Connection delay in steps.

Return type:

dict

Raises:

ValueError – If coeffarray is empty or cannot be converted to a 1D array.

See also

coeffarray_to_step_events

Expand coefficient array to per-step events.

Examples

>>> conn = rate_connection_delayed(weight=2.0, delay_steps=3)
>>> event = conn.prepare_secondary_event([0.5, 1.0, 0.3])
>>> event['coeffarray']
array([0.5, 1. , 0.3])
>>> event['weight']
2.0
property properties: dict[str, Any]#

Return connection model properties.

Returns:

Dictionary with keys:

  • 'has_delay' (bool): Always True for this model.

  • 'supports_wfr' (bool): Always False (waveform relaxation not supported).

Return type:

dict

set_delay(delay)[source]#

Update the connection delay (alias for set_delay_steps).

Parameters:

delay (int or array-like) – New delay in simulation steps. Must be integer-valued scalar >= 1. Accepts saiunit.Quantity (mantissa will be extracted).

Raises:

ValueError – If delay is not scalar, not integer-valued, or < 1.

Examples

>>> conn = rate_connection_delayed()
>>> conn.set_delay(5)
>>> conn.get('delay_steps')
5
set_delay_steps(delay_steps)[source]#

Update the connection delay in simulation steps.

Parameters:

delay_steps (int or array-like) – New delay in simulation steps. Must be integer-valued scalar >= 1. Accepts saiunit.Quantity (mantissa will be extracted).

Raises:

ValueError – If delay_steps is not scalar, not integer-valued, or < 1.

Examples

>>> conn = rate_connection_delayed()
>>> conn.set_delay_steps(3)
>>> conn.get('delay_steps')
3
set_status(status=None, **kwargs)[source]#

Update connection parameters from a dictionary or keyword arguments.

Follows NEST’s SetStatus API convention. Accepts both delay and delay_steps as aliases (if both provided, they must match).

Parameters:
  • status (dict or None, optional) – Dictionary of parameters to update. Keys: 'weight', 'delay', 'delay_steps'.

  • **kwargs – Alternative parameter specification as keyword arguments. Merged with status (keyword args take precedence).

Raises:
  • ValueError – If delay and delay_steps are both provided with conflicting values.

  • ValueError – If any parameter fails validation (e.g., non-scalar, delay < 1).

Examples

>>> conn = rate_connection_delayed(weight=1.0, delay_steps=1)
>>> conn.set_status({'weight': 2.5, 'delay_steps': 4})
>>> conn.get('weight')
2.5
>>> conn.set_status(weight=3.0)  # Keyword argument style
>>> conn.get('weight')
3.0
set_weight(weight)[source]#

Update the connection weight.

Parameters:

weight (float or array-like) – New connection gain. Must be scalar. Accepts saiunit.Quantity (mantissa will be extracted).

Raises:

ValueError – If weight is not scalar.

Examples

>>> conn = rate_connection_delayed()
>>> conn.set_weight(2.5)
>>> conn.get('weight')
2.5
to_rate_event(rate, multiplicity=1.0, delay_steps=None)[source]#

Create a delayed-rate event payload for step-based simulation APIs.

Constructs an event dictionary that can be passed to rate neuron receivers to transmit a rate signal with the connection’s weight and delay.

Parameters:
  • rate (float or array-like) – Rate value to transmit. Can be scalar (single rate) or array (multiple rates). Accepts saiunit.Quantity (mantissa will be extracted).

  • multiplicity (float or array-like, optional) – Scaling factor for stochastic or probabilistic connections. Must be scalar. Default: 1.0.

  • delay_steps (int or array-like or None, optional) – Override delay for this event. Must be integer-valued scalar >= 1. If None, uses the connection’s self.delay_steps. Default: None.

Returns:

Event payload with keys:

  • 'rate' (float or ndarray): Rate value (scalar or array).

  • 'weight' (float): Connection weight.

  • 'delay_steps' (int): Delay in steps.

  • 'multiplicity' (float): Scaling factor.

Return type:

dict

Raises:

ValueError – If multiplicity or delay_steps is not scalar, or if delay_steps < 1.

Examples

>>> conn = rate_connection_delayed(weight=2.0, delay_steps=3)
>>> event = conn.to_rate_event(rate=5.0)
>>> event
{'rate': 5.0, 'weight': 2.0, 'delay_steps': 3, 'multiplicity': 1.0}

Override delay for a specific event:

>>> event = conn.to_rate_event(rate=5.0, delay_steps=5)
>>> event['delay_steps']
5