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_synapseconnection model.Short description
Synapse type for spike-timing dependent plasticity with symmetric nearest-neighbour spike pairing.
Description
stdp_nn_symm_synapsemirrors NESTmodels/stdp_nn_symm_synapse.hand 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 presynapticKplustrace. 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 runningKplustrace) and the pre-centeredstdp_nn_pre_centered_synapse(which uses only the first postsynaptic spike and resetsKplus). 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::sendperforms:Read postsynaptic history in \((t_{\mathrm{last}}-d,\, t_{\mathrm{pre}}-d]\).
For each postsynaptic spike in that interval, apply facilitation with \(\exp((t_{\mathrm{last}}-(t_{\mathrm{post}}+d))/\tau_+)\).
Apply depression from nearest-neighbor postsynaptic trace at \(t_{\mathrm{pre}}-d\): \(\exp((t_{\mathrm{post}}^{\mathrm{nn}}-(t_{\mathrm{pre}}-d))/\tau_-)\).
Send event with updated
weight.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_epsbehavior). If \(t_{\mathrm{pre}} = t_{\mathrm{post}} + d\) (within1e-6ms), 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 asweight. 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_minusbelongs 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.
Kplusis not a public parameter for this model because it is not used in the symmetric nearest-neighbor scheme. The constructor internally setsKplus=0.0in 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
Kplusparameter (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:
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_synapseandstdp_nn_pre_centered_synapse, this model does not maintain a presynaptic traceKplus, 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::sendupdate sequence:Query postsynaptic spike history in the interval \((t_{\mathrm{last}}-d,\, t_{\mathrm{spike}}-d]\).
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.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_-)\]Enqueue a spike event with the updated weight for delivery at step \(\mathrm{current\_step} + \mathrm{delay\_steps}\).
Update
t_lastspiketo the current spike time.
No presynaptic trace
Kplusis 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. IfNone, uses the default receiver set at construction.receptor_type (
ArrayLikeorNone, optional) – Receptor port id for the event. IfNone, usesself.receptor_type. Must be a non-negative integer.
- Returns:
Trueif the event was scheduled,Falseifmultiplicitywas zero and no event was sent.- Return type:
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-6ms tolerance) are excluded from both facilitation and depression windows.Unlike
stdp_synapse, no presynaptic trace is maintained; unlikestdp_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
Kplusbecause 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 inkwargs. The symmetric nearest-neighbor scheme does not use a presynaptic trace, so settingKplusis 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