def test_routing(Simulator, seed, plt): model = spa.Network(seed=seed) model.config[spa.State].vocab = 3 model.config[spa.State].subdimensions = 3 with model: model.ctrl = spa.State(16, subdimensions=16, label='ctrl') def input_func(t): if t < 0.2: return 'A' elif t < 0.4: return 'B' else: return 'C' model.input = spa.Transcode(input_func, output_vocab=16) model.buff1 = spa.State(label='buff1') model.buff2 = spa.State(label='buff2') model.buff3 = spa.State(label='buff3') node1 = nengo.Node([0, 1, 0]) node2 = nengo.Node([0, 0, 1]) nengo.Connection(node1, model.buff1.input) nengo.Connection(node2, model.buff2.input) model.input >> model.ctrl with spa.ActionSelection(): spa.ifmax(spa.dot(model.ctrl, spa.sym.A), model.buff1 >> model.buff3) spa.ifmax(spa.dot(model.ctrl, spa.sym.B), model.buff2 >> model.buff3) spa.ifmax(spa.dot(model.ctrl, spa.sym.C), model.buff1 * model.buff2 >> model.buff3) buff3_probe = nengo.Probe(model.buff3.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.6) data = sim.data[buff3_probe] plt.plot(sim.trange(), data) valueA = np.mean(data[150:200], axis=0) # should be [0, 1, 0] valueB = np.mean(data[350:400], axis=0) # should be [0, 0, 1] valueC = np.mean(data[550:600], axis=0) # should be [1, 0, 0] assert valueA[0] < 0.2 assert valueA[1] > 0.7 assert valueA[2] < 0.2 assert valueB[0] < 0.2 assert valueB[1] < 0.2 assert valueB[2] > 0.7 assert valueC[0] > 0.7 assert valueC[1] < 0.2 assert valueC[2] < 0.2
def test_constructed_objects_are_accessible(): with spa.Network() as model: model.config[spa.State].vocab = 16 model.state1 = spa.State() model.state2 = spa.State() model.state3 = spa.State() with spa.ActionSelection() as actions: spa.ifmax(spa.dot(model.state1, spa.sym.A), model.state3 >> model.state2) spa.ifmax(0.5, spa.sym.B >> model.state2) bg = actions.bg thalamus = actions.thalamus assert isinstance(thalamus.gates[0], nengo.Ensemble) assert isinstance(thalamus.gate_in_connections[0], nengo.Connection) assert isinstance(thalamus.gate_out_connections[0], nengo.Connection) assert isinstance(thalamus.channels[0], spa.State) assert isinstance(thalamus.channel_out_connections[0], nengo.Connection) assert isinstance(thalamus.fixed_connections[1], nengo.Connection) assert thalamus.bg_connection.pre is bg.output assert thalamus.bg_connection.post is thalamus.input
def test_action_selection_enforces_connections_to_be_part_of_action(): with spa.Network(): state1 = spa.State(16) state2 = spa.State(16) with pytest.raises(SpaActionSelectionError): with ActionSelection(): state1 >> state2
def model(self): with spa.Network() as model: model.state_a = spa.State(16) model.state_b = spa.State(32) model.state_c = spa.State(32) model.scalar = spa.Scalar() return model
def test_direct(Simulator, seed): with spa.Network(seed=seed) as model: model.buffer1 = spa.State(vocab=16) model.buffer1.vocab.populate('A; B; C') model.buffer2 = spa.State(vocab=32) model.buffer2.vocab.populate('A; B; C') spa.sym.A >> model.buffer1 spa.sym.B >> model.buffer2 spa.sym.C >> model.buffer1 spa.sym.C >> model.buffer2 with model: p1 = nengo.Probe(model.buffer1.output, synapse=0.03) p2 = nengo.Probe(model.buffer2.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.2) match1 = np.dot(sim.data[p1], model.buffer1.vocab.parse('A+C').v) match2 = np.dot(sim.data[p2], model.buffer2.vocab.parse('B+C').v) # both values should be near 1.0 since buffer1 is driven to both A and C # and buffer2 is driven to both B and C. assert match1[199] > 0.75 assert match2[199] > 0.75
def __init__(self, vocab=Default, feedback=1., feedback_syn=.1, diff_scale=100., subdimensions=16, **kwargs): super(GatedMemory, self).__init__(**kwargs) self.vocab = vocab with self: self.diff = spa.State(self.vocab) self.mem = spa.State(self.vocab, subdimensions=subdimensions, feedback=feedback, feedback_synapse=feedback_syn) self.input_store = nengo.Node(size_in=1) nengo.Connection(self.diff.output, self.mem.input, transform=diff_scale * feedback_syn, synapse=feedback_syn) nengo.Connection(self.mem.output, self.diff.input, transform=-1) inhibit_net(self.input_store, self.diff.state_ensembles, strength=3.) self.input = self.diff.input self.output = self.mem.output self.inputs = dict(default=(self.diff.input, vocab), store=(self.input_store, None)) self.outputs = dict(default=(self.mem.output, vocab))
def test_nondefault_routing(Simulator, seed): m = spa.Network(seed=seed) m.config[spa.State].vocab = 3 m.config[spa.State].subdimensions = 3 with m: m.ctrl = spa.State(16, subdimensions=16, label="ctrl") def input_func(t): if t < 0.2: return "A" elif t < 0.4: return "B" else: return "C" m.input = spa.Transcode(input_func, output_vocab=16) m.buff1 = spa.State(label="buff1") m.buff2 = spa.State(label="buff2") m.cmp = spa.Compare(3) node1 = nengo.Node([0, 1, 0]) node2 = nengo.Node([0, 0, 1]) nengo.Connection(node1, m.buff1.input) nengo.Connection(node2, m.buff2.input) m.input >> m.ctrl with spa.ActionSelection(): spa.ifmax( spa.dot(m.ctrl, spa.sym.A), m.buff1 >> m.cmp.input_a, m.buff1 >> m.cmp.input_b, ) spa.ifmax( spa.dot(m.ctrl, spa.sym.B), m.buff1 >> m.cmp.input_a, m.buff2 >> m.cmp.input_b, ) spa.ifmax( spa.dot(m.ctrl, spa.sym.C), m.buff2 >> m.cmp.input_a, m.buff2 >> m.cmp.input_b, ) compare_probe = nengo.Probe(m.cmp.output, synapse=0.03) with Simulator(m) as sim: sim.run(0.6) similarity = sim.data[compare_probe] valueA = np.mean(similarity[150:200], axis=0) # should be [1] valueB = np.mean(similarity[350:400], axis=0) # should be [0] valueC = np.mean(similarity[550:600], axis=0) # should be [1] assert valueA > 0.6 assert valueB < 0.3 assert valueC > 0.6
def test_no_root_spa_network_required(): with nengo.Network(): # nengo.Network, not spa.Network! state = spa.State(16) state2 = spa.State(16) # Next line will raise an exception if the two states do not share # the same vocab. They are supposed to share the vocab despite not # being in a spa.Network. state >> state2
def test_action_selection_is_not_built_on_exception(): with spa.Network(): state1 = spa.State(16) state2 = spa.State(32) with pytest.raises(SpaTypeError): with ActionSelection() as action_sel: spa.ifmax(1.0, state1 >> state2) assert not action_sel.built
def test_no_magic_vocab_transform(): d = 16 v1 = spa.Vocabulary(d) v2 = spa.Vocabulary(d) with spa.Network() as model: model.a = spa.State(vocab=v1) model.b = spa.State(vocab=v2) with pytest.raises(SpaTypeError): model.a >> model.b
def __init__(self, input_vocab=Default, output_vocab=Default, init_transform=None, learning_rate=1., decay=1., **kwargs): super(UnconstrainedAssocMatLearning, self).__init__(**kwargs) self.input_vocab = input_vocab self.output_vocab = output_vocab with self: self.state = spa.State(self.input_vocab, subdimensions=64) for e in self.state.all_ensembles: e.radius = 0.5 e.intercepts = nengo.dists.Uniform(-1., 1.) e.eval_points = nengo.dists.UniformHypersphere(surface=False) self.target = spa.State(self.output_vocab) self.input_cue = self.state.input self.input_target = self.target.input self.output = nengo.Node(size_in=self.output_vocab.dimensions) self.input_scale = nengo.Node(size_in=1) self.input_no_learn = nengo.Node(size_in=1) inhibit_net(self.input_no_learn, self.target) for i, e in enumerate(self.state.all_ensembles): sd = e.dimensions start = i * sd end = (i + 1) * sd conn = nengo.Connection( e, self.output[start:end], learning_rule_type=AML(sd, learning_rate), function=lambda x, sd=sd: np.zeros(sd), # noqa, pylint: disable=undefined-variable solver=nengo.solvers.LstsqL2(solver=RandomizedSVD())) n = nengo.Node(size_in=sd + 2) nengo.Connection(self.target.output[start:end], n[2:]) nengo.Connection(self.input_scale, n[0], synapse=None) nengo.Connection(nengo.Node(decay), n[1], synapse=None) nengo.Connection(n, conn.learning_rule) if init_transform is not None: nengo.Connection(self.state.output, self.output, transform=init_transform) self.inputs = { 'default': (self.input_cue, self.input_vocab), 'target': (self.input_target, self.output_vocab), 'no_learn': (self.input_no_learn, None), 'scale': (self.input_scale, None) } self.outputs = {'default': (self.output, self.output_vocab)}
def test_constructed_input_connections_are_accessible(): with spa.Network() as model: model.config[spa.State].vocab = 16 model.state1 = spa.State() model.state2 = spa.State() with spa.ActionSelection() as actions: spa.ifmax(spa.dot(model.state1, spa.sym.A), spa.sym.A >> model.state2) bg = actions.bg assert isinstance(bg.input_connections[0], nengo.Connection)
def test_action_selection_is_side_effect_free_if_exception_is_raised(): with spa.Network(): state_a = spa.State(32) state_b = spa.State(32) state_c = spa.State(64) with pytest.raises(SpaTypeError): with ActionSelection(): spa.ifmax(1, state_a >> state_b, state_a >> state_c) with ActionSelection(): pass
def test_routing_recurrency_compilation(Simulator, seed): model = spa.Network(seed=seed) model.config[spa.State].vocab = 2 model.config[spa.State].subdimensions = 2 with model: model.buff1 = spa.State(label="buff1") model.buff2 = spa.State(label="buff2") with spa.ActionSelection(): spa.ifmax(0.5, model.buff1 >> model.buff2, model.buff2 >> model.buff1) with Simulator(model) as sim: assert sim
def __init__(self, dimensions, label=None, seed=None, add_to_container=None): super(SpaCommunicationChannel, self).__init__(label, seed, add_to_container) with self: self.state_in = spa.State(dimensions) self.state_out = spa.State(dimensions) self.secondary = spa.State(dimensions) self.state_in >> self.state_out self.input = self.state_in.input self.input_secondary = self.secondary.input self.output = self.state_out.output self.output_secondary = self.secondary.output
def test_naming_of_actions(): with spa.Network(): state1 = spa.State(16) state2 = spa.State(16) with ActionSelection() as action_sel: u0 = spa.ifmax("name0", 0.0, state1 >> state2) u1 = spa.ifmax(0.0, state1 >> state2) u2 = spa.ifmax("name2", 0.0, state1 >> state2) assert tuple(action_sel.keys()) == ("name0", 1, "name2") assert action_sel["name0"] is u0 assert action_sel["name2"] is u2 for i, u in enumerate((u0, u1, u2)): assert action_sel[i] is u
def BoundedIntegrator(d, beta, **kwargs): kwargs.setdefault('label', "context.BoundedIntegrator") net = nengo.Network(**kwargs) with net: net.input = nengo.Node(size_in=d) net.bias_node = nengo.Node(1) net.gate = spa.State(d) net.current = spa.State(d, feedback=1, neurons_per_dimension=300) net.dot = spa.Compare(d) with nengo.presets.ThresholdingEnsembles(0.): net.update_done = nengo.Ensemble(150, 1) net.update_done_th = nengo.Node(size_in=1) nengo.Connection(net.input, net.gate.input, synapse=None) nengo.Connection(net.input, net.dot.input_a) nengo.Connection(net.gate.output, net.current.input, transform=0.3) nengo.Connection(net.current.output, net.dot.input_b) nengo.Connection(net.dot.output, net.update_done) nengo.Connection(net.bias_node, net.update_done, transform=-beta) nengo.Connection(net.update_done, net.update_done_th, synapse=None, function=lambda x: x > 0) inhibit_net(net.update_done_th, net.gate, strength=3.) ctx_square = net.current.state_ensembles.add_output( 'square', lambda x: x * x) with nengo.presets.ThresholdingEnsembles(-0.1): net.length = nengo.Ensemble(150, 1) nengo.Connection(ctx_square, net.length, transform=-np.ones((1, d))) nengo.Connection(net.bias_node, net.length) net.downscale = spa.State(d) nengo.Connection(net.current.output, net.downscale.input) nengo.Connection(net.downscale.output, net.current.input, transform=-0.1) inhibit_net(net.length, net.downscale, strength=3, function=lambda x: 1 if x >= -0.1 else 0) net.output = net.current.output return net
def test_transform(Simulator, seed): with spa.Network(seed=seed) as model: model.buffer1 = spa.State(vocab=32) model.buffer2 = spa.State(vocab=32) spa.sym.A >> model.buffer1 model.buffer1 * spa.sym.B >> model.buffer2 with model: p = nengo.Probe(model.buffer2.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.2) match = np.dot(sim.data[p], model.buffer2.vocab.parse('A*B').v) assert match[199] > 0.7
def test_encode_with_input(Simulator, seed): with spa.Network(seed=seed) as model: buffer = spa.State(vocab=16) def stimulus(t, x): return x[0] * buffer.vocab.parse('A') ctrl = nengo.Node(lambda t: t > 0.2) encode = spa.Transcode(stimulus, output_vocab=16, size_in=1) nengo.Connection(ctrl, encode.input) encode >> buffer p = nengo.Probe(buffer.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.4) vocab = buffer.vocab assert_sp_close(sim.trange(), sim.data[p], vocab.parse('0'), duration=0.2) assert_sp_close(sim.trange(), sim.data[p], vocab.parse('A'), skip=.38, duration=0.02)
def test_missing_pointer(): vocab = spa.Vocabulary(16) with spa.Network(): a = spa.State(vocab) assert a with pytest.raises(SpaParseError): spa.sym.A >> a
def test_missing_source(): d = 16 with spa.Network(): a = spa.State(d) assert a with pytest.raises(NameError): b >> a # noqa: F821
def test_missing_sink(sink): d = 16 with spa.Network(): a = spa.State(d) assert a with pytest.raises(NameError): eval('a >> %s' % sink)
def test_invalid_sink(sink): d = 16 with spa.Network(): a = spa.State(d) assert a with pytest.raises((SyntaxError, SpaTypeError)): eval('a >> {}'.format(sink))
def test_no_feedback_run(Simulator, plt, seed): with spa.Network(seed=seed) as model: state = spa.State(vocab=32, feedback=0.0) def state_input(t): if 0 <= t < 0.3: return "A" elif 0.2 <= t < 0.6: return "B" else: return "0" state_input = spa.Transcode(state_input, output_vocab=32) state_input >> state with model: p = nengo.Probe(state.output, synapse=0.05) with Simulator(model) as sim: sim.run(0.8) data = np.dot(sim.data[p], state.vocab.vectors.T) plt.plot(sim.trange(), data) assert data[299, 0] > 0.9 assert data[299, 1] < 0.2 assert data[599, 0] < 0.2 assert data[599, 1] > 0.9 assert data[799, 0] < 0.2 assert data[799, 1] < 0.2
def test_memory_run(Simulator, seed, plt): with spa.Network(seed=seed) as model: memory = spa.State(vocab=32, feedback=1.0, feedback_synapse=0.01) def state_input(t): if 0 <= t < 0.05: return "A" else: return "0" state_input = spa.Transcode(state_input, output_vocab=32) state_input >> memory with model: p = nengo.Probe(memory.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.5) t = sim.trange() similarity = np.dot(sim.data[p], memory.vocab.vectors.T) plt.plot(t, similarity) plt.ylabel("Similarity to 'A'") plt.xlabel("Time (s)") # value should peak above 1.0, then decay down to near 1.0 assert np.mean(similarity[(t > 0.05) & (t < 0.1)]) > 1.0 assert np.mean(similarity[(t > 0.2) & (t < 0.3)]) > 0.7 assert np.mean(similarity[t > 0.49]) > 0.5
def test_errors(): # motor does not exist with pytest.raises(AttributeError): with spa.Network() as model: model.vision = spa.State(vocab=16) with spa.ActionSelection: spa.ifmax(0.5, spa.sym.A >> model.motor)
def test_memory_run_decay(Simulator, plt, seed): with spa.Network(seed=seed) as model: memory = spa.State(vocab=32, feedback=(1.0 - 0.01 / 0.05), feedback_synapse=0.01) def state_input(t): if 0 <= t < 0.05: return "A" else: return "0" state_input = spa.Transcode(state_input, output_vocab=32) state_input >> memory with model: p = nengo.Probe(memory.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.3) data = np.dot(sim.data[p], memory.vocab.vectors.T) t = sim.trange() plt.plot(t, data) assert data[t == 0.05, 0] > 1.0 assert data[t == 0.299, 0] < 0.4
def test_neurons(): with spa.Network(): state = spa.State(vocab=16, neurons_per_dimension=2, represent_cc_identity=False) assert len(state.state_ensembles.ensembles) == 1 assert state.state_ensembles.ensembles[0].n_neurons == 16 * 2 with spa.Network(): state = spa.State(vocab=16, subdimensions=1, neurons_per_dimension=2, represent_cc_identity=False) assert len(state.state_ensembles.ensembles) == 16 assert state.state_ensembles.ensembles[0].n_neurons == 2
def test_output_types(Simulator, value): with spa.Network() as model: stim = spa.Transcode(value, output_vocab=32) state = spa.State(32) stim >> state with Simulator(model) as sim: sim.run(0.01)
def test_translate(Simulator, seed): with spa.Network(seed=seed) as model: model.buffer1 = spa.State(vocab=16) model.buffer2 = spa.State(vocab=32) spa.sym.A >> model.buffer1 spa.translate(model.buffer1, model.buffer2.vocab, populate=True) >> model.buffer2 with model: p = nengo.Probe(model.buffer2.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.2) match = np.dot(sim.data[p], model.buffer2.vocab.parse("A").v) assert match[199] > 0.8