def test_apply_SWAP_gate_efficient(self):
        qc = QC(2, 0)
        qc.X(0)
        qc.SWAP(0, 1, efficient=True)

        np.testing.assert_array_equal(
            qc.total_density_matrix()[0].toarray(),
            np.array([[0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]))
    def test_apply_SWAP_full_swap(self):
        qc = QC(3, 0, noise=True, pg=0.1)
        qc.CNOT(0, 1)
        qc.CNOT(1, 0)
        qc.CNOT(0, 1)

        qc2 = QC(3, 0, noise=True, pg=0.1)
        qc2.SWAP(0, 1, efficient=False)

        np.testing.assert_array_almost_equal(
            qc.total_density_matrix()[0].toarray(),
            qc2.total_density_matrix()[0].toarray())
    def test_SWAP(self):
        qc = QC(5, 0)
        qc.X(0)
        qc.SWAP(0, 1)

        density_matrix_0, qubits_0 = qc._qubit_density_matrix_lookup[0]
        density_matrix_1, qubits_1 = qc._qubit_density_matrix_lookup[1]
        np.testing.assert_array_equal(density_matrix_0.toarray(),
                                      np.array([[1, 0], [0, 0]]))
        np.testing.assert_array_equal(density_matrix_1.toarray(),
                                      np.array([[0, 0], [0, 1]]))
        self.assertEqual(qubits_0, [0])
        self.assertEqual(qubits_1, [1])
    def test_apply_SWAP_efficient_swap(self):
        qc = QC(3, 0, noise=True, pg=0.1, pn=0.1)
        qc.create_bell_pair(1, 2)
        qc._uninitialised_qubits.append(0)
        # SWAP is equal to three CNOT operations
        qc.CNOT(1, 0)
        qc.CNOT(0, 1)
        qc.CNOT(1, 0)
        # Qubit 1 is now uninitialised due to swapping. Measure it such that it disappears from the density matrix
        qc.measure(1)

        qc2 = QC(3, 0, noise=True, pg=0.1, pn=0.1)
        qc2.create_bell_pair(1, 2)
        qc2._uninitialised_qubits.append(0)
        qc2.SWAP(1, 0, efficient=True)
        # Measurement of qubit 1 is not necessary, since the density matrices are not fused with the efficient SWAP

        np.testing.assert_array_almost_equal(
            qc.get_combined_density_matrix([0])[0].toarray(),
            qc2.get_combined_density_matrix([0])[0].toarray())
    def test_SWAP_bell_pair(self):
        qc = QC(5, 0)
        qc.create_bell_pair(0, 1)
        qc.SWAP(0, 2)
        qc.SWAP(1, 3)

        density_matrix_0, qubits_0 = qc._qubit_density_matrix_lookup[0]
        density_matrix_1, qubits_1 = qc._qubit_density_matrix_lookup[1]
        density_matrix_2, qubits_2 = qc._qubit_density_matrix_lookup[2]
        density_matrix_3, qubits_3 = qc._qubit_density_matrix_lookup[3]
        self.assertTrue(density_matrix_2 is density_matrix_3)
        self.assertTrue(density_matrix_2.shape == (4, 4))
        self.assertTrue(qubits_2 is qubits_3)
        np.testing.assert_array_equal(density_matrix_0.toarray(),
                                      np.array([[1, 0], [0, 0]]))
        np.testing.assert_array_equal(density_matrix_1.toarray(),
                                      np.array([[1, 0], [0, 0]]))
        self.assertTrue(qubits_0 is not qubits_1)
        self.assertEqual(qubits_0, [0])
        self.assertEqual(qubits_1, [1])
        self.assertEqual(qubits_3, [3, 2])