Hi @bindok. Unfortunately, I do not have the time for an exhaustive response right now, maybe someone else can jump in. Brian has a system to support arbitrary functions that you can define in code, but this is a mechanism that is used/necessary only for functions that you cannot write down as simple expressions based on existing functions. E.g., while in theory you could enhance Brian’s function system by a function inverse
that is defined as inverse(x) = 1/x
, in practice you’d use what we call a “subexpression” (see e.g. Models and neuron groups — Brian 2 2.5.4 documentation). An equation (just for illustration, not making sense): \frac{dv}{dt} = -v \cdot \text{inverse}(\tau) : volt would be written in Brian as:
"""
dv/dt = -v * inverse : volt
inverse = 1/tau : 1/second
"""
Here, inverse
isn’t really a function, but just a convenience replacement for better readability. The code is exactly equivalent to
"""
dv/dt = -v * (1/tau) : volt
"""
For your code this means to write simply F
in the equation for Ssyn
(instead of F(...)
), and define F
as
F = 1/(1+exp(-(vpre-thetasyn)/sigmasyn)) : 1
We’ve discussed having a more generic system that would be useful if you re-use the same function with different parameters several times (where with Brian’s approach you’d need to repeat the subexpression with different names), but for now we don’t have this – but then, it doesn’t seem to be necessary for your use case.
Note that the above isn’t exactly correct, since your equations state v_{\text{pre}}(t - \tau_d), i.e refer to the membrane potential from the past. This isn’t actually possible at the moment in Brian (again, there had been discussions to add this feature, but it is non-trivial to implement). Currently, these exact equations can only been implemented using network_operation
or user-defined functions (see Delay in continuous connections for a lot of pointers). But in my experience, using the sigmoid function of the pre-synaptic membrane potential with a continuous delayed connection is often unnecessarily complex, replacing it with a computationally simpler spike-based connection or (if necessary) with a more abstract implementation like a “square pulse” (see "Square" signal in response to spike) will most likely not change the result in a meaningful way.
Hope that helps a bit at least!