Matrix product states
Matrix product states are an ansatz for describing and estimating states of one-dimensional systems. In this package, MPS can be used for a variety of applications, e.g., ground state estimation, simulating dynamics, and quantum circuit calculations.
Matrix product states (MPS)
Initiating an MPS
There are many ways to create an MPS, and the method will depend on the problem at hand.
Random states
For variational problems, we sometimes recommend initiating an MPS randomly using ψ = randommps(dim, length, bonddim), where dim is the physical dimension of the lattice, length is the number of sites in the lattice, and bonddim is the bond dimension of the MPS.
TeNe.randommps — Functionrandommps(dim::Int, length::Int, bonddim::Int)Create an MPS with dimensions dim, size length and bond dimension bonddim, with random tensors.
Optional Keyword Arguments
- `T::Type=ComplexF64`: The element type for the tensors.Product states
An alternative option is to initalise the MPS is a state with known desirable properties. This can be done in a few ways. The simplest way is to just provide a translationally invariant tensor A for the MPS (with bond dimension one), ψ = productmps(N, A).
TeNe.productmps — Methodproductmps(N::Int, A<:AbstractArray; kwargs...)Create a product MPS of size N, composed of array A. A can be a vector or rank-3 tensor.
Optional Keyword Arguments
- `T::Type=ComplexF64`: The element type for the tensors.
- `normalise::Bool=false`: Normalise the MPS after creating it?Alternatively, we can use the LatticeTypes interface to write a product state.
TeNe.productmps — Methodproductmps(lt::LatticeTypes, states::AbstractVector{String})Create an MPS from a string of states.
Example
julia> lt = Qubits();
julia> ψ = productmps(lt, ["up" for _ = 1:20]);From StateVectors
If you need to write an MPS using some known StateVector, you can call MPS(ψ::StateVector).
TeNe.MPS — MethodMPS(ψ::StateVector; kwargs...)Write a StateVector as a MPS.
Optional Keyword Arguments
- `cutoff::Float64=0.0`: Truncation criteria to reduce the bond dimension.
Good values range from 1e-8 to 1e-14.
- `mindim::Int=1`: Minimum dimension for the truncation.
- `maxdim::Int=0`: Maximum bond dimension for truncation. Set to 0 to have
no limit.Examples
julia> ψ = randomsv(2, 10);
julia> ψ = MPS(ψ; cutoff=1e-12);Properties of an MPS
LinearAlgebra.rank — Methodrank(::GStateTensor)Returns the rank of a state tensor.
rank(::GMPS)Returns the rank of an MPS object.
TeNe.dim — Methoddim(ψ::GMPS, [which::Int, site::Int])The size of the physical dimensions in a GMPS. Returns 0 for heterogeneous systems (i.e. an invariant physical dimension). The axis and the lattice site can also be specified.
TeNe.center — Methodcenter(::GMPS)The orthogonal center of an MPS. Returns 0 if nothing is set.
TeNe.bonddim — Methodbonddim(::GMPS, idx::Int)Return the bond dimension size between idx and idx + 1. Returns nothing if out of range.
TeNe.maxbonddim — Methodmaxbonddim(::GMPS)Calculate the maximum bond dimension within an GMPS.
LinearAlgebra.norm — Methodnorm(ψ::GMPS)Calculate the norm of an GMPS.
TeNe.entropy — Methodentropy(ψ::MPS, site::Int)Calculate the entanglement entropy of an MPS ψ between sites i and i+1.
Manipulations of an MPS
Normalization
LinearAlgebra.normalize! — Methodnormalize!(ψ::GMPS)Normalize a GMPS.
Canonical center
An important property of MPS is that they can be brought into a canonical representation, allowing for better conditioned calculations and simplifications in many MPS algorithms. The canonical center of an MPS ψ is easily moved to idx using movecenter!(ψ, idx). This also allows for dynamic truncation of the MPS, using keyword arguments such as maxdim or cutoff.
TeNe.movecenter! — Methodmovecenter!(ψ::GMPS, idx::Int; kwargs...)Move the orthogonal center of an GMPS ψ to idx.
Optional Keyword Arguments
- `cutoff::Float64=0.0`: Truncation criteria to reduce the bond dimension.
Good values range from 1e-8 to 1e-14.
- `mindim::Int=1`: Minimum dimension for the truncation.
- `maxdim::Int=0`: Maximum bond dimension for truncation. Set to 0 to have
no limit.Truncations
The bond dimension of the MPS controls its accuracy. A larger bond dimension has a higher capacity for precision, but also increases the computational cost of algorithms. To reduce the bond dimension (and sacrificing as little accuracy as possible), one can truncate the MPS.
TeNe.truncate! — Methodtruncate!(ψ::GMPS; kwargs...)Truncate the bond dimension of a GMPS ψ.
Optional Keyword Arguments
- `cutoff::Float64=0.0`: Truncation criteria to reduce the bond dimension.
Good values range from 1e-8 to 1e-14.
- `mindim::Int=1`: Minimum dimension for the truncation.
- `maxdim::Int=0`: Maximum bond dimension for truncation. Set to 0 to have
no limit.Inner products
Some linear algebra operations such as the inner product are easy to calculate for MPS.
TeNe.inner — Methodinner(ψ::MPS, ϕ::MPS)
dot(ψ::MPS, ϕ::MPS)
*(ψ::MPS, ϕ::MPS)Calculate the inner product of two MPSs ψ and ϕ.
Examples
julia> ψ = productmps(10, [1, 1]);
julia> ϕ = productmps(10, [1, 0]);
julia> ϕ * ψ
1Sampling an MPS
By considering an MPS to be a wavefunction from quantum mechanics (we sometimes call this a Born machine in a classical context), we are able to sample it exactly.
TeNe.sample — Methodsample(ψ::MPS)Sample the MPS ψ with the interpretation that it is a wavefunction (or Born ansatz).
Matrix product operators (MPO)
Just as a wavefunction, or state vector, can be represented as an MPS, an operator can be represented by a matrix product operator.
Initiating an MPO
Like the MPS, an MPO can be initiated randomly or as a product operator. It can also be initiated from some StateOperator.
TeNe.randommpo — Functionrandommpo(dim::Int, length::Int, bonddim::Int; kwargs...)Create an MPO with dimensions dim, size length and bond dimension bonddim, with random tensors.
Optional Keyword Arguments
- `T::Type=ComplexF64`: The element type for the tensors.TeNe.productmpo — Methodproductmpo(N::Int, A::AbstractArray; kwargs...)Create a product MPO of size N, composed of array A. A can be a matrix or rank-4 tensor.
Optional Keyword Arguments
- `T::Type=ComplexF64`: The element type for the tensors.TeNe.MPO — MethodMPO(O::StateOperator; kwargs...)Write a StateOperator as a MPO.
Optional Keyword Arguments
- `cutoff::Float64=0.0`: Truncation criteria to reduce the bond dimension.
Good values range from 1e-8 to 1e-14.
- `mindim::Int=1`: Minimum dimension for the truncation.
- `maxdim::Int=0`: Maximum bond dimension for truncation. Set to 0 to have
no limit.Examples
julia> ψ = randomsv(2, 10);
julia> ψ = MPS(ψ; cutoff=1e-12);Alternatively, we can use the LatticeTypes interface to write an operator.
TeNe.productmpo — Methodproductmpo(lt::LatticeTypes, ops::AbstractVector{String})Create an MPO from a string of operators.
Example
julia> lt = Qubits();
julia> O = productmpo(lt, ["x" for _ = 1:20]);Construct an MPO from an operator list
A more powerful option is to write an operator as an OpList, and then use the MPO(::OpList) function to automatically find an exact MPO representation.
TeNe.MPO — MethodMPO(H::OpList; kwargs...)Create an exact MPO representation from an OpList.
Optional Keyword Arguments
- `cutoff::Float64=1.0e-12`: Truncation criteria to reduce the bond dimension.
Good values range from 1e-8 to 1e-14.
- `mindim::Int=1`: Minimum dimension for the truncation.
- `maxdim::Int=0`: Maximum bond dimension for truncation. Set to 0 to have
no limit.Examples
julia> lt = Qubits();
julia> H = OpList(lt, 20);
julia> for i = 1:20 add!(H, "x", i) end;
julia> for i = 1:19 add!(H, ["z", "z"], [i, i+1]) end;
julia> H = MPO(H);Products
The expectation value of a string of MPOs with respect to some MPSs can be calculated exactly. The below can be done with many MPOs.
TeNe.inner — Methodinner(ψ::MPS, O::MPO, ϕ::MPS)
inner(ψ::MPS, O1::MPO, O2::MPO, ϕ::MPS)Calculate the expectation of a string of operators Os with respect to MPSs ψ and ϕ.
Similarly, the trace of a string of MPOs can be calculated.
TeNe.trace — Methodtrace(Os::MPO...)Compute the trace of the product of many MPOs.