Hi!
I have the following
#!/usr/bin/env python3
from brian2 import *
@check_units(x=1, result=1)
def heaviside(x):
return (x > 0).astype(int)
neuron = NeuronGroup(1, "dv/dt = -v/(1*ms) : 1", method='euler')
ssg = SpikeGeneratorGroup(1, [0], [0*ms])
syn = Synapses(ssg, neuron, "dx/dt = 3/ms*heaviside(x - 1) - 4/ms*heaviside(-(x+2)) : 1")
run(1*ms)
Which fails with
NotImplementedError: The expression "3/ms*heaviside(x - 1) - 4/ms*heaviside(-(x+2))" contains more than one call of heaviside, this is currently not supported since heaviside is a stateful function and its multiple calls might be treated incorrectly (e.g."rand() - rand()" could be simplified to "0.0").
How do I tell Brian2 that my function is not stateful?
Thanks,
Sebastian
Hmm, that’s odd, user-defined functions should default to being stateless I think. I’ll have to check this again, but in the meantime adding the following (somewhat redundant) statement after your function definition should do the trick:
heaviside = Function(heaviside)
Also note that you don’t really need to define your own heaviside function, you can use e.g. int(x > 1) directly in the equations (which will then work with C++ etc. automatically).
2 Likes
Hi, I have also been looking for a way to implement the Heaviside function. Is this still the optimal solution?
I found this in the docs:
Brian also provides a special purpose function int, which can be used to convert an expression or variable into an integer value. This is especially useful for boolean values (which will be converted into 0 or 1), for example to have a conditional evaluation as part of an equation or statement which sometimes allows to circumvent the lack of an if statement. For example, the following reset statement resets the variable v to either v_r1 or v_r2, depending on the value of w:'v = v_r1 * int(w <= 0.5) + v_r2 * int(w > 0.5)'
Thank you.
Hi @mpagkalos . Yes, using something like int(x > 1) would still be the best way to implement a Heaviside function.
1 Like
That’s actually a very neat trick!
Thanks 
1 Like
Replying to this thread to add that I have the same problem with this function:
def f(x, g=1, r_0=20, r_max=100):
r_neg = r_0*tanh(g*x/r_0)
r_pos = (r_max-r_0)*tanh(g*x/(r_max-r_0))
return int(x >= 0)*r_pos + int(x < 0)*r_neg
I don’t know if this is a known issue by now but I thought mentioning would be beneficial.