예제 #1
0
def test_invalid_vectorize_folds_jagged():
    @vectorize
    def f(a):
        return a

    with pytest.raises(TypeError, match="instantiated with a Fold"):
        f(fold([stimuli([0, 1]), stimuli(2)]))
예제 #2
0
def test_join_invalid():
    with pytest.raises(ValueError,
                       match="expected all input ops to be an Operator"):
        bundle([stimuli(np.ones(3)), stimuli(np.ones(2))])

    with pytest.raises(ValueError, match="cannot bundle zero nodes"):
        bundle([])
예제 #3
0
def test_lower_folds_recursive():
    @lower_folds
    def f(a):
        assert isinstance(a, list)
        assert not any(isinstance(a_i, Fold) for a_i in a)
        return a

    f([stimuli(np.ones((3, 1))), stimuli(np.ones((3, 1)))])
예제 #4
0
def test_invalid_vectorize_op_input():
    class InvalidInput(Operator):
        @property
        def size_out(self):
            return [1, 1]

    with pytest.raises(ValueError, match="all input_ops produce an integer size_out"):
        stimuli(InvalidInput([]))
예제 #5
0
def test_custom_subnetworks():
    synapse = 0.01

    def gyrus_custom_subnetwork(node_a, node_b, synapse):
        out_a = node_a**2
        out_b = (node_a * node_b - out_a) / 2
        return fold([out_a, out_b]).filter(synapse)

    def nengo_custom_subnetwork(node_a, node_b, synapse):
        assert node_a.size_out == node_b.size_out
        d = node_a.size_out

        product = nengo.networks.Product(200, dimensions=d, seed=0)
        ens = nengo.Ensemble(100, d, seed=0)

        nengo.Connection(node_a, ens, synapse=None)
        nengo.Connection(node_a, product.input_a, synapse=None)
        nengo.Connection(node_b, product.input_b, synapse=None)

        decode_a = nengo.Node(size_in=d)
        decode_b = nengo.Node(size_in=d)

        nengo.Connection(ens, decode_a, function=np.square, synapse=synapse)
        nengo.Connection(product.output,
                         decode_b,
                         transform=0.5,
                         synapse=synapse)
        nengo.Connection(decode_a, decode_b, transform=-0.5, synapse=None)

        return [decode_a, decode_b]

    # Running it in Gyrus.
    input_function1 = lambda t: np.sin(2 * np.pi * t)
    input_function2 = lambda t: t

    x1 = stimuli(input_function1)
    x2 = stimuli(input_function2)

    y = gyrus_custom_subnetwork(x1, x2, synapse)

    out1, out2 = y.run(1)

    # Running it in Nengo.
    with nengo.Network() as model:
        stim1 = nengo.Node(input_function1)
        stim2 = nengo.Node(input_function2)

        y1, y2 = nengo_custom_subnetwork(stim1, stim2, synapse)

        p1 = nengo.Probe(y1)
        p2 = nengo.Probe(y2)

    with nengo.Simulator(model) as sim:
        sim.run(1)

    assert np.allclose(sim.data[p1], out1)
    assert np.allclose(sim.data[p2], out2)
예제 #6
0
def test_config_left_to_right_precedence():
    x1 = stimuli(0).configure(n_neurons=300)
    x2 = stimuli(1).configure(n_neurons=500)

    assert (x1 * x2)._impl_kwargs == {"n_neurons": 300}
    assert (x2 * x1)._impl_kwargs == {"n_neurons": 500}

    assert Configure.resolve_config([x1, x2]) == {"n_neurons": 300}
    assert Configure.resolve_config([x2, x1]) == {"n_neurons": 500}
예제 #7
0
def test_lower_folds():
    @lower_folds
    def f(a, b=0):
        assert not isinstance(a, Fold)
        assert not isinstance(b, Fold)
        return a

    f(stimuli(np.ones((3, 1))))
    f(stimulus(0), b=stimuli(np.ones((3, 1))))
예제 #8
0
def test_multiple_outputs():
    input_functions = [
        lambda t: np.sqrt(t) * np.cos(2 * np.pi * t),
        lambda t: np.sqrt(t) * np.sin(2 * np.pi * t),
    ]
    n_neurons = 100

    with nengo.Network(seed=0) as model:
        model.config[nengo.Connection].synapse = None

        stim1 = nengo.Node(output=input_functions[0])
        stim2 = nengo.Node(output=input_functions[1])

        x1 = nengo.Ensemble(n_neurons, stim1.size_out, seed=0)
        x2 = nengo.Ensemble(n_neurons, stim2.size_out, seed=0)

        y = nengo.Node(size_in=1)
        y_hat = nengo.Node(size_in=1)
        error = nengo.Node(size_in=1)

        nengo.Connection(stim1, y, function=np.square)
        nengo.Connection(stim2, y, function=np.square)
        nengo.Connection(y, error)

        nengo.Connection(stim1, x1)
        nengo.Connection(stim2, x2)
        nengo.Connection(x1, y_hat, function=np.square)
        nengo.Connection(x2, y_hat, function=np.square)
        nengo.Connection(y_hat, error, transform=-1)

        p_y = nengo.Probe(y)
        p_y_hat = nengo.Probe(y_hat)
        p_error = nengo.Probe(error)

    with nengo.Simulator(model, dt=0.005) as sim:
        sim.run(1)

    out1 = sim.data[p_y], sim.data[p_y_hat], sim.data[p_error]

    # An explicit approach in Gyrus.
    x = stimuli(input_functions)
    y = x[0].apply(np.square) + x[1].apply(np.square)
    y_hat = x[0].decode(np.square, n_neurons=n_neurons, seed=0) + x[1].decode(
        np.square, n_neurons=n_neurons, seed=0)
    out2 = fold([y, y_hat, y - y_hat]).run(1, dt=0.005, seed=0)

    # Alternative operator overload approach in Gyrus.
    x = stimuli(input_functions)
    y = np.sum(x.apply(np.square))
    y_hat = np.sum(x**2)
    out3 = fold([y, y_hat, y - y_hat]).run(1, dt=0.005, seed=0)

    assert np.allclose(out1, out2)
    assert np.allclose(out2, out3)
예제 #9
0
def test_str():
    assert str(stimuli(np.ones((1, 2)))) == "Fold(Fold(Stimuli(), Stimuli()))"
    assert str(stimuli(np.ones((1, 1, 1)))) == "Fold(Fold(Fold(Stimuli())))"
    assert str(stimuli(np.ones(
        (1, 1, 2)))) == "Fold(Fold(Fold(Stimuli(), Stimuli())))"
    assert str(stimuli(np.ones((1, 1, 1, 1)))) == "Fold(Fold(Fold(Fold(...))))"

    assert (stimuli(np.ones(3)).bundle().__str__(
        max_width=2) == "Bundle1D(Stimuli(), Stimuli(), ...)")
    assert (stimulus(np.ones(2)).unbundle().__str__(
        max_depth=2, max_width=2) == "Fold(Slice(...), Slice(...))")
예제 #10
0
def test_asoperator():
    stim = stimuli(0)
    assert asoperator(stim) is stim

    input_ops = (stimuli(0), stimuli(1))
    op = asoperator(input_ops)
    assert isinstance(op, Fold)
    assert op.input_ops == input_ops

    assert asoperator(np.asarray(stim)) is stim

    with pytest.raises(TypeError,
                       match="expected array scalar .* to be an Operator"):
        asoperator(np.asarray(0))
예제 #11
0
def test_high_dimensional_integrator(plt):
    d = 32
    dt = 1e-3

    def f(t, hz):
        return np.cos(2 * np.pi * hz * (t - dt)) * (2 * np.pi * hz)

    input_functions = [
        lambda t, hz=hz: f(t, hz) for hz in np.linspace(1, 2, d)
    ]
    u = stimuli(input_functions)
    x = u.integrate()

    y = np.asarray(x.run(1, dt=dt))
    y_hat = np.asarray(x.decode().filter(5e-3).run(1, dt=dt))
    assert y.shape == y_hat.shape

    t = (1 + np.arange(y.shape[1])) * dt
    y_check = np.cumsum(np.asarray([f(t)
                                    for f in input_functions]), axis=1) * dt
    assert np.allclose(y.squeeze(axis=2)[:, 1:], y_check[:, :-1])
    assert rms(y - y_hat) < 0.1

    for y_i, y_hat_i in zip(y, y_hat):
        plt.plot(y_i.squeeze(axis=1), linestyle="--")
        plt.plot(y_hat_i.squeeze(axis=1), alpha=0.7)
    plt.xlabel("Time-step")
예제 #12
0
def test_multidimensional_function():
    input_function = lambda t: [t, -np.sqrt(t), t**3]
    n_neurons = 2000
    tau = 0.005

    with nengo.Network() as model:
        stim = nengo.Node(output=input_function)

        x = nengo.Ensemble(n_neurons, 3, radius=np.sqrt(3), seed=0)
        y = nengo.Node(size_in=1)

        nengo.Connection(stim, x, synapse=None)
        nengo.Connection(x, y, function=np.prod, synapse=tau)

        p = nengo.Probe(y)

    with nengo.Simulator(model) as sim:
        sim.run(1)

    out1 = sim.data[p]

    x = (stimuli(input_function).decode(np.prod,
                                        n_neurons=n_neurons,
                                        radius=np.sqrt(3)).filter(tau))
    out2 = x.run(1)

    assert np.allclose(out1, out2)
예제 #13
0
def test_broadcast_to():
    a = stimuli([1, 2])
    b = np.broadcast_to(a, (3, 2))
    assert isinstance(b, Fold)
    assert b.shape == (3, 2)
    assert b[0, 0] is b[1, 0] is b[2, 0]
    assert b[0, 1] is b[1, 1] is b[2, 1]
예제 #14
0
def test_invalid_vectorize_folds():
    @vectorize("F", excluded=[0])
    def f(a):
        return a

    with pytest.raises(TypeError, match="instantiated with a Fold"):
        f(stimuli([0, 1]))
예제 #15
0
def test_transform():
    twod = stimuli([1, 2]).bundle()
    assert twod.size_out == 2
    assert np.all(twod.run(1, 1) == [[1, 2]])
    assert np.allclose(twod.transform([2, -3]).run(1, 1), [[2, -6]])
    assert np.allclose(twod.transform([[2, -3]]).run(1, 1), [[-4]])
    assert np.allclose(twod.transform([[2, -3], [4, -1]]).run(1, 1), [[-4, 2]])
예제 #16
0
def test_flatten():
    data = np.arange(2 * 3 * 4).reshape((2, 3, 4))
    stim = stimuli(data)
    assert stim.shape == data.shape
    flat = stim.flatten()
    assert flat.shape == (data.size, )
    assert np.allclose(flat.run(1, 1), data.flatten()[:, None, None])
예제 #17
0
def test_np_prod():
    input_functions = [
        lambda t: [1, -1, 0, 0.5],
        lambda t: [1, 0.5, -1, 1],
    ]
    d = 4
    tau = 0.1

    with nengo.Network() as model:
        stim1 = nengo.Node(output=input_functions[0])
        stim2 = nengo.Node(output=input_functions[1])

        x = nengo.networks.Product(200, dimensions=d, seed=0)

        nengo.Connection(stim1, x.input_a, synapse=None)
        nengo.Connection(stim2, x.input_b, synapse=None)

        p = nengo.Probe(x.output, synapse=tau)

    with nengo.Simulator(model) as sim:
        sim.run(1)

    out1 = sim.data[p]

    out2 = np.prod(stimuli(input_functions)).filter(tau).run(1)

    assert np.allclose(out1, out2)
예제 #18
0
def test_oscillator():
    frequency = 4
    t = 1
    A, _ = oscillator(frequency)

    input_function = nengo.processes.Piecewise({0: [10, 0], 0.1: [0, 0]})
    kick = stimuli(input_function)

    x = kick.integrate(lambda x: x.decode().transform(A))
    y = x.run(t)

    with nengo.Network() as model:
        ens = nengo.Ensemble(100, dimensions=2, seed=0)
        kick = nengo.Node(input_function)
        psc = nengo.Node(size_in=2)

        integrator = nengo.synapses.LinearFilter([1], [1, 0])
        nengo.Connection(kick, psc, synapse=integrator)
        nengo.Connection(ens, psc, transform=A, synapse=integrator)
        nengo.Connection(psc, ens, synapse=None)

        ens_probe = nengo.Probe(psc)

    with nengo.Simulator(model) as sim:
        sim.run(t)

    assert np.allclose(sim.data[ens_probe], y)
예제 #19
0
def test_make_context():
    x = stimuli(0).decode()

    with nengo.Network() as model:
        assert model not in Operator._network_to_cache
        a = x.make()
        assert model in Operator._network_to_cache
        # Test that next two makes are redundant.
        assert len(model.all_ensembles) == 1
        b = x.make()
        c = x.make()
        assert len(model.all_ensembles) == 1

        with nengo.Network() as subnet:
            assert subnet not in Operator._network_to_cache
            d = x.make()
            assert subnet in Operator._network_to_cache

        assert a is b is c
        assert c is not d

    # There should be two ensembles, one in model and one in subnet.
    assert len(model.all_ensembles) == 2
    assert len(model.ensembles) == 1
    assert len(subnet.ensembles) == 1
예제 #20
0
def test_subtract_scalar():
    input_function = lambda t: (2 * t - 1) * np.pi
    n_neurons = 100
    tau = 0.005

    with nengo.Network(seed=0) as model:
        stim = nengo.Node(input_function)
        one = nengo.Node(1)

        x = nengo.Ensemble(n_neurons, stim.size_out, radius=np.pi, seed=0)
        y = nengo.Node(size_in=1)
        one_minus_y = nengo.Node(size_in=1)

        nengo.Connection(stim, x, synapse=None)
        nengo.Connection(x, y, function=np.sin, synapse=tau)

        nengo.Connection(one, one_minus_y, synapse=None)
        nengo.Connection(y, one_minus_y, synapse=None, transform=-1)

        p_one_minus_y = nengo.Probe(one_minus_y)

    with nengo.Simulator(model) as sim:
        sim.run(1.0)

    out1 = sim.data[p_one_minus_y]

    x = stimuli(input_function)
    y = x.decode(np.sin, n_neurons=n_neurons, radius=np.pi, seed=0).filter(tau)
    out2 = (1 - y).run(1)
    out3 = ((-y) + 1).run(1)

    assert np.allclose(out1, out2)
    assert np.allclose(out2, out3)
예제 #21
0
 def _lift_arg(cls, arg):
     # A bit like the inverse of base.py::lower_folds::_lower_arg except direct mode
     # stimuli are automatically created from arrays for testing convenience.
     if is_array(arg):
         return stimuli(arg).configure(neuron_type=nengo.Direct())
     if isinstance(arg, (tuple, list)):
         return type(arg)(map(cls._lift_arg, arg))
     return arg
예제 #22
0
def test_config_downstream_precedence():
    stim = stimuli(0).configure(n_neurons=200)
    assert stim.config == {"n_neurons": 200}
    x = stim.configure(n_neurons=300)
    y = x.transform(2)
    z = y ** 2
    assert z._impl_kwargs == {"n_neurons": 300}
    assert Configure.resolve_config([z]) == {"n_neurons": 300}
    assert z in Configure._cache

    a = stimuli(0).configure(n_neurons=400, radius=2)
    assert Configure.resolve_config([z + a]) == {"n_neurons": 300, "radius": 2}
    assert Configure.resolve_config([a + z]) == {"n_neurons": 400, "radius": 2}

    # Test hard reset of config downstream.
    b = (z + a).configure(reset=True, radius=3)
    assert b.config == {"radius": 3}
    assert Configure.resolve_config([b]) == {"radius": 3}
예제 #23
0
def test_transform_invalid():
    with pytest.raises(TypeError, match="must be a Fold"):
        Transforms(stimulus(0), [1])

    with pytest.raises(
            ValueError,
            match=
            r"input operators \(2\) must equal the number of transforms \(3\)",
    ):
        Transforms(stimuli([2, 2]), np.ones(3))

    with pytest.raises(ValueError,
                       match="expected a Fold with only a single axis"):
        Transforms(stimuli(np.eye(2)), np.ones(2))

    with pytest.raises(ValueError,
                       match="input_ops must have all the same size"):
        Transforms(fold([stimulus(1), stimulus([1, 1])]), np.ones(2))
예제 #24
0
def test_multiply_direct(rng):
    shape = (2, 1, 3)
    a = rng.randn(*shape)
    b = rng.randn(*shape)

    input_a = stimuli(a).configure(neuron_type=nengo.Direct())
    input_b = stimuli(b)

    y = input_a * input_b
    with nengo.Network() as model:
        y.make()

    for ens in model.all_ensembles:
        assert ens.neuron_type == nengo.Direct()
    assert len(model.all_ensembles) == 2 * np.prod(shape)

    out = np.asarray(y.run(1, 1))
    assert np.allclose(out.squeeze(axis=(-2, -1)), a * b)
예제 #25
0
def test_vectorize_example():
    def multiply_by_two(x):
        y = nengo.Node(size_in=x.size_out)
        nengo.Connection(x, y, transform=2, synapse=None)
        return y

    x = stimuli([1, 2, 3])
    y = vectorize(multiply_by_two)(x)
    assert np.all(np.asarray(y.run(1, dt=1)).squeeze(axis=(1, 2)) == [2, 4, 6])
예제 #26
0
def test_sum_dot():
    A = [[1, 2, 3], [4, 5, 6]]
    x = [7, 8, 9]
    y_check = np.dot(A, x)

    y1 = np.dot(stimuli(A), x)
    assert y1.shape == (2, )
    assert np.all(y1.size_out == [1, 1])
    out1 = np.asarray(y1.run(1, 1)).squeeze(axis=(-2, -1))
    assert np.allclose(out1, y_check)

    y2 = np.sum((stimuli(A).bundle().transform(x)).unbundle(), axis=1)
    assert y2.shape == (2, )
    out2 = np.asarray(y2.run(1, 1)).squeeze(axis=(-2, -1))
    assert np.allclose(out1, out2)

    y3 = stimuli(A).bundle().transform(x).transform(np.ones((1, len(x))))
    assert y3.shape == (2, )
    out3 = np.asarray(y3.run(1, 1)).squeeze(axis=(-2, -1))
    assert np.allclose(out2, out3)
예제 #27
0
def test_multiply_bundle(rng):
    a = rng.randn(4, 3)
    b = rng.randn(4, 3)

    op_a = stimuli(a).configure(neuron_type=nengo.Direct())
    op_b = stimuli(b)

    out_ideal = a * b

    y1 = op_a.bundle() * op_b.bundle()
    assert y1.shape == (4, )
    assert np.all(y1.size_out == [3, 3, 3, 3])
    out1 = np.asarray(y1.run(1, 1)).squeeze(axis=-2)

    y2 = op_a * op_b
    assert y2.shape == (4, 3)
    out2 = np.asarray(y2.run(1, 1)).squeeze(axis=(-2, -1))

    assert np.allclose(out_ideal, out1)
    assert np.allclose(out_ideal, out2)
예제 #28
0
def test_add_folds(rng):
    shape = (3, 1, 2)

    a = rng.randn(*shape)
    b = rng.randn(*shape)

    op_a = stimuli(a)
    op_b = stimuli(b)

    y1 = op_a + b
    y2 = b + op_a
    y3 = op_a + op_b

    out1 = np.asarray(y1.run(1, 1)).squeeze(axis=(-2, -1))
    out2 = np.asarray(y2.run(1, 1)).squeeze(axis=(-2, -1))
    out3 = np.asarray(y3.run(1, 1)).squeeze(axis=(-2, -1))

    assert np.allclose(a + b, out1)
    assert np.allclose(a + b, out2)
    assert np.allclose(a + b, out3)
예제 #29
0
def test_recursive_fold():
    shape = (2, 3, 4, 5)
    constants = np.arange(np.prod(shape)).reshape(shape)

    @np.vectorize
    def make_lambdas(x):
        return lambda _: x * np.ones(7)

    input_functions = make_lambdas(constants)
    assert input_functions.shape == shape
    stim = stimuli(input_functions)
    assert stim.shape == shape

    r = np.asarray(stim.run(6, dt=1))
    assert r.shape == shape + (6, 7)
    assert np.allclose(r, constants[..., None, None])

    # Test jagged dimensions across fold
    out1, out2 = stimuli([lambda t: [1, 3, 4], lambda t: [1, 2]]).run(1, dt=1)
    assert np.allclose(out1, [1, 3, 4])
    assert np.allclose(out2, [1, 2])
예제 #30
0
def test_bundle_unbundle():
    data = np.arange(3 * 4 * 5).reshape(3, 4, 5)
    stim = stimuli(data)
    t = 6

    y = stim.bundle()
    assert y.shape == (3, 4)
    out = np.asarray(y.run(t, 1))
    y_split = y.unbundle()
    assert y_split.shape == (3, 4, 5)
    y_check = y_split.bundle()
    assert y_check.shape == (3, 4)
    out_check = np.asarray(y_check.run(t, 1))
    assert np.allclose(out, out_check)
    out_check = np.asarray(y_split.run(t, 1)).squeeze(axis=-1).transpose(
        (0, 1, 3, 2))
    assert out.shape == (3, 4, t, 5)
    assert np.allclose(out_check, out)
    for i in range(t):
        assert np.allclose(out[:, :, i, :], data)

    y = bundle(stim, axis=-2)
    assert y.shape == (3, 5)
    out = np.asarray(y.run(t, 1))
    y_split = y.unbundle()
    assert y_split.shape == (3, 5, 4)
    out_check = np.asarray(y_split.run(t, 1)).squeeze(axis=-1).transpose(
        (0, 1, 3, 2))
    assert out.shape == (3, 5, t, 4)
    assert np.allclose(out_check, out)
    for i in range(t):
        assert np.allclose(out[:, :, i, :], data.transpose((0, 2, 1)))

    y_split = y.unbundle(axis=-2)
    assert y_split.shape == (3, 4, 5)
    out_check = np.asarray(y_split.run(t, 1)).squeeze(axis=-1)
    for i in range(t):
        assert np.allclose(out_check[..., i], data)

    y = bundle(stim, axis=0)
    assert y.shape == (4, 5)
    out = np.asarray(y.run(t, 1))
    y_split = y.unbundle()
    assert y_split.shape == (4, 5, 3)
    out_check = np.asarray(y_split.run(t, 1)).squeeze(axis=-1).transpose(
        (0, 1, 3, 2))
    assert out.shape == (4, 5, t, 3)
    assert np.allclose(out_check, out)
    for i in range(t):
        assert np.allclose(out[:, :, i, :], data.transpose((1, 2, 0)))