mirror of https://github.com/Qiskit/qiskit.git
Fix setter so that `SparsePauliOp.paulis.phase` stays zero (#12884)
* absorb `phase` into `coeffs` in `paulis()` setter * do not mutate input array * add test that paulis setter absorbs phase * lint * If input paulis have phase, mutate and warn * add release note * release-note formatting * add test with `simplify()` * remove phase-warning from paulis setter * lint * remove unused import * update reno
This commit is contained in:
parent
48cca36078
commit
8c74a49dcd
|
@ -256,6 +256,8 @@ class SparsePauliOp(LinearOp):
|
|||
raise ValueError(
|
||||
f"incorrect number of operators: expected {len(self.paulis)}, got {len(value)}"
|
||||
)
|
||||
self.coeffs *= (-1j) ** value.phase
|
||||
value.phase = 0
|
||||
self._pauli_list = value
|
||||
|
||||
@property
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixed a bug when :attr:`.SparsePauliOp.paulis` is set to be a :class:`.PauliList` with nonzero
|
||||
phase, where subsequent calls to several :class:`.SparsePauliOp` methods would produce
|
||||
incorrect results. Now when :attr:`.SparsePauliOp.paulis` is set to a :class:`.PauliList` with
|
||||
nonzero phase, the phase is absorbed into :attr:`.SparsePauliOp.coeffs`, and the phase of the
|
||||
input :class:`.PauliList` is set to zero.
|
|
@ -1097,6 +1097,25 @@ class TestSparsePauliOpMethods(QiskitTestCase):
|
|||
with self.assertRaisesRegex(ValueError, "incorrect number of operators"):
|
||||
op.paulis = PauliList([Pauli("XY"), Pauli("ZX"), Pauli("YZ")])
|
||||
|
||||
def test_paulis_setter_absorbs_phase(self):
|
||||
"""Test that the setter for `paulis` absorbs `paulis.phase` to `self.coeffs`."""
|
||||
coeffs_init = np.array([1, 1j])
|
||||
op = SparsePauliOp(["XY", "ZX"], coeffs=coeffs_init)
|
||||
paulis_new = PauliList(["-1jXY", "1jZX"])
|
||||
op.paulis = paulis_new
|
||||
# Paulis attribute should have no phase:
|
||||
self.assertEqual(op.paulis, PauliList(["XY", "ZX"]))
|
||||
# Coeffs attribute should now include that phase:
|
||||
self.assertTrue(np.allclose(op.coeffs, coeffs_init * np.array([-1j, 1j])))
|
||||
# The phase of the input array is now zero:
|
||||
self.assertTrue(np.allclose(paulis_new.phase, np.array([0, 0])))
|
||||
|
||||
def test_paulis_setter_absorbs_phase_2(self):
|
||||
"""Test that `paulis` setter followed by `simplify()` handle phase OK."""
|
||||
spo = SparsePauliOp(["X", "X"])
|
||||
spo.paulis = ["X", "-X"]
|
||||
self.assertEqual(spo.simplify(), SparsePauliOp(["I"], coeffs=[0.0 + 0.0j]))
|
||||
|
||||
def test_apply_layout_with_transpile(self):
|
||||
"""Test the apply_layout method with a transpiler layout."""
|
||||
psi = EfficientSU2(4, reps=4, entanglement="circular")
|
||||
|
|
Loading…
Reference in New Issue