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,77 @@
1
+ #include "neuron_srm_01.h"
2
+ #include "simulator.h"
3
+ #include <math.h>
4
+
5
+ // formerly known as KernelbasedLIF
6
+
7
+
8
+ Neuron_SRM_01::Neuron_SRM_01()
9
+ {
10
+ this->tau_m = 0.0;
11
+ this->tau_ref = 0.0;
12
+ this->ref_weight = 0.0;
13
+ this->mem_pot = 0.0;
14
+ this->const_threshold = 0.0;
15
+ }
16
+
17
+ void
18
+ Neuron_SRM_01::dump(jsonHash *into)
19
+ {
20
+ }
21
+
22
+ void
23
+ Neuron_SRM_01::load(jsonHash *data)
24
+ {
25
+ super::load(data);
26
+
27
+ this->tau_m = data->get_number("tau_m", 0.0);
28
+ this->tau_ref = data->get_number("tau_ref", 0.0);
29
+ this->ref_weight = data->get_number("ref_weight", 0.0);
30
+ this->mem_pot = data->get_number("mem_pot", 0.0);
31
+ this->const_threshold = data->get_number("const_threshold", 0.0);
32
+ }
33
+
34
+ void
35
+ Neuron_SRM_01::stimulate(simtime at, real weight, NeuralEntity *source)
36
+ {
37
+ if (at >= this->last_fire_time + this->abs_refr_duration)
38
+ {
39
+ ++this->simulator->stat_event_counter;
40
+ super::stimulate(at, weight, source);
41
+ }
42
+ }
43
+
44
+ void
45
+ Neuron_SRM_01::process(simtime at)
46
+ {
47
+ real weight = stimuli_sum(at);
48
+ const real delta = at - this->last_fire_time - this->abs_refr_duration;
49
+
50
+ if (delta < 0.0) return;
51
+
52
+ /*
53
+ * Calculate new membrane potential
54
+ */
55
+
56
+ this->mem_pot = weight + this->mem_pot * real_exp( -(at - this->last_spike_time)/this->tau_m );
57
+ this->last_spike_time = at;
58
+
59
+ /*
60
+ * Calculate dynamic threshold
61
+ */
62
+ const real dynamic_threshold = this->ref_weight * real_exp(-delta/this->tau_ref);
63
+
64
+ if (this->mem_pot >= this->const_threshold + dynamic_threshold)
65
+ {
66
+ fire(at);
67
+ }
68
+ }
69
+
70
+ void
71
+ Neuron_SRM_01::fire(simtime at)
72
+ {
73
+ this->simulator->stat_record_fire_event(at, this);
74
+ this->mem_pot = 0.0;
75
+ this->last_fire_time = at;
76
+ fire_synapses(at);
77
+ }
@@ -0,0 +1,36 @@
1
+ #ifndef __YINSPIRE__NEURON_SRM_01__
2
+ #define __YINSPIRE__NEURON_SRM_01__
3
+
4
+ #include "neuron.h"
5
+
6
+ class Neuron_SRM_01 : public Neuron
7
+ {
8
+ typedef Neuron super;
9
+
10
+ protected:
11
+
12
+ real tau_m;
13
+ real tau_ref;
14
+ real ref_weight;
15
+ real mem_pot;
16
+ real const_threshold;
17
+
18
+ public:
19
+
20
+ Neuron_SRM_01();
21
+
22
+ public:
23
+
24
+ virtual void dump(jsonHash *into);
25
+ virtual void load(jsonHash *data);
26
+
27
+ virtual void stimulate(simtime at, real weight, NeuralEntity *source);
28
+ virtual void process(simtime at);
29
+
30
+ protected:
31
+
32
+ void fire(simtime at);
33
+
34
+ };
35
+
36
+ #endif
@@ -0,0 +1,151 @@
1
+ #include <math.h>
2
+ #include <string>
3
+ #include "simulator.h"
4
+ #include "json/json_parser.h"
5
+
6
+ Simulator::Simulator()
7
+ {
8
+ this->schedule_current_time = 0.0;
9
+ this->schedule_step = INFINITY;
10
+ this->schedule_next_step = this->schedule_current_time + this->schedule_step;
11
+ this->schedule_stepping_list_root = NULL;
12
+ this->stimuli_tolerance = 0.0;
13
+ this->stat_event_counter = 0;
14
+ this->stat_fire_counter = 0;
15
+ }
16
+
17
+ void
18
+ Simulator::entity_register_type(const char *type, entity_factory_t factory)
19
+ {
20
+ this->types[type] = factory;
21
+ }
22
+
23
+ NeuralEntity*
24
+ Simulator::entity_allocate(const char* type)
25
+ {
26
+ entity_factory_t factory = this->types[type];
27
+ return factory();
28
+ }
29
+
30
+ void
31
+ Simulator::load(const char *filename)
32
+ {
33
+ jsonHash *data = jsonParser::parse_file_mmap(filename)->asHash();
34
+
35
+ std::string format = data->get("format")->asString()->value;
36
+
37
+ if (format != "yinspire.c")
38
+ {
39
+ throw "unrecognized data format";
40
+ }
41
+
42
+ jsonHash *templates = data->get("templates")->asHash();
43
+ jsonArray *entities = data->get("entities")->asArray();
44
+ jsonArray *connections = data->get("connections")->asArray();
45
+ jsonHash *events = data->get("events")->asHash();
46
+
47
+ /*
48
+ * construct entities
49
+ */
50
+ jsonArrayIterator_EACH(entities, e)
51
+ {
52
+ jsonArray *entity_spec = e->asArray();
53
+ jsonString *id = entity_spec->get(0)->asString();
54
+ jsonString *template_name = entity_spec->get(1)->asString();
55
+
56
+ jsonArray *t = templates->get(template_name)->asArray();
57
+
58
+ jsonString *type = t->get(0)->asString();
59
+ jsonHash *hash = t->get(1)->asHash();
60
+
61
+ NeuralEntity *entity = entity_allocate(type->value.c_str());
62
+
63
+ entity->set_id(strdup(id->asString()->value.c_str()));
64
+ entity->set_simulator(this);
65
+ this->entities[entity->get_id()] = entity;
66
+
67
+ entity->load(hash);
68
+ }
69
+
70
+ /*
71
+ * connect entities
72
+ */
73
+ jsonArrayIterator_EACH(connections, conn)
74
+ {
75
+ NeuralEntity *from = NULL;
76
+ jsonArrayIterator_EACH(conn->asArray(), i)
77
+ {
78
+ std::string &id = i->asString()->value;
79
+ NeuralEntity *e = this->entities[id.c_str()];
80
+ if (from == NULL) from = e;
81
+ else from->connect(e);
82
+ }
83
+ }
84
+
85
+ /*
86
+ * events
87
+ */
88
+ jsonHashIterator_EACH(events, key, val)
89
+ {
90
+ NeuralEntity *entity = this->entities[key->value.c_str()];
91
+ jsonArrayIterator_EACH(val->asArray(), e)
92
+ {
93
+ entity->stimulate(e->asNumber()->value, INFINITY, NULL);
94
+ }
95
+ }
96
+
97
+ data->ref_decr();
98
+ }
99
+
100
+ void
101
+ Simulator::run(simtime stop_at)
102
+ {
103
+ while (true)
104
+ {
105
+ simtime next_stop = MIN(stop_at, this->schedule_next_step);
106
+
107
+ /*
108
+ * Calculate all events from the priority queue until the next time
109
+ * step is reached.
110
+ */
111
+ while (!this->schedule_pq.empty())
112
+ {
113
+ NeuralEntity *top = this->schedule_pq.top();
114
+ if (top->get_schedule_at() >= next_stop)
115
+ break;
116
+ this->schedule_current_time = top->get_schedule_at();
117
+ this->schedule_pq.pop();
118
+ top->process(top->get_schedule_at());
119
+ }
120
+
121
+ if (this->schedule_current_time >= stop_at)
122
+ break;
123
+
124
+ if (this->schedule_stepping_list_root == NULL && this->schedule_pq.empty())
125
+ break;
126
+
127
+ /*
128
+ * Calculate the entities that require stepped processing.
129
+ */
130
+ this->schedule_current_time = this->schedule_next_step;
131
+
132
+ if (this->schedule_stepping_list_root != NULL)
133
+ {
134
+ // FIXME: collect all entities in an array. then process them.
135
+ }
136
+
137
+ this->schedule_next_step += this->schedule_step;
138
+ }
139
+ }
140
+
141
+ void
142
+ Simulator::schedule_update(NeuralEntity *entity)
143
+ {
144
+ this->schedule_pq.update(entity);
145
+ }
146
+
147
+ void
148
+ Simulator::stat_record_fire_event(simtime at, NeuralEntity *source)
149
+ {
150
+ ++this->stat_fire_counter;
151
+ }
@@ -0,0 +1,116 @@
1
+ #ifndef __YINSPIRE__SIMULATOR__
2
+ #define __YINSPIRE__SIMULATOR__
3
+
4
+ #include "types.h"
5
+ #include "neural_entity.h"
6
+ #include "memory_allocator.h"
7
+ #include "algo/indexed_binary_heap.h"
8
+ #include <string.h>
9
+ #include <map>
10
+
11
+ struct ltstr
12
+ {
13
+ inline bool operator()(const char *s1, const char *s2) const
14
+ {
15
+ return strcmp(s1, s2) < 0;
16
+ }
17
+ };
18
+
19
+ class Simulator
20
+ {
21
+ friend class NeuralEntity;
22
+
23
+ protected:
24
+
25
+ /*
26
+ * The current time.
27
+ */
28
+ simtime schedule_current_time;
29
+
30
+ /*
31
+ * The time step used for stepped scheduling.
32
+ */
33
+ simtime schedule_step;
34
+
35
+ /*
36
+ * The time of the next step.
37
+ */
38
+ simtime schedule_next_step;
39
+
40
+ /*
41
+ * The tolerance (time difference) up to which local stimuli are
42
+ * accumulated.
43
+ */
44
+ simtime stimuli_tolerance;
45
+
46
+ /*
47
+ * Priority queue used to schedule the entities.
48
+ */
49
+ IndexedBinaryHeap<NeuralEntity *, MemoryAllocator<NeuralEntity*>, NeuralEntity> schedule_pq;
50
+
51
+ /*
52
+ * If stepped scheduling is used, this points to the
53
+ * first entity in the stepped schedule list.
54
+ */
55
+ NeuralEntity *schedule_stepping_list_root;
56
+
57
+ /*
58
+ * An id -> NeuralEntity mapping
59
+ *
60
+ * Contains all entities known by the simulator.
61
+ */
62
+ std::map<const char *, NeuralEntity *, ltstr> entities;
63
+
64
+ /*
65
+ * An entity type name -> "factory function for this type" mapping.
66
+ */
67
+ typedef NeuralEntity* (*entity_factory_t)();
68
+ std::map<const char *, entity_factory_t, ltstr> types;
69
+
70
+ public:
71
+
72
+ /*
73
+ * Constructor
74
+ */
75
+ Simulator();
76
+
77
+ /*
78
+ * Load the neural net from +filename+.
79
+ */
80
+ void load(const char *filename);
81
+
82
+ /*
83
+ * Start the simulation.
84
+ */
85
+ void run(simtime stop_at);
86
+
87
+ /*
88
+ * Register an entity type and the corresponding +factory+ function.
89
+ */
90
+ void entity_register_type(const char *type, entity_factory_t factory);
91
+
92
+ /*
93
+ * Allocate an entity of the specified +type+.
94
+ */
95
+ NeuralEntity *entity_allocate(const char *type);
96
+
97
+ /*
98
+ * If an entity has changed it's scheduling time,
99
+ * it has to call this method to reflect the change within the
100
+ * priority queue.
101
+ */
102
+ void schedule_update(NeuralEntity *entity);
103
+
104
+ /*
105
+ * Notify that a fire event has happened
106
+ */
107
+ void stat_record_fire_event(simtime at, NeuralEntity *source);
108
+
109
+ public:
110
+
111
+ uint stat_fire_counter;
112
+ uint stat_event_counter;
113
+
114
+ };
115
+
116
+ #endif
@@ -0,0 +1,117 @@
1
+ #include "synapse.h"
2
+ #include "neuron.h"
3
+ #include <assert.h>
4
+
5
+ Synapse::Synapse()
6
+ {
7
+ this->weight = 0.0;
8
+ this->delay = 0.0;
9
+ this->pre_neuron = NULL;
10
+ this->post_neuron = NULL;
11
+ this->next_pre_synapse = NULL;
12
+ this->next_post_synapse = NULL;
13
+ }
14
+
15
+ void
16
+ Synapse::dump(jsonHash *into)
17
+ {
18
+ }
19
+
20
+ void
21
+ Synapse::load(jsonHash *data)
22
+ {
23
+ super::load(data);
24
+
25
+ this->weight = data->get_number("weight", 0.0);
26
+ this->delay = data->get_number("delay", 0.0);
27
+ }
28
+
29
+
30
+ void
31
+ Synapse::stimulate(simtime at, real weight, NeuralEntity *source)
32
+ {
33
+ /*
34
+ * Only propagate the stimulation if it doesn't originate from the
35
+ * post Neuron. Stimuli from a post Neuron are handled by a specific
36
+ * Synapse class (e.g. Hebb).
37
+ *
38
+ * We ignore the weight parameter that is passed by the Neuron.
39
+ */
40
+ if (source != this->post_neuron)
41
+ {
42
+ this->post_neuron->stimulate(at + this->delay, this->weight, this);
43
+ }
44
+ }
45
+
46
+
47
+ /*
48
+ * Adding a pre synapse. Target must be a Neuron.
49
+ *
50
+ * O(1)
51
+ */
52
+ void
53
+ Synapse::connect(NeuralEntity *target)
54
+ {
55
+ Neuron *neuron = dynamic_cast<Neuron*>(target);
56
+
57
+ if (this->post_neuron != NULL || this->next_pre_synapse != NULL)
58
+ throw "Synapse already connected";
59
+
60
+ this->next_pre_synapse = neuron->first_pre_synapse;
61
+ neuron->first_pre_synapse = this;
62
+ this->post_neuron = neuron;
63
+ }
64
+
65
+ /*
66
+ * O(n)
67
+ */
68
+ void
69
+ Synapse::disconnect(NeuralEntity *target)
70
+ {
71
+ Neuron *neuron = dynamic_cast<Neuron*>(target);
72
+
73
+ if (this->post_neuron != neuron)
74
+ throw "Synapse not connected to this Neuron";
75
+
76
+ /*
77
+ * Find the synapse in the linked list that precedes +this+.
78
+ */
79
+ Synapse *prev = NULL;
80
+ Synapse *curr = neuron->first_pre_synapse;
81
+
82
+ while (true)
83
+ {
84
+ if (curr == NULL) break;
85
+ if (curr == this) break;
86
+ prev = curr;
87
+ curr = curr->next_pre_synapse;
88
+ }
89
+
90
+ if (curr != this)
91
+ throw "Synapse not in pre synapse list";
92
+
93
+ /*
94
+ * Remove ourself (this) from linked list
95
+ */
96
+ if (prev == NULL)
97
+ {
98
+ /*
99
+ * we are the last synapse in the pre synapse list.
100
+ */
101
+ assert(neuron->first_pre_synapse == this);
102
+ neuron->first_pre_synapse = NULL;
103
+ }
104
+ else
105
+ {
106
+ prev->next_pre_synapse = this->next_pre_synapse;
107
+ }
108
+
109
+ this->post_neuron = NULL;
110
+ this->next_pre_synapse = NULL;
111
+ }
112
+
113
+ void
114
+ Synapse::each_connection(void (*yield)(NeuralEntity *self, NeuralEntity *conn))
115
+ {
116
+ yield(this, this->post_neuron);
117
+ }