nest / nestml

A domain specific language for neuron and synapse models in spiking neural network simulation
GNU General Public License v2.0
44 stars 46 forks source link

Issue in using sine and cosine functions in kernel definition #1074

Open Geenetto opened 3 days ago

Geenetto commented 3 days ago

Hi! I am using the latest version of the NESTML master branch, with the sine and cosine implementation. I wrote two NESTML codes for stdp synapses, which present sine and cosine functions in the kernel function. the synapses equations are the following: kernel K = (1. / C) * exp((-t-t0)/tau) * sin(2*pi*((t-t0)/tau)) for sine stdp synapse

kernel K =exp(-abs(t)/tau) * cos(t/tau) * cos(t/tau) for the cosine stdp synapse

Also, for both of the kernel equations, I did the convolution with the presynaptic spike: inline w_conv real = convolve(K, pre_spikes)

It happens that building the models gives me two different results: -the code execution just keeps running indefinetly without generating anything -only in the sine stdp gives me this error File "~/Documents/workspace/bsb-nest/lib/python3.10/site-packages/odetoolbox/system_of_shapes.py", line 193, in generate_propagator_solver raise PropagatorGenerationException("The imaginary unit was found in the propagator matrix. This can happen if the dynamical system that was passed to ode-toolbox is unstable, i.e. one or more state variables will diverge to minus or positive infinity.") odetoolbox.system_of_shapes.PropagatorGenerationException: The imaginary unit was found in the propagator matrix. This can happen if the dynamical system that was passed to ode-toolbox is unstable, i.e. one or more state variables will diverge to minus or positive infinity.

Also, if I remove the sine or cosine functions from the kernel equations, or if I put only a constant in the functions' argument (i.e. sin(100)), the models build correctly

What can I do to solve this problem? Is it a syntax issue in the kernel equation or is something else?

clinssen commented 2 days ago

Hi, thanks again for writing in! Sorry, I did not realise you wanted to use sin() and cos() in a kernel inside a synapse. This runs into the following issue: for computational efficiency reasons, NEST Simulator only updates the synapse state when a spike is processed, rather than at every simulation timestep. This means that by default, no numeric solver (like forward Euler or Runge-Kutta) is supported for numerics in the synapse; only "propagator" solvers are supported. (This is a limitation of NEST and not NESTML per se.)

There are several ways to work around this issue: 1) if you can derive a propagator by algebraic means, you can program this directly into the update block of the synapse model. 2) a workaround is to write your own little forward Euler integrator inside the update block, which steps in small constant timestep between the spike times (it's like an integration loop inside an integration loop). I have attached an example that implements this: forward_euler_in_synapse.tar.gz 3) we could try to add proper GSL solver support to synapses. However, note that memory consumption and compute time could become very large for larger networks.

Geenetto commented 2 days ago

Thank you very much. I'll try the first and second solution that you proposed and I'll let you know if everything goes well.

Thanks again :)