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

Add gates.GeneralizedRBS gate #1373

Merged
merged 45 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
5c8ac5c
matrix form
renatomello Jun 26, 2024
48156a3
gate class
renatomello Jun 26, 2024
0e2ed8b
gate decomposition
renatomello Jun 26, 2024
41a3301
remove print
renatomello Jun 26, 2024
0a68c74
docstring + api ref
renatomello Jun 26, 2024
db8410b
fix lint error
renatomello Jun 26, 2024
01ea9b7
remove dagger
renatomello Jun 26, 2024
684d522
test
renatomello Jun 26, 2024
eb3ba1d
fix decomposition
renatomello Jun 26, 2024
e7732e6
save phases in arguments
renatomello Jun 26, 2024
c193c6b
point to `qibojit` branch
renatomello Jun 26, 2024
b11fbba
updated docstring
renatomello Jun 26, 2024
fcc7f40
add reference
renatomello Jun 26, 2024
27fffd7
fix matrix in docstring
renatomello Jun 26, 2024
2ce6f99
improve doctring and fix api ref
renatomello Jun 27, 2024
002688e
fix docstring math input
renatomello Jun 27, 2024
9d6c68b
Merge branch 'master' into grbs
renatomello Jun 28, 2024
b25d790
Merge branch 'master' into grbs
renatomello Jun 28, 2024
42a84ac
Merge branch 'master' into grbs
renatomello Jul 1, 2024
66433da
lock file
renatomello Jul 1, 2024
f62e490
Merge branch 'master' into grbs
renatomello Jul 4, 2024
e5031c6
Merge branch 'master' into grbs
renatomello Jul 5, 2024
97f2afe
minor fix
renatomello Jul 9, 2024
a36dd7a
Merge branch 'master' into grbs
renatomello Jul 12, 2024
7c778b4
remove lock
renatomello Jul 12, 2024
d09b79f
new lock
renatomello Jul 12, 2024
2916356
Merge branch 'master' into grbs
renatomello Jul 13, 2024
c9acf60
lock file
renatomello Jul 13, 2024
3b1eb9d
Merge branch 'master' into grbs
renatomello Jul 16, 2024
6f1c788
lock file
renatomello Jul 16, 2024
329affe
fixx parameter casting
renatomello Jul 17, 2024
dbe06a6
Merge branch 'master' into grbs
renatomello Jul 17, 2024
797d05d
Merge branch 'master' into grbs
renatomello Jul 20, 2024
1fa4d58
Merge branch 'master' into grbs
renatomello Jul 20, 2024
de9149c
new lock file
renatomello Jul 20, 2024
4e96684
Merge branch 'master' into grbs
renatomello Jul 25, 2024
02005e0
Merge branch 'master' into grbs
renatomello Jul 30, 2024
5dbc88e
Merge branch 'master' into grbs
renatomello Jul 31, 2024
8f1a989
Merge branch 'master' into grbs
renatomello Jul 31, 2024
a3587c1
Merge branch 'master' into grbs
renatomello Aug 8, 2024
0913d80
update lock
renatomello Aug 8, 2024
e6b5aa0
Merge branch 'master' into grbs
renatomello Aug 8, 2024
1c0ed7f
Merge branch 'master' into grbs
renatomello Aug 14, 2024
58541ab
Merge branch 'master' into grbs
renatomello Aug 14, 2024
3e83876
updating poetry
scarrazza Aug 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions doc/source/api-reference/qibo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,15 @@ Deutsch
:members:
:member-order: bysource


Generalized Reconfigurable Beam Splitter (RBS)
""""""""""""""""""""""""""""""""""""""""""""""

.. autoclass:: qibo.gates.GeneralizedRBS
:members:
:member-order: bysource


Arbitrary unitary
"""""""""""""""""

Expand Down
34 changes: 12 additions & 22 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pylint = "3.1.0"
matplotlib = "^3.7.0"
tensorflow = { version = "^2.16.1", markers = "sys_platform == 'linux'" }
torch = "^2.1.1"
qibojit = { git = "https://github.com/qiboteam/qibojit.git" }
qibojit = { git = "https://github.com/qiboteam/qibojit.git" , branch = "grbs" }
qibotn = { git = "https://github.com/qiboteam/qibotn.git" }
stim = "^1.12.0"

Expand All @@ -91,7 +91,7 @@ optional = true
[tool.poetry.group.cuda11.dependencies]
cupy-cuda11x = "^12.0.0"
cuquantum-python-cu11 = "^23.3.0"
qibojit = { git = "https://github.com/qiboteam/qibojit.git" }
qibojit = { git = "https://github.com/qiboteam/qibojit.git" , branch = "grbs" }
qibotn = { git = "https://github.com/qiboteam/qibotn.git" }


Expand All @@ -101,7 +101,7 @@ optional = true
[tool.poetry.group.cuda12.dependencies]
cupy-cuda12x = "^12.0.0"
cuquantum-python-cu12 = "^23.3.0"
qibojit = { git = "https://github.com/qiboteam/qibojit.git" }
qibojit = { git = "https://github.com/qiboteam/qibojit.git" , branch = "grbs" }
qibotn = { git = "https://github.com/qiboteam/qibotn.git" }

[tool.poetry.extras]
Expand Down
23 changes: 23 additions & 0 deletions src/qibo/backends/npmatrices.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,29 @@ def DEUTSCH(self, theta):
dtype=self.dtype,
)

def GeneralizedRBS(self, qubits_in, qubits_out, theta, phi):
renatomello marked this conversation as resolved.
Show resolved Hide resolved
bitstring_length = len(qubits_in) + len(qubits_out)
integer_in = "".join(
["1" if k in qubits_in else "0" for k in range(bitstring_length)]
)
integer_in = int(integer_in, 2)
integer_out = "".join(
["1" if k in qubits_out else "0" for k in range(bitstring_length)]
)
integer_out = int(integer_out, 2)

matrix = [
[1 + 0j if l == k else 0j for l in range(2**bitstring_length)]
for k in range(2**bitstring_length)
]
exp, sin, cos = self.np.exp(1j * phi), self.np.sin(theta), self.np.cos(theta)
matrix[integer_in][integer_in] = exp * cos
matrix[integer_in][integer_out] = -exp * sin
matrix[integer_out][integer_in] = self.np.conj(exp) * sin
matrix[integer_out][integer_out] = self.np.conj(exp) * cos

return self._cast(matrix, dtype=self.dtype)

def Unitary(self, u):
return self.np.array(u, dtype=self.dtype, copy=False)

Expand Down
12 changes: 10 additions & 2 deletions src/qibo/backends/numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,21 @@ def matrix(self, gate):
_matrix = getattr(self.matrices, name)
if callable(_matrix):
_matrix = _matrix(2 ** len(gate.target_qubits))

return self.cast(_matrix, dtype=_matrix.dtype)

def matrix_parametrized(self, gate):
"""Convert a parametrized gate to its matrix representation in the computational basis."""
name = gate.__class__.__name__
matrix = getattr(self.matrices, name)(*gate.parameters)
matrix = getattr(self.matrices, name)
if name == "GeneralizedRBS":
matrix = matrix(
qubits_in=gate.init_args[0],
qubits_out=gate.init_args[1],
theta=gate.init_kwargs["theta"],
phi=gate.init_kwargs["phi"],
)
else:
matrix = matrix(*gate.parameters)
return self.cast(matrix, dtype=matrix.dtype)

def matrix_fused(self, fgate):
Expand Down
74 changes: 73 additions & 1 deletion src/qibo/gates/gates.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import math
from typing import List
from typing import List, Tuple, Union

import numpy as np

Expand Down Expand Up @@ -2469,6 +2469,78 @@ def __init__(self, q0, q1, q2, theta, trainable=True):
self.init_kwargs = {"theta": theta, "trainable": trainable}


class GeneralizedRBS(ParametrizedGate):
"""The generalized (complex) Reconfigurable Beam Splitter gate (:math:`\\text{gRBS}`).

Given a register called ``qubits_in`` containing :math:`m` qubits and a
register named ``qubits_out`` containing :math:`m'` qubits, the :math:`\\text{gRBS}`
is a :math:`(m + m')`-qubit gate that has the following matrix representation:

.. math::

\\begin{pmatrix}
I & & & & \\\\
& e^{-i\\phi}\\cos\\theta & & e^{-i\\phi}\\sin\\theta & \\\\
& & I' & & \\\\
& -e^{i\\phi}\\sin\\theta & & e^{i\\phi}\\cos\\theta & \\\\
& & & & I\\\\
\\end{pmatrix} \\,\\, ,

where :math:`I` and :math:`I'` are, respectively, identity matrices of size
:math:`2^{m} - 1` and :math:`2^{m}(2^{m'} - 2)`.

This unitary matrix is also known as a
`Givens rotation <https://en.wikipedia.org/wiki/Givens_rotation>`_.

References:
1. R. M. S. Farias, T. O. Maciel, G. Camilo, R. Lin, S. Ramos-Calderer, and L. Aolita,
*Quantum encoder for fixed Hamming-weight subspaces*.
`arXiv:2405.20408 [quant-ph] <https://arxiv.org/abs/2405.20408>`_

Args:
qubits_in (tuple or list): ids of "input" qubits.
qubits_out (tuple or list): ids of "output" qubits.
theta (float): the rotation angle.
phi (float): the phase angle. Defaults to :math:`0.0`.
trainable (bool): whether gate parameter can be updated using
:meth:`qibo.models.circuit.AbstractCircuit.set_parameters`.
Defaults to ``True``.
"""

def __init__(
self,
qubits_in: Union[Tuple[int], List[int]],
qubits_out: Union[Tuple[int], List[int]],
theta: float,
phi: float = 0.0,
trainable: bool = True,
):
super().__init__(trainable)
self.name = "grbs"
self.draw_label = "gRBS"
self.target_qubits = tuple(qubits_in + qubits_out)
self.unitary = True

self.parameter_names = "theta"
self.parameters = theta, phi
self.nparams = 2

self.init_args = [qubits_in, qubits_out]
self.init_kwargs = {"theta": theta, "phi": phi, "trainable": trainable}

def decompose(self) -> List[Gate]:
"""Decomposition of :math:`\\text{gRBS}` gate.

Decompose :math:`\\text{gRBS}` gate into :class:`qibo.gates.X`, :class:`qibo.gates.CNOT`,
:class:`qibo.gates.RY`, and :class:`qibo.gates.RZ`.
"""
from qibo.transpiler.decompositions import ( # pylint: disable=C0415
standard_decompositions,
)

return standard_decompositions(self)


class Unitary(ParametrizedGate):
"""Arbitrary unitary gate.

Expand Down
54 changes: 54 additions & 0 deletions src/qibo/transpiler/decompositions.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,38 @@ def _u3_to_gpi2(t, p, l):
)


def _decomposition_generalized_RBS(ins, outs, theta, phi, controls):
renatomello marked this conversation as resolved.
Show resolved Hide resolved
"""Generalized RBS gate as in Fig. 2 of arXiv:2405.20408"""
rotation_controls = ins[:-1] + outs
if controls is not None:
rotation_controls += controls

list_gates = []
list_gates.append(gates.X(ins[-1]))
list_gates.append(gates.X(outs[0]))
for target in ins[:-1]:
list_gates.append(gates.CNOT(ins[-1], target))
for target in outs[1:][::-1]:
list_gates.append(gates.CNOT(outs[0], target))
list_gates.append(gates.X(ins[-1]))
list_gates.append(gates.X(outs[0]))
list_gates.append(gates.CNOT(ins[-1], outs[0]))
list_gates.append(gates.RY(ins[-1], -2 * theta).controlled_by(*rotation_controls))
if phi != 0.0:
list_gates.append(gates.RZ(ins[-1], 2 * phi).controlled_by(*rotation_controls))
list_gates.append(gates.CNOT(ins[-1], outs[0]))
list_gates.append(gates.X(outs[0]))
list_gates.append(gates.X(ins[-1]))
for target in outs[1:]:
list_gates.append(gates.CNOT(outs[0], target))
for target in ins[:-1][::-1]:
list_gates.append(gates.CNOT(ins[-1], target))
list_gates.append(gates.X(outs[0]))
list_gates.append(gates.X(ins[-1]))

return list_gates


# standard gate decompositions used by :meth:`qibo.gates.gates.Gate.decompose`
standard_decompositions = GateDecompositions()
standard_decompositions.add(gates.SX, [gates.RX(0, np.pi / 2, trainable=False)])
Expand Down Expand Up @@ -502,3 +534,25 @@ def _u3_to_gpi2(t, p, l):
gates.CNOT(0, 1),
],
)
standard_decompositions.add(
gates.GeneralizedRBS,
lambda gate: _decomposition_generalized_RBS(
ins=list(range(len(gate.init_args[0]))),
outs=list(
range(
len(gate.init_args[0]),
len(gate.init_args[0]) + len(gate.init_args[1]),
)
),
theta=gate.init_kwargs["theta"],
phi=gate.init_kwargs["phi"],
controls=list(
range(
len(gate.init_args[0]) + len(gate.init_args[1]),
len(gate.init_args[0])
+ len(gate.init_args[1])
+ len(gate.control_qubits),
)
),
),
)
Loading