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

Handling of += expressions by Equations() #1219

Open
smalltimer opened this issue Aug 27, 2020 · 10 comments
Open

Handling of += expressions by Equations() #1219

smalltimer opened this issue Aug 27, 2020 · 10 comments

Comments

@smalltimer
Copy link

Hi,

While defining equations using Equations() can be very useful when defining models which can then be fine-tuned by substituting variables or values, this method does not seem to work for on_pre and on_post events. If there is a variable which is only used during the events, it will not feature in the model equation (or can be included there as a declaration like 'x : 1'). However, such a declaration cannot be substituted using Equations(), thus limiting the use of Equations() in on_pre and on_post to define flexible models which can be adjusted for various synaptic groups.

Any workarounds/tips would be really helpful. I am not sure if this is strictly an issue, but I think it does limit the use of the very handy Equations() structure.

Cheers

@thesamovar
Copy link
Member

Interesting idea. The same would be true of threshold, reset in NeuronGroup. Having the same substitution options for these would be nice, and not a complicated feature to implement. Thanks for the suggestion. I don't suppose you'd like to implement it would you? We'd be very happy to help.

@thesamovar
Copy link
Member

The first thing to do would be to decide the syntax. I suspect Equations might not be easy to adapt to work with this because it's really specific to differential equations. We could have a new object (e.g. Statements) with the same syntax for substitutions, or try to add in sequences of statements as an additional option for Equations. Any thoughts @mstimberg ?

@smalltimer
Copy link
Author

That was fast, thanks @thesamovar ! I am afraid I have only been working from the wiki as a reference, and have not explored the Equations() code. I am writing some models in collaboration with a group of experimentalists, so making the code as easy to tune as possible for non-programmers was what led me to raise the issue.

@thesamovar
Copy link
Member

No worries! It's a really interesting and useful idea, and we should have done this from the beginning actually.

Maybe the simplest thing is to just have a nice function that just does the same clever substitution stuff as Equations does.

@smalltimer
Copy link
Author

smalltimer commented Aug 27, 2020

I may have found a hack-y solution which might be helpful in the meanwhile. Assuming an instantaneous synapse with scaled updating, the following does not work.

m = '''dg/dt = -g/tau : siemens'''
m_onpre = '''g += k*w'''
S = Synapses( N_pre, N_post, model =  Equations(m, tau = 3*ms), on_pre = Equations(m_onpre, k = 0.3) )

A possible work-around is to include ALL parameters in the model, even the ones which are strictly event-driven.

m = '''
dg/dt = -g/tau : siemens
k = k_parameter : 1
'''
m_onpre = '''g += k*w'''
S = Synapses( N_pre, N_post, model =  Equations(m, tau = 3*ms, k_parameter = 0.3), on_pre = m_onpre)

This way, all variables of the model are declared/collected in a single Equations() object, and you can choose to expose only the tau and k_parameter variables if needed. However, in this case, event-driven parameters will have to be defined using assignments to dummy variables, making this solution inelegant, and probably less efficient than a separate, clean implementation of a Statement() object as @thesamovar suggested.

@mstimberg
Copy link
Member

I have to say that I'm not 100% sure I understood the suggestion from the title and the description. Do I understand correctly that by "using Equations" you only mean that you'd like to its substitution mechanism also for statements like on_pre? If yes, I agree that makes sense and could be useful for complex models!

We could have a new object (e.g. Statements) with the same syntax for substitutions, or try to add in sequences of statements as an additional option for Equations.

We actually do already have such an object, and it is called... Statements 😄 It is currently not doing anything, but I think this would be the place to put the functionality.

@smalltimer
Copy link
Author

@mstimberg

Do I understand correctly that by "using Equations" you only mean that you'd like to its substitution mechanism also for statements like on_pre?

That is exactly it! Sorry, I agree the title I chose is rather vague...

And I see! I am guessing this is not high priority at all, so after I'm done with a couple of projects here I can have a look at whether we can transfer some of that Equations goodness over to the Statements object :D

@mstimberg
Copy link
Member

This makes all sense, and I think for consistency the syntax should be exactly like the one for Equations, i.e. with the feature available you should be able to use:

>>> Statements('g += k*w', k=0.3)
Statements('g += 0.3*w')
>>> Statements('g += k*w', g='g_ampa')
Statements('g_ampa += k*w')

@mstimberg
Copy link
Member

A possible work-around is to include ALL parameters in the model, even the ones which are strictly event-driven.

Another (I think preferable) workaround would be to use external variables. I guess you do not want to write them as simple Python variables (i.e. tau = 3*ms and k = 0.3) because your network gets constructed piece by piece in separate functions? In that case you could use the namespace argument:

constants = {'tau': 3*ms, k: 0.3}
m = '''dg/dt = -g/tau : siemens'''
m_onpre = '''g += k*w'''
S = Synapses(N_pre, N_post, model=m, on_pre=m_onpre, namespace=constants)

@smalltimer
Copy link
Author

smalltimer commented Aug 27, 2020

Ah, that does seem so much better. That way one could collect all the variables for each model in separate namespace dictionaries. Fantastic. Thank you!

One of the reasons I am looking at Equations() is, as un-programmer-ly as it sounds, to avoid a soup of variable names like Syn_e_N1_N2_tau, Syn_i_N3_N1_w etc.. As I mentioned, I am writing this particular model in collaboration with people who are not programmers, so I want them to have as clean and easy to understand interface to the code as possible. I think namespaces are definitely the way to go.

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

No branches or pull requests

3 participants