Skip to content

Commit

Permalink
Fix the calculation for identity operator's expectation value (#13345) (
Browse files Browse the repository at this point in the history
#13436)

* Fix the calculation for identity operator's expectation value

* Add release note and test

* reformatted `test_statevector.py` with black

* Update releasenotes/notes/fix_identity_operator_9e2ec9770ac046a6.yaml

Co-authored-by: Julien Gacon <[email protected]>

* add a docstring to pass the pylint test

* Fix leading `.`

---------

Co-authored-by: Julien Gacon <[email protected]>
(cherry picked from commit edad499)

Co-authored-by: Jinghong Yang <[email protected]>
  • Loading branch information
mergify[bot] and yjh-bill authored Nov 14, 2024
1 parent 2bf578e commit 27d753a
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 1 deletion.
2 changes: 1 addition & 1 deletion qiskit/quantum_info/states/statevector.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ def _expectation_value_pauli(self, pauli, qargs=None):
pauli_phase = (-1j) ** pauli.phase if pauli.phase else 1

if x_mask + z_mask == 0:
return pauli_phase * np.linalg.norm(self.data)
return pauli_phase * np.linalg.norm(self.data) ** 2

if x_mask == 0:
return pauli_phase * expval_pauli_no_x(self.data, self.num_qubits, z_mask)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
fixes:
- |
Fixed a bug that caused :meth:`.Statevector.expectation_value` to yield incorrect results
for the identity operator when the statevector was not normalized.
25 changes: 25 additions & 0 deletions test/python/quantum_info/states/test_statevector.py
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,31 @@ def test_expval_pauli_qargs(self, qubits):
expval = state.expectation_value(op, qubits)
self.assertAlmostEqual(expval, target)

def test_expval_identity(self):
"""Test whether the calculation for identity operator has been fixed"""

# 1 qubit case test
state_1 = Statevector.from_label("0")
state_1_n1 = 2 * state_1 # test the same state with different norms
state_1_n2 = (1 + 2j) * state_1
identity_op_1 = SparsePauliOp.from_list([("I", 1)])
expval_state_1 = state_1.expectation_value(identity_op_1)
expval_state_1_n1 = state_1_n1.expectation_value(identity_op_1)
expval_state_1_n2 = state_1_n2.expectation_value(identity_op_1)
self.assertAlmostEqual(expval_state_1, 1.0 + 0j)
self.assertAlmostEqual(expval_state_1_n1, 4 + 0j)
self.assertAlmostEqual(expval_state_1_n2, 5 + 0j)

# Let's try a multi-qubit case
n_qubits = 3
state_coeff = 3 - 4j
op_coeff = 2 - 2j
state_test = state_coeff * Statevector.from_label("0" * n_qubits)
op_test = SparsePauliOp.from_list([("I" * n_qubits, op_coeff)])
expval = state_test.expectation_value(op_test)
target = op_coeff * np.abs(state_coeff) ** 2
self.assertAlmostEqual(expval, target)

@data(*(qargs for i in range(4) for qargs in permutations(range(4), r=i + 1)))
def test_probabilities_qargs(self, qargs):
"""Test probabilities method with qargs"""
Expand Down

0 comments on commit 27d753a

Please sign in to comment.