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

Adding a bunch of gates from the lab #520

Open
wants to merge 39 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
8950aeb
Adding a bunch of gates from the lab
arsalan-motamedi Nov 6, 2024
3b4dbfa
fixing a codefactor issue
arsalan-motamedi Nov 6, 2024
b66efa2
improvement + Pgate tests added
arsalan-motamedi Nov 6, 2024
c923193
added tests for cxgate
arsalan-motamedi Nov 6, 2024
50917c8
CZ gate tests added
arsalan-motamedi Nov 6, 2024
bdecc2f
added bargmann eigenstates
arsalan-motamedi Nov 7, 2024
ed7a7bd
bugfix in CZ test
arsalan-motamedi Nov 7, 2024
318f2d3
added mzgate tests
arsalan-motamedi Nov 8, 2024
8f2c2d3
improved czgate test
arsalan-motamedi Nov 8, 2024
feabd56
- an issue regarding the initialization of mzgate fixed
arsalan-motamedi Nov 8, 2024
624430c
small improvement in test_mzgate.py
arsalan-motamedi Nov 8, 2024
f3331b6
interferometer tests added
arsalan-motamedi Nov 8, 2024
2ab72f0
- improvements to realinterferometer
arsalan-motamedi Nov 8, 2024
d68c34c
tests for bargmanneigenstate added
arsalan-motamedi Nov 8, 2024
b288bd1
codefactor should be happy now
arsalan-motamedi Nov 8, 2024
db65a92
bugfix in TF tests
arsalan-motamedi Nov 8, 2024
2794e6b
Addressing some of Anthony's comments
arsalan-motamedi Nov 8, 2024
e6bb856
whitespace added
arsalan-motamedi Nov 8, 2024
ab62f2e
added Gaussian Ket and DM. Tests to be added
arsalan-motamedi Nov 14, 2024
eb0ec72
making codefactor happy
arsalan-motamedi Nov 14, 2024
264d318
some improvements, but things are faulty still
arsalan-motamedi Nov 15, 2024
fe9b982
Merge branch 'develop' into many-unitaries
arsalan-motamedi Nov 19, 2024
a68cd95
some improvements
arsalan-motamedi Nov 20, 2024
646b297
small improvement
arsalan-motamedi Nov 20, 2024
81dcf81
adding the missing exp in the calculation of gdm triples
arsalan-motamedi Nov 22, 2024
2cd56cc
Gstate tests addded
arsalan-motamedi Nov 25, 2024
8708a5d
Test improvement
arsalan-motamedi Nov 25, 2024
5a14cdb
increased slackness in cft test (was giving errors)
arsalan-motamedi Nov 25, 2024
5d5b097
making codefactor happy
arsalan-motamedi Nov 25, 2024
a7e6353
tensorflow error addressed
arsalan-motamedi Nov 25, 2024
04201c7
Update mrmustard/lab_dev/states/gstate.py
arsalan-motamedi Nov 25, 2024
2745e1d
formatting
arsalan-motamedi Nov 25, 2024
8e5b8c7
np -> math (#527)
ziofil Nov 27, 2024
0af0a16
Merge branch 'develop' into many-unitaries
ziofil Nov 27, 2024
a86232f
added getitem_builtin for Gaussian states
arsalan-motamedi Dec 2, 2024
0bcfb79
tests added for getitem
arsalan-motamedi Dec 2, 2024
ffc8614
we can send one beta for multiple modes on Gdm
arsalan-motamedi Dec 2, 2024
034e760
docstring of czgate improved
arsalan-motamedi Dec 2, 2024
f40de7e
removed print
arsalan-motamedi Dec 2, 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
2 changes: 2 additions & 0 deletions mrmustard/lab_dev/states/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
from .ket import Ket
from .dm import DM

from .bargmann_eigenstate import BargmannEigenstate
from .coherent import Coherent
from .displaced_squeezed import DisplacedSqueezed
from .gstate import Gket, Gdm
from .number import Number
from .quadrature_eigenstate import QuadratureEigenstate
from .squeezed_vacuum import SqueezedVacuum
Expand Down
67 changes: 67 additions & 0 deletions mrmustard/lab_dev/states/bargmann_eigenstate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Copyright 2024 Xanadu Quantum Technologies Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
The class representing a Bargmann eigenstate.
"""

from __future__ import annotations

from typing import Sequence

from mrmustard.physics.ansatz import PolyExpAnsatz
from mrmustard.physics import triples
from .ket import Ket
from ..utils import make_parameter

__all__ = ["BargmannEigenstate"]


class BargmannEigenstate(Ket):
r"""
The `N`-mode Bargmann eigenstate.

.. code-block ::

>>> from mrmustard.lab_dev import BargmannEigenstate

>>> state = BargmannEigenstate([1, 2], [0.1, 0.5j])
>>> assert state.modes == [1, 2]

Args:
modes: A list of modes.
alpha: The displacement of the state (i.e., the eigen-value).

.. details::
Its ``(A,b,c)`` triple is given by
.. math::
A = 0 , b = alpha, c = 1.
"""

short_name = "Be"

def __init__(
self,
modes: Sequence[int],
alpha: float | Sequence[float] = 0.0,
alpha_trainable: bool = False,
alpha_bounds: tuple[float | None, float | None] = (None, None),
):
super().__init__(name="BargmannEigenstate")

self._add_parameter(make_parameter(alpha_trainable, alpha, "alpha", alpha_bounds))
self._representation = self.from_ansatz(
modes=modes,
ansatz=PolyExpAnsatz.from_function(fn=triples.bargmann_eigenstate_Abc, x=self.alpha),
).representation
116 changes: 116 additions & 0 deletions mrmustard/lab_dev/states/gstate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Copyright 2024 Xanadu Quantum Technologies Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Classes that are initialized by a symplectic matrix and possibly thermal states if we have a DM.
"""

from __future__ import annotations

from typing import Sequence

from mrmustard import math
from mrmustard.math.parameters import update_symplectic
from mrmustard.physics.ansatz import PolyExpAnsatz
from mrmustard.physics import triples
from mrmustard.utils.typing import RealMatrix
from .ket import Ket
from .dm import DM
from ..utils import make_parameter

__all__ = ["Gket", "Gdm"]


class Gket(Ket):
r"""
The `N`-mode pure state described by a Gaussian gate that acts on Vacuum.
"""

short_name = "Gk"

def __init__(
self,
modes: Sequence[int],
symplectic: RealMatrix = None,
symplectic_trainable: bool = False,
) -> None:
super().__init__(name="Gket")
m = len(modes)
if symplectic is None:
symplectic = math.random_symplectic(m)

self._add_parameter(
make_parameter(
symplectic_trainable,
symplectic,
"symplectic",
(None, None),
update_symplectic,
)
)

self._representation = self.from_ansatz(
modes=modes,
ansatz=PolyExpAnsatz.from_function(
fn=triples.gket_state_Abc, symplectic=self.symplectic
),
).representation


arsalan-motamedi marked this conversation as resolved.
Show resolved Hide resolved
class Gdm(DM):
r"""
The `N`-mode mixed state described by a Gaussian gate that acts on a given thermal state.
"""

short_name = "Gd"

def __init__(
self,
modes: Sequence[int],
betas: float | Sequence[float],
symplectic: RealMatrix = None,
symplectic_trainable: bool = False,
betas_trainable: bool = False,
) -> None:
super().__init__(name="Gdm")
m = len(modes)

if symplectic is None:
symplectic = math.random_symplectic(m)

self._add_parameter(
make_parameter(
symplectic_trainable,
symplectic,
"symplectic",
(None, None),
update_symplectic,
)
)

self._add_parameter(
make_parameter(
betas_trainable,
math.astensor(betas),
"betas",
(0, None),
)
)

self._representation = self.from_ansatz(
modes=modes,
ansatz=PolyExpAnsatz.from_function(
fn=triples.gdm_state_Abc, betas=self.betas, symplectic=symplectic
),
).representation
2 changes: 1 addition & 1 deletion mrmustard/lab_dev/states/ket.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def random(cls, modes: Sequence[int], max_r: float = 1.0) -> Ket:
S = math.random_symplectic(m, max_r)
transformation = (
1
/ np.sqrt(2)
/ math.sqrt(complex(2))
* math.block(
[
[
Expand Down
6 changes: 6 additions & 0 deletions mrmustard/lab_dev/transformations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,18 @@
from .base import *
from .bsgate import *
from .cft import *
from .cxgate import *
from .czgate import *
from .dgate import *
from .fockdamping import *
from .ggate import *
from .gaussrandnoise import *
from .identity import *
from .interferometer import *
from .mzgate import *
from .pgate import *
from .phasenoise import *
from .realinterferometer import *
from .rgate import *
from .s2gate import *
from .sgate import *
81 changes: 81 additions & 0 deletions mrmustard/lab_dev/transformations/cxgate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Copyright 2024 Xanadu Quantum Technologies Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
The class representing a controlled-X gate.
"""

from __future__ import annotations

from typing import Sequence
from mrmustard import math
from mrmustard.physics.ansatz import PolyExpAnsatz

from .base import Unitary
from ..utils import make_parameter

__all__ = ["CXgate"]


class CXgate(Unitary):
r"""Controlled X gate.

It applies to a single pair of modes. One can optionally set bounds for each parameter, which
the optimizer will respect.

.. math::

C_X = \exp(is q_1 \otimes p_2).

Reference: https://arxiv.org/pdf/2110.03247.pdf, Equation 9.


Args:
modes (optional, Sequance[int]): the list of modes this gate is applied to
s (float): control parameter
s_bounds (float, float): bounds for the control angle
s_trainable (bool): whether s is a trainable variable
"""

short_name = "CX"

def __init__(
self,
modes: Sequence[int],
s: float = 0.0,
s_trainable: bool = False,
s_bounds: tuple[float | None, float | None] = (None, None),
):
if len(modes) != 2:
raise ValueError(
f"The number of modes for a CXgate must be 2 (your input has {len(modes)} many modes)."
)
super().__init__(name="CXgate")
self._add_parameter(make_parameter(s_trainable, s, "s", s_bounds))
symplectic = math.astensor(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should you override the symplectic property?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess so.. I will take a look at Ggate to see how it's done

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually no, I think it is characterized by other parameters (here it is just s). So, I believe we don't want to have it as a property.

[
[1, 0, 0, 0],
[s, 1, 0, 0],
[0, 0, 1, -s],
[0, 0, 0, 1],
],
dtype="complex128",
)
self._representation = self.from_ansatz(
modes_in=modes,
modes_out=modes,
ansatz=PolyExpAnsatz.from_function(
fn=lambda sym: Unitary.from_symplectic(modes, sym).bargmann_triple(), sym=symplectic
),
).representation
82 changes: 82 additions & 0 deletions mrmustard/lab_dev/transformations/czgate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Copyright 2024 Xanadu Quantum Technologies Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
The class representing a controlled-phase gate.
"""

from __future__ import annotations

from typing import Sequence
from mrmustard import math
from mrmustard.physics.ansatz import PolyExpAnsatz

from .base import Unitary
from ..utils import make_parameter

__all__ = ["CZgate"]


class CZgate(Unitary):
r"""Controlled Z gate.

It applies to a single pair of modes. One can optionally set bounds for each parameter, which
the optimizer will respect.

.. math::

C_Z = \exp(ig q_1 \otimes q_2 / \hbar).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is g the same as s? should we use the same letter if they are the same?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they are the same thing. I will make this change



Reference: https://arxiv.org/pdf/2110.03247.pdf, Equation 8.
https://arxiv.org/pdf/1110.3234.pdf, Equation 161.


Args:
modes (optional, Sequence[int]): the list of modes this gate is applied to
s (float): control parameter
s_bounds (float, float): bounds for the control angle
s_trainable (bool): whether s is a trainable variable
"""

short_name = "CZ"

def __init__(
self,
modes: Sequence[int],
s: float = 0.0,
s_trainable: bool = False,
s_bounds: tuple[float | None, float | None] = (None, None),
):
if len(modes) != 2:
raise ValueError(
f"The number of modes for a CZgate must be 2 (your input has {len(modes)} many modes)."
)
super().__init__(name="CZgate")
self._add_parameter(make_parameter(s_trainable, s, "s", s_bounds))
symplectic = math.astensor(
[
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, s, 1, 0],
[s, 0, 0, 1],
]
)
self._representation = self.from_ansatz(
modes_in=modes,
modes_out=modes,
ansatz=PolyExpAnsatz.from_function(
fn=lambda sym: Unitary.from_symplectic(modes, sym).bargmann_triple(), sym=symplectic
),
).representation
Loading