Example #1
0
    def test_scalar(self):
        """A network that represents sin(t)."""
        N = 30

        m = nengo.Model('test_scalar', seed=123)
        m.make_node('in', output=np.sin)
        m.make_ensemble('A', nengo.LIF(N), 1)
        m.connect('in', 'A')
        m.probe('in')
        m.probe('A', filter=0.02)

        sim = m.simulator(dt=0.001, sim_class=self.Simulator)
        sim.run(5.0)

        with Plotter(self.Simulator) as plt:
            t = sim.data(m.t)
            plt.plot(t, sim.data('in'), label='Input')
            plt.plot(t, sim.data('A'), label='Neuron approximation, pstc=0.02')
            plt.legend(loc=0)
            plt.savefig('test_ensemble.test_scalar.pdf')
            plt.close()

        target = np.sin(np.arange(5000) / 1000.)
        target.shape = (-1, 1)
        logger.debug("[New API] input RMSE: %f", rmse(target, sim.data('in')))
        logger.debug("[New API] A RMSE: %f", rmse(target, sim.data('A')))
        self.assertTrue(rmse(target, sim.data('in')) < 0.001)
        self.assertTrue(rmse(target, sim.data('A')) < 0.1)
Example #2
0
    def test_prod(self):
        def product(x):
            return x[0] * x[1]

        N = 250
        seed = 123
        net = nef.Network('Matrix Multiplication',
                          seed=seed,
                          simulator=self.Simulator)

        net.make_input('sin', value=np.sin)
        net.make_input('neg', value=[-.5])
        net.make_array('p', 2 * N, 1, dimensions=2, radius=1.5)
        net.make_array('D', N, 1, dimensions=1)
        net.connect('sin', 'p', transform=[[1], [0]])
        net.connect('neg', 'p', transform=[[0], [1]])
        net.connect('p', 'D', func=product, pstc=0.01)

        p_raw = net._probe_decoded_signals(
            [net.ensembles['p'].origin['product'].sigs[0]],
            dt_sample=.01,
            pstc=.01)

        probe_p = net.make_probe('p', dt_sample=.01, pstc=.01)
        probe_d = net.make_probe('D', dt_sample=.01, pstc=.01)

        net.run(6)

        data_p = probe_p.get_data()
        data_d = probe_d.get_data()
        data_r = p_raw.get_data()

        with Plotter(self.Simulator) as plt:
            plt.subplot(211)
            plt.plot(data_p)
            plt.plot(np.sin(np.arange(0, 6, .01)))
            plt.subplot(212)
            plt.plot(data_d)
            plt.plot(data_r)
            plt.plot(-.5 * np.sin(np.arange(0, 6, .01)))
            plt.savefig('test_old_api.test_prod.pdf')
            plt.close()

        self.assertTrue(
            np.allclose(data_p[:, 0],
                        np.sin(np.arange(0, 6, .01)),
                        atol=.1,
                        rtol=.01))
        self.assertTrue(np.allclose(data_p[20:, 1], -0.5, atol=.1, rtol=.01))

        def match(a, b):
            self.assertTrue(np.allclose(a, b, .1, .1))

        match(data_d[:, 0], -0.5 * np.sin(np.arange(0, 6, .01)))
        match(data_r[:, 0], -0.5 * np.sin(np.arange(0, 6, .01)))
Example #3
0
    def test_decoder_to_nonlinearity(self):
        N = 30

        m = nengo.Model('test_decoder_to_nonlinearity', seed=123)
        a = m.make_ensemble('A', nengo.LIF(N), dimensions=1)
        b = m.make_ensemble('B', nengo.LIF(N), dimensions=1)
        m.make_node('in', output=np.sin)
        m.make_node('inh', piecewise({0: 0, 2.5: 1}))
        m.make_node('ideal', piecewise({0: np.sin, 2.5: 0}))

        m.connect('in', 'A')
        m.connect('inh', 'B')

        con = m.connect('B', a.neurons, transform=[[-2.5]] * N)

        m.probe('in')
        m.probe('A', filter=0.1)
        m.probe('B', filter=0.1)
        m.probe('inh')
        m.probe('ideal')

        sim = m.simulator(dt=0.001, sim_class=self.Simulator)
        sim.run(5.0)

        with Plotter(self.Simulator) as plt:
            t = sim.data(m.t)
            plt.plot(t, sim.data('in'), label='Input')
            plt.plot(t, sim.data('A'), label='Neuron approx, pstc=0.1')
            plt.plot(t,
                     sim.data('B'),
                     label='Neuron approx of inhib sig, pstc=0.1')
            plt.plot(t, sim.data('inh'), label='Inhib signal')
            plt.plot(t, sim.data('ideal'), label='Ideal output')
            plt.legend(loc=0, prop={'size': 10})
            plt.savefig(
                'test_tononlinearity_connection.test_decoder_to_nonlinearity.pdf'
            )
            plt.close()

        self.assertTrue(
            np.allclose(sim.data('A')[-10:],
                        sim.data('ideal')[-10:],
                        atol=.1,
                        rtol=.01))
        self.assertTrue(
            np.allclose(sim.data('B')[-10:],
                        sim.data('inh')[-10:],
                        atol=.1,
                        rtol=.01))
Example #4
0
    def test_product(self):
        def product(x):
            return x[0] * x[1]

        m = nengo.Model('test_product', seed=124)

        N = 80
        m.make_node('sin', output=np.sin)
        m.make_node('-0.5', output=-.5)
        factors = m.make_ensemble(
            'factors', nengo.LIF(2 * N), dimensions=2, radius=1.5)
        factors.encoders = np.tile([[1, 1],[-1, 1],[1, -1],[-1, -1]],
                                   (factors.n_neurons / 4, 1))
        m.make_ensemble('product', nengo.LIF(N), dimensions=1)
        m.connect('sin', 'factors', transform=[[1], [0]])
        m.connect('-0.5', 'factors', transform=[[0], [1]])
        conn = m.connect('factors', 'product', function=product, filter=0.01)

        m.probe('sin', sample_every=.01)
        # m.probe(conn, sample_every=.01)  # FIXME
        m.probe('factors', sample_every=.01, filter=.01)
        m.probe('product', sample_every=.01, filter=.01)

        sim = m.simulator(dt=0.001, sim_class=self.Simulator)
        sim.run(6)

        with Plotter(self.Simulator) as plt:
            plt.subplot(211)
            plt.plot(sim.data('factors'))
            plt.plot(np.sin(np.arange(0, 6, .01)))
            plt.plot(sim.data('sin'))
            plt.subplot(212)
            plt.plot(sim.data('product'))
            #plt.plot(sim.data(conn))
            plt.plot(-.5 * np.sin(np.arange(0, 6, .01)))
            plt.savefig('test_ensemble.test_prod.pdf')
            plt.close()

        self.assertTrue(rmse(sim.data('factors')[:, 0],
                             np.sin(np.arange(0, 6, .01))) < 0.1)
        self.assertTrue(rmse(sim.data('factors')[20:, 1], -0.5) < 0.1)

        def match(a, b):
            self.assertTrue(rmse(a, b) < 0.1)

        match(sim.data('product')[:, 0], -0.5 * np.sin(np.arange(0, 6, .01)))
Example #5
0
    def test_simple(self):
        dt = 0.001
        m = nengo.Model('test_simple', seed=123)
        m.make_node('in', output=np.sin)
        m.probe('in')

        sim = m.simulator(dt=dt, sim_class=self.Simulator)
        runtime = 0.5
        sim.run(runtime)

        with Plotter(self.Simulator) as plt:
            plt.plot(sim.data(m.t), sim.data('in'), label='sin')
            plt.legend(loc='best')
            plt.savefig('test_node.test_simple.pdf')
            plt.close()

        sim_t = sim.data(m.t).ravel()
        sim_in = sim.data('in').ravel()
        t = dt * np.arange(len(sim_t))
        self.assertTrue(np.allclose(sim_t, t))
        self.assertTrue(np.allclose(sim_in[1:],
                                    np.sin(t[:-1])))  # 1-step delay
Example #6
0
    def test_vector(self):
        """A network that represents sin(t), cos(t), arctan(t)."""
        simulator = self.Simulator
        params = dict(simulator=simulator, seed=123, dt=0.001)
        N = 40
        target = np.vstack(
            (np.sin(np.arange(4999) / 1000.), np.cos(np.arange(4999) / 1000.),
             np.arctan(np.arange(4999) / 1000.))).T

        # Old API
        net = nef.Network('test_vector', **params)
        net.make_input('sin', value=np.sin)
        net.make_input('cos', value=np.cos)
        net.make_input('arctan', value=np.arctan)
        net.make('A', N * 3, 3, radius=2)
        net.connect('sin', 'A', transform=[[1], [0], [0]])
        net.connect('cos', 'A', transform=[[0], [1], [0]])
        net.connect('arctan', 'A', transform=[[0], [0], [1]])

        sin_p = net.make_probe('sin', dt_sample=0.001, pstc=0.0)
        cos_p = net.make_probe('cos', dt_sample=0.001, pstc=0.0)
        arctan_p = net.make_probe('arctan', dt_sample=0.001, pstc=0.0)
        a_p = net.make_probe('A', dt_sample=0.001, pstc=0.02)
        net.run(5)

        sin_data = sin_p.get_data()
        cos_data = cos_p.get_data()
        arctan_data = arctan_p.get_data()
        a_data = a_p.get_data()

        with Plotter(simulator) as plt:
            t = net.model.data[net.model.simtime]
            plt.plot(t, sin_data, label='sin')
            plt.plot(t, cos_data, label='cos')
            plt.plot(t, arctan_data, label='arctan')
            plt.plot(t, a_data, label='Neuron approximation, pstc=0.02')
            plt.legend(loc=0, prop={'size': 10})
            plt.savefig('test_ensemble.test_vector-old.pdf')
            plt.close()

        logger.debug("[Old API] sin RMSE: %f", rmse(target[:, 0], sin_data))
        logger.debug("[Old API] cos RMSE: %f", rmse(target[:, 1], cos_data))
        logger.debug("[Old API] atan RMSE: %f", rmse(target[:, 2],
                                                     arctan_data))
        logger.debug("[Old API] A RMSE: %f", rmse(target, a_data))
        self.assertTrue(rmse(target, a_data) < 0.1)

        # New API
        m = nengo.Model('test_vector', **params)
        m.make_node('sin', output=np.sin)
        m.make_node('cos', output=np.cos)
        m.make_node('arctan', output=np.arctan)
        m.make_ensemble('A', nengo.LIF(N * 3), 3, radius=2)
        m.connect('sin', 'A', transform=[[1], [0], [0]])
        m.connect('cos', 'A', transform=[[0], [1], [0]])
        m.connect('arctan', 'A', transform=[[0], [0], [1]])

        m.probe('sin')
        m.probe('cos')
        m.probe('arctan')
        m.probe('A', filter=0.02)
        m.run(5)

        with Plotter(simulator) as plt:
            t = m.data[m.simtime]
            plt.plot(t, m.data['sin'], label='sin')
            plt.plot(t, m.data['cos'], label='cos')
            plt.plot(t, m.data['arctan'], label='arctan')
            plt.plot(t, m.data['A'], label='Neuron approximation, pstc=0.02')
            plt.legend(loc=0, prop={'size': 10})
            plt.savefig('test_ensemble.test_vector-new.pdf')
            plt.close()

        # Not sure why, but this isn't working...
        logger.debug("[New API] sin RMSE: %f", rmse(target[:, 0],
                                                    m.data['sin']))
        logger.debug("[New API] cos RMSE: %f", rmse(target[:, 1],
                                                    m.data['cos']))
        logger.debug("[New API] atan RMSE: %f",
                     rmse(target[:, 2], m.data['arctan']))
        logger.debug("[New API] A RMSE: %f", rmse(target, m.data['A']))
        self.assertTrue(rmse(target, m.data['A']) < 0.1)

        # Check old/new API similarity
        logger.debug("Old/New API RMSE: %f", rmse(a_data, m.data['A']))
        self.assertTrue(rmse(a_data, m.data['A']) < 0.1)
Example #7
0
    def _test_circularconv(self, dims=5, neurons_per_product=128):
        rng = np.random.RandomState(42342)

        n_neurons = neurons_per_product * dims
        n_neurons_d = 2 * neurons_per_product * (2 * dims -
                                                 (2 if dims % 2 == 0 else 1))
        radius = 1

        a = rng.normal(scale=np.sqrt(1. / dims), size=dims)
        b = rng.normal(scale=np.sqrt(1. / dims), size=dims)
        c = circconv(a, b)
        self.assertTrue(np.abs(a).max() < radius)
        self.assertTrue(np.abs(b).max() < radius)
        self.assertTrue(np.abs(c).max() < radius)

        ### model
        model = nengo.Model("circular convolution")
        inputA = model.make_node("inputA", output=a)
        inputB = model.make_node("inputB", output=b)
        A = model.add(
            EnsembleArray('A', nengo.LIF(n_neurons), dims, radius=radius))
        B = model.add(
            EnsembleArray('B', nengo.LIF(n_neurons), dims, radius=radius))
        C = model.add(
            EnsembleArray('C', nengo.LIF(n_neurons), dims, radius=radius))
        D = model.add(
            CircularConvolution('D',
                                neurons=nengo.LIF(n_neurons_d),
                                dimensions=A.dimensions,
                                radius=radius))

        inputA.connect_to(A)
        inputB.connect_to(B)
        A.connect_to(D.A)
        B.connect_to(D.B)
        D.output.connect_to(C)

        model.probe(A, filter=0.03)
        model.probe(B, filter=0.03)
        model.probe(C, filter=0.03)
        model.probe(D.ensemble, filter=0.03)

        # check FFT magnitude
        d = np.dot(D.transformA, a) + np.dot(D.transformB, b)
        self.assertTrue(np.abs(d).max() < radius)

        ### simulation
        sim = model.simulator(sim_class=self.Simulator)
        sim.run(1.0)

        t = sim.data(model.t).flatten()

        with Plotter(self.Simulator) as plt:

            def plot(sim, a, A, title=""):
                a_ref = np.tile(a, (len(t), 1))
                a_sim = sim.data(A)
                colors = ['b', 'g', 'r', 'c', 'm', 'y']
                for i in xrange(min(dims, len(colors))):
                    plt.plot(t, a_ref[:, i], '--', color=colors[i])
                    plt.plot(t, a_sim[:, i], '-', color=colors[i])
                    plt.title(title)

            plt.subplot(221)
            plot(sim, a, A, title="A")
            plt.subplot(222)
            plot(sim, b, B, title="B")
            plt.subplot(223)
            plot(sim, c, C, title="C")
            plt.subplot(224)
            plot(sim, d, D.ensemble, title="D")
            plt.savefig('test_circularconv.test_circularconv_%d.pdf' % dims)
            plt.close()

        ### results
        tmask = t > (0.5 + sim.model.dt / 2)
        self.assertEqual(sim.data(A)[tmask].shape, (499, dims))
        a_sim = sim.data(A)[tmask].mean(axis=0)
        b_sim = sim.data(B)[tmask].mean(axis=0)
        c_sim = sim.data(C)[tmask].mean(axis=0)
        d_sim = sim.data(D.ensemble)[tmask].mean(axis=0)

        rtol, atol = 0.1, 0.05
        self.assertTrue(np.allclose(a, a_sim, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(b, b_sim, rtol=rtol, atol=atol))
        self.assertTrue(np.allclose(d, d_sim, rtol=rtol, atol=atol))
        self.assertTrue(rmse(c, c_sim) < 0.075)
Example #8
0
    def test_multidim(self):
        """Test an ensemble array with multiple dimensions per ensemble"""
        dims = 3
        n_neurons = 3 * 60
        radius = 1.5

        rng = np.random.RandomState(523887)
        a = rng.uniform(low=-0.7, high=0.7, size=dims)
        b = rng.uniform(low=-0.7, high=0.7, size=dims)

        ta = np.zeros((6, 3))
        ta[[0, 2, 4], [0, 1, 2]] = 1
        tb = np.zeros((6, 3))
        tb[[1, 3, 5], [0, 1, 2]] = 1
        c = np.dot(ta, a) + np.dot(tb, b)

        model = nengo.Model('Multidim', seed=123)
        inputA = model.make_node('input A', output=a)
        inputB = model.make_node('input B', output=b)
        A = model.add(
            EnsembleArray('A', nengo.LIF(n_neurons), dims, radius=radius))
        B = model.add(
            EnsembleArray('B', nengo.LIF(n_neurons), dims, radius=radius))
        C = model.add(
            EnsembleArray('C',
                          nengo.LIF(n_neurons * 2),
                          dims,
                          dimensions_per_ensemble=2,
                          radius=radius))

        model.connect(inputA, A)
        model.connect(inputB, B)
        model.connect(A, C, transform=ta)
        model.connect(B, C, transform=tb)

        model.probe(A, filter=0.03)
        model.probe(B, filter=0.03)
        model.probe(C, filter=0.03)

        sim = model.simulator(sim_class=self.Simulator)
        sim.run(1.0)

        t = sim.data(model.t).flatten()
        with Plotter(self.Simulator) as plt:

            def plot(sim, a, A, title=""):
                a_ref = np.tile(a, (len(t), 1))
                a_sim = sim.data(A)
                colors = ['b', 'g', 'r', 'c', 'm', 'y']
                for i in xrange(a_sim.shape[1]):
                    plt.plot(t, a_ref[:, i], '--', color=colors[i])
                    plt.plot(t, a_sim[:, i], '-', color=colors[i])
                plt.title(title)

            plt.subplot(131)
            plot(sim, a, A, title="A")
            plt.subplot(132)
            plot(sim, b, B, title="B")
            plt.subplot(133)
            plot(sim, c, C, title="C")
            plt.savefig('test_ensemble_array.test_multidim.pdf')
            plt.close()

        a_sim = sim.data(A)[t > 0.5].mean(axis=0)
        b_sim = sim.data(B)[t > 0.5].mean(axis=0)
        c_sim = sim.data(C)[t > 0.5].mean(axis=0)

        rtol, atol = 0.1, 0.05
        self.assertTrue(np.allclose(a, a_sim, atol=atol, rtol=rtol))
        self.assertTrue(np.allclose(b, b_sim, atol=atol, rtol=rtol))
        self.assertTrue(np.allclose(c, c_sim, atol=atol, rtol=rtol))
Example #9
0
    def test_matrix_mul(self):
        N = 100

        Amat = np.asarray([[.5, -.5]])
        Bmat = np.asarray([[
            0,
            -1.,
        ], [.7, 0]])

        model = nengo.Model('Matrix Multiplication', seed=123)

        radius = 1

        model.add(
            EnsembleArray('A',
                          nengo.LIF(N * Amat.size),
                          Amat.size,
                          radius=radius))
        model.add(
            EnsembleArray('B',
                          nengo.LIF(N * Bmat.size),
                          Bmat.size,
                          radius=radius))

        inputA = model.make_node('input A', output=Amat.ravel())
        inputB = model.make_node('input B', output=Bmat.ravel())
        model.connect('input A', 'A')
        model.connect('input B', 'B')
        model.probe('A', sample_every=0.01, filter=0.01)
        model.probe('B', sample_every=0.01, filter=0.01)

        C = model.add(
            EnsembleArray('C',
                          nengo.LIF(N * Amat.size * Bmat.shape[1] * 2),
                          Amat.size * Bmat.shape[1],
                          dimensions_per_ensemble=2,
                          radius=1.5 * radius))

        for ens in C.ensembles:
            ens.encoders = np.tile([[1, 1], [-1, 1], [1, -1], [-1, -1]],
                                   (ens.n_neurons / 4, 1))

        transformA = np.zeros((C.dimensions, Amat.size))
        transformB = np.zeros((C.dimensions, Bmat.size))

        for i in range(Amat.shape[0]):
            for j in range(Amat.shape[1]):
                for k in range(Bmat.shape[1]):
                    tmp = (j + k * Amat.shape[1] + i * Bmat.size)
                    transformA[tmp * 2][j + i * Amat.shape[1]] = 1
                    transformB[tmp * 2 + 1][k + j * Bmat.shape[1]] = 1

        model.connect('A', 'C', transform=transformA)
        model.connect('B', 'C', transform=transformB)
        model.probe('C', sample_every=0.01, filter=0.01)

        D = model.add(
            EnsembleArray('D',
                          nengo.LIF(N * Amat.shape[0] * Bmat.shape[1]),
                          Amat.shape[0] * Bmat.shape[1],
                          radius=radius))

        def product(x):
            return x[0] * x[1]

        transformC = np.zeros((D.dimensions, Bmat.size))
        for i in range(Bmat.size):
            transformC[i / Bmat.shape[0]][i] = 1

        model.connect('C', 'D', function=product, transform=transformC)
        model.probe('D', sample_every=0.01, filter=0.01)

        sim = model.simulator(sim_class=self.Simulator)
        sim.run(1)

        with Plotter(self.Simulator) as plt:
            plt.plot(sim.data('D'))
            for d in np.dot(Amat, Bmat).flatten():
                plt.axhline(d, color='k')
            plt.savefig('test_ensemble_array.test_matrix_mul.pdf')
            plt.close()

        self.assertTrue(
            np.allclose(sim.data('A')[50:, 0], 0.5, atol=.1, rtol=.01))
        self.assertTrue(
            np.allclose(sim.data('A')[50:, 1], -0.5, atol=.1, rtol=.01))

        self.assertTrue(
            np.allclose(sim.data('B')[50:, 0], 0, atol=.1, rtol=.01))
        self.assertTrue(
            np.allclose(sim.data('B')[50:, 1], -1, atol=.1, rtol=.01))
        self.assertTrue(
            np.allclose(sim.data('B')[50:, 2], .7, atol=.1, rtol=.01))
        self.assertTrue(
            np.allclose(sim.data('B')[50:, 3], 0, atol=.1, rtol=.01))

        Dmat = np.dot(Amat, Bmat)
        for i in range(Amat.shape[0]):
            for k in range(Bmat.shape[1]):
                self.assertTrue(
                    np.allclose(sim.data('D')[-10:, i * Bmat.shape[1] + k],
                                Dmat[i, k],
                                atol=0.1,
                                rtol=0.1),
                    (sim.data('D')[-10:, i * Bmat.shape[1] + k], Dmat[i, k]))
Example #10
0
    def test_multidim_probe(self):
        # Adjust these values to change the matrix dimensions
        #  Matrix A is D1xD2
        #  Matrix B is D2xD3
        #  result is D1xD3
        D1 = 1
        D2 = 2
        D3 = 3
        seed = 123
        N = 200

        Amat = np.asarray([[.4, .8]])
        Bmat = np.asarray([[-1.0, -0.6, -.15], [0.25, .5, .7]])

        net = nef.Network('V', seed=seed, simulator=self.Simulator)

        # values should stay within the range (-radius,radius)
        radius = 2.0

        # make 2 matrices to store the input
        logging.debug("make_array: input matrices A and B")
        net.make_array('A',
                       neurons=N,
                       array_size=D1 * D2,
                       radius=radius,
                       neuron_type='lif')
        net.make_array('B',
                       neurons=N,
                       array_size=D2 * D3,
                       radius=radius,
                       neuron_type='lif')

        # connect inputs to them so we can set their value
        inputA = net.make_input('input A', value=Amat.flatten())
        inputB = net.make_input('input B', value=Bmat.flatten())
        logging.debug("connect: input matrices A and B")
        net.connect('input A', 'A')
        net.connect('input B', 'B')

        # the C matrix holds the intermediate product calculations
        #  need to compute D1*D2*D3 products to multiply 2 matrices together
        logging.debug("make_array: intermediate C")
        net.make_array('C',
                       4 * N,
                       D1 * D2 * D3,
                       dimensions=2,
                       radius=1.5 * radius,
                       encoders=[[1, 1], [1, -1], [-1, 1], [-1, -1]],
                       neuron_type='lif')

        transformA = [[0] * (D1 * D2) for i in range(D1 * D2 * D3 * 2)]
        transformB = [[0] * (D2 * D3) for i in range(D1 * D2 * D3 * 2)]
        for i in range(D1):
            for k in range(D3):
                for j in range(D2):
                    tmp = (j + k * D2 + i * D2 * D3)
                    transformA[tmp * 2][j + i * D2] = 1
                    transformB[tmp * 2 + 1][k + j * D3] = 1

        logging.debug("transA: %s", str(transformA))
        logging.debug("transB: %s", str(transformB))

        logging.debug("connect A->C")
        net.connect('A', 'C', transform=transformA)
        logging.debug("connect B->C")
        net.connect('B', 'C', transform=transformB)

        Cprobe = net.make_probe('C', dt_sample=0.01, pstc=0.01)

        net.run(1)

        logging.debug("Cprove.shape=%s", str(Cprobe.get_data().shape))
        logging.debug("Amat=%s", str(Amat))
        logging.debug("Bmat=%s", str(Bmat))
        data = Cprobe.get_data()

        with Plotter(self.Simulator) as plt:
            for i in range(D1):
                for k in range(D3):
                    for j in range(D2):
                        tmp = (j + k * D2 + i * D2 * D3)
                        plt.subplot(D1 * D2 * D3, 2, 1 + 2 * tmp)
                        plt.title('A[%i, %i]' % (i, j))
                        plt.axhline(Amat[i, j])
                        plt.ylim(-radius, radius)
                        plt.plot(data[:, 2 * tmp])

                        plt.subplot(D1 * D2 * D3, 2, 2 + 2 * tmp)
                        plt.title('B[%i, %i]' % (j, k))
                        plt.axhline(Bmat[j, k])
                        plt.ylim(-radius, radius)
                        plt.plot(data[:, 2 * tmp + 1])
            plt.savefig('test_old_api.test_multidimprobe.pdf')
            plt.close()

        for i in range(D1):
            for k in range(D3):
                for j in range(D2):
                    tmp = (j + k * D2 + i * D2 * D3)
                    self.assertTrue(
                        np.allclose(data[-10:, 2 * tmp],
                                    Amat[i, j],
                                    atol=0.1,
                                    rtol=0.1),
                        (data[-10:, 2 * tmp], Amat[i, j]))

                    self.assertTrue(
                        np.allclose(data[-10:, 1 + 2 * tmp],
                                    Bmat[j, k],
                                    atol=0.1,
                                    rtol=0.1))
Example #11
0
    def test_matrix_mul(self):
        # Adjust these values to change the matrix dimensions
        #  Matrix A is D1xD2
        #  Matrix B is D2xD3
        #  result is D1xD3
        D1 = 1
        D2 = 2
        D3 = 2
        seed = 123
        N = 200

        Amat = np.asarray([[.5, -.5]])
        Bmat = np.asarray([[
            0,
            -1.,
        ], [.7, 0]])

        net = nef.Network('Matrix Multiplication',
                          seed=seed,
                          simulator=self.Simulator)

        # values should stay within the range (-radius,radius)
        radius = 1

        # make 2 matrices to store the input
        logging.debug("make_array: input matrices A and B")
        net.make_array('A',
                       neurons=N,
                       array_size=D1 * D2,
                       radius=radius,
                       neuron_type='lif')
        net.make_array('B',
                       neurons=N,
                       array_size=D2 * D3,
                       radius=radius,
                       neuron_type='lif')

        # connect inputs to them so we can set their value
        inputA = net.make_input('input A', value=Amat.ravel())
        inputB = net.make_input('input B', value=Bmat.ravel())
        logging.debug("connect: input matrices A and B")
        net.connect('input A', 'A')
        net.connect('input B', 'B')

        # the C matrix holds the intermediate product calculations
        #  need to compute D1*D2*D3 products to multiply 2 matrices together
        logging.debug("make_array: intermediate C")
        net.make_array('C',
                       4 * N,
                       D1 * D2 * D3,
                       dimensions=2,
                       radius=1.5 * radius,
                       encoders=[[1, 1], [1, -1], [-1, 1], [-1, -1]],
                       neuron_type='lif')

        #  determine the transformation matrices to get the correct pairwise
        #  products computed.  This looks a bit like black magic but if
        #  you manually try multiplying two matrices together, you can see
        #  the underlying pattern.  Basically, we need to build up D1*D2*D3
        #  pairs of numbers in C to compute the product of.  If i,j,k are the
        #  indexes into the D1*D2*D3 products, we want to compute the product
        #  of element (i,j) in A with the element (j,k) in B.  The index in
        #  A of (i,j) is j+i*D2 and the index in B of (j,k) is k+j*D3.
        #  The index in C is j+k*D2+i*D2*D3, multiplied by 2 since there are
        #  two values per ensemble.  We add 1 to the B index so it goes into
        #  the second value in the ensemble.
        transformA = [[0] * (D1 * D2) for i in range(D1 * D2 * D3 * 2)]
        transformB = [[0] * (D2 * D3) for i in range(D1 * D2 * D3 * 2)]
        for i in range(D1):
            for j in range(D2):
                for k in range(D3):
                    tmp = (j + k * D2 + i * D2 * D3)
                    transformA[tmp * 2][j + i * D2] = 1
                    transformB[tmp * 2 + 1][k + j * D3] = 1

        logging.debug("connect A->C")
        net.connect('A', 'C', transform=transformA)
        logging.debug("connect B->C")
        net.connect('B', 'C', transform=transformB)

        # now compute the products and do the appropriate summing
        logging.debug("make_array: output D")
        net.make_array('D', N, D1 * D3, radius=radius, neuron_type='lif')

        def product(x):
            return x[0] * x[1]

        # the mapping for this transformation is much easier, since we want to
        # combine D2 pairs of elements (we sum D2 products together)

        net.connect('C',
                    'D',
                    index_post=[i / D2 for i in range(D1 * D2 * D3)],
                    func=product)

        Aprobe = net.make_probe('A', dt_sample=0.01, pstc=0.01)
        Bprobe = net.make_probe('B', dt_sample=0.01, pstc=0.01)
        Cprobe = net.make_probe('C', dt_sample=0.01, pstc=0.01)
        Dprobe = net.make_probe('D', dt_sample=0.01, pstc=0.01)

        prod_probe = net._probe_decoded_signals(
            net.ensembles['C'].origin['product'].sigs,
            dt_sample=0.01,
            pstc=.01)

        net.run(1)

        Dmat = np.dot(Amat, Bmat)
        data = Dprobe.get_data()

        with Plotter(self.Simulator) as plt:
            for i in range(D1):
                for k in range(D3):
                    plt.subplot(D1, D3, i * D3 + k + 1)
                    plt.title('D[%i, %i]' % (i, k))
                    plt.plot(data[:, i * D3 + k])
                    plt.axhline(Dmat[i, k])
                    plt.ylim(-radius, radius)
            plt.savefig('test_old_api.test_matrix_mul.pdf')
            plt.close()

        self.assertTrue(
            np.allclose(Aprobe.get_data()[50:, 0], 0.5, atol=.1, rtol=.01))
        self.assertTrue(
            np.allclose(Aprobe.get_data()[50:, 1], -0.5, atol=.1, rtol=.01))

        self.assertTrue(
            np.allclose(Bprobe.get_data()[50:, 0], 0, atol=.1, rtol=.01))
        self.assertTrue(
            np.allclose(Bprobe.get_data()[50:, 1], -1, atol=.1, rtol=.01))
        self.assertTrue(
            np.allclose(Bprobe.get_data()[50:, 2], .7, atol=.1, rtol=.01))
        self.assertTrue(
            np.allclose(Bprobe.get_data()[50:, 3], 0, atol=.1, rtol=.01))

        for i in range(D1):
            for k in range(D3):
                self.assertTrue(
                    np.allclose(data[-10:, i * D3 + k],
                                Dmat[i, k],
                                atol=0.1,
                                rtol=0.1),
                    (data[-10:, i * D3 + k], Dmat[i, k]))