From ccb5d828e7546c6c2c9e3fabdcb537cc799dcf7a Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Wed, 11 Oct 2023 12:28:32 +0400 Subject: [PATCH 01/11] matrix representation --- src/qibo/backends/npmatrices.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/qibo/backends/npmatrices.py b/src/qibo/backends/npmatrices.py index ece8721018..7b9487d8c1 100644 --- a/src/qibo/backends/npmatrices.py +++ b/src/qibo/backends/npmatrices.py @@ -112,6 +112,9 @@ def U3(self, theta, phi, lam): dtype=self.dtype, ) + def U1q(self, theta, phi): + return self.U3(theta, phi - self.np.pi / 2, self.np.pi / 2 - phi) + @cached_property def CNOT(self): return self.np.array( From 208efbe0f2b607648bfcf5bf845ea0c99245c076 Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Wed, 11 Oct 2023 12:28:42 +0400 Subject: [PATCH 02/11] gate class --- src/qibo/gates/gates.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/qibo/gates/gates.py b/src/qibo/gates/gates.py index ecda9aafcf..ce36a01ce9 100644 --- a/src/qibo/gates/gates.py +++ b/src/qibo/gates/gates.py @@ -865,6 +865,23 @@ def _dagger(self) -> "Gate": return self.__class__(self.target_qubits[0], theta, phi, lam) +class U1q(_Un_): + def __init__(self, q, theta, phi, trainable=True): + super().__init__(q, trainable=trainable) + self.name = "u1q" + self.draw_label = "U1q" + self.nparams = 2 + self._theta, self._phi = None, None + self.init_kwargs = {"theta": theta, "phi": phi, "trainable": trainable} + self.parameter_names = ["theta", "phi"] + self.parameters = theta, phi + + def _dagger(self) -> "Gate": + """""" + theta, phi = tuple(-x for x in self.parameters) # pylint: disable=E1130 + return self.__class__(self.target_qubits[0], theta, phi) + + class CNOT(Gate): """The Controlled-NOT gate. From a28561a794e66624b58c9c21e38f4e405111cfec Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Wed, 11 Oct 2023 12:28:46 +0400 Subject: [PATCH 03/11] tests --- tests/test_gates_gates.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/test_gates_gates.py b/tests/test_gates_gates.py index 60db57a4a1..2fb9ee110e 100644 --- a/tests/test_gates_gates.py +++ b/tests/test_gates_gates.py @@ -419,6 +419,30 @@ def test_u3(backend): assert gates.U3(0, theta, phi, lam).unitary +@pytest.mark.parametrize("seed_state", list(range(1, 10 + 1))) +def test_u1q(backend, seed_state): + nqubits = 1 + theta, phi = np.random.rand(2) + + initial_state = random_statevector(2**nqubits, seed=seed_state, backend=backend) + final_state = apply_gates( + backend, [gates.U1q(0, theta, phi)], initial_state=initial_state + ) + cost, sint = np.cos(theta / 2), np.sin(theta / 2) + + matrix = np.array( + [[cost, -1j * np.exp(-1j * phi) * sint], [-1j * np.exp(1j * phi) * sint, cost]] + ) + matrix = backend.cast(matrix, dtype=matrix.dtype) + + target_state = np.dot(matrix, initial_state) + + backend.assert_allclose(final_state, target_state) + + assert not gates.U1q(0, theta, phi).clifford + assert gates.U1q(0, theta, phi).unitary + + @pytest.mark.parametrize("applyx", [False, True]) def test_cnot(backend, applyx): if applyx: From 194a9fb41a771210320413a7132d756357933064 Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Wed, 11 Oct 2023 12:39:20 +0400 Subject: [PATCH 04/11] docstring for `U1q` --- src/qibo/gates/gates.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/qibo/gates/gates.py b/src/qibo/gates/gates.py index ce36a01ce9..b9f1f2ac93 100644 --- a/src/qibo/gates/gates.py +++ b/src/qibo/gates/gates.py @@ -866,6 +866,31 @@ def _dagger(self) -> "Gate": class U1q(_Un_): + """Native single-qubit gate in the Quantinuum platform. + + Corresponds to the following unitary matrix: + + .. math:: + \\begin{pmatrix} + \\cos\\left(\\frac{\\theta}{2}\\right) & + -i \\, e^{-i \\, \\phi} \\, \\sin\\left(\\frac{\\theta}{2}\\right) \\\\ + -i \\, e^{i \\, \\phi} \\, \\sin\\left(\\frac{\\theta}{2}\\right) & + \\cos\\left(\\frac{\\theta}{2}\\right) \\\\ + \\end{pmatrix} + + Note that + :math:`U_{1q}(\\theta, \\phi) = U_{3}(\\theta, \\phi - \\frac{\\pi}{2}, \\frac{\\pi}{2} - \\phi)`, + where :math:`U_{3}` is :class:`qibo.gates.U3`. + + Args: + q (int): the qubit id number. + theta (float): first rotation angle. + phi (float): second rotation angle. + trainable (bool): whether gate parameters can be updated using + :meth:`qibo.models.circuit.Circuit.set_parameters`. + Defaults to ``True``. + """ + def __init__(self, q, theta, phi, trainable=True): super().__init__(q, trainable=trainable) self.name = "u1q" From 72b7ce75781742568afe10e3084ab01406508b2a Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Wed, 11 Oct 2023 13:00:29 +0400 Subject: [PATCH 05/11] api reference --- doc/source/api-reference/qibo.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/doc/source/api-reference/qibo.rst b/doc/source/api-reference/qibo.rst index 574c4568c1..0d00b1830c 100644 --- a/doc/source/api-reference/qibo.rst +++ b/doc/source/api-reference/qibo.rst @@ -744,6 +744,23 @@ Mølmer–Sørensen (MS) :members: :member-order: bysource +Quantinuum native gates +^^^^^^^^^^^^^^^^^^^^^^^ + +U1q +""" + +.. autoclass:: qibo.gates.U1q + :members: + :member-order: bysource + +.. note:: + Note that the other Quantinuum single-qubit and two-qubit native gates are + implemented in Qibo as: + - Pauli-:math:`Z` rotation: :class:`qibo.gates.RZ` + - Arbitrary :math:`ZZ` rotation: :class:`qibo.gates.RZZ` + - Fully-entangling :math:`ZZ`-interaction: :math:`R_{ZZ}(\\pi/2)` + _______________________ From 12bf356ef541b3698f45737b4dab0b2fdb99ccd9 Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Wed, 11 Oct 2023 13:14:04 +0400 Subject: [PATCH 06/11] fix to `SYC` docstring --- src/qibo/gates/gates.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qibo/gates/gates.py b/src/qibo/gates/gates.py index b9f1f2ac93..6f1ab1a7cc 100644 --- a/src/qibo/gates/gates.py +++ b/src/qibo/gates/gates.py @@ -1505,7 +1505,7 @@ class SYC(Gate): Corresponding to the following unitary matrix .. math:: - \\text{fSim}(\\pi / 2, \\, \\pi / 6) = \\beging{pmatrix} + \\text{fSim}(\\pi / 2, \\, \\pi / 6) = \\begin{pmatrix} 1 & 0 & 0 & 0 \\\\ 0 & 0 & -i & 0 \\\\ 0 & -i & 0 & 0 \\\\ From bea5b82da9282ca65b4276f422fee6af9f9bd9f9 Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Wed, 11 Oct 2023 13:43:07 +0400 Subject: [PATCH 07/11] introducing docstring bug back --- src/qibo/gates/gates.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qibo/gates/gates.py b/src/qibo/gates/gates.py index bd0a957e54..5ccc832d5d 100644 --- a/src/qibo/gates/gates.py +++ b/src/qibo/gates/gates.py @@ -1541,7 +1541,7 @@ class SYC(Gate): Corresponding to the following unitary matrix .. math:: - \\text{fSim}(\\pi / 2, \\, \\pi / 6) = \\begin{pmatrix} + \\text{fSim}(\\pi / 2, \\, \\pi / 6) = \\beging{pmatrix} 1 & 0 & 0 & 0 \\\\ 0 & 0 & -i & 0 \\\\ 0 & -i & 0 & 0 \\\\ From dd8e3c2f71b9932d853789b186a85e602d3825e8 Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Wed, 11 Oct 2023 14:24:35 +0400 Subject: [PATCH 08/11] fix coverage --- tests/test_gates_gates.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_gates_gates.py b/tests/test_gates_gates.py index f271ba706a..0a44653edf 100644 --- a/tests/test_gates_gates.py +++ b/tests/test_gates_gates.py @@ -1432,6 +1432,7 @@ def test_controlled_unitary_matrix(backend): ("U1", (0, 0.1)), ("U2", (0, 0.2, 0.3)), ("U3", (0, 0.1, 0.2, 0.3)), + ("U1q", (0, 0.1, 0.2)), ("CNOT", (0, 1)), ("CZ", (0, 1)), ("CSX", (0, 1)), From ba85ec5583b658a7c4d7059ae730f478bedd502f Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Wed, 11 Oct 2023 15:03:03 +0400 Subject: [PATCH 09/11] fix `dagger` implementation --- src/qibo/gates/gates.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qibo/gates/gates.py b/src/qibo/gates/gates.py index 5ccc832d5d..cfcad471c3 100644 --- a/src/qibo/gates/gates.py +++ b/src/qibo/gates/gates.py @@ -930,8 +930,8 @@ def __init__(self, q, theta, phi, trainable=True): def _dagger(self) -> "Gate": """""" - theta, phi = tuple(-x for x in self.parameters) # pylint: disable=E1130 - return self.__class__(self.target_qubits[0], theta, phi) + theta, phi = self.parameters + return self.__class__(self.target_qubits[0], -theta, phi) class CNOT(Gate): From 5dca61cd89572778292ba0c030e4df332d86c599 Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Wed, 11 Oct 2023 16:01:07 +0400 Subject: [PATCH 10/11] fix `pylint` error --- src/qibo/gates/gates.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qibo/gates/gates.py b/src/qibo/gates/gates.py index cfcad471c3..05acf4a5b2 100644 --- a/src/qibo/gates/gates.py +++ b/src/qibo/gates/gates.py @@ -930,8 +930,8 @@ def __init__(self, q, theta, phi, trainable=True): def _dagger(self) -> "Gate": """""" - theta, phi = self.parameters - return self.__class__(self.target_qubits[0], -theta, phi) + theta, phi = self.init_kwargs["theta"], self.init_kwargs["phi"] + return self.__class__(self.init_args[0], -theta, phi) class CNOT(Gate): From f62c2232b61040b553754e9f559dade378a5cf23 Mon Sep 17 00:00:00 2001 From: Renato Mello Date: Thu, 12 Oct 2023 11:46:16 +0000 Subject: [PATCH 11/11] Update doc/source/api-reference/qibo.rst Co-authored-by: Stavros Efthymiou <35475381+stavros11@users.noreply.github.com> --- doc/source/api-reference/qibo.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/api-reference/qibo.rst b/doc/source/api-reference/qibo.rst index 47e0aa1050..e1d2887865 100644 --- a/doc/source/api-reference/qibo.rst +++ b/doc/source/api-reference/qibo.rst @@ -755,7 +755,7 @@ U1q :member-order: bysource .. note:: - Note that the other Quantinuum single-qubit and two-qubit native gates are + The other Quantinuum single-qubit and two-qubit native gates are implemented in Qibo as: - Pauli-:math:`Z` rotation: :class:`qibo.gates.RZ` - Arbitrary :math:`ZZ` rotation: :class:`qibo.gates.RZZ`