# DualExponV2#

class brainpy.dyn.DualExponV2(size, keep_size=False, sharding=None, method='exp_auto', name=None, mode=None, tau_decay=10.0, tau_rise=1.0, A=None)[source]#

Dual exponential synapse model.

Model Descriptions

The dual exponential synapse model [1], also named as difference of two exponentials model, is given by:

$g_{\mathrm{syn}}(t)=g_{\mathrm{max}} A \left(\exp \left(-\frac{t-t_{0}}{\tau_{1}}\right) -\exp \left(-\frac{t-t_{0}}{\tau_{2}}\right)\right)$

where $$\tau_1$$ is the time constant of the decay phase, $$\tau_2$$ is the time constant of the rise phase, $$t_0$$ is the time of the pre-synaptic spike, $$g_{\mathrm{max}}$$ is the maximal conductance.

However, in practice, this formula is hard to implement. The equivalent solution is two coupled linear differential equations [2]:

\begin{split}\begin{aligned} &\frac{d g}{d t}=-\frac{g}{\tau_{\mathrm{decay}}}+h \\ &\frac{d h}{d t}=-\frac{h}{\tau_{\text {rise }}}+ (\frac{1}{\tau_{\text{rise}}} - \frac{1}{\tau_{\text{decay}}}) A \delta\left(t_{0}-t\right), \end{aligned}\end{split}

By default, $$A$$ has the following value:

$A = \frac{{\tau }_{decay}}{{\tau }_{decay}-{\tau }_{rise}}{\left(\frac{{\tau }_{rise}}{{\tau }_{decay}}\right)}^{\frac{{\tau }_{rise}}{{\tau }_{rise}-{\tau }_{decay}}}$

Note

Different from DualExpon, this model can be used in both modes of AlignPre and AlignPost projections.

This module can be used with interface brainpy.dyn.ProjAlignPreMg2, as shown in the following example:

import numpy as np
import brainpy as bp
import brainpy.math as bm

import matplotlib.pyplot as plt

class DualExponV2SparseCOBA(bp.Projection):
def __init__(self, pre, post, delay, prob, g_max, tau_decay, tau_rise, E):
super().__init__()

self.proj = bp.dyn.ProjAlignPreMg2(
pre=pre,
delay=delay,
syn=bp.dyn.DualExponV2.desc(pre.num, tau_decay=tau_decay, tau_rise=tau_rise),
comm=bp.dnn.CSRLinear(bp.conn.FixedProb(prob, pre=pre.num, post=post.num), g_max),
out=bp.dyn.COBA(E=E),
post=post,
)

class SimpleNet(bp.DynSysGroup):
def __init__(self, syn_cls, E=0.):
super().__init__()
self.pre = bp.dyn.SpikeTimeGroup(1, indices=(0, 0, 0, 0), times=(10., 30., 50., 70.))
self.post = bp.dyn.LifRef(1, V_rest=-60., V_th=-50., V_reset=-60., tau=20., tau_ref=5.,
V_initializer=bp.init.Constant(-60.))
self.syn = syn_cls(self.pre, self.post, delay=None, prob=1., g_max=1., tau_decay=5., tau_rise=1., E=E)

def update(self):
self.pre()
self.syn()
self.post()
# monitor the following variables
conductance = self.syn.proj.refs['syn'].g_rise
current = self.post.sum_inputs(self.post.V)
return conductance, current, self.post.V

indices = np.arange(1000)  # 100 ms, dt= 0.1 ms
net = SimpleNet(DualExponV2SparseCOBAPost, E=0.)
conductances, currents, potentials = bm.for_loop(net.step_run, indices, progress_bar=True)
ts = indices * bm.get_dt()
fig, gs = bp.visualize.get_figure(1, 3, 3.5, 4)
plt.plot(ts, conductances)
plt.title('Syn conductance')
plt.plot(ts, currents)
plt.title('Syn current')
plt.plot(ts, potentials)
plt.title('Post V')
plt.show()


Moreover, it can also be used with interface ProjAlignPostMg2:

class DualExponV2SparseCOBAPost(bp.Projection):
def __init__(self, pre, post, delay, prob, g_max, tau_decay, tau_rise, E):
super().__init__()

self.proj = bp.dyn.ProjAlignPostMg2(
pre=pre,
delay=delay,
comm=bp.dnn.EventCSRLinear(bp.conn.FixedProb(prob, pre=pre.num, post=post.num), g_max),
syn=bp.dyn.DualExponV2.desc(post.num, tau_decay=tau_decay, tau_rise=tau_rise),
out=bp.dyn.COBA.desc(E=E),
post=post,
)