Skip to content

Commit

Permalink
Merge branch 'master' into quantum_networks
Browse files Browse the repository at this point in the history
  • Loading branch information
renatomello committed Feb 7, 2024
2 parents cda5633 + 8e9d1c0 commit a18089b
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 79 deletions.
1 change: 1 addition & 0 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"sphinx.ext.napoleon",
"sphinx.ext.intersphinx",
"sphinx_copybutton",
"sphinx.ext.viewcode",
"recommonmark",
"nbsphinx",
]
Expand Down
124 changes: 61 additions & 63 deletions src/qibo/gates/gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,11 @@ def decompose(self):
being the :class:`qibo.gates.RX` gate. More precisely,
:math:`\\sqrt{X} = e^{i \\pi / 4} \\, \\text{RX}(\\pi / 2)`.
"""
return [RX(self.init_args[0], np.pi / 2, trainable=False)]
from qibo.transpiler.decompositions import ( # pylint: disable=C0415
standard_decompositions,
)

return standard_decompositions(self)

def _dagger(self):
""""""
Expand Down Expand Up @@ -314,7 +318,11 @@ def decompose(self):
being the :class:`qibo.gates.RX` gate. More precisely,
:math:`(\\sqrt{X})^{\\dagger} = e^{-i \\pi / 4} \\, \\text{RX}(-\\pi / 2)`.
"""
return [RX(self.init_args[0], -np.pi / 2, trainable=False)]
from qibo.transpiler.decompositions import ( # pylint: disable=C0415
standard_decompositions,
)

return standard_decompositions(self)

def _dagger(self):
""""""
Expand Down Expand Up @@ -892,14 +900,11 @@ def decompose(self) -> List[Gate]:
where :math:`\\text{RZ}` and :math:`\\sqrt{X}` are, respectively,
:class:`qibo.gates.RZ` and :class`qibo.gates.SX`.
"""
q = self.init_args[0]
return [
RZ(q, self.init_kwargs["lam"]),
SX(q),
RZ(q, self.init_kwargs["theta"] + math.pi),
SX(q),
RZ(q, self.init_kwargs["phi"] + math.pi),
]
from qibo.transpiler.decompositions import ( # pylint: disable=C0415
standard_decompositions,
)

return standard_decompositions(self)


class U1q(_Un_):
Expand Down Expand Up @@ -1020,8 +1025,11 @@ def decompose(self) -> List[Gate]:
the target qubit, followed by :class:`qibo.gates.CNOT`, followed
by a :class:`qibo.gates.S` in the target qubit.
"""
q0, q1 = self.init_args
return [SDG(q1), CNOT(q0, q1), S(q1)]
from qibo.transpiler.decompositions import ( # pylint: disable=C0415
standard_decompositions,
)

return standard_decompositions(self)


class CZ(Gate):
Expand Down Expand Up @@ -1063,8 +1071,11 @@ def decompose(self) -> List[Gate]:
the target qubit, followed by :class:`qibo.gates.CNOT`, followed
by another :class:`qibo.gates.H` in the target qubit
"""
q0, q1 = self.init_args
return [H(q1), CNOT(q0, q1), H(q1)]
from qibo.transpiler.decompositions import ( # pylint: disable=C0415
standard_decompositions,
)

return standard_decompositions(self)


class CSX(Gate):
Expand Down Expand Up @@ -1100,8 +1111,11 @@ def qasm_label(self):

def decompose(self, *free, use_toffolis: bool = True) -> List[Gate]:
""""""
q0, q1 = self.init_args
return [H(q1), CU1(q0, q1, np.pi / 2), H(q1)]
from qibo.transpiler.decompositions import ( # pylint: disable=C0415
standard_decompositions,
)

return standard_decompositions(self)

def _dagger(self):
""""""
Expand Down Expand Up @@ -1141,8 +1155,11 @@ def qasm_label(self):

def decompose(self, *free, use_toffolis: bool = True) -> List[Gate]:
""""""
q0, q1 = self.init_args
return [H(q1), CU1(q0, q1, -np.pi / 2), H(q1)]
from qibo.transpiler.decompositions import ( # pylint: disable=C0415
standard_decompositions,
)

return standard_decompositions(self)

def _dagger(self):
""""""
Expand Down Expand Up @@ -1901,9 +1918,11 @@ def __init__(self, q0, q1, theta, trainable=True):

def decompose(self, *free, use_toffolis: bool = True) -> List[Gate]:
""""""
q0, q1 = self.target_qubits
theta = self.init_kwargs["theta"]
return [H(q1), CNOT(q0, q1), RZ(q1, theta), CNOT(q0, q1), H(q1)]
from qibo.transpiler.decompositions import ( # pylint: disable=C0415
standard_decompositions,
)

return standard_decompositions(self)


class RXXYY(_Rnn_):
Expand Down Expand Up @@ -1942,22 +1961,11 @@ def decompose(self, *free, use_toffolis: bool = True) -> List[Gate]:
the original gate due to a phase difference in
:math:`\\left(\\sqrt{X}\\right)^{\\dagger}`.
"""
q0, q1 = self.target_qubits
theta = self.init_kwargs["theta"]
return [
RZ(q1, -np.pi / 2),
S(q0),
SX(q1),
RZ(q1, np.pi / 2),
CNOT(q1, q0),
RY(q0, -theta / 2),
RY(q1, -theta / 2),
CNOT(q1, q0),
SDG(q0),
RZ(q1, -np.pi / 2),
SX(q1).dagger(),
RZ(q1, np.pi / 2),
]
from qibo.transpiler.decompositions import ( # pylint: disable=C0415
standard_decompositions,
)

return standard_decompositions(self)


class MS(ParametrizedGate):
Expand Down Expand Up @@ -2062,18 +2070,13 @@ def _dagger(self) -> "Gate":
return self.__class__(*self.target_qubits, -self.parameters[0])

def decompose(self, *free, use_toffolis: bool = True) -> List[Gate]:
"""Decomposition of Givens gate according to `ArXiv:2106.13839
<https://arxiv.org/abs/2106.13839>`_."""
q0, q1 = self.target_qubits
theta = self.init_kwargs["theta"]
return [
CNOT(q0, q1),
RY(q0, theta),
CNOT(q1, q0),
RY(q0, -theta),
CNOT(q1, q0),
CNOT(q0, q1),
]
"""Decomposition of RBS gate according to `ArXiv:2109.09685
<https://arxiv.org/abs/2109.09685>`_."""
from qibo.transpiler.decompositions import ( # pylint: disable=C0415
standard_decompositions,
)

return standard_decompositions(self)


class RBS(ParametrizedGate):
Expand Down Expand Up @@ -2123,18 +2126,11 @@ def _dagger(self) -> "Gate":
def decompose(self, *free, use_toffolis: bool = True) -> List[Gate]:
"""Decomposition of RBS gate according to `ArXiv:2109.09685
<https://arxiv.org/abs/2109.09685>`_."""
q0, q1 = self.target_qubits
theta = self.init_kwargs["theta"]
return [
H(q0),
CNOT(q0, q1),
H(q1),
RY(q0, theta),
RY(q1, -theta),
H(q1),
CNOT(q0, q1),
H(q0),
]
from qibo.transpiler.decompositions import ( # pylint: disable=C0415
standard_decompositions,
)

return standard_decompositions(self)


class ECR(Gate):
Expand Down Expand Up @@ -2175,9 +2171,11 @@ def decompose(self, *free, use_toffolis: bool = True) -> List[Gate]:
\\textup{ECR} = e^{i 7 \\pi / 4} \\, S(q_{0}) \\, \\sqrt{X}(q_{1}) \\,
\\textup{CNOT}(q_{0}, q_{1}) \\, X(q_{0})
"""
from qibo.transpiler.decompositions import ( # pylint: disable=C0415
standard_decompositions,
)

q0, q1 = self.target_qubits
return [S(q0), SX(q1), CNOT(q0, q1), X(q0)]
return standard_decompositions(self)


class TOFFOLI(Gate):
Expand Down
105 changes: 89 additions & 16 deletions src/qibo/transpiler/decompositions.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def _u3_to_gpi2(t, p, l):

# Decompose single qubit gates using U3
u3_dec = GateDecompositions()
u3_dec.add(gates.H, [gates.U3(0, 7 * np.pi / 2, np.pi, 0)])
u3_dec.add(gates.H, [gates.U3(0, -np.pi / 2, np.pi, 0)])
u3_dec.add(gates.X, [gates.U3(0, np.pi, 0, np.pi)])
u3_dec.add(gates.Y, [gates.U3(0, np.pi, 0, 0)])
u3_dec.add(gates.Z, [gates.Z(0)])
Expand Down Expand Up @@ -159,28 +159,28 @@ def _u3_to_gpi2(t, p, l):
gates.CNOT,
[
gates.U3(0, 3 * np.pi / 2, np.pi, 0),
gates.U3(1, np.pi / 2, -np.pi, -np.pi),
gates.U3(1, np.pi / 2, np.pi, np.pi),
gates.iSWAP(0, 1),
gates.U3(0, np.pi, 0, np.pi),
gates.U3(1, np.pi / 2, -np.pi, -np.pi),
gates.U3(1, np.pi / 2, np.pi, np.pi),
gates.iSWAP(0, 1),
gates.U3(0, np.pi / 2, np.pi / 2, -np.pi),
gates.U3(1, np.pi / 2, -np.pi, -np.pi / 2),
gates.U3(0, np.pi / 2, np.pi / 2, np.pi),
gates.U3(1, np.pi / 2, np.pi, -np.pi / 2),
],
)
iswap_dec.add(
gates.CZ,
[
gates.U3(0, 7 * np.pi / 2, np.pi, 0),
gates.U3(1, 7 * np.pi / 2, np.pi, 0),
gates.U3(1, np.pi / 2, -np.pi, -np.pi),
gates.U3(0, -np.pi / 2, np.pi, 0),
gates.U3(1, -np.pi / 2, np.pi, 0),
gates.U3(1, np.pi / 2, np.pi, np.pi),
gates.iSWAP(0, 1),
gates.U3(0, np.pi, 0, np.pi),
gates.U3(1, np.pi / 2, -np.pi, -np.pi),
gates.U3(1, np.pi / 2, np.pi, np.pi),
gates.iSWAP(0, 1),
gates.U3(0, np.pi / 2, np.pi / 2, -np.pi),
gates.U3(1, np.pi / 2, -np.pi, -np.pi / 2),
gates.U3(1, 7 * np.pi / 2, np.pi, 0),
gates.U3(0, np.pi / 2, np.pi / 2, np.pi),
gates.U3(1, np.pi / 2, np.pi, -np.pi / 2),
gates.U3(1, -np.pi / 2, np.pi, 0),
],
)
iswap_dec.add(
Expand Down Expand Up @@ -304,14 +304,14 @@ def _u3_to_gpi2(t, p, l):
cz_dec.add(
gates.FSWAP,
[
gates.U3(0, np.pi / 2, -np.pi / 2, -np.pi),
gates.U3(0, np.pi / 2, -np.pi / 2, np.pi),
gates.U3(1, np.pi / 2, np.pi / 2, np.pi / 2),
gates.CZ(0, 1),
gates.U3(0, np.pi / 2, 0, -np.pi / 2),
gates.U3(1, np.pi / 2, 0, np.pi / 2),
gates.CZ(0, 1),
gates.U3(0, np.pi / 2, np.pi / 2, -np.pi),
gates.U3(1, np.pi / 2, 0, -np.pi),
gates.U3(0, np.pi / 2, np.pi / 2, np.pi),
gates.U3(1, np.pi / 2, 0, np.pi),
],
)
cz_dec.add(
Expand All @@ -328,7 +328,7 @@ def _u3_to_gpi2(t, p, l):
gates.RYY,
lambda gate: [
gates.RX(0, np.pi / 2),
gates.U3(1, np.pi / 2, np.pi / 2, -np.pi),
gates.U3(1, np.pi / 2, np.pi / 2, np.pi),
gates.CZ(0, 1),
gates.RX(1, gate.parameters[0]),
gates.CZ(0, 1),
Expand Down Expand Up @@ -392,3 +392,76 @@ def _u3_to_gpi2(t, p, l):
gates.H(1),
],
)


# 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)])
standard_decompositions.add(gates.SXDG, [gates.RX(0, -np.pi / 2, trainable=False)])
standard_decompositions.add(
gates.U3,
lambda gate: [
gates.RZ(0, gate.parameters[2]),
gates.SX(0),
gates.RZ(0, gate.parameters[0] + np.pi),
gates.SX(0),
gates.RZ(0, gate.parameters[1] + np.pi),
],
)
standard_decompositions.add(gates.CY, [gates.SDG(1), gates.CNOT(0, 1), gates.S(1)])
standard_decompositions.add(gates.CZ, [gates.H(1), gates.CNOT(0, 1), gates.H(1)])
standard_decompositions.add(
gates.CSX, [gates.H(1), gates.CU1(0, 1, np.pi / 2), gates.H(1)]
)
standard_decompositions.add(
gates.CSXDG, [gates.H(1), gates.CU1(0, 1, -np.pi / 2), gates.H(1)]
)
standard_decompositions.add(
gates.RZX,
lambda gate: [
gates.H(1),
gates.CNOT(0, 1),
gates.RZ(1, gate.parameters[0]),
gates.CNOT(0, 1),
gates.H(1),
],
)
standard_decompositions.add(
gates.RXXYY,
lambda gate: [
gates.RZ(1, -np.pi / 2),
gates.S(0),
gates.SX(1),
gates.RZ(1, np.pi / 2),
gates.CNOT(1, 0),
gates.RY(0, -gate.parameters[0] / 2),
gates.RY(1, -gate.parameters[0] / 2),
gates.CNOT(1, 0),
gates.SDG(0),
gates.RZ(1, -np.pi / 2),
gates.SX(1).dagger(),
gates.RZ(1, np.pi / 2),
],
)
standard_decompositions.add(
gates.RBS,
lambda gate: [
gates.H(0),
gates.CNOT(0, 1),
gates.H(1),
gates.RY(0, gate.parameters[0]),
gates.RY(1, -gate.parameters[0]),
gates.H(1),
gates.CNOT(0, 1),
gates.H(0),
],
)
standard_decompositions.add(
gates.GIVENS, lambda gate: gates.RBS(0, 1, -gate.parameters[0]).decompose()
)
standard_decompositions.add(
gates.FSWAP, [gates.X(1)] + gates.GIVENS(0, 1, np.pi / 2).decompose() + [gates.X(0)]
)
standard_decompositions.add(
gates.ECR, [gates.S(0), gates.SX(1), gates.CNOT(0, 1), gates.X(0)]
)

0 comments on commit a18089b

Please sign in to comment.