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,60 @@
1
+ #ifndef __YINSPIRE__SYNAPSE__
2
+ #define __YINSPIRE__SYNAPSE__
3
+
4
+ #include "neural_entity.h"
5
+
6
+ class Neuron; // forward declaration
7
+
8
+ class Synapse : public NeuralEntity
9
+ {
10
+ friend class Neuron;
11
+ typedef NeuralEntity super;
12
+
13
+ protected:
14
+
15
+ /*
16
+ * The fire weight of a Synapse.
17
+ */
18
+ real weight;
19
+
20
+ /*
21
+ * The propagation delay of a Synapse.
22
+ */
23
+ simtime delay;
24
+
25
+ /*
26
+ * The pre and post Neurons of the Synapse.
27
+ */
28
+ Neuron *pre_neuron;
29
+ Neuron *post_neuron;
30
+
31
+ /*
32
+ * Those two pointers are part of an internal linked-list that
33
+ * starts at a Neuron and connects all pre-synapses of an Neuron
34
+ * together. In the same way it connects all post-synapses of an
35
+ * Neuron together.
36
+ */
37
+ Synapse *next_pre_synapse;
38
+ Synapse *next_post_synapse;
39
+
40
+ public:
41
+
42
+ /*
43
+ * Constructor
44
+ */
45
+ Synapse();
46
+
47
+ public:
48
+
49
+ virtual void dump(jsonHash *into);
50
+ virtual void load(jsonHash *data);
51
+
52
+ virtual void stimulate(simtime at, real weight, NeuralEntity *source);
53
+ virtual void connect(NeuralEntity *target);
54
+ virtual void disconnect(NeuralEntity *target);
55
+ virtual void each_connection(
56
+ void (*yield)(NeuralEntity *self, NeuralEntity *conn));
57
+
58
+ };
59
+
60
+ #endif
@@ -0,0 +1,18 @@
1
+ #ifndef __YINSPIRE__TYPES__
2
+ #define __YINSPIRE__TYPES__
3
+
4
+ typedef unsigned int uint;
5
+ typedef float real;
6
+ typedef float simtime;
7
+
8
+ #define real_exp expf
9
+ #define real_fabs fabsf
10
+
11
+ #ifndef NULL
12
+ #define NULL 0L
13
+ #endif
14
+
15
+ #define MIN(a,b) ((a) < (b) ? (a) : (b))
16
+ #define MAX(a,b) ((a) > (b) ? (a) : (b))
17
+
18
+ #endif
data/run.rb ADDED
@@ -0,0 +1,68 @@
1
+ require 'rubygems'
2
+ $LOAD_PATH.unshift "lib"
3
+
4
+ require 'Yinspire'
5
+ require 'Yinspire/Models/Neuron_Input'
6
+ require 'Yinspire/Models/Neuron_Output'
7
+ require 'Yinspire/Models/Neuron_SRM01'
8
+ require 'Yinspire/Models/Neuron_SRM02'
9
+ require 'Yinspire/Models/Synapse_Hebb'
10
+ require 'Yinspire/Loaders/Loader_JSON'
11
+ require 'Yinspire/Loaders/Loader_GraphML'
12
+ require 'Yinspire/Loaders/Loader_Yin'
13
+
14
+ def example_net(sim, n)
15
+ inputs = (0...n).map {|i|
16
+ Neuron_Input.new("inp_#{i}", sim)
17
+ }
18
+
19
+ outputs = (0...n).map {|i|
20
+ Neuron_Output.new("out_#{i}", sim)
21
+ }
22
+
23
+ synapses = (0...n).map {|i|
24
+ Synapse.new("syn_#{i}", sim) {|s|
25
+ s.delay = 0.4
26
+ s.weight = 10.0
27
+ }
28
+ }
29
+
30
+ (0...n).each {|i|
31
+ inputs[i].connect(synapses[i])
32
+ synapses[i].connect(outputs[i])
33
+ }
34
+
35
+ (0...n).each {|i|
36
+ inputs[i].stimulate(0.0+i, 1.0, nil)
37
+ }
38
+ end
39
+
40
+ Yinspire.commit('./work/Yinspire')
41
+
42
+ sim = Simulator.new
43
+ sim.stimuli_tolerance = 0.0
44
+
45
+ class Neuron_Output
46
+ def fire(at, weight)
47
+ puts "#{id()}\t#{at}\t#{weight}"
48
+ end
49
+ end
50
+
51
+ #loader = Loader_GraphML.new(sim)
52
+ #loader.load('examples/nets/skorpion.graphml')
53
+
54
+ #loader = Loader_JSON.new(sim)
55
+ #loader.load('/tmp/gereon2005.json')
56
+
57
+ loader = Loader_Yin.new(sim)
58
+ loader.load('./examples/nets/gereon2005.yin')
59
+
60
+ #require 'pp'
61
+ #pp loader.dump_entities
62
+ #example_net(sim, 10_000)
63
+
64
+ stop_at = ARGV[0].to_f
65
+ puts "stop_at: #{stop_at}"
66
+ sim.run(stop_at)
67
+ puts "events: #{sim.event_counter}"
68
+ puts "fires: #{sim.fire_counter}"
@@ -0,0 +1,165 @@
1
+ require 'yaml'
2
+ require 'enumerator'
3
+
4
+ class String
5
+ def to_yin_str
6
+ if self =~ /^\w+$/
7
+ self
8
+ else
9
+ '"' + self + '"'
10
+ end
11
+ end
12
+ end
13
+
14
+ class TrueClass; alias to_yin_str to_s end
15
+ class FalseClass; alias to_yin_str to_s end
16
+ class Float; alias to_yin_str to_s end
17
+ class Fixnum; alias to_yin_str to_s end
18
+ class Bignum; alias to_yin_str to_s end
19
+
20
+ class Hash
21
+ def to_yin_str(out="")
22
+ out << "{\n"
23
+ self.keys.sort.each do |k|
24
+ out << " " if $verbose
25
+ out << "#{k.to_yin_str} = #{self[k].to_yin_str}\n"
26
+ end
27
+ out << "}\n"
28
+ end
29
+ end
30
+
31
+ data = YAML.load(STDIN.read)
32
+ out = STDOUT
33
+ $verbose = true
34
+
35
+ raise unless data['format'] == 'yinspire.c'
36
+
37
+ #data['entities'] = nil
38
+ #data['templates'] = nil
39
+ #data['connections'] = nil
40
+
41
+ #
42
+ # Write out templates
43
+ #
44
+
45
+ templates = data["templates"] || {}
46
+ if $verbose and !templates.empty?
47
+ out << "#\n"
48
+ out << "# Templates\n"
49
+ out << "#\n\n"
50
+ end
51
+
52
+ templates.keys.sort.each do |key|
53
+ base_type, base_data = *templates[key]
54
+
55
+ out << "TEMPLATE " if $verbose
56
+ out << "#{key.to_yin_str} < #{base_type.to_yin_str}"
57
+ if base_data and not base_data.empty?
58
+ out << " "
59
+ base_data.to_yin_str(out)
60
+ else
61
+ out << "\n"
62
+ end
63
+ out << "\n" if $verbose
64
+ end
65
+
66
+
67
+ #
68
+ # Write out entities
69
+ #
70
+
71
+ entities = data["entities"] || []
72
+ if $verbose and !entities.empty?
73
+ out << "#\n"
74
+ out << "# Entities\n"
75
+ out << "#\n\n"
76
+ end
77
+
78
+ group_by = {}
79
+ entities.each do |id, type, edata|
80
+ key = [type, edata]
81
+ group_by[key] ||= []
82
+ group_by[key] << id
83
+ end
84
+
85
+
86
+ group_by.keys.sort_by {|type, _| type}.each do |key|
87
+ type, edata = *key
88
+ ids = group_by[key]
89
+ out << "ENTITY " if $verbose
90
+ out << ids.sort.map {|id| id.to_yin_str}.enum_for(:each_slice, 8).map {|sl|
91
+ sl.join(", ")
92
+ }.join(",\n ")
93
+
94
+ out << " = #{ type.to_yin_str }"
95
+
96
+
97
+ if edata and not edata.empty?
98
+ out << " "
99
+ edata.to_yin_str(out)
100
+ else
101
+ out << "\n"
102
+ end
103
+ out << "\n" if $verbose
104
+ end
105
+
106
+ #
107
+ # Write out connections
108
+ #
109
+
110
+ connections = data["connections"] || []
111
+ if $verbose and !connections.empty?
112
+ out << "#\n"
113
+ out << "# Connections\n"
114
+ out << "#\n\n"
115
+ end
116
+
117
+ connections.each do |arr|
118
+ src, *targets = *arr
119
+ out << "CONNECT " if $verbose
120
+ out << "#{src.to_yin_str} -> "
121
+
122
+ out << targets.map {|t| t.to_yin_str}.enum_for(:each_slice, 8).map {|sl|
123
+ sl.join(", ")
124
+ }.join(",\n ")
125
+ out << "\n"
126
+
127
+ out << "\n" if $verbose
128
+ end
129
+
130
+ #
131
+ # Write out stimuli
132
+ #
133
+
134
+ events = data["events"] || {}
135
+ if $verbose and !events.empty?
136
+ out << "#\n"
137
+ out << "# Stimulations\n"
138
+ out << "#\n\n"
139
+ end
140
+
141
+ events.keys.sort.each do |key|
142
+ ev = events[key]
143
+ next if ev.empty?
144
+
145
+ out << "STIMULATE " if $verbose
146
+ out << "#{key.to_yin_str} ! {\n"
147
+
148
+ out << " "
149
+ char_pos = 1
150
+
151
+ ev.each do |e|
152
+ str = e.to_yin_str
153
+ if char_pos > 40 && char_pos+str.size > 75
154
+ out << "\n "
155
+ char_pos = 1
156
+ end
157
+ out << " "
158
+ out << str
159
+ char_pos += 1 + str.size
160
+ end
161
+
162
+ out << "\n}\n"
163
+
164
+ out << "\n" if $verbose
165
+ end
@@ -0,0 +1,93 @@
1
+ require 'yaml'
2
+ require 'json_writer'
3
+
4
+ # format changes:
5
+ #
6
+ # * neuron/synapse type names changed
7
+ # * property names changed
8
+ # * no longer post_neuron, pre_neuron, instead connections.
9
+ #
10
+
11
+ old = YAML.load(File.read('/tmp/gereon2005'))
12
+ new = {}
13
+ new['format'] = 'yinspire.1'
14
+ new['templates'] = {}
15
+ entities = new['entities'] = {}
16
+ connections = new['connections'] = {}
17
+ new['events'] = old['events']
18
+
19
+ #
20
+ # convert templates
21
+ #
22
+ old['templates'].each do |name, hash|
23
+
24
+ type =
25
+ case hash.delete("type")
26
+ when 'Synapse_Default' then 'Synapse'
27
+ when 'Neuron_KernelBasedLIF' then 'Neuron_SRM_01'
28
+ else
29
+ raise
30
+ end
31
+
32
+ if abs_ref_duration = hash.delete('abs_ref_duration')
33
+ hash['abs_refr_duration'] = abs_ref_duration
34
+ end
35
+
36
+ new['templates'][name] = [type, hash]
37
+ end
38
+
39
+
40
+
41
+ #
42
+ # convert entities and connections
43
+ #
44
+ old['net'].each do |hash|
45
+ template = hash.delete('_')
46
+ post_neuron = hash.delete('post_neuron')
47
+ pre_neuron = hash.delete('pre_neuron')
48
+ id = hash.delete('id') || raise
49
+
50
+ if post_neuron
51
+ connections[id] ||= []
52
+ connections[id] << post_neuron
53
+ end
54
+
55
+ if pre_neuron
56
+ connections[pre_neuron] ||= []
57
+ connections[pre_neuron] << id
58
+ end
59
+
60
+ if hash.empty?
61
+ entities[id] = template
62
+ else
63
+ entities[id] = [template, hash]
64
+ end
65
+ end
66
+
67
+ # new2 is efficient for jsonParser/jsonHash which
68
+ # is implemented as a linked list.
69
+ def to_new2(new)
70
+ new2 = Hash.new
71
+ new2['format'] = 'yinspire.2'
72
+ new2['templates'] = new['templates']
73
+ entities = new2['entities'] = []
74
+ connections = new2['connections'] = []
75
+ new['entities'].keys.sort.each do |id|
76
+ v = new['entities'][id]
77
+ entities << [id, v].flatten
78
+ end
79
+
80
+ new['connections'].keys.sort.each do |from|
81
+ to = new['connections'][from]
82
+ #|from, to|
83
+ connections << [from, to].flatten
84
+ end
85
+
86
+ new2['events'] = new['events']
87
+
88
+ return new2
89
+ end
90
+
91
+ #puts YAML.dump(new)
92
+ #new = to_new2(new)
93
+ json_pp(new)
@@ -0,0 +1,122 @@
1
+ #
2
+ # Pretty print Ruby objects as JSON
3
+ #
4
+ # Copyright (c) 2007 by Michael Neumann (mneumann@ntecs.de)
5
+ #
6
+
7
+ require 'prettyprint'
8
+
9
+ class Hash
10
+ def to_json(pp)
11
+ ks = keys
12
+ pp.group(1, '{', '}') {
13
+ ks.each_with_index do |k, i|
14
+ v = self[k]
15
+
16
+ pp.group {
17
+ pp.text k.to_s.to_json(true)
18
+ pp.text ':'
19
+ pp.group(1) {
20
+ pp.breakable ' '
21
+ case v
22
+ when Hash, Array
23
+ v.to_json(pp)
24
+ else
25
+ pp.text v.to_json
26
+ end
27
+ }
28
+
29
+ if i < ks.size-1
30
+ pp.text ","
31
+ pp.breakable
32
+ end
33
+ }
34
+ end
35
+ }
36
+ end
37
+ end
38
+
39
+ class Array
40
+ def to_json(pp)
41
+ pp.group(1, "[", "]") {
42
+ each_with_index do |v, i|
43
+ pp.group {
44
+ case v
45
+ when Hash, Array
46
+ v.to_json(pp)
47
+ else
48
+ pp.text v.to_json
49
+ end
50
+
51
+ if i < size()-1
52
+ pp.text ","
53
+ pp.breakable ' '
54
+ end
55
+ }
56
+ end
57
+ }
58
+ end
59
+ end
60
+
61
+ class TrueClass
62
+ TRUE = "true".freeze
63
+ def to_json
64
+ TRUE
65
+ end
66
+ end
67
+
68
+ class FalseClass
69
+ FALSE = "false".freeze
70
+ def to_json
71
+ FALSE
72
+ end
73
+ end
74
+
75
+ class NilClass
76
+ NULL = "null".freeze
77
+ def to_json
78
+ NULL
79
+ end
80
+ end
81
+
82
+ class Fixnum
83
+ alias to_json to_s
84
+ end
85
+
86
+ class Bignum
87
+ alias to_json to_s
88
+ end
89
+
90
+ class Float
91
+ alias to_json to_s
92
+ end
93
+
94
+ class String
95
+ def to_json(label=false)
96
+ label = false # FIXME
97
+ if label and self =~ /^[A-Za-z_][A-Za-z0-9_]*$/
98
+ self
99
+ else
100
+ inspect
101
+ end
102
+ end
103
+ end
104
+
105
+ class Symbol
106
+ def to_json(label=false)
107
+ to_s.to_json(label)
108
+ end
109
+ end
110
+
111
+ def json_pp(obj, out=STDOUT, width=79)
112
+ case obj
113
+ when Array, Hash
114
+ q = PrettyPrint.new(out, width)
115
+ obj.to_json(q)
116
+ q.flush
117
+ else
118
+ out << obj.to_json
119
+ end
120
+ out << "\n"
121
+ return out
122
+ end