#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::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)); }