summaryrefslogtreecommitdiff
path: root/code/core/event.cpp
blob: cb6f5ff7d9d51a26ef005506a430c78dd43f247e (plain)
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));
}
contact: Jan Huwald // Impressum