def test_full_transform_scalar(self):
        """Test extracting the full transform when only a scalar is provided.
        """
        # Construct the expected matrix
        expected = np.zeros((4, 8))
        expected[np.array([1, 2, 3]), np.array([5, 6, 7])] = 1.5

        # Create the transform
        t = Transform(size_in=8, slice_in=slice(5, None),
                      transform=1.5,
                      size_out=4, slice_out=[1, 2, 3])

        # Check the full transform is correct
        assert np.array_equal(
            t.full_transform(slice_in=True, slice_out=False),
            expected[:, 5:]
        )

        assert np.array_equal(
            t.full_transform(slice_in=False, slice_out=True),
            expected[1:]
        )

        assert np.array_equal(
            t.full_transform(slice_in=False, slice_out=False),
            expected
        )
    def test_full_transform_matrix(self):
        """Test extracting the full transform when a matrix is provided.
        """
        # Construct the expected matrix
        expected = np.zeros((4, 8))
        matrix = np.arange(9)
        matrix.shape = (3, 3)
        expected[:3, 3:6] = matrix

        # Create the transform
        t = Transform(size_in=8,
                      slice_in=[3, 4, 5],
                      transform=matrix,
                      size_out=4,
                      slice_out=slice(3))

        # Check the full transform is correct
        assert np.array_equal(t.full_transform(slice_in=True, slice_out=False),
                              expected[:, 3:6])

        assert np.array_equal(t.full_transform(slice_in=False, slice_out=True),
                              expected[:3])

        assert np.array_equal(
            t.full_transform(slice_in=False, slice_out=False), expected)
    def test_full_transform_vector(self):
        """Test extracting the full transform when only a vector is provided.
        """
        # Construct the expected matrix
        expected = np.zeros((4, 8))
        diag = np.array([1.0, 2.0, 3.0])
        expected[np.array([0, 1, 2]), np.array([3, 4, 5])] = diag

        # Create the transform
        t = Transform(size_in=8, slice_in=[3, 4, 5],
                      transform=diag,
                      size_out=4, slice_out=slice(3))

        # Check the full transform is correct
        assert np.array_equal(
            t.full_transform(slice_in=True, slice_out=False),
            expected[:, 3:6]
        )

        assert np.array_equal(
            t.full_transform(slice_in=False, slice_out=True),
            expected[:3]
        )

        assert np.array_equal(
            t.full_transform(slice_in=False, slice_out=False),
            expected
        )
    def test_full_transform_matrix(self):
        """Test extracting the full transform when a matrix is provided.
        """
        # Construct the expected matrix
        expected = np.zeros((4, 8))
        matrix = np.arange(9)
        matrix.shape = (3, 3)
        expected[:3, 3:6] = matrix

        # Create the transform
        t = Transform(size_in=8, slice_in=[3, 4, 5],
                      transform=matrix,
                      size_out=4, slice_out=slice(3))

        # Check the full transform is correct
        assert np.array_equal(
            t.full_transform(slice_in=True, slice_out=False),
            expected[:, 3:6]
        )

        assert np.array_equal(
            t.full_transform(slice_in=False, slice_out=True),
            expected[:3]
        )

        assert np.array_equal(
            t.full_transform(slice_in=False, slice_out=False),
            expected
        )
    def test_concat(self):
        """Test concatenating Node transmission parameters with passthrough
        node transmission parameters.
        """
        a = NodeTransmissionParameters(Transform(size_in=2,
                                                 size_out=5,
                                                 transform=[[2.0, 0.0],
                                                            [0.0, 2.0]],
                                                 slice_out=(1, 3)),
                                       pre_slice=slice(0, 3),
                                       function=object())
        b = PassthroughNodeTransmissionParameters(
            Transform(size_in=5,
                      size_out=2,
                      transform=[0.5, 0.25],
                      slice_in=(0, 3)))

        # Combine
        c = a.concat(b)
        assert c.size_in == a.size_in
        assert c.pre_slice == a.pre_slice
        assert c.function is a.function
        assert np.array_equal(
            c.full_transform(False, False),
            np.dot(b.full_transform(False, False),
                   a.full_transform(False, False)))
    def test_concat(self):
        """Test that passthrough node connection parameters can be combined
        with later passthrough node connection parameters to build a new set of
        parameters.
        """
        # Check that these parameters are combined correctly
        a = PassthroughNodeTransmissionParameters(
            Transform(size_in=5,
                      size_out=3,
                      transform=2.0,
                      slice_in=slice(2),
                      slice_out=slice(2)))
        b = PassthroughNodeTransmissionParameters(
            Transform(size_in=3,
                      size_out=3,
                      slice_in=slice(2),
                      slice_out=slice(1, 3),
                      transform=[-1.0, 1.5]))

        # Combine the connections
        c = a.concat(b)

        # Check the new parameters
        assert c.size_in == a.size_in
        assert c.size_out == b.size_out
        assert np.array_equal(c.slice_in, a.slice_in)
        assert np.array_equal(c.slice_out, b.slice_out)

        assert np.array_equal(
            c.full_transform(False, False),
            np.dot(b.full_transform(False, False),
                   a.full_transform(False, False)))
    def test_hstack_two_matrices(self):
        """Test horizontally stacking two matrices with some misaligned rows.
        """
        transform_a = np.ones((3, 3))
        transform_b = np.ones((2, 1)) * -1

        A = Transform(size_in=4,
                      size_out=5,
                      transform=transform_a,
                      slice_in=(0, 1, 2),
                      slice_out=(2, 3, 4))
        B = Transform(size_in=2,
                      size_out=5,
                      transform=transform_b,
                      slice_in=(1, ),
                      slice_out=(1, 2))

        # Stack the transforms
        C = A.hstack(B)

        # Check the full transform is correct
        assert np.array_equal(
            C.full_transform(False, False),
            np.array([[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
                      [0.0, 0.0, 0.0, 0.0, 0.0, -1.0],
                      [1.0, 1.0, 1.0, 0.0, 0.0, -1.0],
                      [1.0, 1.0, 1.0, 0.0, 0.0, 0.0],
                      [1.0, 1.0, 1.0, 0.0, 0.0, 0.0]]))
    def test_equivalence_transform(self):
        # With different transforms
        tp1 = Transform(2, 2, np.ones((2, 2)))
        tp2 = Transform(2, 2, np.zeros((2, 2)))
        assert tp1 != tp2
        assert hash(tp1) != hash(tp2)

        # With the same transforms
        tp3 = Transform(2, 2, np.ones((2, 2)))
        assert tp1 == tp3
        assert hash(tp1) == hash(tp3)
    def test_equivalence_different_size_in(self):
        # With different size ins
        tp1 = Transform(size_in=1, size_out=3, transform=1)
        tp2 = Transform(size_in=2, size_out=3, transform=1)
        assert tp1 != tp2
        assert hash(tp1) != hash(tp2)

        # With the same size ins
        tp3 = Transform(size_in=1, size_out=3, transform=1)
        assert tp1 == tp3
        assert hash(tp1) == hash(tp3)
    def test_equivalence_transform(self):
        # With different transforms
        tp1 = NodeTransmissionParameters(Transform(2, 1, np.ones((2, 2))))
        tp2 = NodeTransmissionParameters(Transform(2, 1, np.zeros((2, 2))))
        assert tp1 != tp2
        assert hash(tp1) != hash(tp2)

        # With the same transforms
        tp3 = NodeTransmissionParameters(Transform(2, 1, np.ones((2, 2))))
        assert tp1 == tp3
        assert hash(tp1) == hash(tp3)
示例#11
0
    def test_insert_interposers_simple(self):
        """Test that interposers are inserted correctly."""
        cm = model.ConnectionMap()

        # Add a connection from a node to a passthrough node to the model
        nodes = [object(), object()]
        ptn = model.PassthroughNode()

        for node in nodes:
            cm.add_connection(
                node, OutputPort.standard, model.SignalParameters(weight=1),
                NodeTransmissionParameters(Transform(1, 1, 1)),
                ptn, InputPort.standard,
                model.ReceptionParameters(None, 1, None)
            )

        # Add a connection from the passthrough node to another node
        sink = object()
        sink_port = object()
        cm.add_connection(
            ptn, OutputPort.standard, model.SignalParameters(weight=70),
            PassthroughNodeTransmissionParameters(
                Transform(1, 70, np.ones((70, 1)))
            ),
            sink, sink_port, model.ReceptionParameters(None, 70, None)
        )

        # Insert interposers, getting a list of interposers and a new
        # connection map.
        interposers, new_cm = cm.insert_interposers()
        assert len(interposers) == 1  # Should insert 1 interposer
        interposer = interposers[0]

        # Check that each of the nodes connects to the interposer
        for node in nodes:
            from_node = new_cm._connections[node][OutputPort.standard]
            assert len(from_node) == 1

            for sinks in itervalues(from_node):
                assert len(sinks) == 1
                for s in sinks:
                    assert s.sink_object is interposer
                    assert s.port is InputPort.standard

        # Check that the interposer connects to the sink
        from_interposer = new_cm._connections[interposer][OutputPort.standard]
        assert len(from_interposer) == 1

        for sinks in itervalues(from_interposer):
            assert len(sinks) == 1
            for s in sinks:
                assert s.sink_object is sink
                assert s.port is sink_port
    def test_concat_empty_transform_zero_transform_trivial(self):
        # Build the transforms
        A = Transform(size_in=2, transform=0, size_out=2)
        B = Transform(size_in=2, transform=1, size_out=2)

        # Check that the test is correct
        expected = np.dot(B.full_transform(False, False),
                          A.full_transform(False, False))
        assert not np.any(expected), "Test broken"

        # Combine the transforms, this should return None to indicate that the
        # transform is empty.
        assert A.concat(B) is None
    def test_concat_empty_transform_mismatched_slicing(self):
        # Build the transforms
        A = Transform(size_in=1, transform=1, size_out=2, slice_out=[0])
        B = Transform(size_in=2, slice_in=[1], transform=1, size_out=1)

        # Check that the test is correct
        expected = np.dot(B.full_transform(False, False),
                          A.full_transform(False, False))
        assert not np.any(expected), "Test broken"

        # Combine the transforms, this should return None to indicate that the
        # transform is empty.
        assert A.concat(B) is None
    def test_concat_no_connection(self):
        a = EnsembleTransmissionParameters(decoders=[[1.0, 2.0, 3.0, 4.0],
                                                     [4.0, 3.0, 2.0, 1.0]],
                                           transform=Transform(2,
                                                               4,
                                                               1,
                                                               slice_out=(1,
                                                                          2)))
        b = PassthroughNodeTransmissionParameters(
            Transform(size_in=4, size_out=2, transform=1.0, slice_in=(0, 3)))

        # Combine the parameters
        assert a.concat(b) is None
    def test_concat(self, a_params, b_params):
        # Build the transforms
        A = Transform(size_in=8, size_out=8, **a_params)
        B = Transform(size_in=8, size_out=4, **b_params)

        # Compute the expected combined transform
        expected = np.dot(B.full_transform(False, False),
                          A.full_transform(False, False))

        # Combine the transforms
        C = A.concat(B)

        # Test
        assert np.array_equal(expected, C.full_transform(False, False))
    def test_concat_no_connection(self):
        a = NodeTransmissionParameters(Transform(size_in=2,
                                                 size_out=5,
                                                 transform=[[2.0, 0.0],
                                                            [0.0, 2.0]],
                                                 slice_out=(1, 3)),
                                       pre_slice=slice(0, 3),
                                       function=object())
        b = PassthroughNodeTransmissionParameters(
            Transform(size_in=5,
                      size_out=2,
                      transform=[0.5, 0.25],
                      slice_in=(0, 2)))

        # Combine
        assert a.concat(b) is None
    def test_concat_no_connection(self):
        """Test that None is returned if concatenating connections results in
        an empty transform.
        """
        a = PassthroughNodeTransmissionParameters(
            Transform(size_in=4,
                      size_out=16,
                      slice_out=slice(4),
                      transform=1.0))
        b = PassthroughNodeTransmissionParameters(
            Transform(size_in=16,
                      size_out=4,
                      slice_in=slice(4, 8),
                      transform=1.0))

        # Combine the connections
        assert a.concat(b) is None
    def test_hash_with_sliced_input(self):
        tp = Transform(size_in=10,
                       size_out=5,
                       transform=1,
                       slice_in=slice(0, 10, 2))

        # Fails if the slicing is performed poorly
        hash(tp)
    def test_equivalence_slice_out(self):
        # With different slices
        tp1 = Transform(size_in=2,
                        size_out=3,
                        transform=1,
                        slice_out=slice(0, 2))
        tp2 = Transform(size_in=2,
                        size_out=3,
                        transform=1,
                        slice_out=slice(1, 3))
        assert tp1 != tp2
        assert hash(tp1) != hash(tp2)

        # With equivalent but differently expressed slices
        tp3 = Transform(size_in=2, size_out=3, transform=1, slice_out=(0, 1))
        assert tp1 == tp3
        assert hash(tp1) == hash(tp3)
    def test_supports_global_inhibition(self):
        tp1 = PassthroughNodeTransmissionParameters(
            Transform(size_in=10, size_out=100, transform=np.ones((100, 10))))
        assert tp1.supports_global_inhibition

        tp2 = tp1.as_global_inhibition_connection
        assert tp2.size_in == tp1.size_in
        assert tp2.size_out == 1
        assert tp2.slice_out.size == 1
        assert np.array_equal(tp2.full_transform(), np.ones((1, 10)))
    def test_equivalence_decoders(self):
        """Parameters are only equivalent if they have the same decoders."""
        transform = Transform(1, 1, 1)
        tp1 = EnsembleTransmissionParameters(np.ones((3, 100)), transform)
        tp2 = EnsembleTransmissionParameters(np.zeros((3, 100)), transform)
        assert tp1 != tp2

        tp3 = EnsembleTransmissionParameters(np.ones((3, 100)), transform)
        assert hash(tp1) == hash(tp3)
        assert tp1 == tp3
示例#22
0
    def test_insert_interposers_removes_passthrough_node(self):
        """Test that passthrough nodes are removed while inserting interposers.
        """
        cm = model.ConnectionMap()

        # Add a connection from a node to a passthrough node to the model
        node = object()
        ptn = model.PassthroughNode()
        cm.add_connection(
            node, OutputPort.standard, model.SignalParameters(weight=1),
            NodeTransmissionParameters(Transform(1, 1, 1)),
            ptn, InputPort.standard, model.ReceptionParameters(None, 1, None)
        )

        # Add a connection from the passthrough node to another node
        sink = object()
        cm.add_connection(
            ptn, OutputPort.standard, model.SignalParameters(weight=1),
            PassthroughNodeTransmissionParameters(Transform(1, 1, 1)),
            sink, InputPort.standard, model.ReceptionParameters(None, 1, None)
        )

        # Insert interposers, getting a list of interposers (empty) and a new
        # connection map.
        interposers, new_cm = cm.insert_interposers()
        assert len(interposers) == 0  # No interposers expected

        # Check that there is now just one connection from the node to the sink
        from_node = new_cm._connections[node]
        assert list(from_node) == [OutputPort.standard]

        for (signal_pars, transmission_pars), sinks in \
                iteritems(from_node[OutputPort.standard]):
            # Check the transmission parameters
            assert transmission_pars == NodeTransmissionParameters(
                Transform(1, 1, 1)
            )

            # Check that the sink is correct
            assert len(sinks) == 1
            for s in sinks:
                assert s.sink_object is sink
    def test_global_inhibition(self):
        tp = EnsembleTransmissionParameters(
            decoders=np.random.normal(size=(10, 100)),
            transform=Transform(size_in=10,
                                size_out=200,
                                transform=np.ones((200, 10))))
        assert tp.supports_global_inhibition

        tp2 = tp.as_global_inhibition_connection
        assert tp2.size_out == 1 and tp2.slice_out.size == 1
        assert np.array_equal(tp2.full_transform(), np.ones((1, 10)))
    def test_concat_no_learning_rule(self):
        a = EnsembleTransmissionParameters(decoders=[[1.0, 2.0, 3.0, 4.0],
                                                     [4.0, 3.0, 2.0, 1.0]],
                                           transform=Transform(2,
                                                               4,
                                                               1,
                                                               slice_out=(1,
                                                                          2)))
        b = PassthroughNodeTransmissionParameters(
            Transform(size_in=4, size_out=2, transform=1.0, slice_in=(1, 2)))

        # Combine the parameters
        c = a.concat(b)

        # Check the results
        assert isinstance(c, EnsembleTransmissionParameters)
        assert c.learning_rule is None
        assert c.size_out == b.size_out
        assert np.array_equal(c.slice_out, b.slice_out)
        assert np.array_equal(c.decoders, a.decoders)
    def test_hstack_scalar_and_vector(self):
        """Test horizontally stacking two matrices with some misaligned rows.
        """
        A = Transform(size_in=5, size_out=5, transform=1.0,
                      slice_in=(0, 1), slice_out=(2, 3))
        B = Transform(size_in=3, size_out=5, transform=[2.0, 3.0, 4.0],
                      slice_out=(0, 2, 3))

        # Stack the transforms
        C = A.hstack(B)

        # Check the full transform is correct
        assert np.array_equal(
            C.full_transform(False, False),
            np.array([[0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0],
                      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
                      [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0],
                      [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0],
                      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])
        )
    def test_equivalence_pre_slice(self):
        # NOTE: Slices can't be hashed
        # With different slices
        t = Transform(2, 2, 1)
        tp1 = NodeTransmissionParameters(t, pre_slice=slice(0, 2))
        tp2 = NodeTransmissionParameters(t, pre_slice=slice(1, 3))
        assert tp1 != tp2

        # With equivalent but differently expressed slices
        tp3 = NodeTransmissionParameters(t, pre_slice=slice(0, 2))
        assert tp1 == tp3
    def test_full_decoders(self):
        """Test that the decoders and transform are combined correctly."""
        decoders = np.array([[0.5, 2.5, -.3, 1.0]])
        transform = Transform(size_in=1, size_out=2, transform=[[-1.0], [1.0]])

        tp = EnsembleTransmissionParameters(decoders=decoders,
                                            transform=transform)

        assert np.array_equal(
            tp.full_decoders,
            np.array([[-0.5, -2.5, 0.3, -1.0], [0.5, 2.5, -.3, 1.0]]))
示例#28
0
    def test_insert_interposers_ignore_sinkless(self):
        """Test that interposers are inserted correctly, ignoring those that
        don't connect to anything.
        """
        cm = model.ConnectionMap()

        # Add a connection from a node to a passthrough node to the model
        nodes = [object(), object()]
        ptn = model.PassthroughNode()

        for node in nodes:
            cm.add_connection(
                node, OutputPort.standard, model.SignalParameters(weight=1),
                NodeTransmissionParameters(Transform(1, 1, 1)),
                ptn, InputPort.standard,
                model.ReceptionParameters(None, 1, None)
            )

        # Connect the passthrough node to another passthrough node
        ptn2 = model.PassthroughNode()
        cm.add_connection(ptn, OutputPort.standard, model.SignalParameters(),
                          PassthroughNodeTransmissionParameters(
                            Transform(1, 70, transform=np.ones((70, 1)))),
                          ptn2, InputPort.standard,
                          model.ReceptionParameters(None, 70, None))

        # Connect the passthrough node to another passthrough node
        ptn3 = model.PassthroughNode()
        cm.add_connection(ptn2, OutputPort.standard, model.SignalParameters(),
                          PassthroughNodeTransmissionParameters(
                            Transform(70, 70, 1)),
                          ptn3, InputPort.standard,
                          model.ReceptionParameters(None, 70, None))

        # Insert interposers, getting a list of interposers and a new
        # connection map.
        interposers, new_cm = cm.insert_interposers()
        assert len(interposers) == 0  # No interposers

        # No signals at all
        assert len(list(new_cm.get_signals())) == 0
    def test_global_inhibition(self):
        tp = NodeTransmissionParameters(Transform(size_in=3,
                                                  size_out=100,
                                                  transform=np.ones((100, 3))),
                                        pre_slice=slice(0, 100),
                                        function=object())
        assert tp.supports_global_inhibition

        tp2 = tp.as_global_inhibition_connection
        assert tp2.function is tp.function
        assert tp2.pre_slice == tp.pre_slice
        assert tp2.size_out == 1
        assert np.array_equal(tp2.full_transform(), np.ones((1, 3)))
    def test_hstack_two_matrices(self):
        """Test horizontally stacking two matrices with some misaligned rows.
        """
        transform_a = np.ones((3, 3))
        transform_b = np.ones((2, 1)) * -1

        A = Transform(size_in=4, size_out=5, transform=transform_a,
                      slice_in=(0, 1, 2), slice_out=(2, 3, 4))
        B = Transform(size_in=2, size_out=5, transform=transform_b,
                      slice_in=(1, ), slice_out=(1, 2))

        # Stack the transforms
        C = A.hstack(B)

        # Check the full transform is correct
        assert np.array_equal(
            C.full_transform(False, False),
            np.array([[0.0, 0.0, 0.0, 0.0, 0.0,  0.0],
                      [0.0, 0.0, 0.0, 0.0, 0.0, -1.0],
                      [1.0, 1.0, 1.0, 0.0, 0.0, -1.0],
                      [1.0, 1.0, 1.0, 0.0, 0.0,  0.0],
                      [1.0, 1.0, 1.0, 0.0, 0.0,  0.0]])
        )
    def test_full_transform_scalar(self):
        """Test extracting the full transform when only a scalar is provided.
        """
        # Construct the expected matrix
        expected = np.zeros((4, 8))
        expected[np.array([1, 2, 3]), np.array([5, 6, 7])] = 1.5

        # Create the transform
        t = Transform(size_in=8,
                      slice_in=slice(5, None),
                      transform=1.5,
                      size_out=4,
                      slice_out=[1, 2, 3])

        # Check the full transform is correct
        assert np.array_equal(t.full_transform(slice_in=True, slice_out=False),
                              expected[:, 5:])

        assert np.array_equal(t.full_transform(slice_in=False, slice_out=True),
                              expected[1:])

        assert np.array_equal(
            t.full_transform(slice_in=False, slice_out=False), expected)
示例#32
0
    def test_stack_interposers_no_stack(self):
        # Create a network consisting of two ensembles targeting a sink, insert
        # interposers into this network and then stack the interposers to
        # reduce later connectivity.
        MockEnsemble = collections.namedtuple("MockEnsemble", "size_in")
        source_1 = EnsembleLIF(MockEnsemble(1))
        source_2 = EnsembleLIF(MockEnsemble(1))
        sink = object()

        # Create a connection map and add the connections
        cm = model.ConnectionMap()
        cm.add_connection(
            source_1, OutputPort.standard, model.SignalParameters(weight=512),
            EnsembleTransmissionParameters(
                decoders=np.ones((1, 100)),
                transform=Transform(
                    size_in=1, size_out=512, transform=np.ones((512, 1))
                )
            ), sink, InputPort.standard,
            model.ReceptionParameters(None, 512, None)
        )

        cm.add_connection(  # Transform and the filter are distinct!
            source_2, OutputPort.standard, model.SignalParameters(weight=512),
            EnsembleTransmissionParameters(
                decoders=np.ones((1, 100)),
                transform=Transform(
                    size_in=1, size_out=512, transform=0.5*np.ones((512, 1))
                )
            ), sink, InputPort.standard,
            model.ReceptionParameters(object(), 512, None)
        )

        # Insert and stack the interposers
        interposers, new_cm = cm.insert_and_stack_interposers()
        new_cm = new_cm._connections
        assert len(interposers) == 2
示例#33
0
    def test_stack_interposers_no_interposer(self):
        # Create a network consisting of two ensembles targeting a sink
        MockEnsemble = collections.namedtuple("MockEnsemble", "size_in")
        source_1 = EnsembleLIF(MockEnsemble(1))
        source_2 = EnsembleLIF(MockEnsemble(1))
        sink = object()

        # Create a connection map and add the connections
        cm = model.ConnectionMap()
        cm.add_connection(
            source_1, OutputPort.standard, model.SignalParameters(weight=512),
            EnsembleTransmissionParameters(
                decoders=np.ones((1, 100)),
                transform=Transform(
                    size_in=1, size_out=1, transform=1.0
                )
            ), sink, InputPort.standard,
            model.ReceptionParameters(None, 1, None)
        )

        cm.add_connection(  # Make sure the transform is distinct!
            source_2, OutputPort.standard, model.SignalParameters(weight=512),
            EnsembleTransmissionParameters(
                decoders=np.ones((1, 100)),
                transform=Transform(
                    size_in=1, size_out=1, transform=0.5
                )
            ), sink, InputPort.standard,
            model.ReceptionParameters(None, 512, None)
        )

        # Insert and stack the interposers
        interposers, new_cm = cm.insert_and_stack_interposers()
        assert len(interposers) == 0

        # The connection map should be unchanged
        assert new_cm._connections == cm._connections
    def test_concat_empty_transform_zero_transform_trivial(self):
        # Build the transforms
        A = Transform(size_in=2, transform=0, size_out=2)
        B = Transform(size_in=2, transform=1, size_out=2)

        # Check that the test is correct
        expected = np.dot(B.full_transform(False, False),
                          A.full_transform(False, False))
        assert not np.any(expected), "Test broken"

        # Combine the transforms, this should return None to indicate that the
        # transform is empty.
        assert A.concat(B) is None
    def test_concat_empty_transform_mismatched_slicing(self):
        # Build the transforms
        A = Transform(size_in=1, transform=1, size_out=2, slice_out=[0])
        B = Transform(size_in=2, slice_in=[1], transform=1, size_out=1)

        # Check that the test is correct
        expected = np.dot(B.full_transform(False, False),
                          A.full_transform(False, False))
        assert not np.any(expected), "Test broken"

        # Combine the transforms, this should return None to indicate that the
        # transform is empty.
        assert A.concat(B) is None
    def test_equivalence_learning_rule(self):
        """Parameters are equivalent only if they both have no learning rule."""
        t = Transform(1, 1, 1)
        tp1 = EnsembleTransmissionParameters([[1]], t, learning_rule=None)
        tp2 = EnsembleTransmissionParameters([[1]], t, learning_rule=object())
        assert tp1 != tp2

        tp3 = EnsembleTransmissionParameters([[1]], t)
        assert hash(tp1) == hash(tp3)
        assert tp1 == tp3

        tp4 = EnsembleTransmissionParameters([[1]],
                                             t,
                                             learning_rule=tp2.learning_rule)
        assert tp4 != tp2
    def test_projects_to(self):
        """Test that the parameters correctly report if they transmit any
        values to the dimensions listed.
        """
        tp = EnsembleTransmissionParameters(decoders=np.ones((1, 4)),
                                            transform=Transform(
                                                size_in=1,
                                                size_out=16,
                                                transform=1.0,
                                                slice_out=slice(4)))

        assert tp.projects_to(slice(1))
        assert tp.projects_to(slice(5))
        assert not tp.projects_to(slice(4, 8))
        assert tp.projects_to((0, 1, 2, 4))
    def test_hstack_scalar_and_vector(self):
        """Test horizontally stacking two matrices with some misaligned rows.
        """
        A = Transform(size_in=5,
                      size_out=5,
                      transform=1.0,
                      slice_in=(0, 1),
                      slice_out=(2, 3))
        B = Transform(size_in=3,
                      size_out=5,
                      transform=[2.0, 3.0, 4.0],
                      slice_out=(0, 2, 3))

        # Stack the transforms
        C = A.hstack(B)

        # Check the full transform is correct
        assert np.array_equal(
            C.full_transform(False, False),
            np.array([[0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0],
                      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
                      [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0],
                      [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0],
                      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]))