States
FiniteMPS
A FiniteMPS is - at its core - a chain of mps tensors.
Usage
A FiniteMPS
can be created by passing in a vector of tensormaps:
data = fill(TensorMap(rand,ComplexF64,ℂ^1*ℂ^2,ℂ^1),10);
FiniteMPS(data);
Or alternatively by
len = 10;
max_bond_dimension = ℂ^10;
physical_space = ℂ^2;
FiniteMPS(rand,ComplexF64,len,physical_space,max_bond_dimension);
You can take dot products, renormalize!, expectation values,....
Gauging
There is residual gauge freedom in such a finite mps :
which is often exploited in mps algorithms. The gauging logic is handled behind the scenes, if you call
state.AL[3]
then the state will be gauged such that the third tensor is a left isometry (similarly for state.AR).
state.AC[3]
gauges the state in such a way that all tensors to the left are left isometries, and to the right will be right isometries.As a result you should have
norm(state) == norm(state.AC[3])
lastly there is also the CR field, with the following property:
@tensor a[-1 -2;-3] := state.AL[3][-1 -2;1]*state.CR[3][1;-3]
@tensor b[-1 -2;-3] := state.CR[2][-1;1]*state.AR[3][1 -2;-3]
a ≈ state.AC[3];
b ≈ state.AC[3];
Implementation details
Behind the scenes, a finite mps has 4 fields
ALs::Vector{Union{Missing,A}}
ARs::Vector{Union{Missing,A}}
ACs::Vector{Union{Missing,A}}
CLs::Vector{Union{Missing,B}}
calling state.AC returns an "orthoview" instance, which is a very simple dummy object. When you call get/setindex on an orthoview, it will move the gauge for the underlying state, and return the result. The idea behind this construction is that one never has to worry about how the state is gauged, as this gets handled automagically.
The following bit of code shows the logic in action:
state = FiniteMPS(10,ℂ^2,ℂ^10); # a random initial state
@show ismissing.(state.ALs) # all AL fields are already calculated
@show ismissing.(state.ARs) # all AR fields are missing
#if we now query state.AC[2], it should calculate and store all AR fields left of position 2
state.AC[2];
@show ismissing.(state.ARs)
InfiniteMPS
An infinite mps can be thought of as a finite mps, where the set of tensors is repeated periodically.
It can be created by passing in a vector of tensormaps:
data = fill(TensorMap(rand,ComplexF64,ℂ^10*ℂ^2,ℂ^10),2);
InfiniteMPS(data);
The above code would create an infinite mps with an A-B structure (a 2 site unit cell).
much like a finite mps, we can again query the fields state.AL, state.AR, state.AC and state.CR. The implementation is much easier, as they are now just plain fields in the struct
AL::PeriodicArray{A,1}
AR::PeriodicArray{A,1}
CR::PeriodicArray{B,1}
AC::PeriodicArray{A,1}
The periodic array is an array-like type where all indices are repeated periodically.
WindowMPS
WindowMPS is a bit of a mix between an infinite mps and a finite mps. It represents a window of mutable tensors embedded in an infinite mps.
It can be created using:
mpco = WindowMPS(left_infinite_mps,window_of_tensors,right_infinite_mps)
Algorithms will then act on this window of tensors, while leaving the left and right infinite mps's invariant.
Behind the scenes it uses the same orthoview logic as finitemps.
Multiline
Statistical physics partition functions can be represented by an infinite tensor network which then needs to be contracted. This is done by finding approximate fixpoint infinite matrix product states. However, there is no good reason why a single mps should suffice and indeed we find in practice that this can require a nontrivial unit cell in both dimensions.
In other words, the fixpoints can be well described by a set of matrix product states.
Such a set can be created by
data = fill(TensorMap(rand,ComplexF64,ℂ^10*ℂ^2,ℂ^10),2,2);
MPSMultiline(data);
MPSMultiline is also used extensively in as of yet unreleased peps code.
You can access properties by calling
state.AL[row,collumn]
state.AC[row,collumn]
state.AR[row,collumn]
state.CR[row,collumn]
Behind the scenes, we have a type called Multiline, defined as:
struct Multiline{T}
data::PeriodicArray{T,1}
end
MPSMultiline/MPOMultiline are then defined as ```julia const MPSMultiline = Multiline{<:InfiniteMPS} const MPOMultiline = Multiline{<:DenseMPO}