コード例 #1
0
ファイル: test_synthesis.py プロジェクト: yinxx/qiskit-terra
    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))
コード例 #2
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))