Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
23 changes: 12 additions & 11 deletions cirq-core/cirq/ops/pauli_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ def __mul__(self, other):
known = True
elif isinstance(other, (PauliString, numbers.Number)):
known = True
elif (as_pauli_string := _try_interpret_as_pauli_string(other)) is not None:
return self * as_pauli_string
if known:
return PauliString(
cast(PAULI_STRING_LIKE, other),
Expand All @@ -297,6 +299,8 @@ def __rmul__(self, other) -> PauliString:

if isinstance(other, raw_types.Operation) and isinstance(other.gate, identity.IdentityGate):
return self # pragma: no cover
elif (as_pauli_string := _try_interpret_as_pauli_string(other)) is not None:
return as_pauli_string * self

# Note: PauliString case handled by __mul__.
return NotImplemented
Expand Down Expand Up @@ -1103,17 +1107,14 @@ def _validate_qubit_mapping(
def _try_interpret_as_pauli_string(op: Any):
"""Return a reprepresentation of an operation as a pauli string, if it is possible."""
if isinstance(op, gate_operation.GateOperation):
gates = {
common_gates.XPowGate: pauli_gates.X,
common_gates.YPowGate: pauli_gates.Y,
common_gates.ZPowGate: pauli_gates.Z,
}
if (pauli := gates.get(type(op.gate), None)) is not None:
exponent = op.gate.exponent # type: ignore
if exponent % 2 == 0:
return PauliString()
if exponent % 2 == 1:
return pauli.on(op.qubits[0])
try:
pauli_expansion_op = protocols.pauli_expansion(op)
if pauli_expansion_op is not None and len(pauli_expansion_op) == 1:
gate, coef = next(iter(pauli_expansion_op.items()))
return coef * PauliString({q: gate for q in op.qubits})
except TypeError:
# return None if there is no Pauli expansion for this GateOperation.
pass
return None


Expand Down
8 changes: 8 additions & 0 deletions cirq-core/cirq/ops/raw_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,10 +483,18 @@ def _commutes_(self, other: Any, *, atol: float = 1e-8) -> None | NotImplemented

def _mul_with_qubits(self, qubits: tuple[cirq.Qid, ...], other):
"""cirq.GateOperation.__mul__ delegates to this method."""
from cirq.ops.pauli_string import _try_interpret_as_pauli_string

if (as_pauli_string := _try_interpret_as_pauli_string(self.on(*qubits))) is not None:
return as_pauli_string * other
return NotImplemented

def _rmul_with_qubits(self, qubits: tuple[cirq.Qid, ...], other):
"""cirq.GateOperation.__rmul__ delegates to this method."""
from cirq.ops.pauli_string import _try_interpret_as_pauli_string

if (as_pauli_string := _try_interpret_as_pauli_string(self.on(*qubits))) is not None:
return other * as_pauli_string
return NotImplemented

def _json_dict_(self) -> dict[str, Any]:
Expand Down
Loading