Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Different outputs for U3Gate and QasmUGate #5928

Closed
ArfatSalman opened this issue Oct 24, 2022 · 4 comments · Fixed by #5945
Closed

Different outputs for U3Gate and QasmUGate #5928

ArfatSalman opened this issue Oct 24, 2022 · 4 comments · Fixed by #5945
Assignees
Labels
area/gates kind/bug-report Something doesn't seem to work. triage/accepted there is consensus amongst maintainers that this is a real bug or a reasonable feature to add

Comments

@ArfatSalman
Copy link

Description of the issue

These two equivalent circuits show different outputs.

How to reproduce the issue

Qiskit (version 0.37)

from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit import Aer, transpile, execute
from qiskit.circuit.library.standard_gates import U3Gate

qr = QuantumRegister(1, name='qr')
cr = ClassicalRegister(1, name='cr')
qc = QuantumCircuit(qr, cr, name='qc')

qc.append(U3Gate(4.690513260097172,1.1919742794819272,2.1795142072537406), qargs=[qr[0]], cargs=[])

qc.measure(qr, cr)

qc = transpile(qc)

backend = Aer.get_backend('qasm_simulator')
counts = execute(qc, backend=backend, shots=7838).result().get_counts(qc)
# {'0': 3731, '1': 4107}
import cirq
from cirq.circuits.qasm_output import QasmUGate
from functools import reduce

qr = [cirq.NamedQubit('q' + str(i)) for i in range(1)]
circuit = cirq.Circuit(
  QasmUGate(4.690513260097172, 1.1919742794819272, 2.1795142072537406)(qr[0]), 
  cirq.measure(qr[0], key='cr0')
)

simulator = cirq.Simulator()
result = simulator.run(circuit, repetitions=7838)
result_dict = dict(result.multi_measurement_histogram(keys=['cr0']))
# {(1,): 6137, (0,): 1701}

The documentation here at Gate conversion rules states that QASM u3(θ,φ,λ) is equaivalent to QasmUGate(θ,φ,λ) (as far as I could tell). So I'm not sure why the outputs are different. Interestingly, if I use circuit_from_qasm, and generate a circuit from qiskit's QASM, I get correct (in this case, similar to qiskit) result.

The documentation (and also this issue) leads me to believe that the u3 and QasmUGate are equivalent. Using circuit_from_qasm works, but using the gate directly doesn't seem to. Am I missing something?

Cirq version
1.0.0

@ArfatSalman ArfatSalman added the kind/bug-report Something doesn't seem to work. label Oct 24, 2022
@daxfohl
Copy link
Contributor

daxfohl commented Oct 24, 2022

I'm not a maintainer but I believe qiskit is in radians whereas cirq is in half-turns. Try dividing the angles by pi?

@viathor
Copy link
Collaborator

viathor commented Nov 8, 2022

As @daxfohl said, QasmUGate takes half-turns, not radians, so the angles must be divided by pi. To confirm, I ran

import numpy as np

import cirq
from cirq.circuits.qasm_output import QasmUGate

from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit import Aer, transpile, execute
from qiskit.circuit.library.standard_gates import U3Gate

theta = 4.690513260097172
phi = 1.1919742794819272
lmbda = 2.1795142072537406

# Cirq:
qr = [cirq.NamedQubit('q' + str(i)) for i in range(1)]
circuit = cirq.Circuit(
    QasmUGate(theta / np.pi, phi / np.pi, lmbda / np.pi)(qr[0]),
    cirq.measure(qr[0], key='cr0'),
)
u1 = cirq.unitary(circuit)
print('unitary according to cirq:')
print(u1)

# Qiskit:
qr = QuantumRegister(1, name='qr')
cr = ClassicalRegister(1, name='cr')
qc = QuantumCircuit(qr, cr, name='qc')
qc.append(U3Gate(theta, phi, lmbda), qargs=[qr[0]], cargs=[])
qc = transpile(qc)
backend = Aer.get_backend('unitary_simulator')
u2 = execute(qc, backend).result().get_unitary(qc)
print('unitary according to qiskit:')
print(u2)

# Comparison:
print('equal up to global phase?')
print(cirq.equal_up_to_global_phase(u1, u2))

and got

unitary according to cirq:
[[ 0.08020966+0.69471535j -0.62941756-0.33877799j]
 [ 0.62941756-0.33877799j  0.08020966-0.69471535j]]
unitary according to qiskit:
Operator([[-0.6993304 +8.56432739e-17j,  0.40873333-5.86407753e-01j],
          [ 0.2643513 +6.64120002e-01j,  0.68093112+1.59360684e-01j]],
         input_dims=(2,), output_dims=(2,))
equal up to global phase?
True

@viathor viathor closed this as completed Nov 8, 2022
@viathor
Copy link
Collaborator

viathor commented Nov 8, 2022

Note that documentation is explicit about the units.

@viathor
Copy link
Collaborator

viathor commented Nov 8, 2022

Actually, not everywhere.

@viathor viathor reopened this Nov 8, 2022
@viathor viathor added triage/accepted there is consensus amongst maintainers that this is a real bug or a reasonable feature to add area/gates labels Nov 8, 2022
CirqBot pushed a commit that referenced this issue Nov 9, 2022
@viathor viathor self-assigned this Dec 13, 2022
rht pushed a commit to rht/Cirq that referenced this issue May 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/gates kind/bug-report Something doesn't seem to work. triage/accepted there is consensus amongst maintainers that this is a real bug or a reasonable feature to add
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants