Пример #1
0
    def test_basic_zz(self):
        """Test to decompose a ZZ-based evolution op.

        The expected circuit is:

        ..parsed-literal::
                                                           ┌────────────────┐
            q_0: ───────────────────X──────────────────────┤0               ├
                 ┌────────────────┐ │ ┌────────────────┐   │  exp(-i ZZ)(3) │
            q_1: ┤0               ├─X─┤0               ├─X─┤1               ├
                 │  exp(-i ZZ)(1) │   │  exp(-i ZZ)(2) │ │ └────────────────┘
            q_2: ┤1               ├─X─┤1               ├─X───────────────────
                 └────────────────┘ │ └────────────────┘
            q_3: ───────────────────X────────────────────────────────────────


        """

        op = PauliSumOp.from_list([("IZZI", 1), ("ZIIZ", 2), ("ZIZI", 3)])
        circ = QuantumCircuit(4)
        circ.append(PauliEvolutionGate(op, 1), range(4))

        swapped = self.pm_.run(circ)

        expected = QuantumCircuit(4)
        expected.append(PauliEvolutionGate(Pauli("ZZ"), 1), (1, 2))
        expected.swap(0, 1)
        expected.swap(2, 3)
        expected.append(PauliEvolutionGate(Pauli("ZZ"), 2), (1, 2))
        expected.swap(1, 2)
        expected.append(PauliEvolutionGate(Pauli("ZZ"), 3), (0, 1))

        self.assertEqual(swapped, expected)
Пример #2
0
    def test_inverse(self, synth_cls):
        """Test calculating the inverse is correct."""
        evo = PauliEvolutionGate(X + Y, time=0.12, synthesis=synth_cls())

        circuit = QuantumCircuit(1)
        circuit.append(evo, circuit.qubits)
        circuit.append(evo.inverse(), circuit.qubits)

        self.assertTrue(
            Operator(circuit).equiv(np.identity(2**circuit.num_qubits)))
Пример #3
0
    def test_ccx(self):
        """Test that extra multi-qubit operations are properly adjusted.

        Here, we test that the circuit

        .. parsed-literal::

                 ┌──────────────────────────┐
            q_0: ┤0                         ├──■──
                 │                          │┌─┴─┐
            q_1: ┤1 exp(-it (IZZ + ZIZ))(1) ├┤ X ├
                 │                          │└─┬─┘
            q_2: ┤2                         ├──■──
                 └──────────────────────────┘
            q_3: ─────────────────────────────────

        becomes

        .. parsed-literal::

                 ┌─────────────────┐                      ┌───┐
            q_0: ┤0                ├─X────────────────────┤ X ├
                 │  exp(-it ZZ)(1) │ │ ┌─────────────────┐└─┬─┘
            q_1: ┤1                ├─X─┤0                ├──■──
                 └─────────────────┘   │  exp(-it ZZ)(2) │  │
            q_2: ──────────────────────┤1                ├──■──
                                       └─────────────────┘
            q_3: ──────────────────────────────────────────────


        as expected. I.e. the Toffoli is properly adjusted at the end.
        """
        cmap = CouplingMap(couplinglist=[(0, 1), (1, 2)])
        swap_strat = SwapStrategy(cmap, swap_layers=(((0, 1), ), ))

        pm_ = PassManager([
            FindCommutingPauliEvolutions(),
            Commuting2qGateRouter(swap_strat),
        ])
        op = PauliSumOp.from_list([("IZZ", 1), ("ZIZ", 2)])
        circ = QuantumCircuit(4)
        circ.append(PauliEvolutionGate(op, 1), range(3))
        circ.ccx(0, 2, 1)

        swapped = pm_.run(circ)

        expected = QuantumCircuit(4)
        expected.append(PauliEvolutionGate(Pauli("ZZ"), 1), (0, 1))
        expected.swap(0, 1)
        expected.append(PauliEvolutionGate(Pauli("ZZ"), 2), (1, 2))
        expected.ccx(1, 2, 0)

        self.assertEqual(swapped, expected)
Пример #4
0
    def test_different_input_types(self, op):
        """Test all different supported input types and that they yield the same."""
        expected = QuantumCircuit(2)
        expected.rx(4, 1)

        with self.subTest(msg="plain"):
            evo = PauliEvolutionGate(op, time=2, synthesis=LieTrotter())
            self.assertEqual(evo.definition, expected)

        with self.subTest(msg="wrapped in list"):
            evo = PauliEvolutionGate([op], time=2, synthesis=LieTrotter())
            self.assertEqual(evo.definition, expected)
Пример #5
0
    def test_basic_xx_with_measure(self):
        """Test to route an XX-based evolution op with measures.

        The op is :code:`[("XXII", -1), ("IIXX", 1), ("XIIX", -2), ("IXIX", 2)]`.

        The expected circuit is:

        ..parsed-literal::

                     ┌────────────────┐                                            ░    ┌─┐
               q_0: ─┤0               ├─X──────────────────────────────────────────░────┤M├──────
                     │  exp(-i XX)(3) │ │ ┌─────────────────┐                      ░    └╥┘   ┌─┐
               q_1: ─┤1               ├─X─┤0                ├─X────────────────────░─────╫────┤M├
                    ┌┴────────────────┤   │  exp(-i XX)(-6) │ │ ┌────────────────┐ ░ ┌─┐ ║    └╥┘
               q_2: ┤0                ├─X─┤1                ├─X─┤0               ├─░─┤M├─╫─────╫─
                    │  exp(-i XX)(-3) │ │ └─────────────────┘   │  exp(-i XX)(6) │ ░ └╥┘ ║ ┌─┐ ║
               q_3: ┤1                ├─X───────────────────────┤1               ├─░──╫──╫─┤M├─╫─
                    └─────────────────┘                         └────────────────┘ ░  ║  ║ └╥┘ ║
            meas: 4/══════════════════════════════════════════════════════════════════╩══╩══╩══╩═
                                                                                      0  1  2  3
        """

        op = PauliSumOp.from_list([("XXII", -1), ("IIXX", 1), ("XIIX", -2),
                                   ("IXIX", 2)])

        circ = QuantumCircuit(4, 4)
        circ.append(PauliEvolutionGate(op, 3), range(4))
        circ.barrier()
        for idx in range(4):
            circ.measure(idx, idx)

        swapped = self.pm_.run(circ)

        expected = QuantumCircuit(4, 4)
        expected.append(PauliEvolutionGate(Pauli("XX"), 3), (0, 1))
        expected.append(PauliEvolutionGate(Pauli("XX"), -3), (2, 3))
        expected.swap(0, 1)
        expected.swap(2, 3)
        expected.append(PauliEvolutionGate(Pauli("XX"), -6), (1, 2))
        expected.swap(1, 2)
        expected.append(PauliEvolutionGate(Pauli("XX"), 6), (2, 3))
        expected.barrier()
        expected.measure(2, 0)
        expected.measure(0, 1)
        expected.measure(3, 2)
        expected.measure(1, 3)

        self.assertEqual(swapped, expected)
Пример #6
0
    def _recursive_convert(self, operator: OperatorBase) -> OperatorBase:
        if isinstance(operator, EvolvedOp):
            if isinstance(operator.primitive, (PauliOp, PauliSumOp)):
                pauli = operator.primitive.primitive
                time = operator.coeff * operator.primitive.coeff
                evo = PauliEvolutionGate(
                    pauli,
                    time=time,
                    synthesis=self._get_evolution_synthesis())
                return CircuitOp(evo.definition)
                # operator = EvolvedOp(operator.primitive.to_pauli_op(), coeff=operator.coeff)
            if not {"Pauli"} == operator.primitive_strings():
                logger.warning(
                    "Evolved Hamiltonian is not composed of only Paulis, converting to "
                    "Pauli representation, which can be expensive.")
                # Setting massive=False because this conversion is implicit. User can perform this
                # action on the Hamiltonian with massive=True explicitly if they so choose.
                # TODO explore performance to see whether we should avoid doing this repeatedly
                pauli_ham = operator.primitive.to_pauli_op(massive=False)
                operator = EvolvedOp(pauli_ham, coeff=operator.coeff)

            if isinstance(operator.primitive, SummedOp):
                # TODO uncomment when we implement Abelian grouped evolution.
                # if operator.primitive.abelian:
                #     return self.evolution_for_abelian_paulisum(operator.primitive)
                # else:
                # Collect terms that are not the identity.
                oplist = [
                    x for x in operator.primitive
                    if not isinstance(x, PauliOp) or sum(x.primitive.x +
                                                         x.primitive.z) != 0
                ]
                # Collect the coefficients of any identity terms,
                # which become global phases when exponentiated.
                identity_phases = [
                    x.coeff for x in operator.primitive
                    if isinstance(x, PauliOp) and sum(x.primitive.x +
                                                      x.primitive.z) == 0
                ]
                # Construct sum without the identity operators.
                new_primitive = SummedOp(oplist,
                                         coeff=operator.primitive.coeff)
                trotterized = self.trotter.convert(new_primitive)
                circuit_no_identities = self._recursive_convert(trotterized)
                # Set the global phase of the QuantumCircuit to account for removed identity terms.
                global_phase = -sum(identity_phases) * operator.primitive.coeff
                circuit_no_identities.primitive.global_phase = global_phase
                return circuit_no_identities
            # Covers ListOp, ComposedOp, TensoredOp
            elif isinstance(operator.primitive, ListOp):
                converted_ops = [
                    self._recursive_convert(op)
                    for op in operator.primitive.oplist
                ]
                return operator.primitive.__class__(converted_ops,
                                                    coeff=operator.coeff)
        elif isinstance(operator, ListOp):
            return operator.traverse(self.convert).reduce()

        return operator
Пример #7
0
    def test_cnot_chain_options(self, option):
        """Test selecting different kinds of CNOT chains."""

        op = Z ^ Z ^ Z
        synthesis = LieTrotter(reps=1, cx_structure=option)
        evo = PauliEvolutionGate(op, synthesis=synthesis)

        expected = QuantumCircuit(3)
        if option == "chain":
            expected.cx(2, 1)
            expected.cx(1, 0)
        else:
            expected.cx(1, 0)
            expected.cx(2, 0)

        expected.rz(2, 0)

        if option == "chain":
            expected.cx(1, 0)
            expected.cx(2, 1)
        else:
            expected.cx(2, 0)
            expected.cx(1, 0)

        self.assertEqual(expected, evo.definition)
    def _decompose_to_2q(self, dag: DAGCircuit,
                         op: PauliEvolutionGate) -> DAGCircuit:
        """Decompose the PauliSumOp into two-qubit.

        Args:
            dag: The dag needed to get access to qubits.
            op: The operator with all the Pauli terms we need to apply.

        Returns:
            A dag made of two-qubit :class:`.PauliEvolutionGate`.
        """
        sub_dag = dag.copy_empty_like()

        required_paulis = {
            self._pauli_to_edge(pauli): (pauli, coeff)
            for pauli, coeff in zip(op.operator.paulis, op.operator.coeffs)
        }

        for edge, (pauli, coeff) in required_paulis.items():

            qubits = [dag.qubits[edge[0]], dag.qubits[edge[1]]]

            simple_pauli = Pauli(pauli.to_label().replace("I", ""))

            pauli_2q = PauliEvolutionGate(simple_pauli,
                                          op.time * np.real(coeff))
            sub_dag.apply_operation_back(pauli_2q, qubits)

        return sub_dag
Пример #9
0
    def test_suzuki_trotter_manual(self):
        """Test the evolution circuit of Suzuki Trotter against a manually constructed circuit."""
        op = X + Y
        time = 0.1
        reps = 1
        evo_gate = PauliEvolutionGate(op,
                                      time,
                                      synthesis=SuzukiTrotter(order=4,
                                                              reps=reps))

        # manually construct expected evolution
        expected = QuantumCircuit(1)
        p_4 = 1 / (4 - 4**(1 / 3)
                   )  # coefficient for reduced time from Suzuki paper
        for _ in range(2):
            # factor of 1/2 already included with factor 1/2 in rotation gate
            expected.rx(p_4 * time, 0)
            expected.ry(2 * p_4 * time, 0)
            expected.rx(p_4 * time, 0)

        expected.rx((1 - 4 * p_4) * time, 0)
        expected.ry(2 * (1 - 4 * p_4) * time, 0)
        expected.rx((1 - 4 * p_4) * time, 0)

        for _ in range(2):
            expected.rx(p_4 * time, 0)
            expected.ry(2 * p_4 * time, 0)
            expected.rx(p_4 * time, 0)

        self.assertEqual(evo_gate.definition.decompose(), expected)
Пример #10
0
 def test_lie_trotter(self):
     """Test constructing the circuit with Lie Trotter decomposition."""
     op = (X ^ 3) + (Y ^ 3) + (Z ^ 3)
     time = 0.123
     reps = 4
     evo_gate = PauliEvolutionGate(op, time, synthesis=LieTrotter(reps=reps))
     decomposed = evo_gate.definition.decompose()
     self.assertEqual(decomposed.count_ops()["cx"], reps * 3 * 4)
Пример #11
0
 def test_passing_grouped_paulis(self):
     """Test passing a list of already grouped Paulis."""
     grouped_ops = [(X ^ Y) + (Y ^ X), (Z ^ I) + (Z ^ Z) + (I ^ Z), (X ^ X)]
     evo_gate = PauliEvolutionGate(grouped_ops, time=0.12, synthesis=LieTrotter())
     decomposed = evo_gate.definition.decompose()
     self.assertEqual(decomposed.count_ops()["rz"], 4)
     self.assertEqual(decomposed.count_ops()["rzz"], 1)
     self.assertEqual(decomposed.count_ops()["rxx"], 1)
Пример #12
0
    def test_single_qubit_circuit(self):
        """Test that a circuit with only single qubit gates is left unchanged."""
        op = PauliSumOp.from_list([("IIIX", 1), ("IIXI", 2), ("IZII", 3),
                                   ("XIII", 4)])

        circ = QuantumCircuit(4)
        circ.append(PauliEvolutionGate(op, 1), range(4))

        self.assertEqual(circ, self.pm_.run(circ))
Пример #13
0
 def test_paulisumop_coefficients_respected(self):
     """Test that global ``PauliSumOp`` coefficients are being taken care of."""
     evo = PauliEvolutionGate(5 * (2 * X + 3 * Y - Z), time=1, synthesis=LieTrotter())
     circuit = evo.definition.decompose()
     rz_angles = [
         circuit.data[0][0].params[0],  # X
         circuit.data[1][0].params[0],  # Y
         circuit.data[2][0].params[0],  # Z
     ]
     self.assertListEqual(rz_angles, [20, 30, -10])
Пример #14
0
    def test_labels_and_name(self):
        """Test the name and labels are correct."""
        operators = [X, (X + Y), ((I ^ Z) + (Z ^ I) - 0.2 * (X ^ X))]

        # note: the labels do not show coefficients!
        expected_labels = ["X", "(X + Y)", "(IZ + ZI + XX)"]
        for op, label in zip(operators, expected_labels):
            with self.subTest(op=op, label=label):
                evo = PauliEvolutionGate(op)
                self.assertEqual(evo.name, "PauliEvolution")
                self.assertEqual(evo.label, f"exp(-it {label})")
Пример #15
0
    def test_qdrift_evolution(self):
        """Test QDrift on an example."""
        op = 0.1 * (Z ^ Z) + (X ^ I) + (I ^ X) + 0.2 * (X ^ X)
        reps = 20
        qdrift = PauliEvolutionGate(op, time=0.5 / reps, synthesis=QDrift(reps=reps)).definition
        exact = scipy.linalg.expm(-0.5j * op.to_matrix()).dot(np.eye(4)[0, :])

        def energy(evo):
            return Statevector(evo).expectation_value(op.to_matrix())

        self.assertAlmostEqual(energy(exact), energy(qdrift), places=2)
Пример #16
0
    def test_matrix_decomposition(self):
        """Test the default decomposition."""
        op = (X ^ 3) + (Y ^ 3) + (Z ^ 3)
        time = 0.123

        matrix = op.to_matrix()
        evolved = scipy.linalg.expm(-1j * time * matrix)

        evo_gate = PauliEvolutionGate(op, time, synthesis=MatrixExponential())

        self.assertTrue(Operator(evo_gate).equiv(evolved))
Пример #17
0
def generate_evolution_gate():
    """Generate a circuit with a pauli evolution gate."""
    # Runtime import since this only exists in terra 0.19.0
    from qiskit.circuit.library import PauliEvolutionGate
    from qiskit.synthesis import SuzukiTrotter

    synthesis = SuzukiTrotter()
    evo = PauliEvolutionGate([(Z ^ I) + (I ^ Z)] * 5, time=2.0, synthesis=synthesis)
    qc = QuantumCircuit(2)
    qc.append(evo, range(2))
    return qc
Пример #18
0
    def test_idle_qubit(self):
        """Test to route on an op that has an idle qubit.

        The op is :code:`[("IIXX", 1), ("IXIX", 2)]`.

        The expected circuit is:

        ..parsed-literal::

                 ┌─────────────────┐
            q_0: ┤0                ├─X────────────────────
                 │  exp(-it XX)(3) │ │ ┌─────────────────┐
            q_1: ┤1                ├─X─┤0                ├
                 └─────────────────┘   │  exp(-it XX)(6) │
            q_2: ──────────────────────┤1                ├
                                       └─────────────────┘
            q_3: ─────────────────────────────────────────

        """
        op = PauliSumOp.from_list([("IIXX", 1), ("IXIX", 2)])

        cmap = CouplingMap(couplinglist=[(0, 1), (1, 2), (2, 3)])
        swap_strat = SwapStrategy(cmap, swap_layers=(((0, 1), ), ))

        pm_ = PassManager([
            FindCommutingPauliEvolutions(),
            Commuting2qGateRouter(swap_strat)
        ])

        circ = QuantumCircuit(4)
        circ.append(PauliEvolutionGate(op, 3), range(4))

        swapped = pm_.run(circ)

        expected = QuantumCircuit(4)
        expected.append(PauliEvolutionGate(Pauli("XX"), 3), (0, 1))
        expected.swap(0, 1)
        expected.append(PauliEvolutionGate(Pauli("XX"), 6), (1, 2))

        self.assertEqual(swapped, expected)
Пример #19
0
    def test_enlarge_with_ancilla(self):
        """This pass tests that idle qubits after an embedding are left idle."""

        # Create a four qubit problem.
        op = PauliSumOp.from_list([("IZZI", 1), ("ZIIZ", 2), ("ZIZI", 3)])

        circ = QuantumCircuit(4)
        circ.append(PauliEvolutionGate(op, 1), range(4))

        # Create a four qubit quantum circuit.
        backend_cmap = CouplingMap(couplinglist=[(0, 1), (1, 2), (1, 3), (3,
                                                                          4)])

        swap_cmap = CouplingMap(couplinglist=[(0, 1), (1, 2), (2, 3)])
        swap_strat = SwapStrategy(swap_cmap,
                                  swap_layers=(((0, 1), (2, 3)), ((1, 2), )))

        initial_layout = Layout.from_intlist([0, 1, 3, 4], *circ.qregs)

        pm_pre = PassManager([
            FindCommutingPauliEvolutions(),
            Commuting2qGateRouter(swap_strat),
            SetLayout(initial_layout),
            FullAncillaAllocation(backend_cmap),
            EnlargeWithAncilla(),
            ApplyLayout(),
        ])

        embedded = pm_pre.run(circ)

        expected = QuantumCircuit(5)
        expected.append(PauliEvolutionGate(Pauli("ZZ"), 1), (1, 3))
        expected.swap(0, 1)
        expected.swap(3, 4)
        expected.append(PauliEvolutionGate(Pauli("ZZ"), 2), (1, 3))
        expected.swap(1, 3)
        expected.append(PauliEvolutionGate(Pauli("ZZ"), 3), (0, 1))

        self.assertEqual(embedded, expected)
Пример #20
0
    def test_lie_trotter_two_qubit_correct_order(self):
        """Test that evolutions on two qubit operators are in the right order.

        Regression test of Qiskit/qiskit-terra#7544.
        """
        operator = I ^ Z ^ Z
        time = 0.5
        exact = scipy.linalg.expm(-1j * time * operator.to_matrix())
        lie_trotter = PauliEvolutionGate(operator,
                                         time,
                                         synthesis=LieTrotter())

        self.assertTrue(Operator(lie_trotter).equiv(exact))
Пример #21
0
    def test_basic_xx(self):
        """Test to route an XX-based evolution op.

        The op is :code:`[("XXII", -1), ("IIXX", 1), ("XIIX", -2), ("IXIX", 2)]`.

        The expected circuit is:

        ..parsed-literal::

                  ┌────────────────┐
            q_0: ─┤0               ├─X─────────────────────────────────────────
                  │  exp(-i XX)(3) │ │ ┌─────────────────┐
            q_1: ─┤1               ├─X─┤0                ├─X───────────────────
                 ┌┴────────────────┤   │  exp(-i XX)(-6) │ │ ┌────────────────┐
            q_2: ┤0                ├─X─┤1                ├─X─┤0               ├
                 │  exp(-i XX)(-3) │ │ └─────────────────┘   │  exp(-i XX)(6) │
            q_3: ┤1                ├─X───────────────────────┤1               ├
                 └─────────────────┘                         └────────────────┘
        """

        op = PauliSumOp.from_list([("XXII", -1), ("IIXX", 1), ("XIIX", -2),
                                   ("IXIX", 2)])

        circ = QuantumCircuit(4)
        circ.append(PauliEvolutionGate(op, 3), range(4))

        swapped = self.pm_.run(circ)

        expected = QuantumCircuit(4)
        expected.append(PauliEvolutionGate(Pauli("XX"), 3), (0, 1))
        expected.append(PauliEvolutionGate(Pauli("XX"), -3), (2, 3))
        expected.swap(0, 1)
        expected.swap(2, 3)
        expected.append(PauliEvolutionGate(Pauli("XX"), -6), (1, 2))
        expected.swap(1, 2)
        expected.append(PauliEvolutionGate(Pauli("XX"), 6), (2, 3))

        self.assertEqual(swapped, expected)
Пример #22
0
    def test_rzx_order(self):
        """Test ZX is mapped onto the correct qubits."""
        evo_gate = PauliEvolutionGate(X ^ Z)
        decomposed = evo_gate.definition.decompose()

        ref = QuantumCircuit(2)
        ref.h(1)
        ref.cx(1, 0)
        ref.rz(2.0, 0)
        ref.cx(1, 0)
        ref.h(1)

        # don't use circuit equality since RZX here decomposes with RZ on the bottom
        self.assertTrue(Operator(decomposed).equiv(ref))
Пример #23
0
    def test_qdrift_manual(self, op, time, reps, sampled_ops):
        """Test the evolution circuit of Suzuki Trotter against a manually constructed circuit."""
        qdrift = QDrift(reps=reps)
        evo_gate = PauliEvolutionGate(op, time, synthesis=qdrift)
        evo_gate.definition.decompose()

        # manually construct expected evolution
        expected = QuantumCircuit(1)
        for pauli in sampled_ops:
            if pauli[0].to_label() == "X":
                expected.rx(2 * pauli[1], 0)
            elif pauli[0].to_label() == "Y":
                expected.ry(2 * pauli[1], 0)

        self.assertTrue(Operator(evo_gate.definition).equiv(expected))
Пример #24
0
    def setUp(self):
        """Setup useful variables."""
        super().setUp()

        # A fully connected problem.
        op = PauliSumOp.from_list([("IIZZ", 1), ("IZIZ", 1), ("ZIIZ", 1),
                                   ("IZZI", 1), ("ZIZI", 1), ("ZZII", 1)])
        self.circ = QuantumCircuit(4)
        self.circ.append(PauliEvolutionGate(op, 1), range(4))

        self.swap_cmap = CouplingMap(couplinglist=[(0, 1), (1, 2), (2, 3)])

        # This swap strategy does not reach full connectivity.
        self.swap_strat = SwapStrategy(self.swap_cmap,
                                       swap_layers=(((0, 1), (2, 3)), ))
    def test_op_list_evolutiongate(self):
        """Test loading a circuit with evolution gate works."""
        evo = PauliEvolutionGate([(Z ^ I) + (I ^ Z)] * 5, time=0.2, synthesis=None)
        qc = QuantumCircuit(2)
        qc.append(evo, range(2))
        qpy_file = io.BytesIO()
        dump(qc, qpy_file)
        qpy_file.seek(0)
        new_circ = load(qpy_file)[0]

        self.assertEqual(qc, new_circ)
        self.assertEqual([x[0].label for x in qc.data], [x[0].label for x in new_circ.data])

        new_evo = new_circ.data[0][0]
        self.assertIsInstance(new_evo, PauliEvolutionGate)
    def test_op_evolution_gate_suzuki_trotter(self):
        """Test qpy path with a suzuki trotter synthesis method on an evolution gate."""
        synthesis = SuzukiTrotter()
        evo = PauliEvolutionGate((Z ^ I) + (I ^ Z), time=0.2, synthesis=synthesis)
        qc = QuantumCircuit(2)
        qc.append(evo, range(2))
        qpy_file = io.BytesIO()
        dump(qc, qpy_file)
        qpy_file.seek(0)
        new_circ = load(qpy_file)[0]

        self.assertEqual(qc, new_circ)
        self.assertEqual([x[0].label for x in qc.data], [x[0].label for x in new_circ.data])

        new_evo = new_circ.data[0][0]
        self.assertIsInstance(new_evo, PauliEvolutionGate)
Пример #27
0
    def test_dag_conversion(self):
        """Test constructing a circuit with evolutions yields a DAG with evolution blocks."""
        time = Parameter("t")
        evo = PauliEvolutionGate((Z ^ 2) + (X ^ 2), time=time)

        circuit = QuantumCircuit(2)
        circuit.h(circuit.qubits)
        circuit.append(evo, circuit.qubits)
        circuit.cx(0, 1)

        dag = circuit_to_dag(circuit)

        expected_ops = {"HGate", "CXGate", "PauliEvolutionGate"}
        ops = set(node.op.__class__.__name__ for node in dag.op_nodes())

        self.assertEqual(ops, expected_ops)
    def test_evolutiongate_param_vec_time(self):
        """Test loading a an evolution gate that has a param vector element for time."""
        synthesis = LieTrotter(reps=2)
        time = ParameterVector("TimeVec", 1)
        evo = PauliEvolutionGate((Z ^ I) + (I ^ Z), time=time[0], synthesis=synthesis)
        qc = QuantumCircuit(2)
        qc.append(evo, range(2))
        qpy_file = io.BytesIO()
        dump(qc, qpy_file)
        qpy_file.seek(0)
        new_circ = load(qpy_file)[0]

        self.assertEqual(qc, new_circ)
        self.assertEqual([x[0].label for x in qc.data], [x[0].label for x in new_circ.data])

        new_evo = new_circ.data[0][0]
        self.assertIsInstance(new_evo, PauliEvolutionGate)
Пример #29
0
    def test_list_from_grouped_paulis(self):
        """Test getting a string representation from grouped Paulis."""
        grouped_ops = [(X ^ Y) + (Y ^ X), (Z ^ I) + (Z ^ Z) + (I ^ Z), (X ^ X)]
        evo_gate = PauliEvolutionGate(grouped_ops, time=0.12, synthesis=LieTrotter())

        pauli_strings = []
        for op in evo_gate.operator:
            if isinstance(op, SparsePauliOp):
                pauli_strings.append(op.to_list())
            else:
                pauli_strings.append([(str(op), 1 + 0j)])

        expected = [
            [("XY", 1 + 0j), ("YX", 1 + 0j)],
            [("ZI", 1 + 0j), ("ZZ", 1 + 0j), ("IZ", 1 + 0j)],
            [("XX", 1 + 0j)],
        ]
        self.assertListEqual(pauli_strings, expected)
    def test_evolutiongate(self):
        """Test loading a circuit with evolution gate works."""
        synthesis = LieTrotter(reps=2)
        evo = PauliEvolutionGate((Z ^ I) + (I ^ Z),
                                 time=2,
                                 synthesis=synthesis)
        qc = QuantumCircuit(2)
        qc.append(evo, range(2))
        qpy_file = io.BytesIO()
        dump(qc, qpy_file)
        qpy_file.seek(0)
        new_circ = load(qpy_file)[0]

        self.assertEqual(qc, new_circ)
        self.assertEqual([x.operation.label for x in qc.data],
                         [x.operation.label for x in new_circ.data])

        new_evo = new_circ.data[0].operation
        self.assertIsInstance(new_evo, PauliEvolutionGate)