diff options
Diffstat (limited to 'code/core/event.cpp')
-rw-r--r-- | code/core/event.cpp | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/code/core/event.cpp b/code/core/event.cpp new file mode 100644 index 0000000..cb6f5ff --- /dev/null +++ b/code/core/event.cpp @@ -0,0 +1,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)); +} |