# DualExpon#

class brainpy.dyn.DualExpon(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}}}$

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 DualExpSparseCOBA(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.DualExpon.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
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(DualExpSparseCOBA, 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()


The implementation of this model can only be used in AlignPre projections. One the contrary, to seek the AlignPost projection, please use DualExponV2.