Transformations¶
The noisy amplifier channel. |
|
The noisy attenuator channel. |
|
The beam splitter gate. |
|
Base class for all CPTP channels. |
|
Controlled X gate. |
|
Controlled Z gate. |
|
The displacement gate. |
|
The Fock damping operator. |
|
The generic N-mode Gaussian gate. |
|
The Gaussian random noise channel. |
|
The identity gate. |
|
N-mode interferometer. |
|
The Kerr gate. |
|
A |
|
Mach-Zehnder gate. |
|
A CircuitComponent with input and output wires on the ket side. |
|
The Phase noise channel. |
|
Quadratic phase gate. |
|
N-mode interferometer parametrized by an NxN orthogonal matrix (or 2N x 2N block-diagonal orthogonal matrix). |
|
The rotation gate. |
|
The two-mode squeezing gate. |
|
The squeezing gate. |
|
Base class for all transformations. |
|
Base class for all unitary transformations. |
Inheritance Diagram¶

Amplifier¶
- class mrmustard.lab.transformations.Amplifier(mode, gain=1.0, name=None)[source]¶
Bases:
ChannelThe noisy amplifier channel.
>>> import numpy as np >>> from mrmustard.lab import Amplifier, Coherent >>> from mrmustard import settings >>> amp = Amplifier(0, gain=4) >>> coh = Coherent(0, alpha=1.0 + 2.0j) >>> _, mu, _ = (coh >> amp).phase_space(0) >>> assert np.allclose(mu*np.sqrt(2/settings.HBAR), np.array([4.0, 8.0]))
- Parameters:
mode (int | tuple[int]) – The mode this gate is applied to.
gain (float | Sequence[float] | Parameter) – The gain.
name (str | None) – A name for the channel. If not provided, the class name will be used.
Details and Conventions
The \(N\)-mode attenuator is defined as
\[X = /sqrt{/bar{g}}I_{2N} \text{ , } Y = (/bar{g}-1)I_{2N} \text{ , and } d = O_{4N}\:,\]where \(/bar{g}\) is the gain and \(\text{diag}_N(\bar{g})\) is the \(N\text{x}N\) matrix with diagonal \(\bar{g}\).
Its
(A,b,c)triple is given by\[\begin{split}A &= \begin{bmatrix} O_N & \text{diag}_N(1/(\sqrt{\bar{g}}) & \text{diag}_N(1-1/\bar{g}) & O_N \\ \text{diag}_N(1/(\sqrt{\bar{g}}) & O_N & O_N & O_N \\ \text{diag}_N(1-1/\bar{g}) & O_N & O_N & \text{diag}_N(1/(\bar{g})\\ O_N & O_N & \text{diag}_N(1/(\sqrt{\bar{g}}) & O_N \end{bmatrix} \\ \\ b &= O_{4N} \\ \\ c &= 1//bar{g}\:.\end{split}\]
Attenuator¶
- class mrmustard.lab.transformations.Attenuator(mode, transmissivity=1.0, name=None)[source]¶
Bases:
ChannelThe noisy attenuator channel.
>>> from mrmustard import math >>> from mrmustard.lab import Attenuator >>> channel = Attenuator(mode=1, transmissivity=0.1) >>> assert channel.modes == (1,) >>> assert channel.parameters.transmissivity.value == 0.1
- Parameters:
mode (int | tuple[int]) – The mode this gate is applied to.
transmissivity (float | Sequence[float] | Parameter) – The transmissivity.
name (str | None) – A name for the channel. If not provided, the class name will be used.
Details and Conventions
The \(N\)-mode attenuator is defined as
\[X = \text{cos}(\theta)I_{2N} \text{ , } Y = \text{sin}^2(\theta)I_{2N} \text{ , and } d = O_{4N}\:,\]where the \(\theta=\text{arcos}(\sqrt{\bar{\eta}})\), \(\eta\) is the transmissivity, and \(\text{diag}_N(\bar{\eta})\) is the \(N\text{x}N\) matrix with diagonal \(\bar{\eta}\).
Its
(A,b,c)triple is given by\[\begin{split}A &= \begin{bmatrix} O_N & \text{diag}_N(\sqrt{\bar{\eta}}) & O_N & O_N \\ \text{diag}_N(\sqrt{\bar{\eta}}) & O_N & O_N & \text{diag}_N(1-\sqrt{\bar{\eta}})\\ O_N & O_N & O_N & \text{diag}_N(\sqrt{\bar{\eta}})\\ O_N & \text{diag}_N(1-\sqrt{\bar{\eta}}) & \text{diag}_N(\sqrt{\bar{\eta}}) & O_N \end{bmatrix} \\ \\ b &= O_{4N} \\ \\ c &= 1\:.\end{split}\]
BSgate¶
- class mrmustard.lab.transformations.BSgate(modes, theta=0.0, phi=0.0, name=None)[source]¶
Bases:
UnitaryThe beam splitter gate.
>>> from mrmustard.lab import BSgate >>> unitary = BSgate(modes=(1, 2), theta=0.1) >>> assert unitary.modes == (1, 2) >>> assert unitary.parameters.theta.value == 0.1 >>> assert unitary.parameters.phi.value == 0.0
- Parameters:
Details and Conventions
The beamsplitter gate is a Gaussian gate defined by
\[\begin{split}S = \begin{bmatrix} \text{Re}(U) & -\text{Im}(U)\\ \text{Im}(U) & \text{Re}(U) \end{bmatrix} \text{ and } d = O_4\:,\end{split}\]with
\[\begin{split}U &= \begin{bmatrix} \text{cos}(\theta) & -e^{-i\phi}\text{sin}(\theta)\\ e^{i\phi}\text{sin}(\theta) & \text{cos}(\theta) \end{bmatrix} \\\end{split}\]Its
(A,b,c)triple is given by\[\begin{split}A = \begin{bmatrix} O_2 & U \\ U^{T} & O_2 \end{bmatrix} \text{, } b = O_{4} \text{, and } c = 1\end{split}\]- fock_array(shape=None, method='stable')[source]¶
Returns the unitary representation of the Beam Splitter gate in the Fock basis.
- Parameters:
shape (int | Sequence[int] | None) – The shape of the returned representation. If
shapeis given as anint, it is broadcasted to all the dimensions. If not given, it defaults tosettings.DEFAULT_FOCK_SIZE.method (str) – The method to use to compute the Fock array. Available methods are: -
"vanilla": standard recurrence relation (not numerically stable, but slightly faster than the stable one). -"schwinger": Use the Schwinger representation to compute the Fock array. -"stable": Use the stable implementation of the beamsplitter. (default)
- Returns:
The Fock representation of this component.
- Return type:
array
Channel¶
- class mrmustard.lab.transformations.Channel(ansatz_factory=None, wires=None, name=None)[source]¶
Bases:
MapBase class for all CPTP channels.
- Parameters:
ansatz_factory (AnsatzFactory | None)
wires (Wires | None)
name (str | None)
- property is_CP: bool¶
Whether this channel is completely positive (CP).
>>> from mrmustard.lab import Channel >>> channel = Channel.random((0, 1, 2)) >>> assert channel.is_CP
- property is_TP: bool¶
Whether this channel is trace preserving (TP).
>>> from mrmustard.lab import Channel >>> channel = Channel.random((0, 1, 2)) >>> assert channel.is_TP
- property is_physical: bool¶
Whether this channel is physical (i.e. CPTP).
>>> from mrmustard.lab import Channel >>> channel = Channel.random((0, 1, 2)) >>> assert channel.is_physical
- property XY: tuple[mrmustard.utils.typing.ComplexMatrix, mrmustard.utils.typing.ComplexMatrix]¶
Returns the X and Y matrix corresponding to the channel.
>>> from mrmustard.lab import Channel >>> channel = Channel.random((0, 1)) >>> X, Y = channel.XY >>> assert X.shape == (4, 4) >>> assert Y.shape == (4, 4)
- classmethod from_ansatz(modes_out, modes_in, ansatz=None, name=None)[source]¶
Initializes a transformation of type
clsgiven modes and an ansatz.- Parameters:
modes_out (Sequence[int]) – The output modes of this transformation.
modes_in (Sequence[int]) – The input modes of this transformation.
ansatz (PolyExpAnsatz | ArrayAnsatz | None) – The ansatz of this transformation.
name (str | None) – The name of this transformation.
- Returns:
A transformation.
- Return type:
- classmethod from_XY(modes_out, modes_in, X, Y, d=None, name=None)[source]¶
Initialize a Channel from its XY representation.
>>> from mrmustard.lab import Attenuator, Channel >>> X = math.eye(2) >>> Y = math.zeros((2,2)) >>> channel = Channel.from_XY([0], [0], X,Y) >>> assert channel == Attenuator(0, transmissivity=1)
- Parameters:
modes_out (Sequence[int]) – The output modes of the channel.
modes_in (Sequence[int]) – The input modes of the channel.
X (RealMatrix) – The X matrix of the channel.
Y (RealMatrix) – The Y matrix of the channel.
d (Vector | None) – The displacement vector of the channel.
name (str | None) – A name for the channel. If not provided, the class name will be used.
- Raises:
ValueError – If the dimensions of the X,Y matrices and the number of modes don’t match.
- Return type:
Details and Conventions
Each Gaussian channel transforms a state with covarince matrix \(\Sigma\) and mean \(\mu\) into a state with covariance matrix \(X \Sigma X^T + Y\) and vector of means \(X\mu + d\). This channel has a Bargmann triple that is computed in https://arxiv.org/pdf/2209.06069. We borrow the formulas from the paper to implement the corresponding channel.
- classmethod random(modes, max_r=1.0, seed=None, name=None)[source]¶
A random channel without displacement.
>>> from mrmustard.lab import Channel >>> channel = Channel.random((0, 1, 2), max_r=1.2) >>> assert channel.modes == (0, 1, 2)
- Parameters:
modes (int | tuple[int, ...]) – The modes of the channel.
max_r (float) – The maximum squeezing parameter.
seed (int | None) – The random seed. If
None, the global seed is used.name (str | None) – A name for the channel. If not provided, the class name will be used.
- Returns:
The random channel.
- Raises:
ValueError – if
modesis an empty tuple.- Return type:
CXgate¶
- class mrmustard.lab.transformations.CXgate(modes, s=0.0, name=None)[source]¶
Bases:
UnitaryControlled X gate.
>>> from mrmustard.lab import CXgate >>> gate = CXgate((0, 1), s=0.5) >>> assert gate.modes == (0, 1) >>> assert gate.parameters.s.value == 0.5
- Parameters:
modes (tuple[int, int]) – The pair of modes of the controlled-X gate.
s (float | Sequence[float] | Parameter) – The control parameter.
name (str | None) – A name for the gate. If not provided, the class name will be used.
Details and Conventions
- We have that the controlled-X gate is defined as
- \[C_X = \exp(is q_1 \otimes p_2)\]
Reference: https://arxiv.org/pdf/2110.03247.pdf, Equation 9.
CZgate¶
- class mrmustard.lab.transformations.CZgate(modes, s=0.0, name=None)[source]¶
Bases:
UnitaryControlled Z gate.
>>> from mrmustard.lab import CZgate >>> gate = CZgate((0, 1), s=0.5) >>> assert gate.modes == (0, 1) >>> assert gate.parameters.s.value == 0.5
- Parameters:
modes (tuple[int, int]) – The pair of modes of the controlled-Z gate.
s (float | Sequence[float] | Parameter) – The control parameter.
name (str | None) – A name for the gate. If not provided, the class name will be used.
Details and Conventions
We have that the controlled-Z gate is defined as
\[C_Z = \exp(is q_1 \otimes q_2 / \hbar).\]Reference: https://arxiv.org/pdf/2110.03247.pdf, Equation 8. https://arxiv.org/pdf/1110.3234.pdf, Equation 161.
Dgate¶
- class mrmustard.lab.transformations.Dgate(mode, alpha=0j, name=None)[source]¶
Bases:
UnitaryThe displacement gate.
>>> from mrmustard.lab import Dgate >>> unitary = Dgate(mode=1, alpha=0.1 + 0.2j) >>> assert unitary.modes == (1,) >>> assert unitary.parameters.alpha.value == 0.1 + 0.2j
- Parameters:
mode (int | tuple[int]) – The mode this gate is applied to.
alpha (complex | Sequence[complex] | Parameter) – The displacement in the complex phase space.
name (str | None) – A name for the gate. If not provided, the class name will be used.
Details and Conventions
For any \(\bar{\alpha} = \bar{x} + i\bar{y}\) of length \(N\), the \(N\)-mode displacement gate is defined by
\[S = I_N \text{ and } r = \sqrt{2\hbar}\big[\text{Re}(\bar{\alpha}), \text{Im}(\bar{\alpha})\big].\]Its
(A,b,c)triple is given by\[\begin{split}A &= \begin{bmatrix} O_N & I_N\\ I_N & O_N \end{bmatrix} \\ \\ b &= \begin{bmatrix} \bar{\alpha} & -\bar{\alpha}^* \end{bmatrix} \\ \\ c &= \text{exp}\big(-|\bar{\alpha}^2|/2\big).\end{split}\]
FockDamping¶
- class mrmustard.lab.transformations.FockDamping(mode, damping=0.0, name=None)[source]¶
Bases:
OperationThe Fock damping operator.
>>> from mrmustard.lab import FockDamping, Coherent >>> operator = FockDamping(mode=0, damping=0.1) >>> input_state = Coherent(mode=0, alpha=1 + 0.5j) >>> output_state = input_state >> operator >>> assert operator.modes == (0,) >>> assert operator.parameters.damping.value == 0.1 >>> assert output_state.L2_norm < 1
- Parameters:
mode (int | tuple[int]) – The mode this gate is applied to.
damping (float | Sequence[float] | Parameter) – The damping parameter.
name (str | None) – A name for the operator. If not provided, the class name will be used.
Details and Conventions
Its
(A,b,c)triple is given by\[ \begin{align}\begin{aligned}\begin{split}A &= e^{-\beta}\begin{bmatrix} O_N & I_N & \\ I_N & O_N &\end{split}\\\begin{split} \end{bmatrix} \\ \\ b &= O_{2N} \\ \\ c &= 1\:.\end{split}\end{aligned}\end{align} \]
Ggate¶
- class mrmustard.lab.transformations.Ggate(modes, symplectic, name=None)[source]¶
Bases:
UnitaryThe generic N-mode Gaussian gate.
>>> from mrmustard import math >>> from mrmustard.lab import Ggate, Vacuum, Identity, Ket >>> U = Ggate.random(modes=0) >>> assert isinstance(Vacuum(0) >> U, Ket) >>> assert U >> U.dual == Identity(0)
- Parameters:
modes (int | tuple[int, ...]) – The modes this gate is applied to.
symplectic (RealMatrix | Parameter) – The symplectic matrix of the gate in the XXPP ordering.
name (str | None) – A name for the gate. If not provided, the class name will be used.
- property symplectic¶
Returns the symplectic matrix that corresponds to this unitary.
- classmethod random(modes, max_r=1.0, seed=None, name=None)[source]¶
Returns a random Ggate.
- Parameters:
modes (int | tuple[int, ...]) – The modes of the Ggate.
max_r (float) – Maximum squeezing parameter over which we make random choices.
seed (int | None) – The random seed. If
None, the global seed is used.name (str | None) – A name for the gate. If not provided, the class name will be used.
- Returns:
The random Ggate.
- Raises:
ValueError – if
modesis an empty tuple.- Return type:
GaussianRandomNoise¶
- class mrmustard.lab.transformations.GaussianRandomNoise(modes, Y, name=None)[source]¶
Bases:
ChannelThe Gaussian random noise channel.
>>> import numpy as np >>> from mrmustard.lab import GaussianRandomNoise >>> channel = GaussianRandomNoise(modes=(1, 2), Y = 0.2 * np.eye(4)) >>> assert channel.modes == (1, 2) >>> assert math.allclose(channel.parameters.Y.value, 0.2 * np.eye(4))
- Parameters:
modes (int | tuple[int, ...]) – The modes the channel is applied to. The number of modes must match half of the size of
Y.Y (RealMatrix | Parameter) – The Y matrix of the Gaussian random noise channel.
name (str | None) – A name for the channel. If not provided, the class name will be used.
- Raises:
ValueError – If the number of modes does not match half of the size of
Y.
Details and Conventions
The Bargmann representation of the channel is computed via the formulas provided in the paper: https://arxiv.org/pdf/2209.06069
The channel maps an inout covariance matrix
covas\[cov \mapsto cov + Y.\]
Identity¶
- class mrmustard.lab.transformations.Identity(modes, name=None)[source]¶
Bases:
UnitaryThe identity gate.
>>> from mrmustard.lab import Identity >>> unitary = Identity(modes=(1, 2)) >>> assert unitary.modes == (1, 2)
- Parameters:
modes (int | tuple[int, ...]) – The modes this gate is applied to.
name (str | None) – A name for the gate. If not provided, the class name will be used.
Details and Conventions
The Abc parametrization of the identity gate is given by (c.f. https://www.scipost.org/10.21468/SciPostPhys.17.3.082) .. math:
A = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}, \quad b = \begin{pmatrix} 0 \\ 0 \end{pmatrix}, \quad c = 1
Interferometer¶
- class mrmustard.lab.transformations.Interferometer(modes, unitary, name=None)[source]¶
Bases:
UnitaryN-mode interferometer.
It corresponds to a Ggate with zero mean and a
2N x 2Nunitary symplectic matrix.>>> from mrmustard import math >>> from mrmustard.lab import Interferometer >>> unitary = Interferometer(modes=(1, 2), unitary=math.eye(2)) >>> assert unitary.modes == (1, 2) >>> assert math.allclose(unitary.symplectic, math.eye(4))
- Parameters:
modes (int | tuple[int, ...]) – The modes this gate is applied to.
unitary (ComplexMatrix | Parameter) – A unitary matrix. For N modes it must have shape (N,N).
name (str | None) – A name for the gate. If not provided, the class name will be used.
- Raises:
ValueError – If the size of the unitary does not match the number of modes.
- classmethod random(modes, seed=None, name=None)[source]¶
Returns a random Interferometer.
- Parameters:
modes (int | tuple[int, ...]) – The modes of the Interferometer.
seed (int | None) – The random seed. If
None, the global seed is used.name (str | None) – A name for the gate. If not provided, the class name will be used.
- Returns:
The random Interferometer.
- Raises:
ValueError – if
modesis an empty tuple.- Return type:
Kgate¶
- class mrmustard.lab.transformations.Kgate(mode, kappa=0.0, normal_ordered=True)[source]¶
Bases:
UnitaryThe Kerr gate.
A non-Gaussian single-mode unitary, diagonal in the Fock basis. By default the generator is the normal-ordered \(a^\dagger a^\dagger a a = n(n-1)\), giving \(U|n\rangle = e^{i\kappa n(n-1)}|n\rangle\). With
normal_ordered=Falsethe generator is \(n^2\), giving \(U|n\rangle = e^{i\kappa n^2}|n\rangle\).>>> from mrmustard.lab import Kgate, Number >>> gate = Kgate(mode=0, kappa=0.1) >>> assert gate.modes == (0,)
- Parameters:
mode (int | tuple[int]) – The mode the gate is applied to.
kappa (float | Parameter) – The Kerr nonlinearity strength.
normal_ordered (bool) – If
True(default), the generator is \(a^\dagger a^\dagger a a = n(n-1)\). IfFalse, the generator is \(n^2\). The two differ only by a linear rotation \(e^{i\kappa n}\), i.e. anRgate.
- property normal_ordered: bool¶
Whether the generator is \(n(n-1)\) (True) or \(n^2\) (False).
Map¶
- class mrmustard.lab.transformations.Map(ansatz_factory=None, wires=None, name=None)[source]¶
Bases:
TransformationA
CircuitComponentmore general thanChannel, which are CPTP maps.- Parameters:
ansatz_factory (AnsatzFactory | None)
wires (Wires | None)
name (str | None)
- classmethod from_ansatz(modes_out, modes_in, ansatz=None, name=None)[source]¶
Initializes a transformation of type
clsgiven modes and an ansatz.- Parameters:
modes_out (Sequence[int]) – The output modes of this transformation.
modes_in (Sequence[int]) – The input modes of this transformation.
ansatz (PolyExpAnsatz | ArrayAnsatz | None) – The ansatz of this transformation.
name (str | None) – The name of this transformation.
- Returns:
A transformation.
- Return type:
MZgate¶
- class mrmustard.lab.transformations.MZgate(modes, phi_a=0.0, phi_b=0.0, internal=False, name=None)[source]¶
Bases:
UnitaryMach-Zehnder gate.
- It supports two conventions:
if
internal=True, both phases act inside the interferometer:phi_aon the upper arm,phi_bon the lower arm.if
internal = False, both phases act on the upper arm:phi_abefore the first BS,phi_bafter the first BS.
>>> from mrmustard.lab import MZgate >>> mz = MZgate((0, 1), phi_a=0.1, phi_b=0.2) >>> assert mz.modes == (0, 1) >>> assert mz.parameters.phi_a.value == 0.1 >>> assert mz.parameters.phi_b.value == 0.2
- Parameters:
modes (tuple[int, int]) – The pair of modes of the MZ gate.
phi_a (float | Sequence[float] | Parameter) – The phase in the upper arm of the MZ interferometer.
phi_b (float | Sequence[float] | Parameter) – The phase in the lower arm or external of the MZ interferometer.
internal (bool) – Whether phases are both in the internal arms.
name (str | None) – A name for the gate. If not provided, the class name will be used.
Operation¶
- class mrmustard.lab.transformations.Operation(ansatz_factory=None, wires=None, name=None)[source]¶
Bases:
TransformationA CircuitComponent with input and output wires on the ket side. Operation are allowed to have a different number of input and output wires.
- Parameters:
ansatz_factory (AnsatzFactory | None)
wires (Wires | None)
name (str | None)
- classmethod from_ansatz(modes_out, modes_in, ansatz=None, name=None)[source]¶
Initializes a transformation of type
clsgiven modes and an ansatz.- Parameters:
modes_out (Sequence[int]) – The output modes of this transformation.
modes_in (Sequence[int]) – The input modes of this transformation.
ansatz (PolyExpAnsatz | ArrayAnsatz | None) – The ansatz of this transformation.
name (str | None) – The name of this transformation.
- Returns:
A transformation.
- Return type:
PhaseNoise¶
- class mrmustard.lab.transformations.PhaseNoise(mode, phase_stdev=0.0, name=None)[source]¶
Bases:
ChannelThe Phase noise channel.
This class represents the application of a random phase. The distributiuon of the phase is assumed to be a Gaussian with mean zero, and standard deviation phase_stdev.
>>> from mrmustard.lab import PhaseNoise, Coherent, DM >>> phase_noise = PhaseNoise(0, phase_stdev=0.5) >>> assert isinstance(Coherent(0, 1) >> phase_noise, DM)
- Parameters:
mode (int | tuple[int]) – The mode the channel is applied to.
phase_stdev (float | Parameter) – The standard deviation of the random phase noise.
name (str | None) – A name for the channel. If not provided, the class name will be used.
Details and Conventions
The Fock representation is connected to the Fourier coefficients of the distribution.
Pgate¶
- class mrmustard.lab.transformations.Pgate(mode, shearing=0.0, name=None)[source]¶
Bases:
UnitaryQuadratic phase gate.
- Parameters:
modes – The modes this gate is applied to.
shearing (float | Sequence[float] | Parameter) – The shearing parameter.
name (str | None) – A name for the gate. If not provided, the class name will be used.
mode (int | tuple[int])
Details and Conventions
The quadratic phase gate is defined as
\[P = \exp(i s q^2 / 2 \hbar)\]Reference: https://strawberryfields.ai/photonics/conventions/gates.html
RealInterferometer¶
- class mrmustard.lab.transformations.RealInterferometer(modes, orthogonal, name=None)[source]¶
Bases:
UnitaryN-mode interferometer parametrized by an NxN orthogonal matrix (or 2N x 2N block-diagonal orthogonal matrix). Does not mix q’s and p’s.
>>> from mrmustard import math >>> from mrmustard.lab import RealInterferometer, Identity >>> ri = RealInterferometer([0, 1], orthogonal = math.eye(2)) >>> assert ri == Identity((0,1))
- Parameters:
modes (int | tuple[int, ...]) – The modes this gate is applied to.
orthogonal (RealMatrix | Parameter) – A real unitary (orthogonal) matrix. For N modes it must have shape (N,N).
name (str | None) – A name for the gate. If not provided, the class name will be used.
- classmethod random(modes, seed=None, name=None)[source]¶
Returns a random RealInterferometer.
- Parameters:
modes (int | tuple[int, ...]) – The modes of the RealInterferometer.
seed (int | None) – The random seed. If
None, the global seed is used.name (str | None) – A name for the gate. If not provided, the class name will be used.
- Returns:
The random RealInterferometer.
- Raises:
ValueError – if
modesis an empty tuple.- Return type:
Rgate¶
- class mrmustard.lab.transformations.Rgate(mode, theta=0.0, name=None)[source]¶
Bases:
UnitaryThe rotation gate.
>>> from mrmustard.lab import Rgate >>> unitary = Rgate(mode=1, theta=0.1) >>> assert unitary.modes == (1,)
- Parameters:
mode (int | tuple[int]) – The mode this gate is applied to.
theta (float | Sequence[float] | Parameter) – The rotation angle.
name (str | None) – A name for the gate. If not provided, the class name will be used.
S2gate¶
- class mrmustard.lab.transformations.S2gate(modes, r=0.0, phi=0.0, name=None)[source]¶
Bases:
UnitaryThe two-mode squeezing gate.
>>> from mrmustard.lab import S2gate >>> unitary = S2gate(modes=(1, 2), r=1) >>> assert unitary.modes == (1, 2) >>> assert unitary.parameters.r.value == 1 >>> assert unitary.parameters.phi.value == 0.0
- Parameters:
Details and Conventions
Its
(A,b,c)triple is given by\[\begin{split}A = \begin{bmatrix} O & e^{i\phi}\tanh(r) & \sech(r) & 0 \\ e^{i\phi}\tanh(r) & 0 & 0 & \sech(r) \\ \sech(r) & & 0 & 0 -e^{i\phi}\tanh(r) \\ O & \sech(r) & -e^{i\phi}\tanh(r) & 0 \end{bmatrix} \text{, } b = O_{4} \text{, and } c = \sech(r)\end{split}\]
Sgate¶
- class mrmustard.lab.transformations.Sgate(mode, r=0.0, phi=0.0, name=None)[source]¶
Bases:
UnitaryThe squeezing gate.
>>> from mrmustard.lab import Sgate >>> unitary = Sgate(mode=1, r=0.1, phi=0.2) >>> assert unitary.modes == (1,) >>> assert unitary.parameters.r.value == 0.1 >>> assert unitary.parameters.phi.value == 0.2
- Parameters:
Details and Conventions
For any \(\bar{r}\) and \(\bar{\phi}\) of length \(N\), the \(N\)-mode squeezing gate is defined by
\[\begin{split}S = \begin{bmatrix} \text{diag}_N(\text{cosh}(\bar{r})) & \text{diag}_N(e^{-i\bar{\phi}}\text{sinh}(\bar{r}))\\ -\text{diag}_N(e^{i\bar{\phi}}\text{sinh}(\bar{r})) & \text{diag}_N(\text{cosh}(\bar{r})) \end{bmatrix} \text{ and } d = O_{2N},\end{split}\]where \(\text{diag}_N(\bar{a})\) is the \(N\text{x}N\) matrix with diagonal \(\bar{a}\). Its
(A,b,c)triple is given by\[\begin{split}A &= \begin{bmatrix} -\text{diag}_N(e^{i\bar{\phi}}\text{tanh}(\bar{r})) & \text{diag}_N(\text{sech}(\bar{r}))\\ \text{diag}_N(\text{sech}(\bar{r})) & \text{diag}_N(e^{-i\bar{\phi}}\text{tanh}(\bar{r})) \end{bmatrix} \\ \\ b &= O_{2N} \\ \\ c &= \prod_{i=1}^N\sqrt{\text{sech}{\:r_i}}\:.\end{split}\]
Transformation¶
- class mrmustard.lab.transformations.Transformation(ansatz_factory=None, wires=None, name=None)[source]¶
Bases:
CircuitComponentBase class for all transformations.
- Parameters:
ansatz_factory (AnsatzFactory | None)
wires (Wires | None)
name (str | None)
- abstract classmethod from_ansatz(modes_out, modes_in, ansatz=None, name=None)[source]¶
Initializes a transformation of type
clsgiven modes and an ansatz.- Parameters:
modes_out (Sequence[int]) – The output modes of this transformation.
modes_in (Sequence[int]) – The input modes of this transformation.
ansatz (PolyExpAnsatz | ArrayAnsatz | None) – The ansatz of this transformation.
name (str | None) – The name of this transformation.
- Returns:
A transformation.
- Return type:
Self
- classmethod from_bargmann(modes_out, modes_in, triple, name=None)[source]¶
Initialize a Transformation from the given Bargmann triple (A,b,c) which parametrizes the Bargmann function of the transformation as \(c * exp(0.5*z^T A z + b^T z)\).
- Parameters:
modes_out (Sequence[int])
modes_in (Sequence[int])
triple (tuple)
name (str | None)
- Return type:
Self
- classmethod from_fock(modes_out, modes_in, array, batch_dims=0, name=None)[source]¶
Initializes a transformation of type
clsgiven modes and a fock array.- Parameters:
modes_out (Sequence[int]) – The output modes of this transformation.
modes_in (Sequence[int]) – The input modes of this transformation.
array (ComplexTensor) – The fock array of this transformation.
batch_dims (int) – The number of batch dimensions in the given array.
name (str | None) – The name of this transformation.
- Returns:
A transformation in the Fock representation.
- Return type:
Self
- classmethod from_quadrature(modes_out, modes_in, triple, phi=0, name=None)[source]¶
Initialize a Transformation from the given quadrature triple (A, b, c). The triple parametrizes the quadrature representation of the transformation as \(c * exp(0.5*x^T A x + b^T x)\).
- Parameters:
modes_out (Sequence[int])
modes_in (Sequence[int])
triple (tuple)
phi (float)
name (str | None)
- Return type:
Self
- inverse()[source]¶
Returns the mathematical inverse of the transformation, if it exists. Note that it can be unphysical, for example when the original is not unitary.
>>> from mrmustard.lab import GaussianDM, Identity, Operation >>> rho = GaussianDM.random(modes=0, seed=1) >>> rho_as_operator = Operation.from_bargmann([0], [0], rho.ansatz.triple) >>> assert rho_as_operator >> rho_as_operator.inverse() == Identity([0])
- Returns:
The inverse of the transformation.
- Raises:
NotImplementedError – If the input and output wires have different lengths.
NotImplementedError – If the transformation is not in the Bargmann representation.
- Return type:
Unitary¶
- class mrmustard.lab.transformations.Unitary(ansatz_factory=None, wires=None, name=None)[source]¶
Bases:
OperationBase class for all unitary transformations.
- Parameters:
ansatz_factory (AnsatzFactory | None)
wires (Wires | None)
name (str | None)
- property symplectic¶
Returns the symplectic matrix that corresponds to this unitary.
- classmethod from_ansatz(modes_out, modes_in, ansatz=None, name=None)[source]¶
Initializes a transformation of type
clsgiven modes and an ansatz.- Parameters:
modes_out (Sequence[int]) – The output modes of this transformation.
modes_in (Sequence[int]) – The input modes of this transformation.
ansatz (PolyExpAnsatz | ArrayAnsatz | None) – The ansatz of this transformation.
name (str | None) – The name of this transformation.
- Returns:
A transformation.
- Return type:
- classmethod from_symplectic(modes, S, name=None)[source]¶
A method for constructing a
Unitaryfrom its symplectic representation.>>> from mrmustard import math >>> from mrmustard.lab import Unitary, Identity >>> S = math.eye(2) >>> U = Unitary.from_symplectic([0], S) >>> assert U == Identity([0])
- Parameters:
modes (Sequence[int]) – the modes that we want the unitary to act on (should be a list of int)
S (RealMatrix) – the symplectic representation (in XXPP order)
name (str | None) – A name for the unitary. If not provided, the class name will be used.
- Return type:
- classmethod random(modes, max_r=1.0, seed=None, name=None)[source]¶
Returns a random unitary.
>>> from mrmustard.lab import Unitary >>> U = Unitary.random((0, 1, 2), max_r=1.2) >>> assert U.modes == (0,1,2)
- Parameters:
modes (int | tuple[int, ...]) – The modes of the unitary.
max_r (float) – The maximum squeezing parameter.
seed (int | None) – The random seed. If
None, the global seed is used.name (str | None) – A name for the unitary. If not provided, the class name will be used.
- Returns:
The random Unitary.
- Raises:
ValueError – if
modesis an empty tuple.- Return type: