Skip to content

Commit

Permalink
extend fix to general PauliSumOp
Browse files Browse the repository at this point in the history
  • Loading branch information
Cryoris committed Dec 2, 2021
1 parent b7e2f6e commit 6c4fa32
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 9 deletions.
12 changes: 7 additions & 5 deletions qiskit/opflow/primitive_ops/pauli_sum_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def __init__(
f"PauliSumOp can only be instantiated with SparsePauliOp, not {type(primitive)}"
)

super().__init__(primitive, coeff=coeff)
super().__init__(primitive.copy(), coeff=coeff)
self._grouping_type = grouping_type

def primitive_strings(self) -> Set[str]:
Expand Down Expand Up @@ -210,13 +210,15 @@ def permute(self, permutation: List[int]) -> "PauliSumOp":
if length > self.num_qubits:
spop = self.primitive.tensor(SparsePauliOp(Pauli("I" * (length - self.num_qubits))))
else:
spop = self.primitive.copy()
spop = self.primitive

permuted = PauliSumOp(spop, self.coeff)

permutation = [i for i in range(length) if i not in permutation] + permutation
permu_arr = np.arange(length)[np.argsort(permutation)]
spop.paulis.x = spop.paulis.x[:, permu_arr]
spop.paulis.z = spop.paulis.z[:, permu_arr]
return PauliSumOp(spop, self.coeff)
permuted.primitive.paulis.x = permuted.primitive.paulis.x[:, permu_arr]
permuted.primitive.paulis.z = permuted.primitive.paulis.z[:, permu_arr]
return permuted

def compose(
self,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
---
fixes:
- |
Fix a bug in :meth:`qiskit.opflow.PauliSumOp.permute` where the original object on which
the method is called is permuted, instead of only returning a new, permuted copy.
This bug only occured for permutations that left the number of qubits in the operator
unchanged.
Fix a bug in the :class:`~qiskit.opflow.PauliSumOp` which previously stored the
:class:`~qiskit.quantum_info.SparsePauliOp` it was instantiated with by reference and not
by value. This led to several bugs, where e.g. the ``PauliSumOp`` was affected by changes in the
original ``SparsePauliOp`` or methods such as :meth:`~qiskit.opflow.PauliSumOp.permute` modified
the object they are called on instead of leaving them unchanged.
11 changes: 11 additions & 0 deletions test/python/opflow/test_pauli_sum_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ def test_construct(self):
self.assertEqual(pauli_sum.coeff, coeff)
self.assertEqual(pauli_sum.num_qubits, 4)

def test_primitive_is_copied(self):
"""Test the PauliSumOp is not affected by changes of the primitive after construction."""
sparse_pauli = SparsePauliOp(Pauli("X"), coeffs=[1.0])
pauli_sum = PauliSumOp(sparse_pauli)

# change SparsePauliOp from which PauliSumOp is constructed
sparse_pauli.coeffs[0] = 2

# assert PauliSumOp is unchanged
self.assertEqual(pauli_sum.primitive.coeffs[0], 1)

def test_coeffs(self):
"""ListOp.coeffs test"""
sum1 = SummedOp(
Expand Down

0 comments on commit 6c4fa32

Please sign in to comment.