def test_run_2qubits(self):
        """Test for 2-qubit cases (to check endian)"""
        qc = QuantumCircuit(2)
        qc2 = QuantumCircuit(2)
        qc2.x(0)

        op = SparsePauliOp.from_list([("II", 1)])
        op2 = SparsePauliOp.from_list([("ZI", 1)])
        op3 = SparsePauliOp.from_list([("IZ", 1)])

        est = Estimator()
        result = est.run([qc], [op], [[]]).result()
        self.assertIsInstance(result, EstimatorResult)
        np.testing.assert_allclose(result.values, [1])

        result = est.run([qc2], [op], [[]]).result()
        self.assertIsInstance(result, EstimatorResult)
        np.testing.assert_allclose(result.values, [1])

        result = est.run([qc], [op2], [[]]).result()
        self.assertIsInstance(result, EstimatorResult)
        np.testing.assert_allclose(result.values, [1])

        result = est.run([qc2], [op2], [[]]).result()
        self.assertIsInstance(result, EstimatorResult)
        np.testing.assert_allclose(result.values, [1])

        result = est.run([qc], [op3], [[]]).result()
        self.assertIsInstance(result, EstimatorResult)
        np.testing.assert_allclose(result.values, [1])

        result = est.run([qc2], [op3], [[]]).result()
        self.assertIsInstance(result, EstimatorResult)
        np.testing.assert_allclose(result.values, [-1])
    def setUp(self):
        super().setUp()
        self.ansatz = RealAmplitudes(num_qubits=2, reps=2)
        self.observable = PauliSumOp.from_list([
            ("II", -1.052373245772859),
            ("IZ", 0.39793742484318045),
            ("ZI", -0.39793742484318045),
            ("ZZ", -0.01128010425623538),
            ("XX", 0.18093119978423156),
        ])
        self.expvals = -1.0284380963435145, -1.284366511861733

        self.psi = (RealAmplitudes(num_qubits=2,
                                   reps=2), RealAmplitudes(num_qubits=2,
                                                           reps=3))
        self.params = tuple(psi.parameters for psi in self.psi)
        self.hamiltonian = (
            SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)]),
            SparsePauliOp.from_list([("IZ", 1)]),
            SparsePauliOp.from_list([("ZI", 1), ("ZZ", 1)]),
        )
        self.theta = (
            [0, 1, 1, 2, 3, 5],
            [0, 1, 1, 2, 3, 5, 8, 13],
            [1, 2, 3, 4, 5, 6],
        )
    def test_run_1qubit(self):
        """Test for 1-qubit cases"""
        qc = QuantumCircuit(1)
        qc2 = QuantumCircuit(1)
        qc2.x(0)

        op = SparsePauliOp.from_list([("I", 1)])
        op2 = SparsePauliOp.from_list([("Z", 1)])

        est = Estimator()
        result = est.run([qc], [op], [[]]).result()
        self.assertIsInstance(result, EstimatorResult)
        np.testing.assert_allclose(result.values, [1])

        result = est.run([qc], [op2], [[]]).result()
        self.assertIsInstance(result, EstimatorResult)
        np.testing.assert_allclose(result.values, [1])

        result = est.run([qc2], [op], [[]]).result()
        self.assertIsInstance(result, EstimatorResult)
        np.testing.assert_allclose(result.values, [1])

        result = est.run([qc2], [op2], [[]]).result()
        self.assertIsInstance(result, EstimatorResult)
        np.testing.assert_allclose(result.values, [-1])
    def test_1qubit(self):
        """Test for 1-qubit cases"""
        qc = QuantumCircuit(1)
        qc2 = QuantumCircuit(1)
        qc2.x(0)

        op = SparsePauliOp.from_list([("I", 1)])
        op2 = SparsePauliOp.from_list([("Z", 1)])

        with self.assertWarns(DeprecationWarning):
            est = Estimator([qc, qc2], [op, op2], [[]] * 2)
            result = est([0], [0], [[]])
        self.assertIsInstance(result, EstimatorResult)
        np.testing.assert_allclose(result.values, [1])

        with self.assertWarns(DeprecationWarning):
            result = est([0], [1], [[]])
        self.assertIsInstance(result, EstimatorResult)
        np.testing.assert_allclose(result.values, [1])

        with self.assertWarns(DeprecationWarning):
            result = est([1], [0], [[]])
        self.assertIsInstance(result, EstimatorResult)
        np.testing.assert_allclose(result.values, [1])

        with self.assertWarns(DeprecationWarning):
            result = est([1], [1], [[]])
        self.assertIsInstance(result, EstimatorResult)
        np.testing.assert_allclose(result.values, [-1])
    def test_errors(self):
        """Test for errors"""
        qc = QuantumCircuit(1)
        qc2 = QuantumCircuit(2)

        op = SparsePauliOp.from_list([("I", 1)])
        op2 = SparsePauliOp.from_list([("II", 1)])

        with self.assertWarns(DeprecationWarning):
            est = Estimator([qc, qc2], [op, op2], [[]] * 2)
        with self.assertRaises(QiskitError), self.assertWarns(
                DeprecationWarning):
            est([0], [1], [[]])
        with self.assertRaises(QiskitError), self.assertWarns(
                DeprecationWarning):
            est([1], [0], [[]])
        with self.assertRaises(QiskitError), self.assertWarns(
                DeprecationWarning):
            est([0], [0], [[1e4]])
        with self.assertRaises(QiskitError), self.assertWarns(
                DeprecationWarning):
            est([1], [1], [[1, 2]])
        with self.assertRaises(QiskitError), self.assertWarns(
                DeprecationWarning):
            est([0, 1], [1], [[1]])
        with self.assertRaises(QiskitError), self.assertWarns(
                DeprecationWarning):
            est([0], [0, 1], [[1]])
Exemple #6
0
    def add(self, other: OperatorBase) -> OperatorBase:
        if not self.num_qubits == other.num_qubits:
            raise ValueError(
                "Sum over operators with different numbers of qubits, {} and {}, is not well "
                "defined".format(self.num_qubits, other.num_qubits)
            )

        if isinstance(other, PauliOp) and self.primitive == other.primitive:
            return PauliOp(self.primitive, coeff=self.coeff + other.coeff)

        # pylint: disable=cyclic-import
        from .pauli_sum_op import PauliSumOp

        if (
            isinstance(other, PauliOp)
            and isinstance(self.coeff, (int, float, complex))
            and isinstance(other.coeff, (int, float, complex))
        ):
            return PauliSumOp(
                SparsePauliOp(self.primitive, coeffs=[self.coeff])
                + SparsePauliOp(other.primitive, coeffs=[other.coeff])
            )

        if isinstance(other, PauliSumOp) and isinstance(self.coeff, (int, float, complex)):
            return PauliSumOp(SparsePauliOp(self.primitive, coeffs=[self.coeff])) + other

        return SummedOp([self, other])
Exemple #7
0
def init_observable(observable: BaseOperator | PauliSumOp) -> SparsePauliOp:
    """Initialize observable by converting the input to a :class:`~qiskit.quantum_info.SparsePauliOp`.

    Args:
        observable: The observable.

    Returns:
        The observable as :class:`~qiskit.quantum_info.SparsePauliOp`.

    Raises:
        TypeError: If the observable is a :class:`~qiskit.opflow.PauliSumOp` and has a parameterized
            coefficient.
    """
    if isinstance(observable, SparsePauliOp):
        return observable
    elif isinstance(observable, PauliSumOp):
        if isinstance(observable.coeff, ParameterExpression):
            raise TypeError(
                f"Observable must have numerical coefficient, not {type(observable.coeff)}."
            )
        return observable.coeff * observable.primitive
    elif isinstance(observable, BasePauli):
        return SparsePauliOp(observable)
    elif isinstance(observable, BaseOperator):
        return SparsePauliOp.from_operator(observable)
    else:
        return SparsePauliOp(observable)
Exemple #8
0
def _expval_params(operator, variance=False):

    # Convert O to SparsePauliOp representation
    if isinstance(operator, Pauli):
        operator = SparsePauliOp(operator)
    elif not isinstance(operator, SparsePauliOp):
        operator = SparsePauliOp.from_operator(Operator(operator))
    if not isinstance(operator, SparsePauliOp):
        raise ExtensionError("Invalid input operator")

    params = {}

    # Add Pauli basis components of O
    for pauli, coeff in operator.label_iter():
        if pauli in params:
            coeff1 = params[pauli][0]
            params[pauli] = (coeff1 + coeff.real, 0)
        else:
            params[pauli] = (coeff.real, 0)

    # Add Pauli basis components of O^2
    if variance:
        for pauli, coeff in operator.dot(operator).label_iter():
            if pauli in params:
                coeff1, coeff2 = params[pauli]
                params[pauli] = (coeff1, coeff2 + coeff.real)
            else:
                params[pauli] = (0, coeff.real)

    # Convert to list
    return list(params.items())
Exemple #9
0
def _to_sparse_pauli_op(operator):
    """Cast the operator to a SparsePauliOp.

    For Opflow objects, return a global coefficient that must be multiplied to the evolution time.
    Since this coefficient might contain unbound parameters it cannot be absorbed into the
    coefficients of the SparsePauliOp.
    """
    # pylint: disable=cyclic-import
    from qiskit.opflow import PauliSumOp, PauliOp

    if isinstance(operator, PauliSumOp):
        sparse_pauli = operator.primitive
        sparse_pauli._coeffs *= operator.coeff
    elif isinstance(operator, PauliOp):
        sparse_pauli = SparsePauliOp(operator.primitive)
        sparse_pauli._coeffs *= operator.coeff
    elif isinstance(operator, Pauli):
        sparse_pauli = SparsePauliOp(operator)
    elif isinstance(operator, SparsePauliOp):
        sparse_pauli = operator
    else:
        raise ValueError(
            f"Unsupported operator type for evolution: {type(operator)}.")

    return sparse_pauli
    def _replace_pauli_sums(cls, operator):
        try:
            from qiskit.providers.aer.library import SaveExpectationValue
        except ImportError as ex:
            raise MissingOptionalLibraryError(
                libname="qiskit-aer",
                name="AerPauliExpectation",
                pip_install="pip install qiskit-aer",
            ) from ex
        # The 'expval_measurement' label on the save instruction is special - the
        # CircuitSampler will look for it to know that the circuit is a Expectation
        # measurement, and not simply a
        # circuit to replace with a DictStateFn
        if operator.__class__ == ListOp:
            return operator.traverse(cls._replace_pauli_sums)

        if isinstance(operator, PauliSumOp):
            save_instruction = SaveExpectationValue(operator.primitive,
                                                    "expval_measurement")
            return CircuitStateFn(save_instruction,
                                  coeff=operator.coeff,
                                  is_measurement=True,
                                  from_operator=True)

        # Change to Pauli representation if necessary
        if {"Pauli"} != operator.primitive_strings():
            logger.warning(
                "Measured Observable 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 Observable with massive=True explicitly if they so choose.
            operator = operator.to_pauli_op(massive=False)

        if isinstance(operator, SummedOp):
            sparse_pauli = reduce(add,
                                  (meas.coeff * SparsePauliOp(meas.primitive)
                                   for meas in operator.oplist))
            save_instruction = SaveExpectationValue(sparse_pauli,
                                                    "expval_measurement")
            return CircuitStateFn(save_instruction,
                                  coeff=operator.coeff,
                                  is_measurement=True,
                                  from_operator=True)

        if isinstance(operator, PauliOp):
            sparse_pauli = operator.coeff * SparsePauliOp(operator.primitive)
            save_instruction = SaveExpectationValue(sparse_pauli,
                                                    "expval_measurement")
            return CircuitStateFn(save_instruction,
                                  is_measurement=True,
                                  from_operator=True)

        raise TypeError(
            f"Conversion of OperatorStateFn of {operator.__class__.__name__} is not defined."
        )
Exemple #11
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)
Exemple #12
0
    def test_permute(self, permutation, expected_pauli):
        """Test the permute method."""
        pauli_sum = PauliSumOp(SparsePauliOp.from_list([("XYZ", 1)]))
        expected = PauliSumOp(SparsePauliOp.from_list([(expected_pauli, 1)]))
        permuted = pauli_sum.permute(permutation)

        with self.subTest(msg="test permutated object"):
            self.assertEqual(permuted, expected)

        with self.subTest(msg="test original object is unchanged"):
            original = PauliSumOp(SparsePauliOp.from_list([("XYZ", 1)]))
            self.assertEqual(pauli_sum, original)
    def test_adjoint(self):
        """ adjoint test """
        pauli_sum = PauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[2]),
                               coeff=3)
        expected = PauliSumOp(SparsePauliOp(Pauli("XYZX")), coeff=-6)

        self.assertEqual(pauli_sum.adjoint(), expected)

        pauli_sum = PauliSumOp(SparsePauliOp(Pauli("XYZY"), coeffs=[2]),
                               coeff=3j)
        expected = PauliSumOp(SparsePauliOp(Pauli("XYZY")), coeff=-6j)
        self.assertEqual(pauli_sum.adjoint(), expected)
Exemple #14
0
def init_observable(observable: BaseOperator | PauliSumOp) -> SparsePauliOp:
    """Initialize observable"""
    if isinstance(observable, SparsePauliOp):
        return observable
    if isinstance(observable, PauliSumOp):
        if isinstance(observable.coeff, ParameterExpression):
            raise TypeError(
                f"observable must have numerical coefficient, not {type(observable.coeff)}"
            )
        return observable.coeff * observable.primitive
    if isinstance(observable, BaseOperator):
        return SparsePauliOp.from_operator(observable)
    return SparsePauliOp(observable)
Exemple #15
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)
Exemple #16
0
    def __init__(self,
                 operator,
                 label="expectation_value_variance",
                 unnormalized=False,
                 pershot=False,
                 conditional=False):
        r"""Instruction to save the expectation value and variance of a Hermitian operator.

        The expectation value of a Hermitian operator :math:`H` for a
        simulator in quantum state :math`\rho`is given by
        :math:`\langle H\rangle = \mbox{Tr}[H.\rho]`. The variance is given by
        :math:`\sigma^2 = \langle H^2 \rangle - \langle H \rangle>^2`.

        Args:
            operator (Pauli or SparsePauliOp or Operator): a Hermitian operator.
            label (str): the key for retrieving saved data from results.
            unnormalized (bool): If True return save the unnormalized accumulated
                                 or conditional accumulated expectation value
                                 over all shot [Default: False].
            pershot (bool): if True save a list of expectation values for each shot
                            of the simulation rather than the average over
                            all shots [Default: False].
            conditional (bool): if True save the average or pershot data
                                conditional on the current classical register
                                values [Default: False].

        Raises:
            ExtensionError: if the input operator is invalid or not Hermitian.

        .. note::

            This instruction can be directly appended to a circuit using
            the :func:`save_expectation_value` circuit method.
        """
        # Convert O to SparsePauliOp representation
        if isinstance(operator, Pauli):
            operator = SparsePauliOp(operator)
        elif not isinstance(operator, SparsePauliOp):
            operator = SparsePauliOp.from_operator(Operator(operator))
        if not allclose(operator.coeffs.imag, 0):
            raise ExtensionError("Input operator is not Hermitian.")
        params = _expval_params(operator, variance=True)
        super().__init__('save_expval_var',
                         operator.num_qubits,
                         label,
                         unnormalized=unnormalized,
                         pershot=pershot,
                         conditional=conditional,
                         params=params)
    def test_equals(self):
        """ equality test """

        self.assertNotEqual((X ^ X) + (Y ^ Y), X + Y)
        self.assertEqual((X ^ X) + (Y ^ Y), (Y ^ Y) + (X ^ X))

        theta = ParameterVector("theta", 2)
        pauli_sum0 = theta[0] * (X + Z)
        pauli_sum1 = theta[1] * (X + Z)
        expected = PauliSumOp(
            SparsePauliOp(Pauli("X")) + SparsePauliOp(Pauli("Z")),
            coeff=1.0 * theta[0],
        )
        self.assertEqual(pauli_sum0, expected)
        self.assertNotEqual(pauli_sum1, expected)
    def test_grouped_pauli_statefn(self):
        """grouped pauli test with statefn"""
        grouped_pauli = PauliSumOp(SparsePauliOp(["Y"]), grouping_type="TPB")
        observable = OperatorStateFn(grouped_pauli, is_measurement=True)

        converter = PauliBasisChange(
            replacement_fn=PauliBasisChange.measurement_replacement_fn)
        cob = converter.convert(observable)

        expected = PauliSumOp(SparsePauliOp(["Z"]), grouping_type="TPB")
        self.assertEqual(cob[0].primitive, expected)
        circuit = QuantumCircuit(1)
        circuit.sdg(0)
        circuit.h(0)
        self.assertEqual(cob[1].primitive, circuit)
Exemple #19
0
    def to_pauli_op(self, massive: bool = False) -> OperatorBase:
        """ Returns a sum of ``PauliOp`` s equivalent to this Operator. """
        # pylint: disable=import-outside-toplevel,cyclic-import
        from ..list_ops.summed_op import SummedOp
        mat_op = self.to_matrix_op(massive=massive)
        sparse_pauli = SparsePauliOp.from_operator(
            mat_op.primitive)  # type: ignore
        if not sparse_pauli.to_list():
            # pylint: disable=import-outside-toplevel
            from ..operator_globals import I
            return (I ^ self.num_qubits) * 0.0
        if len(sparse_pauli) == 1:
            label, coeff = sparse_pauli.to_list()[0]
            coeff = coeff.real if np.isreal(coeff) else coeff
            return PrimitiveOp(Pauli(label), coeff * self.coeff)

        return SummedOp(
            [
                PrimitiveOp(
                    Pauli(label),
                    coeff.real if coeff == coeff.real else coeff,
                ) for (label, coeff) in sparse_pauli.to_list()
            ],
            self.coeff,
        )
Exemple #20
0
def _sort_simplify(sparse_pauli):
    sparse_pauli = sparse_pauli.simplify()
    indices = sparse_pauli.paulis.argsort()
    table = sparse_pauli.paulis[indices]
    coeffs = sparse_pauli.coeffs[indices]
    sparse_pauli = SparsePauliOp(table, coeffs)
    return sparse_pauli
Exemple #21
0
    def test_permute(self):
        """permute test"""
        pauli_sum = PauliSumOp(SparsePauliOp((X ^ Y ^ Z).primitive))
        expected = PauliSumOp(SparsePauliOp((X ^ I ^ Y ^ Z ^ I).primitive))

        self.assertEqual(pauli_sum.permute([1, 2, 4]), expected)

        pauli_sum = PauliSumOp(SparsePauliOp((X ^ Y ^ Z).primitive))
        expected = PauliSumOp(SparsePauliOp((Z ^ Y ^ X).primitive))
        self.assertEqual(pauli_sum.permute([2, 1, 0]), expected)

        with self.assertRaises(OpflowError):
            pauli_sum.permute([1, 2, 1])

        with self.assertRaises(OpflowError):
            pauli_sum.permute([1, 2, -1])
Exemple #22
0
 def _expand_dim(self, num_qubits: int) -> "PauliSumOp":
     return PauliSumOp(
         self.primitive.tensor(  # type:ignore
             SparsePauliOp(Pauli("I" * num_qubits))
         ),
         coeff=self.coeff,
     )
Exemple #23
0
    def test_decoder_import(self):
        """Test runtime decoder importing modules."""
        script = """
import sys
import json
from qiskit.providers.ibmq.runtime import RuntimeDecoder
if __name__ == '__main__':
    obj = json.loads(sys.argv[1], cls=RuntimeDecoder)
    print(obj.__class__.__name__)
"""
        temp_fp = tempfile.NamedTemporaryFile(mode='w', delete=False)
        self.addCleanup(os.remove, temp_fp.name)
        temp_fp.write(script)
        temp_fp.close()

        subtests = (
            PauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[2]), coeff=3),
            DictStateFn("1" * 3, is_measurement=True),
            Statevector([1, 0]),
        )
        for op in subtests:
            with self.subTest(op=op):
                encoded = json.dumps(op, cls=RuntimeEncoder)
                self.assertIsInstance(encoded, str)
                cmd = ["python", temp_fp.name, encoded]
                proc = subprocess.run(cmd,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE,
                                      universal_newlines=True,
                                      check=True)
                self.assertIn(op.__class__.__name__, proc.stdout)
    def test_find_Z2_symmetries(self):
        """test for find_Z2_symmetries"""

        qubit_op = PauliSumOp.from_list([
            ("II", -1.0537076071291125),
            ("IZ", 0.393983679438514),
            ("ZI", -0.39398367943851387),
            ("ZZ", -0.01123658523318205),
            ("XX", 0.1812888082114961),
        ])
        z2_symmetries = Z2Symmetries.find_Z2_symmetries(qubit_op)
        self.assertEqual(z2_symmetries.symmetries, [Pauli("ZZ")])
        self.assertEqual(z2_symmetries.sq_paulis, [Pauli("IX")])
        self.assertEqual(z2_symmetries.sq_list, [0])
        self.assertEqual(z2_symmetries.tapering_values, None)

        tapered_op = z2_symmetries.taper(qubit_op)[1]
        self.assertEqual(tapered_op.z2_symmetries.symmetries, [Pauli("ZZ")])
        self.assertEqual(tapered_op.z2_symmetries.sq_paulis, [Pauli("IX")])
        self.assertEqual(tapered_op.z2_symmetries.sq_list, [0])
        self.assertEqual(tapered_op.z2_symmetries.tapering_values, [-1])

        z2_symmetries.tapering_values = [-1]
        primitive = SparsePauliOp.from_list([
            ("I", -1.0424710218959303),
            ("Z", -0.7879673588770277),
            ("X", -0.18128880821149604),
        ])
        expected_op = TaperedPauliSumOp(primitive, z2_symmetries)
        self.assertEqual(tapered_op, expected_op)
Exemple #25
0
    def permute(self, permutation: List[int]) -> "PauliSumOp":
        """Permutes the sequence of ``PauliSumOp``.

        Args:
            permutation: A list defining where each Pauli should be permuted. The Pauli at index
                j of the primitive should be permuted to position permutation[j].

        Returns:
              A new PauliSumOp representing the permuted operator. For operator (X ^ Y ^ Z) and
              indices=[1,2,4], it returns (X ^ I ^ Y ^ Z ^ I).

        Raises:
            OpflowError: if indices do not define a new index for each qubit.
        """
        if len(permutation) != self.num_qubits:
            raise OpflowError(
                "List of indices to permute must have the same size as Pauli Operator"
            )
        length = max(permutation) + 1
        spop = self.primitive.tensor(
            SparsePauliOp(Pauli("I" * (length - self.num_qubits))))
        permutation = [i for i in range(length) if i not in permutation
                       ] + permutation
        permu_arr = np.arange(length)[np.argsort(permutation)]
        spop.paulis.x = spop.paulis.x[:, permu_arr]
        spop.paulis.z = spop.paulis.z[:, permu_arr]
        return PauliSumOp(spop, self.coeff)
Exemple #26
0
    def compose(
        self, other: OperatorBase, permutation: Optional[List[int]] = None, front: bool = False
    ) -> OperatorBase:

        new_self, other = self._expand_shorter_operator_and_permute(other, permutation)
        new_self = cast(PauliOp, new_self)

        if front:
            return other.compose(new_self)
        # If self is identity, just return other.
        if not any(new_self.primitive.x + new_self.primitive.z):
            return other * new_self.coeff

        # Both Paulis
        if isinstance(other, PauliOp):
            product = new_self.primitive.dot(other.primitive)
            return PrimitiveOp(product, coeff=new_self.coeff * other.coeff)

        # pylint: disable=cyclic-import
        from .pauli_sum_op import PauliSumOp

        if isinstance(other, PauliSumOp):
            return PauliSumOp(
                SparsePauliOp(new_self.primitive).dot(other.primitive),
                coeff=new_self.coeff * other.coeff,
            )

        # pylint: disable=cyclic-import
        from ..state_fns.circuit_state_fn import CircuitStateFn
        from .circuit_op import CircuitOp

        if isinstance(other, (CircuitOp, CircuitStateFn)):
            return new_self.to_circuit_op().compose(other)

        return super(PauliOp, new_self).compose(other)
def save_expval_params(pauli=False):
    """Dictionary of labels and params, qubits for exp val snapshots."""
    if pauli:
        X_wpo = Pauli('X')
        Y_wpo = Pauli('Y')
        Z_wpo = Pauli('Z')
        H_wpo = np.sqrt(0.5) * (SparsePauliOp('X') + SparsePauliOp('Z'))
        IX_wpo = Pauli('IX')
        IY_wpo = Pauli('IY')
        IZ_wpo = Pauli('IZ')
        IH_wpo = np.sqrt(0.5) * (SparsePauliOp('IX') + SparsePauliOp('IZ'))
        XX_wpo = Pauli('XX')
        YY_wpo = Pauli('YY')
        ZZ_wpo = Pauli('ZZ')
    else:
        X_wpo = np.array([[0, 1], [1, 0]], dtype=complex)
        Y_wpo = np.array([[0, -1j], [1j, 0]], dtype=complex)
        Z_wpo = np.array([[1, 0], [0, -1]], dtype=complex)
        H_wpo = np.array([[1, 1], [1, -1]], dtype=complex) / np.sqrt(2)
        IX_wpo = np.kron(np.eye(2), X_wpo)
        IY_wpo = np.kron(np.eye(2), Y_wpo)
        IZ_wpo = np.kron(np.eye(2), Z_wpo)
        IH_wpo = np.kron(np.eye(2), H_wpo)
        XX_wpo = np.kron(X_wpo, X_wpo)
        YY_wpo = np.kron(Y_wpo, Y_wpo)
        ZZ_wpo = np.kron(Z_wpo, Z_wpo)
    return {
        "<H[0]>": (H_wpo, [0]),
        "<H[1]>": (H_wpo, [1]),
        "<X[0]>": (X_wpo, [0]),
        "<X[1]>": (X_wpo, [1]),
        "<Y[1]>": (Y_wpo, [0]),
        "<Y[1]>": (Y_wpo, [1]),
        "<Z[0]>": (Z_wpo, [0]),
        "<Z[1]>": (Z_wpo, [1]),
        "<H[0], I[1]>": (IH_wpo, [0, 1]),
        "<I[0], H[1]>": (IH_wpo, [1, 0]),
        "<X[0], I[1]>": (IX_wpo, [0, 1]),
        "<I[0], X[1]>": (IX_wpo, [1, 0]),
        "<Y[0], I[1]>": (IY_wpo, [0, 1]),
        "<I[0], Y[1]>": (IY_wpo, [1, 0]),
        "<Z[0], I[1]>": (IZ_wpo, [0, 1]),
        "<I[0], Z[1]>": (IZ_wpo, [1, 0]),
        "<X[0], X[1]>": (XX_wpo, [0, 1]),
        "<Y[0], Y[1]>": (YY_wpo, [0, 1]),
        "<Z[0], Z[1]>": (ZZ_wpo, [0, 1]),
    }
 def test_construct(self):
     """ constructor test """
     sparse_pauli = SparsePauliOp(Pauli("XYZX"), coeffs=[2.0])
     coeff = 3.0
     pauli_sum = PauliSumOp(sparse_pauli, coeff=coeff)
     self.assertIsInstance(pauli_sum, PauliSumOp)
     self.assertEqual(pauli_sum.primitive, sparse_pauli)
     self.assertEqual(pauli_sum.coeff, coeff)
     self.assertEqual(pauli_sum.num_qubits, 4)
 def test_matrix_iter(self):
     """Test PauliSumOp dense matrix_iter method."""
     labels = ["III", "IXI", "IYY", "YIZ", "XYZ", "III"]
     coeffs = np.array([1, 2, 3, 4, 5, 6])
     table = PauliTable.from_labels(labels)
     coeff = 10
     op = PauliSumOp(SparsePauliOp(table, coeffs), coeff)
     for idx, i in enumerate(op.matrix_iter()):
         self.assertTrue(np.array_equal(i, coeff * coeffs[idx] * Pauli(labels[idx]).to_matrix()))
    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)