def test_permute_on_list_op(self):
        """Test if ListOp permute method is consistent with PrimitiveOps permute methods."""

        op1 = (X ^ Y ^ Z).to_circuit_op()
        op2 = Z ^ X ^ Y

        # ComposedOp
        indices = [1, 2, 0]
        primitive_op = op1 @ op2
        primitive_op_perm = primitive_op.permute(indices)  # CircuitOp.permute

        composed_op = ComposedOp([op1, op2])
        composed_op_perm = composed_op.permute(indices)

        # reduce the ListOp to PrimitiveOp
        to_primitive = composed_op_perm.oplist[0] @ composed_op_perm.oplist[1]
        # compare resulting PrimitiveOps
        equal = np.allclose(primitive_op_perm.to_matrix(),
                            to_primitive.to_matrix())
        self.assertTrue(equal)

        # TensoredOp
        indices = [3, 5, 4, 0, 2, 1]
        primitive_op = op1 ^ op2
        primitive_op_perm = primitive_op.permute(indices)

        tensored_op = TensoredOp([op1, op2])
        tensored_op_perm = tensored_op.permute(indices)

        # reduce the ListOp to PrimitiveOp
        composed_oplist = tensored_op_perm.oplist
        to_primitive = (composed_oplist[0] @ (composed_oplist[1].oplist[0]
                                              ^ composed_oplist[1].oplist[1])
                        @ composed_oplist[2])

        # compare resulting PrimitiveOps
        equal = np.allclose(primitive_op_perm.to_matrix(),
                            to_primitive.to_matrix())
        self.assertTrue(equal)

        # SummedOp
        primitive_op = X ^ Y ^ Z
        summed_op = SummedOp([primitive_op])

        indices = [1, 2, 0]
        primitive_op_perm = primitive_op.permute(indices)  # PauliOp.permute
        summed_op_perm = summed_op.permute(indices)

        # reduce the ListOp to PrimitiveOp
        to_primitive = summed_op_perm.oplist[
            0] @ primitive_op @ summed_op_perm.oplist[2]

        # compare resulting PrimitiveOps
        equal = np.allclose(primitive_op_perm.to_matrix(),
                            to_primitive.to_matrix())
        self.assertTrue(equal)
Ejemplo n.º 2
0
    def test_evals(self):
        """ evals test """
        # TODO: Think about eval names
        self.assertEqual(Z.eval('0').eval('0'), 1)
        self.assertEqual(Z.eval('1').eval('0'), 0)
        self.assertEqual(Z.eval('0').eval('1'), 0)
        self.assertEqual(Z.eval('1').eval('1'), -1)
        self.assertEqual(X.eval('0').eval('0'), 0)
        self.assertEqual(X.eval('1').eval('0'), 1)
        self.assertEqual(X.eval('0').eval('1'), 1)
        self.assertEqual(X.eval('1').eval('1'), 0)
        self.assertEqual(Y.eval('0').eval('0'), 0)
        self.assertEqual(Y.eval('1').eval('0'), -1j)
        self.assertEqual(Y.eval('0').eval('1'), 1j)
        self.assertEqual(Y.eval('1').eval('1'), 0)

        with self.assertRaises(ValueError):
            Y.eval('11')

        with self.assertRaises(ValueError):
            (X ^ Y).eval('1111')

        with self.assertRaises(ValueError):
            Y.eval((X ^ X).to_matrix_op())

        # Check that Pauli logic eval returns same as matrix logic
        self.assertEqual(PrimitiveOp(Z.to_matrix()).eval('0').eval('0'), 1)
        self.assertEqual(PrimitiveOp(Z.to_matrix()).eval('1').eval('0'), 0)
        self.assertEqual(PrimitiveOp(Z.to_matrix()).eval('0').eval('1'), 0)
        self.assertEqual(PrimitiveOp(Z.to_matrix()).eval('1').eval('1'), -1)
        self.assertEqual(PrimitiveOp(X.to_matrix()).eval('0').eval('0'), 0)
        self.assertEqual(PrimitiveOp(X.to_matrix()).eval('1').eval('0'), 1)
        self.assertEqual(PrimitiveOp(X.to_matrix()).eval('0').eval('1'), 1)
        self.assertEqual(PrimitiveOp(X.to_matrix()).eval('1').eval('1'), 0)
        self.assertEqual(PrimitiveOp(Y.to_matrix()).eval('0').eval('0'), 0)
        self.assertEqual(PrimitiveOp(Y.to_matrix()).eval('1').eval('0'), -1j)
        self.assertEqual(PrimitiveOp(Y.to_matrix()).eval('0').eval('1'), 1j)
        self.assertEqual(PrimitiveOp(Y.to_matrix()).eval('1').eval('1'), 0)

        pauli_op = Z ^ I ^ X ^ Y
        mat_op = PrimitiveOp(pauli_op.to_matrix())
        full_basis = list(map(''.join, itertools.product('01', repeat=pauli_op.num_qubits)))
        for bstr1, bstr2 in itertools.product(full_basis, full_basis):
            # print('{} {} {} {}'.format(bstr1, bstr2, pauli_op.eval(bstr1, bstr2),
            # mat_op.eval(bstr1, bstr2)))
            np.testing.assert_array_almost_equal(pauli_op.eval(bstr1).eval(bstr2),
                                                 mat_op.eval(bstr1).eval(bstr2))

        gnarly_op = SummedOp([(H ^ I ^ Y).compose(X ^ X ^ Z).tensor(Z),
                              PrimitiveOp(Operator.from_label('+r0I')),
                              3 * (X ^ CX ^ T)], coeff=3 + .2j)
        gnarly_mat_op = PrimitiveOp(gnarly_op.to_matrix())
        full_basis = list(map(''.join, itertools.product('01', repeat=gnarly_op.num_qubits)))
        for bstr1, bstr2 in itertools.product(full_basis, full_basis):
            np.testing.assert_array_almost_equal(gnarly_op.eval(bstr1).eval(bstr2),
                                                 gnarly_mat_op.eval(bstr1).eval(bstr2))
    def test_trotter_qrte_qdrift(self, initial_state, expected_state):
        """Test for TrotterQRTE with QDrift."""
        operator = SummedOp([X, Z])
        time = 1
        evolution_problem = EvolutionProblem(operator, time, initial_state)

        algorithm_globals.random_seed = 0
        trotter_qrte = TrotterQRTE(product_formula=QDrift())
        evolution_result = trotter_qrte.evolve(evolution_problem)
        np.testing.assert_equal(evolution_result.evolved_state.eval(), expected_state)
Ejemplo n.º 4
0
    def test_bind_parameters_complex(self):
        """bind parameters with a complex value test"""
        th1 = Parameter("th1")
        th2 = Parameter("th2")

        operator = th1 * X + th2 * Y
        bound_operator = operator.bind_parameters({th1: 3j, th2: 2})

        expected_bound_operator = SummedOp([3j * X, (2 + 0j) * Y])
        self.assertEqual(bound_operator, expected_bound_operator)
    def test_trotter_qrte_trotter_single_qubit(self, product_formula, expected_state):
        """Test for default TrotterQRTE on a single qubit."""
        operator = SummedOp([X, Z])
        initial_state = StateFn([1, 0])
        time = 1
        evolution_problem = EvolutionProblem(operator, time, initial_state)

        trotter_qrte = TrotterQRTE(product_formula=product_formula)
        evolution_result_state_circuit = trotter_qrte.evolve(evolution_problem).evolved_state

        np.testing.assert_equal(evolution_result_state_circuit.eval(), expected_state)
Ejemplo n.º 6
0
    def test_add(self):
        """ add test """
        pauli_sum = 3 * X + Y
        self.assertIsInstance(pauli_sum, PauliSumOp)
        expected = PauliSumOp(3.0 * SparsePauliOp(Pauli("X")) +
                              SparsePauliOp(Pauli("Y")))
        self.assertEqual(pauli_sum, expected)

        pauli_sum = X + Y
        summed_op = SummedOp([X, Y])
        self.assertEqual(pauli_sum, summed_op)
Ejemplo n.º 7
0
    def test_add(self):
        """add test"""
        pauli_sum = 3 * X + Y
        self.assertIsInstance(pauli_sum, PauliSumOp)
        expected = PauliSumOp(3.0 * SparsePauliOp(Pauli("X")) +
                              SparsePauliOp(Pauli("Y")))
        self.assertEqual(pauli_sum, expected)

        pauli_sum = X + Y
        summed_op = SummedOp([X, Y])
        self.assertEqual(pauli_sum, summed_op)

        a = Parameter("a")
        b = Parameter("b")
        actual = a * PauliSumOp.from_list(
            [("X", 2)]) + b * PauliSumOp.from_list([("Y", 1)])
        expected = SummedOp([
            PauliSumOp.from_list([("X", 2)], a),
            PauliSumOp.from_list([("Y", 1)], b)
        ])
        self.assertEqual(actual, expected)
Ejemplo n.º 8
0
    def test_group_subops(self, is_summed_op):
        """grouper subroutine test"""
        paulis = (I ^ X) + (2 * X ^ X) + (3 * Z ^ Y)
        if is_summed_op:
            paulis = paulis.to_pauli_op()
        grouped_sum = AbelianGrouper.group_subops(paulis)
        self.assertEqual(len(grouped_sum), 2)
        with self.subTest("test group subops 1"):
            if is_summed_op:
                expected = SummedOp([
                    SummedOp([I ^ X, 2.0 * X ^ X], abelian=True),
                    SummedOp([3.0 * Z ^ Y], abelian=True)
                ])
                self.assertEqual(grouped_sum, expected)
            else:
                self.assertSetEqual(
                    frozenset([
                        frozenset(grouped_sum[i].primitive.to_list())
                        for i in range(2)
                    ]),
                    frozenset({
                        frozenset({('ZY', 3)}),
                        frozenset({('IX', 1), ('XX', 2)})
                    }))

        paulis = X + (2 * Y) + (3 * Z)
        if is_summed_op:
            paulis = paulis.to_pauli_op()
        grouped_sum = AbelianGrouper.group_subops(paulis)
        self.assertEqual(len(grouped_sum), 3)
        with self.subTest("test group subops 2"):
            if is_summed_op:
                self.assertEqual(grouped_sum, paulis)
            else:
                self.assertSetEqual(
                    frozenset(
                        sum([
                            grouped_sum[i].primitive.to_list()
                            for i in range(3)
                        ], [])), frozenset([('X', 1), ('Y', 2), ('Z', 3)]))
Ejemplo n.º 9
0
    def test_coeffs(self):
        """ListOp.coeffs test"""
        sum1 = SummedOp([(0 + 1j) * X, (1 / np.sqrt(2) + 1j / np.sqrt(2)) * Z],
                        0.5).collapse_summands()
        self.assertAlmostEqual(sum1.coeffs[0], 0.5j)
        self.assertAlmostEqual(sum1.coeffs[1], (1 + 1j) / (2 * np.sqrt(2)))

        a_param = Parameter("a")
        b_param = Parameter("b")
        param_exp = ParameterExpression({
            a_param: 1,
            b_param: 0
        },
                                        Symbol("a")**2 + Symbol("b"))
        sum2 = SummedOp([X, (1 / np.sqrt(2) - 1j / np.sqrt(2)) * Y],
                        param_exp).collapse_summands()
        self.assertIsInstance(sum2.coeffs[0], ParameterExpression)
        self.assertIsInstance(sum2.coeffs[1], ParameterExpression)

        # Nested ListOp
        sum_nested = SummedOp([X, sum1])
        self.assertRaises(TypeError, lambda: sum_nested.coeffs)
Ejemplo n.º 10
0
 def test_summedop_pauli_evolution(self):
     """SummedOp[PauliOp] evolution test"""
     op = SummedOp([
         (-1.052373245772859 * I ^ I),
         (0.39793742484318045 * I ^ Z),
         (0.18093119978423156 * X ^ X),
         (-0.39793742484318045 * Z ^ I),
         (-0.01128010425623538 * Z ^ Z),
     ])
     evolution = EvolutionFactory.build(operator=op)
     # wf = (Pl^Pl) + (Ze^Ze)
     wf = ((np.pi / 2) * op).exp_i() @ CX @ (H ^ I) @ Zero
     mean = evolution.convert(wf)
     self.assertIsNotNone(mean)
Ejemplo n.º 11
0
def _remove_identity(pauli_sum):
    """Remove any identity operators from `pauli_sum`. Return
    the sum of the coefficients of the identities and the new operator.
    """
    idcoeff = 0.0
    ops = []
    for op in pauli_sum:
        p = op.primitive
        if p.x.any() or p.z.any():
            ops.append(op)
        else:
            idcoeff += op.coeff

    return idcoeff, SummedOp(ops)
Ejemplo n.º 12
0
    def test_coder_operators(self):
        """Test runtime encoder and decoder for operators."""
        x = Parameter("x")
        y = x + 1
        qc = QuantumCircuit(1)
        qc.h(0)
        coeffs = np.array([1, 2, 3, 4, 5, 6])
        table = PauliTable.from_labels(
            ["III", "IXI", "IYY", "YIZ", "XYZ", "III"])
        op = (2.0 * I ^ I)
        z2_symmetries = Z2Symmetries(
            [Pauli("IIZI"), Pauli("ZIII")],
            [Pauli("IIXI"), Pauli("XIII")], [1, 3], [-1, 1])
        isqrt2 = 1 / np.sqrt(2)
        sparse = scipy.sparse.csr_matrix([[0, isqrt2, 0, isqrt2]])

        subtests = (
            PauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[2]), coeff=3),
            PauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[1]), coeff=y),
            PauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[1 + 2j]),
                       coeff=3 - 2j),
            PauliSumOp.from_list([("II", -1.052373245772859),
                                  ("IZ", 0.39793742484318045)]),
            PauliSumOp(SparsePauliOp(table, coeffs), coeff=10),
            MatrixOp(primitive=np.array([[0, -1j], [1j, 0]]), coeff=x),
            PauliOp(primitive=Pauli("Y"), coeff=x),
            CircuitOp(qc, coeff=x),
            EvolvedOp(op, coeff=x),
            TaperedPauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[2]),
                              z2_symmetries),
            StateFn(qc, coeff=x),
            CircuitStateFn(qc, is_measurement=True),
            DictStateFn("1" * 3, is_measurement=True),
            VectorStateFn(np.ones(2**3, dtype=complex)),
            OperatorStateFn(CircuitOp(QuantumCircuit(1))),
            SparseVectorStateFn(sparse),
            Statevector([1, 0]),
            CVaRMeasurement(Z, 0.2),
            ComposedOp([(X ^ Y ^ Z), (Z ^ X ^ Y ^ Z).to_matrix_op()]),
            SummedOp([X ^ X * 2, Y ^ Y], 2),
            TensoredOp([(X ^ Y), (Z ^ I)]),
            (Z ^ Z) ^ (I ^ 2),
        )
        for op in subtests:
            with self.subTest(op=op):
                encoded = json.dumps(op, cls=RuntimeEncoder)
                self.assertIsInstance(encoded, str)
                decoded = json.loads(encoded, cls=RuntimeDecoder)
                self.assertEqual(op, decoded)
Ejemplo n.º 13
0
    def test_expand_on_list_op(self):
        """ Test if expanded ListOp has expected num_qubits. """
        add_qubits = 3

        # ComposedOp
        composed_op = ComposedOp([(X ^ Y ^ Z), (H ^ T), (Z ^ X ^ Y ^ Z).to_matrix_op()])
        expanded = composed_op._expand_dim(add_qubits)
        self.assertEqual(composed_op.num_qubits + add_qubits, expanded.num_qubits)

        # TensoredOp
        tensored_op = TensoredOp([(X ^ Y), (Z ^ I)])
        expanded = tensored_op._expand_dim(add_qubits)
        self.assertEqual(tensored_op.num_qubits + add_qubits, expanded.num_qubits)

        # SummedOp
        summed_op = SummedOp([(X ^ Y), (Z ^ I ^ Z)])
        expanded = summed_op._expand_dim(add_qubits)
        self.assertEqual(summed_op.num_qubits + add_qubits, expanded.num_qubits)
Ejemplo n.º 14
0
 def test_qdrift_summed_op(self):
     """QDrift test for SummedOp"""
     op = SummedOp([
         (2 * Z ^ Z),
         (3 * X ^ X),
         (-4 * Y ^ Y),
         (0.5 * Z ^ I),
     ])
     trotterization = QDrift().convert(op)
     self.assertGreater(len(trotterization.oplist), 150)
     last_coeff = None
     # Check that all types are correct and all coefficients are equals
     for op in trotterization.oplist:
         self.assertIsInstance(op, (EvolvedOp, CircuitOp))
         if isinstance(op, EvolvedOp):
             if last_coeff:
                 self.assertEqual(op.primitive.coeff, last_coeff)
             else:
                 last_coeff = op.primitive.coeff
Ejemplo n.º 15
0
    def test_trotter_qrte_trotter_single_qubit_aux_ops(self):
        """Test for default TrotterQRTE on a single qubit with auxiliary operators."""
        operator = SummedOp([X, Z])
        # LieTrotter with 1 rep
        aux_ops = [X, Y]

        initial_state = Zero
        time = 3
        evolution_problem = EvolutionProblem(operator, time, initial_state, aux_ops)

        expected_evolved_state = VectorStateFn(
            Statevector([0.98008514 + 0.13970775j, 0.01991486 + 0.13970775j], dims=(2,))
        )
        expected_aux_ops_evaluated = [(0.078073, 0.0), (0.268286, 0.0)]
        expected_aux_ops_evaluated_qasm = [
            (0.05799999999999995, 0.011161518713866855),
            (0.2495, 0.010826759383582883),
        ]

        for backend_name in self.backends_names_not_none:
            with self.subTest(msg=f"Test {backend_name} backend."):
                algorithm_globals.random_seed = 0
                backend = self.backends_dict[backend_name]
                expectation = ExpectationFactory.build(
                    operator=operator,
                    backend=backend,
                )
                trotter_qrte = TrotterQRTE(quantum_instance=backend, expectation=expectation)
                evolution_result = trotter_qrte.evolve(evolution_problem)

                np.testing.assert_equal(
                    evolution_result.evolved_state.eval(), expected_evolved_state
                )
                if backend_name == "qi_qasm":
                    expected_aux_ops_evaluated = expected_aux_ops_evaluated_qasm
                np.testing.assert_array_almost_equal(
                    evolution_result.aux_ops_evaluated, expected_aux_ops_evaluated
                )
    def test_list_op_parameters(self):
        """Test that Parameters are stored correctly in a List Operator"""
        lam = Parameter("λ")
        phi = Parameter("φ")
        omega = Parameter("ω")

        mat_op = PrimitiveOp([[0, 1], [1, 0]], coeff=omega)

        qc = QuantumCircuit(1)
        qc.rx(phi, 0)
        qc_op = PrimitiveOp(qc)

        op1 = SummedOp([mat_op, qc_op])

        params = [phi, omega]
        self.assertEqual(op1.parameters, set(params))

        # check list nesting case
        op2 = PrimitiveOp([[1, 0], [0, -1]], coeff=lam)

        list_op = ListOp([op1, op2])

        params.append(lam)
        self.assertEqual(list_op.parameters, set(params))
    def test_summed_op_reduce(self):
        """Test SummedOp"""
        sum_op = (X ^ X * 2) + (Y ^ Y)  # type: PauliSumOp
        sum_op = sum_op.to_pauli_op()  # type: SummedOp[PauliOp]
        with self.subTest("SummedOp test 1"):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ["XX", "YY"])
            self.assertListEqual([op.coeff for op in sum_op], [2, 1])

        sum_op = (X ^ X * 2) + (Y ^ Y)
        sum_op += Y ^ Y
        sum_op = sum_op.to_pauli_op()  # type: SummedOp[PauliOp]
        with self.subTest("SummedOp test 2-a"):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ["XX", "YY", "YY"])
            self.assertListEqual([op.coeff for op in sum_op], [2, 1, 1])

        sum_op = sum_op.collapse_summands()
        with self.subTest("SummedOp test 2-b"):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ["XX", "YY"])
            self.assertListEqual([op.coeff for op in sum_op], [2, 2])

        sum_op = (X ^ X * 2) + (Y ^ Y)
        sum_op += (Y ^ Y) + (X ^ X * 2)
        sum_op = sum_op.to_pauli_op()  # type: SummedOp[PauliOp]
        with self.subTest("SummedOp test 3-a"):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ["XX", "YY", "YY", "XX"])
            self.assertListEqual([op.coeff for op in sum_op], [2, 1, 1, 2])

        sum_op = sum_op.reduce().to_pauli_op()
        with self.subTest("SummedOp test 3-b"):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ["XX", "YY"])
            self.assertListEqual([op.coeff for op in sum_op], [4, 2])

        sum_op = SummedOp([X ^ X * 2, Y ^ Y], 2)
        with self.subTest("SummedOp test 4-a"):
            self.assertEqual(sum_op.coeff, 2)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ["XX", "YY"])
            self.assertListEqual([op.coeff for op in sum_op], [2, 1])

        sum_op = sum_op.collapse_summands()
        with self.subTest("SummedOp test 4-b"):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ["XX", "YY"])
            self.assertListEqual([op.coeff for op in sum_op], [4, 2])

        sum_op = SummedOp([X ^ X * 2, Y ^ Y], 2)
        sum_op += Y ^ Y
        with self.subTest("SummedOp test 5-a"):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ["XX", "YY", "YY"])
            self.assertListEqual([op.coeff for op in sum_op], [4, 2, 1])

        sum_op = sum_op.collapse_summands()
        with self.subTest("SummedOp test 5-b"):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ["XX", "YY"])
            self.assertListEqual([op.coeff for op in sum_op], [4, 3])

        sum_op = SummedOp([X ^ X * 2, Y ^ Y], 2)
        sum_op += ((X ^ X) * 2 + (Y ^ Y)).to_pauli_op()
        with self.subTest("SummedOp test 6-a"):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ["XX", "YY", "XX", "YY"])
            self.assertListEqual([op.coeff for op in sum_op], [4, 2, 2, 1])

        sum_op = sum_op.collapse_summands()
        with self.subTest("SummedOp test 6-b"):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ["XX", "YY"])
            self.assertListEqual([op.coeff for op in sum_op], [6, 3])

        sum_op = SummedOp([X ^ X * 2, Y ^ Y], 2)
        sum_op += sum_op
        with self.subTest("SummedOp test 7-a"):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ["XX", "YY", "XX", "YY"])
            self.assertListEqual([op.coeff for op in sum_op], [4, 2, 4, 2])

        sum_op = sum_op.collapse_summands()
        with self.subTest("SummedOp test 7-b"):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ["XX", "YY"])
            self.assertListEqual([op.coeff for op in sum_op], [8, 4])

        sum_op = SummedOp([X ^ X * 2, Y ^ Y], 2) + SummedOp([X ^ X * 2, Z ^ Z],
                                                            3)
        with self.subTest("SummedOp test 8-a"):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ["XX", "YY", "XX", "ZZ"])
            self.assertListEqual([op.coeff for op in sum_op], [4, 2, 6, 3])

        sum_op = sum_op.collapse_summands()
        with self.subTest("SummedOp test 8-b"):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ["XX", "YY", "ZZ"])
            self.assertListEqual([op.coeff for op in sum_op], [10, 2, 3])

        sum_op = SummedOp([])
        with self.subTest("SummedOp test 9"):
            self.assertEqual(sum_op.reduce(), sum_op)

        sum_op = ((Z + I) ^ Z) + (Z ^ X)
        with self.subTest("SummedOp test 10"):
            expected = SummedOp([
                PauliOp(Pauli("ZZ")),
                PauliOp(Pauli("IZ")),
                PauliOp(Pauli("ZX"))
            ])
            self.assertEqual(sum_op.to_pauli_op(), expected)
Ejemplo n.º 18
0
    def test_summed_op_reduce(self):
        """Test SummedOp"""
        sum_op = (X ^ X * 2) + (Y ^ Y)  # type: PauliSumOp
        sum_op = sum_op.to_pauli_op()  # type: SummedOp[PauliOp]
        with self.subTest('SummedOp test 1'):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ['XX', 'YY'])
            self.assertListEqual([op.coeff for op in sum_op], [2, 1])

        sum_op = (X ^ X * 2) + (Y ^ Y)
        sum_op += Y ^ Y
        sum_op = sum_op.to_pauli_op()  # type: SummedOp[PauliOp]
        with self.subTest('SummedOp test 2-a'):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ['XX', 'YY', 'YY'])
            self.assertListEqual([op.coeff for op in sum_op], [2, 1, 1])

        sum_op = sum_op.collapse_summands()
        with self.subTest('SummedOp test 2-b'):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ['XX', 'YY'])
            self.assertListEqual([op.coeff for op in sum_op], [2, 2])

        sum_op = (X ^ X * 2) + (Y ^ Y)
        sum_op += (Y ^ Y) + (X ^ X * 2)
        sum_op = sum_op.to_pauli_op()  # type: SummedOp[PauliOp]
        with self.subTest('SummedOp test 3-a'):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ['XX', 'YY', 'YY', 'XX'])
            self.assertListEqual([op.coeff for op in sum_op], [2, 1, 1, 2])

        sum_op = sum_op.reduce().to_pauli_op()
        with self.subTest('SummedOp test 3-b'):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ['XX', 'YY'])
            self.assertListEqual([op.coeff for op in sum_op], [4, 2])

        sum_op = SummedOp([X ^ X * 2, Y ^ Y], 2)
        with self.subTest('SummedOp test 4-a'):
            self.assertEqual(sum_op.coeff, 2)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ['XX', 'YY'])
            self.assertListEqual([op.coeff for op in sum_op], [2, 1])

        sum_op = sum_op.collapse_summands()
        with self.subTest('SummedOp test 4-b'):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ['XX', 'YY'])
            self.assertListEqual([op.coeff for op in sum_op], [4, 2])

        sum_op = SummedOp([X ^ X * 2, Y ^ Y], 2)
        sum_op += Y ^ Y
        with self.subTest('SummedOp test 5-a'):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ['XX', 'YY', 'YY'])
            self.assertListEqual([op.coeff for op in sum_op], [4, 2, 1])

        sum_op = sum_op.collapse_summands()
        with self.subTest('SummedOp test 5-b'):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ['XX', 'YY'])
            self.assertListEqual([op.coeff for op in sum_op], [4, 3])

        sum_op = SummedOp([X ^ X * 2, Y ^ Y], 2)
        sum_op += ((X ^ X) * 2 + (Y ^ Y)).to_pauli_op()
        with self.subTest('SummedOp test 6-a'):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ['XX', 'YY', 'XX', 'YY'])
            self.assertListEqual([op.coeff for op in sum_op], [4, 2, 2, 1])

        sum_op = sum_op.collapse_summands()
        with self.subTest('SummedOp test 6-b'):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ['XX', 'YY'])
            self.assertListEqual([op.coeff for op in sum_op], [6, 3])

        sum_op = SummedOp([X ^ X * 2, Y ^ Y], 2)
        sum_op += sum_op
        with self.subTest('SummedOp test 7-a'):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ['XX', 'YY', 'XX', 'YY'])
            self.assertListEqual([op.coeff for op in sum_op], [4, 2, 4, 2])

        sum_op = sum_op.collapse_summands()
        with self.subTest('SummedOp test 7-b'):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ['XX', 'YY'])
            self.assertListEqual([op.coeff for op in sum_op], [8, 4])

        sum_op = SummedOp([X ^ X * 2, Y ^ Y], 2) + SummedOp([X ^ X * 2, Z ^ Z],
                                                            3)
        with self.subTest('SummedOp test 8-a'):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ['XX', 'YY', 'XX', 'ZZ'])
            self.assertListEqual([op.coeff for op in sum_op], [4, 2, 6, 3])

        sum_op = sum_op.collapse_summands()
        with self.subTest('SummedOp test 8-b'):
            self.assertEqual(sum_op.coeff, 1)
            self.assertListEqual([str(op.primitive) for op in sum_op],
                                 ['XX', 'YY', 'ZZ'])
            self.assertListEqual([op.coeff for op in sum_op], [10, 2, 3])
Ejemplo n.º 19
0
 def test_to_pauli_op(self):
     """ test to_pauli_op method """
     target = X + Y
     self.assertIsInstance(target, PauliSumOp)
     expected = SummedOp([X, Y])
     self.assertEqual(target.to_pauli_op(), expected)
Ejemplo n.º 20
0
class TestTrotterQRTE(QiskitOpflowTestCase):
    """TrotterQRTE tests."""

    def setUp(self):
        super().setUp()
        self.seed = 50
        algorithm_globals.random_seed = self.seed
        backend_statevector = BasicAer.get_backend("statevector_simulator")
        backend_qasm = BasicAer.get_backend("qasm_simulator")
        self.quantum_instance = QuantumInstance(
            backend=backend_statevector,
            shots=1,
            seed_simulator=self.seed,
            seed_transpiler=self.seed,
        )
        self.quantum_instance_qasm = QuantumInstance(
            backend=backend_qasm,
            shots=8000,
            seed_simulator=self.seed,
            seed_transpiler=self.seed,
        )
        self.backends_dict = {
            "qi_sv": self.quantum_instance,
            "qi_qasm": self.quantum_instance_qasm,
            "b_sv": backend_statevector,
            "None": None,
        }

        self.backends_names = ["qi_qasm", "b_sv", "None", "qi_sv"]
        self.backends_names_not_none = ["qi_sv", "b_sv", "qi_qasm"]

    @data(
        (
            None,
            VectorStateFn(
                Statevector([0.29192658 - 0.45464871j, 0.70807342 - 0.45464871j], dims=(2,))
            ),
        ),
        (
            SuzukiTrotter(),
            VectorStateFn(Statevector([0.29192658 - 0.84147098j, 0.0 - 0.45464871j], dims=(2,))),
        ),
    )
    @unpack
    def test_trotter_qrte_trotter_single_qubit(self, product_formula, expected_state):
        """Test for default TrotterQRTE on a single qubit."""
        operator = SummedOp([X, Z])
        initial_state = StateFn([1, 0])
        time = 1
        evolution_problem = EvolutionProblem(operator, time, initial_state)

        trotter_qrte = TrotterQRTE(product_formula=product_formula)
        evolution_result_state_circuit = trotter_qrte.evolve(evolution_problem).evolved_state

        np.testing.assert_equal(evolution_result_state_circuit.eval(), expected_state)

    def test_trotter_qrte_trotter_single_qubit_aux_ops(self):
        """Test for default TrotterQRTE on a single qubit with auxiliary operators."""
        operator = SummedOp([X, Z])
        # LieTrotter with 1 rep
        aux_ops = [X, Y]

        initial_state = Zero
        time = 3
        evolution_problem = EvolutionProblem(operator, time, initial_state, aux_ops)

        expected_evolved_state = VectorStateFn(
            Statevector([0.98008514 + 0.13970775j, 0.01991486 + 0.13970775j], dims=(2,))
        )
        expected_aux_ops_evaluated = [(0.078073, 0.0), (0.268286, 0.0)]
        expected_aux_ops_evaluated_qasm = [
            (0.05799999999999995, 0.011161518713866855),
            (0.2495, 0.010826759383582883),
        ]

        for backend_name in self.backends_names_not_none:
            with self.subTest(msg=f"Test {backend_name} backend."):
                algorithm_globals.random_seed = 0
                backend = self.backends_dict[backend_name]
                expectation = ExpectationFactory.build(
                    operator=operator,
                    backend=backend,
                )
                trotter_qrte = TrotterQRTE(quantum_instance=backend, expectation=expectation)
                evolution_result = trotter_qrte.evolve(evolution_problem)

                np.testing.assert_equal(
                    evolution_result.evolved_state.eval(), expected_evolved_state
                )
                if backend_name == "qi_qasm":
                    expected_aux_ops_evaluated = expected_aux_ops_evaluated_qasm
                np.testing.assert_array_almost_equal(
                    evolution_result.aux_ops_evaluated, expected_aux_ops_evaluated
                )

    @data(
        (
            SummedOp([(X ^ Y), (Y ^ X)]),
            VectorStateFn(
                Statevector(
                    [-0.41614684 + 0.0j, 0.0 + 0.0j, 0.0 + 0.0j, 0.90929743 + 0.0j], dims=(2, 2)
                )
            ),
        ),
        (
            (Z ^ Z) + (Z ^ I) + (I ^ Z),
            VectorStateFn(
                Statevector(
                    [-0.9899925 - 0.14112001j, 0.0 + 0.0j, 0.0 + 0.0j, 0.0 + 0.0j], dims=(2, 2)
                )
            ),
        ),
        (
            Y ^ Y,
            VectorStateFn(
                Statevector(
                    [0.54030231 + 0.0j, 0.0 + 0.0j, 0.0 + 0.0j, 0.0 + 0.84147098j], dims=(2, 2)
                )
            ),
        ),
    )
    @unpack
    def test_trotter_qrte_trotter_two_qubits(self, operator, expected_state):
        """Test for TrotterQRTE on two qubits with various types of a Hamiltonian."""
        # LieTrotter with 1 rep
        initial_state = StateFn([1, 0, 0, 0])
        evolution_problem = EvolutionProblem(operator, 1, initial_state)

        trotter_qrte = TrotterQRTE()
        evolution_result = trotter_qrte.evolve(evolution_problem)
        np.testing.assert_equal(evolution_result.evolved_state.eval(), expected_state)

    def test_trotter_qrte_trotter_two_qubits_with_params(self):
        """Test for TrotterQRTE on two qubits with a parametrized Hamiltonian."""
        # LieTrotter with 1 rep
        initial_state = StateFn([1, 0, 0, 0])
        w_param = Parameter("w")
        u_param = Parameter("u")
        params_dict = {w_param: 2.0, u_param: 3.0}
        operator = w_param * (Z ^ Z) / 2.0 + (Z ^ I) + u_param * (I ^ Z) / 3.0
        time = 1
        evolution_problem = EvolutionProblem(
            operator, time, initial_state, hamiltonian_value_dict=params_dict
        )
        expected_state = VectorStateFn(
            Statevector([-0.9899925 - 0.14112001j, 0.0 + 0.0j, 0.0 + 0.0j, 0.0 + 0.0j], dims=(2, 2))
        )
        trotter_qrte = TrotterQRTE()
        evolution_result = trotter_qrte.evolve(evolution_problem)
        np.testing.assert_equal(evolution_result.evolved_state.eval(), expected_state)

    @data(
        (
            Zero,
            VectorStateFn(
                Statevector([0.23071786 - 0.69436148j, 0.4646314 - 0.49874749j], dims=(2,))
            ),
        ),
        (
            QuantumCircuit(1).compose(ZGate(), [0]),
            VectorStateFn(
                Statevector([0.23071786 - 0.69436148j, 0.4646314 - 0.49874749j], dims=(2,))
            ),
        ),
    )
    @unpack
    def test_trotter_qrte_qdrift(self, initial_state, expected_state):
        """Test for TrotterQRTE with QDrift."""
        operator = SummedOp([X, Z])
        time = 1
        evolution_problem = EvolutionProblem(operator, time, initial_state)

        algorithm_globals.random_seed = 0
        trotter_qrte = TrotterQRTE(product_formula=QDrift())
        evolution_result = trotter_qrte.evolve(evolution_problem)
        np.testing.assert_equal(evolution_result.evolved_state.eval(), expected_state)

    @data((Parameter("t"), {}), (None, {Parameter("x"): 2}), (None, None))
    @unpack
    def test_trotter_qrte_trotter_errors(self, t_param, hamiltonian_value_dict):
        """Test TrotterQRTE with raising errors."""
        operator = X * Parameter("t") + Z
        initial_state = Zero
        time = 1
        algorithm_globals.random_seed = 0
        trotter_qrte = TrotterQRTE()
        with assert_raises(ValueError):
            evolution_problem = EvolutionProblem(
                operator,
                time,
                initial_state,
                t_param=t_param,
                hamiltonian_value_dict=hamiltonian_value_dict,
            )
            _ = trotter_qrte.evolve(evolution_problem)
Ejemplo n.º 21
0
    def estimate(
            self,
            hamiltonian: OperatorBase,
            state_preparation: Optional[StateFn] = None,
            evolution: Optional[EvolutionBase] = None,
            bound: Optional[float] = None) -> HamiltonianPhaseEstimationResult:
        """Run the Hamiltonian phase estimation algorithm.

        Args:
            hamiltonian: A Hermitian operator.
            state_preparation: The ``StateFn`` to be prepared, whose eigenphase will be
                measured. If this parameter is omitted, no preparation circuit will be run and
                input state will be the all-zero state in the computational basis.
            evolution: An evolution converter that generates a unitary from ``hamiltonian``. If
                ``None``, then the default ``PauliTrotterEvolution`` is used.
            bound: An upper bound on the absolute value of the eigenvalues of
                ``hamiltonian``. If omitted, then ``hamiltonian`` must be a Pauli sum, or a
                ``PauliOp``, in which case a bound will be computed. If ``hamiltonian``
                is a ``MatrixOp``, then ``bound`` may not be ``None``. The tighter the bound,
                the higher the resolution of computed phases.

        Returns:
            HamiltonianPhaseEstimationResult instance containing the result of the estimation
            and diagnostic information.

        Raises:
            ValueError: If ``bound`` is ``None`` and ``hamiltonian`` is not a Pauli sum, i.e. a
                ``PauliSumOp`` or a ``SummedOp`` whose terms are of type ``PauliOp``.
            TypeError: If ``evolution`` is not of type ``EvolutionBase``.
        """
        if evolution is None:
            evolution = PauliTrotterEvolution()
        elif not isinstance(evolution, EvolutionBase):
            raise TypeError(
                f'Expecting type EvolutionBase, got {type(evolution)}')

        if isinstance(hamiltonian, PauliSumOp):
            hamiltonian = hamiltonian.to_pauli_op()
        elif isinstance(hamiltonian, PauliOp):
            hamiltonian = SummedOp([hamiltonian])

        if isinstance(hamiltonian, SummedOp):
            # remove identitiy terms
            # The term propto the identity is removed from hamiltonian.
            # This is done for three reasons:
            # 1. Work around an unknown bug that otherwise causes the energies to be wrong in some
            #    cases.
            # 2. Allow working with a simpler Hamiltonian, one with fewer terms.
            # 3. Tighten the bound on the eigenvalues so that the spectrum is better resolved, i.e.
            #   occupies more of the range of values representable by the qubit register.
            # The coefficient of this term will be added to the eigenvalues.
            id_coefficient, hamiltonian_no_id = _remove_identity(hamiltonian)

            # get the rescaling object
            pe_scale = self._get_scale(hamiltonian_no_id, bound)

            # get the unitary
            unitary = self._get_unitary(hamiltonian_no_id, pe_scale, evolution)

        elif isinstance(hamiltonian, MatrixOp):
            if bound is None:
                raise ValueError(
                    'bound must be specified if Hermitian operator is MatrixOp'
                )

            # Do not subtract an identity term from the matrix, so do not compensate.
            id_coefficient = 0.0
            pe_scale = self._get_scale(hamiltonian, bound)
            unitary = self._get_unitary(hamiltonian, pe_scale, evolution)
        else:
            raise TypeError(
                f'Hermitian operator of type {type(hamiltonian)} not supported.'
            )

        if state_preparation is not None:
            state_preparation = state_preparation.to_circuit_op().to_circuit()
        # run phase estimation
        phase_estimation_result = self._phase_estimation.estimate(
            unitary=unitary, state_preparation=state_preparation)

        return HamiltonianPhaseEstimationResult(
            phase_estimation_result=phase_estimation_result,
            id_coefficient=id_coefficient,
            phase_estimation_scale=pe_scale)