Ejemplo n.º 1
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())
Ejemplo n.º 2
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,
        )
Ejemplo n.º 3
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)
Ejemplo n.º 4
0
 def to_pauli_op(self, massive: bool = False) -> OperatorBase:
     """ Returns a sum of ``PauliOp`` s equivalent to this Operator. """
     mat_op = self.to_matrix_op(massive=massive)
     sparse_pauli = SparsePauliOp.from_operator(mat_op.primitive)
     return sum([
         PrimitiveOp(Pauli.from_label(label),
                     coeff.real if coeff == coeff.real else coeff)
         for (label, coeff) in sparse_pauli.to_list()
     ]) * self.coeff
Ejemplo n.º 5
0
    def to_pauli_op(self, massive: bool = False) -> OperatorBase:
        """ Returns a sum of ``PauliOp`` s equivalent to this Operator. """
        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

        return sum([PrimitiveOp(Pauli.from_label(label),  # type: ignore
                                coeff.real if coeff == coeff.real else coeff)
                    for (label, coeff) in sparse_pauli.to_list()]) * self.coeff
Ejemplo n.º 6
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)
Ejemplo n.º 7
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)