yinspire 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +24 -0
- data/bench/pq/Makefile +5 -0
- data/bench/pq/bench.cc +321 -0
- data/bench/pq/bench.rb +125 -0
- data/bench/pq/bench_binaryheap.h +46 -0
- data/bench/pq/bench_calendarqueue.h +58 -0
- data/bench/pq/bench_pairingheap.h +61 -0
- data/bench/pq/bench_stlpq.h +46 -0
- data/bench/pq/benchmark.h +225 -0
- data/bench/pq/distribution.h +93 -0
- data/bench/pq/make.rb +24 -0
- data/bin/yinspire +186 -0
- data/examples/nets/gereon2005.c.json +93723 -0
- data/examples/nets/gereon2005.yin +232650 -0
- data/examples/nets/skorpion.graphml +396 -0
- data/examples/nets/spiketrains_angle_180.txt +8 -0
- data/lib/Algorithms/Array.h +52 -0
- data/lib/Algorithms/BinaryHeap.h +265 -0
- data/lib/Algorithms/CalendarQueue.h +257 -0
- data/lib/Algorithms/IndexedBinaryHeap.h +90 -0
- data/lib/Algorithms/PairingHeap.h +169 -0
- data/lib/Allocators/ChunkedFreelistAllocator.h +96 -0
- data/lib/Allocators/MemoryAllocator.h +45 -0
- data/lib/Allocators/RubyMemoryAllocator.h +37 -0
- data/lib/Yinspire.rb +69 -0
- data/lib/Yinspire/All.rb +10 -0
- data/lib/Yinspire/Core/NeuralEntity.rb +133 -0
- data/lib/Yinspire/Core/Neuron.rb +162 -0
- data/lib/Yinspire/Core/Scheduling/NeuralEntity.rb +123 -0
- data/lib/Yinspire/Core/Scheduling/Simulator.rb +94 -0
- data/lib/Yinspire/Core/Simulator.rb +36 -0
- data/lib/Yinspire/Core/StimuliMixin.rb +103 -0
- data/lib/Yinspire/Core/Stimulus.rb +25 -0
- data/lib/Yinspire/Core/Synapse.rb +64 -0
- data/lib/Yinspire/Dumpers/Dumper.rb +19 -0
- data/lib/Yinspire/Dumpers/Dumper_Dot.rb +28 -0
- data/lib/Yinspire/Loaders/GraphML.rb +84 -0
- data/lib/Yinspire/Loaders/Loader.rb +31 -0
- data/lib/Yinspire/Loaders/Loader_GraphML.rb +97 -0
- data/lib/Yinspire/Loaders/Loader_JSON.rb +181 -0
- data/lib/Yinspire/Loaders/Loader_Spike.rb +42 -0
- data/lib/Yinspire/Loaders/Loader_Yin.rb +62 -0
- data/lib/Yinspire/Loaders/YinScanner.rb +247 -0
- data/lib/Yinspire/Models/Neuron_Base.rb +38 -0
- data/lib/Yinspire/Models/Neuron_Input.rb +12 -0
- data/lib/Yinspire/Models/Neuron_InputOutput.rb +39 -0
- data/lib/Yinspire/Models/Neuron_Output.rb +15 -0
- data/lib/Yinspire/Models/Neuron_SRM01.rb +50 -0
- data/lib/Yinspire/Models/Neuron_SRM02.rb +64 -0
- data/lib/Yinspire/Models/Synapse_Hebb.rb +67 -0
- data/pure_cpp/Makefile +22 -0
- data/pure_cpp/README +2 -0
- data/pure_cpp/src/algo/binary_heap.h +277 -0
- data/pure_cpp/src/algo/indexed_binary_heap.h +90 -0
- data/pure_cpp/src/json/json.cc +542 -0
- data/pure_cpp/src/json/json.h +182 -0
- data/pure_cpp/src/json/json_parser.cc +685 -0
- data/pure_cpp/src/json/json_parser.h +15 -0
- data/pure_cpp/src/json/json_parser.rl +213 -0
- data/pure_cpp/src/main.cc +49 -0
- data/pure_cpp/src/memory_allocator.h +45 -0
- data/pure_cpp/src/neural_entity.cc +208 -0
- data/pure_cpp/src/neural_entity.h +243 -0
- data/pure_cpp/src/neuron.cc +136 -0
- data/pure_cpp/src/neuron.h +70 -0
- data/pure_cpp/src/neuron_srm_01.cc +77 -0
- data/pure_cpp/src/neuron_srm_01.h +36 -0
- data/pure_cpp/src/simulator.cc +151 -0
- data/pure_cpp/src/simulator.h +116 -0
- data/pure_cpp/src/synapse.cc +117 -0
- data/pure_cpp/src/synapse.h +60 -0
- data/pure_cpp/src/types.h +18 -0
- data/run.rb +68 -0
- data/tools/conv_jsonc_to_yin.rb +165 -0
- data/tools/converter.rb +93 -0
- data/tools/json_writer.rb +122 -0
- data/yinspire.gemspec +20 -0
- 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
|