stdp_nn_symm_synapse#

class brainpy.state.stdp_nn_symm_synapse(weight=1.0, delay=Quantity(1., 'ms'), receptor_type=0, tau_plus=Quantity(20., 'ms'), tau_minus=Quantity(20., 'ms'), lambda_=0.01, alpha=1.0, mu_plus=1.0, mu_minus=1.0, Wmax=100.0, post=None, name=None)#

NEST-compatible stdp_nn_symm_synapse connection model.

Short description

Synapse type for spike-timing dependent plasticity with symmetric nearest-neighbour spike pairing.

Description

stdp_nn_symm_synapse mirrors NEST models/stdp_nn_symm_synapse.h and implements the symmetric nearest- neighbour pairing scheme from Morrison et al. (2007, 2008):

  • on a presynaptic spike, depression uses the nearest preceding postsynaptic spike,

  • postsynaptic spikes since the previous presynaptic spike contribute facilitation with nearest-neighbour trace factors.

Compared with stdp_synapse, this model removes the running presynaptic Kplus trace. Facilitation for each postsynaptic spike in the readout window uses \(\exp((t_{\mathrm{last}}-(t_{post}+d))/\tau_+)\) directly.

1. Mathematical Model

The weight update follows the same functional forms as stdp_synapse, but with symmetric nearest-neighbor pairing:

\[\hat{w} \leftarrow \hat{w} + \lambda (1-\hat{w})^{\mu_+} \sum_{i} \exp((t_{\mathrm{last}}-(t_{\mathrm{post}}^{(i)}+d))/\tau_+)\]
\[\hat{w} \leftarrow \hat{w} - \alpha \lambda \hat{w}^{\mu_-} k_-^{\mathrm{NN}}\]

where \(\hat{w} = w / W_{\mathrm{max}}\) is the normalized weight, \(t_{\mathrm{post}}^{(i)}\) are all postsynaptic spikes in the interval \((t_{\mathrm{last}}-d,\, t_{\mathrm{pre}}-d]\), and

\[\begin{split}k_-^{\mathrm{NN}} = \begin{cases} \exp((t_{\mathrm{post}}^{\mathrm{last}} - (t_{\mathrm{pre}}-d))/\tau_-) & \text{if } \exists t_{\mathrm{post}}^{\mathrm{last}} < t_{\mathrm{pre}}-d \\ 0 & \text{otherwise} \end{cases}\end{split}\]

Here \(t_{\mathrm{post}}^{\mathrm{last}}\) denotes the nearest preceding postsynaptic spike before \(t_{\mathrm{pre}}-d\).

The symmetric scheme differs from both the all-to-all stdp_synapse (which accumulates a running Kplus trace) and the pre-centered stdp_nn_pre_centered_synapse (which uses only the first postsynaptic spike and resets Kplus). Here, all postsynaptic spikes in the window contribute to potentiation, but each uses an exponential factor computed directly from \(t_{\mathrm{last}}\) without a presynaptic trace variable.

2. Update Order (NEST Source Equivalent)

For a presynaptic spike at \(t_{\mathrm{pre}}\) with dendritic delay \(d\), NEST stdp_nn_symm_synapse::send performs:

  1. Read postsynaptic history in \((t_{\mathrm{last}}-d,\, t_{\mathrm{pre}}-d]\).

  2. For each postsynaptic spike in that interval, apply facilitation with \(\exp((t_{\mathrm{last}}-(t_{\mathrm{post}}+d))/\tau_+)\).

  3. Apply depression from nearest-neighbor postsynaptic trace at \(t_{\mathrm{pre}}-d\): \(\exp((t_{\mathrm{post}}^{\mathrm{nn}}-(t_{\mathrm{pre}}-d))/\tau_-)\).

  4. Send event with updated weight.

  5. Set t_lastspike = t_pre.

This implementation preserves that exact ordering.

3. Coincidence Semantics

Pairs with exact coincidence are discarded by strict time comparisons (NEST stdp_eps behavior). If \(t_{\mathrm{pre}} = t_{\mathrm{post}} + d\) (within 1e-6 ms), the coincident postsynaptic spike is not used for depression/facilitation; earlier valid nearest neighbors are used instead.

Parameters:
  • weight (ArrayLike, optional) – Initial synaptic weight. Default: 1.0.

  • delay (ArrayLike, optional) – Synaptic delay \(d\) in ms. Default: 1.0 * u.ms.

  • receptor_type (int, optional) – Receiver port/receptor id. Default: 0.

  • tau_plus (ArrayLike, optional) – Potentiation time constant \(\tau_+\) in ms. Default: 20.0 * u.ms.

  • tau_minus (ArrayLike, optional) – Depression trace time constant \(\tau_-\) in ms. In NEST this is a postsynaptic-neuron parameter; here it is stored on the synapse for standalone compatibility. Default: 20.0 * u.ms.

  • lambda (ArrayLike, optional) – Learning-rate parameter \(\lambda\). Default: 0.01.

  • alpha (ArrayLike, optional) – Depression scaling parameter \(\alpha\). Default: 1.0.

  • mu_plus (ArrayLike, optional) – Potentiation exponent \(\mu_+\). Default: 1.0.

  • mu_minus (ArrayLike, optional) – Depression exponent \(\mu_-\). Default: 1.0.

  • Wmax (ArrayLike, optional) – Maximum weight bound \(W_{\mathrm{max}}\). Must have same sign as weight. Default: 100.0.

  • post (object, optional) – Default receiver object for spike transmission.

  • name (str, optional) – Object name for debugging and serialization.

Notes

  • In NEST, tau_minus belongs to the postsynaptic archiving neuron. This backend stores equivalent state locally for standalone compatibility, while preserving update semantics.

  • As in NEST, the model uses on-grid spike stamps and ignores sub-step precise spike offsets for STDP updates.

  • Kplus is not a public parameter for this model because it is not used in the symmetric nearest-neighbor scheme. The constructor internally sets Kplus=0.0 in the parent class, but it plays no role in weight updates.

  • The symmetric scheme produces different weight dynamics than all-to-all STDP: each postsynaptic spike contributes independently to facilitation, weighted by its temporal distance from the last presynaptic spike, rather than being accumulated into a running trace.

Examples

Symmetric nearest-neighbor STDP with custom parameters:

>>> import brainpy.state as bp
>>> import saiunit as u
>>> syn = bp.stdp_nn_symm_synapse(
...     weight=0.5,
...     delay=1.5 * u.ms,
...     tau_plus=16.8 * u.ms,
...     tau_minus=33.7 * u.ms,
...     lambda_=0.005,
...     alpha=0.85,
...     Wmax=5.0,
... )
>>> syn.weight
0.5

References

get()[source]#

Return current public parameters and mutable state.

Returns a dictionary containing all synapse parameters and internal state variables, excluding the unused Kplus parameter (which is not part of the symmetric nearest-neighbor scheme).

Returns:

Dictionary with keys 'synapse_model' (str, set to 'stdp_nn_symm_synapse'), 'weight' (float), 'delay' (float in ms), 'receptor_type' (int), 'tau_plus' (float in ms), 'tau_minus' (float in ms), 'lambda' (float), 'alpha' (float), 'mu_plus' (float), 'mu_minus' (float), 'Wmax' (float), 't_lastspike' (float in ms), and internal history state. The 'Kplus' key is explicitly removed because it is not used.

Return type:

dict

Notes

  • The returned dictionary is a snapshot and does not dynamically reflect subsequent state changes.

  • This method is used for serialization, debugging, and NEST-API compatibility (GetStatus).

  • Unlike stdp_synapse and stdp_nn_pre_centered_synapse, this model does not maintain a presynaptic trace Kplus, so it is excluded from the returned state.

send(multiplicity=1.0, *, post=None, receptor_type=None)[source]#

Schedule one outgoing spike event with symmetric nearest-neighbor STDP.

This method implements the complete NEST stdp_nn_symm_synapse::send update sequence:

  1. Query postsynaptic spike history in the interval \((t_{\mathrm{last}}-d,\, t_{\mathrm{spike}}-d]\).

  2. For each postsynaptic spike \(t_{\mathrm{post}}^{(i)}\) in that interval, apply facilitation with:

    \[w \leftarrow w + \lambda (1-w/W_{\mathrm{max}})^{\mu_+} \exp((t_{\mathrm{last}} - (t_{\mathrm{post}}^{(i)} + d))/\tau_+)\]

    Unlike stdp_nn_pre_centered_synapse, this uses all postsynaptic spikes in the window, not just the first.

  3. Apply depression from the nearest preceding postsynaptic spike:

    \[w \leftarrow w - \alpha \lambda (w/W_{\mathrm{max}})^{\mu_-} \exp((t_{\mathrm{post}}^{\mathrm{last}} - (t_{\mathrm{spike}}-d))/\tau_-)\]
  4. Enqueue a spike event with the updated weight for delivery at step \(\mathrm{current\_step} + \mathrm{delay\_steps}\).

  5. Update t_lastspike to the current spike time.

No presynaptic trace Kplus is updated because this model does not use one.

Parameters:
  • multiplicity (ArrayLike, optional) – Spike multiplicity (weight scaling factor). If zero, no event is sent. Default: 1.0.

  • post (object, optional) – Target receiver object. If None, uses the default receiver set at construction.

  • receptor_type (ArrayLike or None, optional) – Receptor port id for the event. If None, uses self.receptor_type. Must be a non-negative integer.

Returns:

True if the event was scheduled, False if multiplicity was zero and no event was sent.

Return type:

bool

Notes

  • The weight update occurs before the event is enqueued, so the transmitted spike carries the plasticity-modified weight.

  • All postsynaptic spikes in the facilitation window contribute independently to potentiation, weighted by their temporal distance from the last presynaptic spike. This is the “symmetric” aspect of the model.

  • Depression uses a strict nearest-neighbor rule: only the most recent postsynaptic spike before \(t_{\mathrm{spike}}-d\) contributes.

  • Coincident spikes (within 1e-6 ms tolerance) are excluded from both facilitation and depression windows.

  • Unlike stdp_synapse, no presynaptic trace is maintained; unlike stdp_nn_pre_centered_synapse, the presynaptic trace is not reset after facilitation (because it does not exist).

  • This method is typically called by the presynaptic neuron’s spike transmission logic; it can also be invoked manually for testing or standalone STDP simulation.

Examples

Manually trigger a presynaptic spike event:

>>> import brainpy.state as bp
>>> import saiunit as u
>>> syn = bp.stdp_nn_symm_synapse(
...     weight=1.0, delay=1.0 * u.ms, tau_plus=20.0 * u.ms
... )
>>> # Assume postsynaptic spikes have been recorded...
>>> success = syn.send(multiplicity=1.0)
>>> print(success)
True
>>> print(syn.weight)  # Weight has been updated by STDP
set(**kwargs)[source]#

Set NEST-style public parameters and mutable state.

Updates synapse parameters dynamically. Rejects attempts to set Kplus because it is not part of the symmetric nearest-neighbor STDP model.

Parameters:

**kwargs (dict) – Parameter names and values to update. Valid keys include 'weight', 'delay', 'receptor_type', 'tau_plus', 'tau_minus', 'lambda', 'alpha', 'mu_plus', 'mu_minus', 'Wmax', and 't_lastspike'.

Raises:

ValueError – If 'Kplus' is present in kwargs. The symmetric nearest-neighbor scheme does not use a presynaptic trace, so setting Kplus is invalid.

Notes

  • This method provides NEST-API compatibility (SetStatus).

  • Parameter updates take effect immediately and apply to subsequent plasticity updates.

  • Unlike models with Kplus, this model computes facilitation traces directly from postsynaptic spike times without maintaining a running presynaptic trace variable.

Examples

Update learning rate and potentiation time constant:

>>> import brainpy.state as bp
>>> import saiunit as u
>>> syn = bp.stdp_nn_symm_synapse(weight=1.0)
>>> syn.set(lambda_=0.02, tau_plus=15.0 * u.ms)
>>> syn.get()['lambda']
0.02