Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

biexp synapse documentation not matching implementation? #1179

Open
felix11h opened this issue Apr 6, 2020 · 11 comments
Open

biexp synapse documentation not matching implementation? #1179

felix11h opened this issue Apr 6, 2020 · 11 comments

Comments

@felix11h
Copy link

felix11h commented Apr 6, 2020

A biexponential synapse, as per the Brian 2 documentation, should implement a current/conductance as g(t)=(tau2/(tau2-tau1))*(exp(-t/tau1)-exp(-t/tau2)).

When playing around with the biexponential synapse concept, I found that maybe the above description might need to be updated. Consider

import matplotlib as mpl
mpl.use('Agg')
import pylab as pl

import numpy as np
from brian2 import *

fig, ax = pl.subplots()

xmin, xmax = 0,100
xs = np.linspace(xmin, xmax, 10000)

# biexp as implemented in library/synapses.py
model = '''
        dx/dt = (invpeak*y-x)*invtau1 : 1
        dy/dt = -y*invtau2            : 1
        '''

tau1, tau2 = 1.5*ms, 10*ms

invtau1, invtau2 = 1./tau1, 1./tau2
invpeak = (tau2 / tau1) ** (tau1 / (tau2 - tau1))

N = NeuronGroup(1, model)
N.y = 1

mon = StateMonitor(N, 'x', record=True)
run(xmax*ms)
ax.plot(mon.t/ms, mon.x.T)


# --------------------------

# g(t) of biexp as explained in documentation
def g(t, tau1, tau2):
    return (tau2/(tau2-tau1))*(np.exp(-t/tau1)-np.exp(-t/tau2))

ax.plot(xs, g(xs, tau1/ms, tau2/ms))

fig.savefig('figure.png')

which gives

figure

I expected to see identical curves.

Note that it doesn't simply seem to be a matter of a missing minus sign as the amplitudes also don't seem to match. Any thoughts on this? Am I missing something? Thanks!

@mstimberg
Copy link
Member

Hi Felix. I'm a bit confused, but where do you see the description in the documentation? In Brian 2, this function does not exist any more, so we only mention it in the conversion guide where we don't show the actual equation. In the Brian 1 documentation it mentions that the equation is valid "up to a normalizing factor". The model used by Brian makes sure that the peak equals 1. Now, I agree I would not have expected that the equation gives a negative curve, even though strictly speaking it does not make the statement incorrect (the normalizing factor could be negative...). But then again, I don't see where in the Brian 2 documentation we mention anything like this, so where would the documentation have to be corrected?

@felix11h
Copy link
Author

felix11h commented Apr 6, 2020

Hi Marcel, thanks for the speedy reply! Oh, I see, I must admit I didn't pay attention to the version I'm looking at. You're right, one of the references I mention is from Brian 1.

I got the idea of using biexponential synapses from the Brian 2 documentation here https://brian2.readthedocs.io/en/stable/user/converting_from_integrated_form.html and it still seems to mention the equation for V(t), maybe a pointer to the missing normalization factor could be helpful here.

Thanks also for the reference to the Brian 1 documentation, that clears up things for me a lot!

@mstimberg
Copy link
Member

Oh, I did not think of this page! I guess one could say its equation for V(t) is not wrong but simply a bit vague, given that it does not refer to the initial value V(0) (or w later in the code/equation). It would certainly be better to make this unambiguous.

@wilhelmbraun
Copy link

wilhelmbraun commented Apr 6, 2020

Hi Felix and Marcel,
I want to add that defining an additional function for the maximum of g and then exchanging tau1 and tau2 in the difference of exponentials for g makes the two definitions equivalent, as g does not have its peak at 1, but at g_peak.

def g_peak(tau1, tau2):

    return (tau2/(tau2-tau1))*((tau1/tau2)**(tau1/(tau2-tau1)) - (tau1/tau2)**(tau2/(tau2-tau1)))

def g(t, tau1, tau2):

    return (1./g_peak(tau1, tau2))*(tau2/(tau2-tau1))*(np.exp(-t/tau2)-np.exp(-t/tau1))

Now both the sign (because of the exchange) and the peak (because of g_peak)
are correct, which one can also show directly by solving the coupled system for (x,y) above. Here's a plot:
image

@felix11h
Copy link
Author

felix11h commented Apr 7, 2020

Thanks @wilhelmbraun, this looks great!

@mstimberg
Copy link
Member

If anyone is up for updating the documentation: pull requests welcome 😄

@Syed-Osama-Hussain
Copy link

Hello. @mstimberg, can I try it?

@mstimberg
Copy link
Member

Hello. @mstimberg, can I try it?

Sure, please go ahead.

@Syed-Osama-Hussain
Copy link

Just to be sure, I have to replace the existing biexponential synapse equation to the one provided by @wilhelmbraun ?

@wilhelmbraun
Copy link

wilhelmbraun commented Apr 14, 2020 via email

@Syed-Osama-Hussain
Copy link

Thanks for the explanation!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants