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())
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, )
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)
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
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
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)
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)