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,265 @@
1
+ /*
2
+ * An implicit Binary Heap.
3
+ *
4
+ * Copyright (c) 2007, 2008 by Michael Neumann (mneumann@ntecs.de)
5
+ *
6
+ * NOTE: We start counting from 1 in the elements array!
7
+ *
8
+ * Template parameters:
9
+ *
10
+ * E: Element type
11
+ * Alloc: Allocator
12
+ * Acc: Accessor struct. Defines ordering relation (less).
13
+ * MIN_CAPA: minimum number of elements
14
+ *
15
+ * Example:
16
+ *
17
+ * struct Acc
18
+ * {
19
+ * static inline bool less(const int& a, const int& b)
20
+ * {
21
+ * return a < b;
22
+ * }
23
+ * };
24
+ *
25
+ * BinaryHeap<int, MemoryAllocator, Acc> heap;
26
+ * heap.push(4);
27
+ * heap.pop();
28
+ * ...
29
+ *
30
+ */
31
+
32
+ #ifndef __YINSPIRE__BINARY_HEAP__
33
+ #define __YINSPIRE__BINARY_HEAP__
34
+
35
+ #include <assert.h>
36
+
37
+ /*
38
+ * This is used to be able to keep track of
39
+ * an elements index in the IndexedBinaryHeap subclass.
40
+ * Unused in this class.
41
+ */
42
+ template <typename E>
43
+ struct BinaryHeapDummyIndexer
44
+ {
45
+ static inline void index_changed(E& e, unsigned int i)
46
+ {
47
+ /* DUMMY */
48
+ }
49
+ };
50
+
51
+ template <typename E, class Alloc, class Acc=E, class Idx=BinaryHeapDummyIndexer<E>, unsigned int MIN_CAPA=1024>
52
+ class BinaryHeap
53
+ {
54
+ typedef unsigned int I; // index type
55
+
56
+ public:
57
+
58
+ BinaryHeap()
59
+ {
60
+ this->capacity = 0;
61
+ this->size_ = 0;
62
+ this->elements = NULL; // we do lazy allocation!
63
+ }
64
+
65
+ ~BinaryHeap()
66
+ {
67
+ if (this->elements != NULL)
68
+ {
69
+ Alloc::free(this->elements+1);
70
+ }
71
+ this->elements = NULL;
72
+ }
73
+
74
+ inline E&
75
+ top() const
76
+ {
77
+ assert(this->size > 0);
78
+ return this->elements[1];
79
+ }
80
+
81
+ void
82
+ pop()
83
+ {
84
+ remove(1);
85
+ }
86
+
87
+ inline void
88
+ remove(I i)
89
+ {
90
+ assert(i <= this->size_);
91
+
92
+ //
93
+ // Element i is removed from the heap and as such becomes
94
+ // a "bubble" (free element). Move the bubble until
95
+ // the bubble becomes a leaf element.
96
+ //
97
+ Idx::index_changed(this->elements[i], 0); // detach from heap
98
+ I bubble = move_bubble_down(i);
99
+
100
+ //
101
+ // Now take the last element and insert it at the position of
102
+ // the bubble. In case the bubble is already the last element we
103
+ // are done.
104
+ //
105
+ if (bubble != this->size_)
106
+ {
107
+ insert_and_bubble_up(bubble, this->elements[this->size_]);
108
+ }
109
+ --this->size_;
110
+ }
111
+
112
+ void
113
+ push(const E& element)
114
+ {
115
+ if (this->size_ >= this->capacity) resize(2*this->capacity);
116
+ insert_and_bubble_up(++this->size_, element);
117
+ }
118
+
119
+ inline I
120
+ size() const
121
+ {
122
+ return this->size_;
123
+ }
124
+
125
+ inline bool
126
+ empty() const
127
+ {
128
+ return (this->size_ == 0);
129
+ }
130
+
131
+ /*
132
+ * Returns NULL or a pointer to the parent of +element+.
133
+ */
134
+ E*
135
+ find_parent(const E& element)
136
+ {
137
+ I i;
138
+
139
+ //
140
+ // Find the position of the first element that is less than +element+.
141
+ //
142
+ for (i = this->size_; i != 0 && Acc::less(element, this->elements[i]); i /= 2);
143
+
144
+ return (i == 0 ? NULL : &this->elements[i]);
145
+ }
146
+
147
+ /*
148
+ * Iterate over all elements (non-destructive)
149
+ */
150
+ void
151
+ each(void (*yield)(const E&, void*), void *data)
152
+ {
153
+ for (I i=1; i <= this->size_; i++)
154
+ {
155
+ yield(this->elements[i], data);
156
+ }
157
+ }
158
+
159
+ protected:
160
+
161
+ /*
162
+ * Insert +element+ into the heap beginning from
163
+ * +i+ and searching upwards to the root for the
164
+ * right position (heap ordered) to insert.
165
+ *
166
+ * Element at index +i+ MUST be empty, i.e. unused!
167
+ */
168
+ inline void
169
+ insert_and_bubble_up(I i, const E& element)
170
+ {
171
+ for (;i >= 2 && Acc::less(element, this->elements[i/2]); i /= 2)
172
+ {
173
+ store_element(i, this->elements[i/2]);
174
+ }
175
+
176
+ // finally store it into the determined hole
177
+ store_element(i, element);
178
+ }
179
+
180
+ /*
181
+ * Move the bubble (empty element) at +i+ down in direction
182
+ * to the leaves. When the bubble reaches a leaf, stop and
183
+ * return the index of the leaf element which is now empty.
184
+ */
185
+ inline I
186
+ move_bubble_down(I i)
187
+ {
188
+ const I sz = this->size_;
189
+ I right_child = i * 2 + 1;
190
+
191
+ while (right_child <= sz)
192
+ {
193
+ if (Acc::less(this->elements[right_child-1], this->elements[right_child]))
194
+ {
195
+ --right_child; // minimum child is left child
196
+ }
197
+
198
+ store_element(i, this->elements[right_child]);
199
+ i = right_child;
200
+ right_child = i * 2 + 1;
201
+ }
202
+
203
+ //
204
+ // Edge case (comparison with the last element)
205
+ //
206
+ if (right_child-1 == sz)
207
+ {
208
+ store_element(i, this->elements[right_child-1]);
209
+ i = right_child-1;
210
+ }
211
+
212
+ return i;
213
+ }
214
+
215
+ /*
216
+ * The 0'th element is never used (accessed), so
217
+ * we allocate only "capacity" elements (instead of capacity+1)
218
+ * and move the pointer one element before the begin of the
219
+ * allocated memory.
220
+ */
221
+ void
222
+ resize(I new_capacity)
223
+ {
224
+ E *new_elements;
225
+
226
+ if (new_capacity < MIN_CAPA) this->capacity = MIN_CAPA;
227
+ else this->capacity = new_capacity;
228
+
229
+ //
230
+ // We do lazy allocation!
231
+ //
232
+ if (this->elements != NULL)
233
+ {
234
+ new_elements = Alloc::realloc_n(this->elements+1, this->capacity);
235
+ }
236
+ else
237
+ {
238
+ new_elements = Alloc::alloc_n(this->capacity);
239
+ }
240
+
241
+ assert(new_elements != NULL);
242
+ assert(this->capacity >= this->size);
243
+
244
+ //
245
+ // move pointer so that we "introduce" a zero'th
246
+ // element.
247
+ //
248
+ this->elements = new_elements-1;
249
+ }
250
+
251
+ inline void
252
+ store_element(I i, const E& element)
253
+ {
254
+ this->elements[i] = element;
255
+ Idx::index_changed(this->elements[i], i);
256
+ }
257
+
258
+ protected:
259
+
260
+ I size_;
261
+ E *elements;
262
+ I capacity;
263
+ };
264
+
265
+ #endif
@@ -0,0 +1,257 @@
1
+ /*
2
+ * A Calendar Queue implementation.
3
+ *
4
+ * Copyright (c) 2007, 2008 by Michael Neumann (mneumann@ntecs.de)
5
+ *
6
+ * Template parameters:
7
+ *
8
+ * E: Element type
9
+ * ACC: Accessor
10
+ * priority -> real
11
+ * next -> E*&
12
+ * real: precision type
13
+ *
14
+ */
15
+
16
+ #ifndef __YINSPIRE__CALENDAR_QUEUE__
17
+ #define __YINSPIRE__CALENDAR_QUEUE__
18
+
19
+ #include <assert.h>
20
+
21
+ template <typename E, class ACC = E, typename real=float>
22
+ class CalendarQueue
23
+ {
24
+ typedef unsigned int I; // index type
25
+
26
+ public:
27
+
28
+ CalendarQueue(real year_width=1.0)
29
+ {
30
+ this->size_ = 0;
31
+ this->year_width = year_width;
32
+ this->day_width = year_width;
33
+
34
+ this->current_year = 0;
35
+ this->current_day = 0;
36
+
37
+ this->num_days = 1;
38
+ this->days = new E*[1];
39
+ this->days[0] = NULL;
40
+ }
41
+
42
+ inline I
43
+ size() const
44
+ {
45
+ return this->size_;
46
+ }
47
+
48
+ inline bool
49
+ empty() const
50
+ {
51
+ return (this->size_ == 0);
52
+ }
53
+
54
+ void
55
+ push(E *element)
56
+ {
57
+ const real priority = ACC::priority(element);
58
+
59
+ assert(priority >= 0.0);
60
+
61
+ if (++this->size_ > 2*this->num_days) resize_double();
62
+
63
+ // map priority to a day
64
+ I day = ((I)(priority / this->day_width)) % this->num_days;
65
+
66
+ // and sort element into that day
67
+ insert_sorted(day, element);
68
+
69
+ //
70
+ // in case that the newly inserted element is smaller than the
71
+ // currently smallest value we have to change the current year
72
+ // and day.
73
+ //
74
+ if (priority < min_start())
75
+ {
76
+ this->current_day = day;
77
+ this->current_year = (I)(priority / this->year_width);
78
+ }
79
+ }
80
+
81
+ inline real min_start() const { return day_start() + year_start(); }
82
+ inline real day_start() const { return this->current_day * this->day_width; }
83
+ inline real year_start() const { return this->current_year * this->year_width; }
84
+
85
+ E*
86
+ pop()
87
+ {
88
+ assert(this->size_ > 0);
89
+
90
+ if (--this->size_ < this->num_days/2 && this->num_days > 1) resize_half();
91
+
92
+ real priority;
93
+ real min_priority = INFINITY;
94
+ real max_value_this_year = (this->current_year+1)*this->year_width;
95
+ E *top;
96
+ I i;
97
+
98
+ for (i = this->current_day; i < this->num_days; i++)
99
+ {
100
+ top = this->days[i];
101
+ if (top != NULL)
102
+ {
103
+ priority = ACC::priority(top);
104
+
105
+ if (priority < max_value_this_year)
106
+ {
107
+ // remove top element
108
+ this->days[i] = ACC::next(top);
109
+ this->current_day = i;
110
+ ACC::next(top) = NULL;
111
+ return top;
112
+ }
113
+ if (priority < min_priority) min_priority = priority;
114
+ }
115
+ }
116
+
117
+ //
118
+ // continue with the first element up to this->current_day
119
+ //
120
+ for (i = 0; i < this->current_day; i++)
121
+ {
122
+ top = this->days[i];
123
+ if (top != NULL)
124
+ {
125
+ priority = ACC::priority(top);
126
+ if (priority < min_priority) min_priority = priority;
127
+ }
128
+ }
129
+
130
+ this->current_year = (I)(min_priority / this->year_width);
131
+ this->current_day = (I)(min_priority / this->day_width) % this->num_days;
132
+
133
+ top = this->days[this->current_day];
134
+ this->days[this->current_day] = ACC::next(top);
135
+ ACC::next(top) = NULL;
136
+
137
+ return top;
138
+ }
139
+
140
+ protected:
141
+
142
+ void
143
+ insert_sorted(I day, E *element)
144
+ {
145
+ E *curr = this->days[day];
146
+ E *prev = NULL;
147
+ const real priority = ACC::priority(element);
148
+
149
+ //
150
+ // Find the first element that is >= +element+.
151
+ // Insert +element+ *before* that element.
152
+ //
153
+ while (curr != NULL && ACC::priority(curr) < priority)
154
+ {
155
+ prev = curr;
156
+ curr = ACC::next(curr);
157
+ }
158
+
159
+ ACC::next(element) = curr;
160
+
161
+ if (prev != NULL) ACC::next(prev) = element;
162
+ else this->days[day] = element;
163
+ }
164
+
165
+ /*
166
+ * Each day is split into two days.
167
+ */
168
+ void
169
+ resize_double()
170
+ {
171
+ E **new_days = new E*[2*this->num_days];
172
+
173
+ const real dw = this->day_width / 2.0;
174
+ E* c[2];
175
+
176
+ for (I i = 0; i < this->num_days; i++)
177
+ {
178
+ c[0] = new_days[i*2] = NULL;
179
+ c[1] = new_days[i*2+1] = NULL;
180
+ for (E *curr = this->days[i]; curr != NULL; curr = ACC::next(curr))
181
+ {
182
+ const I day = (I)(ACC::priority(curr) / dw) % 2;
183
+ if (c[day] != NULL)
184
+ {
185
+ ACC::next(c[day]) = curr;
186
+ }
187
+ else
188
+ {
189
+ new_days[i*2+day] = curr;
190
+ }
191
+ c[day] = curr;
192
+ }
193
+
194
+ if (c[0] != NULL) ACC::next(c[0]) = NULL;
195
+ if (c[1] != NULL) ACC::next(c[1]) = NULL;
196
+ }
197
+
198
+ delete [] this->days;
199
+
200
+ this->days = new_days;
201
+ this->num_days *= 2;
202
+ this->day_width /= 2.0;
203
+ this->current_year = 0;
204
+ this->current_day = 0;
205
+ }
206
+
207
+ // TODO: merge
208
+ void
209
+ resize_half()
210
+ {
211
+ resize(this->num_days/2, this->day_width*2.0);
212
+ }
213
+
214
+ void
215
+ resize(I new_num_days, real new_day_width)
216
+ {
217
+ E **old_days = this->days;
218
+ this->days = new E*[new_num_days];
219
+ E *element;
220
+
221
+ // initialize this->days to NULL
222
+ for (I i = 0; i < new_num_days; i++) this->days[i] = NULL;
223
+
224
+ for (I i = 0; i < this->num_days; i++)
225
+ {
226
+ for (E *curr = old_days[i]; curr != NULL; )
227
+ {
228
+ const I day = ((I)(ACC::priority(curr) / new_day_width)) % new_num_days;
229
+ element = curr;
230
+ curr = ACC::next(curr);
231
+ insert_sorted(day, element);
232
+ }
233
+ }
234
+
235
+ delete[] old_days;
236
+
237
+ this->num_days = new_num_days;
238
+ this->day_width = new_day_width;
239
+ this->current_year = 0;
240
+ this->current_day = 0;
241
+ }
242
+
243
+ private:
244
+
245
+ I size_;
246
+
247
+ I num_days;
248
+ E** days;
249
+
250
+ real day_width;
251
+ real year_width;
252
+
253
+ I current_year;
254
+ I current_day;
255
+ };
256
+
257
+ #endif