GeNN  4.9.0
GPU enhanced Neuronal Networks (GeNN)
neuronModels.h
Go to the documentation of this file.
1 #pragma once
2 
3 // Standard includes
4 #include <array>
5 #include <functional>
6 #include <string>
7 #include <tuple>
8 #include <vector>
9 
10 // Standard C includes
11 #include <cmath>
12 
13 // GeNN includes
14 #include "models.h"
15 
16 //----------------------------------------------------------------------------
17 // Macros
18 //----------------------------------------------------------------------------
19 #define SET_SIM_CODE(SIM_CODE) virtual std::string getSimCode() const override{ return SIM_CODE; }
20 #define SET_THRESHOLD_CONDITION_CODE(THRESHOLD_CONDITION_CODE) virtual std::string getThresholdConditionCode() const override{ return THRESHOLD_CONDITION_CODE; }
21 #define SET_RESET_CODE(RESET_CODE) virtual std::string getResetCode() const override{ return RESET_CODE; }
22 #define SET_SUPPORT_CODE(SUPPORT_CODE) virtual std::string getSupportCode() const override{ return SUPPORT_CODE; }
23 #define SET_ADDITIONAL_INPUT_VARS(...) virtual ParamValVec getAdditionalInputVars() const override{ return __VA_ARGS__; }
24 #define SET_NEEDS_AUTO_REFRACTORY(AUTO_REFRACTORY_REQUIRED) virtual bool isAutoRefractoryRequired() const override{ return AUTO_REFRACTORY_REQUIRED; }
25 
26 //----------------------------------------------------------------------------
27 // NeuronModels::Base
28 //----------------------------------------------------------------------------
29 namespace NeuronModels
30 {
33 {
34 public:
35  //----------------------------------------------------------------------------
36  // Declared virtuals
37  //----------------------------------------------------------------------------
39 
41  virtual std::string getSimCode() const{ return ""; }
42 
44 
45  virtual std::string getThresholdConditionCode() const{ return ""; }
46 
48  virtual std::string getResetCode() const{ return ""; }
49 
51 
54  virtual std::string getSupportCode() const{ return ""; }
55 
58  virtual Models::Base::ParamValVec getAdditionalInputVars() const{ return {}; }
59 
61  virtual bool isAutoRefractoryRequired() const{ return true; }
62 
63  //----------------------------------------------------------------------------
64  // Public API
65  //----------------------------------------------------------------------------
67  boost::uuids::detail::sha1::digest_type getHashDigest() const;
68 
70  void validate() const;
71 };
72 
73 //----------------------------------------------------------------------------
74 // NeuronModels::RulkovMap
75 //----------------------------------------------------------------------------
77 
103 class RulkovMap : public Base
104 {
105 public:
107 
108  SET_SIM_CODE(
109  "if ($(V) <= 0) {\n"
110  " $(preV)= $(V);\n"
111  " $(V)= $(ip0)/(($(Vspike)) - $(V) - ($(beta))*$(Isyn)) +($(ip1));\n"
112  "}\n"
113  "else {"
114  " if (($(V) < $(ip2)) && ($(preV) <= 0)) {\n"
115  " $(preV)= $(V);\n"
116  " $(V)= $(ip2);\n"
117  " }\n"
118  " else {\n"
119  " $(preV)= $(V);\n"
120  " $(V)= -($(Vspike));\n"
121  " }\n"
122  "}\n");
123 
124  SET_THRESHOLD_CONDITION_CODE("$(V) >= $(ip2)");
125 
126  SET_PARAM_NAMES({"Vspike", "alpha", "y", "beta"});
127  SET_VARS({{"V","scalar"}, {"preV", "scalar"}});
128 
130  {"ip0", [](const std::vector<double> &pars, double){ return pars[0] * pars[0] * pars[1]; }},
131  {"ip1", [](const std::vector<double> &pars, double){ return pars[0] * pars[2]; }},
132  {"ip2", [](const std::vector<double> &pars, double){ return (pars[0] * pars[1]) + (pars[0] * pars[2]); }}});
133 };
134 
135 //----------------------------------------------------------------------------
136 // NeuronModels::Izhikevich
137 //----------------------------------------------------------------------------
139 
156 class Izhikevich : public Base
157 {
158 public:
160 
161  SET_SIM_CODE(
162  "if ($(V) >= 30.0){\n"
163  " $(V)=$(c);\n"
164  " $(U)+=$(d);\n"
165  "} \n"
166  "$(V)+=0.5*(0.04*$(V)*$(V)+5.0*$(V)+140.0-$(U)+$(Isyn))*DT; //at two times for numerical stability\n"
167  "$(V)+=0.5*(0.04*$(V)*$(V)+5.0*$(V)+140.0-$(U)+$(Isyn))*DT;\n"
168  "$(U)+=$(a)*($(b)*$(V)-$(U))*DT;\n"
169  "if ($(V) > 30.0){ //keep this to not confuse users with unrealistiv voltage values \n"
170  " $(V)=30.0; \n"
171  "}\n");
172 
174 
175  SET_PARAM_NAMES({"a", "b", "c", "d"});
176  SET_VARS({{"V","scalar"}, {"U", "scalar"}});
177 
179 };
180 
181 //----------------------------------------------------------------------------
182 // NeuronModels::IzhikevichVariable
183 //----------------------------------------------------------------------------
185 
199 {
200 public:
202 
204  SET_VARS({{"V","scalar"}, {"U", "scalar"},
205  {"a", "scalar", VarAccess::READ_ONLY}, {"b", "scalar", VarAccess::READ_ONLY},
206  {"c", "scalar", VarAccess::READ_ONLY}, {"d", "scalar", VarAccess::READ_ONLY}});
207 };
208 
209 //----------------------------------------------------------------------------
210 // NeuronModels::LIF
211 //----------------------------------------------------------------------------
212 class LIF : public Base
213 {
214 public:
216 
217  SET_SIM_CODE(
218  "if ($(RefracTime) <= 0.0) {\n"
219  " scalar alpha = (($(Isyn) + $(Ioffset)) * $(Rmembrane)) + $(Vrest);\n"
220  " $(V) = alpha - ($(ExpTC) * (alpha - $(V)));\n"
221  "}\n"
222  "else {\n"
223  " $(RefracTime) -= DT;\n"
224  "}\n"
225  );
226 
227  SET_THRESHOLD_CONDITION_CODE("$(RefracTime) <= 0.0 && $(V) >= $(Vthresh)");
228 
230  "$(V) = $(Vreset);\n"
231  "$(RefracTime) = $(TauRefrac);\n");
232 
234  "C", // Membrane capacitance
235  "TauM", // Membrane time constant [ms]
236  "Vrest", // Resting membrane potential [mV]
237  "Vreset", // Reset voltage [mV]
238  "Vthresh", // Spiking threshold [mV]
239  "Ioffset", // Offset current
240  "TauRefrac"});
241 
243  {"ExpTC", [](const std::vector<double> &pars, double dt){ return std::exp(-dt / pars[1]); }},
244  {"Rmembrane", [](const std::vector<double> &pars, double){ return pars[1] / pars[0]; }}});
245 
246  SET_VARS({{"V", "scalar"}, {"RefracTime", "scalar"}});
247 
249 };
250 
251 //----------------------------------------------------------------------------
252 // NeuronModels::SpikeSource
253 //----------------------------------------------------------------------------
255 
257 class SpikeSource : public Base
258 {
259 public:
261 
264 };
265 
266 //----------------------------------------------------------------------------
267 // NeuronModels::SpikeSourceArray
268 //----------------------------------------------------------------------------
270 
281 class SpikeSourceArray : public Base
282 {
283 public:
287  "$(startSpike) != $(endSpike) && "
288  "$(t) >= $(spikeTimes)[$(startSpike)]" );
289  SET_RESET_CODE( "$(startSpike)++;\n" );
290  SET_VARS( {{"startSpike", "unsigned int"}, {"endSpike", "unsigned int", VarAccess::READ_ONLY_DUPLICATE}} );
291  SET_EXTRA_GLOBAL_PARAMS( {{"spikeTimes", "scalar*"}} );
293 };
294 
295 //----------------------------------------------------------------------------
296 // NeuronModels::Poisson
297 //----------------------------------------------------------------------------
299 
332 class Poisson : public Base
333 {
334 public:
336 
337  SET_SIM_CODE(
338  "if(($(t) - $(spikeTime)) > $(tspike) && $(V) > $(Vrest)){\n"
339  " $(V) = $(Vrest);\n"
340  "}"
341  "else if(($(t) - $(spikeTime)) > $(trefract)){\n"
342  " if($(gennrand_uniform) < $(firingProb)[$(offset) + $(id)]){\n"
343  " $(V) = $(Vspike);\n"
344  " $(spikeTime) = $(t);\n"
345  " }\n"
346  "}\n");
347  SET_THRESHOLD_CONDITION_CODE("$(V) >= $(Vspike)");
348 
349  SET_PARAM_NAMES({"trefract", "tspike", "Vspike", "Vrest"});
350  SET_VARS({{"V", "scalar"}, {"spikeTime", "scalar"}});
351  SET_EXTRA_GLOBAL_PARAMS({{"firingProb", "scalar*"}, {"offset", "unsigned int"}});
352 };
353 
354 //----------------------------------------------------------------------------
355 // NeuronModels::PoissonNew
356 //----------------------------------------------------------------------------
358 
371 class PoissonNew : public Base
372 {
373 public:
375 
376  SET_SIM_CODE(
377  "if($(timeStepToSpike) <= 0.0f) {\n"
378  " $(timeStepToSpike) += $(isi) * $(gennrand_exponential);\n"
379  "}\n"
380  "$(timeStepToSpike) -= 1.0;\n"
381  );
382 
383  SET_THRESHOLD_CONDITION_CODE("$(timeStepToSpike) <= 0.0");
384 
385  SET_PARAM_NAMES({"rate"});
386  SET_VARS({{"timeStepToSpike", "scalar"}});
387  SET_DERIVED_PARAMS({{"isi", [](const std::vector<double> &pars, double dt){ return 1000.0 / (pars[0] * dt); }}});
389 };
390 
391 //----------------------------------------------------------------------------
392 // NeuronModels::TraubMiles
393 //----------------------------------------------------------------------------
395 
439 class TraubMiles : public Base
440 {
441 public:
443 
444  SET_SIM_CODE(
445  "scalar Imem;\n"
446  "unsigned int mt;\n"
447  "scalar mdt= DT/25.0;\n"
448  "for (mt=0; mt < 25; mt++) {\n"
449  " Imem= -($(m)*$(m)*$(m)*$(h)*$(gNa)*($(V)-($(ENa)))+\n"
450  " $(n)*$(n)*$(n)*$(n)*$(gK)*($(V)-($(EK)))+\n"
451  " $(gl)*($(V)-($(El)))-$(Isyn));\n"
452  " scalar _a;\n"
453  " if (lV == -52.0) {\n"
454  " _a= 1.28;\n"
455  " }\n"
456  " else {\n"
457  " _a= 0.32*(-52.0-$(V))/(exp((-52.0-$(V))/4.0)-1.0);\n"
458  " }\n"
459  " scalar _b;\n"
460  " if (lV == -25.0) {\n"
461  " _b= 1.4;\n"
462  " }\n"
463  " else {\n"
464  " _b= 0.28*($(V)+25.0)/(exp(($(V)+25.0)/5.0)-1.0);\n"
465  " }\n"
466  " $(m)+= (_a*(1.0-$(m))-_b*$(m))*mdt;\n"
467  " _a= 0.128*exp((-48.0-$(V))/18.0);\n"
468  " _b= 4.0 / (exp((-25.0-$(V))/5.0)+1.0);\n"
469  " $(h)+= (_a*(1.0-$(h))-_b*$(h))*mdt;\n"
470  " if (lV == -50.0) {\n"
471  " _a= 0.16;\n"
472  " }\n"
473  " else {\n"
474  " _a= 0.032*(-50.0-$(V))/(exp((-50.0-$(V))/5.0)-1.0);\n"
475  " }\n"
476  " _b= 0.5*exp((-55.0-$(V))/40.0);\n"
477  " $(n)+= (_a*(1.0-$(n))-_b*$(n))*mdt;\n"
478  " $(V)+= Imem/$(C)*mdt;\n"
479  "}\n");
480 
482 
483  SET_PARAM_NAMES({"gNa", "ENa", "gK", "EK", "gl", "El", "C"});
484  SET_VARS({{"V", "scalar"}, {"m", "scalar"}, {"h", "scalar"}, {"n", "scalar"}});
485 };
486 
487 //----------------------------------------------------------------------------
488 // NeuronModels::TraubMilesFast
489 //----------------------------------------------------------------------------
491 
495 {
496 public:
498 
499  SET_SIM_CODE(
500  "scalar Imem;\n"
501  "unsigned int mt;\n"
502  "scalar mdt= DT/25.0;\n"
503  "for (mt=0; mt < 25; mt++) {\n"
504  " Imem= -($(m)*$(m)*$(m)*$(h)*$(gNa)*($(V)-($(ENa)))+\n"
505  " $(n)*$(n)*$(n)*$(n)*$(gK)*($(V)-($(EK)))+\n"
506  " $(gl)*($(V)-($(El)))-$(Isyn));\n"
507  " scalar _a= 0.32*(-52.0-$(V))/(exp((-52.0-$(V))/4.0)-1.0);\n"
508  " scalar _b= 0.28*($(V)+25.0)/(exp(($(V)+25.0)/5.0)-1.0);\n"
509  " $(m)+= (_a*(1.0-$(m))-_b*$(m))*mdt;\n"
510  " _a= 0.128*exp((-48.0-$(V))/18.0);\n"
511  " _b= 4.0 / (exp((-25.0-$(V))/5.0)+1.0);\n"
512  " $(h)+= (_a*(1.0-$(h))-_b*$(h))*mdt;\n"
513  " _a= 0.032*(-50.0-$(V))/(exp((-50.0-$(V))/5.0)-1.0);\n"
514  " _b= 0.5*exp((-55.0-$(V))/40.0);\n"
515  " $(n)+= (_a*(1.0-$(n))-_b*$(n))*mdt;\n"
516  " $(V)+= Imem/$(C)*mdt;\n"
517  "}\n");
518 };
519 
520 //----------------------------------------------------------------------------
521 // NeuronModels::TraubMilesAlt
522 //----------------------------------------------------------------------------
524 
527 class TraubMilesAlt : public TraubMiles
528 {
529 public:
531 
532  SET_SIM_CODE(
533  "scalar Imem;\n"
534  "unsigned int mt;\n"
535  "scalar mdt= DT/25.0;\n"
536  "for (mt=0; mt < 25; mt++) {\n"
537  " Imem= -($(m)*$(m)*$(m)*$(h)*$(gNa)*($(V)-($(ENa)))+\n"
538  " $(n)*$(n)*$(n)*$(n)*$(gK)*($(V)-($(EK)))+\n"
539  " $(gl)*($(V)-($(El)))-$(Isyn));\n"
540  " scalar volatile _tmp= abs(exp((-52.0-$(V))/4.0)-1.0);\n"
541  " scalar _a= 0.32*abs(-52.0-$(V))/(_tmp+SCALAR_MIN);\n"
542  " _tmp= abs(exp(($(V)+25.0)/5.0)-1.0);\n"
543  " scalar _b= 0.28*abs($(V)+25.0)/(_tmp+SCALAR_MIN);\n"
544  " $(m)+= (_a*(1.0-$(m))-_b*$(m))*mdt;\n"
545  " _a= 0.128*exp((-48.0-$(V))/18.0);\n"
546  " _b= 4.0 / (exp((-25.0-$(V))/5.0)+1.0);\n"
547  " $(h)+= (_a*(1.0-$(h))-_b*$(h))*mdt;\n"
548  " _tmp= abs(exp((-50.0-$(V))/5.0)-1.0);\n"
549  " _a= 0.032*abs(-50.0-$(V))/(_tmp+SCALAR_MIN);\n"
550  " _b= 0.5*exp((-55.0-$(V))/40.0);\n"
551  " $(n)+= (_a*(1.0-$(n))-_b*$(n))*mdt;\n"
552  " $(V)+= Imem/$(C)*mdt;\n"
553  "}\n");
554 };
555 
556 //----------------------------------------------------------------------------
557 // NeuronModels::TraubMilesNStep
558 //----------------------------------------------------------------------------
560 
564 {
565 public:
567 
568  SET_SIM_CODE(
569  "scalar Imem;\n"
570  "unsigned int mt;\n"
571  "scalar mdt= DT/scalar($(ntimes));\n"
572  "for (mt=0; mt < $(ntimes); mt++) {\n"
573  " Imem= -($(m)*$(m)*$(m)*$(h)*$(gNa)*($(V)-($(ENa)))+\n"
574  " $(n)*$(n)*$(n)*$(n)*$(gK)*($(V)-($(EK)))+\n"
575  " $(gl)*($(V)-($(El)))-$(Isyn));\n"
576  " scalar _a;\n"
577  " if (lV == -52.0) {\n"
578  " _a= 1.28;\n"
579  " }\n"
580  " else {\n"
581  " _a= 0.32*(-52.0-$(V))/(exp((-52.0-$(V))/4.0)-1.0);\n"
582  " }\n"
583  " scalar _b;\n"
584  " if (lV == -25.0) {\n"
585  " _b= 1.4;\n"
586  " }\n"
587  " else {\n"
588  " _b= 0.28*($(V)+25.0)/(exp(($(V)+25.0)/5.0)-1.0);\n"
589  " }\n"
590  " $(m)+= (_a*(1.0-$(m))-_b*$(m))*mdt;\n"
591  " _a= 0.128*exp((-48.0-$(V))/18.0);\n"
592  " _b= 4.0 / (exp((-25.0-$(V))/5.0)+1.0);\n"
593  " $(h)+= (_a*(1.0-$(h))-_b*$(h))*mdt;\n"
594  " if (lV == -50.0) {\n"
595  " _a= 0.16;\n"
596  " }\n"
597  " else {\n"
598  " _a= 0.032*(-50.0-$(V))/(exp((-50.0-$(V))/5.0)-1.0);\n"
599  " }\n"
600  " _b= 0.5*exp((-55.0-$(V))/40.0);\n"
601  " $(n)+= (_a*(1.0-$(n))-_b*$(n))*mdt;\n"
602  " $(V)+= Imem/$(C)*mdt;\n"
603  "}\n");
604 
605  SET_PARAM_NAMES({"gNa", "ENa", "gK", "EK", "gl", "El", "C", "ntimes"});
606 };
607 } // NeuronModels
virtual std::string getSupportCode() const
Gets support code to be made available within the neuron kernel/funcion.
Definition: neuronModels.h:54
#define SET_VARS(...)
Definition: models.h:39
Izhikevich neuron with fixed parameters .
Definition: neuronModels.h:156
Hodgkin-Huxley neurons with Traub & Miles algorithm.
Definition: neuronModels.h:563
#define SET_NEEDS_AUTO_REFRACTORY(AUTO_REFRACTORY_REQUIRED)
Definition: neuronModels.h:24
Hodgkin-Huxley neurons with Traub & Miles algorithm: Original fast implementation, using 25 inner iterations.
Definition: neuronModels.h:494
Hodgkin-Huxley neurons with Traub & Miles algorithm.
Definition: neuronModels.h:439
Definition: models.h:48
#define GENN_EXPORT
Definition: gennExport.h:13
virtual std::string getResetCode() const
Gets code that defines the reset action taken after a spike occurred. This can be empty...
Definition: neuronModels.h:48
virtual std::string getSimCode() const
Gets the code that defines the execution of one timestep of integration of the neuron model...
Definition: neuronModels.h:41
virtual Models::Base::ParamValVec getAdditionalInputVars() const
Definition: neuronModels.h:58
#define SET_SIM_CODE(SIM_CODE)
Definition: neuronModels.h:19
Poisson neurons.
Definition: neuronModels.h:371
Poisson neurons.
Definition: neuronModels.h:332
#define SET_THRESHOLD_CONDITION_CODE(THRESHOLD_CONDITION_CODE)
Definition: neuronModels.h:20
#define DECLARE_MODEL(TYPE, NUM_PARAMS, NUM_VARS)
Definition: models.h:31
#define SET_RESET_CODE(RESET_CODE)
Definition: neuronModels.h:21
Rulkov Map neuron.
Definition: neuronModels.h:103
Spike source array.
Definition: neuronModels.h:281
Definition: neuronModels.h:212
virtual std::string getThresholdConditionCode() const
Gets code which defines the condition for a true spike in the described neuron model.
Definition: neuronModels.h:45
#define SET_DERIVED_PARAMS(...)
Definition: snippet.h:37
Izhikevich neuron with variable parameters .
Definition: neuronModels.h:198
virtual bool isAutoRefractoryRequired() const
Does this model require auto-refractory logic?
Definition: neuronModels.h:61
Hodgkin-Huxley neurons with Traub & Miles algorithm.
Definition: neuronModels.h:527
#define SET_PARAM_NAMES(...)
Definition: snippet.h:36
Base class for all neuron models.
Definition: neuronModels.h:32
Definition: neuronModels.h:29
#define SET_EXTRA_GLOBAL_PARAMS(...)
Definition: snippet.h:38
Empty neuron which allows setting spikes from external sources.
Definition: neuronModels.h:257
std::vector< ParamVal > ParamValVec
Definition: snippet.h:180