yinspire 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/README +24 -0
  2. data/bench/pq/Makefile +5 -0
  3. data/bench/pq/bench.cc +321 -0
  4. data/bench/pq/bench.rb +125 -0
  5. data/bench/pq/bench_binaryheap.h +46 -0
  6. data/bench/pq/bench_calendarqueue.h +58 -0
  7. data/bench/pq/bench_pairingheap.h +61 -0
  8. data/bench/pq/bench_stlpq.h +46 -0
  9. data/bench/pq/benchmark.h +225 -0
  10. data/bench/pq/distribution.h +93 -0
  11. data/bench/pq/make.rb +24 -0
  12. data/bin/yinspire +186 -0
  13. data/examples/nets/gereon2005.c.json +93723 -0
  14. data/examples/nets/gereon2005.yin +232650 -0
  15. data/examples/nets/skorpion.graphml +396 -0
  16. data/examples/nets/spiketrains_angle_180.txt +8 -0
  17. data/lib/Algorithms/Array.h +52 -0
  18. data/lib/Algorithms/BinaryHeap.h +265 -0
  19. data/lib/Algorithms/CalendarQueue.h +257 -0
  20. data/lib/Algorithms/IndexedBinaryHeap.h +90 -0
  21. data/lib/Algorithms/PairingHeap.h +169 -0
  22. data/lib/Allocators/ChunkedFreelistAllocator.h +96 -0
  23. data/lib/Allocators/MemoryAllocator.h +45 -0
  24. data/lib/Allocators/RubyMemoryAllocator.h +37 -0
  25. data/lib/Yinspire.rb +69 -0
  26. data/lib/Yinspire/All.rb +10 -0
  27. data/lib/Yinspire/Core/NeuralEntity.rb +133 -0
  28. data/lib/Yinspire/Core/Neuron.rb +162 -0
  29. data/lib/Yinspire/Core/Scheduling/NeuralEntity.rb +123 -0
  30. data/lib/Yinspire/Core/Scheduling/Simulator.rb +94 -0
  31. data/lib/Yinspire/Core/Simulator.rb +36 -0
  32. data/lib/Yinspire/Core/StimuliMixin.rb +103 -0
  33. data/lib/Yinspire/Core/Stimulus.rb +25 -0
  34. data/lib/Yinspire/Core/Synapse.rb +64 -0
  35. data/lib/Yinspire/Dumpers/Dumper.rb +19 -0
  36. data/lib/Yinspire/Dumpers/Dumper_Dot.rb +28 -0
  37. data/lib/Yinspire/Loaders/GraphML.rb +84 -0
  38. data/lib/Yinspire/Loaders/Loader.rb +31 -0
  39. data/lib/Yinspire/Loaders/Loader_GraphML.rb +97 -0
  40. data/lib/Yinspire/Loaders/Loader_JSON.rb +181 -0
  41. data/lib/Yinspire/Loaders/Loader_Spike.rb +42 -0
  42. data/lib/Yinspire/Loaders/Loader_Yin.rb +62 -0
  43. data/lib/Yinspire/Loaders/YinScanner.rb +247 -0
  44. data/lib/Yinspire/Models/Neuron_Base.rb +38 -0
  45. data/lib/Yinspire/Models/Neuron_Input.rb +12 -0
  46. data/lib/Yinspire/Models/Neuron_InputOutput.rb +39 -0
  47. data/lib/Yinspire/Models/Neuron_Output.rb +15 -0
  48. data/lib/Yinspire/Models/Neuron_SRM01.rb +50 -0
  49. data/lib/Yinspire/Models/Neuron_SRM02.rb +64 -0
  50. data/lib/Yinspire/Models/Synapse_Hebb.rb +67 -0
  51. data/pure_cpp/Makefile +22 -0
  52. data/pure_cpp/README +2 -0
  53. data/pure_cpp/src/algo/binary_heap.h +277 -0
  54. data/pure_cpp/src/algo/indexed_binary_heap.h +90 -0
  55. data/pure_cpp/src/json/json.cc +542 -0
  56. data/pure_cpp/src/json/json.h +182 -0
  57. data/pure_cpp/src/json/json_parser.cc +685 -0
  58. data/pure_cpp/src/json/json_parser.h +15 -0
  59. data/pure_cpp/src/json/json_parser.rl +213 -0
  60. data/pure_cpp/src/main.cc +49 -0
  61. data/pure_cpp/src/memory_allocator.h +45 -0
  62. data/pure_cpp/src/neural_entity.cc +208 -0
  63. data/pure_cpp/src/neural_entity.h +243 -0
  64. data/pure_cpp/src/neuron.cc +136 -0
  65. data/pure_cpp/src/neuron.h +70 -0
  66. data/pure_cpp/src/neuron_srm_01.cc +77 -0
  67. data/pure_cpp/src/neuron_srm_01.h +36 -0
  68. data/pure_cpp/src/simulator.cc +151 -0
  69. data/pure_cpp/src/simulator.h +116 -0
  70. data/pure_cpp/src/synapse.cc +117 -0
  71. data/pure_cpp/src/synapse.h +60 -0
  72. data/pure_cpp/src/types.h +18 -0
  73. data/run.rb +68 -0
  74. data/tools/conv_jsonc_to_yin.rb +165 -0
  75. data/tools/converter.rb +93 -0
  76. data/tools/json_writer.rb +122 -0
  77. data/yinspire.gemspec +20 -0
  78. metadata +156 -0
@@ -0,0 +1,243 @@
1
+ #ifndef __YINSPIRE__NEURAL_ENTITY__
2
+ #define __YINSPIRE__NEURAL_ENTITY__
3
+
4
+ #include "types.h"
5
+ #include "memory_allocator.h"
6
+ #include "algo/binary_heap.h"
7
+ #include "json/json.h"
8
+
9
+ class Simulator; // forward declaration
10
+
11
+ /*
12
+ * The data structure used for storing a fire impluse or any other form
13
+ * of stimulation.
14
+ */
15
+ struct Stimulus
16
+ {
17
+ simtime at;
18
+ real weight;
19
+
20
+ inline static bool
21
+ less(const Stimulus &a, const Stimulus &b)
22
+ {
23
+ return (a.at < b.at);
24
+ }
25
+ };
26
+
27
+ /*
28
+ * The NeuralEntity is the base class of all entities in a neural net,
29
+ * i.e. Neurons and Synapses.
30
+ */
31
+ class NeuralEntity
32
+ {
33
+ protected:
34
+
35
+ /*
36
+ * Each NeuralEntity has a pointer to the Simulator.
37
+ * This is used for example to update it's scheduling
38
+ * or to report a fire event.
39
+ *
40
+ * It's assigned by the Simulator!
41
+ */
42
+ Simulator *simulator;
43
+
44
+ /*
45
+ * Each NeuralEntity has an +id+ associated which uniquely
46
+ * identifies itself within a Simulator instance. This +id+ is
47
+ * assigned by the Simulator and should not be changed by the
48
+ * NeuralEntity itself.
49
+ *
50
+ * The reference is NOT owned by the NeuralEntity. It's the
51
+ * responsibility of the Simulator to allocate and free the memory!
52
+ */
53
+ const char *id;
54
+
55
+ /*
56
+ * Index of this entity in the entity priority queue managed by the
57
+ * Simulator. If schedule_index is zero then the entity is currently
58
+ * not present in the priority queue and as such the entity is not
59
+ * scheduled for a specific time.
60
+ */
61
+ uint schedule_index;
62
+
63
+ /*
64
+ * The timestamp of the earliest event in the local priority queue.
65
+ */
66
+ simtime schedule_at;
67
+
68
+ /*
69
+ * If stepped scheduling is used, points to the previous/next
70
+ * entity in the schedule list.
71
+ */
72
+ NeuralEntity *schedule_stepping_list_prev;
73
+ NeuralEntity *schedule_stepping_list_next;
74
+
75
+ /*
76
+ * To be able to modify the stepped scheduling list
77
+ * (schedule_stepping_list_prev/next) during stepped schedule
78
+ * processing, we build up an internal linked list that we use to
79
+ * traverse all entities that require stepped schedule processing.
80
+ *
81
+ * This is cheaper than using an externalized linked list, as we
82
+ * would have to allocate memory, which we overcome with this
83
+ * approach.
84
+ *
85
+ * This is only used by the simulator!
86
+ */
87
+ NeuralEntity *schedule_stepping_list_internal_next;
88
+
89
+ /*
90
+ * Each NeuralEntity has it's own local stimuli priority queue.
91
+ * Neurons make use of this whereas Synapses currently not.
92
+ *
93
+ * It's a quite low overhead to have this in the NeuralEntity class,
94
+ * just around 12 additional bytes.
95
+ */
96
+ BinaryHeap<Stimulus, MemoryAllocator<Stimulus> > stimuli_pq;
97
+
98
+ public:
99
+
100
+ /*
101
+ * Constructor
102
+ */
103
+ NeuralEntity();
104
+
105
+ /*
106
+ * Destructor
107
+ */
108
+ virtual ~NeuralEntity();
109
+
110
+ /*
111
+ * Load the internal state of a NeuralEntity
112
+ * from +data+.
113
+ *
114
+ * Note that loading does not neccessarily reset
115
+ * the internal state of the entity!
116
+ */
117
+ virtual void load(jsonHash *data);
118
+
119
+ /*
120
+ * Dump the internal state of a NeuralEntity
121
+ * and return it. Internal state does not contain
122
+ * the network connection (they have to be dumped
123
+ * separatly by the simulator using +each_connection+.
124
+ */
125
+ virtual void dump(jsonHash *into);
126
+
127
+ /*
128
+ * Connect +self+ with +target+.
129
+ */
130
+ virtual void connect(NeuralEntity *target) = 0;
131
+
132
+ /*
133
+ * Disconnect +self+ from +target+.
134
+ */
135
+ virtual void disconnect(NeuralEntity *target) = 0;
136
+
137
+ /*
138
+ * Disconnect from all connections. Uses +each_connection+ and
139
+ * +disconnect+.
140
+ */
141
+ void disconnect_all();
142
+
143
+ /*
144
+ * Calls the iterator function for each outgoing connection.
145
+ */
146
+ virtual void each_connection(
147
+ void (*yield)(NeuralEntity *self, NeuralEntity *conn)) = 0;
148
+
149
+ /*
150
+ * Stimulate an entity at a specific time with a specific weight.
151
+ */
152
+ virtual void stimulate(simtime at, real weight, NeuralEntity *source) = 0;
153
+
154
+ /*
155
+ * This method is called when a NeuralEntity reached it's scheduling
156
+ * time.
157
+ *
158
+ * Overwrite it if you need this behaviour.
159
+ */
160
+ virtual void
161
+ process(simtime at)
162
+ {
163
+ throw "Abstract method";
164
+ }
165
+
166
+ /*
167
+ * This method is called in each time-step, if a NeuralEntity
168
+ * uses stepped scheduling.
169
+ *
170
+ * Overwrite it if you need this behaviour.
171
+ */
172
+ virtual void
173
+ process_stepped(simtime at, simtime step)
174
+ {
175
+ throw "Abstract method";
176
+ }
177
+
178
+ /*
179
+ * Attribute accessor functions
180
+ */
181
+ void set_simulator(Simulator *simulator);
182
+ void set_id(const char *id);
183
+ Simulator *get_simulator() const;
184
+ const char *get_id() const;
185
+ inline simtime get_schedule_at() const { return this->schedule_at; }
186
+
187
+ protected:
188
+
189
+ /*
190
+ * Schedules the entity at a specific time.
191
+ */
192
+ void schedule(simtime at);
193
+
194
+ /*
195
+ * Returns true if stepped scheduling is enabled.
196
+ */
197
+ bool schedule_stepping_enabled();
198
+
199
+ /*
200
+ * Enable/Disable stepped scheduling.
201
+ */
202
+ void schedule_enable_stepping();
203
+ void schedule_disable_stepping();
204
+
205
+ /*
206
+ * Add a Stimuli to the local pq.
207
+ */
208
+ void stimuli_add(simtime at, real weight);
209
+
210
+ /*
211
+ * Sum all Stimuli until +until+.
212
+ */
213
+ real stimuli_sum(simtime until);
214
+
215
+ /*
216
+ * Sum all Stimuli until +until+, but treat infinite values
217
+ * differently. Do not sum them, instead set +is_inf+ to true.
218
+ */
219
+ real stimuli_sum_inf(simtime until, bool &is_inf);
220
+
221
+ public:
222
+
223
+ /*
224
+ * Accessor function for BinaryHeap
225
+ */
226
+ inline static bool
227
+ less(const NeuralEntity *a, const NeuralEntity *b)
228
+ {
229
+ return (a->schedule_at < b->schedule_at);
230
+ }
231
+
232
+ /*
233
+ * Accessor function for BinaryHeap
234
+ */
235
+ inline static uint &
236
+ index(NeuralEntity *self)
237
+ {
238
+ return self->schedule_index;
239
+ }
240
+
241
+ };
242
+
243
+ #endif
@@ -0,0 +1,136 @@
1
+ #include "neuron.h"
2
+ #include "synapse.h"
3
+ #include <math.h>
4
+ #include <assert.h>
5
+ #include "simulator.h" // ?
6
+
7
+ Neuron::Neuron()
8
+ {
9
+ this->first_pre_synapse = NULL;
10
+ this->first_post_synapse = NULL;
11
+ this->abs_refr_duration = 0.0;
12
+ this->last_spike_time = -INFINITY;
13
+ this->last_fire_time = -INFINITY;
14
+ this->hebb = false;
15
+ }
16
+
17
+ void
18
+ Neuron::dump(jsonHash *into)
19
+ {
20
+ }
21
+
22
+ void
23
+ Neuron::load(jsonHash *data)
24
+ {
25
+ super::load(data);
26
+
27
+ this->abs_refr_duration = data->get_number("abs_refr_duration", 0.0);
28
+ this->last_spike_time = data->get_number("last_spike_time", -INFINITY);
29
+ this->last_fire_time = data->get_number("last_fire_time", -INFINITY);
30
+ this->hebb = data->get_bool("hebb", false);
31
+ }
32
+
33
+ void
34
+ Neuron::each_connection(void (*yield)(NeuralEntity *self, NeuralEntity *conn))
35
+ {
36
+ for (Synapse *syn = this->first_post_synapse; syn != NULL;
37
+ syn = syn->next_post_synapse)
38
+ {
39
+ yield(this, syn);
40
+ }
41
+ }
42
+
43
+ void
44
+ Neuron::stimulate(simtime at, real weight, NeuralEntity *source)
45
+ {
46
+ stimuli_add(at, weight);
47
+ }
48
+
49
+ /*
50
+ * Adding a post synapse. Target must be a Synapse.
51
+ *
52
+ * O(1)
53
+ */
54
+ void
55
+ Neuron::connect(NeuralEntity *target)
56
+ {
57
+ Synapse *syn = dynamic_cast<Synapse*>(target);
58
+
59
+ if (syn->pre_neuron != NULL || syn->next_post_synapse != NULL)
60
+ throw "Synapse already connected";
61
+
62
+ syn->next_post_synapse = this->first_post_synapse;
63
+ this->first_post_synapse = syn;
64
+ syn->pre_neuron = this;
65
+ }
66
+
67
+ /*
68
+ * O(n)
69
+ */
70
+ void
71
+ Neuron::disconnect(NeuralEntity *target)
72
+ {
73
+ Synapse *syn = dynamic_cast<Synapse*>(target);
74
+
75
+ if (syn->pre_neuron != this)
76
+ throw "Synapse not connected to this Neuron";
77
+
78
+ /*
79
+ * Find the synapse in the linked list that precedes +syn+.
80
+ */
81
+ Synapse *prev = NULL;
82
+ Synapse *curr = this->first_post_synapse;
83
+
84
+ while (true)
85
+ {
86
+ if (curr == NULL) break;
87
+ if (curr == syn) break;
88
+ prev = curr;
89
+ curr = curr->next_post_synapse;
90
+ }
91
+
92
+ if (curr != syn)
93
+ throw "Synapse not in post synapse list";
94
+
95
+ /*
96
+ * Remove syn from linked list
97
+ */
98
+ if (prev == NULL)
99
+ {
100
+ /*
101
+ * syn is the last synapse in the post synapse list.
102
+ */
103
+ assert(this->first_post_synapse == syn);
104
+ this->first_post_synapse = NULL;
105
+ }
106
+ else
107
+ {
108
+ prev->next_post_synapse = syn->next_post_synapse;
109
+ }
110
+
111
+ syn->pre_neuron = NULL;
112
+ syn->next_post_synapse = NULL;
113
+ }
114
+
115
+ /*
116
+ * NOTE: The stimulation weight is 0.0 below
117
+ * as the synapse will add it's weight to the
118
+ * preceding neurons.
119
+ */
120
+ void
121
+ Neuron::fire_synapses(simtime at)
122
+ {
123
+ if (this->hebb)
124
+ {
125
+ for (Synapse *syn = this->first_pre_synapse; syn != NULL;
126
+ syn = syn->next_pre_synapse)
127
+ {
128
+ syn->stimulate(at, 0.0, this);
129
+ }
130
+ }
131
+ for (Synapse *syn = this->first_post_synapse; syn != NULL;
132
+ syn = syn->next_post_synapse)
133
+ {
134
+ syn->stimulate(at, 0.0, this);
135
+ }
136
+ }
@@ -0,0 +1,70 @@
1
+ #ifndef __YINSPIRE__NEURON__
2
+ #define __YINSPIRE__NEURON__
3
+
4
+ #include "neural_entity.h"
5
+
6
+ class Synapse; // forward declaration
7
+
8
+ /*
9
+ * The base class of all neurons.
10
+ */
11
+ class Neuron : public NeuralEntity
12
+ {
13
+ friend class Synapse;
14
+ typedef NeuralEntity super;
15
+
16
+ protected:
17
+
18
+ /*
19
+ * Pointers to the first pre/post synapse
20
+ */
21
+ Synapse *first_pre_synapse;
22
+ Synapse *first_post_synapse;
23
+
24
+ /*
25
+ * Duration of the absolute refraction period.
26
+ */
27
+ simtime abs_refr_duration;
28
+
29
+ /*
30
+ * Last spike time
31
+ */
32
+ simtime last_spike_time;
33
+
34
+ /*
35
+ * Last fire time
36
+ */
37
+ simtime last_fire_time;
38
+
39
+ /*
40
+ * Whether this neuron is a hebb neuron or not.
41
+ * A hebb neuron also stimulates it's pre synapses
42
+ * upon firing.
43
+ */
44
+ bool hebb;
45
+
46
+ protected:
47
+
48
+ /*
49
+ * Constructor
50
+ */
51
+ Neuron();
52
+
53
+ public:
54
+
55
+ virtual void dump(jsonHash *into);
56
+ virtual void load(jsonHash *data);
57
+
58
+ virtual void stimulate(simtime at, real weight, NeuralEntity *source);
59
+ virtual void connect(NeuralEntity *target);
60
+ virtual void disconnect(NeuralEntity *target);
61
+ virtual void each_connection(
62
+ void (*yield)(NeuralEntity *self, NeuralEntity *conn));
63
+
64
+ protected:
65
+
66
+ void fire_synapses(simtime at);
67
+
68
+ };
69
+
70
+ #endif