-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Provide native support for U3 gate #7717
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
base: main
Are you sure you want to change the base?
Changes from all commits
5776456
764c63a
b72a3dc
82921d8
319d0be
fa75343
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -75,10 +75,12 @@ def __repr__(self) -> str: | |||||
|
|
||||||
| def _decompose_(self, qubits): | ||||||
| q = qubits[0] | ||||||
| phase_correction_half_turns = (self.phi + self.lmda) / 2 | ||||||
| return [ | ||||||
| ops.rz(self.lmda * np.pi).on(q), | ||||||
| ops.ry(self.theta * np.pi).on(q), | ||||||
| ops.rz(self.phi * np.pi).on(q), | ||||||
| ops.global_phase_operation(1j ** (2 * phase_correction_half_turns)), | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to divide by two above only to multiply by two here
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ack. I worked through the multiplication of |
||||||
| ] | ||||||
|
|
||||||
| def _value_equality_values_(self): | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -29,6 +29,17 @@ def _make_qubits(n): | |||||||||||||
| return [cirq.NamedQubit(f'q{i}') for i in range(n)] | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| def _qiskit_unitary(gate: QasmUGate) -> np.ndarray: | ||||||||||||||
| # Ref: https://quantum.cloud.ibm.com/docs/en/api/qiskit/qiskit.circuit.library.U3Gate#u3gate | ||||||||||||||
| th, ph, lm = np.pi * np.array([gate.theta, gate.phi, gate.lmda]) | ||||||||||||||
|
Comment on lines
+32
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would change this to a generating function for just the matrix, so it can be used for some additional tests suggested below
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, I am sure other people are better with keeping track of angle conventions between cirq and qasm. The intent in passing a gate was to avoid having to know angle units when calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enough, I would at least rename to |
||||||||||||||
| return np.array( | ||||||||||||||
| [ | ||||||||||||||
| [np.cos(th / 2), -np.exp(1j * lm) * np.sin(th / 2)], | ||||||||||||||
| [np.exp(1j * ph) * np.sin(th / 2), np.exp(1j * (ph + lm)) * np.cos(th / 2)], | ||||||||||||||
| ] | ||||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| def test_u_gate_repr() -> None: | ||||||||||||||
| gate = QasmUGate(0.1, 0.2, 0.3) | ||||||||||||||
| assert repr(gate) == 'cirq.circuits.qasm_output.QasmUGate(theta=0.1, phi=0.2, lmda=0.3)' | ||||||||||||||
|
|
@@ -53,13 +64,14 @@ def test_qasm_u_qubit_gate_unitary() -> None: | |||||||||||||
| u = cirq.testing.random_unitary(2) | ||||||||||||||
| g = QasmUGate.from_matrix(u) | ||||||||||||||
| cirq.testing.assert_allclose_up_to_global_phase(cirq.unitary(g), u, atol=1e-7) | ||||||||||||||
|
|
||||||||||||||
| cirq.testing.assert_implements_consistent_protocols(g) | ||||||||||||||
| np.testing.assert_allclose(cirq.unitary(g), _qiskit_unitary(g), atol=1e-7) | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
|
|
||||||||||||||
| u = cirq.unitary(cirq.Y) | ||||||||||||||
| g = QasmUGate.from_matrix(u) | ||||||||||||||
| cirq.testing.assert_allclose_up_to_global_phase(cirq.unitary(g), u, atol=1e-7) | ||||||||||||||
| cirq.testing.assert_implements_consistent_protocols(g) | ||||||||||||||
| np.testing.assert_allclose(cirq.unitary(g), _qiskit_unitary(g), atol=1e-7) | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| def test_qasm_two_qubit_gate_unitary() -> None: | ||||||||||||||
|
|
@@ -200,7 +212,7 @@ def test_h_gate_with_parameter() -> None: | |||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| def test_qasm_global_pahse() -> None: | ||||||||||||||
| def test_qasm_global_phase() -> None: | ||||||||||||||
| output = cirq.QasmOutput((cirq.global_phase_operation(np.exp(1j * 5))), ()) | ||||||||||||||
| assert ( | ||||||||||||||
| str(output) | ||||||||||||||
|
|
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.