Open ArfatSalman opened 1 year ago
Thank you for a detailed bug report! This is helpful!
Related: #5928
If two unitaries U1
and U2
are equal upto global phase but not identical, then their controlled versions would not be equal upto global phase because the global phase of U1
/U2
becomes local phase of CU1
and CU2
.
A classic example would X
gate and Rx
gate, both of which differ only by a global phase. For example:
>>> import cirq
>>> import numpy as np
>>> g1, g2 = cirq.X, cirq.Rx(rads=np.pi)
>>> cirq.equal_up_to_global_phase(g1, g2)
True
>>> cg1, cg2 = g1.controlled(), g2.controlled()
>>> cirq.equal_up_to_global_phase(cg1, cg2)
False
>>> cirq.unitary(cg1) # CX gate swaps 0/1 based when control is 1.
array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
[0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j]])
>>> cirq.unitary(cg2) # CRx gate swaps 0/1 and also adds a -1 phase when control is 1.
Out[14]:
array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 0.-1.j],
[0.+0.j, 0.+0.j, 0.-1.j, 0.+0.j]])
Note that the two controlled gates shown in the example above are still equivalent upto single qubit rotations (eg: prepend a Z rotation on qubit 0).
Thank you for the detailed comment, @tanujkhattar!
I think @tanujkhattar is correct about the root cause. Still, the fact that qiskit's CU3Gate(...)
and cirq's QasmUGate(...).controlled_by(...)
are inequivalent gates sounds like a problem.
Description of the issue It seems like the unitary of controlled QasmUGate is not correct with qiskit's
CU3Gate
.How to reproduce the issue
As per the docs,
U3Gate
corresponds toQasmUGate
with half turns. So I am expecting the controlled version to correspond toCU3Gate
. However, the unitaries are different for some reason.Cirq version 1.0.0