Reference
This package contains two main parts.
- The definition of a matrix-product state type to represent mixed states as pure states in an enlarged Hilbert space, through a purification technique called superboson formalism, described in Superboson matrix-product states. The package offers functions to manage these objects and extract physical information from them, as well as methods that implement many Gaussian operations on states in this representation (see Gaussian states and operations).
- The implementation of the algorithm in [1] that simulates the outcome of a Gaussian boson-sampling experiment, given the covariance matrix of the output state of the lossy apparatus. The methods pertaining to this part are explained in Gaussian boson-sampling output simulation.
Superboson matrix-product states
This package implements the superboson formalism [4] in a many-body bosonic Fock space, which is a purification method with which $N$-mode mixed states can be represented as pure states in a $2N$-mode bosonic Fock space. To each original, physical mode we associate an artificial ancillary mode in the enlarged space, and in the end we recover physical information by tracing away the ancillary degrees of freedom.
In order to work with this representation, we introduce a new type, called SuperBosonMPS, which is essentially an ordinary MPS from ITensors with some additional decoration and dedicated functions. This type is a subtype of AbstractMPS, so most of the methods already defined by ITensors to work on MPSs (such as expect, sample, and so on) can be seamlessly called on SuperBosonMPS objects, too.
Constructors
GaussianBosonSamplingMPS.SuperBosonMPS — Type
SuperBosonMPSA finite-size matrix-product state type that represents mixed states in the superboson formalism [4].
References
- [4] Schmutz, M. Z Physik B 30, 97–106 (1978)
Utility functions
To make working with a superboson space easier, this library provides the following utilities.
GaussianStates.nmodes — Function
nmodes(v::SuperBosonMPS)Return the number of "true" bosonic modes contained in the SuperBosonMPS v, i.e. half its actual length.
GaussianBosonSamplingMPS.enlargelocaldim — Function
enlargelocaldim(v::AbstractMPS, newdim)Return a new MPS with the local dimension increased to newdim.
Note that the new MPS will be defined on a new set of site indices, so it will be incompatible with the original one.
GaussianBosonSamplingMPS.sb_siteinds — Function
sb_siteinds(; nmodes, maxnumber)Return a list of ITensor site indices suited to define a superbosonic state, with alternating "physical" and "ancillary" sites.
Keyword arguments (mandatory)
nmodes: the number of "real-world" bosonic modes of the system (the actual MPS will have2nmodessites).maxnumber: maximum number of bosons allowed on each site. The local Hilbert spaces will be truncated to a dimension ofmaxnumber+1.
Example
julia> sb_siteinds(; nmodes=2, maxnumber=4)
4-element Vector{Index{Int64}}:
(dim=5|id=962|"Boson,Site,n=1,phy")
(dim=5|id=41|"Boson,Site,anc,n=1")
(dim=5|id=794|"Boson,Site,n=2,phy")
(dim=5|id=198|"Boson,Site,anc,n=2")GaussianBosonSamplingMPS.sb_outer — Function
sb_outer(ψ::MPS)Compute the projection operator $|ψ⟩⟨ψ| / ‖ψ‖²$, from the MPS ψ representing a pure state, returning a SuperBosonMPS object (of double the size).
Expectation values and sampling
To extract physical information from a SuperBosonMPS object, you can use the expect, correlation_matrix and sample functions, which work exactly as in the ITensorMPS library.
ITensorMPS.expect — Function
expect(v::SuperBosonMPS, op::AbstractString...; kwargs...)
expect(v::SuperBosonMPS, op::Matrix{<:Number}...; kwargs...)
expect(v::SuperBosonMPS, ops; kwargs...)Given a superbosonic MPS v and a single operator name or matrix, returns a vector of the expected value of the operator on each site of the SuperBosonMPS.
If multiple operator names are provided, returns a tuple of expectation value vectors.
If a container of operator names is provided, returns the same type of container with names replaced by vectors of expectation values.
Optional keyword arguments
sites = 1:nmodes(v): compute expected values only for modes in the given range
Examples
N = 10
s = sb_siteinds("Boson", N)
v = sb_outer(random_mps(s; linkdims=4))
expect(v, "N") # compute for all sites
expect(v, "N"; sites=2:4) # compute for sites 2, 3 and 4
expect(v, "N"; sites=3) # compute for site 3 only (output will be a scalar)
expect(v, ["A*Adag", "N"]) # compute A*Adag and N for all sites
expect(v, [0 0; 0 1]) # same as expect(v, "N") if maxnumber == 1ITensorMPS.correlation_matrix — Function
correlation_matrix(
v::SuperBosonMPS, A::AbstractString, B::AbstractString; kwargs...
)
correlation_matrix(
v::SuperBosonMPS, A::Matrix{<:Number}, B::Matrix{<:Number}; kwargs...
)Given a SuperBosonMPS v representing a state $ρ$ and two strings or matrices A and B denoting operators (as recognized by the op function), computes the two-point correlation function matrix $C_{ij} = \textrm{tr}(A_i B_j ρ)$ using efficient MPS techniques. Returns the matrix C.
Optional keyword arguments
sites = 1:nmodes(v): compute correlations only for sites in the given rangeishermitian = false: iffalse, force independent calculations of the matrix elements above and below the diagonal, while iftrueassume they are complex conjugates.
Examples
julia> s = siteinds("Boson", 3; dim=4);
julia> vac = sb_outer(MPS(ComplexF64, s, "0"));
julia> correlation_matrix(vac, "x", "x")
3×3 Matrix{ComplexF64}:
0.5+0.0im 0.0+0.0im 0.0+0.0im
0.0-0.0im 0.5+0.0im 0.0+0.0im
0.0-0.0im 0.0-0.0im 0.5+0.0im
julia> correlation_matrix(vac, "p", "x")
3×3 Matrix{ComplexF64}:
0.0-0.5im 0.0+0.0im 0.0+0.0im
0.0+0.0im 0.0-0.5im 0.0+0.0im
0.0+0.0im 0.0+0.0im 0.0-0.5imITensorMPS.sample — Function
sample(m::SuperBosonMPS)Given a "superbosonic" MPS m with unit trace, compute a Vector{Int} of nmodes(m) elements corresponding to one sample of the probability distribution defined by the components of the density matrix that the MPS represents.
Gaussian states and operations
This package works in tandem with the GaussianStates package, extending some of its methods to define them on matrix-product states (both ordinary and superbosonic ones).
First and second moments
GaussianStates.firstmoments — Function
firstmoments(v::Union{MPS,SuperBosonMPS}; warn_atol=1e-14)Compute the first moments of the state represented by v (either a pure state, if v is an MPS, or a mixed one, if v is a SuperBosonMPS), displayed in the xpxp order, i.e. the vector $(⟨x_1⟩, ⟨p_1⟩, ⟨x_2⟩, ⟨p_2⟩, ..., ⟨x_N⟩, ⟨p_N⟩)$.
The warn_atol keyword argument can be used to adjust the threshold used by the function to warn when the computed moments are not real. The imaginary part of the result is always truncated.
GaussianStates.covariancematrix — Function
covariancematrix(v::Union{MPS,SuperBosonMPS}; warn_atol=1e-14)Compute the covariance matrix of the state represented by v (either a pure state, if v is an MPS, or a mixed one, if v is a SuperBosonMPS), displayed in the xpxp order.
The warn_atol keyword argument can be used to adjust the threshold used by the function to warn when the computed moments are not real. The imaginary part of the result is always truncated.
Gaussian operations
The following methods can be applied to an MPS in order to simulate quantum optical operations. The matrix elements of the squeezing operator are taken from [5].
The operators are defined through their exact coefficients in the infinite-dimensional case, that is, they are the truncated version of the “true” physical operators. As such, they are not unitary, and care must be taken so that the finite-dimensional Hilbert space is large enough to contain the dynamics.
GaussianBosonSamplingMPS.attenuate — Function
attenuate(v::SuperBosonMPS, attenuation, n)Apply the attenuator channel $ρ ↦ \sum_{k=0}^{+∞} B_k ρ \adj{B_k}$ to the n-th mode of the state $ρ$ represented by the SuperBosonMPS v, where
\[B_k = \sum_{m=0}^{+∞} \binom{m+k}{k}^{\frac12} (1-η^2)^{\frac{k}{2}} η^m |m⟩⟨m+k|\]
and $η$ is the attenuation coefficient, such that $\sum_{k=0}^{+\infty} B_k ρ \adj{B_k}$ is equal to $|0⟩⟨0|$ when $η = 0$ and to $ρ$ when $η = 1$.
GaussianStates.displace — Function
displace(v::Union{MPS,SuperBosonMPS}, α, n; kwargs...)Apply the displacement operator
\[D(α) = \exp(α \adj{a} - \conj{α} a)\]
with $α ∈ ℂ$, to the n-th mode of the state represented by v.
displace(v::Union{MPS,SuperBosonMPS}, α; kwargs...)Apply the displacement operator
\[⨂_{i=1}^{n} D(α_i), \quad D(α) = \exp(α \adj{a} - \conj{α} a)\]
with $α_i ∈ ℂ$, to all modes of the state represented by v.
GaussianStates.squeeze — Function
squeeze(v::Union{MPS,SuperBosonMPS}, z, n; kwargs...)Apply the squeezing operator
\[S(z) = \exp\bigl(\tfrac12 z (\adj{a})^2 - \tfrac12 \conj{z} a^2\bigr)\]
with $z ∈ ℂ$, to the n-th mode of the state represented by v.
squeeze(v::Union{MPS,SuperBosonMPS}, z; kwargs...)Apply the squeezing operator
\[⨂_{i=1}^{n} S(z_i), \quad S(z) = \exp\bigl(\tfrac12 z (\adj{a})^2 - \tfrac12 \conj{z} a^2\bigr),\]
with $z_i ∈ ℂ$, to all modes of the state represented by v.
GaussianStates.squeeze2 — Function
squeeze2(v::Union{MPS,SuperBosonMPS}, z, n1, n2; kwargs...)Apply the two-mode squeezing operator
\[S₂(z) = \exp(z \adj{a} ⊗ \adj{a} - \conj{z} a ⊗ a)\]
with $z ∈ ℂ$, on modes n1 and n2 of the state represented by v.
GaussianStates.beamsplitter — Function
beamsplitter(v::Union{MPS,SuperBosonMPS}, z, n1, n2; kwargs...)Apply the beam-splitter operator
\[B(z) = \exp(z \adj{a} ⊗ a - \conj{z} a ⊗ \adj{a})\]
with $z ∈ ℂ$, to modes n1 and n2 of the state represented by v.
Gaussian boson-sampling output simulation
Here lies the heart of this package: the following methods implement the algorithms in [1] and [2] in order to be able to simulate a Gaussian boson sampling experiment with matrix-product states.
The main functions are the following.
optimiseuses semi-definite programming, through the JuMP and SCS libraries, to decompose the covariance matrix of a Gaussian state into a sum of- a pure covariance matrix which "contains" a smaller amount of photons,
- a positive semi-definite matrix
MPScomputes a matrix-product state that approximates a pure Gaussian state following the algorithm presented in [1], by using the Franck-Condon formula from [2].sample_displacedsamples from a state after the application of a random displacement channel.
See Borealis experiment for a tutorial on how to use these methods.
GaussianBosonSamplingMPS.normal_mode_decomposition — Function
normal_mode_decomposition(g::GaussianState, N, maxnumber; kwargs...)Compute the normal-mode decomposition [6, Eq. (3.60) at page 47] of the Gaussian state g up to the N largest eigenvalues, calculated by considering only the k-particle sectors for k ≤ maxnumber on each mode. Return vals, nums, S where vals contains the eigenvalues in decreasing order, nums contains the occupation numbers of the Fock basis vector associated to the corresponding value in vals, and S is the symplectic matrix from the Williamson decomposition of g.
The output satisfies the following identities:
julia> D, S = williamson(Symmetric(covariancematrix(g)));
julia> d = diag(D)[1:2:end];
julia> normalmode_evs, nums, S' = normal_mode_decomposition(g, N, maxnumber);
julia> all(
val == prod(normal_mode_eigenvalue(d[j], m[j]) for j in eachindex(m)) for
(val, m) in zip(normalmode_evs, nums)
)
true
julia> S == S'
trueReferences
- [6] Serafini, A. (2023)
GaussianBosonSamplingMPS.franckcondon — Function
franckcondon(m, α, Wₗ, S, Wᵣ, n)
franckcondon(m, Wₗ, S, Wᵣ, n)Compute the matrix element $⟨m| D(α) U(W_l) U(S) U(W_r) |n⟩$ according to the algorithm presented in Ref. [2]. Wₗ, S and Wᵣ are symplectic matrices, in particular Wₗ and Wᵣ are also orthogonal, and α is a complex vector (which defaults to the zero vector). If $N$ is the number of modes of the system, then
mandnare tuples of $N$ natural numbers,αis a vector of $N$ complex numbers,Wₗ,SandWᵣare $2N × 2N$ matrices.
References
- [2] Quesada, N. J Chem Phys 150.16 (2019)
ITensorMPS.MPS — Type
MPS(g::GaussianState; maxdim, maxnumber, kwargs...)Build an MPS representation of the Gaussian state g with bond dimension up to maxdim, truncating the Fock space of each mode at the maxnumber-particle sector.
GaussianBosonSamplingMPS.optimise — Function
optimise(g::GaussianState; verbose=false, scs_eps=nothing)Return gₚ, W where gₚ is a new Gaussian state and W is a positive semi-definite matrix such that W + covariancematrix(gₚ) == covariancematrix(g) and gₚ contains a smaller number of photons.
Set verbose = true to print the information provided by SCS about the optimisation.
GaussianBosonSamplingMPS.sample_displaced — Function
sample_displaced(ψ::MPS, W; nsamples, nsamples_per_displacement, eval_atol=0, kwargs...)Apply random displacements sampled from the positive semi-definite matrix W to the pure state ψ and sample nsamples elements from the resulting state.
Return s, αs such that:
sis a matrix ofUInt8elements such that each column is a sample drawn from the final state, with a new displacement vector for eachnsamples_per_displacementdraws. (The matrix will actually have a number of columns equal tonsamples_per_displacement * floor(nsamples / nsamples_per_displacement).)αsis a matrix whose columns are the displacement vectors drawn fromW, such thatαs[:, k]is used for the samples from(k-1)NtokN, withN = floor(nsamples / nsamples_per_displacement).
The eval_atol keyword argument is used as threshold to decide whether an eigenvalue of W must be considered zero (usually it should be of the same order of the eps tolerances of the SCS optimiser).