예제 #1
0
    def test_euler_basis_selection(self):
        """Verify decomposition uses euler_basis for 1q gates."""

        euler_bases = [
            ('U3', ['u3']),
            ('U1X', ['u1', 'rx']),
            ('RR', ['r']),
            ('ZYZ', ['rz', 'ry']),
            ('ZXZ', ['rz', 'rx']),
            ('XYX', ['rx', 'ry']),
        ]

        kak_gates = [
            (CXGate(), 'cx'),
            (CZGate(), 'cz'),
            (iSwapGate(), 'iswap'),
            (RXXGate(np.pi / 2), 'rxx'),
        ]

        for basis in product(euler_bases, kak_gates):
            (euler_basis, oneq_gates), (kak_gate, kak_gate_name) = basis

            with self.subTest(euler_basis=euler_basis, kak_gate=kak_gate):
                decomposer = TwoQubitBasisDecomposer(kak_gate,
                                                     euler_basis=euler_basis)
                unitary = random_unitary(4)
                self.check_exact_decomposition(unitary.data, decomposer)

                decomposition_basis = set(decomposer(unitary).count_ops())
                requested_basis = set(oneq_gates + [kak_gate_name])
                self.assertTrue(decomposition_basis.issubset(requested_basis))
    def test_circuit_construction(self):
        """circuit construction test"""
        hadq2 = H ^ I
        cz = hadq2.compose(CX).compose(hadq2)
        qc = QuantumCircuit(2)
        qc.append(cz.primitive, qargs=range(2))

        ref_cz_mat = PrimitiveOp(CZGate()).to_matrix()
        np.testing.assert_array_almost_equal(cz.to_matrix(), ref_cz_mat)
class TestParameterCtrlState(QiskitTestCase):
    """Test gate equality with ctrl_state parameter."""
    @data((RXGate(0.5), CRXGate(0.5)), (RYGate(0.5), CRYGate(0.5)),
          (RZGate(0.5), CRZGate(0.5)), (XGate(), CXGate()),
          (YGate(), CYGate()), (ZGate(), CZGate()),
          (U1Gate(0.5), CU1Gate(0.5)), (SwapGate(), CSwapGate()),
          (HGate(), CHGate()), (U3Gate(0.1, 0.2, 0.3), CU3Gate(0.1, 0.2, 0.3)))
    @unpack
    def test_ctrl_state_one(self, gate, controlled_gate):
        """Test controlled gates with ctrl_state
        See https://github.com/Qiskit/qiskit-terra/pull/4025
        """
        self.assertEqual(gate.control(1, ctrl_state='1'), controlled_gate)
예제 #4
0
    def test_mcmt_v_chain_ancilla_test(self):
        """Test too few and too many ancillas for the MCMT V-chain mode."""
        with self.subTest(msg='insufficient number of ancillas on gate'):
            qc = QuantumCircuit(5)
            mcmt = MCMTVChain(ZGate(), 3, 1)
            with self.assertRaises(QiskitError):
                qc.append(mcmt, [0, 1, 2, 3, 4])

        with self.subTest(msg='insufficient number of ancillas on method'):
            qc = QuantumCircuit(5)
            mcmt = MCMTVChain(ZGate(), 3, 1)
            with self.assertRaises(QiskitError):
                qc.append(mcmt, [0, 1, 2, 3, 4], [])

        with self.subTest(msg='too many ancillas works on method'):
            qc = QuantumCircuit(8)
            qc.mcmt(CZGate(), [0, 1, 2], 3, [4, 5, 6, 7])
예제 #5
0
def random_clifford_circuit(num_qubits, num_gates, gates='all', seed=None):
    """Generate a pseudo random Clifford circuit."""

    if gates == 'all':
        if num_qubits == 1:
            gates = ['i', 'x', 'y', 'z', 'h', 's', 'sdg', 'v', 'w']
        else:
            gates = [
                'i', 'x', 'y', 'z', 'h', 's', 'sdg', 'v', 'w', 'cx', 'cz',
                'swap'
            ]

    instructions = {
        'i': (IGate(), 1),
        'x': (XGate(), 1),
        'y': (YGate(), 1),
        'z': (ZGate(), 1),
        'h': (HGate(), 1),
        's': (SGate(), 1),
        'sdg': (SdgGate(), 1),
        'v': (VGate(), 1),
        'w': (WGate(), 1),
        'cx': (CXGate(), 2),
        'cz': (CZGate(), 2),
        'swap': (SwapGate(), 2)
    }

    if isinstance(seed, np.random.Generator):
        rng = seed
    else:
        rng = np.random.default_rng(seed)

    samples = rng.choice(gates, num_gates)

    circ = QuantumCircuit(num_qubits)

    for name in samples:
        gate, nqargs = instructions[name]
        qargs = rng.choice(range(num_qubits), nqargs, replace=False).tolist()
        circ.append(gate, qargs)

    return circ
예제 #6
0
def random_clifford_circuit(num_qubits, num_gates, gates="all", seed=None):
    """Generate a pseudo random Clifford circuit."""

    if gates == "all":
        if num_qubits == 1:
            gates = ["i", "x", "y", "z", "h", "s", "sdg", "v", "w"]
        else:
            gates = [
                "i", "x", "y", "z", "h", "s", "sdg", "v", "w", "cx", "cz",
                "swap"
            ]

    instructions = {
        "i": (IGate(), 1),
        "x": (XGate(), 1),
        "y": (YGate(), 1),
        "z": (ZGate(), 1),
        "h": (HGate(), 1),
        "s": (SGate(), 1),
        "sdg": (SdgGate(), 1),
        "v": (VGate(), 1),
        "w": (WGate(), 1),
        "cx": (CXGate(), 2),
        "cz": (CZGate(), 2),
        "swap": (SwapGate(), 2),
    }

    if isinstance(seed, np.random.Generator):
        rng = seed
    else:
        rng = np.random.default_rng(seed)

    samples = rng.choice(gates, num_gates)

    circ = QuantumCircuit(num_qubits)

    for name in samples:
        gate, nqargs = instructions[name]
        qargs = rng.choice(range(num_qubits), nqargs, replace=False).tolist()
        circ.append(gate, qargs)

    return circ
예제 #7
0
class TestTwoQubitDecomposeExact(CheckDecompositions):
    """Test TwoQubitBasisDecomposer() for exact decompositions
    """

    def test_cnot_rxx_decompose(self):
        """Verify CNOT decomposition into RXX gate is correct"""
        cnot = Operator(CXGate())
        decomps = [cnot_rxx_decompose(),
                   cnot_rxx_decompose(plus_ry=True, plus_rxx=True),
                   cnot_rxx_decompose(plus_ry=True, plus_rxx=False),
                   cnot_rxx_decompose(plus_ry=False, plus_rxx=True),
                   cnot_rxx_decompose(plus_ry=False, plus_rxx=False)]
        for decomp in decomps:
            self.assertTrue(cnot.equiv(decomp))

    @combine(seed=range(10), name='test_exact_two_qubit_cnot_decompose_random_{seed}')
    def test_exact_two_qubit_cnot_decompose_random(self, seed):
        """Verify exact CNOT decomposition for random Haar 4x4 unitary (seed={seed}).
        """
        unitary = random_unitary(4, seed=seed)
        self.check_exact_decomposition(unitary.data, two_qubit_cnot_decompose)

    def test_exact_two_qubit_cnot_decompose_paulis(self):
        """Verify exact CNOT decomposition for Paulis
        """
        unitary = Operator.from_label('XZ')
        self.check_exact_decomposition(unitary.data, two_qubit_cnot_decompose)

    @combine(seed=range(10), name='test_exact_supercontrolled_decompose_random_{seed}')
    def test_exact_supercontrolled_decompose_random(self, seed):
        """Exact decomposition for random supercontrolled basis and random target (seed={seed})"""
        # pylint: disable=invalid-name
        k1 = np.kron(random_unitary(2, seed=seed).data, random_unitary(2, seed=seed + 1).data)
        k2 = np.kron(random_unitary(2, seed=seed + 2).data, random_unitary(2, seed=seed + 3).data)
        basis_unitary = k1 @ Ud(np.pi / 4, 0, 0) @ k2
        decomposer = TwoQubitBasisDecomposer(UnitaryGate(basis_unitary))
        self.check_exact_decomposition(random_unitary(4, seed=seed + 4).data, decomposer)

    def test_exact_nonsupercontrolled_decompose(self):
        """Check that the nonsupercontrolled basis throws a warning"""
        with self.assertWarns(UserWarning, msg="Supposed to warn when basis non-supercontrolled"):
            TwoQubitBasisDecomposer(UnitaryGate(Ud(np.pi / 4, 0.2, 0.1)))

    def test_cx_equivalence_0cx(self, seed=0):
        """Check circuits with  0 cx gates locally equivalent to identity
        """
        state = np.random.default_rng(seed)
        rnd = 2 * np.pi * state.random(size=6)

        qr = QuantumRegister(2, name='q')
        qc = QuantumCircuit(qr)

        qc.u(rnd[0], rnd[1], rnd[2], qr[0])
        qc.u(rnd[3], rnd[4], rnd[5], qr[1])

        sim = UnitarySimulatorPy()
        unitary = execute(qc, sim).result().get_unitary()
        self.assertEqual(two_qubit_cnot_decompose.num_basis_gates(unitary), 0)
        self.assertTrue(Operator(two_qubit_cnot_decompose(unitary)).equiv(unitary))

    def test_cx_equivalence_1cx(self, seed=1):
        """Check circuits with  1 cx gates locally equivalent to a cx
        """
        state = np.random.default_rng(seed)
        rnd = 2 * np.pi * state.random(size=12)

        qr = QuantumRegister(2, name='q')
        qc = QuantumCircuit(qr)

        qc.u(rnd[0], rnd[1], rnd[2], qr[0])
        qc.u(rnd[3], rnd[4], rnd[5], qr[1])

        qc.cx(qr[1], qr[0])

        qc.u(rnd[6], rnd[7], rnd[8], qr[0])
        qc.u(rnd[9], rnd[10], rnd[11], qr[1])

        sim = UnitarySimulatorPy()
        unitary = execute(qc, sim).result().get_unitary()
        self.assertEqual(two_qubit_cnot_decompose.num_basis_gates(unitary), 1)
        self.assertTrue(Operator(two_qubit_cnot_decompose(unitary)).equiv(unitary))

    def test_cx_equivalence_2cx(self, seed=2):
        """Check circuits with  2 cx gates locally equivalent to some circuit with 2 cx.
        """
        state = np.random.default_rng(seed)
        rnd = 2 * np.pi * state.random(size=18)

        qr = QuantumRegister(2, name='q')
        qc = QuantumCircuit(qr)

        qc.u(rnd[0], rnd[1], rnd[2], qr[0])
        qc.u(rnd[3], rnd[4], rnd[5], qr[1])

        qc.cx(qr[1], qr[0])

        qc.u(rnd[6], rnd[7], rnd[8], qr[0])
        qc.u(rnd[9], rnd[10], rnd[11], qr[1])

        qc.cx(qr[0], qr[1])

        qc.u(rnd[12], rnd[13], rnd[14], qr[0])
        qc.u(rnd[15], rnd[16], rnd[17], qr[1])

        sim = UnitarySimulatorPy()
        unitary = execute(qc, sim).result().get_unitary()
        self.assertEqual(two_qubit_cnot_decompose.num_basis_gates(unitary), 2)
        self.assertTrue(Operator(two_qubit_cnot_decompose(unitary)).equiv(unitary))

    def test_cx_equivalence_3cx(self, seed=3):
        """Check circuits with 3 cx gates are outside the 0, 1, and 2 qubit regions.
        """
        state = np.random.default_rng(seed)
        rnd = 2 * np.pi * state.random(size=24)

        qr = QuantumRegister(2, name='q')
        qc = QuantumCircuit(qr)

        qc.u(rnd[0], rnd[1], rnd[2], qr[0])
        qc.u(rnd[3], rnd[4], rnd[5], qr[1])

        qc.cx(qr[1], qr[0])

        qc.u(rnd[6], rnd[7], rnd[8], qr[0])
        qc.u(rnd[9], rnd[10], rnd[11], qr[1])

        qc.cx(qr[0], qr[1])

        qc.u(rnd[12], rnd[13], rnd[14], qr[0])
        qc.u(rnd[15], rnd[16], rnd[17], qr[1])

        qc.cx(qr[1], qr[0])

        qc.u(rnd[18], rnd[19], rnd[20], qr[0])
        qc.u(rnd[21], rnd[22], rnd[23], qr[1])

        sim = UnitarySimulatorPy()
        unitary = execute(qc, sim).result().get_unitary()
        self.assertEqual(two_qubit_cnot_decompose.num_basis_gates(unitary), 3)
        self.assertTrue(Operator(two_qubit_cnot_decompose(unitary)).equiv(unitary))

    def test_seed_289(self):
        """This specific case failed when PR #3585 was applied
        See https://github.com/Qiskit/qiskit-terra/pull/3652"""
        unitary = random_unitary(4, seed=289)
        self.check_exact_decomposition(unitary.data, two_qubit_cnot_decompose)

    @combine(seed=range(10),
             euler_bases=[('U3', ['u3']), ('U', ['u']), ('U1X', ['u1', 'rx']), ('RR', ['r']),
                          ('PSX', ['p', 'sx']), ('ZYZ', ['rz', 'ry']), ('ZXZ', ['rz', 'rx']),
                          ('XYX', ['rx', 'ry']), ('ZSX', ['rz', 'sx'])],
             kak_gates=[(CXGate(), 'cx'), (CZGate(), 'cz'), (iSwapGate(), 'iswap'),
                        (RXXGate(np.pi / 2), 'rxx')],
             name='test_euler_basis_selection_{seed}_{euler_bases[0]}_{kak_gates[1]}')
    def test_euler_basis_selection(self, euler_bases, kak_gates, seed):
        """Verify decomposition uses euler_basis for 1q gates."""
        (euler_basis, oneq_gates) = euler_bases
        (kak_gate, kak_gate_name) = kak_gates

        with self.subTest(euler_basis=euler_basis, kak_gate=kak_gate):
            decomposer = TwoQubitBasisDecomposer(kak_gate, euler_basis=euler_basis)
            unitary = random_unitary(4, seed=seed)
            self.check_exact_decomposition(unitary.data, decomposer)

            decomposition_basis = set(decomposer(unitary).count_ops())
            requested_basis = set(oneq_gates + [kak_gate_name])
            self.assertTrue(
                decomposition_basis.issubset(requested_basis))
예제 #8
0
def make_immutable(obj):
    """ Delete the __setattr__ property to make the object mostly immutable. """

    # TODO figure out how to get correct error message
    # def throw_immutability_exception(self, *args):
    #     raise OpflowError('Operator convenience globals are immutable.')

    obj.__setattr__ = None
    return obj


# 1-Qubit Paulis
X = make_immutable(PauliOp(Pauli('X')))
Y = make_immutable(PauliOp(Pauli('Y')))
Z = make_immutable(PauliOp(Pauli('Z')))
I = make_immutable(PauliOp(Pauli('I')))

# Clifford+T, and some other common non-parameterized gates
CX = make_immutable(CircuitOp(CXGate()))
S = make_immutable(CircuitOp(SGate()))
H = make_immutable(CircuitOp(HGate()))
T = make_immutable(CircuitOp(TGate()))
Swap = make_immutable(CircuitOp(SwapGate()))
CZ = make_immutable(CircuitOp(CZGate()))

# 1-Qubit Paulis
Zero = make_immutable(StateFn('0'))
One = make_immutable(StateFn('1'))
Plus = make_immutable(H.compose(Zero))
Minus = make_immutable(H.compose(X).compose(Zero))
예제 #9
0
    def test_2_qubit_identities(self):
        """Tests identities for 2-qubit gates"""
        # SI * CX * SdgI = CX
        elem = CNOTDihedral(CXGate())
        circ1 = QuantumCircuit(2)
        circ1.s(0)
        circ1.cx(0, 1)
        circ1.sdg(0)
        elem1 = CNOTDihedral(circ1)
        self.assertEqual(elem, elem1,
                         "Error: 2-qubit CX identity does not hold")

        # SI * CZ * SdgI = CZ
        elem = CNOTDihedral(CZGate())
        circ1 = QuantumCircuit(2)
        circ1.s(0)
        circ1.cz(1, 0)
        circ1.sdg(0)
        elem1 = CNOTDihedral(circ1)
        self.assertEqual(elem, elem1,
                         "Error: 2-qubit CZ identity does not hold")

        # SWAP = CX01 * CX10 * CX01 = CX10 * CX01 * CX10
        elem = CNOTDihedral(SwapGate())
        circ1 = QuantumCircuit(2)
        circ1.cx(0, 1)
        circ1.cx(1, 0)
        circ1.cx(0, 1)
        circ2 = QuantumCircuit(2)
        circ2.cx(1, 0)
        circ2.cx(0, 1)
        circ2.cx(1, 0)
        elem1 = CNOTDihedral(circ1)
        elem2 = CNOTDihedral(circ2)
        self.assertEqual(elem, elem1,
                         "Error: 2-qubit SWAP identity does not hold")
        self.assertEqual(elem1, elem2,
                         "Error: 2-qubit SWAP identity does not hold")

        # CS01 = CS10 (symmetric)
        #
        #      ┌───┐
        # q_0: ┤ T ├──■───────────■──
        #      ├───┤┌─┴─┐┌─────┐┌─┴─┐
        # q_1: ┤ T ├┤ X ├┤ Tdg ├┤ X ├
        #      └───┘└───┘└─────┘└───┘
        circ1 = QuantumCircuit(2)
        circ1.t(0)
        circ1.t(1)
        circ1.cx(0, 1)
        circ1.tdg(1)
        circ1.cx(0, 1)

        #      ┌───┐┌───┐┌─────┐┌───┐
        # q_0: ┤ T ├┤ X ├┤ Tdg ├┤ X ├
        #      ├───┤└─┬─┘└─────┘└─┬─┘
        # q_1: ┤ T ├──■───────────■──
        #      └───┘
        circ2 = QuantumCircuit(2)
        circ2.t(1)
        circ2.t(0)
        circ2.cx(1, 0)
        circ2.tdg(0)
        circ2.cx(1, 0)
        elem1 = CNOTDihedral(circ1)
        elem2 = CNOTDihedral(circ2)
        self.assertEqual(elem1, elem2,
                         "Error: 2-qubit CS identity does not hold")

        # TI*CS*TdgI = CS
        #
        #      ┌───┐┌───┐                 ┌─────┐
        # q_0: ┤ T ├┤ T ├──■───────────■──┤ Tdg ├
        #      ├───┤└───┘┌─┴─┐┌─────┐┌─┴─┐└─────┘
        # q_1: ┤ T ├─────┤ X ├┤ Tdg ├┤ X ├───────
        #      └───┘     └───┘└─────┘└───┘
        circ3 = QuantumCircuit(2)
        circ3.t(0)
        circ3.t(0)
        circ3.t(1)
        circ3.cx(0, 1)
        circ3.tdg(1)
        circ3.cx(0, 1)
        circ3.tdg(0)
        elem3 = CNOTDihedral(circ3)
        self.assertEqual(elem1, elem3,
                         "Error: 2-qubit CS identity does not hold")

        # IT*CS*ITdg = CS
        #
        #      ┌───┐
        # q_0: ┤ T ├───────■───────────■─────────
        #      ├───┤┌───┐┌─┴─┐┌─────┐┌─┴─┐┌─────┐
        # q_1: ┤ T ├┤ T ├┤ X ├┤ Tdg ├┤ X ├┤ Tdg ├
        #      └───┘└───┘└───┘└─────┘└───┘└─────┘
        circ4 = QuantumCircuit(2)
        circ4.t(1)
        circ4.t(0)
        circ4.t(1)
        circ4.cx(0, 1)
        circ4.tdg(1)
        circ4.cx(0, 1)
        circ4.tdg(1)
        elem4 = CNOTDihedral(circ4)
        self.assertEqual(elem1, elem4,
                         "Error: 2-qubit CS identity does not hold")

        # XX*CS*XX*SS = CS
        #
        #      ┌───┐┌───┐                 ┌───┐┌───┐
        # q_0: ┤ X ├┤ T ├──■───────────■──┤ X ├┤ S ├
        #      ├───┤├───┤┌─┴─┐┌─────┐┌─┴─┐├───┤├───┤
        # q_1: ┤ X ├┤ T ├┤ X ├┤ Tdg ├┤ X ├┤ X ├┤ S ├
        #      └───┘└───┘└───┘└─────┘└───┘└───┘└───┘
        circ5 = QuantumCircuit(2)
        circ5.x(0)
        circ5.x(1)
        circ5.t(0)
        circ5.t(1)
        circ5.cx(0, 1)
        circ5.tdg(1)
        circ5.cx(0, 1)
        circ5.x(0)
        circ5.x(1)
        circ5.s(0)
        circ5.s(1)
        elem5 = CNOTDihedral(circ5)
        self.assertEqual(elem1, elem5,
                         "Error: 2-qubit CS identity does not hold")

        # CSdg01 = CSdg10 (symmetric)
        #
        #      ┌─────┐
        # q_0: ┤ Tdg ├──■─────────■──
        #      ├─────┤┌─┴─┐┌───┐┌─┴─┐
        # q_1: ┤ Tdg ├┤ X ├┤ T ├┤ X ├
        #      └─────┘└───┘└───┘└───┘
        circ1 = QuantumCircuit(2)
        circ1.tdg(0)
        circ1.tdg(1)
        circ1.cx(0, 1)
        circ1.t(1)
        circ1.cx(0, 1)

        #      ┌─────┐┌───┐┌───┐┌───┐
        # q_0: ┤ Tdg ├┤ X ├┤ T ├┤ X ├
        #      ├─────┤└─┬─┘└───┘└─┬─┘
        # q_1: ┤ Tdg ├──■─────────■──
        #      └─────┘
        circ2 = QuantumCircuit(2)
        circ2.tdg(1)
        circ2.tdg(0)
        circ2.cx(1, 0)
        circ2.t(0)
        circ2.cx(1, 0)
        elem1 = CNOTDihedral(circ1)
        elem2 = CNOTDihedral(circ2)
        self.assertEqual(elem1, elem2,
                         "Error: 2-qubit CSdg identity does not hold")

        # XI*CS*XI*ISdg = CSdg
        #
        #      ┌───┐┌───┐                  ┌───┐
        # q_0: ┤ X ├┤ T ├──■───────────■───┤ X ├─
        #      ├───┤└───┘┌─┴─┐┌─────┐┌─┴─┐┌┴───┴┐
        # q_1: ┤ T ├─────┤ X ├┤ Tdg ├┤ X ├┤ Sdg ├
        #      └───┘     └───┘└─────┘└───┘└─────┘
        circ3 = QuantumCircuit(2)
        circ3.x(0)
        circ3.t(0)
        circ3.t(1)
        circ3.cx(0, 1)
        circ3.tdg(1)
        circ3.cx(0, 1)
        circ3.x(0)
        circ3.sdg(1)
        elem3 = CNOTDihedral(circ3)
        self.assertEqual(elem1, elem3,
                         "Error: 2-qubit CSdg identity does not hold")

        # IX*CS*IX*SdgI = CSdg
        #
        #      ┌───┐                      ┌─────┐
        # q_0: ┤ T ├───────■───────────■──┤ Sdg ├
        #      ├───┤┌───┐┌─┴─┐┌─────┐┌─┴─┐└┬───┬┘
        # q_1: ┤ X ├┤ T ├┤ X ├┤ Tdg ├┤ X ├─┤ X ├─
        #      └───┘└───┘└───┘└─────┘└───┘ └───┘
        circ4 = QuantumCircuit(2)
        circ4.x(1)
        circ4.t(0)
        circ4.t(1)
        circ4.cx(0, 1)
        circ4.tdg(1)
        circ4.cx(0, 1)
        circ4.x(1)
        circ4.sdg(0)
        elem4 = CNOTDihedral(circ4)
        self.assertEqual(elem1, elem4,
                         "Error: 2-qubit CSdg identity does not hold")

        # relations for CZ
        # CZ(0,1) = CZ(1,0)
        elem = CNOTDihedral(CZGate())
        circ1 = QuantumCircuit(2)
        circ1.cz(0, 1)
        circ2 = QuantumCircuit(2)
        circ2.cz(1, 0)
        elem1 = CNOTDihedral(circ1)
        elem2 = CNOTDihedral(circ2)
        self.assertEqual(elem, elem1,
                         "Error: 2-qubit CZ identity does not hold")
        self.assertEqual(elem1, elem2,
                         "Error: 2-qubit CZ identity does not hold")

        # CZ = CS * CS
        #
        #      ┌───┐                 ┌───┐
        # q_0: ┤ T ├──■───────────■──┤ T ├──■───────────■──
        #      ├───┤┌─┴─┐┌─────┐┌─┴─┐├───┤┌─┴─┐┌─────┐┌─┴─┐
        # q_1: ┤ T ├┤ X ├┤ Tdg ├┤ X ├┤ T ├┤ X ├┤ Tdg ├┤ X ├
        #      └───┘└───┘└─────┘└───┘└───┘└───┘└─────┘└───┘
        circ3 = QuantumCircuit(2)
        circ3.t(0)
        circ3.t(1)
        circ3.cx(0, 1)
        circ3.tdg(1)
        circ3.cx(0, 1)
        circ3.t(0)
        circ3.t(1)
        circ3.cx(0, 1)
        circ3.tdg(1)
        circ3.cx(0, 1)
        elem3 = CNOTDihedral(circ3)
        self.assertEqual(elem1, elem3,
                         "Error: 2-qubit CZ identity does not hold")

        # CZ = CSdg * CSdg
        #
        #      ┌─────┐               ┌─────┐
        # q_0: ┤ Tdg ├──■─────────■──┤ Tdg ├──■─────────■──
        #      ├─────┤┌─┴─┐┌───┐┌─┴─┐├─────┤┌─┴─┐┌───┐┌─┴─┐
        # q_1: ┤ Tdg ├┤ X ├┤ T ├┤ X ├┤ Tdg ├┤ X ├┤ T ├┤ X ├
        #      └─────┘└───┘└───┘└───┘└─────┘└───┘└───┘└───┘
        circ4 = QuantumCircuit(2)
        circ4.tdg(0)
        circ4.tdg(1)
        circ4.cx(0, 1)
        circ4.t(1)
        circ4.cx(0, 1)
        circ4.tdg(0)
        circ4.tdg(1)
        circ4.cx(0, 1)
        circ4.t(1)
        circ4.cx(0, 1)
        elem4 = CNOTDihedral(circ4)
        self.assertEqual(elem1, elem4,
                         "Error: 2-qubit CZ identity does not hold")

        # CZ = TdgTdg * CX * T^2I * CX * TdgTdg
        #
        #      ┌─────┐┌───┐┌───┐┌───┐┌───┐┌─────┐
        # q_0: ┤ Tdg ├┤ X ├┤ T ├┤ T ├┤ X ├┤ Tdg ├
        #      ├─────┤└─┬─┘└───┘└───┘└─┬─┘├─────┤
        # q_1: ┤ Tdg ├──■──────────────■──┤ Tdg ├
        #      └─────┘                    └─────┘
        circ5 = QuantumCircuit(2)
        circ5.tdg(0)
        circ5.tdg(1)
        circ5.cx(1, 0)
        circ5.t(0)
        circ5.t(0)
        circ5.cx(1, 0)
        circ5.tdg(0)
        circ5.tdg(1)
        elem5 = CNOTDihedral(circ5)
        self.assertEqual(elem1, elem5,
                         "Error: 2-qubit CZ identity does not hold")

        # relations for CX
        circ1 = QuantumCircuit(2)
        circ1.cx(0, 1)
        elem1 = CNOTDihedral(circ1)

        # TI*CX*TdgI = CX
        #
        #      ┌───┐     ┌─────┐
        # q_0: ┤ T ├──■──┤ Tdg ├
        #      └───┘┌─┴─┐└─────┘
        # q_1: ─────┤ X ├───────
        #           └───┘
        circ2 = QuantumCircuit(2)
        circ2.t(0)
        circ2.cx(0, 1)
        circ2.tdg(0)
        elem2 = CNOTDihedral(circ2)
        self.assertEqual(elem1, elem2,
                         "Error: 2-qubit CX identity does not hold")

        # IZ*CX*ZZ = CX
        #
        #                ┌───┐
        # q_0: ───────■──┤ Z ├
        #      ┌───┐┌─┴─┐├───┤
        # q_1: ┤ Z ├┤ X ├┤ Z ├
        #      └───┘└───┘└───┘
        circ3 = QuantumCircuit(2)
        circ3.z(1)
        circ3.cx(0, 1)
        circ3.z(0)
        circ3.z(1)
        elem3 = CNOTDihedral(circ3)
        self.assertEqual(elem1, elem3,
                         "Error: 2-qubit CX identity does not hold")

        # IX*CX*IX = CX
        #
        # q_0: ───────■───────
        #      ┌───┐┌─┴─┐┌───┐
        # q_1: ┤ X ├┤ X ├┤ X ├
        #      └───┘└───┘└───┘
        circ4 = QuantumCircuit(2)
        circ4.x(1)
        circ4.cx(0, 1)
        circ4.x(1)
        elem4 = CNOTDihedral(circ4)
        self.assertEqual(elem1, elem4,
                         "Error: 2-qubit CX identity does not hold")

        # XI*CX*XX = CX
        #
        #      ┌───┐     ┌───┐
        # q_0: ┤ X ├──■──┤ X ├
        #      └───┘┌─┴─┐├───┤
        # q_1: ─────┤ X ├┤ X ├
        #           └───┘└───┘
        circ5 = QuantumCircuit(2)
        circ5.x(0)
        circ5.cx(0, 1)
        circ5.x(0)
        circ5.x(1)
        elem5 = CNOTDihedral(circ5)
        self.assertEqual(elem1, elem5,
                         "Error: 2-qubit CX identity does not hold")

        # IT*CX01*CX10*TdgI = CX01*CX10
        #
        #           ┌───┐
        # q_0: ──■──┤ X ├
        #      ┌─┴─┐└─┬─┘
        # q_1: ┤ X ├──■──
        #      └───┘
        circ1 = QuantumCircuit(2)
        circ1.cx(0, 1)
        circ1.cx(1, 0)

        #                ┌───┐┌─────┐
        # q_0: ───────■──┤ X ├┤ Tdg ├
        #      ┌───┐┌─┴─┐└─┬─┘└─────┘
        # q_1: ┤ T ├┤ X ├──■─────────
        #      └───┘└───┘
        circ2 = QuantumCircuit(2)
        circ2.t(1)
        circ2.cx(0, 1)
        circ2.cx(1, 0)
        circ2.tdg(0)
        elem1 = CNOTDihedral(circ1)
        elem2 = CNOTDihedral(circ2)
        self.assertEqual(elem1, elem2,
                         "Error: 2-qubit CX01*CX10 identity does not hold")
예제 #10
0
    def test_2_qubit_identities(self):
        """Tests identities for 2-qubit gates"""
        # SI * CX * SdgI = CX
        elem = CNOTDihedral(CXGate())
        circ1 = QuantumCircuit(2)
        circ1.s(0)
        circ1.cx(0, 1)
        circ1.sdg(0)
        elem1 = CNOTDihedral(circ1)
        self.assertEqual(elem, elem1,
                         "Error: 2-qubit CX identity does not hold")

        # SI * CZ * SdgI = CZ
        elem = CNOTDihedral(CZGate())
        circ1 = QuantumCircuit(2)
        circ1.s(0)
        circ1.cz(1, 0)
        circ1.sdg(0)
        elem1 = CNOTDihedral(circ1)
        self.assertEqual(elem, elem1,
                         "Error: 2-qubit CZ identity does not hold")

        # SWAP = CX01 * CX10 * CX01 = CX10 * CX01 * CX10
        elem = CNOTDihedral(SwapGate())
        circ1 = QuantumCircuit(2)
        circ1.cx(0, 1)
        circ1.cx(1, 0)
        circ1.cx(0, 1)
        circ2 = QuantumCircuit(2)
        circ2.cx(1, 0)
        circ2.cx(0, 1)
        circ2.cx(1, 0)
        elem1 = CNOTDihedral(circ1)
        elem2 = CNOTDihedral(circ2)
        self.assertEqual(elem, elem1,
                         "Error: 2-qubit SWAP identity does not hold")
        self.assertEqual(elem1, elem2,
                         "Error: 2-qubit SWAP identity does not hold")

        # CS01 = CS10 (symmetric)
        circ1 = QuantumCircuit(2)
        circ1.t(0)
        circ1.t(1)
        circ1.cx(0, 1)
        circ1.tdg(1)
        circ1.cx(0, 1)
        circ2 = QuantumCircuit(2)
        circ2.t(1)
        circ2.t(0)
        circ2.cx(1, 0)
        circ2.tdg(0)
        circ2.cx(1, 0)
        elem1 = CNOTDihedral(circ1)
        elem2 = CNOTDihedral(circ2)
        self.assertEqual(elem1, elem2,
                         "Error: 2-qubit CS identity does not hold")

        # TI*CS*TdgI = CS
        circ3 = QuantumCircuit(2)
        circ3.t(0)
        circ3.t(0)
        circ3.t(1)
        circ3.cx(0, 1)
        circ3.tdg(1)
        circ3.cx(0, 1)
        circ3.tdg(0)
        elem3 = CNOTDihedral(circ3)
        self.assertEqual(elem1, elem3,
                         "Error: 2-qubit CS identity does not hold")

        # IT*CS*ITdg = CS
        circ4 = QuantumCircuit(2)
        circ4.t(1)
        circ4.t(0)
        circ4.t(1)
        circ4.cx(0, 1)
        circ4.tdg(1)
        circ4.cx(0, 1)
        circ4.tdg(1)
        elem4 = CNOTDihedral(circ4)
        self.assertEqual(elem1, elem4,
                         "Error: 2-qubit CS identity does not hold")

        # XX*CS*XX*SS = CS
        circ5 = QuantumCircuit(2)
        circ5.x(0)
        circ5.x(1)
        circ5.t(0)
        circ5.t(1)
        circ5.cx(0, 1)
        circ5.tdg(1)
        circ5.cx(0, 1)
        circ5.x(0)
        circ5.x(1)
        circ5.s(0)
        circ5.s(1)
        elem5 = CNOTDihedral(circ5)
        self.assertEqual(elem1, elem5,
                         "Error: 2-qubit CS identity does not hold")

        # CSdg01 = CSdg10 (symmetric)
        circ1 = QuantumCircuit(2)
        circ1.tdg(0)
        circ1.tdg(1)
        circ1.cx(0, 1)
        circ1.t(1)
        circ1.cx(0, 1)
        circ2 = QuantumCircuit(2)
        circ2.tdg(1)
        circ2.tdg(0)
        circ2.cx(1, 0)
        circ2.t(0)
        circ2.cx(1, 0)
        elem1 = CNOTDihedral(circ1)
        elem2 = CNOTDihedral(circ2)
        self.assertEqual(elem1, elem2,
                         "Error: 2-qubit CSdg identity does not hold")

        # XI*CS*XI*ISdg = CSdg
        circ3 = QuantumCircuit(2)
        circ3.x(0)
        circ3.t(0)
        circ3.t(1)
        circ3.cx(0, 1)
        circ3.tdg(1)
        circ3.cx(0, 1)
        circ3.x(0)
        circ3.sdg(1)
        elem3 = CNOTDihedral(circ3)
        self.assertEqual(elem1, elem3,
                         "Error: 2-qubit CSdg identity does not hold")

        # IX*CS*IX*SdgI = CSdg
        circ4 = QuantumCircuit(2)
        circ4.x(1)
        circ4.t(0)
        circ4.t(1)
        circ4.cx(0, 1)
        circ4.tdg(1)
        circ4.cx(0, 1)
        circ4.x(1)
        circ4.sdg(0)
        elem4 = CNOTDihedral(circ4)
        self.assertEqual(elem1, elem4,
                         "Error: 2-qubit CSdg identity does not hold")

        # relations for CZ
        # CZ(0,1) = CZ(1,0)
        elem = CNOTDihedral(CZGate())
        circ1 = QuantumCircuit(2)
        circ1.cz(0, 1)
        circ2 = QuantumCircuit(2)
        circ2.cz(1, 0)
        elem1 = CNOTDihedral(circ1)
        elem2 = CNOTDihedral(circ2)
        self.assertEqual(elem, elem1,
                         "Error: 2-qubit CZ identity does not hold")
        self.assertEqual(elem1, elem2,
                         "Error: 2-qubit CZ identity does not hold")

        # CZ = CS * CS
        circ3 = QuantumCircuit(2)
        circ3.t(0)
        circ3.t(1)
        circ3.cx(0, 1)
        circ3.tdg(1)
        circ3.cx(0, 1)
        circ3.t(0)
        circ3.t(1)
        circ3.cx(0, 1)
        circ3.tdg(1)
        circ3.cx(0, 1)
        elem3 = CNOTDihedral(circ3)
        self.assertEqual(elem1, elem3,
                         "Error: 2-qubit CZ identity does not hold")

        # CZ = CSdg * CSdg
        circ4 = QuantumCircuit(2)
        circ4.tdg(0)
        circ4.tdg(1)
        circ4.cx(0, 1)
        circ4.t(1)
        circ4.cx(0, 1)
        circ4.tdg(0)
        circ4.tdg(1)
        circ4.cx(0, 1)
        circ4.t(1)
        circ4.cx(0, 1)
        elem4 = CNOTDihedral(circ4)
        self.assertEqual(elem1, elem4,
                         "Error: 2-qubit CZ identity does not hold")

        # CZ = TdgTdg * CX * T^2I * CX * TdgTdg
        circ5 = QuantumCircuit(2)
        circ5.tdg(0)
        circ5.tdg(1)
        circ5.cx(1, 0)
        circ5.t(0)
        circ5.t(0)
        circ5.cx(1, 0)
        circ5.tdg(0)
        circ5.tdg(1)
        elem5 = CNOTDihedral(circ5)
        self.assertEqual(elem1, elem5,
                         "Error: 2-qubit CZ identity does not hold")

        # relations for CX
        circ1 = QuantumCircuit(2)
        circ1.cx(0, 1)
        elem1 = CNOTDihedral(circ1)

        # TI*CX*TdgI = CX
        circ2 = QuantumCircuit(2)
        circ2.t(0)
        circ2.cx(0, 1)
        circ2.tdg(0)
        elem2 = CNOTDihedral(circ2)
        self.assertEqual(elem1, elem2,
                         "Error: 2-qubit CX identity does not hold")

        # IZ*CX*ZZ = CX
        circ3 = QuantumCircuit(2)
        circ3.z(1)
        circ3.cx(0, 1)
        circ3.z(0)
        circ3.z(1)
        elem3 = CNOTDihedral(circ3)
        self.assertEqual(elem1, elem3,
                         "Error: 2-qubit CX identity does not hold")

        # IX*CX*IX = CX
        circ4 = QuantumCircuit(2)
        circ4.x(1)
        circ4.cx(0, 1)
        circ4.x(1)
        elem4 = CNOTDihedral(circ4)
        self.assertEqual(elem1, elem4,
                         "Error: 2-qubit CX identity does not hold")

        # XI*CX*XX = CX
        circ5 = QuantumCircuit(2)
        circ5.x(0)
        circ5.cx(0, 1)
        circ5.x(0)
        circ5.x(1)
        elem5 = CNOTDihedral(circ5)
        self.assertEqual(elem1, elem5,
                         "Error: 2-qubit CX identity does not hold")

        # IT*CX01*CX10*TdgI = CX01*CX10
        circ1 = QuantumCircuit(2)
        circ1.cx(0, 1)
        circ1.cx(1, 0)
        circ2 = QuantumCircuit(2)
        circ2.t(1)
        circ2.cx(0, 1)
        circ2.cx(1, 0)
        circ2.tdg(0)
        elem1 = CNOTDihedral(circ1)
        elem2 = CNOTDihedral(circ2)
        self.assertEqual(elem1, elem2,
                         "Error: 2-qubit CX01*CX10 identity does not hold")
class TestPauli(QiskitTestCase):
    """Tests for Pauli operator class."""
    @data(*pauli_group_labels(2))
    def test_conjugate(self, label):
        """Test conjugate method."""
        value = Pauli(label).conjugate()
        target = operator_from_label(label).conjugate()
        self.assertEqual(Operator(value), target)

    @data(*pauli_group_labels(2))
    def test_transpose(self, label):
        """Test transpose method."""
        value = Pauli(label).transpose()
        target = operator_from_label(label).transpose()
        self.assertEqual(Operator(value), target)

    @data(*pauli_group_labels(2))
    def test_adjoint(self, label):
        """Test adjoint method."""
        value = Pauli(label).adjoint()
        target = operator_from_label(label).adjoint()
        self.assertEqual(Operator(value), target)

    @data(*pauli_group_labels(2))
    def test_inverse(self, label):
        """Test inverse method."""
        pauli = Pauli(label)
        value = pauli.inverse()
        target = pauli.adjoint()
        self.assertEqual(value, target)

    @data(*it.product(pauli_group_labels(2, full_group=False), repeat=2))
    @unpack
    def test_dot(self, label1, label2):
        """Test dot method."""
        p1 = Pauli(label1)
        p2 = Pauli(label2)
        value = Operator(p1.dot(p2))
        op1 = operator_from_label(label1)
        op2 = operator_from_label(label2)
        target = op1.dot(op2)
        self.assertEqual(value, target)

    @data(*pauli_group_labels(1))
    def test_dot_qargs(self, label2):
        """Test dot method with qargs."""
        label1 = '-iXYZ'
        p1 = Pauli(label1)
        p2 = Pauli(label2)
        qargs = [0]
        value = Operator(p1.dot(p2, qargs=qargs))
        op1 = operator_from_label(label1)
        op2 = operator_from_label(label2)
        target = op1.dot(op2, qargs=qargs)
        self.assertEqual(value, target)

    @data(*it.product(pauli_group_labels(2, full_group=False), repeat=2))
    @unpack
    def test_compose(self, label1, label2):
        """Test compose method."""
        p1 = Pauli(label1)
        p2 = Pauli(label2)
        value = Operator(p1.compose(p2))
        op1 = operator_from_label(label1)
        op2 = operator_from_label(label2)
        target = op1.compose(op2)
        self.assertEqual(value, target)

    @data(*pauli_group_labels(1))
    def test_compose_qargs(self, label2):
        """Test compose method with qargs."""
        label1 = '-XYZ'
        p1 = Pauli(label1)
        p2 = Pauli(label2)
        qargs = [0]
        value = Operator(p1.compose(p2, qargs=qargs))
        op1 = operator_from_label(label1)
        op2 = operator_from_label(label2)
        target = op1.compose(op2, qargs=qargs)
        self.assertEqual(value, target)

    @data(*it.product(pauli_group_labels(1, full_group=False), repeat=2))
    @unpack
    def test_tensor(self, label1, label2):
        """Test tensor method."""
        p1 = Pauli(label1)
        p2 = Pauli(label2)
        value = Operator(p1.tensor(p2))
        op1 = operator_from_label(label1)
        op2 = operator_from_label(label2)
        target = op1.tensor(op2)
        self.assertEqual(value, target)

    @data(*it.product(pauli_group_labels(1, full_group=False), repeat=2))
    @unpack
    def test_expand(self, label1, label2):
        """Test expand method."""
        p1 = Pauli(label1)
        p2 = Pauli(label2)
        value = Operator(p1.expand(p2))
        op1 = operator_from_label(label1)
        op2 = operator_from_label(label2)
        target = op1.expand(op2)
        self.assertEqual(value, target)

    @data('II', 'XI', 'YX', 'ZZ', 'YZ')
    def test_power(self, label):
        """Test power method."""
        iden = Pauli('II')
        op = Pauli(label)
        self.assertTrue(op**2, iden)

    @data(1, 1.0, -1, -1.0, 1j, -1j)
    def test_multiply(self, val):
        """Test multiply method."""
        op = val * Pauli(([True, True], [False, False], 0))
        phase = (-1j)**op.phase
        self.assertEqual(phase, val)

    def test_multiply_except(self):
        """Test multiply method raises exceptions."""
        op = Pauli('XYZ')
        self.assertRaises(QiskitError, op._multiply, 2)

    @data(0, 1, 2, 3)
    def test_negate(self, phase):
        """Test negate method"""
        op = Pauli(([False], [True], phase))
        neg = -op
        self.assertTrue(op.equiv(neg))
        self.assertEqual(neg.phase, (op.phase + 2) % 4)

    @data(*it.product(pauli_group_labels(1, False), repeat=2))
    @unpack
    def test_commutes(self, p1, p2):
        """Test commutes method"""
        P1 = Pauli(p1)
        P2 = Pauli(p2)
        self.assertEqual(P1.commutes(P2), P1.dot(P2) == P2.dot(P1))

    @data(*it.product(pauli_group_labels(1, False), repeat=2))
    @unpack
    def test_anticommutes(self, p1, p2):
        """Test anticommutes method"""
        P1 = Pauli(p1)
        P2 = Pauli(p2)
        self.assertEqual(P1.anticommutes(P2), P1.dot(P2) == -P2.dot(P1))

    @data(*it.product(
        (IGate(), XGate(), YGate(), ZGate(), HGate(), SGate(), SdgGate()),
        pauli_group_labels(1, False)))
    @unpack
    def test_evolve_clifford1(self, gate, label):
        """Test evolve method for 1-qubit Clifford gates."""
        cliff = Clifford(gate)
        op = Operator(gate)
        pauli = Pauli(label)
        value = Operator(pauli.evolve(cliff))
        target = op.adjoint().dot(pauli).dot(op)
        self.assertEqual(value, target)

    @data(*it.product((CXGate(), CYGate(), CZGate(), SwapGate()),
                      pauli_group_labels(2, False)))
    @unpack
    def test_evolve_clifford2(self, gate, label):
        """Test evolve method for 2-qubit Clifford gates."""
        cliff = Clifford(gate)
        op = Operator(gate)
        pauli = Pauli(label)
        value = Operator(pauli.evolve(cliff))
        target = op.adjoint().dot(pauli).dot(op)
        self.assertEqual(value, target)

    def test_evolve_clifford_qargs(self):
        """Test evolve method for random Clifford"""
        cliff = random_clifford(3, seed=10)
        op = Operator(cliff)
        pauli = random_pauli(5, seed=10)
        qargs = [3, 0, 1]
        value = Operator(pauli.evolve(cliff, qargs=qargs))
        target = Operator(pauli).compose(op.adjoint(),
                                         qargs=qargs).dot(op, qargs=qargs)
        self.assertEqual(value, target)
예제 #12
0
def make_immutable(obj):
    """ Delete the __setattr__ property to make the object mostly immutable. """

    # TODO figure out how to get correct error message
    # def throw_immutability_exception(self, *args):
    #     raise AquaError('Operator convenience globals are immutable.')

    obj.__setattr__ = None
    return obj


# 1-Qubit Paulis
X = make_immutable(PauliOp(Pauli('X')))
Y = make_immutable(PauliOp(Pauli('Y')))
Z = make_immutable(PauliOp(Pauli('Z')))
I = make_immutable(PauliOp(Pauli('I')))

# Clifford+T, and some other common non-parameterized gates
CX = make_immutable(PrimitiveOp(CXGate()))
S = make_immutable(PrimitiveOp(SGate()))
H = make_immutable(PrimitiveOp(HGate()))
T = make_immutable(PrimitiveOp(TGate()))
Swap = make_immutable(PrimitiveOp(SwapGate()))
CZ = make_immutable(PrimitiveOp(CZGate()))

# 1-Qubit Paulis
Zero = make_immutable(StateFn('0'))
One = make_immutable(StateFn('1'))
Plus = make_immutable(H.compose(Zero))
Minus = make_immutable(H.compose(X).compose(Zero))
 def test_controlled_z(self):
     """Test creation of controlled z gate"""
     self.assertEqual(ZGate().control(), CZGate())
예제 #14
0
class TestPauli(QiskitTestCase):
    """Tests for Pauli operator class."""
    @data(*pauli_group_labels(2))
    def test_conjugate(self, label):
        """Test conjugate method."""
        value = Pauli(label).conjugate()
        target = operator_from_label(label).conjugate()
        self.assertEqual(Operator(value), target)

    @data(*pauli_group_labels(2))
    def test_transpose(self, label):
        """Test transpose method."""
        value = Pauli(label).transpose()
        target = operator_from_label(label).transpose()
        self.assertEqual(Operator(value), target)

    @data(*pauli_group_labels(2))
    def test_adjoint(self, label):
        """Test adjoint method."""
        value = Pauli(label).adjoint()
        target = operator_from_label(label).adjoint()
        self.assertEqual(Operator(value), target)

    @data(*pauli_group_labels(2))
    def test_inverse(self, label):
        """Test inverse method."""
        pauli = Pauli(label)
        value = pauli.inverse()
        target = pauli.adjoint()
        self.assertEqual(value, target)

    @data(*it.product(pauli_group_labels(2, full_group=False), repeat=2))
    @unpack
    def test_dot(self, label1, label2):
        """Test dot method."""
        p1 = Pauli(label1)
        p2 = Pauli(label2)
        value = Operator(p1.dot(p2))
        op1 = operator_from_label(label1)
        op2 = operator_from_label(label2)
        target = op1.dot(op2)
        self.assertEqual(value, target)

    @data(*pauli_group_labels(1))
    def test_dot_qargs(self, label2):
        """Test dot method with qargs."""
        label1 = "-iXYZ"
        p1 = Pauli(label1)
        p2 = Pauli(label2)
        qargs = [0]
        value = Operator(p1.dot(p2, qargs=qargs))
        op1 = operator_from_label(label1)
        op2 = operator_from_label(label2)
        target = op1.dot(op2, qargs=qargs)
        self.assertEqual(value, target)

    @data(*it.product(pauli_group_labels(2, full_group=False), repeat=2))
    @unpack
    def test_compose(self, label1, label2):
        """Test compose method."""
        p1 = Pauli(label1)
        p2 = Pauli(label2)
        value = Operator(p1.compose(p2))
        op1 = operator_from_label(label1)
        op2 = operator_from_label(label2)
        target = op1.compose(op2)
        self.assertEqual(value, target)

    @data(*pauli_group_labels(1))
    def test_compose_qargs(self, label2):
        """Test compose method with qargs."""
        label1 = "-XYZ"
        p1 = Pauli(label1)
        p2 = Pauli(label2)
        qargs = [0]
        value = Operator(p1.compose(p2, qargs=qargs))
        op1 = operator_from_label(label1)
        op2 = operator_from_label(label2)
        target = op1.compose(op2, qargs=qargs)
        self.assertEqual(value, target)

    @data(*it.product(pauli_group_labels(1, full_group=False), repeat=2))
    @unpack
    def test_tensor(self, label1, label2):
        """Test tensor method."""
        p1 = Pauli(label1)
        p2 = Pauli(label2)
        value = Operator(p1.tensor(p2))
        op1 = operator_from_label(label1)
        op2 = operator_from_label(label2)
        target = op1.tensor(op2)
        self.assertEqual(value, target)

    @data(*it.product(pauli_group_labels(1, full_group=False), repeat=2))
    @unpack
    def test_expand(self, label1, label2):
        """Test expand method."""
        p1 = Pauli(label1)
        p2 = Pauli(label2)
        value = Operator(p1.expand(p2))
        op1 = operator_from_label(label1)
        op2 = operator_from_label(label2)
        target = op1.expand(op2)
        self.assertEqual(value, target)

    @data("II", "XI", "YX", "ZZ", "YZ")
    def test_power(self, label):
        """Test power method."""
        iden = Pauli("II")
        op = Pauli(label)
        self.assertTrue(op**2, iden)

    @data(1, 1.0, -1, -1.0, 1j, -1j)
    def test_multiply(self, val):
        """Test multiply method."""
        op = val * Pauli(([True, True], [False, False], 0))
        phase = (-1j)**op.phase
        self.assertEqual(phase, val)

    def test_multiply_except(self):
        """Test multiply method raises exceptions."""
        op = Pauli("XYZ")
        self.assertRaises(QiskitError, op._multiply, 2)

    @data(0, 1, 2, 3)
    def test_negate(self, phase):
        """Test negate method"""
        op = Pauli(([False], [True], phase))
        neg = -op
        self.assertTrue(op.equiv(neg))
        self.assertEqual(neg.phase, (op.phase + 2) % 4)

    @data(*it.product(pauli_group_labels(1, False), repeat=2))
    @unpack
    def test_commutes(self, p1, p2):
        """Test commutes method"""
        P1 = Pauli(p1)
        P2 = Pauli(p2)
        self.assertEqual(P1.commutes(P2), P1.dot(P2) == P2.dot(P1))

    @data(*it.product(pauli_group_labels(1, False), repeat=2))
    @unpack
    def test_anticommutes(self, p1, p2):
        """Test anticommutes method"""
        P1 = Pauli(p1)
        P2 = Pauli(p2)
        self.assertEqual(P1.anticommutes(P2), P1.dot(P2) == -P2.dot(P1))

    @data(*it.product(
        (IGate(), XGate(), YGate(), ZGate(), HGate(), SGate(), SdgGate()),
        pauli_group_labels(1, False),
    ))
    @unpack
    def test_evolve_clifford1(self, gate, label):
        """Test evolve method for 1-qubit Clifford gates."""
        op = Operator(gate)
        pauli = Pauli(label)
        value = Operator(pauli.evolve(gate))
        value_h = Operator(pauli.evolve(gate, frame="h"))
        value_s = Operator(pauli.evolve(gate, frame="s"))
        value_inv = Operator(pauli.evolve(gate.inverse()))
        target = op.adjoint().dot(pauli).dot(op)
        self.assertEqual(value, target)
        self.assertEqual(value, value_h)
        self.assertEqual(value_inv, value_s)

    @data(*it.product((CXGate(), CYGate(), CZGate(), SwapGate()),
                      pauli_group_labels(2, False)))
    @unpack
    def test_evolve_clifford2(self, gate, label):
        """Test evolve method for 2-qubit Clifford gates."""
        op = Operator(gate)
        pauli = Pauli(label)
        value = Operator(pauli.evolve(gate))
        value_h = Operator(pauli.evolve(gate, frame="h"))
        value_s = Operator(pauli.evolve(gate, frame="s"))
        value_inv = Operator(pauli.evolve(gate.inverse()))
        target = op.adjoint().dot(pauli).dot(op)
        self.assertEqual(value, target)
        self.assertEqual(value, value_h)
        self.assertEqual(value_inv, value_s)

    def test_evolve_clifford_qargs(self):
        """Test evolve method for random Clifford"""
        cliff = random_clifford(3, seed=10)
        op = Operator(cliff)
        pauli = random_pauli(5, seed=10)
        qargs = [3, 0, 1]
        value = Operator(pauli.evolve(cliff, qargs=qargs))
        value_h = Operator(pauli.evolve(cliff, qargs=qargs, frame="h"))
        value_s = Operator(pauli.evolve(cliff, qargs=qargs, frame="s"))
        value_inv = Operator(pauli.evolve(cliff.adjoint(), qargs=qargs))
        target = Operator(pauli).compose(op.adjoint(),
                                         qargs=qargs).dot(op, qargs=qargs)
        self.assertEqual(value, target)
        self.assertEqual(value, value_h)
        self.assertEqual(value_inv, value_s)

    def test_barrier_delay_sim(self):
        """Test barrier and delay instructions can be simulated"""
        target_circ = QuantumCircuit(2)
        target_circ.x(0)
        target_circ.y(1)
        target = Pauli(target_circ)

        circ = QuantumCircuit(2)
        circ.x(0)
        circ.delay(100, 0)
        circ.barrier([0, 1])
        circ.y(1)
        value = Pauli(circ)
        self.assertEqual(value, target)
예제 #15
0
class TestMCMT(QiskitTestCase):
    """Test the multi-controlled multi-target circuit."""

    @data(MCMT, MCMTVChain)
    def test_mcmt_label(self, mcmt_class):
        """Test MCMT label remains functional but is deprecated."""
        custom_label = "abc"
        with self.subTest(msg="init with label and get"):
            with self.assertWarns(DeprecationWarning):
                mcmt = mcmt_class(
                    XGate(), num_ctrl_qubits=1, num_target_qubits=1, label=custom_label
                )
            with self.assertWarns(DeprecationWarning):
                self.assertEqual(mcmt.label, custom_label)

        with self.subTest(msg="label set and get"):
            mcmt = mcmt_class(XGate(), num_ctrl_qubits=1, num_target_qubits=1)
            with self.assertWarns(DeprecationWarning):
                mcmt.label = custom_label
            with self.assertWarns(DeprecationWarning):
                self.assertEqual(mcmt.label, custom_label)

        with self.subTest(msg="control gate label"):
            mcmt = mcmt_class(XGate(), num_ctrl_qubits=1, num_target_qubits=1)
            c_mcmt = mcmt.control()
            with self.assertWarns(DeprecationWarning):
                c_mcmt = mcmt.control(label=custom_label)
            with self.assertWarns(DeprecationWarning):
                self.assertEqual(c_mcmt.label, custom_label)

    @data(MCMT, MCMTVChain)
    def test_mcmt_as_normal_control(self, mcmt_class):
        """Test that the MCMT can act as normal control gate."""
        qc = QuantumCircuit(2)
        mcmt = mcmt_class(gate=CHGate(), num_ctrl_qubits=1, num_target_qubits=1)
        qc = qc.compose(mcmt, [0, 1])

        ref = QuantumCircuit(2)
        ref.ch(0, 1)

        self.assertEqual(qc, ref)

    def test_missing_qubits(self):
        """Test that an error is raised if qubits are missing."""
        with self.subTest(msg="no control qubits"):
            with self.assertRaises(AttributeError):
                _ = MCMT(XGate(), num_ctrl_qubits=0, num_target_qubits=1)

        with self.subTest(msg="no target qubits"):
            with self.assertRaises(AttributeError):
                _ = MCMT(ZGate(), num_ctrl_qubits=4, num_target_qubits=0)

    def test_different_gate_types(self):
        """Test the different supported input types for the target gate."""
        x_circ = QuantumCircuit(1)
        x_circ.x(0)
        for input_gate in [x_circ, QuantumCircuit.cx, QuantumCircuit.x, "cx", "x", CXGate()]:
            with self.subTest(input_gate=input_gate):
                mcmt = MCMT(input_gate, 2, 2)
                if isinstance(input_gate, QuantumCircuit):
                    self.assertEqual(mcmt.gate.definition[0][0], XGate())
                    self.assertEqual(len(mcmt.gate.definition), 1)
                else:
                    self.assertEqual(mcmt.gate, XGate())

    def test_mcmt_v_chain_ancilla_test(self):
        """Test too few and too many ancillas for the MCMT V-chain mode."""
        with self.subTest(msg="insufficient number of auxiliary qubits on gate"):
            qc = QuantumCircuit(5)
            mcmt = MCMTVChain(ZGate(), 3, 1)
            with self.assertRaises(QiskitError):
                qc.append(mcmt, range(5))

        with self.subTest(msg="too many auxiliary qubits on gate"):
            qc = QuantumCircuit(9)
            mcmt = MCMTVChain(ZGate(), 3, 1)
            with self.assertRaises(QiskitError):
                qc.append(mcmt, range(9))

    @data(
        [CZGate(), 1, 1],
        [CHGate(), 1, 1],
        [CZGate(), 3, 3],
        [CHGate(), 3, 3],
        [CZGate(), 1, 5],
        [CHGate(), 1, 5],
        [CZGate(), 5, 1],
        [CHGate(), 5, 1],
    )
    @unpack
    def test_mcmt_v_chain_simulation(self, cgate, num_controls, num_targets):
        """Test the MCMT V-chain implementation test on a simulation."""
        controls = QuantumRegister(num_controls)
        targets = QuantumRegister(num_targets)

        subsets = [tuple(range(i)) for i in range(num_controls + 1)]
        for subset in subsets:
            qc = QuantumCircuit(targets, controls)
            # Initialize all targets to 1, just to be sure that
            # the generic gate has some effect (f.e. Z gate has no effect
            # on a 0 state)
            qc.x(targets)

            num_ancillas = max(0, num_controls - 1)

            if num_ancillas > 0:
                ancillas = QuantumRegister(num_ancillas)
                qc.add_register(ancillas)
                qubits = controls[:] + targets[:] + ancillas[:]
            else:
                qubits = controls[:] + targets[:]

            for i in subset:
                qc.x(controls[i])

            mcmt = MCMTVChain(cgate, num_controls, num_targets)
            qc.compose(mcmt, qubits, inplace=True)

            for i in subset:
                qc.x(controls[i])

            vec = Statevector.from_label("0" * qc.num_qubits).evolve(qc)

            # target register is initially |11...1>, with length equal to 2**(n_targets)
            vec_exp = np.array([0] * (2 ** (num_targets) - 1) + [1])

            if isinstance(cgate, CZGate):
                # Z gate flips the last qubit only if it's applied an odd number of times
                if len(subset) == num_controls and (num_controls % 2) == 1:
                    vec_exp[-1] = -1
            elif isinstance(cgate, CHGate):
                # if all the control qubits have been activated,
                # we repeatedly apply the kronecker product of the Hadamard
                # with itself and then multiply the results for the original
                # state of the target qubits
                if len(subset) == num_controls:
                    h_i = 1 / np.sqrt(2) * np.array([[1, 1], [1, -1]])
                    h_tot = np.array([1])
                    for _ in range(num_targets):
                        h_tot = np.kron(h_tot, h_i)
                    vec_exp = np.dot(h_tot, vec_exp)
            else:
                raise ValueError(f"Test not implement for gate: {cgate}")

            # append the remaining part of the state
            vec_exp = np.concatenate(
                (vec_exp, [0] * (2 ** (num_controls + num_ancillas + num_targets) - vec_exp.size))
            )
            f_i = state_fidelity(vec, vec_exp)
            self.assertAlmostEqual(f_i, 1)
예제 #16
0
class TestRBUtilities(QiskitExperimentsTestCase):
    """
    A test class for additional functionality provided by the StandardRB
    class.
    """

    instructions = {
        "i": IGate(),
        "x": XGate(),
        "y": YGate(),
        "z": ZGate(),
        "h": HGate(),
        "s": SGate(),
        "sdg": SdgGate(),
        "cx": CXGate(),
        "cz": CZGate(),
        "swap": SwapGate(),
    }
    seed = 42

    @data(
        [1, {((0,), "x"): 3, ((0,), "y"): 2, ((0,), "h"): 1}],
        [5, {((1,), "x"): 3, ((4,), "y"): 2, ((1,), "h"): 1, ((1, 4), "cx"): 7}],
    )
    @unpack
    def test_count_ops(self, num_qubits, expected_counts):
        """Testing the count_ops utility function
        this function receives a circuit and counts the number of gates
        in it, counting gates for different qubits separately"""
        circuit = QuantumCircuit(num_qubits)
        gates_to_add = []
        for gate, count in expected_counts.items():
            gates_to_add += [gate for _ in range(count)]
        rng = np.random.default_rng(self.seed)
        rng.shuffle(gates_to_add)
        for qubits, gate in gates_to_add:
            circuit.append(self.instructions[gate], qubits)
        counts = rb.RBUtils.count_ops(circuit)
        self.assertDictEqual(expected_counts, counts)

    def test_calculate_1q_epg(self):
        """Testing the calculation of 1 qubit error per gate
        The EPG is computed based on the error per clifford determined
        in the RB experiment, the gate counts, and an estimate about the
        relations between the errors of different gate types
        """
        epc_1_qubit = FitVal(0.0037, 0)
        qubits = [0]
        gate_error_ratio = {((0,), "id"): 1, ((0,), "rz"): 0, ((0,), "sx"): 1, ((0,), "x"): 1}
        gates_per_clifford = {((0,), "rz"): 10.5, ((0,), "sx"): 8.15, ((0,), "x"): 0.25}
        epg = rb.RBUtils.calculate_1q_epg(epc_1_qubit, qubits, gate_error_ratio, gates_per_clifford)
        error_dict = {
            ((0,), "rz"): FitVal(0, 0),
            ((0,), "sx"): FitVal(0.0004432101747785104, 0),
            ((0,), "x"): FitVal(0.0004432101747785104, 0),
        }

        for gate in ["x", "sx", "rz"]:
            expected_epg = error_dict[((0,), gate)]
            actual_epg = epg[(0,)][gate]
            self.assertTrue(np.allclose(expected_epg.value, actual_epg.value, atol=0.001))
            self.assertTrue(np.allclose(expected_epg.stderr, actual_epg.stderr, atol=0.001))

    def test_calculate_2q_epg(self):
        """Testing the calculation of 2 qubit error per gate
        The EPG is computed based on the error per clifford determined
        in the RB experiment, the gate counts, and an estimate about the
        relations between the errors of different gate types
        """
        epc_2_qubit = FitVal(0.034184849962675984, 0)
        qubits = [1, 4]
        gate_error_ratio = {
            ((1,), "id"): 1,
            ((4,), "id"): 1,
            ((1,), "rz"): 0,
            ((4,), "rz"): 0,
            ((1,), "sx"): 1,
            ((4,), "sx"): 1,
            ((1,), "x"): 1,
            ((4,), "x"): 1,
            ((4, 1), "cx"): 1,
            ((1, 4), "cx"): 1,
        }
        gates_per_clifford = {
            ((1, 4), "barrier"): 1.032967032967033,
            ((1,), "rz"): 15.932967032967033,
            ((1,), "sx"): 12.382417582417583,
            ((4,), "rz"): 18.681946624803768,
            ((4,), "sx"): 14.522605965463109,
            ((1, 4), "cx"): 1.0246506515936569,
            ((4, 1), "cx"): 0.5212064090480678,
            ((4,), "x"): 0.24237661112857592,
            ((1,), "measure"): 0.01098901098901099,
            ((4,), "measure"): 0.01098901098901099,
            ((1,), "x"): 0.2525918944392083,
        }
        epg_1_qubit = [
            AnalysisResultData("EPG_rz", 0.0, device_components=[1]),
            AnalysisResultData("EPG_rz", 0.0, device_components=[4]),
            AnalysisResultData("EPG_sx", 0.00036207066403884814, device_components=[1]),
            AnalysisResultData("EPG_sx", 0.0005429962529239195, device_components=[4]),
            AnalysisResultData("EPG_x", 0.00036207066403884814, device_components=[1]),
            AnalysisResultData("EPG_x", 0.0005429962529239195, device_components=[4]),
        ]
        epg = rb.RBUtils.calculate_2q_epg(
            epc_2_qubit, qubits, gate_error_ratio, gates_per_clifford, epg_1_qubit
        )

        error_dict = {
            ((1, 4), "cx"): FitVal(0.012438847900902494, 0),
        }

        expected_epg = error_dict[((1, 4), "cx")]
        actual_epg = epg[(1, 4)]["cx"]
        self.assertTrue(np.allclose(expected_epg.value, actual_epg.value, atol=0.001))
        self.assertTrue(np.allclose(expected_epg.stderr, actual_epg.stderr, atol=0.001))

    def test_coherence_limit(self):
        """Test coherence_limit."""
        t1 = 100.0
        t2 = 100.0
        gate_2_qubits = 0.5
        gate_1_qubit = 0.1
        twoq_coherence_err = rb.RBUtils.coherence_limit(2, [t1, t1], [t2, t2], gate_2_qubits)

        oneq_coherence_err = rb.RBUtils.coherence_limit(1, [t1], [t2], gate_1_qubit)

        self.assertAlmostEqual(oneq_coherence_err, 0.00049975, 6, "Error: 1Q Coherence Limit")

        self.assertAlmostEqual(twoq_coherence_err, 0.00597, 5, "Error: 2Q Coherence Limit")

    def test_clifford_1_qubit_generation(self):
        """Verify 1-qubit clifford indeed generates the correct group"""
        clifford_dicts = [
            {"stabilizer": ["+Z"], "destabilizer": ["+X"]},
            {"stabilizer": ["+X"], "destabilizer": ["+Z"]},
            {"stabilizer": ["+Y"], "destabilizer": ["+X"]},
            {"stabilizer": ["+X"], "destabilizer": ["+Y"]},
            {"stabilizer": ["+Z"], "destabilizer": ["+Y"]},
            {"stabilizer": ["+Y"], "destabilizer": ["+Z"]},
            {"stabilizer": ["-Z"], "destabilizer": ["+X"]},
            {"stabilizer": ["+X"], "destabilizer": ["-Z"]},
            {"stabilizer": ["-Y"], "destabilizer": ["+X"]},
            {"stabilizer": ["+X"], "destabilizer": ["-Y"]},
            {"stabilizer": ["-Z"], "destabilizer": ["-Y"]},
            {"stabilizer": ["-Y"], "destabilizer": ["-Z"]},
            {"stabilizer": ["-Z"], "destabilizer": ["-X"]},
            {"stabilizer": ["-X"], "destabilizer": ["-Z"]},
            {"stabilizer": ["+Y"], "destabilizer": ["-X"]},
            {"stabilizer": ["-X"], "destabilizer": ["+Y"]},
            {"stabilizer": ["-Z"], "destabilizer": ["+Y"]},
            {"stabilizer": ["+Y"], "destabilizer": ["-Z"]},
            {"stabilizer": ["+Z"], "destabilizer": ["-X"]},
            {"stabilizer": ["-X"], "destabilizer": ["+Z"]},
            {"stabilizer": ["-Y"], "destabilizer": ["-X"]},
            {"stabilizer": ["-X"], "destabilizer": ["-Y"]},
            {"stabilizer": ["+Z"], "destabilizer": ["-Y"]},
            {"stabilizer": ["-Y"], "destabilizer": ["+Z"]},
        ]
        cliffords = [Clifford.from_dict(i) for i in clifford_dicts]
        utils = rb.CliffordUtils()
        for n in range(24):
            clifford = utils.clifford_1_qubit(n)
            self.assertEqual(clifford, cliffords[n])

    def test_clifford_2_qubit_generation(self):
        """Verify 2-qubit clifford indeed generates the correct group"""
        utils = rb.CliffordUtils()
        pauli_free_elements = [
            0,
            1,
            2,
            3,
            4,
            5,
            6,
            7,
            8,
            9,
            10,
            11,
            12,
            13,
            14,
            15,
            16,
            17,
            18,
            19,
            20,
            21,
            22,
            23,
            24,
            25,
            26,
            27,
            28,
            29,
            30,
            31,
            32,
            33,
            34,
            35,
            576,
            577,
            578,
            579,
            580,
            581,
            582,
            583,
            584,
            585,
            586,
            587,
            588,
            589,
            590,
            591,
            592,
            593,
            594,
            595,
            596,
            597,
            598,
            599,
            600,
            601,
            602,
            603,
            604,
            605,
            606,
            607,
            608,
            609,
            610,
            611,
            612,
            613,
            614,
            615,
            616,
            617,
            618,
            619,
            620,
            621,
            622,
            623,
            624,
            625,
            626,
            627,
            628,
            629,
            630,
            631,
            632,
            633,
            634,
            635,
            636,
            637,
            638,
            639,
            640,
            641,
            642,
            643,
            644,
            645,
            646,
            647,
            648,
            649,
            650,
            651,
            652,
            653,
            654,
            655,
            656,
            657,
            658,
            659,
            660,
            661,
            662,
            663,
            664,
            665,
            666,
            667,
            668,
            669,
            670,
            671,
            672,
            673,
            674,
            675,
            676,
            677,
            678,
            679,
            680,
            681,
            682,
            683,
            684,
            685,
            686,
            687,
            688,
            689,
            690,
            691,
            692,
            693,
            694,
            695,
            696,
            697,
            698,
            699,
            700,
            701,
            702,
            703,
            704,
            705,
            706,
            707,
            708,
            709,
            710,
            711,
            712,
            713,
            714,
            715,
            716,
            717,
            718,
            719,
            720,
            721,
            722,
            723,
            724,
            725,
            726,
            727,
            728,
            729,
            730,
            731,
            732,
            733,
            734,
            735,
            736,
            737,
            738,
            739,
            740,
            741,
            742,
            743,
            744,
            745,
            746,
            747,
            748,
            749,
            750,
            751,
            752,
            753,
            754,
            755,
            756,
            757,
            758,
            759,
            760,
            761,
            762,
            763,
            764,
            765,
            766,
            767,
            768,
            769,
            770,
            771,
            772,
            773,
            774,
            775,
            776,
            777,
            778,
            779,
            780,
            781,
            782,
            783,
            784,
            785,
            786,
            787,
            788,
            789,
            790,
            791,
            792,
            793,
            794,
            795,
            796,
            797,
            798,
            799,
            800,
            801,
            802,
            803,
            804,
            805,
            806,
            807,
            808,
            809,
            810,
            811,
            812,
            813,
            814,
            815,
            816,
            817,
            818,
            819,
            820,
            821,
            822,
            823,
            824,
            825,
            826,
            827,
            828,
            829,
            830,
            831,
            832,
            833,
            834,
            835,
            836,
            837,
            838,
            839,
            840,
            841,
            842,
            843,
            844,
            845,
            846,
            847,
            848,
            849,
            850,
            851,
            852,
            853,
            854,
            855,
            856,
            857,
            858,
            859,
            860,
            861,
            862,
            863,
            864,
            865,
            866,
            867,
            868,
            869,
            870,
            871,
            872,
            873,
            874,
            875,
            876,
            877,
            878,
            879,
            880,
            881,
            882,
            883,
            884,
            885,
            886,
            887,
            888,
            889,
            890,
            891,
            892,
            893,
            894,
            895,
            896,
            897,
            898,
            899,
            5760,
            5761,
            5762,
            5763,
            5764,
            5765,
            5766,
            5767,
            5768,
            5769,
            5770,
            5771,
            5772,
            5773,
            5774,
            5775,
            5776,
            5777,
            5778,
            5779,
            5780,
            5781,
            5782,
            5783,
            5784,
            5785,
            5786,
            5787,
            5788,
            5789,
            5790,
            5791,
            5792,
            5793,
            5794,
            5795,
            5796,
            5797,
            5798,
            5799,
            5800,
            5801,
            5802,
            5803,
            5804,
            5805,
            5806,
            5807,
            5808,
            5809,
            5810,
            5811,
            5812,
            5813,
            5814,
            5815,
            5816,
            5817,
            5818,
            5819,
            5820,
            5821,
            5822,
            5823,
            5824,
            5825,
            5826,
            5827,
            5828,
            5829,
            5830,
            5831,
            5832,
            5833,
            5834,
            5835,
            5836,
            5837,
            5838,
            5839,
            5840,
            5841,
            5842,
            5843,
            5844,
            5845,
            5846,
            5847,
            5848,
            5849,
            5850,
            5851,
            5852,
            5853,
            5854,
            5855,
            5856,
            5857,
            5858,
            5859,
            5860,
            5861,
            5862,
            5863,
            5864,
            5865,
            5866,
            5867,
            5868,
            5869,
            5870,
            5871,
            5872,
            5873,
            5874,
            5875,
            5876,
            5877,
            5878,
            5879,
            5880,
            5881,
            5882,
            5883,
            5884,
            5885,
            5886,
            5887,
            5888,
            5889,
            5890,
            5891,
            5892,
            5893,
            5894,
            5895,
            5896,
            5897,
            5898,
            5899,
            5900,
            5901,
            5902,
            5903,
            5904,
            5905,
            5906,
            5907,
            5908,
            5909,
            5910,
            5911,
            5912,
            5913,
            5914,
            5915,
            5916,
            5917,
            5918,
            5919,
            5920,
            5921,
            5922,
            5923,
            5924,
            5925,
            5926,
            5927,
            5928,
            5929,
            5930,
            5931,
            5932,
            5933,
            5934,
            5935,
            5936,
            5937,
            5938,
            5939,
            5940,
            5941,
            5942,
            5943,
            5944,
            5945,
            5946,
            5947,
            5948,
            5949,
            5950,
            5951,
            5952,
            5953,
            5954,
            5955,
            5956,
            5957,
            5958,
            5959,
            5960,
            5961,
            5962,
            5963,
            5964,
            5965,
            5966,
            5967,
            5968,
            5969,
            5970,
            5971,
            5972,
            5973,
            5974,
            5975,
            5976,
            5977,
            5978,
            5979,
            5980,
            5981,
            5982,
            5983,
            5984,
            5985,
            5986,
            5987,
            5988,
            5989,
            5990,
            5991,
            5992,
            5993,
            5994,
            5995,
            5996,
            5997,
            5998,
            5999,
            6000,
            6001,
            6002,
            6003,
            6004,
            6005,
            6006,
            6007,
            6008,
            6009,
            6010,
            6011,
            6012,
            6013,
            6014,
            6015,
            6016,
            6017,
            6018,
            6019,
            6020,
            6021,
            6022,
            6023,
            6024,
            6025,
            6026,
            6027,
            6028,
            6029,
            6030,
            6031,
            6032,
            6033,
            6034,
            6035,
            6036,
            6037,
            6038,
            6039,
            6040,
            6041,
            6042,
            6043,
            6044,
            6045,
            6046,
            6047,
            6048,
            6049,
            6050,
            6051,
            6052,
            6053,
            6054,
            6055,
            6056,
            6057,
            6058,
            6059,
            6060,
            6061,
            6062,
            6063,
            6064,
            6065,
            6066,
            6067,
            6068,
            6069,
            6070,
            6071,
            6072,
            6073,
            6074,
            6075,
            6076,
            6077,
            6078,
            6079,
            6080,
            6081,
            6082,
            6083,
            10944,
            10945,
            10946,
            10947,
            10948,
            10949,
            10950,
            10951,
            10952,
            10953,
            10954,
            10955,
            10956,
            10957,
            10958,
            10959,
            10960,
            10961,
            10962,
            10963,
            10964,
            10965,
            10966,
            10967,
            10968,
            10969,
            10970,
            10971,
            10972,
            10973,
            10974,
            10975,
            10976,
            10977,
            10978,
            10979,
        ]
        cliffords = []
        for n in pauli_free_elements:
            clifford = utils.clifford_2_qubit(n)
            phase = clifford.table.phase
            for i in range(4):
                self.assertFalse(phase[i])
            for other_clifford in cliffords:
                self.assertNotEqual(clifford, other_clifford)
            cliffords.append(clifford)

        pauli_check_elements_list = [
            [0, 36, 72, 108, 144, 180, 216, 252, 288, 324, 360, 396, 432, 468, 504, 540],
            [
                576,
                900,
                1224,
                1548,
                1872,
                2196,
                2520,
                2844,
                3168,
                3492,
                3816,
                4140,
                4464,
                4788,
                5112,
                5436,
            ],
            [
                5760,
                6084,
                6408,
                6732,
                7056,
                7380,
                7704,
                8028,
                8352,
                8676,
                9000,
                9324,
                9648,
                9972,
                10296,
                10620,
            ],
            [
                10944,
                10980,
                11016,
                11052,
                11088,
                11124,
                11160,
                11196,
                11232,
                11268,
                11304,
                11340,
                11376,
                11412,
                11448,
                11484,
            ],
        ]
        for pauli_check_elements in pauli_check_elements_list:
            phases = []
            table = None
            for n in pauli_check_elements:
                clifford = utils.clifford_2_qubit(n)
                if table is None:
                    table = clifford.table.array
                else:
                    self.assertTrue(np.all(table == clifford.table.array))
                phase = tuple(clifford.table.phase)
                for other_phase in phases:
                    self.assertNotEqual(phase, other_phase)
                phases.append(phase)
예제 #17
0
    'X' : XGate(),
    'Y' : YGate(),
    'Z' : ZGate(),
    'S' : SGate(),
    'T' : TGate(),
    'T_dg' : TdgGate(),
    'S_dg' : SdgGate(),
    'Ry' : RYGate(np.pi / 4)
}

CONTROLLED_GATE_DICT = {
    'CX0' : CXGate(),
    'CX1' : CXGate(),
    'CY0' : CYGate(),
    'CY1' : CYGate(),
    'CZ0' : CZGate(),
    'CZ1' : CYGate(),
    'CH0' : CHGate(),
    'CH1' : CHGate()
}

def _state_to_gates(state):

    gates = []
    for qtop_gate, qbot_gate in zip(state[0], state[1]):
        if qtop_gate in SINGLE_GATE_DICT.keys():
            gates.append([qtop_gate, [0]])
            gates.append([qbot_gate, [1]])
        elif qtop_gate in CONTROLLED_GATE_DICT.keys():
            gates.append([qtop_gate, [0, 1] if qtop_gate[-1] == '0' else [1, 0] ])