def test_am_basic(Simulator, plt, seed, rng): """Basic associative memory test.""" d = 64 vocab = Vocabulary(d, pointer_gen=rng) vocab.populate("A; B; C; D") with spa.Network("model", seed=seed) as m: m.am = ThresholdingAssocMem( threshold=0.3, input_vocab=vocab, mapping=vocab.keys(), function=filtered_step_fn, ) spa.sym.A >> m.am in_p = nengo.Probe(m.am.input) out_p = nengo.Probe(m.am.output, synapse=0.03) with Simulator(m) as sim: sim.run(0.2) t = sim.trange() plt.subplot(3, 1, 1) plt.plot(t, similarity(sim.data[in_p], vocab)) plt.ylabel("Input") plt.ylim(top=1.1) plt.subplot(3, 1, 2) plt.plot(t, similarity(sim.data[out_p], vocab)) plt.plot(t[t > 0.15], np.ones(t.shape)[t > 0.15] * 0.95, c="g", lw=2) plt.ylabel("Output") assert_sp_close(t, sim.data[in_p], vocab["A"], skip=0.15, atol=0.05) assert_sp_close(t, sim.data[out_p], vocab["A"], skip=0.15)
def test_binary_operation_on_modules_with_fixed_pointer( Simulator, algebra, op, order, rng): vocab = spa.Vocabulary(16, pointer_gen=rng, algebra=algebra) vocab.populate("A; B") b = SemanticPointer(vocab["B"].v) # noqa: F841 with spa.Network() as model: a = spa.Transcode("A", output_vocab=vocab) # noqa: F841 if order == "AB": x = eval("a" + op + "b") elif order == "BA": x = eval("b" + op + "a") else: raise ValueError("Invalid order argument.") p = nengo.Probe(x.construct(), synapse=0.03) with Simulator(model) as sim: sim.run(0.3) assert_sp_close( sim.trange(), sim.data[p], vocab.parse(order[0] + op + order[1]), skip=0.2, atol=0.3, )
def test_unbind(Simulator, side, seed): rng = np.random.RandomState(seed) vocab = spa.Vocabulary(36, pointer_gen=rng, algebra=VtbAlgebra()) vocab.populate("A; B") with spa.Network(seed=seed) as model: vtb = VTB(100, 36, unbind_left=(side == "left"), unbind_right=(side == "right")) if side == "left": left = nengo.Node(vocab["B"].v) right = nengo.Node(vocab.parse("B*A").v) elif side == "right": left = nengo.Node(vocab.parse("A*B").v) right = nengo.Node(vocab["B"].v) else: raise ValueError("Invalid 'side' value.") nengo.Connection(left, vtb.input_left) nengo.Connection(right, vtb.input_right) p = nengo.Probe(vtb.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.2) assert_sp_close(sim.trange(), sim.data[p], vocab.parse("A * B * ~B"), skip=0.15, atol=0.3)
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_unbind(Simulator, algebra, side, seed): rng = np.random.RandomState(seed) vocab = spa.Vocabulary(64, pointer_gen=rng, algebra=algebra) vocab.populate('A; B') with spa.Network(seed=seed) as model: model.bind = spa.Bind(vocab, unbind_left=(side == 'left'), unbind_right=(side == 'right')) if side == 'left': spa.sym.B >> model.bind.input_left spa.sym.B * spa.sym.A >> model.bind.input_right elif side == 'right': spa.sym.A * spa.sym.B >> model.bind.input_left spa.sym.B >> model.bind.input_right else: raise ValueError("Invalid 'side' value.") with model: p = nengo.Probe(model.bind.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.2) assert_sp_close(sim.trange(), sim.data[p], vocab.parse('A * B * ~B'), skip=0.15, atol=0.3)
def test_passthrough(Simulator, seed): with spa.Network(seed=seed) as model: passthrough = Transcode(input_vocab=16, output_vocab=16) spa.sym.A >> passthrough p = nengo.Probe(passthrough.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.2) assert_sp_close(sim.trange(), sim.data[p], passthrough.output_vocab.parse('A'), skip=0.18)
def test_unary_operation_on_module(Simulator, algebra, op, suffix, rng): vocab = spa.Vocabulary(16, pointer_gen=rng, algebra=algebra) vocab.populate("A") with spa.Network() as model: stimulus = spa.Transcode("A", output_vocab=vocab) # noqa: F841 x = eval(op + "stimulus" + suffix) p = nengo.Probe(x.construct(), synapse=0.03) with Simulator(model) as sim: sim.run(0.3) assert_sp_close(sim.trange(), sim.data[p], vocab.parse(op + "A"), skip=0.2)
def test_assignment_of_pointer_symbol(Simulator, rng): vocab = spa.Vocabulary(16, pointer_gen=rng) vocab.populate("A") with spa.Network() as model: sink = spa.State(vocab) PointerSymbol("A") >> sink p = nengo.Probe(sink.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.5) assert_sp_close(sim.trange(), sim.data[p], vocab["A"], skip=0.3)
def test_assignment_of_dynamic_pointer(Simulator, rng): vocab = spa.Vocabulary(16, pointer_gen=rng) vocab.populate('A') with spa.Network() as model: source = spa.Transcode('A', output_vocab=vocab) sink = spa.State(vocab) source >> sink p = nengo.Probe(sink.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.5) assert_sp_close(sim.trange(), sim.data[p], vocab['A'], skip=0.3)
def test_transcode(Simulator, seed): def transcode_fn(t, sp): assert t < 0.15 or sp.vocab.parse('A').dot(sp) > 0.8 return 'B' with spa.Network(seed=seed) as model: transcode = Transcode(transcode_fn, input_vocab=16, output_vocab=16) spa.sym.A >> transcode p = nengo.Probe(transcode.output, synapse=None) with Simulator(model) as sim: sim.run(0.2) assert_sp_close(sim.trange(), sim.data[p], transcode.output_vocab.parse('B'))
def test_dynamic_translate(Simulator, rng): v1 = spa.Vocabulary(64, pointer_gen=rng) v1.populate("A; B") v2 = spa.Vocabulary(64, pointer_gen=rng) v2.populate("A; B") with spa.Network() as model: source = spa.Transcode("A", output_vocab=v1) x = spa.translate(source, v2) p = nengo.Probe(x.construct(), synapse=0.03) with nengo.Simulator(model) as sim: sim.run(0.5) assert_sp_close(sim.trange(), sim.data[p], v2["A"], skip=0.3, atol=0.2)
def test_transformed_and_pointer_symbol(Simulator, algebra, rng): vocab = spa.Vocabulary(16, pointer_gen=rng, algebra=algebra) vocab.populate("A; B") with spa.Network() as model: a = spa.Transcode("A", output_vocab=vocab) x = (a * PointerSymbol("B")) * PointerSymbol("~B") p = nengo.Probe(x.construct(), synapse=0.3) with nengo.Simulator(model) as sim: sim.run(0.3) assert_sp_close(sim.trange(), sim.data[p], vocab.parse("A * B * ~B"), skip=0.2, normalized=True)
def test_transformed(Simulator, algebra, rng): vocab = spa.Vocabulary(16, pointer_gen=rng, algebra=algebra) vocab.populate('A; B') with spa.Network() as model: a = spa.Transcode('A', output_vocab=vocab) x = PointerSymbol('B') * a p = nengo.Probe(x.construct(), synapse=0.3) with nengo.Simulator(model) as sim: sim.run(0.3) assert_sp_close(sim.trange(), sim.data[p], vocab.parse('B*A'), skip=0.2, normalized=True)
def test_am_wta(Simulator, plt, seed, rng): """Test the winner-take-all ability of the associative memory.""" d = 64 vocab = Vocabulary(d, pointer_gen=rng) vocab.populate("A; B; C; D") def input_func(t): if t < 0.2: return "A + 0.8 * B" elif t < 0.3: return "0" else: return "0.8 * A + B" with spa.Network("model", seed=seed) as m: m.am = WTAAssocMem( threshold=0.3, input_vocab=vocab, mapping=vocab.keys(), function=filtered_step_fn, ) m.stimulus = spa.Transcode(input_func, output_vocab=vocab) m.stimulus >> m.am in_p = nengo.Probe(m.am.input) out_p = nengo.Probe(m.am.output, synapse=0.03) with Simulator(m) as sim: sim.run(0.5) t = sim.trange() more_a = (t > 0.15) & (t < 0.2) more_b = t > 0.45 plt.subplot(2, 1, 1) plt.plot(t, similarity(sim.data[in_p], vocab)) plt.ylabel("Input") plt.ylim(top=1.1) plt.subplot(2, 1, 2) plt.plot(t, similarity(sim.data[out_p], vocab)) plt.plot(t[more_a], np.ones(t.shape)[more_a] * 0.9, c="g", lw=2) plt.plot(t[more_b], np.ones(t.shape)[more_b] * 0.9, c="g", lw=2) plt.ylabel("Output") assert_sp_close(t, sim.data[out_p], vocab["A"], skip=0.15, duration=0.05) assert_sp_close(t, sim.data[out_p], vocab["B"], skip=0.45, duration=0.05)
def test_binary_operation_on_modules(Simulator, algebra, op, suffix, rng): vocab = spa.Vocabulary(16, pointer_gen=rng, algebra=algebra) vocab.populate('A; B') with spa.Network() as model: a = spa.Transcode('A', output_vocab=vocab) # noqa: F841 b = spa.Transcode('B', output_vocab=vocab) # noqa: F841 x = eval('a' + suffix + op + 'b' + suffix) p = nengo.Probe(x.construct(), synapse=0.03) with Simulator(model) as sim: sim.run(0.3) assert_sp_close(sim.trange(), sim.data[p], vocab.parse('A' + op + 'B'), skip=0.2, atol=0.3)
def test_add_output(Simulator, seed, rng, plt): d = 8 pointer = next(UnitLengthVectors(d, rng)) with nengo.Network(seed=seed) as model: ea = IdentityEnsembleArray(15, d, 4) input_node = nengo.Node(pointer) nengo.Connection(input_node, ea.input) out = ea.add_output('const', lambda x: -x) assert ea.const is out p = nengo.Probe(out, synapse=0.01) with Simulator(model) as sim: sim.run(0.3) plt.plot(sim.trange(), np.dot(sim.data[p], -pointer)) assert_sp_close(sim.trange(), sim.data[p], SemanticPointer(-pointer), skip=0.2, atol=0.3)
def test_am_ia(Simulator, plt, seed, rng): """Test the winner-take-all ability of the IA memory.""" d = 64 vocab = Vocabulary(d, pointer_gen=rng) vocab.populate("A; B; C; D") def input_func(t): if t < 0.2: return "A + 0.8 * B" else: return "0.6 * A + B" with spa.Network("model", seed=seed) as m: m.am = IAAssocMem(input_vocab=vocab, mapping=vocab.keys()) m.stimulus = spa.Transcode(input_func, output_vocab=vocab) m.reset = nengo.Node(lambda t: 0.2 < t < 0.4) m.stimulus >> m.am nengo.Connection(m.reset, m.am.input_reset, synapse=0.1) in_p = nengo.Probe(m.am.input) reset_p = nengo.Probe(m.reset) out_p = nengo.Probe(m.am.output, synapse=0.03) with nengo.Simulator(m) as sim: sim.run(0.7) t = sim.trange() more_a = (t > 0.15) & (t < 0.2) more_b = t > 0.65 plt.subplot(2, 1, 1) plt.plot(t, similarity(sim.data[in_p], vocab)) plt.plot(t, sim.data[reset_p], c="k", linestyle="--") plt.ylabel("Input") plt.ylim(top=1.1) plt.subplot(2, 1, 2) plt.plot(t, similarity(sim.data[out_p], vocab)) plt.plot(t[more_a], np.ones(t.shape)[more_a] * 0.9, c="tab:blue", lw=2) plt.plot(t[more_b], np.ones(t.shape)[more_b] * 0.9, c="tab:orange", lw=2) plt.ylabel("Output") assert_sp_close(t, sim.data[out_p], vocab["A"], skip=0.15, duration=0.05) assert_sp_close(t, sim.data[out_p], vocab["B"], skip=0.65, duration=0.05)
def test_bind(Simulator, seed): rng = np.random.RandomState(seed) vocab = spa.Vocabulary(16, pointer_gen=rng, algebra=VtbAlgebra()) vocab.populate("A; B") with spa.Network(seed=seed) as model: vtb = VTB(100, 16) nengo.Connection(nengo.Node(vocab["A"].v), vtb.input_left) nengo.Connection(nengo.Node(vocab["B"].v), vtb.input_right) p = nengo.Probe(vtb.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.2) assert_sp_close(sim.trange(), sim.data[p], vocab.parse("A*B"), skip=0.15, atol=0.3)
def test_am_threshold(Simulator, plt, seed, rng): """Associative memory thresholding with differing input/output vocabs.""" d = 64 vocab = Vocabulary(d, pointer_gen=rng) vocab.populate("A; B; C; D") d2 = int(d / 2) vocab2 = Vocabulary(d2, pointer_gen=rng) vocab2.populate("A; B; C; D") def input_func(t): return "0.49 * A" if t < 0.1 else "0.8 * B" with spa.Network("model", seed=seed) as m: m.am = ThresholdingAssocMem( threshold=0.5, input_vocab=vocab, output_vocab=vocab2, function=filtered_step_fn, mapping="by-key", ) m.stimulus = spa.Transcode(input_func, output_vocab=vocab) m.stimulus >> m.am in_p = nengo.Probe(m.am.input) out_p = nengo.Probe(m.am.output, synapse=0.03) with Simulator(m) as sim: sim.run(0.3) t = sim.trange() below_th = t < 0.1 above_th = t > 0.25 plt.subplot(2, 1, 1) plt.plot(t, similarity(sim.data[in_p], vocab)) plt.ylabel("Input") plt.subplot(2, 1, 2) plt.plot(t, similarity(sim.data[out_p], vocab2)) plt.plot(t[above_th], np.ones(t.shape)[above_th] * 0.9, c="g", lw=2) plt.ylabel("Output") assert np.mean(sim.data[out_p][below_th]) < 0.01 assert_sp_close(t, sim.data[out_p], vocab2["B"], skip=0.25, duration=0.05)
def test_non_default_input_and_output(Simulator, rng): vocab = spa.Vocabulary(32, pointer_gen=rng) vocab.populate("A; B") with spa.Network() as model: a = spa.Transcode("A", output_vocab=vocab) b = spa.Transcode("B", output_vocab=vocab) bind = spa.Bind(vocab) a.output >> bind.input_left b.output >> bind.input_right p = nengo.Probe(bind.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.5) assert_sp_close(sim.trange(), sim.data[p], vocab.parse("A*B"), skip=0.3, atol=0.3)
def test_transformed_and_transformed(Simulator, algebra, rng): vocab = spa.Vocabulary(16, pointer_gen=rng, algebra=algebra) vocab.populate("A; B.unitary(); C") with spa.Network() as model: a = spa.Transcode("A", output_vocab=vocab) c = spa.Transcode("C", output_vocab=vocab) x = (PointerSymbol("B") * a) * (PointerSymbol("~B") * c) p = nengo.Probe(x.construct(), synapse=0.3) with nengo.Simulator(model) as sim: sim.run(0.3) assert_sp_close( sim.trange(), sim.data[p], vocab.parse("(B * A) * (~B * C)"), skip=0.2, normalized=True, atol=0.3, )
def test_complex_rule(Simulator, algebra, rng): vocab = spa.Vocabulary(16, pointer_gen=rng, algebra=algebra) vocab.populate('A; B; C; D') with spa.Network() as model: a = spa.Transcode('A', output_vocab=vocab) b = spa.Transcode('B', output_vocab=vocab) x = (0.5 * PointerSymbol('C') * a + 0.5 * PointerSymbol('D')) * (0.5 * b + a * 0.5) p = nengo.Probe(x.construct(), synapse=0.3) with nengo.Simulator(model) as sim: sim.run(0.3) assert_sp_close( sim.trange(), sim.data[p], vocab.parse('(0.5 * C * A + 0.5 * D) * (0.5 * B + 0.5 * A)'), skip=0.2, normalized=True)
def test_action_selection(Simulator, rng): vocab = spa.Vocabulary(64) vocab.populate("A; B; C; D; E; F") with spa.Network() as model: state = spa.Transcode(lambda t: "ABCDEF"[min(5, int(t / 0.5))], output_vocab=vocab) scalar = spa.Scalar() pointer = spa.State(vocab) with ActionSelection(): spa.ifmax(spa.dot(state, PointerSymbol("A")), 0.5 >> scalar) spa.ifmax(spa.dot(state, PointerSymbol("B")), PointerSymbol("B") >> pointer) spa.ifmax(spa.dot(state, PointerSymbol("C")), state >> pointer) d_utility = spa.ifmax(0, PointerSymbol("D") >> pointer) spa.ifmax( spa.dot(state, PointerSymbol("E")), 0.25 >> scalar, PointerSymbol("E") >> pointer, ) nengo.Connection(nengo.Node(lambda t: 1.5 < t <= 2.0), d_utility) p_scalar = nengo.Probe(scalar.output, synapse=0.03) p_pointer = nengo.Probe(pointer.output, synapse=0.03) with Simulator(model) as sim: sim.run(3.0) t = sim.trange() assert_allclose(sim.data[p_scalar][(0.3 < t) & (t <= 0.5)], 0.5, atol=0.2) assert_sp_close(sim.trange(), sim.data[p_pointer], vocab["B"], skip=0.8, duration=0.2) assert_sp_close(sim.trange(), sim.data[p_pointer], vocab["C"], skip=1.3, duration=0.2) assert_sp_close(sim.trange(), sim.data[p_pointer], vocab["D"], skip=1.8, duration=0.2) assert_allclose(sim.data[p_scalar][(2.3 < t) & (t <= 2.5)], 0.25, atol=0.2) assert_sp_close(sim.trange(), sim.data[p_pointer], vocab["E"], skip=2.3, duration=0.2)
def test_fixed(Simulator, seed): with spa.Network(seed=seed) as model: model.buffer1 = spa.State(vocab=16) model.buffer2 = spa.State(vocab=8, subdimensions=8) model.input1 = spa.Transcode('A', output_vocab=16) model.input2 = spa.Transcode('B', output_vocab=8) model.input1 >> model.buffer1 model.input2 >> model.buffer2 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.1) assert_sp_close(sim.trange(), sim.data[p1], model.buffer1.vocab.parse('A'), skip=0.08) assert_sp_close(sim.trange(), sim.data[p2], model.buffer2.vocab.parse('B'), skip=0.08)
def test_binary_operation_on_modules_with_pointer_symbol( Simulator, algebra, op, order, rng): vocab = spa.Vocabulary(16, pointer_gen=rng, algebra=algebra) vocab.populate('A; B') with spa.Network() as model: a = spa.Transcode('A', output_vocab=vocab) # noqa: F841 if order == 'AB': x = eval('a' + op + 'PointerSymbol("B")') elif order == 'BA': x = eval('PointerSymbol("B")' + op + 'a') else: raise ValueError('Invalid order argument.') p = nengo.Probe(x.construct(), synapse=0.03) with Simulator(model) as sim: sim.run(0.3) assert_sp_close(sim.trange(), sim.data[p], vocab.parse(order[0] + op + order[1]), skip=0.2)
def test_binary_operation_on_fixed_pointer_with_pointer_symbol( Simulator, op, order, rng): vocab = spa.Vocabulary(64, pointer_gen=rng) vocab.populate('A; B') a = PointerSymbol('A', TVocabulary(vocab)) # noqa: F841 b = SemanticPointer(vocab['B'].v) # noqa: F841 with spa.Network() as model: if order == 'AB': x = eval('a' + op + 'b') elif order == 'BA': x = eval('b' + op + 'a') else: raise ValueError('Invalid order argument.') p = nengo.Probe(x.construct(), synapse=0.03) with Simulator(model) as sim: sim.run(0.5) assert_sp_close(sim.trange(), sim.data[p], vocab.parse(order[0] + op + order[1]), skip=0.3)
def test_add_output_multiple_fn(Simulator, seed, rng, plt): d = 8 pointer = next(UnitLengthVectors(d, rng)) with nengo.Network(seed=seed) as model: ea = IdentityEnsembleArray(15, d, 4) input_node = nengo.Node(pointer) nengo.Connection(input_node, ea.input) out = ea.add_output("const", (lambda x: -x, lambda x: 0.5 * x, lambda x: x)) assert ea.const is out p = nengo.Probe(out, synapse=0.01) with Simulator(model) as sim: sim.run(0.3) expected = np.array(pointer) expected[0] *= -1.0 expected[1:4] *= 0.5 plt.plot(sim.trange(), np.dot(sim.data[p], expected)) assert_sp_close( sim.trange(), sim.data[p], SemanticPointer(expected), skip=0.2, atol=0.3 )
def test_binary_operation_on_fixed_pointer_with_pointer_symbol( Simulator, op, order, rng ): vocab = spa.Vocabulary(64, pointer_gen=rng) vocab.populate("A; B") a = PointerSymbol("A", TVocabulary(vocab)) # noqa: F841 b = SemanticPointer(vocab["B"].v) # noqa: F841 with spa.Network() as model: if order == "AB": x = eval("a" + op + "b") elif order == "BA": x = eval("b" + op + "a") else: raise ValueError("Invalid order argument.") p = nengo.Probe(x.construct(), synapse=0.03) with Simulator(model) as sim: sim.run(0.5) assert_sp_close( sim.trange(), sim.data[p], vocab.parse(order[0] + op + order[1]), skip=0.3 )
def test_time_varying_encode(Simulator, seed): with spa.Network(seed=seed) as model: model.buffer = spa.State(vocab=16) def stimulus(t): if t < 0.1: return 'A' elif t < 0.2: return model.buffer.vocab.parse('B') elif t < 0.3: return model.buffer.vocab.parse('C').v else: return '0' model.encode = spa.Transcode(stimulus, output_vocab=16) model.encode >> model.buffer p = nengo.Probe(model.buffer.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.3) vocab = model.buffer.vocab assert_sp_close(sim.trange(), sim.data[p], vocab.parse('A'), skip=0.08, duration=0.02) assert_sp_close(sim.trange(), sim.data[p], vocab.parse('B'), skip=0.18, duration=0.02) assert_sp_close(sim.trange(), sim.data[p], vocab.parse('C'), skip=0.28, duration=0.02) assert_sp_close(sim.trange(), sim.data[p], vocab.parse('0'), skip=0.38, duration=0.02)