Skip to content

Commit

Permalink
Reject multiplication of cirq.PauliSum inside in cirq.PauliString (
Browse files Browse the repository at this point in the history
  • Loading branch information
vtomole authored Feb 22, 2022
1 parent ca4c8e7 commit 3177647
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 8 deletions.
20 changes: 12 additions & 8 deletions cirq-core/cirq/ops/pauli_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

from cirq import value, protocols, linalg, qis
from cirq._doc import document
from cirq._import import LazyLoader
from cirq.ops import (
clifford_gate,
common_gates,
Expand All @@ -58,6 +59,9 @@
if TYPE_CHECKING:
import cirq

# Lazy imports to break circular dependencies.
linear_combinations = LazyLoader("linear_combinations", globals(), "cirq.ops.linear_combinations")

TDefault = TypeVar('TDefault')
TKey = TypeVar('TKey', bound=raw_types.Qid)
TKeyNew = TypeVar('TKeyNew', bound=raw_types.Qid)
Expand Down Expand Up @@ -289,17 +293,13 @@ def __truediv__(self, other):
return NotImplemented

def __add__(self, other):
from cirq.ops.linear_combinations import PauliSum

return PauliSum.from_pauli_strings(self).__add__(other)
return linear_combinations.PauliSum.from_pauli_strings(self).__add__(other)

def __radd__(self, other):
return self.__add__(other)

def __sub__(self, other):
from cirq.ops.linear_combinations import PauliSum

return PauliSum.from_pauli_strings(self).__sub__(other)
return linear_combinations.PauliSum.from_pauli_strings(self).__sub__(other)

def __rsub__(self, other):
return -self.__sub__(other)
Expand Down Expand Up @@ -1237,7 +1237,6 @@ def _imul_helper(self, other: 'cirq.PAULI_STRING_LIKE', sign: int):
Returns:
self on success, NotImplemented given an unknown type of value.
"""

if isinstance(other, (Mapping, PauliString, MutablePauliString)):
if isinstance(other, (PauliString, MutablePauliString)):
self.coefficient *= other.coefficient
Expand All @@ -1252,7 +1251,11 @@ def _imul_helper(self, other: 'cirq.PAULI_STRING_LIKE', sign: int):
other.gate, identity.IdentityGate
):
pass
elif isinstance(other, Iterable) and not isinstance(other, str):
elif (
isinstance(other, Iterable)
and not isinstance(other, str)
and not isinstance(other, linear_combinations.PauliSum)
):
if sign == +1:
other = reversed(list(other))
for item in other:
Expand All @@ -1265,6 +1268,7 @@ def _imul_helper(self, other: 'cirq.PAULI_STRING_LIKE', sign: int):

def _imul_helper_checkpoint(self, other: 'cirq.PAULI_STRING_LIKE', sign: int):
"""Like `_imul_helper` but guarantees no-op on error."""

if not isinstance(other, (numbers.Number, PauliString, MutablePauliString)):
other = MutablePauliString()._imul_helper(other, sign)
if other is NotImplemented:
Expand Down
2 changes: 2 additions & 0 deletions cirq-core/cirq/ops/pauli_string_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ def test_constructor_flexibility():
_ = cirq.PauliString('test')
with pytest.raises(TypeError, match='S is not a Pauli'):
_ = cirq.PauliString(qubit_pauli_map={a: cirq.S})
with pytest.raises(TypeError, match="cirq.PAULI_STRING_LIKE"):
_ = cirq.PauliString(cirq.Z(a) + cirq.Z(b))

assert cirq.PauliString(cirq.X(a)) == cirq.PauliString(qubit_pauli_map={a: cirq.X})
assert cirq.PauliString([cirq.X(a)]) == cirq.PauliString(qubit_pauli_map={a: cirq.X})
Expand Down

0 comments on commit 3177647

Please sign in to comment.