Skip to content

Commit 053ee32

Browse files
authored
StabilizerState.expectation_value can also accept SparsePauliOp (Qiskit#13539)
* update ecpectation_value function * add a test * add release notes * revision following code review
1 parent cf5ef03 commit 053ee32

File tree

3 files changed

+47
-3
lines changed

3 files changed

+47
-3
lines changed

qiskit/quantum_info/states/stabilizerstate.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from qiskit.exceptions import QiskitError
2525
from qiskit.quantum_info.operators.op_shape import OpShape
2626
from qiskit.quantum_info.operators.operator import Operator
27-
from qiskit.quantum_info.operators.symplectic import Clifford, Pauli, PauliList
27+
from qiskit.quantum_info.operators.symplectic import Clifford, Pauli, PauliList, SparsePauliOp
2828
from qiskit.quantum_info.operators.symplectic.clifford_circuits import _append_x
2929
from qiskit.quantum_info.states.quantum_state import QuantumState
3030
from qiskit.circuit import QuantumCircuit, Instruction
@@ -259,7 +259,34 @@ def evolve(
259259
ret._data = self.clifford.compose(other.clifford, qargs=qargs)
260260
return ret
261261

262-
def expectation_value(self, oper: Pauli, qargs: None | list = None) -> complex:
262+
def expectation_value(self, oper: Pauli | SparsePauliOp, qargs: None | list = None) -> complex:
263+
"""Compute the expectation value of a Pauli or SparsePauliOp operator.
264+
265+
Args:
266+
oper: A Pauli or SparsePauliOp operator to evaluate the expectation value.
267+
qargs: Subsystems to apply the operator on.
268+
269+
Returns:
270+
The expectation value.
271+
272+
Raises:
273+
QiskitError: if oper is not a Pauli or SparsePauliOp operator.
274+
"""
275+
if isinstance(oper, Pauli):
276+
return self._expectation_value_pauli(oper, qargs)
277+
278+
if isinstance(oper, SparsePauliOp):
279+
return sum(
280+
coeff * self._expectation_value_pauli(Pauli((z, x)), qargs)
281+
for z, x, coeff in zip(oper.paulis.z, oper.paulis.x, oper.coeffs)
282+
)
283+
284+
raise QiskitError(
285+
"Operator for expectation value is not a Pauli or SparsePauliOp operator, "
286+
f"but {type(oper)}."
287+
)
288+
289+
def _expectation_value_pauli(self, oper: Pauli, qargs: None | list = None) -> complex:
263290
"""Compute the expectation value of a Pauli operator.
264291
265292
Args:
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
features_quantum_info:
3+
- |
4+
The method :meth:`.StabilizerState.expectation_value` can now accept an operator of type
5+
:class:`.SparsePauliOp`.

test/python/quantum_info/states/test_stabilizerstate.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from qiskit.quantum_info.random import random_clifford, random_pauli
2626
from qiskit.quantum_info.states import StabilizerState, Statevector
2727
from qiskit.circuit.library import IGate, XGate, HGate
28-
from qiskit.quantum_info.operators import Clifford, Pauli, Operator
28+
from qiskit.quantum_info.operators import Clifford, Pauli, Operator, SparsePauliOp
2929
from test import combine # pylint: disable=wrong-import-order
3030
from test import QiskitTestCase # pylint: disable=wrong-import-order
3131

@@ -1101,6 +1101,18 @@ def test_expval_random_subsystem(self, num_qubits):
11011101
target = Statevector(qc).expectation_value(op, qargs)
11021102
self.assertAlmostEqual(exp_val, target)
11031103

1104+
def test_expval_sparsepauliop(self):
1105+
"""Test expectation_value method of SparsePauliOp"""
1106+
cliff = random_clifford(num_qubits=3, seed=1234)
1107+
stab = StabilizerState(cliff)
1108+
labels = ["XXX", "IXI", "YYY", "III"]
1109+
coeffs = [3.0, 5.5, -1j, 23]
1110+
spp_op = SparsePauliOp.from_list(list(zip(labels, coeffs)))
1111+
expval = stab.expectation_value(spp_op)
1112+
qc = cliff.to_circuit()
1113+
target = Statevector(qc).expectation_value(spp_op)
1114+
self.assertAlmostEqual(expval, target)
1115+
11041116
def test_stabilizer_bell_equiv(self):
11051117
"""Test that two circuits produce the same stabilizer group."""
11061118

0 commit comments

Comments
 (0)