ModeRotation¶
- class ModeRotation(rotation_unitary, *, synthesis=None)¶
Bases:
BosonicGateImplements a passive linear-optical mode transformation.
Given an \(M \times M\) unitary matrix \(U\) (
rotation_unitary), this gate implements the basis change that maps the creation operators as\[b^\dagger_i \mapsto \sum_j U_{ji} \, b^\dagger_j \, ,\]equivalently the many-body unitary
\[\exp\left(\sum_{ij} \log(U)_{ij} \, b^\dagger_i b_j\right) \, .\]The number of bosonic modes the gate acts on is the dimension \(M\) of
rotation_unitary.Action on the occupation sectors
Restricted to the single-particle sector, the gate is the \(M \times M\) matrix \(U\) itself. It acts on every occupation sector at once, however: the two-particle block is the symmetric square of \(U\) (carrying the \(\sqrt{2}\) factors), and so on up to the truncation.
Synthesis
Breaking this gate down in bosonic space (into a circuit of smaller
Evolutiongates) is what thesynthesisattribute governs. It isNoneby default, which leaves the gate whole: there is no preferred decomposition, and a method such asBosonicClementsDecompositionis chosen explicitly, either here or for a whole circuit with theB2BSynthesistranspiler pass. The circuit it produces implements the same unitary as the gate (on the untruncated Fock space), and it is the definition of the gate.A gate that is left whole reaches the boson-to-qubit stage, which needs a plugin registered for
ModeRotationto lower it. The library ships none, because the transpiler preset decomposes the gate in bosonic space first. A plugin that maps the generator ofto_operator()directly is a few lines long; see Lower a rotation without decomposing it. The two-modebeamsplitter()follows the convention of Clements et al. [1]Warning
Because this gate mixes occupation sectors within a mode, a truncation that merely bounds the initial per-mode occupation is not sufficient. Acting on \(\lvert 1, 1 \rangle\), a two-mode rotation populates \(\lvert 2, 0 \rangle\), so a cutoff of
max_occupation=1silently produces a wrong state. The cutoff must bound the total boson number reachable in any single mode. This matters most when the modes have different cutoffs: a rotation moves bosons between modes, so each mode that can receive them needs a cutoff that covers what it can receive, not only what it starts with.This gate is passive: it conserves the total boson number (it is generated by number-conserving \(b^\dagger_i b_j\) terms). The active Gaussian operations – squeezing and displacement – do not conserve boson number and are not expressible as a
ModeRotation.Initializing an instance of this gate can be done with the arguments listed below.
- Parameters:
rotation_unitary (np.ndarray) – the \(M \times M\) unitary matrix \(U\) defining the mode transformation via \(b^\dagger_i \mapsto \sum_j U_{ji} b^\dagger_j\). It must be square and unitary; this is the caller’s responsibility and is not verified.
synthesis (B2BSynthesisPlugin | None) – the boson-to-boson synthesis method with which to decompose this gate, when it gets decomposed at all. If
None(the default), the gate has no bosonic decomposition anddecompose()leaves it in place.
Attributes
- rotation_unitary¶
The unitary matrix representing the mode-transformation coefficients.
Methods
- classmethod beamsplitter(theta, phi=0.0)¶
Constructs the two-mode beamsplitter.
Following the Clements convention, [1] the two-mode transfer matrix is
\[T(\theta, \phi) = \begin{pmatrix} e^{i\phi}\cos\theta & -\sin\theta \\ e^{i\phi}\sin\theta & \cos\theta \end{pmatrix} \, ,\]which together with the single-mode phase shifts generates any \(U(M)\) when arranged in the Clements mesh.
- Parameters:
- Returns:
A two-mode
ModeRotation.- Return type:
- classmethod from_generator(generator)¶
Constructs the rotation from an anti-Hermitian generator.
Returns the gate whose
rotation_unitaryis \(\exp(K)\) for the given \(K\). For the result to be unitary, \(K\) must be anti-Hermitian (\(K^\dagger = -K\)); this is the caller’s responsibility and is not verified.- Parameters:
generator (ndarray) – the \(M \times M\) anti-Hermitian generator \(K\).
- Returns:
A
ModeRotationwithrotation_unitary\(= \exp(K)\).- Return type:
- generator()¶
Returns the anti-Hermitian generator \(\log(U)\) of this rotation.
This is the matrix \(K\) such that the many-body unitary is \(\exp(\sum_{ij} K_{ij} b^\dagger_i b_j)\), which is what a synthesis plugin exponentiates.
- Return type:
- inverse(annotated=False)¶
Returns the inverse of this gate, whose rotation unitary is \(U^\dagger\).
- Parameters:
annotated (bool) – ignored. The inverse of this gate is another
ModeRotation, so it never needs to be anAnnotatedOperation.- Returns:
A
ModeRotationwith the same synthesis method.- Return type:
- classmethod phase_shift(phases)¶
Constructs a product of single-mode phase shifts.
Each mode \(m\) acquires \(b^\dagger_m \mapsto e^{i \varphi_m} b^\dagger_m\), that is, the rotation unitary is \(\mathrm{diag}(e^{i\varphi_0}, \ldots)\).
- Parameters:
phases (Sequence[float]) – the phase \(\varphi_m\) applied to each mode.
- Returns:
A
ModeRotationthat is diagonal in the mode basis.- Return type:
- to_operator(tol=1e-12)¶
Returns the Hermitian generator of this gate as a
BosonOperator.Builds \(H = \sum_{ij} \mathrm{i} \log(U)_{ij} \, b^\dagger_i b_j\), the Hermitian operator for which \(e^{-\mathrm{i} H}\) is this gate. That is exactly the form of an
Evolutiongate at unit time, which makes this the bridge from the gate’s matrix form to the operator algebra, and hence to any boson-to-qubit encoding.The matrix logarithm of a unitary is anti-Hermitian only up to round-off, so the result is built from the anti-Hermitian part of \(\log(U)\) and is exactly Hermitian, as a
PauliEvolutionGaterequires of the mapped operator.- Parameters:
tol (float) – entries of \(H\) with magnitude at or below this are dropped.
logmof a sparse or block-diagonal unitary leaves round-off in nominally-zero entries; keeping them would bloat the operator with meaningless terms.- Returns:
The Hermitian generator as a
BosonOperator.