From be8a435cb5649d1be7af2a6f81fdb84a6b31a599 Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Wed, 4 Sep 2024 12:02:29 -0400 Subject: [PATCH 01/23] WIP --- mrmustard/lab_dev/transformations/cft.py | 43 ++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 mrmustard/lab_dev/transformations/cft.py diff --git a/mrmustard/lab_dev/transformations/cft.py b/mrmustard/lab_dev/transformations/cft.py new file mode 100644 index 000000000..26c092bcc --- /dev/null +++ b/mrmustard/lab_dev/transformations/cft.py @@ -0,0 +1,43 @@ +# 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 complex fourier transform. +""" + +from typing import Sequence +from mrmustard.lab_dev.transformations.base import Map +from mrmustard.physics.representations import Bargmann +from mrmustard.physics import triples + +class CFT(Map): + r"""The Complex Fourier Transformation as a channel. + The main use is to convert between Characteristic functions and phase space functions. + + Args: + num_modes: number of modes of this channel. + """ + + def __init__( + self, + modes: Sequence[int], + ): + super().__init__( + modes_out=modes, + modes_in=modes, + name="CFT", + ) + self._representation = Bargmann.from_function( + fn=triples.complex_fourier_transform_Abc, n_modes=len(modes) + ) \ No newline at end of file From 7121fcdfe09118c13a07a6ee0cacd605aaaaaaf5 Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Wed, 4 Sep 2024 13:08:11 -0400 Subject: [PATCH 02/23] WIP --- mrmustard/physics/triples.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/mrmustard/physics/triples.py b/mrmustard/physics/triples.py index ce66d9393..8c8ede0e7 100644 --- a/mrmustard/physics/triples.py +++ b/mrmustard/physics/triples.py @@ -680,6 +680,26 @@ def displacement_map_s_parametrized_Abc(s: int, n_modes: int) -> Union[Matrix, V c = 1.0 + 0j return math.astensor(A), b, c +def complex_fourier_transform_Abc(n_modes: int) -> Union[Matrix, Vector, Scalar]: + r""" + The ``(A, b, c)`` triple of the complex Fourier transform between two pairs of complex variables. + Given a function :math:`f(z^*, z)`, the complex Fourier transform is defined as + :math: + \hat{f} (y^*, y) = \int_{\mathbb{C}} \frac{d^2 z}{\pi} e^{yz^* - y^*z} f(z^*, z). + The indices of this triple correspond to the variables :math:`(y^*, z^*, y, z)`. + + Args: + n_modes: the number of modes for this map. + + Returns: + The ``(A, b, c)`` triple of the complex fourier transform. + """ + O2n = math.zeros((2 * n_modes, 2 * n_modes)) + Omega = math.J(n_modes) + A = math.block([[O2n, -Omega], [Omega, O2n]]) + b = _vacuum_B_vector(4 * n_modes) + c = 1.0 + 0j + return A, b, c # ~~~~~~~~~~~~~~~~ # Kraus operators From e4088053c148deb995d8ebea4732c7a42a5f3ab1 Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Wed, 4 Sep 2024 13:40:56 -0400 Subject: [PATCH 03/23] WIP --- .../test_transformations/test_cft.py | 50 +++++++++++++++++++ tests/test_physics/test_ansatz.py | 24 ++++----- tests/test_physics/test_triples.py | 6 +-- 3 files changed, 64 insertions(+), 16 deletions(-) create mode 100644 tests/test_lab_dev/test_transformations/test_cft.py diff --git a/tests/test_lab_dev/test_transformations/test_cft.py b/tests/test_lab_dev/test_transformations/test_cft.py new file mode 100644 index 000000000..3d6c52cc3 --- /dev/null +++ b/tests/test_lab_dev/test_transformations/test_cft.py @@ -0,0 +1,50 @@ +# 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. + +"""Tests for the ``CFT`` class.""" + +import numpy as np +from mrmustard import math +from mrmustard.lab_dev import CFT, BtoPS, DisplacedSqueezed +from mrmustard.physics.wigner import wigner_discretized + + +class TestCFT: + r""" + Tests the CFT gate + """ + + def test_init(self): + "tests the initialization of the CFT gate" + cft = CFT([0]) + assert cft.name == "CFT" + assert cft.modes == [0] + + def test_wigner_function(self): + r""" + Tests that the characteristic function is converted to the Wigner function + for a single-mode squeezed state. + """ + state = DisplacedSqueezed([0], r=0.5, phi=1.0, x=0.4, y=0.4) + + dm = math.sum(state.to_fock(100).dm().representation.array, axes=[0]) + xvec = np.linspace(-5, 5, 100) + pvec = np.linspace(-5, 5, 100) + wigner, _, _ = wigner_discretized(dm, xvec, pvec) + + Wigner = (state >> CFT([0]) >> BtoPS([0], s=0)).representation.ansatz + X, Y = np.meshgrid(xvec, pvec) + Z = np.array([X - 1j * Y, X + 1j * Y]).transpose((1, 2, 0)) + assert np.isclose(np.max(np.real(Wigner(Z))), np.max(np.real(wigner)), atol=1e-8) + assert np.isclose(np.max(np.real(Wigner(Z))), np.max(np.real(wigner)), atol=1e-8) diff --git a/tests/test_physics/test_ansatz.py b/tests/test_physics/test_ansatz.py index 4e192eb83..a6b9f9bdd 100644 --- a/tests/test_physics/test_ansatz.py +++ b/tests/test_physics/test_ansatz.py @@ -233,15 +233,15 @@ def test_bargmann_Abc_to_phasespace_cov_means(self): state_means = np.array([0.2, 0.3]) state = DM.from_bargmann([0], wigner_to_bargmann_rho(state_cov, state_means)) state_after = state >> BtoPS(modes=[0], s=0) # pylint: disable=protected-access - A1, b1, c1 = state_after.bargmann_triple(batched=True) + A1, b1, c1 = state_after.bargmann_triple() ( new_state_cov, new_state_means, new_state_coeff, ) = bargmann_Abc_to_phasespace_cov_means(A1, b1, c1) - assert np.allclose(state_cov, new_state_cov[0]) - assert np.allclose(state_means, new_state_means[0]) - assert np.allclose(1.0, new_state_coeff[0]) + assert np.allclose(state_cov, new_state_cov) + assert np.allclose(state_means, new_state_means) + assert np.allclose(1.0 / (2 * np.pi), new_state_coeff) state_cov = np.array( [ @@ -263,20 +263,18 @@ def test_bargmann_Abc_to_phasespace_cov_means(self): new_state_coeff1, ) = bargmann_Abc_to_phasespace_cov_means(A1, b1, c1) - A22, b22, c22 = (state >> BtoPS([0], 0) >> BtoPS([1], 0)).bargmann_triple( - batched=True - ) # pylint: disable=protected-access + A22, b22, c22 = (state >> BtoPS([0], 0) >> BtoPS([1], 0)).bargmann_triple() ( new_state_cov22, new_state_means22, new_state_coeff22, ) = bargmann_Abc_to_phasespace_cov_means(A22, b22, c22) - assert math.allclose(new_state_cov22[0], state_cov) - assert math.allclose(new_state_cov1[0], state_cov) - assert math.allclose(new_state_means1[0], state_means) - assert math.allclose(new_state_means22[0], state_means) - assert math.allclose(new_state_coeff1[0], 1.0) - assert math.allclose(new_state_coeff22[0], 1.0) + assert math.allclose(new_state_cov22, state_cov) + assert math.allclose(new_state_cov1, state_cov) + assert math.allclose(new_state_means1, state_means) + assert math.allclose(new_state_means22, state_means) + assert math.allclose(new_state_coeff1[0], 1.0 / (2 * np.pi)) + assert math.allclose(new_state_coeff22[0], 1.0 / (2 * np.pi)) class TestPolyExpAnsatz: diff --git a/tests/test_physics/test_triples.py b/tests/test_physics/test_triples.py index 2d34d6d96..358e515cc 100644 --- a/tests/test_physics/test_triples.py +++ b/tests/test_physics/test_triples.py @@ -317,19 +317,19 @@ def test_displacement_gate_s_parametrized_Abc(self): A1_correct = np.array([[0, -0.5, -1, 0], [-0.5, 0, 0, 1], [-1, 0, 0, 1], [0, 1, 1, 0]]) assert math.allclose(A1, A1_correct[[0, 3, 1, 2], :][:, [0, 3, 1, 2]]) assert math.allclose(b1, math.zeros(4)) - assert math.allclose(c1, 1) + assert math.allclose(c1, 1 / (2 * np.pi)) A2, b2, c2 = triples.displacement_map_s_parametrized_Abc(s=1, n_modes=1) A2_correct = np.array([[0, 0, -1, 0], [0, 0, 0, 1], [-1, 0, 0, 1], [0, 1, 1, 0]]) assert math.allclose(A2, A2_correct[[0, 3, 1, 2], :][:, [0, 3, 1, 2]]) assert math.allclose(b2, math.zeros(4)) - assert math.allclose(c2, 1) + assert math.allclose(c2, 1 / (2 * np.pi)) A3, b3, c3 = triples.displacement_map_s_parametrized_Abc(s=-1, n_modes=1) A3_correct = np.array([[0, -1, -1, 0], [-1, 0, 0, 1], [-1, 0, 0, 1], [0, 1, 1, 0]]) assert math.allclose(A3, A3_correct[[0, 3, 1, 2], :][:, [0, 3, 1, 2]]) assert math.allclose(b3, math.zeros(4)) - assert math.allclose(c3, 1) + assert math.allclose(c3, 1 / (2 * np.pi)) @pytest.mark.parametrize("eta", [0.0, 0.1, 0.5, 0.9, 1.0]) def test_attenuator_kraus_Abc(self, eta): From 77950f027785e732b449a5f864210919286e3e0f Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Wed, 4 Sep 2024 13:44:55 -0400 Subject: [PATCH 04/23] wip --- mrmustard/physics/ansatze.py | 8 +++++++- tests/test_physics/test_ansatz.py | 6 +++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/mrmustard/physics/ansatze.py b/mrmustard/physics/ansatze.py index be7742a91..561c8db02 100644 --- a/mrmustard/physics/ansatze.py +++ b/mrmustard/physics/ansatze.py @@ -1208,6 +1208,10 @@ def bargmann_Abc_to_phasespace_cov_means( Returns: The covariance matrix, mean vector and coefficient of the state in phase space. """ + batched = len(A.shape) == 3 and len(b.shape) == 2 and len(c.shape) == 1 + A = math.atleast_3d(A) + b = math.atleast_2d(b) + c = math.atleast_1d(c) num_modes = A.shape[-1] // 2 Omega = math.cast(math.transpose(math.J(num_modes)), dtype=math.complex128) W = math.transpose(math.conj(math.rotmat(num_modes))) @@ -1219,4 +1223,6 @@ def bargmann_Abc_to_phasespace_cov_means( 1j * math.matvec(Omega @ W, bvec) * math.sqrt(settings.HBAR, dtype=math.complex128) for bvec in b ] - return math.astensor(cov), math.astensor(mean), coeff + if batched: + return math.astensor(cov), math.astensor(mean), coeff + return cov[0], mean[0], coeff[0] \ No newline at end of file diff --git a/tests/test_physics/test_ansatz.py b/tests/test_physics/test_ansatz.py index a6b9f9bdd..350287ce1 100644 --- a/tests/test_physics/test_ansatz.py +++ b/tests/test_physics/test_ansatz.py @@ -256,7 +256,7 @@ def test_bargmann_Abc_to_phasespace_cov_means(self): state = DM.from_bargmann(modes=[0, 1], triple=(A, b, c)) state_after = state >> BtoPS(modes=[0, 1], s=0) # pylint: disable=protected-access - A1, b1, c1 = state_after.bargmann_triple(batched=True) + A1, b1, c1 = state_after.bargmann_triple() ( new_state_cov1, new_state_means1, @@ -273,8 +273,8 @@ def test_bargmann_Abc_to_phasespace_cov_means(self): assert math.allclose(new_state_cov1, state_cov) assert math.allclose(new_state_means1, state_means) assert math.allclose(new_state_means22, state_means) - assert math.allclose(new_state_coeff1[0], 1.0 / (2 * np.pi)) - assert math.allclose(new_state_coeff22[0], 1.0 / (2 * np.pi)) + assert math.allclose(new_state_coeff1, 1 / (2 * np.pi) ** 2) + assert math.allclose(new_state_coeff22, 1 / (2 * np.pi) ** 2) class TestPolyExpAnsatz: From 54b6e9f9d91dbc0d70d636ac92792fb0124f9557 Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Wed, 4 Sep 2024 14:02:53 -0400 Subject: [PATCH 05/23] wip --- mrmustard/physics/triples.py | 2 +- tests/test_lab_dev/test_transformations/test_cft.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mrmustard/physics/triples.py b/mrmustard/physics/triples.py index 8c8ede0e7..3de8ddf88 100644 --- a/mrmustard/physics/triples.py +++ b/mrmustard/physics/triples.py @@ -677,7 +677,7 @@ def displacement_map_s_parametrized_Abc(s: int, n_modes: int) -> Union[Matrix, V A = math.astensor(math.asnumpy(A)[order_list, :][:, order_list]) b = _vacuum_B_vector(4 * n_modes) - c = 1.0 + 0j + c = 1.0 / (2 * np.pi) ** n_modes + 0.0j return math.astensor(A), b, c def complex_fourier_transform_Abc(n_modes: int) -> Union[Matrix, Vector, Scalar]: diff --git a/tests/test_lab_dev/test_transformations/test_cft.py b/tests/test_lab_dev/test_transformations/test_cft.py index 3d6c52cc3..cc3530ae6 100644 --- a/tests/test_lab_dev/test_transformations/test_cft.py +++ b/tests/test_lab_dev/test_transformations/test_cft.py @@ -16,7 +16,8 @@ import numpy as np from mrmustard import math -from mrmustard.lab_dev import CFT, BtoPS, DisplacedSqueezed +from mrmustard.lab_dev import BtoPS, DisplacedSqueezed +from mrmustard.lab_dev.transformations.cft import CFT from mrmustard.physics.wigner import wigner_discretized From b980bb07de92abb378c26f4e818a7722d47f207d Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Wed, 4 Sep 2024 14:07:15 -0400 Subject: [PATCH 06/23] wip --- tests/test_lab_dev/test_transformations/test_cft.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_lab_dev/test_transformations/test_cft.py b/tests/test_lab_dev/test_transformations/test_cft.py index cc3530ae6..3d6c52cc3 100644 --- a/tests/test_lab_dev/test_transformations/test_cft.py +++ b/tests/test_lab_dev/test_transformations/test_cft.py @@ -16,8 +16,7 @@ import numpy as np from mrmustard import math -from mrmustard.lab_dev import BtoPS, DisplacedSqueezed -from mrmustard.lab_dev.transformations.cft import CFT +from mrmustard.lab_dev import CFT, BtoPS, DisplacedSqueezed from mrmustard.physics.wigner import wigner_discretized From b58e8101036b9c55c4846fe3e9f6215bd2fd36d0 Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Wed, 4 Sep 2024 14:33:58 -0400 Subject: [PATCH 07/23] wip --- mrmustard/physics/triples.py | 1 + tests/test_lab_dev/test_transformations/test_cft.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/mrmustard/physics/triples.py b/mrmustard/physics/triples.py index 3de8ddf88..64175bc3b 100644 --- a/mrmustard/physics/triples.py +++ b/mrmustard/physics/triples.py @@ -680,6 +680,7 @@ def displacement_map_s_parametrized_Abc(s: int, n_modes: int) -> Union[Matrix, V c = 1.0 / (2 * np.pi) ** n_modes + 0.0j return math.astensor(A), b, c + def complex_fourier_transform_Abc(n_modes: int) -> Union[Matrix, Vector, Scalar]: r""" The ``(A, b, c)`` triple of the complex Fourier transform between two pairs of complex variables. diff --git a/tests/test_lab_dev/test_transformations/test_cft.py b/tests/test_lab_dev/test_transformations/test_cft.py index 3d6c52cc3..cc3530ae6 100644 --- a/tests/test_lab_dev/test_transformations/test_cft.py +++ b/tests/test_lab_dev/test_transformations/test_cft.py @@ -16,7 +16,8 @@ import numpy as np from mrmustard import math -from mrmustard.lab_dev import CFT, BtoPS, DisplacedSqueezed +from mrmustard.lab_dev import BtoPS, DisplacedSqueezed +from mrmustard.lab_dev.transformations.cft import CFT from mrmustard.physics.wigner import wigner_discretized From d24fe19a3ccfb447c81eb841c77345b3b0c46ae1 Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Wed, 4 Sep 2024 14:45:17 -0400 Subject: [PATCH 08/23] Working instance --- tests/test_lab_dev/test_transformations/test_cft.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_lab_dev/test_transformations/test_cft.py b/tests/test_lab_dev/test_transformations/test_cft.py index cc3530ae6..8c3f60a16 100644 --- a/tests/test_lab_dev/test_transformations/test_cft.py +++ b/tests/test_lab_dev/test_transformations/test_cft.py @@ -15,12 +15,13 @@ """Tests for the ``CFT`` class.""" import numpy as np -from mrmustard import math +from mrmustard import math, settings from mrmustard.lab_dev import BtoPS, DisplacedSqueezed from mrmustard.lab_dev.transformations.cft import CFT from mrmustard.physics.wigner import wigner_discretized + class TestCFT: r""" Tests the CFT gate @@ -32,11 +33,13 @@ def test_init(self): assert cft.name == "CFT" assert cft.modes == [0] + def test_wigner_function(self): r""" Tests that the characteristic function is converted to the Wigner function for a single-mode squeezed state. """ + settings.HBAR = 2 state = DisplacedSqueezed([0], r=0.5, phi=1.0, x=0.4, y=0.4) dm = math.sum(state.to_fock(100).dm().representation.array, axes=[0]) From d6b60120cc06e7d55e8b8090c574f19944148bae Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Wed, 4 Sep 2024 15:28:23 -0400 Subject: [PATCH 09/23] Corrections to cft tests --- tests/test_lab_dev/test_transformations/test_cft.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/test_lab_dev/test_transformations/test_cft.py b/tests/test_lab_dev/test_transformations/test_cft.py index 8c3f60a16..8086939fb 100644 --- a/tests/test_lab_dev/test_transformations/test_cft.py +++ b/tests/test_lab_dev/test_transformations/test_cft.py @@ -40,9 +40,11 @@ def test_wigner_function(self): for a single-mode squeezed state. """ settings.HBAR = 2 - state = DisplacedSqueezed([0], r=0.5, phi=1.0, x=0.4, y=0.4) + settings.HBAR=2 + state = DisplacedSqueezed([0], r=0.5, phi=0.0, x=1.0, y=0.0) - dm = math.sum(state.to_fock(100).dm().representation.array, axes=[0]) + state2 = DisplacedSqueezed([0], r=0.5, phi=np.pi, x=0.0, y=1.0) + dm = math.sum(state2.to_fock(100).dm().representation.array, axes=[0]) xvec = np.linspace(-5, 5, 100) pvec = np.linspace(-5, 5, 100) wigner, _, _ = wigner_discretized(dm, xvec, pvec) @@ -50,5 +52,5 @@ def test_wigner_function(self): Wigner = (state >> CFT([0]) >> BtoPS([0], s=0)).representation.ansatz X, Y = np.meshgrid(xvec, pvec) Z = np.array([X - 1j * Y, X + 1j * Y]).transpose((1, 2, 0)) - assert np.isclose(np.max(np.real(Wigner(Z))), np.max(np.real(wigner)), atol=1e-8) - assert np.isclose(np.max(np.real(Wigner(Z))), np.max(np.real(wigner)), atol=1e-8) + assert math.allclose((np.real(Wigner(Z))), (np.real(wigner)), atol=1e-8) + assert math.allclose(np.max(np.real(Wigner(Z))), np.max(np.real(wigner)), atol=1e-8) From b967052a0d0d6c56a38383934dd6f82bcf7c7446 Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Wed, 4 Sep 2024 15:32:16 -0400 Subject: [PATCH 10/23] Formatting --- mrmustard/lab_dev/transformations/cft.py | 13 +++++++------ mrmustard/physics/ansatze.py | 2 +- mrmustard/physics/triples.py | 1 + tests/test_lab_dev/test_transformations/test_cft.py | 4 +--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mrmustard/lab_dev/transformations/cft.py b/mrmustard/lab_dev/transformations/cft.py index 26c092bcc..fff327ddf 100644 --- a/mrmustard/lab_dev/transformations/cft.py +++ b/mrmustard/lab_dev/transformations/cft.py @@ -21,6 +21,7 @@ from mrmustard.physics.representations import Bargmann from mrmustard.physics import triples + class CFT(Map): r"""The Complex Fourier Transformation as a channel. The main use is to convert between Characteristic functions and phase space functions. @@ -32,12 +33,12 @@ class CFT(Map): def __init__( self, modes: Sequence[int], - ): + ): super().__init__( - modes_out=modes, - modes_in=modes, - name="CFT", + modes_out=modes, + modes_in=modes, + name="CFT", ) self._representation = Bargmann.from_function( - fn=triples.complex_fourier_transform_Abc, n_modes=len(modes) - ) \ No newline at end of file + fn=triples.complex_fourier_transform_Abc, n_modes=len(modes) + ) diff --git a/mrmustard/physics/ansatze.py b/mrmustard/physics/ansatze.py index 561c8db02..f23d2b8d7 100644 --- a/mrmustard/physics/ansatze.py +++ b/mrmustard/physics/ansatze.py @@ -1225,4 +1225,4 @@ def bargmann_Abc_to_phasespace_cov_means( ] if batched: return math.astensor(cov), math.astensor(mean), coeff - return cov[0], mean[0], coeff[0] \ No newline at end of file + return cov[0], mean[0], coeff[0] diff --git a/mrmustard/physics/triples.py b/mrmustard/physics/triples.py index 64175bc3b..216a96ee0 100644 --- a/mrmustard/physics/triples.py +++ b/mrmustard/physics/triples.py @@ -702,6 +702,7 @@ def complex_fourier_transform_Abc(n_modes: int) -> Union[Matrix, Vector, Scalar] c = 1.0 + 0j return A, b, c + # ~~~~~~~~~~~~~~~~ # Kraus operators # ~~~~~~~~~~~~~~~~ diff --git a/tests/test_lab_dev/test_transformations/test_cft.py b/tests/test_lab_dev/test_transformations/test_cft.py index 8086939fb..2af609e94 100644 --- a/tests/test_lab_dev/test_transformations/test_cft.py +++ b/tests/test_lab_dev/test_transformations/test_cft.py @@ -21,7 +21,6 @@ from mrmustard.physics.wigner import wigner_discretized - class TestCFT: r""" Tests the CFT gate @@ -33,14 +32,13 @@ def test_init(self): assert cft.name == "CFT" assert cft.modes == [0] - def test_wigner_function(self): r""" Tests that the characteristic function is converted to the Wigner function for a single-mode squeezed state. """ settings.HBAR = 2 - settings.HBAR=2 + settings.HBAR = 2 state = DisplacedSqueezed([0], r=0.5, phi=0.0, x=1.0, y=0.0) state2 = DisplacedSqueezed([0], r=0.5, phi=np.pi, x=0.0, y=1.0) From 2a1afc1ded8d887eaf7bdf11dd34da15b299c600 Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Wed, 4 Sep 2024 15:35:19 -0400 Subject: [PATCH 11/23] Formatting --- mrmustard/lab_dev/transformations/cft.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mrmustard/lab_dev/transformations/cft.py b/mrmustard/lab_dev/transformations/cft.py index fff327ddf..df90482a8 100644 --- a/mrmustard/lab_dev/transformations/cft.py +++ b/mrmustard/lab_dev/transformations/cft.py @@ -4,7 +4,7 @@ # 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 +# 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, @@ -27,7 +27,7 @@ class CFT(Map): The main use is to convert between Characteristic functions and phase space functions. Args: - num_modes: number of modes of this channel. + num_modes: number of modes of this channel. """ def __init__( From eeddaff7844ac53b8bb01e5d5d4cc7baf0a3f26e Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Wed, 4 Sep 2024 15:50:38 -0400 Subject: [PATCH 12/23] Test fixes --- tests/test_lab_dev/test_states/test_states_base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_lab_dev/test_states/test_states_base.py b/tests/test_lab_dev/test_states/test_states_base.py index aae1021ca..80614e8c1 100644 --- a/tests/test_lab_dev/test_states/test_states_base.py +++ b/tests/test_lab_dev/test_states/test_states_base.py @@ -144,7 +144,7 @@ def test_to_from_fock(self, modes): @pytest.mark.parametrize("modes", [[0], [0, 1], [3, 19, 2]]) def test_to_from_phase_space(self, modes): cov, means, coeff = Coherent([0], x=1, y=2).phase_space(s=0) - assert math.allclose(coeff[0], 1.0) + assert math.allclose(coeff[0], 1.0 / (2 * np.pi)) assert math.allclose(cov[0], np.eye(2) * settings.HBAR / 2) assert math.allclose(means[0], np.array([1.0, 2.0]) * np.sqrt(2 * settings.HBAR)) n_modes = len(modes) @@ -552,7 +552,7 @@ def test_to_from_fock(self, modes): def test_to_from_phase_space(self): state0 = Coherent([0], x=1, y=2) >> Attenuator([0], 1.0) cov, means, coeff = state0.phase_space(s=0) # batch = 1 - assert coeff[0] == 1.0 + assert coeff[0] == 1.0 / (2 * np.pi) assert math.allclose(cov[0], np.eye(2) * settings.HBAR / 2) assert math.allclose(means[0], np.array([1.0, 2.0]) * np.sqrt(settings.HBAR * 2)) From fe693f308d3dc8aca620e253f3f8be3c590873cf Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Thu, 5 Sep 2024 15:32:25 -0400 Subject: [PATCH 13/23] Addressing Anthony's comments --- mrmustard/physics/ansatze.py | 4 ++-- mrmustard/physics/triples.py | 2 +- tests/test_lab_dev/test_states/test_states_base.py | 12 ++++++------ tests/test_lab_dev/test_transformations/test_cft.py | 13 +++++-------- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/mrmustard/physics/ansatze.py b/mrmustard/physics/ansatze.py index f23d2b8d7..7f5a6d5bd 100644 --- a/mrmustard/physics/ansatze.py +++ b/mrmustard/physics/ansatze.py @@ -1184,7 +1184,7 @@ def __truediv__(self, other: Scalar | ArrayAnsatz) -> ArrayAnsatz: def bargmann_Abc_to_phasespace_cov_means( - A: Matrix, b: Vector, c: Scalar + A: Matrix, b: Vector, c: Scalar, batched: bool = False ) -> tuple[Matrix, Vector, Scalar]: r""" Function to derive the covariance matrix and mean vector of a Gaussian state from its Wigner characteristic function in ABC form. @@ -1208,7 +1208,7 @@ def bargmann_Abc_to_phasespace_cov_means( Returns: The covariance matrix, mean vector and coefficient of the state in phase space. """ - batched = len(A.shape) == 3 and len(b.shape) == 2 and len(c.shape) == 1 + # batched = len(A.shape) == 3 and len(b.shape) == 2 and len(c.shape) == 1 A = math.atleast_3d(A) b = math.atleast_2d(b) c = math.atleast_1d(c) diff --git a/mrmustard/physics/triples.py b/mrmustard/physics/triples.py index 216a96ee0..3a3d1354b 100644 --- a/mrmustard/physics/triples.py +++ b/mrmustard/physics/triples.py @@ -681,7 +681,7 @@ def displacement_map_s_parametrized_Abc(s: int, n_modes: int) -> Union[Matrix, V return math.astensor(A), b, c -def complex_fourier_transform_Abc(n_modes: int) -> Union[Matrix, Vector, Scalar]: +def complex_fourier_transform_Abc(n_modes: int) -> tuple[Matrix, Vector, Scalar]: r""" The ``(A, b, c)`` triple of the complex Fourier transform between two pairs of complex variables. Given a function :math:`f(z^*, z)`, the complex Fourier transform is defined as diff --git a/tests/test_lab_dev/test_states/test_states_base.py b/tests/test_lab_dev/test_states/test_states_base.py index 80614e8c1..79a877fc9 100644 --- a/tests/test_lab_dev/test_states/test_states_base.py +++ b/tests/test_lab_dev/test_states/test_states_base.py @@ -144,9 +144,9 @@ def test_to_from_fock(self, modes): @pytest.mark.parametrize("modes", [[0], [0, 1], [3, 19, 2]]) def test_to_from_phase_space(self, modes): cov, means, coeff = Coherent([0], x=1, y=2).phase_space(s=0) - assert math.allclose(coeff[0], 1.0 / (2 * np.pi)) - assert math.allclose(cov[0], np.eye(2) * settings.HBAR / 2) - assert math.allclose(means[0], np.array([1.0, 2.0]) * np.sqrt(2 * settings.HBAR)) + assert math.allclose(coeff, 1.0 / (2 * np.pi)) + assert math.allclose(cov, np.eye(2) * settings.HBAR / 2) + assert math.allclose(means, np.array([1.0, 2.0]) * np.sqrt(2 * settings.HBAR)) n_modes = len(modes) state1 = Ket.from_phase_space(modes, (vacuum_cov(n_modes), vacuum_means(n_modes), 1.0)) @@ -552,9 +552,9 @@ def test_to_from_fock(self, modes): def test_to_from_phase_space(self): state0 = Coherent([0], x=1, y=2) >> Attenuator([0], 1.0) cov, means, coeff = state0.phase_space(s=0) # batch = 1 - assert coeff[0] == 1.0 / (2 * np.pi) - assert math.allclose(cov[0], np.eye(2) * settings.HBAR / 2) - assert math.allclose(means[0], np.array([1.0, 2.0]) * np.sqrt(settings.HBAR * 2)) + assert coeff == 1.0 / (2 * np.pi) + assert math.allclose(cov, np.eye(2) * settings.HBAR / 2) + assert math.allclose(means, np.array([1.0, 2.0]) * np.sqrt(settings.HBAR * 2)) # test error with pytest.raises(ValueError): diff --git a/tests/test_lab_dev/test_transformations/test_cft.py b/tests/test_lab_dev/test_transformations/test_cft.py index 2af609e94..719352aee 100644 --- a/tests/test_lab_dev/test_transformations/test_cft.py +++ b/tests/test_lab_dev/test_transformations/test_cft.py @@ -37,18 +37,15 @@ def test_wigner_function(self): Tests that the characteristic function is converted to the Wigner function for a single-mode squeezed state. """ - settings.HBAR = 2 - settings.HBAR = 2 + state = DisplacedSqueezed([0], r=0.5, phi=0.0, x=1.0, y=0.0) state2 = DisplacedSqueezed([0], r=0.5, phi=np.pi, x=0.0, y=1.0) dm = math.sum(state2.to_fock(100).dm().representation.array, axes=[0]) - xvec = np.linspace(-5, 5, 100) - pvec = np.linspace(-5, 5, 100) - wigner, _, _ = wigner_discretized(dm, xvec, pvec) + vec = np.linspace(-5, 5, 100) + wigner, _, _ = wigner_discretized(dm, vec, vec) Wigner = (state >> CFT([0]) >> BtoPS([0], s=0)).representation.ansatz - X, Y = np.meshgrid(xvec, pvec) + X, Y = np.meshgrid(vec*np.sqrt(2), vec*np.sqrt(2)) #scaling to take care of HBAR Z = np.array([X - 1j * Y, X + 1j * Y]).transpose((1, 2, 0)) - assert math.allclose((np.real(Wigner(Z))), (np.real(wigner)), atol=1e-8) - assert math.allclose(np.max(np.real(Wigner(Z))), np.max(np.real(wigner)), atol=1e-8) + assert math.allclose(2*(np.real(Wigner(Z))), (np.real(wigner)), atol=1e-8) #scaling to take care of HBAR From 6be3a8236ec80e1e16caea36d2efb094878418ea Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Thu, 5 Sep 2024 15:32:55 -0400 Subject: [PATCH 14/23] Formatting --- tests/test_lab_dev/test_transformations/test_cft.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_lab_dev/test_transformations/test_cft.py b/tests/test_lab_dev/test_transformations/test_cft.py index 719352aee..6ea75860d 100644 --- a/tests/test_lab_dev/test_transformations/test_cft.py +++ b/tests/test_lab_dev/test_transformations/test_cft.py @@ -46,6 +46,8 @@ def test_wigner_function(self): wigner, _, _ = wigner_discretized(dm, vec, vec) Wigner = (state >> CFT([0]) >> BtoPS([0], s=0)).representation.ansatz - X, Y = np.meshgrid(vec*np.sqrt(2), vec*np.sqrt(2)) #scaling to take care of HBAR + X, Y = np.meshgrid(vec * np.sqrt(2), vec * np.sqrt(2)) # scaling to take care of HBAR Z = np.array([X - 1j * Y, X + 1j * Y]).transpose((1, 2, 0)) - assert math.allclose(2*(np.real(Wigner(Z))), (np.real(wigner)), atol=1e-8) #scaling to take care of HBAR + assert math.allclose( + 2 * (np.real(Wigner(Z))), (np.real(wigner)), atol=1e-8 + ) # scaling to take care of HBAR From 9b07e9d21e1556d80a56f363b5303c504e539c92 Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Thu, 5 Sep 2024 16:38:14 -0400 Subject: [PATCH 15/23] hbar and settings and test_probability --- tests/test_lab_dev/test_transformations/test_cft.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_lab_dev/test_transformations/test_cft.py b/tests/test_lab_dev/test_transformations/test_cft.py index 6ea75860d..6e8e7dadb 100644 --- a/tests/test_lab_dev/test_transformations/test_cft.py +++ b/tests/test_lab_dev/test_transformations/test_cft.py @@ -46,8 +46,8 @@ def test_wigner_function(self): wigner, _, _ = wigner_discretized(dm, vec, vec) Wigner = (state >> CFT([0]) >> BtoPS([0], s=0)).representation.ansatz - X, Y = np.meshgrid(vec * np.sqrt(2), vec * np.sqrt(2)) # scaling to take care of HBAR + X, Y = np.meshgrid(vec * np.sqrt(2/settings.HBAR), vec * np.sqrt(2/settings.HBAR)) # scaling to take care of HBAR Z = np.array([X - 1j * Y, X + 1j * Y]).transpose((1, 2, 0)) assert math.allclose( - 2 * (np.real(Wigner(Z))), (np.real(wigner)), atol=1e-8 + 2/settings.HBAR * (np.real(Wigner(Z))), (np.real(wigner)), atol=1e-8 ) # scaling to take care of HBAR From 8e90a9ddf29caf1df173268f8eb770fa81ff3a82 Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Thu, 5 Sep 2024 16:41:48 -0400 Subject: [PATCH 16/23] formatting --- tests/test_lab_dev/test_transformations/test_cft.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_lab_dev/test_transformations/test_cft.py b/tests/test_lab_dev/test_transformations/test_cft.py index 6e8e7dadb..21161920a 100644 --- a/tests/test_lab_dev/test_transformations/test_cft.py +++ b/tests/test_lab_dev/test_transformations/test_cft.py @@ -46,8 +46,10 @@ def test_wigner_function(self): wigner, _, _ = wigner_discretized(dm, vec, vec) Wigner = (state >> CFT([0]) >> BtoPS([0], s=0)).representation.ansatz - X, Y = np.meshgrid(vec * np.sqrt(2/settings.HBAR), vec * np.sqrt(2/settings.HBAR)) # scaling to take care of HBAR + X, Y = np.meshgrid( + vec * np.sqrt(2 / settings.HBAR), vec * np.sqrt(2 / settings.HBAR) + ) # scaling to take care of HBAR Z = np.array([X - 1j * Y, X + 1j * Y]).transpose((1, 2, 0)) assert math.allclose( - 2/settings.HBAR * (np.real(Wigner(Z))), (np.real(wigner)), atol=1e-8 + 2 / settings.HBAR * (np.real(Wigner(Z))), (np.real(wigner)), atol=1e-8 ) # scaling to take care of HBAR From 5f17b44d0b2cca8f906d6ed83b273f9ece55cb77 Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Fri, 6 Sep 2024 10:46:42 -0400 Subject: [PATCH 17/23] A minor fix for the `batched` argument of `def phase_space` --- mrmustard/lab_dev/states/base.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mrmustard/lab_dev/states/base.py b/mrmustard/lab_dev/states/base.py index a702f90eb..49c248a43 100644 --- a/mrmustard/lab_dev/states/base.py +++ b/mrmustard/lab_dev/states/base.py @@ -329,7 +329,9 @@ def phase_space(self, s: float) -> tuple: raise ValueError("Can calculate phase space only for Bargmann states.") new_state = self >> BtoPS(self.modes, s=s) - return bargmann_Abc_to_phasespace_cov_means(*new_state.bargmann_triple(batched=True)) + return bargmann_Abc_to_phasespace_cov_means( + *new_state.bargmann_triple(batched=True), batched=True + ) def quadrature_distribution(self, quad: Vector, phi: float = 0.0) -> tuple | ComplexTensor: r""" From 500dcdcf723a8bd457de748beece05bc4d0dca2f Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Fri, 6 Sep 2024 10:50:31 -0400 Subject: [PATCH 18/23] init-related stuff --- mrmustard/lab_dev/transformations/__init__.py | 1 + mrmustard/lab_dev/transformations/cft.py | 1 + 2 files changed, 2 insertions(+) diff --git a/mrmustard/lab_dev/transformations/__init__.py b/mrmustard/lab_dev/transformations/__init__.py index af390f13a..1ac9cc9fb 100644 --- a/mrmustard/lab_dev/transformations/__init__.py +++ b/mrmustard/lab_dev/transformations/__init__.py @@ -26,3 +26,4 @@ from .rgate import * from .s2gate import * from .sgate import * +from .cft import * \ No newline at end of file diff --git a/mrmustard/lab_dev/transformations/cft.py b/mrmustard/lab_dev/transformations/cft.py index df90482a8..b5b768aab 100644 --- a/mrmustard/lab_dev/transformations/cft.py +++ b/mrmustard/lab_dev/transformations/cft.py @@ -21,6 +21,7 @@ from mrmustard.physics.representations import Bargmann from mrmustard.physics import triples +__all__ = ["CFT"] class CFT(Map): r"""The Complex Fourier Transformation as a channel. From caf67a56af23ae85fcb71c5deafcb054bf8c8784 Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Fri, 6 Sep 2024 10:54:16 -0400 Subject: [PATCH 19/23] formatting --- mrmustard/lab_dev/transformations/__init__.py | 2 +- mrmustard/lab_dev/transformations/cft.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mrmustard/lab_dev/transformations/__init__.py b/mrmustard/lab_dev/transformations/__init__.py index 1ac9cc9fb..675d98fd9 100644 --- a/mrmustard/lab_dev/transformations/__init__.py +++ b/mrmustard/lab_dev/transformations/__init__.py @@ -26,4 +26,4 @@ from .rgate import * from .s2gate import * from .sgate import * -from .cft import * \ No newline at end of file +from .cft import * diff --git a/mrmustard/lab_dev/transformations/cft.py b/mrmustard/lab_dev/transformations/cft.py index b5b768aab..349d377f5 100644 --- a/mrmustard/lab_dev/transformations/cft.py +++ b/mrmustard/lab_dev/transformations/cft.py @@ -23,6 +23,7 @@ __all__ = ["CFT"] + class CFT(Map): r"""The Complex Fourier Transformation as a channel. The main use is to convert between Characteristic functions and phase space functions. From aff7e8940e83009d54703aff10c613af3ad3c8ba Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Fri, 6 Sep 2024 11:04:03 -0400 Subject: [PATCH 20/23] fixed batch errors for phase_space() --- tests/test_lab_dev/test_states/test_states_base.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_lab_dev/test_states/test_states_base.py b/tests/test_lab_dev/test_states/test_states_base.py index 79a877fc9..a34a18438 100644 --- a/tests/test_lab_dev/test_states/test_states_base.py +++ b/tests/test_lab_dev/test_states/test_states_base.py @@ -144,9 +144,9 @@ def test_to_from_fock(self, modes): @pytest.mark.parametrize("modes", [[0], [0, 1], [3, 19, 2]]) def test_to_from_phase_space(self, modes): cov, means, coeff = Coherent([0], x=1, y=2).phase_space(s=0) - assert math.allclose(coeff, 1.0 / (2 * np.pi)) - assert math.allclose(cov, np.eye(2) * settings.HBAR / 2) - assert math.allclose(means, np.array([1.0, 2.0]) * np.sqrt(2 * settings.HBAR)) + assert math.allclose(coeff[0], 1.0 / (2 * np.pi)) + assert math.allclose(cov[0], np.eye(2) * settings.HBAR / 2) + assert math.allclose(means[0], np.array([1.0, 2.0]) * np.sqrt(2 * settings.HBAR)) n_modes = len(modes) state1 = Ket.from_phase_space(modes, (vacuum_cov(n_modes), vacuum_means(n_modes), 1.0)) @@ -553,8 +553,8 @@ def test_to_from_phase_space(self): state0 = Coherent([0], x=1, y=2) >> Attenuator([0], 1.0) cov, means, coeff = state0.phase_space(s=0) # batch = 1 assert coeff == 1.0 / (2 * np.pi) - assert math.allclose(cov, np.eye(2) * settings.HBAR / 2) - assert math.allclose(means, np.array([1.0, 2.0]) * np.sqrt(settings.HBAR * 2)) + assert math.allclose(cov[0], np.eye(2) * settings.HBAR / 2) + assert math.allclose(means[0], np.array([1.0, 2.0]) * np.sqrt(settings.HBAR * 2)) # test error with pytest.raises(ValueError): From e08c16687ae191fa79e0c0aa8bc880871a43d9c0 Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Fri, 6 Sep 2024 11:19:48 -0400 Subject: [PATCH 21/23] improving CFT's test --- tests/test_lab_dev/test_transformations/test_cft.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/test_lab_dev/test_transformations/test_cft.py b/tests/test_lab_dev/test_transformations/test_cft.py index 21161920a..a418986e8 100644 --- a/tests/test_lab_dev/test_transformations/test_cft.py +++ b/tests/test_lab_dev/test_transformations/test_cft.py @@ -16,7 +16,7 @@ import numpy as np from mrmustard import math, settings -from mrmustard.lab_dev import BtoPS, DisplacedSqueezed +from mrmustard.lab_dev import BtoPS, Ket, Dgate from mrmustard.lab_dev.transformations.cft import CFT from mrmustard.physics.wigner import wigner_discretized @@ -38,18 +38,17 @@ def test_wigner_function(self): for a single-mode squeezed state. """ - state = DisplacedSqueezed([0], r=0.5, phi=0.0, x=1.0, y=0.0) + state = Ket.random([0]) >> Dgate([0],x=1.0,y=0.1) - state2 = DisplacedSqueezed([0], r=0.5, phi=np.pi, x=0.0, y=1.0) - dm = math.sum(state2.to_fock(100).dm().representation.array, axes=[0]) + dm = math.sum(state.to_fock(100).dm().representation.array, axes=[0]) vec = np.linspace(-5, 5, 100) wigner, _, _ = wigner_discretized(dm, vec, vec) - Wigner = (state >> CFT([0]) >> BtoPS([0], s=0)).representation.ansatz + Wigner = (state >> CFT([0]).inverse() >> BtoPS([0], s=0)).representation.ansatz X, Y = np.meshgrid( vec * np.sqrt(2 / settings.HBAR), vec * np.sqrt(2 / settings.HBAR) ) # scaling to take care of HBAR Z = np.array([X - 1j * Y, X + 1j * Y]).transpose((1, 2, 0)) assert math.allclose( - 2 / settings.HBAR * (np.real(Wigner(Z))), (np.real(wigner)), atol=1e-8 + 2 / settings.HBAR * (np.real(Wigner(Z))), (np.real(wigner.T)), atol=1e-8 ) # scaling to take care of HBAR From 5aa7afab3ed2aa03f64b91cbf84386293728bc11 Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Fri, 6 Sep 2024 11:20:36 -0400 Subject: [PATCH 22/23] Formatting --- tests/test_lab_dev/test_transformations/test_cft.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_lab_dev/test_transformations/test_cft.py b/tests/test_lab_dev/test_transformations/test_cft.py index a418986e8..478cd45a9 100644 --- a/tests/test_lab_dev/test_transformations/test_cft.py +++ b/tests/test_lab_dev/test_transformations/test_cft.py @@ -38,7 +38,7 @@ def test_wigner_function(self): for a single-mode squeezed state. """ - state = Ket.random([0]) >> Dgate([0],x=1.0,y=0.1) + state = Ket.random([0]) >> Dgate([0], x=1.0, y=0.1) dm = math.sum(state.to_fock(100).dm().representation.array, axes=[0]) vec = np.linspace(-5, 5, 100) From f7210056dc78531b936efd2dd83d67b790f1664b Mon Sep 17 00:00:00 2001 From: Arsalan Motamedi Date: Fri, 6 Sep 2024 11:59:26 -0400 Subject: [PATCH 23/23] Adding details to CFT --- mrmustard/lab_dev/transformations/cft.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mrmustard/lab_dev/transformations/cft.py b/mrmustard/lab_dev/transformations/cft.py index 349d377f5..c5174a026 100644 --- a/mrmustard/lab_dev/transformations/cft.py +++ b/mrmustard/lab_dev/transformations/cft.py @@ -30,6 +30,12 @@ class CFT(Map): Args: num_modes: number of modes of this channel. + + .. details:: + For a function f defined on the complex domain, we can define the following Complex Fourier Transform (aka symplectic Fourier Transform): + .. math:: + \hat f(\zeta) = \int f(z) \exp(z \bar{\zeta} - \bar{z} \zeta) + this formulation can be extended to multi-variables by taking the transform over many (i.e., by as many zeta variables as needed) """ def __init__(