yinspire 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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