Equations in pre and postsynaptic triggers

Hi everyone,

An example explains it best:

Synapses(..., on_pre = Equations('ge_post += w; w += del_w', del_w = 0.1))

So I want to make del_w a tunable constant which should be bound by value to the synapse model. But this doesn’t work and Brian2 raises a parse error. Is there some better way to pass named constants to on_pre, on_post, and other kinds of triggers/actions?

Hi @bjourne. The on_pre statement is not an equation, so this does indeed not work. But I am not 100% sure I understood what you want to do. Do you want to have a hardcoded value there? In this case, you could use standard string processing tools of Python, e.g. on_pre=f"ge_post +=w; w+= {del_w}", passing in the value of del_w from the environment. You could also have an external constant that is only visible by a specific Synapses object by using the namespace argument, e.g.

Synapses(..., on_pre='ge_post +=w; w += del_w', namespace={'del_w': 0.1})

Hope one of these options works for you!

Yes, I can use standard string processing when building the on_pre/post actions. But it becomes kind of messy when you have multiple named constants you want to interpolate into multiple places. F-strings doesn’t work because they call str on the expression and not repr so you have to write `“w += %r” % del_w.

The namespace method could work, but here I think that the value of del_w is not interpolated so this could decrease performance?

Regarding the f-string, you can use them, but they are indeed not super-readable. For using repr you can use !r, e.g. on_pre=f"ge_post +=w; w+= {del_w!r}".

Regarding the performance of using namespace: I doubt it makes a measurable change for the performance. And if you use the C++ standalone mode, then the compiler will most likely do the constant folding for you, so both solutions become basically equivalent.