Cirq icon indicating copy to clipboard operation
Cirq copied to clipboard

`Xa*Zb*Zb*Zb` works but `Xa*Zb**3` raises error

Open tanujkhattar opened this issue 3 years ago • 2 comments

How to reproduce the issue

In [1]: import cirq
   ...: a, b = cirq.LineQubit.range(2)
   ...: Xa, Zb = cirq.X(a), cirq.Z(b)
   ...: print(Xa * Zb * Zb * Zb) # Works because always stays a `cirq.PauliString`. 
   ...: print(Xa * Zb ** 3) # Fails because Zb ** 3 returns a `cirq.ZPowGate` instead of `cirq._PauliZ`; which doesn't support multiplication with other pauli's.

X(q(0))*Z(q(1))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-402c68ab82e4> in <module>
      3 Xa, Zb = cirq.X(a), cirq.Z(b)
      4 print(Xa * Zb * Zb * Zb) # Works because always stays a `cirq.PauliString`.
----> 5 print(Xa * Zb ** 3) # Fails because Zb ** 3 returns a `cirq.ZPowGate` instead of `cirq._PauliZ`; which doesn't support multiplication with other pauli's.

TypeError: unsupported operand type(s) for *: 'SingleQubitPauliStringGateOperation' and 'GateOperation'

Cirq version: 0.16.0.dev

tanujkhattar avatar Jul 11 '22 17:07 tanujkhattar

From cirq sync:

Looks like a bug and should be fixed. Should not be categorized as a breaking change.

tanujkhattar avatar Aug 03 '22 18:08 tanujkhattar

Would this be a good first issue to look into. If so could this be assigned to me?

saeubank avatar Aug 07 '22 17:08 saeubank

Kinda think this is not possible. Presumably it should work for even exponents too. However to work for even exponents, the gate needs to transform to cirq.I. However that ends up causing all sorts of downstream problems (even after making cirq.I an EigenGate) as can be seen in the linked PR above because cirq.I is special cased so much. Additionally it breaks all the eval(repr(x)) == x etc. protocol tests.

daxfohl avatar Nov 05 '22 03:11 daxfohl

Well, it's possible, as I managed to get the linked PR to pass all tests. The changes are probably more breaking than desired though. And we need to add some extra handling and tests since IdentityGate, as an EigenGate, can now have a phase attached.

It also leaves Xa*Xa != Xa**2, which seems wrong. I think to solve this completely we'd need a _PauliI (which may be reasonable? Not sure.)

daxfohl avatar Nov 05 '22 18:11 daxfohl

Nvm, different approach worked.

daxfohl avatar Nov 05 '22 21:11 daxfohl

Nvm again. The second approach had an issue with PauliString(X(q)**2) turning into PauliString() and then losing the qubit and thus changing the commutation properties. To fix that we'd need to make I a paulistring option, which then we'd have to get into making a _PauliI, and then making Identity an EigenGate like in the first attempt. Doable, but a big change that needs some back-and-forth design and approvals since its backwards compatibility is questionable.

Would be a good issue though for someone with more time to contribute.

daxfohl avatar Nov 06 '22 03:11 daxfohl