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,181 @@
|
|
1
|
+
require 'Yinspire/Loaders/Loader'
|
2
|
+
require 'yaml' # YAML is a superset of JSON
|
3
|
+
|
4
|
+
class Loader_JSON < Loader
|
5
|
+
|
6
|
+
def load(filename)
|
7
|
+
@entities = Hash.new
|
8
|
+
data = YAML.load(File.read(filename))
|
9
|
+
|
10
|
+
case data['format']
|
11
|
+
when 'yinspire.1'
|
12
|
+
load_v1(data)
|
13
|
+
when 'yinspire.c'
|
14
|
+
load_c(data)
|
15
|
+
else
|
16
|
+
raise "invalid format"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
#
|
23
|
+
# Format:
|
24
|
+
#
|
25
|
+
# {
|
26
|
+
# templates: {
|
27
|
+
# 'MyNeuron' => ['Neuron_SRM01', {tau_m: 0.5, :ref_weight: 0.1}],
|
28
|
+
# 'MySynapse' => ['Synapse', {weight: 1.0, delay: 0.5}]
|
29
|
+
# },
|
30
|
+
# entities: {
|
31
|
+
# 'id1' => ['MyNeuron', {tau_m: 5.1, const_threshold: 0.44}],
|
32
|
+
# 'id2' => ['Neuron_SRM01', {}],
|
33
|
+
# 'id3' => ['MySynapse'],
|
34
|
+
# 'id4' => 'MyNeuron'
|
35
|
+
# },
|
36
|
+
# connections: {
|
37
|
+
# 'id1' => ['id2', 'id3'],
|
38
|
+
# 'id2' => ['id1']
|
39
|
+
# },
|
40
|
+
# events: {
|
41
|
+
# 'id1' => [100.0, 101.0, timestamp_x, timestamp_y],
|
42
|
+
# 'id2' => [444, 555]
|
43
|
+
# }
|
44
|
+
# }
|
45
|
+
#
|
46
|
+
# Every "section" is optional.
|
47
|
+
#
|
48
|
+
def load_v1(data)
|
49
|
+
templates = data['templates'] || {}
|
50
|
+
entities = data['entities'] || {}
|
51
|
+
connections = data['connections'] || {}
|
52
|
+
events = data['events'] || {}
|
53
|
+
|
54
|
+
#
|
55
|
+
# construct entities
|
56
|
+
#
|
57
|
+
hash = Hash.new
|
58
|
+
entities.each do |id, entity_spec|
|
59
|
+
type, data = *entity_spec
|
60
|
+
|
61
|
+
if t = templates[type]
|
62
|
+
type, template_data = *t
|
63
|
+
hash.update(template_data) if template_data
|
64
|
+
end
|
65
|
+
|
66
|
+
hash.update(data) if data
|
67
|
+
|
68
|
+
create_entity(type, id, hash)
|
69
|
+
|
70
|
+
hash.clear
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# connect them
|
75
|
+
#
|
76
|
+
connections.each do |src, destinations|
|
77
|
+
entity = @entities[src]
|
78
|
+
destinations.each do |dest|
|
79
|
+
entity.connect(@entities[dest])
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# stimulate with events
|
85
|
+
#
|
86
|
+
events.each do |id, time_series|
|
87
|
+
entity = @entities[id]
|
88
|
+
time_series.each do |at|
|
89
|
+
entity.stimulate(at, Infinity, nil)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# This is a version for the pure C++ version of Yinspire. It doesn't
|
96
|
+
# use hashes for entities and connections (because the C++ JSON library
|
97
|
+
# does not implement efficient hash lookup).
|
98
|
+
#
|
99
|
+
# {
|
100
|
+
# templates: {
|
101
|
+
# 'MyNeuron' => ['Neuron_SRM01', {tau_m: 0.5, :ref_weight: 0.1}],
|
102
|
+
# 'MySynapse' => ['Synapse', {weight: 1.0, delay: 0.5}]
|
103
|
+
# },
|
104
|
+
# entities: [
|
105
|
+
# ['id1', 'MyNeuron'],
|
106
|
+
# ['id2', 'Neuron_SRM01'],
|
107
|
+
# ['id3', 'MySynapse'],
|
108
|
+
# ['id4', 'MyNeuron']
|
109
|
+
# ],
|
110
|
+
# connections: {
|
111
|
+
# ['id1', 'id2', 'id3'],
|
112
|
+
# ['id2', 'id1']
|
113
|
+
# },
|
114
|
+
# events: {
|
115
|
+
# 'id1' => [100.0, 101.0, timestamp_x, timestamp_y],
|
116
|
+
# 'id2' => [444, 555]
|
117
|
+
# }
|
118
|
+
# }
|
119
|
+
#
|
120
|
+
# Every "section" is optional.
|
121
|
+
#
|
122
|
+
# BUGS:
|
123
|
+
#
|
124
|
+
# The C++ version does not currently implement to specify an
|
125
|
+
# entity like this:
|
126
|
+
#
|
127
|
+
# ['id1', 'Neuron_SRM01', {...}]
|
128
|
+
#
|
129
|
+
def load_c(data)
|
130
|
+
templates = data['templates'] || {}
|
131
|
+
entities = data['entities'] || []
|
132
|
+
connections = data['connections'] || []
|
133
|
+
events = data['events'] || {}
|
134
|
+
|
135
|
+
#
|
136
|
+
# construct entities
|
137
|
+
#
|
138
|
+
hash = Hash.new
|
139
|
+
entities.each do |arr|
|
140
|
+
hash.clear
|
141
|
+
|
142
|
+
id, type, data = *arr
|
143
|
+
|
144
|
+
if t = templates[type]
|
145
|
+
type, template_data = *t
|
146
|
+
hash.update(template_data)
|
147
|
+
end
|
148
|
+
|
149
|
+
if data
|
150
|
+
hash.update(data)
|
151
|
+
raise # FIXME: C++ version is invalid, because it assume that there
|
152
|
+
# is no data!
|
153
|
+
end
|
154
|
+
|
155
|
+
create_entity(type, id, hash)
|
156
|
+
end
|
157
|
+
|
158
|
+
#
|
159
|
+
# connect them
|
160
|
+
#
|
161
|
+
connections.each do |arr|
|
162
|
+
src, *destinations = *arr
|
163
|
+
raise if destinations.empty?
|
164
|
+
entity = @entities[src] || raise
|
165
|
+
destinations.each do |dest|
|
166
|
+
entity.connect(@entities[dest] || raise)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
#
|
171
|
+
# stimulate with events
|
172
|
+
#
|
173
|
+
events.each do |id, time_series|
|
174
|
+
entity = @entities[id] || raise
|
175
|
+
time_series.each do |at|
|
176
|
+
entity.stimulate(at, Infinity, nil)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'Yinspire/Loaders/Loader'
|
2
|
+
|
3
|
+
#
|
4
|
+
# Loader for spikes in the format:
|
5
|
+
#
|
6
|
+
# Id1 weight1@time1 time2 time3 ...
|
7
|
+
# Id2 time1 time2 time3 ...
|
8
|
+
# ...
|
9
|
+
#
|
10
|
+
# Weight values (e.g. 1.0@time1) are optional.
|
11
|
+
#
|
12
|
+
# Lines beginning with "#" are comments.
|
13
|
+
#
|
14
|
+
class Loader_Spike < Loader
|
15
|
+
|
16
|
+
def load(filename)
|
17
|
+
File.open(filename, 'r') do |f|
|
18
|
+
while line = f.gets
|
19
|
+
line.strip!
|
20
|
+
next if line =~ /^#/ # comment
|
21
|
+
|
22
|
+
#
|
23
|
+
# The following code is to help Matlab to generate spike trains
|
24
|
+
# more easily and allows spaces before and after the "@", e.g.
|
25
|
+
# "123 @ 444".
|
26
|
+
#
|
27
|
+
line.gsub!(/\s+@\s+/, '')
|
28
|
+
|
29
|
+
id, *spikes = line.split
|
30
|
+
raise if spikes.empty?
|
31
|
+
entity = @entities[id] || raise
|
32
|
+
|
33
|
+
spikes.each do |spike|
|
34
|
+
weight, at = spike.split("@")
|
35
|
+
weight, at = Infinity, weight if at.nil? # spike is a pure time-value
|
36
|
+
entity.stimulate(at.to_f, weight.to_f, nil)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'Yinspire/Loaders/Loader'
|
2
|
+
require 'Yinspire/Loaders/YinScanner'
|
3
|
+
|
4
|
+
#
|
5
|
+
# This is a human readable data format for describing neural nets
|
6
|
+
# as well as stimulations.
|
7
|
+
#
|
8
|
+
# Note that it is a streaming scanner/parser, i.e. it's important
|
9
|
+
# to put the template definitions before you actually use them.
|
10
|
+
# The same applies to stimulations and connections!
|
11
|
+
#
|
12
|
+
class Loader_Yin < Loader
|
13
|
+
require 'enumerator'
|
14
|
+
|
15
|
+
def load(filename)
|
16
|
+
templates = {}
|
17
|
+
hash = Hash.new
|
18
|
+
YinScanner.new(File.read(filename)).scan do |cmd|
|
19
|
+
case cmd.shift
|
20
|
+
when :entity
|
21
|
+
ids, type, prop_list = *cmd
|
22
|
+
|
23
|
+
hash.clear
|
24
|
+
if t = templates[type]
|
25
|
+
type, template_data = *t
|
26
|
+
hash.update(template_data) if template_data
|
27
|
+
end
|
28
|
+
hash.update(prop_list) if prop_list
|
29
|
+
|
30
|
+
ids.each {|id| create_entity(type, id, hash) }
|
31
|
+
when :connect
|
32
|
+
cmd.first.each_cons(2) do |from, to|
|
33
|
+
from.each {|f|
|
34
|
+
entity = @entities[f]
|
35
|
+
to.each {|t| entity.connect(@entities[t]) }
|
36
|
+
}
|
37
|
+
end
|
38
|
+
when :stimulate
|
39
|
+
ids, stimuls = *cmd
|
40
|
+
|
41
|
+
ids.map! {|id| @entities[id] }
|
42
|
+
|
43
|
+
stimuls.each do |sti|
|
44
|
+
at, weight = *sti
|
45
|
+
weight ||= Infinity
|
46
|
+
ids.each {|entity|
|
47
|
+
entity.stimulate(at, weight, nil)
|
48
|
+
}
|
49
|
+
end
|
50
|
+
when :template
|
51
|
+
ids, base_type, prop_list = *cmd
|
52
|
+
ids.each do |id|
|
53
|
+
raise if templates[id]
|
54
|
+
templates[id] = [base_type, prop_list]
|
55
|
+
end
|
56
|
+
else
|
57
|
+
raise
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,247 @@
|
|
1
|
+
class YinScanner
|
2
|
+
require 'strscan'
|
3
|
+
|
4
|
+
def initialize(str)
|
5
|
+
@s = StringScanner.new(str)
|
6
|
+
@inf = 1.0/0.0
|
7
|
+
end
|
8
|
+
|
9
|
+
def scan
|
10
|
+
while cmd = scan_command()
|
11
|
+
yield cmd
|
12
|
+
end
|
13
|
+
skip_ws()
|
14
|
+
raise "ParseError" unless @s.eos?
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def skip_ws
|
20
|
+
while @s.skip(/(\s+)/) or # skip whitespace
|
21
|
+
@s.skip(/[#](.*)/) # skip comments
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def scan_property
|
26
|
+
pos = @s.pos
|
27
|
+
if name = scan_id()
|
28
|
+
skip_ws()
|
29
|
+
if @s.skip(/=/)
|
30
|
+
value = scan_value()
|
31
|
+
if value != nil
|
32
|
+
return name, value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
@s.pos = pos
|
38
|
+
return nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def scan_command
|
42
|
+
skip_ws()
|
43
|
+
type = nil
|
44
|
+
if str = @s.scan(/(TEMPLATE|ENTITY|CONNECT|STIMULATE)\s+/)
|
45
|
+
str.strip!
|
46
|
+
str.downcase!
|
47
|
+
type = str.to_sym
|
48
|
+
end
|
49
|
+
|
50
|
+
ids = scan_idlist()
|
51
|
+
raise "ParseError" if type != nil and ids.empty?
|
52
|
+
return nil if ids.empty?
|
53
|
+
|
54
|
+
scanned_type = scan_type()
|
55
|
+
|
56
|
+
raise "ParseError" if (type and type != scanned_type) or scanned_type.nil?
|
57
|
+
|
58
|
+
case scanned_type
|
59
|
+
when :entity, :template
|
60
|
+
id = scan_id()
|
61
|
+
raise "ParseError" unless id
|
62
|
+
prop_list = scan_propertylist()
|
63
|
+
return scanned_type, ids, id, prop_list
|
64
|
+
when :stimulate
|
65
|
+
stimuls = scan_stimulationlist()
|
66
|
+
raise "ParseError" unless stimuls
|
67
|
+
return scanned_type, ids, stimuls
|
68
|
+
when :connect
|
69
|
+
conns = []
|
70
|
+
conns << ids
|
71
|
+
loop do
|
72
|
+
l = scan_idlist()
|
73
|
+
break if l.empty?
|
74
|
+
conns << l
|
75
|
+
|
76
|
+
skip_ws()
|
77
|
+
break unless @s.skip(/->/)
|
78
|
+
end
|
79
|
+
raise "ParseError" if conns.size < 2
|
80
|
+
return scanned_type, conns
|
81
|
+
else
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def scan_propertylist
|
87
|
+
pos = @s.pos
|
88
|
+
skip_ws()
|
89
|
+
props = {}
|
90
|
+
if @s.skip(/[{]/)
|
91
|
+
loop do
|
92
|
+
name, value = scan_property()
|
93
|
+
break unless name
|
94
|
+
props[name] = value
|
95
|
+
end
|
96
|
+
skip_ws()
|
97
|
+
return props if @s.skip(/[}]/)
|
98
|
+
end
|
99
|
+
|
100
|
+
@s.pos = pos
|
101
|
+
return nil
|
102
|
+
end
|
103
|
+
|
104
|
+
def scan_value
|
105
|
+
skip_ws()
|
106
|
+
if str = @s.scan(/[+-]?[0-9]+([.][0-9]+([eE][+-]?[0-9]+)?)?/)
|
107
|
+
str.to_f
|
108
|
+
elsif @s.skip(/[+]?Inf(inity)?/i)
|
109
|
+
@inf
|
110
|
+
elsif @s.skip(/[-]?Inf(inity)?/i)
|
111
|
+
-@inf
|
112
|
+
elsif @s.skip(/true/)
|
113
|
+
true
|
114
|
+
elsif @s.skip(/false/)
|
115
|
+
false
|
116
|
+
else
|
117
|
+
nil
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# no skip_ws!
|
122
|
+
def scan_float
|
123
|
+
if str = @s.scan(/[+-]?[0-9]+([.][0-9]+([eE][+-]?[0-9]+)?)?/)
|
124
|
+
str.to_f
|
125
|
+
elsif @s.skip(/[+]?Inf(inity)?/i)
|
126
|
+
@inf
|
127
|
+
elsif @s.skip(/[-]?Inf(inity)?/i)
|
128
|
+
-@inf
|
129
|
+
else
|
130
|
+
nil
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def scan_stimulationlist
|
135
|
+
pos = @s.pos
|
136
|
+
skip_ws()
|
137
|
+
stimuls = []
|
138
|
+
if @s.skip(/[{]/)
|
139
|
+
loop do
|
140
|
+
arr = scan_stimulation()
|
141
|
+
break unless arr
|
142
|
+
stimuls << arr
|
143
|
+
end
|
144
|
+
skip_ws()
|
145
|
+
return stimuls if @s.skip(/[}]/)
|
146
|
+
end
|
147
|
+
|
148
|
+
@s.pos = pos
|
149
|
+
return nil
|
150
|
+
end
|
151
|
+
|
152
|
+
# [weight@]at
|
153
|
+
# no skip_ws!
|
154
|
+
#
|
155
|
+
def scan_stimulation
|
156
|
+
pos = @s.pos
|
157
|
+
skip_ws()
|
158
|
+
|
159
|
+
if at = scan_float()
|
160
|
+
if @s.skip(/@/)
|
161
|
+
weight = at
|
162
|
+
if at = scan_float()
|
163
|
+
return at, weight
|
164
|
+
end
|
165
|
+
else
|
166
|
+
return at
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
@s.pos = pos
|
171
|
+
return nil
|
172
|
+
end
|
173
|
+
|
174
|
+
def scan_id
|
175
|
+
pos = @s.pos
|
176
|
+
skip_ws()
|
177
|
+
if @s.skip(/["]/)
|
178
|
+
id = @s.scan(/[^"]+/)
|
179
|
+
unless @s.skip(/["]/)
|
180
|
+
@s.pos = pos
|
181
|
+
id = nil
|
182
|
+
end
|
183
|
+
else
|
184
|
+
id = @s.scan(/\w+/)
|
185
|
+
end
|
186
|
+
return id
|
187
|
+
end
|
188
|
+
|
189
|
+
def scan_idlist
|
190
|
+
ids = []
|
191
|
+
loop do
|
192
|
+
id = scan_id()
|
193
|
+
break unless id
|
194
|
+
ids << id
|
195
|
+
skip_ws()
|
196
|
+
break unless @s.skip(/,/) # we expect a "," here
|
197
|
+
end
|
198
|
+
ids
|
199
|
+
end
|
200
|
+
|
201
|
+
def scan_type
|
202
|
+
skip_ws()
|
203
|
+
if @s.skip(/[=]/) then :entity
|
204
|
+
elsif @s.skip(/->/) then :connect
|
205
|
+
elsif @s.skip(/[!]/) then :stimulate
|
206
|
+
elsif @s.skip(/[<]/) then :template
|
207
|
+
else
|
208
|
+
nil
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
if __FILE__ == $0
|
214
|
+
s = YinScanner.new(<<-EOS)
|
215
|
+
#
|
216
|
+
# This is a comment
|
217
|
+
# This also.
|
218
|
+
#
|
219
|
+
# Command names like "TEMPLATE", "ENTITY", "CONNECT" and "STIMULATE"
|
220
|
+
# are optional.
|
221
|
+
#
|
222
|
+
|
223
|
+
TEMPLATE InputType < Neuron_Input {
|
224
|
+
const_threshold = +1.2e+200
|
225
|
+
last_spike_time = -Infinity
|
226
|
+
}
|
227
|
+
|
228
|
+
ENTITY Input1, "input2", Input2, Input3 = InputType
|
229
|
+
ENTITY Input4 = InputType
|
230
|
+
|
231
|
+
Input5, Input6 = Neuron_SRM01 {
|
232
|
+
mem_pot = 10.0
|
233
|
+
}
|
234
|
+
|
235
|
+
Syn1, Syn2, Syn3 = Synapse {
|
236
|
+
weight = 2.3
|
237
|
+
delay = 0.4
|
238
|
+
}
|
239
|
+
|
240
|
+
CONNECT Input1 -> Syn1, Syn2 -> Input5
|
241
|
+
|
242
|
+
STIMULATE Input1, Input5 ! {
|
243
|
+
123@4.4 Inf@23.3 4.5 # weight defaults to Infinity
|
244
|
+
}
|
245
|
+
EOS
|
246
|
+
s.scan {|cmd| p cmd}
|
247
|
+
end
|