1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#include "simulate.h"
#include "event.h"
void Event::execute() {
switch (type) {
case 0:
((InternalSpike*) this)->execute();
break;
case 1:
((ExternalSpike*) this)->execute();
break;
case 2:
((ExternalNoise*) this)->execute();
break;
case 3:
((IntrinsicNeuron*) this)->execute();
break;
case 4:
((VirtualEvent*) this)->vexecute();
break;
}
}
void Event::free() {
switch (type) {
case 0:
delete (InternalSpike*) this;
break;
case 1:
delete (ExternalSpike*) this;
break;
case 2:
delete (ExternalNoise*) this;
break;
case 3:
delete (IntrinsicNeuron*) this;
break;
case 4:
delete (VirtualEvent*) this;
break;
}
}
// comparison of two events regarding their order in the event list; spike events are processed prior to non-spike events (as spikes are incoming and non-spike are intrinsic and depending on all events up to the present)
bool Event::operator>(Event &e) {
return (time > e.time) || ((time == e.time) && (type > e.type));
}
void Spike::execute() {
double nextEventTime = s.neurons[dst].processCurrent(time, current);
// check if there is an event to occur
if (nextEventTime != INFINITY)
s.addEvent(new IntrinsicNeuron(nextEventTime, dst));
}
void ExternalSpike::execute() {
// exec common spike code
((Spike *) this)->execute();
}
void InternalSpike::execute() {
// the spike has to be registered as delieverd in the sending synapse
synapse->lastSpike = time;
if (synapse->firstSpike == -INFINITY)
synapse->firstSpike = time;
// exec common spike code
((Spike *) this)->execute();
// synaptic scaling
s.neurons[dst].normalizeWeight(g.sumWeight);
}
void IntrinsicNeuron::execute() {
// check if a spike does occur
bool spikeDoesOccur;
double nextEventTime = s.neurons[dst].generateSpike(time, spikeDoesOccur);
// check if a spike should be generated
if (!spikeDoesOccur)
return;
// add next intrinsic event
if (nextEventTime != INFINITY)
s.addEvent(new IntrinsicNeuron(nextEventTime, dst));
// create the spike for every neuron where it will be recieved
for (SynapseDstList::iterator i = s.neurons[dst].sout.begin(); i != s.neurons[dst].sout.end(); i++) {
double ntime = time, ncurrent;
i->computePostsynapticPulse(ntime, ncurrent);
s.addEvent(new InternalSpike(ntime, i->dst, ncurrent, &(*i)));
}
// check if we should output a spike of this neuron
for (s.spikeOIfList.iterator i = s.spikeOIfList.begin(); i != s.spikeOIfList.end(); i++)
if (i->isContained(dst)) {
SpikeMUX s(dst, time);
i->pushObject(s);
}
// bin spikes
for (std::set<Bin*>::iterator bin = s.binSets.begin(); bin != s.to.traceBinSets.end(); bin++)
(*bin)->bin(dst);
}
void ExternalNoise::execute() {
// pick a random neuron to send noise to (using a temporary event)
s.addEvent(new ExternalSpike(time, rand() % (s.numNeurons * 4 / 5), g.en_current));
// select the next timepoint from a poisson process
s.addEvent(new ExternalNoise(time - (log(1.0 - drand48()) / (g.en_freq * s.numNeurons))));
}
virtual void GlobalUpdate::vexecute() {
static const double td = 0.001;
g.evolve(td);
s.addEvent(new GlobalUpdate(time + td));
}
|