Cirq icon indicating copy to clipboard operation
Cirq copied to clipboard

PauliString.after() crashes for Clifford gate PhXZ(a=0.25,x=-1,z=0) in _decompose_into_cliffords

Open babacry opened this issue 11 months ago • 10 comments

Description of the issue

PauliString.after() should be able to return a PauliString with Clifford ops input, but failed for the Clifford gate PhasedXZGate(axis_phase_exponent=0.25, x_exponent=-1,z_exponent=0).

How to reproduce the issue

>>> a = cirq.NamedQubit('a')
>>> ps = cirq.PauliString() * cirq.Y(a)
>>> phxz = cirq.PhasedXZGate(axis_phase_exponent=0.25, x_exponent=-1,z_exponent=0)
>>> ps.after(phxz.on(a))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/google/home/renyichen/miniconda3/envs/cirq-conda/lib/python3.10/site-packages/cirq/ops/pauli_string.py", line 1008, in after
    return self.conjugated_by(protocols.inverse(ops))
  File "/usr/local/google/home/renyichen/miniconda3/envs/cirq-conda/lib/python3.10/site-packages/cirq/ops/pauli_string.py", line 987, in conjugated_by
    for clifford_op in _decompose_into_cliffords(op)[::-1]:
  File "/usr/local/google/home/renyichen/miniconda3/envs/cirq-conda/lib/python3.10/site-packages/cirq/ops/pauli_string.py", line 1606, in _decompose_into_cliffords
    return [out for sub_op in decomposed for out in _decompose_into_cliffords(sub_op)]
  File "/usr/local/google/home/renyichen/miniconda3/envs/cirq-conda/lib/python3.10/site-packages/cirq/ops/pauli_string.py", line 1606, in <listcomp>
    return [out for sub_op in decomposed for out in _decompose_into_cliffords(sub_op)]
  File "/usr/local/google/home/renyichen/miniconda3/envs/cirq-conda/lib/python3.10/site-packages/cirq/ops/pauli_string.py", line 1608, in _decompose_into_cliffords
    raise TypeError(
TypeError: Operation is not a known Clifford and did not decompose into known Cliffords: (cirq.T**-1).on(cirq.NamedQubit('a'))

Cirq version

1.5.0.dev20250109234340

babacry avatar Jan 13 '25 20:01 babacry

cirq-sync: convert the gate to a Clifford and detect global phase (Which the clifford gate will ignore)

NoureldinYosri avatar Jan 22 '25 18:01 NoureldinYosri

Interested in investigating and trying to fix this.

babacry avatar Jan 23 '25 19:01 babacry

@babacry thanks Renyi, the fix we suggest is the same as you did in your PR + preserving the global phase

NoureldinYosri avatar Jan 24 '25 18:01 NoureldinYosri

Thanks for the info, noted!

babacry avatar Jan 24 '25 19:01 babacry

Global phases in the Clifford gate won't affect the conjugate_by(), after(), before() results as global phase commute with other gates,

$$ (GC) \cdot P \cdot (GC)^\dagger = C \cdot P \cdot C^\dagger $$

where $\mathrm{G}=k\mathrm{I}$ is the global phase gate, $C$ is Clifford gate, $P$ is Pauli gate.

Directly using cirq.CliffordGate.from_op_list() before calling _decompose_into_cliffords works for the phxz gate mentioned above, but doesn't work for all the use cases.

Investigating the recursive decomposition logic and trying to sort things out with a clean solution.

babacry avatar Jan 28 '25 03:01 babacry

Global phases in the Clifford gate won't affect the conjugate_by(), after(), before()

good observation .. I forgot we were conjugating.

but doesn't work for all the use cases

which cases break it?

NoureldinYosri avatar Jan 28 '25 03:01 NoureldinYosri

Thanks for the comments!

The test case failed in ISwapPowGate as this gate type doesn't have _has_stabilizer_effect_, fixed in the first commit of the PR.

The 2nd commit of the PR fix the issue itself.

babacry avatar Feb 04 '25 00:02 babacry

#7103

babacry avatar Feb 28 '25 01:02 babacry

#7294

babacry avatar Apr 23 '25 23:04 babacry

Other than deprecating pass_operations_over in #7294, I still need to update the inplace_before() and inplace_after() of PauliString, then we may fully remove _decompose_into_cliffords() etc.

babacry avatar Apr 30 '25 22:04 babacry