diff --git a/cirq-ionq/cirq_ionq/ionq_native_gates.py b/cirq-ionq/cirq_ionq/ionq_native_gates.py index e9313b0c43a..80eb49df6aa 100644 --- a/cirq-ionq/cirq_ionq/ionq_native_gates.py +++ b/cirq-ionq/cirq_ionq/ionq_native_gates.py @@ -25,18 +25,18 @@ @cirq.value.value_equality class GPIGate(cirq.Gate): - """The GPI gate is a single qubit gate. + r"""The GPI gate is a single qubit gate. The unitary of this gate is - [[0, e^{-i\\phi}], - [e^{-i\\phi}, 0]] + [[0, e^{-i*2*\pi*\phi}], + [e^{-i*2*\pi*\phi}, 0]] """ def __init__(self, *, phi): self.phi = phi def _unitary_(self) -> np.ndarray: - top = cmath.exp(self.phi * 1j) - bot = cmath.exp(-self.phi * 1j) + top = cmath.exp(self.phi * 2 * math.pi * 1j) + bot = cmath.exp(-self.phi * 2 * math.pi * 1j) return np.array([[0, top], [bot, 0]]) def __str__(self) -> str: @@ -67,10 +67,10 @@ def _circuit_diagram_info_( GPI = GPIGate(phi=0) document( GPI, - """The GPI gate is a single qubit gate. + r"""The GPI gate is a single qubit gate. The unitary of this gate is - [[0, e^{-i\\phi}], - [e^{-i\\phi}, 0]] + [[0, e^{-i*2*\pi*\phi}], + [e^{-i*2*\pi*\phi}, 0]] It is driven by Rabi laser. https://ionq.com/best-practices """, @@ -79,18 +79,18 @@ def _circuit_diagram_info_( @cirq.value.value_equality class GPI2Gate(cirq.Gate): - """The GPI2 gate is a single qubit gate. + r"""The GPI2 gate is a single qubit gate. The unitary of this gate is - \\frac{1}{/\\sqrt{2}}[[1, -i*e^{-i\\phi}], - [-i*e^{-i\\phi}, 1]] + \frac{1}{/\sqrt{2}}[[1, -i*e^{-i\phi}], + [-i*e^{-i\phi}, 1]] """ def __init__(self, *, phi): self.phi = phi def _unitary_(self) -> np.ndarray: - top = -1j * cmath.exp(self.phase * -1j) - bot = -1j * cmath.exp(self.phase * 1j) + top = -1j * cmath.exp(self.phase * 2 * math.pi * -1j) + bot = -1j * cmath.exp(self.phase * 2 * math.pi * 1j) return np.array([[1, top], [bot, 1]]) / math.sqrt(2) @property @@ -121,10 +121,10 @@ def _value_equality_values_(self) -> Any: GPI2 = GPI2Gate(phi=0) document( GPI2, - """The GPI2 gate is a single qubit gate. + r"""The GPI2 gate is a single qubit gate. The unitary of this gate is - \\frac{1}{/\\sqrt{2}}[[1, -i*e^{-i\\phi}], - [-i*e^{-i\\phi}, 1]] + \frac{1}{/\sqrt{2}}[[1, -i*e^{-i*2*\pi*\phi}], + [-i*e^{-i*2*\phi}, 1]] It is driven by Rabi laser. https://ionq.com/best-practices """, @@ -133,32 +133,36 @@ def _value_equality_values_(self) -> Any: @cirq.value.value_equality class MSGate(cirq.Gate): - """The MS gate is a 2 qubit gate. + r"""The MS gate is a 2 qubit gate. The unitary of this gate is - MS(\\phi_1 - \\phi_0) = - MS(t) = - \\frac{1}{\\sqrt{2}} - [[\\cos(t), 0, 0, -i*\\sin(t)], - [0, \\cos(t), -i*\\sin(t), 0], - [0, -i*\\sin(t), \\cos(t), 0], - [-i*\\sin(t), 0, 0, \\cos(t)]] + MS(\phi_0, \phi_1) q_0, q_1 = + \frac{1}{\sqrt{2}} + [[1, 0, 0, -i*e^{-i*2*\pi*(\phi_0+\phi_1}], + [0, 1, -i*e^{-i*2*\pi*(\phi_0-\phi_1}, 0], + [0, -i*e^{i*2*\pi*(\phi_0-\phi_1}, 1, 0], + [-i*e^{i*2*\pi*(\phi_0+\phi_1}, 0, 0, 1]] """ - def __init__(self, *, phi1, phi2): + def __init__(self, *, phi0, phi1): + self.phi0 = phi0 self.phi1 = phi1 - self.phi2 = phi2 def _unitary_(self) -> np.ndarray: - tee = self.phi2 - self.phi1 - diag = math.cos(tee) - adiag = -1j * math.sin(tee) + diag = 1 / math.sqrt(2) + phi0 = self.phi0 + phi1 = self.phi1 return np.array( - [[diag, 0, 0, adiag], [0, diag, adiag, 0], [0, adiag, diag, 0], [adiag, 0, 0, diag]] + [ + [diag, 0, 0, diag * -1j * cmath.exp(-1j * 2 * math.pi * (phi0 + phi1))], + [0, diag, diag * -1j * cmath.exp(-1j * 2 * math.pi * (phi0 - phi1)), 0], + [0, diag * -1j * cmath.exp(1j * 2 * math.pi * (phi0 - phi1)), diag, 0], + [diag * -1j * cmath.exp(1j * 2 * math.pi * (phi0 + phi1)), 0, 0, diag], + ] ) @property def phases(self) -> Sequence[float]: - return [self.phi1, self.phi2] + return [self.phi0, self.phi1] def __str__(self) -> str: return 'MS' @@ -172,27 +176,27 @@ def _circuit_diagram_info_( return protocols.CircuitDiagramInfo(wire_symbols=('MS',), exponent=self.phases) def __repr__(self) -> str: - return f'cirq_ionq.MSGate(phi1={self.phi1!r}, phi2={self.phi2!r})' + return f'cirq_ionq.MSGate(phi0={self.phi0!r}, phi1={self.phi1!r})' def _json_dict_(self) -> Dict[str, Any]: - return cirq.obj_to_dict_helper(self, ['phi1', 'phi2']) + return cirq.obj_to_dict_helper(self, ['phi0', 'phi1']) def _value_equality_values_(self) -> Any: - return (self.phi1, self.phi2) + return (self.phi0, self.phi1) -MS = MSGate(phi1=0, phi2=0) +MS = MSGate(phi0=0, phi1=0) document( MS, - """The MS gate is a 2 qubit gate. + r"""The MS gate is a 2 qubit gate. The unitary of this gate is - MS(\\phi_1 - \\phi_0) = - MS(t) = - \\frac{1}{\\sqrt{2}} - [[\\cos(t), 0, 0, -i*\\sin(t)], - [0, \\cos(t), -i*\\sin(t), 0], - [0, -i*\\sin(t), \\cos(t), 0], - [-i*\\sin(t), 0, 0, \\cos(t)]] + .. math:: + MS(\phi_0, \phi_1) q_0, q_1 = + \frac{1}{\sqrt{2}} + [[1, 0, 0, -i*e^{-i*(\phi_0+\phi_1}], + [0, 1, -i*e^{-i*(\phi_0-\phi_1}, 0], + [0, -i*e^{i*(\phi_0-\phi_1}, 1, 0], + [-i*e^{i*(\phi_0+\phi_1}, 0, 0, 1]] https://ionq.com/best-practices """, diff --git a/cirq-ionq/cirq_ionq/ionq_native_gates_test.py b/cirq-ionq/cirq_ionq/ionq_native_gates_test.py index 7e7dd425c7a..5cb98b27469 100644 --- a/cirq-ionq/cirq_ionq/ionq_native_gates_test.py +++ b/cirq-ionq/cirq_ionq/ionq_native_gates_test.py @@ -21,7 +21,7 @@ @pytest.mark.parametrize( - "gate,nqubits", [(GPIGate(phi=0.1), 1), (GPI2Gate(phi=0.2), 1), (MSGate(phi1=0.1, phi2=0.2), 2)] + "gate,nqubits", [(GPIGate(phi=0.1), 1), (GPI2Gate(phi=0.2), 1), (MSGate(phi0=0.1, phi1=0.2), 2)] ) def test_gate_methods(gate, nqubits): assert str(gate) != "" @@ -30,7 +30,7 @@ def test_gate_methods(gate, nqubits): assert cirq.protocols.circuit_diagram_info(gate) is not None -@pytest.mark.parametrize("gate", [GPIGate(phi=0.1), GPI2Gate(phi=0.2), MSGate(phi1=0.1, phi2=0.2)]) +@pytest.mark.parametrize("gate", [GPIGate(phi=0.1), GPI2Gate(phi=0.2), MSGate(phi0=0.1, phi1=0.2)]) def test_gate_json(gate): g_json = cirq.to_json(gate) assert cirq.read_json(json_text=g_json) == gate @@ -59,7 +59,7 @@ def test_gpi2_unitary(phase): ) def test_ms_unitary(phases): """Tests that the MS gate is unitary.""" - gate = MSGate(phi1=phases[0], phi2=phases[1]) + gate = MSGate(phi0=phases[0], phi1=phases[1]) mat = cirq.protocols.unitary(gate) numpy.testing.assert_array_almost_equal(mat.dot(mat.conj().T), numpy.identity(4)) diff --git a/cirq-ionq/cirq_ionq/json_test_data/MSGate.json b/cirq-ionq/cirq_ionq/json_test_data/MSGate.json index 4b2268733a4..24eea58ec5a 100644 --- a/cirq-ionq/cirq_ionq/json_test_data/MSGate.json +++ b/cirq-ionq/cirq_ionq/json_test_data/MSGate.json @@ -1,5 +1,5 @@ { "cirq_type": "MSGate", - "phi1": 0.1, - "phi2": 0.55 + "phi0": 0.1, + "phi1": 0.55 } diff --git a/cirq-ionq/cirq_ionq/json_test_data/MSGate.repr b/cirq-ionq/cirq_ionq/json_test_data/MSGate.repr index 1e1116467e1..61e1ed5152a 100644 --- a/cirq-ionq/cirq_ionq/json_test_data/MSGate.repr +++ b/cirq-ionq/cirq_ionq/json_test_data/MSGate.repr @@ -1 +1 @@ -cirq_ionq.MSGate(phi1=0.1, phi2=0.55) +cirq_ionq.MSGate(phi0=0.1, phi1=0.55) diff --git a/cirq-ionq/cirq_ionq/serializer_test.py b/cirq-ionq/cirq_ionq/serializer_test.py index 3ddca1146b3..826fca96011 100644 --- a/cirq-ionq/cirq_ionq/serializer_test.py +++ b/cirq-ionq/cirq_ionq/serializer_test.py @@ -258,7 +258,7 @@ def test_serialize_native_gates(): q0, q1, q2 = cirq.LineQubit.range(3) gpi = GPIGate(phi=0.1).on(q0) gpi2 = GPI2Gate(phi=0.2).on(q1) - ms = MSGate(phi1=0.3, phi2=0.4).on(q1, q2) + ms = MSGate(phi0=0.3, phi1=0.4).on(q1, q2) circuit = cirq.Circuit([gpi, gpi2, ms]) serializer = ionq.Serializer() result = serializer.serialize(circuit)