Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions cirq-core/cirq/ops/gate_operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,21 @@ def __mul__(self, other: Any) -> Any:
def __rmul__(self, other: Any) -> Any:
return self.gate._rmul_with_qubits(self._qubits, other)

def __add__(self, other):
return 1 * self + other

def __radd__(self, other):
return other + 1 * self

def __sub__(self, other):
return 1 * self - other

def __rsub__(self, other):
return other + -self

def __neg__(self):
return -1 * self

def _qasm_(self, args: protocols.QasmArgs) -> str | None:
if isinstance(self.gate, ops.GlobalPhaseGate):
warnings.warn(
Expand Down
18 changes: 4 additions & 14 deletions cirq-core/cirq/ops/linear_combinations.py
Original file line number Diff line number Diff line change
Expand Up @@ -746,10 +746,6 @@ def __iadd__(self, other):
other = PauliSum.from_pauli_strings([PauliString(coefficient=other)])
elif isinstance(other, PauliString):
other = PauliSum.from_pauli_strings([other])
elif isinstance(other, raw_types.Operation) and isinstance(
other.gate, identity.IdentityGate
):
other = PauliSum.from_pauli_strings([PauliString()])

if not isinstance(other, PauliSum):
return NotImplemented
Expand All @@ -758,10 +754,9 @@ def __iadd__(self, other):
return self

def __add__(self, other):
if not isinstance(other, (numbers.Complex, PauliString, PauliSum, raw_types.Operation)):
return NotImplemented
result = self.copy()
result += other
if result.__iadd__(other) is NotImplemented:
return NotImplemented
return result

def __radd__(self, other):
Expand All @@ -775,10 +770,6 @@ def __isub__(self, other):
other = PauliSum.from_pauli_strings([PauliString(coefficient=other)])
elif isinstance(other, PauliString):
other = PauliSum.from_pauli_strings([other])
elif isinstance(other, raw_types.Operation) and isinstance(
other.gate, identity.IdentityGate
):
other = PauliSum.from_pauli_strings([PauliString()])

if not isinstance(other, PauliSum):
return NotImplemented
Expand All @@ -787,10 +778,9 @@ def __isub__(self, other):
return self

def __sub__(self, other):
if not isinstance(other, (numbers.Complex, PauliString, PauliSum, raw_types.Operation)):
return NotImplemented
result = self.copy()
result -= other
if result.__isub__(other) is NotImplemented:
return NotImplemented
return result

def __neg__(self):
Expand Down
9 changes: 5 additions & 4 deletions cirq-core/cirq/ops/pauli_string_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2086,12 +2086,13 @@ def test_resolve(resolve_fn) -> None:
ids=str,
)
def test_pauli_ops_identity_gate_operation(gate1: cirq.Pauli, gate2: cirq.Pauli) -> None:
# TODO: Issue #7280 - Support addition and subtraction of identity gate operations.
if gate1 == gate2 == cirq.I:
pytest.skip('Not yet implemented per #7280')
q = cirq.LineQubit(0)
pauli1, pauli2 = gate1.on(q), gate2.on(q)
unitary1, unitary2 = cirq.unitary(gate1), cirq.unitary(gate2)
if gate1 == gate2 == cirq.I:
# PauliSum swallows I qubits, so resulting unitaries are dimensionless
unitary1 = unitary2 = np.array([[1]])
else:
unitary1, unitary2 = cirq.unitary(gate1), cirq.unitary(gate2)
addition = pauli1 + pauli2
assert isinstance(addition, cirq.PauliSum)
assert np.array_equal(addition.matrix(), unitary1 + unitary2)
Expand Down