rate_connection_instantaneous#

class brainpy.state.rate_connection_instantaneous(weight=1.0, name=None)#

NEST-compatible rate_connection_instantaneous connection model.

Implements connection-level semantics for instantaneous (zero-delay) rate connections following NEST’s rate_connection_instantaneous model. This class represents a synapse that transmits rate signals without delay, supporting secondary event propagation and waveform relaxation for rate-based network simulations.

Unlike rate_connection_delayed, this model enforces zero delay and rejects any attempt to configure a delay parameter. Instantaneous connections are essential for modeling fast synaptic interactions and implementing implicit integration schemes.

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

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

weight#

Connection gain (validated scalar).

Type:

float

delay#

Compatibility field, always 1. Exposed in get_status for NEST API parity but ignored by transmission logic. Cannot be modified.

Type:

int

name#

Instance name.

Type:

str or None

HAS_DELAY#

Class attribute, always False (this model enforces zero delay).

Type:

bool

SUPPORTS_WFR#

Class attribute, always True (supports waveform relaxation).

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

Read-only, always 1 (compatibility)

has_delay

HAS_DELAY

Always False (class attribute)

supports_wfr

SUPPORTS_WFR

Always True (class attribute)

Mathematical Description

1. Instantaneous Connection Model

A rate_connection_instantaneous synapse transmits a rate signal \(r_\text{pre}(t)\) from a presynaptic neuron to a postsynaptic neuron without delay, applying only the connection weight \(w\):

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

In contrast to delayed connections, the postsynaptic rate depends on the current (not past) presynaptic rate. This enables instantaneous feedback loops and is required for certain implicit integration methods.

2. Secondary Event Handling with Waveform Relaxation

NEST rate neurons support waveform relaxation (WFR), an iterative method for solving coupled differential equations. During WFR iterations, neurons exchange secondary events containing coefficient arrays \(\{c_0, c_1, \ldots, c_{n-1}\}\) representing contributions at multiple time lags within the current WFR interval.

For instantaneous connections, the receiver processes each coefficient \(c_i\) by adding it to input buffer slot \(i\):

\[I_{\text{instant}}[i] \mathrel{{+}{=}} w \cdot c_i, \quad i = 0, 1, \ldots, n-1\]

This direct indexing reflects the zero-delay nature of the connection—coefficients apply to the current and immediate future steps without temporal offset.

3. Event Payload Structure

An instantaneous rate event contains:

  • rate: Scalar rate value or coefficient (dimensionless)

  • weight: Connection weight

  • delay_steps: Always 0 for instantaneous events

  • multiplicity: Optional scaling factor for probabilistic connections

The method coeffarray_to_step_events() expands a coefficient array into individual per-step events with sequential delay offsets starting from first_delay_steps.

Implementation Notes

Delay Restriction

This model enforces zero delay for all transmissions. Any attempt to set a delay via set_delay(), set_delay_steps(), or set_status(delay=...) raises a ValueError with the message:

"rate_connection_instantaneous has no delay. Please use rate_connection_delayed."

The delay attribute is exposed in get_status() for NEST API compatibility (always returns 1), but this value is ignored by the transmission logic and cannot be modified.

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 connection properties in synapse objects and enforces delay restrictions at runtime. This implementation replicates that behavior by raising errors when delay modification is attempted.

  • Secondary event expansion follows NEST’s direct buffer indexing for instantaneous events (no delay offset applied).

  • The supports_wfr flag is set to True, indicating compatibility with NEST’s waveform relaxation solver.

Coefficient Array Indexing

The method coeffarray_to_step_events() maps each coefficient coeffarray[i] to an event with delay_steps = first_delay_steps + i. This allows instantaneous connections to participate in multi-step implicit integration by distributing coefficients across future time steps, starting from a specified base delay.

Raises:
  • ValueError – If weight is not scalar.

  • ValueError – If any method attempts to set delay, delay_steps, or if to_rate_event is called with non-zero delay_steps.

  • ValueError – If coefficient array is empty or first_delay_steps < 0 in coeffarray_to_step_events.

See also

rate_connection_delayed

Delayed rate connection model (NEST equivalent)

rate_neuron_ipn

Input rate neuron (instantaneous event receiver)

rate_neuron_opn

Output rate neuron (instantaneous event receiver)

References

Examples

Basic Usage

Create an instantaneous connection with weight 2.0:

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

Creating Rate Events

Transmit an instantaneous rate signal:

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

Secondary Event Expansion

Map a coefficient array to per-step events for multi-step integration:

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

Delay Restriction Enforcement

Attempting to set a delay raises an error:

>>> conn.set_delay(3)
Traceback (most recent call last):
    ...
ValueError: rate_connection_instantaneous has no delay. Please use rate_connection_delayed.

Dynamic Weight Updates

Update connection weight at runtime:

>>> conn.set_weight(1.5)
>>> conn.get('weight')
1.5
>>> conn.set_status(weight=3.0)
>>> conn.get('weight')
3.0

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 instantaneous connections for fast feedback
>>> conns = [bst.rate_connection_instantaneous(weight=w)
...          for w in [0.8, 1.2, 0.5]]
>>> # Transmit events during WFR iterations
>>> for conn in conns:
...     event = conn.to_rate_event(pre.rate, multiplicity=1.0)
...     # post.handle_instantaneous_event(event)  # Receiver-side logic
coeffarray_to_step_events(coeffarray, first_delay_steps=0, multiplicity=1.0)[source]#

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

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

Unlike delayed connections, instantaneous connections apply coefficients directly to buffer slots without subtracting a minimum delay. This method is used to distribute waveform relaxation (WFR) coefficients across future time steps.

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).

  • first_delay_steps (int or array-like, optional) – Base delay offset for the first coefficient. Subsequent coefficients are mapped to first_delay_steps + i. Must be integer-valued scalar >= 0. Default: 0.

  • 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 = first_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 first_delay_steps < 0 (instantaneous events start from step 0 or later).

  • ValueError – If first_delay_steps or multiplicity is not scalar.

Notes

NEST Buffer Indexing for Instantaneous Connections

NEST rate neurons handle instantaneous events by directly indexing into the input buffer. For each coefficient \(c_i\), the receiver adds the weighted contribution to buffer slot \(i\):

\[I_{\text{instant}}[d_{\text{first}} + i] \mathrel{{+}{=}} w \cdot c_i\]

This direct indexing reflects the zero-delay nature—no network-wide minimum delay offset is subtracted.

Comparison with Delayed Connections

Delayed connections compute buffer slots as \((d - d_{\text{min}}) + i\) (see rate_connection_delayed.coeffarray_to_step_events). Instantaneous connections use \(d_{\text{first}} + i\) without delay adjustment.

Example Calculation

Suppose first_delay_steps = 0 and coeffarray = [0.5, 1.0, 0.3]:

  • Coefficient 0 (0.5): delay_steps = 0 + 0 = 0

  • Coefficient 1 (1.0): delay_steps = 0 + 1 = 1

  • Coefficient 2 (0.3): delay_steps = 0 + 2 = 2

If first_delay_steps = 2:

  • Coefficient 0: delay_steps = 2 + 0 = 2

  • Coefficient 1: delay_steps = 2 + 1 = 3

  • Coefficient 2: delay_steps = 2 + 2 = 4

See also

prepare_secondary_event

Create secondary event with coefficient array.

to_rate_event

Create single-rate event.

Examples

Basic usage with 3 coefficients starting from step 0:

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

Starting from a later step (e.g., for WFR multi-step integration):

>>> events = conn.coeffarray_to_step_events(coeffs, first_delay_steps=5)
>>> events[0]['delay_steps']
5
>>> events[1]['delay_steps']
6
>>> events[2]['delay_steps']
7

Error when first_delay_steps is negative:

>>> conn.coeffarray_to_step_events([0.5, 1.0], first_delay_steps=-1)
Traceback (most recent call last):
    ...
ValueError: first_delay_steps must be >= 0.

Using with multiplicity scaling:

>>> conn = rate_connection_instantaneous(weight=1.0)
>>> events = conn.coeffarray_to_step_events([0.5, 1.0], first_delay_steps=0, 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', '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_instantaneous(weight=2.0)
>>> conn.get('weight')
2.0
>>> conn.get('has_delay')
False
>>> conn.get('status')
{'weight': 2.0, 'delay': 1, 'has_delay': False, 'supports_wfr': True}
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' (int): Always 1 (compatibility field, read-only).

  • 'has_delay' (bool): Always False.

  • 'supports_wfr' (bool): Always True.

Return type:

dict

Examples

>>> conn = rate_connection_instantaneous(weight=1.5)
>>> status = conn.get_status()
>>> status['weight']
1.5
>>> status['delay']
1
>>> status['has_delay']
False
prepare_secondary_event(coeffarray)[source]#

Create an instantaneous secondary-event payload.

Secondary events are used in waveform relaxation (WFR) and implicit integration schemes for rate neurons. The coefficient array represents contributions at multiple time lags within the current WFR interval.

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.

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_instantaneous(weight=2.0)
>>> 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 False for this model.

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

Return type:

dict

set_delay(_)[source]#

Reject delay modification (instantaneous model has no delay).

This method always raises a ValueError to enforce NEST semantics.

Parameters:

_ (any) – Ignored. Delay cannot be set for instantaneous connections.

Raises:

ValueError – Always raised with NEST-matching error message.

Examples

>>> conn = rate_connection_instantaneous()
>>> conn.set_delay(5)
Traceback (most recent call last):
    ...
ValueError: rate_connection_instantaneous has no delay. Please use rate_connection_delayed.
set_delay_steps(_)[source]#

Reject delay_steps modification (instantaneous model has no delay).

This method always raises a ValueError to enforce NEST semantics.

Parameters:

_ (any) – Ignored. Delay cannot be set for instantaneous connections.

Raises:

ValueError – Always raised with NEST-matching error message.

Examples

>>> conn = rate_connection_instantaneous()
>>> conn.set_delay_steps(3)
Traceback (most recent call last):
    ...
ValueError: rate_connection_instantaneous has no delay. Please use rate_connection_delayed.
set_status(status=None, **kwargs)[source]#

Update connection parameters from a dictionary or keyword arguments.

Follows NEST’s SetStatus API convention. Only allows updating weight. Any attempt to set delay or delay_steps raises a ValueError.

Parameters:
  • status (dict or None, optional) – Dictionary of parameters to update. Only 'weight' is allowed.

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

Raises:
  • ValueError – If delay or delay_steps is present in updates (with NEST-matching error message).

  • ValueError – If weight fails validation (non-scalar).

Examples

>>> conn = rate_connection_instantaneous(weight=1.0)
>>> conn.set_status({'weight': 2.5})
>>> conn.get('weight')
2.5
>>> conn.set_status(weight=3.0)  # Keyword argument style
>>> conn.get('weight')
3.0

Delay updates are rejected:

>>> conn.set_status(delay=3)
Traceback (most recent call last):
    ...
ValueError: rate_connection_instantaneous has no delay. Please use rate_connection_delayed.
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_instantaneous()
>>> conn.set_weight(2.5)
>>> conn.get('weight')
2.5
to_rate_event(rate, multiplicity=1.0, delay_steps=0)[source]#

Create an instantaneous 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 zero 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, optional) – Must be 0 for instantaneous connections. Included for API consistency with rate_connection_delayed. Default: 0.

Returns:

Event payload with keys:

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

  • 'weight' (float): Connection weight.

  • 'delay_steps' (int): Always 0 for instantaneous connections.

  • 'multiplicity' (float): Scaling factor.

Return type:

dict

Raises:
  • ValueError – If delay_steps is not 0 (instantaneous connections enforce zero delay).

  • ValueError – If multiplicity is not scalar.

Examples

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

Non-zero delay raises an error:

>>> conn.to_rate_event(rate=5.0, delay_steps=3)
Traceback (most recent call last):
    ...
ValueError: delay_steps for rate_connection_instantaneous must be 0.