Skip to content

Macro definitions in equations #378

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

Open
thesamovar opened this issue Dec 11, 2014 · 7 comments
Open

Macro definitions in equations #378

thesamovar opened this issue Dec 11, 2014 · 7 comments

Comments

@thesamovar
Copy link
Member

thesamovar commented Dec 11, 2014

e.g. define E(vT)=exp((E-v+vT)/tau) and then use E(15*mV), E(40*mV) in the rest of the equations.

@souravsingh
Copy link

@thesamovar I am interested in working on the issue. How do I start?

@thesamovar
Copy link
Member Author

Thanks for offering to be involved!

For something like this, we normally start with a discussion of use cases, then proposals for the syntax, and then finally move on to implementation. So I'd start by coming up with some suggestions as to how this feature might be used, and ideas for what the user syntax might look like.

@Dyex719
Copy link

Dyex719 commented Jan 1, 2018

Hi! I was hoping to continue with this.
Use cases would include all the mathematical expressions and differential equations. (In differential equations this would allow us to change values of constants, like the threshold without changing the entire equation).
Coming to the syntax,
If the equation is f(x,y) = x+y
I think we should allow syntax like:
f(3,2) and f(x=2,y=4)
Some guidance with this would be great! Thanks!

@mstimberg
Copy link
Member

I think the best thing for now would be to come up with a concrete use case, and show how the new syntax would make things clearer. For example, take the equations from one of the Brian examples and show how a macro definition would make them clearer/more readable.

Note that there is potential for confusion what this issue is about: this is not about having a system just to change constants in equations (we already have several mechanisms for that, see e.g. http://brian2.readthedocs.io/en/stable/user/equations.html#equation-objects and http://brian2.readthedocs.io/en/stable/advanced/namespaces.html). It is rather about shortening/cleaning up equation strings by having a macro for expressions that occur repeatedly (with small variations such as changed constants) across several equations of an equations string.

Oh, and I edited Dan's example in the initial post, it used "x" instead of "vT" by mistake.

@shcecter
Copy link

shcecter commented Apr 27, 2020

Hello!

taking into account rate constants equations from 'COBAHH' example https://brian2.readthedocs.io/en/stable/examples/COBAHH.html:

I am not sure it is small enough changes between three repeated equations, but may be it is useful to use macro in situations with 'exprel' function.

before:

beta_m = 0.28*(mV**-1)*5*mV/exprel((v-VT-40*mV)/(5*mV))/ms : Hz
alpha_h = 0.128*exp((17*mV-v+VT)/(18*mV))/ms : Hz
beta_h = 4./(1+exp((40*mV-v+VT)/(5*mV)))/ms : Hz
alpha_n = 0.032*(mV**-1)*5*mV/exprel((15*mV-v+VT)/(5*mV))/ms : Hz
beta_n = .5*exp((10*mV-v+VT)/(40*mV))/ms : Hz

after:

R(Vnum, Vdenum) = Vdenum/exprel(Vnum/Vdenum)  # R for rate constant
E(Vsh, Vdenum) = exp((Vsh-v+VT)/Vdenum)
alpha_m = 0.32*(mV**-1)*R(13*mV-v+VT, 4*mV)/ms : Hz
beta_m = 0.28*(mV**-1)*R(v-VT-40*mV, 5*mV)/ms : Hz
alpha_h = 0.128*E(17*mV, 18*mV)/ms : Hz
beta_h = 4./(1+E(40*mV, 5*mV))/ms : Hz
alpha_n = 0.032*(mV**-1)*R(15*mV-v+VT, 5*mV)/ms : Hz
beta_n = .5*E(10*mV, 40*mV)/ms : Hz

Also possible usage with gate dynamics:

before:

dm/dt = alpha_m*(1-m)-beta_m*m : 1
dn/dt = alpha_n*(1-n)-beta_n*n : 1
dh/dt = alpha_h*(1-h)-beta_h*h : 1

after:

G((alpha, beta, x) = alpha*(1-x)-beta*(x)
dm/dt = G(alpha_m, beta_m, m) : 1
dn/dt = G(alpha_n, beta_n, n) : 1
dh/dt = G(alpha_h, beta_h, h) : 1

Hope I understood properly.

upd:

Shorter but more tricky with parameters version of R:

R(Vsh, Vsc) = Vsc/exprel((Vsh-v+VT)/Vsc)
alpha_m = 0.32*(mV**-1)*R(13*mV, 4*mV)/ms : Hz
beta_m = 0.28*(mV**-1)*R(40*mV, -5*mV)/ms : Hz
alpha_n = 0.032*(mV**-1)*R(15*mV, 5*mV)/ms : Hz

@maverick4code
Copy link
Contributor

maverick4code commented Mar 24, 2025

Hi @thesamovar , @mstimberg , I would like to propose a macro feature for brian2, with the HH model as a compelling use case due to its repeated exponential patterns in the rate equations (alpham, betam, alphan). Also, I think reusable activation functions(like sigmoids) can also be an use case because they have reusable expressions.

I have taken hodgkin_huxley_model (it is an ideal example and also because I was reading the tutorial_3 last week, so this struck me)
as an reference example from Brian examples. In the HH model, the rate equations(alpham, betam, alphan) share a common structure: exp(some_expression / some_constant) - 1. A macro for this could be defined as:
macro EXP_TERM(p, q) = exp(p / q) - 1 # p: voltage expression, q: scaling factor

This is how the simplified equation string would look like:

eqs = '''
macro EXP_TERM(p, q) = exp(p / q) - 1

alpham = 0.32 * (v - El - 13*mV) / EXP_TERM(v - El - 13*mV, 4*mV) / ms : Hz
betam  = 0.28 * (El + 40*mV - v) / EXP_TERM(El + 40*mV - v, 5*mV) / ms : Hz
alphan = 0.032 * (v - El - 15*mV) / EXP_TERM(v - El - 15*mV, 5*mV) / ms : Hz
''' 

I feel the code looks more clear now, after using a shared form across the equations. Any thoughts / feedback?

@mstimberg
Copy link
Member

Hi @maverick4code, this would indeed be a useful feature to have, and as you can see from the date when this issue was opened, we've been interested in adding this for a long time 😉

I actually did quite a bit of work on this a while ago, to figure out the best way to implement things – unfortunately, I never completely finished it. I'll need to read up on things myself (it's been a few years), but here are a few pointers to previous (long)discussions and code:
https://brian.discourse.group/t/standards-in-compartmental-modeling-libraries-of-mechanisms/148/6
#1244
Note that the discussion is mostly in the context of multi-compartmental models (where it is very common to have complex models with many differential equations), but this does not really matter for this feature, since it is all about the equations.
Note that this is not including the macro in the string itself, but rather in a more object-oriented way, but I think this would be preferred here.

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

6 participants