From fcb8682215b120779b02541076add55de70156a3 Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Mon, 3 Mar 2025 16:07:01 +0000 Subject: [PATCH] build based on ca106c4 --- previews/PR261/.documenter-siteinfo.json | 2 +- .../classic2d/1.hard-hexagon/index.html | 2 +- previews/PR261/examples/index.html | 2 +- .../examples/quantum1d/1.ising-cft/index.html | 2 +- .../examples/quantum1d/2.haldane/index.html | 2 +- .../quantum1d/3.ising-dqpt/index.html | 2 +- .../quantum1d/4.xxz-heisenberg/index.html | 2 +- .../quantum1d/5.haldane-spt/index.html | 2 +- .../examples/quantum1d/6.hubbard/index.html | 2 +- previews/PR261/index.html | 43 ++++----- previews/PR261/lib/lib/index.html | 90 +++++++++---------- previews/PR261/man/algorithms/index.html | 22 ++--- previews/PR261/man/environments/index.html | 2 +- previews/PR261/man/intro/index.html | 18 ++-- previews/PR261/man/lattices/index.html | 2 +- previews/PR261/man/operators/index.html | 2 +- previews/PR261/man/parallelism/index.html | 2 +- previews/PR261/man/states/index.html | 34 +++---- previews/PR261/references/index.html | 2 +- previews/PR261/search_index.js | 2 +- 20 files changed, 119 insertions(+), 118 deletions(-) diff --git a/previews/PR261/.documenter-siteinfo.json b/previews/PR261/.documenter-siteinfo.json index 53aa06ef..6232c3c4 100644 --- a/previews/PR261/.documenter-siteinfo.json +++ b/previews/PR261/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.11.3","generation_timestamp":"2025-03-03T16:04:52","documenter_version":"1.8.1"}} \ No newline at end of file +{"documenter":{"julia_version":"1.11.3","generation_timestamp":"2025-03-03T16:06:53","documenter_version":"1.8.1"}} \ No newline at end of file diff --git a/previews/PR261/examples/classic2d/1.hard-hexagon/index.html b/previews/PR261/examples/classic2d/1.hard-hexagon/index.html index 841ccf56..3252b1b6 100644 --- a/previews/PR261/examples/classic2d/1.hard-hexagon/index.html +++ b/previews/PR261/examples/classic2d/1.hard-hexagon/index.html @@ -97,4 +97,4 @@ -

This page was generated using Literate.jl.

+

This page was generated using Literate.jl.

diff --git a/previews/PR261/examples/index.html b/previews/PR261/examples/index.html index 867d5d65..70c419ae 100644 --- a/previews/PR261/examples/index.html +++ b/previews/PR261/examples/index.html @@ -1,2 +1,2 @@ -Examples · MPSKit.jl +Examples · MPSKit.jl diff --git a/previews/PR261/examples/quantum1d/1.ising-cft/index.html b/previews/PR261/examples/quantum1d/1.ising-cft/index.html index f5c0b836..5b1e80e2 100644 --- a/previews/PR261/examples/quantum1d/1.ising-cft/index.html +++ b/previews/PR261/examples/quantum1d/1.ising-cft/index.html @@ -319,4 +319,4 @@

-

This page was generated using Literate.jl.

+

This page was generated using Literate.jl.

diff --git a/previews/PR261/examples/quantum1d/2.haldane/index.html b/previews/PR261/examples/quantum1d/2.haldane/index.html index e29cab16..5822a079 100644 --- a/previews/PR261/examples/quantum1d/2.haldane/index.html +++ b/previews/PR261/examples/quantum1d/2.haldane/index.html @@ -206,4 +206,4 @@

-

This page was generated using Literate.jl.

+

This page was generated using Literate.jl.

diff --git a/previews/PR261/examples/quantum1d/3.ising-dqpt/index.html b/previews/PR261/examples/quantum1d/3.ising-dqpt/index.html index dae9340e..d22ec223 100644 --- a/previews/PR261/examples/quantum1d/3.ising-dqpt/index.html +++ b/previews/PR261/examples/quantum1d/3.ising-dqpt/index.html @@ -65,4 +65,4 @@ end return times, echos -end
infinite_sim (generic function with 3 methods)


This page was generated using Literate.jl.

+end
infinite_sim (generic function with 3 methods)


This page was generated using Literate.jl.

diff --git a/previews/PR261/examples/quantum1d/4.xxz-heisenberg/index.html b/previews/PR261/examples/quantum1d/4.xxz-heisenberg/index.html index 653a4222..d4a38065 100644 --- a/previews/PR261/examples/quantum1d/4.xxz-heisenberg/index.html +++ b/previews/PR261/examples/quantum1d/4.xxz-heisenberg/index.html @@ -642,4 +642,4 @@ [ Info: VUMPS 65: obj = -8.862878980878e-01 err = 1.5950561789e-12 time = 0.09 sec [ Info: VUMPS 66: obj = -8.862878980878e-01 err = 1.1189780150e-12 time = 0.09 sec [ Info: VUMPS conv 67: obj = -8.862878980878e-01 err = 7.7998640130e-13 time = 18.42 sec -

This page was generated using Literate.jl.

+

This page was generated using Literate.jl.

diff --git a/previews/PR261/examples/quantum1d/5.haldane-spt/index.html b/previews/PR261/examples/quantum1d/5.haldane-spt/index.html index 5c186957..dafbffcd 100644 --- a/previews/PR261/examples/quantum1d/5.haldane-spt/index.html +++ b/previews/PR261/examples/quantum1d/5.haldane-spt/index.html @@ -879,4 +879,4 @@ println("S_minus + log(2) = $(S_minus + log(2))") println("S_plus = $S_plus")
S_minus + log(2) = 1.0155125212288219
 S_plus = 0.7327304247852098
-

This page was generated using Literate.jl.

+

This page was generated using Literate.jl.

diff --git a/previews/PR261/examples/quantum1d/6.hubbard/index.html b/previews/PR261/examples/quantum1d/6.hubbard/index.html index fec0f0c0..349dc5e6 100644 --- a/previews/PR261/examples/quantum1d/6.hubbard/index.html +++ b/previews/PR261/examples/quantum1d/6.hubbard/index.html @@ -618,4 +618,4 @@ -

This page was generated using Literate.jl.

+

This page was generated using Literate.jl.

diff --git a/previews/PR261/index.html b/previews/PR261/index.html index fd44eb7d..3cd55169 100644 --- a/previews/PR261/index.html +++ b/previews/PR261/index.html @@ -48,17 +48,17 @@ FiniteMPOHamiltonian(lattice, (i,) => - g * Z for i in 1:length(lattice)) find_groundstate!(mps, H, DMRG(; maxiter=10)) E0 = expectation_value(mps, H) -println("<mps|H|mps> = $real(E0)")
[ Info: DMRG init:	obj = -3.864838578859e+00	err = 3.9514e-01
-[ Info: DMRG   1:	obj = -9.765010775027e+00	err = 1.5482809199e-02	time = 3.74 sec
-[ Info: DMRG   2:	obj = -9.765503490998e+00	err = 7.3305946591e-04	time = 0.36 sec
-[ Info: DMRG   3:	obj = -9.765503497215e+00	err = 4.6804970920e-06	time = 0.01 sec
-[ Info: DMRG   4:	obj = -9.765503497520e+00	err = 2.0533107869e-06	time = 0.01 sec
-[ Info: DMRG   5:	obj = -9.765503497585e+00	err = 9.7833310322e-07	time = 0.01 sec
-[ Info: DMRG   6:	obj = -9.765503497599e+00	err = 4.7658648441e-07	time = 0.01 sec
-[ Info: DMRG   7:	obj = -9.765503497602e+00	err = 2.3494902442e-07	time = 0.01 sec
-[ Info: DMRG   8:	obj = -9.765503497602e+00	err = 1.1652488789e-07	time = 0.01 sec
-[ Info: DMRG   9:	obj = -9.765503497603e+00	err = 5.7955657438e-08	time = 0.01 sec
-┌ Warning: DMRG cancel 10:	obj = -9.765503497603e+00	err = 2.8861118586e-08	time = 4.22 sec
+println("<mps|H|mps> = $real(E0)")
[ Info: DMRG init:	obj = -3.589471235482e+00	err = 4.1481e-01
+[ Info: DMRG   1:	obj = -9.765310609855e+00	err = 1.7842627356e-02	time = 3.97 sec
+[ Info: DMRG   2:	obj = -9.765503495080e+00	err = 9.4052095296e-04	time = 0.61 sec
+[ Info: DMRG   3:	obj = -9.765503497248e+00	err = 4.2427156119e-06	time = 0.01 sec
+[ Info: DMRG   4:	obj = -9.765503497529e+00	err = 1.9603848507e-06	time = 0.01 sec
+[ Info: DMRG   5:	obj = -9.765503497586e+00	err = 9.3627872709e-07	time = 0.01 sec
+[ Info: DMRG   6:	obj = -9.765503497599e+00	err = 4.5681245222e-07	time = 0.01 sec
+[ Info: DMRG   7:	obj = -9.765503497602e+00	err = 2.2542409303e-07	time = 0.01 sec
+[ Info: DMRG   8:	obj = -9.765503497602e+00	err = 1.1186662617e-07	time = 0.01 sec
+[ Info: DMRG   9:	obj = -9.765503497603e+00	err = 5.5658664967e-08	time = 0.01 sec
+┌ Warning: DMRG cancel 10:	obj = -9.765503497603e+00	err = 2.7722743290e-08	time = 4.68 sec
 └ @ MPSKit ~/work/MPSKit.jl/MPSKit.jl/src/algorithms/groundstate/dmrg.jl:55
 <mps|H|mps> = real(E0)

Infinite Matrix Product States

Similarly, an infinite MPS can be constructed by specifying the tensors for the unit cell, characterised by the spaces (dimensions) thereof.

d = 2 # physical dimension
 D = 5 # virtual dimension
@@ -80,7 +80,7 @@
 

These objects can then be used to compute observables and expectation values. For example, the norm of the MPS, which is equal to the expectation value of the identity operator can be computed by:

N1 = norm(mps)
 N2 = expectation_value(mps, 1 => id(physicalspace(mps, 1)))
 println("‖mps‖ = $N1")
-println("<mps|𝕀₁|mps> = $N2")
‖mps‖ = 0.9999999999999999
+println("<mps|𝕀₁|mps> = $N2")
‖mps‖ = 0.9999999999999998
 <mps|𝕀₁|mps> = 1.0000000000000002 + 0.0im
Normalization of infinite MPS

Because infinite MPS cannot sensibly be normalized to anything but $1$, the norm of an infinite MPS is always set to be $1$ at construction. If this were not the case, any observable computed from the MPS would either blow up to infinity or vanish to zero.

Finally, the MPS can be optimized in order to determine groundstates of given Hamiltonians. There are plenty of pre-defined models in MPSKitModels, but we can also manually construct the groundstate for the transverse field Ising model:

J = 1.0
 g = 0.5
 lattice = PeriodicVector([ComplexSpace(2)])
@@ -89,12 +89,13 @@
 H = InfiniteMPOHamiltonian(lattice, (1, 2) => -J * X ⊗ X, (1,) => - g * Z)
 mps, = find_groundstate(mps, H, VUMPS(; maxiter=10))
 E0 = expectation_value(mps, H)
-println("<mps|H|mps> = $(sum(real(E0)) / length(mps))")
[ Info: VUMPS init:	obj = -7.814978775107e-01	err = 3.3777e-01
-[ Info: VUMPS   1:	obj = -1.063527963103e+00	err = 3.8383351165e-03	time = 7.10 sec
-[ Info: VUMPS   2:	obj = -1.063544409242e+00	err = 2.3155854576e-05	time = 0.00 sec
-[ Info: VUMPS   3:	obj = -1.063544409972e+00	err = 1.1483049210e-06	time = 0.00 sec
-[ Info: VUMPS   4:	obj = -1.063544409973e+00	err = 6.3948942162e-08	time = 0.00 sec
-[ Info: VUMPS   5:	obj = -1.063544409973e+00	err = 6.2360908090e-09	time = 0.00 sec
-[ Info: VUMPS   6:	obj = -1.063544409973e+00	err = 6.6026688931e-10	time = 0.00 sec
-[ Info: VUMPS conv 7:	obj = -1.063544409973e+00	err = 7.0736357295e-11	time = 7.12 sec
-<mps|H|mps> = -1.0635444099732514

Additional Resources

For more detailed information on the functionality and capabilities of MPSKit, refer to the Manual section, or have a look at the Examples page.

Keep in mind that the documentation is still a work in progress, and that some features may not be fully documented yet. If you encounter any issues or have questions, please check the library's issue tracker on the GitHub repository and open a new issue.

+println("<mps|H|mps> = $(sum(real(E0)) / length(mps))")
[ Info: VUMPS init:	obj = -1.048025792522e+00	err = 1.1497e-01
+[ Info: VUMPS   1:	obj = -1.063539222079e+00	err = 1.9505328534e-03	time = 6.99 sec
+[ Info: VUMPS   2:	obj = -1.063544408870e+00	err = 2.9575710949e-05	time = 0.00 sec
+[ Info: VUMPS   3:	obj = -1.063544409971e+00	err = 1.2806558684e-06	time = 0.00 sec
+[ Info: VUMPS   4:	obj = -1.063544409973e+00	err = 1.0780920009e-07	time = 0.00 sec
+[ Info: VUMPS   5:	obj = -1.063544409973e+00	err = 1.0651393823e-08	time = 0.00 sec
+[ Info: VUMPS   6:	obj = -1.063544409973e+00	err = 1.1293766626e-09	time = 0.00 sec
+[ Info: VUMPS   7:	obj = -1.063544409973e+00	err = 1.2084937411e-10	time = 0.00 sec
+[ Info: VUMPS conv 8:	obj = -1.063544409973e+00	err = 1.2963548067e-11	time = 7.00 sec
+<mps|H|mps> = -1.0635444099732492

Additional Resources

For more detailed information on the functionality and capabilities of MPSKit, refer to the Manual section, or have a look at the Examples page.

Keep in mind that the documentation is still a work in progress, and that some features may not be fully documented yet. If you encounter any issues or have questions, please check the library's issue tracker on the GitHub repository and open a new issue.

diff --git a/previews/PR261/lib/lib/index.html b/previews/PR261/lib/lib/index.html index 81231ad6..d16182a3 100644 --- a/previews/PR261/lib/lib/index.html +++ b/previews/PR261/lib/lib/index.html @@ -1,41 +1,41 @@ -Library · MPSKit.jl

Library documentation

MPSKit.WIConstant
const WI = TaylorCluster(; N=1, extension=false, compression=false)

First order Taylor expansion for a time-evolution MPO.

source
MPSKit.AbstractMPOType
abstract type AbstractMPO{O} <: AbstractVector{O} end

Abstract supertype for Matrix Product Operators (MPOs).

source
MPSKit.AlgorithmType
abstract type Algorithm

Abstract supertype for all algorithm structs. These can be thought of as NamedTuples that hold the settings for a given algorithm, which can be used for dispatch. Additionally, the constructors can be used to provide default values and input sanitation.

source
MPSKit.ChepigaAnsatzType
struct ChepigaAnsatz{A<:KrylovKit.KrylovAlgorithm} <: MPSKit.Algorithm

Single-site optimization algorithm for excitations on top of MPS groundstates.

Fields

  • alg::KrylovKit.KrylovAlgorithm: algorithm used for the eigenvalue solvers

Constructors

ChepigaAnsatz()
+Library · MPSKit.jl

Library documentation

MPSKit.WIConstant
const WI = TaylorCluster(; N=1, extension=false, compression=false)

First order Taylor expansion for a time-evolution MPO.

source
MPSKit.AbstractMPOType
abstract type AbstractMPO{O} <: AbstractVector{O} end

Abstract supertype for Matrix Product Operators (MPOs).

source
MPSKit.AlgorithmType
abstract type Algorithm

Abstract supertype for all algorithm structs. These can be thought of as NamedTuples that hold the settings for a given algorithm, which can be used for dispatch. Additionally, the constructors can be used to provide default values and input sanitation.

source
MPSKit.ChepigaAnsatzType
struct ChepigaAnsatz{A<:KrylovKit.KrylovAlgorithm} <: MPSKit.Algorithm

Single-site optimization algorithm for excitations on top of MPS groundstates.

Fields

  • alg::KrylovKit.KrylovAlgorithm: algorithm used for the eigenvalue solvers

Constructors

ChepigaAnsatz()
 ChepigaAnsatz(; kwargs...)
-ChepigaAnsatz(alg)

Create a ChepigaAnsatz algorithm with the given eigensolver, or by passing the keyword arguments to [Arnoldi][@extref KrylovKit.Arnoldi].

References

source
MPSKit.ChepigaAnsatz2Type
ChepigaAnsatz2 <: Algorithm

Two-site optimization algorithm for excitations on top of MPS groundstates.

Fields

  • alg::A = Defaults.eigsolver: algorithm to use for the eigenvalue problem.
  • trscheme = Defaults.trscheme: algorithm to use for truncation.

Constructors

ChepigaAnsatz2()
+ChepigaAnsatz(alg)

Create a ChepigaAnsatz algorithm with the given eigensolver, or by passing the keyword arguments to [Arnoldi][@extref KrylovKit.Arnoldi].

References

source
MPSKit.ChepigaAnsatz2Type
ChepigaAnsatz2 <: Algorithm

Two-site optimization algorithm for excitations on top of MPS groundstates.

Fields

  • alg::A = Defaults.eigsolver: algorithm to use for the eigenvalue problem.
  • trscheme = Defaults.trscheme: algorithm to use for truncation.

Constructors

ChepigaAnsatz2()
 ChepigaAnsatz2(; kwargs...)
-ChepigaAnsatz2(alg, trscheme)

Create a ChepigaAnsatz2 algorithm with the given eigensolver and truncation, or by passing the keyword arguments to Arnoldi.

References

source
MPSKit.DMRGType
struct DMRG{A, F} <: MPSKit.Algorithm

Single-site DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

  • verbosity::Int64: setting for how much information is displayed

  • eigalg::Any: algorithm used for the eigenvalue solvers

source
MPSKit.DMRG2Type
struct DMRG2{A, F} <: MPSKit.Algorithm

Two-site DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

  • verbosity::Int64: setting for how much information is displayed

  • eigalg::Any: algorithm used for the eigenvalue solvers

  • trscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update

source
MPSKit.DynamicalDMRGType
struct DynamicalDMRG{F<:MPSKit.DDMRG_Flavour, S} <: MPSKit.Algorithm

A dynamical DMRG method for calculating dynamical properties and excited states, based on a variational principle for dynamical correlation functions.

Fields

  • flavour::MPSKit.DDMRG_Flavour: flavour of the algorithm to use, either of type NaiveInvert or Jeckelmann

  • solver::Any: algorithm used for the linear solvers

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

References

source
MPSKit.FiniteEnvironmentsType
struct FiniteEnvironments <: AbstractMPSEnvironments

Environment manager for FiniteMPS and WindowMPS. This structure is responsable for automatically checking if the queried environment is still correctly cached and if not recalculates.

source
MPSKit.FiniteExcitedType
struct FiniteExcited{A} <: MPSKit.Algorithm

Variational optimization algorithm for excitations of finite MPS by minimizing the energy of

\[H - λᵢ |ψᵢ⟩⟨ψᵢ|\]

Fields

  • gsalg::Any: optimization algorithm

  • weight::Float64: energy penalty for enforcing orthogonality with previous states

source
MPSKit.FiniteMPOType
FiniteMPO(Os::Vector{O}) -> FiniteMPO{O}
-FiniteMPO(O::AbstractTensorMap{S,N,N}) where {S,N} -> FiniteMPO{O<:MPOTensor}

Matrix Product Operator (MPO) acting on a finite tensor product space with a linear order.

source
MPSKit.FiniteMPSType
FiniteMPS{A<:GenericMPSTensor,B<:MPSBondTensor} <: AbstractFiniteMPS

Type that represents a finite Matrix Product State.

Properties

  • AL – left-gauged MPS tensors
  • AR – right-gauged MPS tensors
  • AC – center-gauged MPS tensors
  • C – gauge tensors
  • center – location of the gauge center

The center property returns center::HalfInt that indicates the location of the MPS center:

  • isinteger(center)center is a whole number and indicates the location of the first AC tensor present in the underlying ψ.ACs field.
  • ishalfodd(center)center is a half-odd-integer, meaning that there are no AC tensors, and indicating between which sites the bond tensor lives.

e.g mps.center = 7/2 means that the bond tensor is to the right of the 3rd site and can be accessed via mps.C[3].

Notes

By convention, we have that:

  • AL[i] * C[i] = AC[i] = C[i-1] * AR[i]
  • AL[i]' * AL[i] = 1
  • AR[i] * AR[i]' = 1

Constructors

FiniteMPS([f, eltype], physicalspaces::Vector{<:Union{S,CompositeSpace{S}}},
+ChepigaAnsatz2(alg, trscheme)

Create a ChepigaAnsatz2 algorithm with the given eigensolver and truncation, or by passing the keyword arguments to Arnoldi.

References

source
MPSKit.DMRGType
struct DMRG{A, F} <: MPSKit.Algorithm

Single-site DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

  • verbosity::Int64: setting for how much information is displayed

  • eigalg::Any: algorithm used for the eigenvalue solvers

source
MPSKit.DMRG2Type
struct DMRG2{A, F} <: MPSKit.Algorithm

Two-site DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

  • verbosity::Int64: setting for how much information is displayed

  • eigalg::Any: algorithm used for the eigenvalue solvers

  • trscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update

source
MPSKit.DynamicalDMRGType
struct DynamicalDMRG{F<:MPSKit.DDMRG_Flavour, S} <: MPSKit.Algorithm

A dynamical DMRG method for calculating dynamical properties and excited states, based on a variational principle for dynamical correlation functions.

Fields

  • flavour::MPSKit.DDMRG_Flavour: flavour of the algorithm to use, either of type NaiveInvert or Jeckelmann

  • solver::Any: algorithm used for the linear solvers

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

References

source
MPSKit.FiniteEnvironmentsType
struct FiniteEnvironments <: AbstractMPSEnvironments

Environment manager for FiniteMPS and WindowMPS. This structure is responsable for automatically checking if the queried environment is still correctly cached and if not recalculates.

source
MPSKit.FiniteExcitedType
struct FiniteExcited{A} <: MPSKit.Algorithm

Variational optimization algorithm for excitations of finite MPS by minimizing the energy of

\[H - λᵢ |ψᵢ⟩⟨ψᵢ|\]

Fields

  • gsalg::Any: optimization algorithm

  • weight::Float64: energy penalty for enforcing orthogonality with previous states

source
MPSKit.FiniteMPOType
FiniteMPO(Os::Vector{O}) -> FiniteMPO{O}
+FiniteMPO(O::AbstractTensorMap{S,N,N}) where {S,N} -> FiniteMPO{O<:MPOTensor}

Matrix Product Operator (MPO) acting on a finite tensor product space with a linear order.

source
MPSKit.FiniteMPSType
FiniteMPS{A<:GenericMPSTensor,B<:MPSBondTensor} <: AbstractFiniteMPS

Type that represents a finite Matrix Product State.

Properties

  • AL – left-gauged MPS tensors
  • AR – right-gauged MPS tensors
  • AC – center-gauged MPS tensors
  • C – gauge tensors
  • center – location of the gauge center

The center property returns center::HalfInt that indicates the location of the MPS center:

  • isinteger(center)center is a whole number and indicates the location of the first AC tensor present in the underlying ψ.ACs field.
  • ishalfodd(center)center is a half-odd-integer, meaning that there are no AC tensors, and indicating between which sites the bond tensor lives.

e.g mps.center = 7/2 means that the bond tensor is to the right of the 3rd site and can be accessed via mps.C[3].

Notes

By convention, we have that:

  • AL[i] * C[i] = AC[i] = C[i-1] * AR[i]
  • AL[i]' * AL[i] = 1
  • AR[i] * AR[i]' = 1

Constructors

FiniteMPS([f, eltype], physicalspaces::Vector{<:Union{S,CompositeSpace{S}}},
           maxvirtualspaces::Union{S,Vector{S}};
           normalize=true, left=oneunit(S), right=oneunit(S)) where {S<:ElementarySpace}
 FiniteMPS([f, eltype], N::Int, physicalspace::Union{S,CompositeSpace{S}},
           maxvirtualspaces::Union{S,Vector{S}};
           normalize=true, left=oneunit(S), right=oneunit(S)) where {S<:ElementarySpace}
-FiniteMPS(As::Vector{<:GenericMPSTensor}; normalize=false, overwrite=false)

Construct an MPS via a specification of physical and virtual spaces, or from a list of tensors As. All cases reduce to the latter. In particular, a state with a non-trivial total charge can be constructed by passing a non-trivially charged vector space as the left or right virtual spaces.

Arguments

  • As::Vector{<:GenericMPSTensor}: vector of site tensors

  • f::Function=rand: initializer function for tensor data

  • eltype::Type{<:Number}=ComplexF64: scalar type of tensors

  • physicalspaces::Vector{<:Union{S, CompositeSpace{S}}: list of physical spaces

  • N::Int: number of sites

  • physicalspace::Union{S,CompositeSpace{S}}: local physical space

  • virtualspaces::Vector{<:Union{S, CompositeSpace{S}}: list of virtual spaces

  • maxvirtualspace::S: maximum virtual space

Keywords

  • normalize=true: normalize the constructed state
  • overwrite=false: overwrite the given input tensors
  • left=oneunit(S): left-most virtual space
  • right=oneunit(S): right-most virtual space
source
MPSKit.GradientGrassmannType
struct GradientGrassmann{O<:OptimKit.OptimizationAlgorithm, F} <: MPSKit.Algorithm

Variational gradient-based optimization algorithm that keeps the MPS in left-canonical form, as points on a Grassmann manifold. The optimization is then a Riemannian gradient descent with a preconditioner to induce the metric from the Hilbert space inner product.

Fields

  • method::OptimKit.OptimizationAlgorithm: optimization algorithm

  • finalize!::Any: callback function applied after each iteration, of signature finalize!(x, f, g, numiter) -> x, f, g

References


Constructors

GradientGrassmann(; kwargs...)

Keywords

  • method=ConjugateGradient: instance of optimization algorithm, or type of optimization algorithm to construct
  • finalize!: finalizer algorithm
  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: level of information display
source
MPSKit.IDMRGType
struct IDMRG{A} <: MPSKit.Algorithm

Single site infinite DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_gauge::Any: algorithm used for gauging the MPS

  • alg_eigsolve::Any: algorithm used for the eigenvalue solvers

source
MPSKit.IDMRG2Type
struct IDMRG2{A} <: MPSKit.Algorithm

Two-site infinite DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_gauge::Any: algorithm used for gauging the MPS

  • alg_eigsolve::Any: algorithm used for the eigenvalue solvers

  • trscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update

source
MPSKit.InfiniteEnvironmentsType
InfiniteEnvironments <: AbstractMPSEnvironments

Environments for an infinite MPS-MPO-MPS combination. These solve the corresponding fixedpoint equations:

\[GLs[i] * T_LL[i] = λ GLs[i + 1] -T_RR[i] * GRs[i] = λ GRs[i - 1]\]

where T_LL and T_RR are the (regularized) transfer matrix operators on a give site for AL-O-AL and AR-O-AR respectively.

source
MPSKit.InfiniteMPOType
InfiniteMPO(Os::PeriodicVector{O}) -> InfiniteMPO{O}

Matrix Product Operator (MPO) acting on an infinite tensor product space with a linear order.

source
MPSKit.InfiniteMPSType
InfiniteMPS{A<:GenericMPSTensor,B<:MPSBondTensor} <: AbtractMPS

Type that represents an infinite Matrix Product State.

Fields

  • AL – left-gauged MPS tensors
  • AR – right-gauged MPS tensors
  • AC – center-gauged MPS tensors
  • C – gauge tensors

Notes

By convention, we have that:

  • AL[i] * C[i] = AC[i] = C[i-1] * AR[i]
  • AL[i]' * AL[i] = 1
  • AR[i] * AR[i]' = 1

Constructors

InfiniteMPS([f, eltype], physicalspaces::Vector{<:Union{S, CompositeSpace{S}},
+FiniteMPS(As::Vector{<:GenericMPSTensor}; normalize=false, overwrite=false)

Construct an MPS via a specification of physical and virtual spaces, or from a list of tensors As. All cases reduce to the latter. In particular, a state with a non-trivial total charge can be constructed by passing a non-trivially charged vector space as the left or right virtual spaces.

Arguments

  • As::Vector{<:GenericMPSTensor}: vector of site tensors

  • f::Function=rand: initializer function for tensor data

  • eltype::Type{<:Number}=ComplexF64: scalar type of tensors

  • physicalspaces::Vector{<:Union{S, CompositeSpace{S}}: list of physical spaces

  • N::Int: number of sites

  • physicalspace::Union{S,CompositeSpace{S}}: local physical space

  • virtualspaces::Vector{<:Union{S, CompositeSpace{S}}: list of virtual spaces

  • maxvirtualspace::S: maximum virtual space

Keywords

  • normalize=true: normalize the constructed state
  • overwrite=false: overwrite the given input tensors
  • left=oneunit(S): left-most virtual space
  • right=oneunit(S): right-most virtual space
source
MPSKit.GradientGrassmannType
struct GradientGrassmann{O<:OptimKit.OptimizationAlgorithm, F} <: MPSKit.Algorithm

Variational gradient-based optimization algorithm that keeps the MPS in left-canonical form, as points on a Grassmann manifold. The optimization is then a Riemannian gradient descent with a preconditioner to induce the metric from the Hilbert space inner product.

Fields

  • method::OptimKit.OptimizationAlgorithm: optimization algorithm

  • finalize!::Any: callback function applied after each iteration, of signature finalize!(x, f, g, numiter) -> x, f, g

References


Constructors

GradientGrassmann(; kwargs...)

Keywords

  • method=ConjugateGradient: instance of optimization algorithm, or type of optimization algorithm to construct
  • finalize!: finalizer algorithm
  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: level of information display
source
MPSKit.IDMRGType
struct IDMRG{A} <: MPSKit.Algorithm

Single site infinite DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_gauge::Any: algorithm used for gauging the MPS

  • alg_eigsolve::Any: algorithm used for the eigenvalue solvers

source
MPSKit.IDMRG2Type
struct IDMRG2{A} <: MPSKit.Algorithm

Two-site infinite DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_gauge::Any: algorithm used for gauging the MPS

  • alg_eigsolve::Any: algorithm used for the eigenvalue solvers

  • trscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update

source
MPSKit.InfiniteEnvironmentsType
InfiniteEnvironments <: AbstractMPSEnvironments

Environments for an infinite MPS-MPO-MPS combination. These solve the corresponding fixedpoint equations:

\[GLs[i] * T_LL[i] = λ GLs[i + 1] +T_RR[i] * GRs[i] = λ GRs[i - 1]\]

where T_LL and T_RR are the (regularized) transfer matrix operators on a give site for AL-O-AL and AR-O-AR respectively.

source
MPSKit.InfiniteMPOType
InfiniteMPO(Os::PeriodicVector{O}) -> InfiniteMPO{O}

Matrix Product Operator (MPO) acting on an infinite tensor product space with a linear order.

source
MPSKit.InfiniteMPSType
InfiniteMPS{A<:GenericMPSTensor,B<:MPSBondTensor} <: AbtractMPS

Type that represents an infinite Matrix Product State.

Fields

  • AL – left-gauged MPS tensors
  • AR – right-gauged MPS tensors
  • AC – center-gauged MPS tensors
  • C – gauge tensors

Notes

By convention, we have that:

  • AL[i] * C[i] = AC[i] = C[i-1] * AR[i]
  • AL[i]' * AL[i] = 1
  • AR[i] * AR[i]' = 1

Constructors

InfiniteMPS([f, eltype], physicalspaces::Vector{<:Union{S, CompositeSpace{S}},
             virtualspaces::Vector{<:Union{S, CompositeSpace{S}};
             kwargs...) where {S<:ElementarySpace}
 InfiniteMPS(As::AbstractVector{<:GenericMPSTensor}; kwargs...)
 InfiniteMPS(ALs::AbstractVector{<:GenericMPSTensor}, C₀::MPSBondTensor;
-            kwargs...)

Construct an MPS via a specification of physical and virtual spaces, or from a list of tensors As, or a list of left-gauged tensors ALs.

Arguments

  • As::AbstractVector{<:GenericMPSTensor}: vector of site tensors

  • ALs::AbstractVector{<:GenericMPSTensor}: vector of left-gauged site tensors

  • C₀::MPSBondTensor: initial gauge tensor

  • f::Function=rand: initializer function for tensor data

  • eltype::Type{<:Number}=ComplexF64: scalar type of tensors

  • physicalspaces::AbstractVector{<:Union{S, CompositeSpace{S}}: list of physical spaces

  • virtualspaces::AbstractVector{<:Union{S, CompositeSpace{S}}: list of virtual spaces

Keywords

  • tol: gauge fixing tolerance
  • maxiter: gauge fixing maximum iterations
source
MPSKit.InfiniteQPEnvironmentsType
InfiniteQPEnvironments <: AbstractMPSEnvironments

Environments for an infinite QP-MPO-QP combination. These solve the corresponding fixedpoint equations:

\[GLs[i] * T_BL[i] + GBLs[i] * T_RL[i] = GBLs[i + 1] -T_BR[i] * GRs[i] + T_LR[i] * GBRs[i] = GBRs[i - 1]\]

where T_BL, T_BR, T_RL and T_LR are the (regularized) transfer matrix operators on a given site for B-O-AL, B-O-AR, AR-O-AL and AL-O-AR respectively.

source
MPSKit.LazySumType
LazySum{O} <: AbstractVector{O}

Type that represents a lazy sum i.e explicit summation is only done when needed. This type is basically an AbstractVector with some extra functionality to calculate things efficiently.

Fields

  • ops – Vector of summable objects

Constructors

LazySum(x::Vector)
source
MPSKit.LeftCanonicalType
struct LeftCanonical <: MPSKit.Algorithm

Algorithm for bringing an InfiniteMPS into the left-canonical form.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_orth::Any: algorithm used for orthogonalization of the tensors

  • alg_eigsolve::Any: algorithm used for the eigensolver

  • eig_miniter::Int64: minimal amount of iterations before using the eigensolver steps

source
MPSKit.MPOType
struct MPO{O,V<:AbstractVector{O}} <: AbstractMPO{O}

Matrix Product Operator (MPO) acting on a tensor product space with a linear order.

See also: FiniteMPO, InfiniteMPO

source
MPSKit.MPOHamiltonianType
MPOHamiltonian(lattice::AbstractArray{<:VectorSpace}, local_operators...)
+            kwargs...)

Construct an MPS via a specification of physical and virtual spaces, or from a list of tensors As, or a list of left-gauged tensors ALs.

Arguments

  • As::AbstractVector{<:GenericMPSTensor}: vector of site tensors

  • ALs::AbstractVector{<:GenericMPSTensor}: vector of left-gauged site tensors

  • C₀::MPSBondTensor: initial gauge tensor

  • f::Function=rand: initializer function for tensor data

  • eltype::Type{<:Number}=ComplexF64: scalar type of tensors

  • physicalspaces::AbstractVector{<:Union{S, CompositeSpace{S}}: list of physical spaces

  • virtualspaces::AbstractVector{<:Union{S, CompositeSpace{S}}: list of virtual spaces

Keywords

  • tol: gauge fixing tolerance
  • maxiter: gauge fixing maximum iterations
source
MPSKit.InfiniteQPEnvironmentsType
InfiniteQPEnvironments <: AbstractMPSEnvironments

Environments for an infinite QP-MPO-QP combination. These solve the corresponding fixedpoint equations:

\[GLs[i] * T_BL[i] + GBLs[i] * T_RL[i] = GBLs[i + 1] +T_BR[i] * GRs[i] + T_LR[i] * GBRs[i] = GBRs[i - 1]\]

where T_BL, T_BR, T_RL and T_LR are the (regularized) transfer matrix operators on a given site for B-O-AL, B-O-AR, AR-O-AL and AL-O-AR respectively.

source
MPSKit.LazySumType
LazySum{O} <: AbstractVector{O}

Type that represents a lazy sum i.e explicit summation is only done when needed. This type is basically an AbstractVector with some extra functionality to calculate things efficiently.

Fields

  • ops – Vector of summable objects

Constructors

LazySum(x::Vector)
source
MPSKit.LeftCanonicalType
struct LeftCanonical <: MPSKit.Algorithm

Algorithm for bringing an InfiniteMPS into the left-canonical form.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_orth::Any: algorithm used for orthogonalization of the tensors

  • alg_eigsolve::Any: algorithm used for the eigensolver

  • eig_miniter::Int64: minimal amount of iterations before using the eigensolver steps

source
MPSKit.MPOType
struct MPO{O,V<:AbstractVector{O}} <: AbstractMPO{O}

Matrix Product Operator (MPO) acting on a tensor product space with a linear order.

See also: FiniteMPO, InfiniteMPO

source
MPSKit.MPOHamiltonianType
MPOHamiltonian(lattice::AbstractArray{<:VectorSpace}, local_operators...)
 MPOHamiltonian(lattice::AbstractArray{<:VectorSpace})
 MPOHamiltonian(x::AbstractArray{<:Any,3})

MPO representation of a hamiltonian. This is a specific form of an AbstractMPO, where all the sites are represented by an upper triangular block matrix of the following form:

\[\begin{pmatrix} 1 & C & D \\ 0 & A & B \\ 0 & 0 & 1 \end{pmatrix}\]

where A, B, C, and D are MPOTensors, or (sparse) blocks thereof.

Examples

For example, constructing a nearest-neighbour Hamiltonian would look like this:

lattice = fill(ℂ^2, 10)
-H = MPOHamiltonian(lattice, (i, i+1) => O for i in 1:length(lattice)-1)

See also instantiate_operator, which is responsable for instantiating the local operators in a form that is compatible with this constructor.

source
MPSKit.MPOTensorType
MPOTensor{S}

Tensor type for representing local MPO tensors, with the index convention W ⊗ S ← N ⊗ E, where N, E, S and W denote the north, east, south and west virtual spaces respectively.

source
MPSKit.MPSTensorType
MPSTensor([f, eltype], d::Int, Dₗ::Int, [Dᵣ]::Int])

Construct an MPSTensor with given physical and virtual dimensions.

Arguments

  • f::Function=rand: initializer function for tensor data
  • eltype::Type{<:Number}=ComplexF64: scalar type of tensors
  • d::Int: physical dimension
  • Dₗ::Int: left virtual dimension
  • Dᵣ::Int: right virtual dimension
source
MPSKit.MPSTensorMethod
MPSTensor([f, eltype], d::Int, left_D::Int, [right_D]::Int])
+H = MPOHamiltonian(lattice, (i, i+1) => O for i in 1:length(lattice)-1)

See also instantiate_operator, which is responsable for instantiating the local operators in a form that is compatible with this constructor.

source
MPSKit.MPOTensorType
MPOTensor{S}

Tensor type for representing local MPO tensors, with the index convention W ⊗ S ← N ⊗ E, where N, E, S and W denote the north, east, south and west virtual spaces respectively.

source
MPSKit.MPSTensorType
MPSTensor([f, eltype], d::Int, Dₗ::Int, [Dᵣ]::Int])

Construct an MPSTensor with given physical and virtual dimensions.

Arguments

  • f::Function=rand: initializer function for tensor data
  • eltype::Type{<:Number}=ComplexF64: scalar type of tensors
  • d::Int: physical dimension
  • Dₗ::Int: left virtual dimension
  • Dᵣ::Int: right virtual dimension
source
MPSKit.MPSTensorMethod
MPSTensor([f, eltype], d::Int, left_D::Int, [right_D]::Int])
 MPSTensor([f, eltype], physicalspace::Union{S,CompositeSpace{S}}, 
-          left_virtualspace::S, [right_virtualspace]::S) where {S<:ElementarySpace}

Construct an MPSTensor with given physical and virtual spaces.

Arguments

  • f::Function=rand: initializer function for tensor data

  • eltype::Type{<:Number}=ComplexF64: scalar type of tensors

  • physicalspace::Union{S,CompositeSpace{S}}: physical space

  • left_virtualspace::S: left virtual space

  • right_virtualspace::S: right virtual space, defaults to equal left

  • d::Int: physical dimension

  • left_D::Int: left virtual dimension

  • right_D::Int: right virtual dimension

source
MPSKit.MixedCanonicalType
struct MixedCanonical <: MPSKit.Algorithm

Algorithm for bringing an InfiniteMPS into the mixed-canonical form.

Fields

  • alg_leftcanonical::MPSKit.LeftCanonical: algorithm for bringing an InfiniteMPS into left-canonical form.

  • alg_rightcanonical::MPSKit.RightCanonical: algorithm for bringing an InfiniteMPS into right-canonical form.

  • order::Symbol: order in which to apply the canonicalizations, should be :L, :R, :LR or :RL

source
MPSKit.MultilineType
struct Multiline{T}

Object that represents multiple lines of objects of type T. Typically used to represent multiple lines of InfiniteMPS (MultilineMPS) or MPO (Multiline{<:AbstractMPO}).

Fields

  • data::PeriodicArray{T,1}: the data of the multiline object

See also: MultilineMPS and MultilineMPO

source
MPSKit.MultilineMPOType
const MultilineMPO = Multiline{<:AbstractMPO}

Type that represents multiple lines of MPO objects.

Constructors

MultilineMPO(mpos::AbstractVector{<:Union{SparseMPO,DenseMPO}})
-MultilineMPO(Os::AbstractMatrix{<:MPOTensor})

See also: Multiline, AbstractMPO

source
MPSKit.MultilineMPSType
const MultilineMPS = Multiline{<:InfiniteMPS}

Type that represents multiple lines of InfiniteMPS objects.

Constructors

MultilineMPS(mpss::AbstractVector{<:InfiniteMPS})
+          left_virtualspace::S, [right_virtualspace]::S) where {S<:ElementarySpace}

Construct an MPSTensor with given physical and virtual spaces.

Arguments

  • f::Function=rand: initializer function for tensor data

  • eltype::Type{<:Number}=ComplexF64: scalar type of tensors

  • physicalspace::Union{S,CompositeSpace{S}}: physical space

  • left_virtualspace::S: left virtual space

  • right_virtualspace::S: right virtual space, defaults to equal left

  • d::Int: physical dimension

  • left_D::Int: left virtual dimension

  • right_D::Int: right virtual dimension

source
MPSKit.MixedCanonicalType
struct MixedCanonical <: MPSKit.Algorithm

Algorithm for bringing an InfiniteMPS into the mixed-canonical form.

Fields

  • alg_leftcanonical::MPSKit.LeftCanonical: algorithm for bringing an InfiniteMPS into left-canonical form.

  • alg_rightcanonical::MPSKit.RightCanonical: algorithm for bringing an InfiniteMPS into right-canonical form.

  • order::Symbol: order in which to apply the canonicalizations, should be :L, :R, :LR or :RL

source
MPSKit.MultilineType
struct Multiline{T}

Object that represents multiple lines of objects of type T. Typically used to represent multiple lines of InfiniteMPS (MultilineMPS) or MPO (Multiline{<:AbstractMPO}).

Fields

  • data::PeriodicArray{T,1}: the data of the multiline object

See also: MultilineMPS and MultilineMPO

source
MPSKit.MultilineMPOType
const MultilineMPO = Multiline{<:AbstractMPO}

Type that represents multiple lines of MPO objects.

Constructors

MultilineMPO(mpos::AbstractVector{<:Union{SparseMPO,DenseMPO}})
+MultilineMPO(Os::AbstractMatrix{<:MPOTensor})

See also: Multiline, AbstractMPO

source
MPSKit.MultilineMPSType
const MultilineMPS = Multiline{<:InfiniteMPS}

Type that represents multiple lines of InfiniteMPS objects.

Constructors

MultilineMPS(mpss::AbstractVector{<:InfiniteMPS})
 MultilineMPS([f, eltype], physicalspaces::Matrix{<:Union{S, CompositeSpace{S}},
              virtualspaces::Matrix{<:Union{S, CompositeSpace{S}}) where
              {S<:ElementarySpace}
 MultilineMPS(As::AbstractMatrix{<:GenericMPSTensor}; kwargs...)
 MultilineMPS(ALs::AbstractMatrix{<:GenericMPSTensor}, 
-             C₀::AbstractVector{<:MPSBondTensor}; kwargs...)

See also: Multiline

source
MPSKit.MultipliedOperatorType
Structure representing a multiplied operator. Consists of
     - An operator op (MPO, Hamiltonian, ...)
-    - An object f that gets multiplied with the operator (Number, function, ...)
source
MPSKit.NaiveInvertType
struct NaiveInvert <: MPSKit.DDMRG_Flavour

An alternative approach to the dynamical DMRG algorithm, without quadratic terms but with a less controlled approximation. This algorithm minimizes the following cost function

\[⟨ψ|(H - E)|ψ⟩ - ⟨ψ|ψ₀⟩ - ⟨ψ₀|ψ⟩\]

which is equivalent to the original approach if

\[|ψ₀⟩ = (H - E)|ψ⟩\]

See also Jeckelmann for the original approach.

source
MPSKit.OptimalExpandType
struct OptimalExpand <: MPSKit.Algorithm

An algorithm that expands the given mps as described in Zauner-Stauber et al. Phys. Rev. B 97 (2018), by selecting the dominant contributions of a two-site updated MPS tensor, orthogonal to the original ψ.

Fields

  • trscheme::TensorKit.TruncationScheme: algorithm used for truncating the expanded space
source
MPSKit.PeriodicArrayType
PeriodicArray{T,N} <: AbstractArray{T,N}

Array wrapper with periodic boundary conditions.

Fields

  • data::Array{T,N}: the data of the array

Examples

A = PeriodicArray([1, 2, 3])
+    - An object f that gets multiplied with the operator (Number, function, ...)
source
MPSKit.NaiveInvertType
struct NaiveInvert <: MPSKit.DDMRG_Flavour

An alternative approach to the dynamical DMRG algorithm, without quadratic terms but with a less controlled approximation. This algorithm minimizes the following cost function

\[⟨ψ|(H - E)|ψ⟩ - ⟨ψ|ψ₀⟩ - ⟨ψ₀|ψ⟩\]

which is equivalent to the original approach if

\[|ψ₀⟩ = (H - E)|ψ⟩\]

See also Jeckelmann for the original approach.

source
MPSKit.OptimalExpandType
struct OptimalExpand <: MPSKit.Algorithm

An algorithm that expands the given mps as described in Zauner-Stauber et al. Phys. Rev. B 97 (2018), by selecting the dominant contributions of a two-site updated MPS tensor, orthogonal to the original ψ.

Fields

  • trscheme::TensorKit.TruncationScheme: algorithm used for truncating the expanded space
source
MPSKit.PeriodicArrayType
PeriodicArray{T,N} <: AbstractArray{T,N}

Array wrapper with periodic boundary conditions.

Fields

  • data::Array{T,N}: the data of the array

Examples

A = PeriodicArray([1, 2, 3])
 A[0], A[2], A[4]
 
 # output
@@ -45,37 +45,36 @@
 
 # output
 
-(1, 1, 3)

See also PeriodicVector, PeriodicMatrix

source
MPSKit.QuasiparticleAnsatzType
struct QuasiparticleAnsatz{A} <: MPSKit.Algorithm

Optimization algorithm for quasi-particle excitations on top of MPS groundstates.

Fields

  • alg::Any: algorithm used for the eigenvalue solvers

Constructors

QuasiparticleAnsatz()
+(1, 1, 3)

See also PeriodicVector, PeriodicMatrix

source
MPSKit.QuasiparticleAnsatzType
struct QuasiparticleAnsatz{A} <: MPSKit.Algorithm

Optimization algorithm for quasi-particle excitations on top of MPS groundstates.

Fields

  • alg::Any: algorithm used for the eigenvalue solvers

Constructors

QuasiparticleAnsatz()
 QuasiparticleAnsatz(; kwargs...)
-QuasiparticleAnsatz(alg)

Create a QuasiparticleAnsatz algorithm with the given algorithm, or by passing the keyword arguments to Arnoldi.

References

source
MPSKit.RandExpandType
struct RandExpand <: MPSKit.Algorithm

An algorithm that expands the bond dimension by adding random unitary vectors that are orthogonal to the existing state. This is achieved by performing a truncated SVD on a random two-site MPS tensor, which is made orthogonal to the existing state.

Fields

  • trscheme::TensorKit.TruncationScheme: algorithm used for [truncation](@extref TensorKit.tsvd] the expanded space
source
MPSKit.RightCanonicalType
struct RightCanonical <: MPSKit.Algorithm

Algorithm for bringing an InfiniteMPS into the right-canonical form.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_orth::Any: algorithm used for orthogonalization of the tensors

  • alg_eigsolve::Any: algorithm used for the eigensolver

  • eig_miniter::Int64: minimal amount of iterations before using the eigensolver steps

source
MPSKit.SvdCutType
struct SvdCut <: MPSKit.Algorithm

An algorithm that uses truncated SVD to change the bond dimension of a ψ.

Fields

  • trscheme::TensorKit.TruncationScheme: algorithm used for [truncation][@extref TensorKit.tsvd] of the gauge tensors
source
MPSKit.TDVPType
struct TDVP{A, F} <: MPSKit.Algorithm

Single site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.

Fields

  • integrator::Any: algorithm used in the exponential solvers

  • tolgauge::Float64: tolerance for gauging algorithm

  • gaugemaxiter::Int64: maximal amount of iterations for gauging algorithm

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

References

source
MPSKit.TDVP2Type
struct TDVP2{A, F} <: MPSKit.Algorithm

Two-site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.

Fields

  • integrator::Any: algorithm used in the exponential solvers

  • tolgauge::Float64: tolerance for gauging algorithm

  • gaugemaxiter::Int64: maximal amount of iterations for gauging algorithm

  • trscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

References

source
MPSKit.TaylorClusterType
struct TaylorCluster <: MPSKit.Algorithm

Algorithm for constructing the Nth order time evolution MPO using the Taylor cluster expansion.

Fields

  • N::Int64: order of the Taylor expansion

  • extension::Bool: include higher-order corrections

  • compression::Bool: approximate compression of corrections, accurate up to order N

References

source
MPSKit.RandExpandType
struct RandExpand <: MPSKit.Algorithm

An algorithm that expands the bond dimension by adding random unitary vectors that are orthogonal to the existing state. This is achieved by performing a truncated SVD on a random two-site MPS tensor, which is made orthogonal to the existing state.

Fields

  • trscheme::TensorKit.TruncationScheme: algorithm used for [truncation](@extref TensorKit.tsvd] the expanded space
source
MPSKit.RightCanonicalType
struct RightCanonical <: MPSKit.Algorithm

Algorithm for bringing an InfiniteMPS into the right-canonical form.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_orth::Any: algorithm used for orthogonalization of the tensors

  • alg_eigsolve::Any: algorithm used for the eigensolver

  • eig_miniter::Int64: minimal amount of iterations before using the eigensolver steps

source
MPSKit.SvdCutType
struct SvdCut <: MPSKit.Algorithm

An algorithm that uses truncated SVD to change the bond dimension of a ψ.

Fields

  • trscheme::TensorKit.TruncationScheme: algorithm used for [truncation][@extref TensorKit.tsvd] of the gauge tensors
source
MPSKit.TDVPType
struct TDVP{A, F} <: MPSKit.Algorithm

Single site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.

Fields

  • integrator::Any: algorithm used in the exponential solvers

  • tolgauge::Float64: tolerance for gauging algorithm

  • gaugemaxiter::Int64: maximal amount of iterations for gauging algorithm

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

References

source
MPSKit.TDVP2Type
struct TDVP2{A, F} <: MPSKit.Algorithm

Two-site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.

Fields

  • integrator::Any: algorithm used in the exponential solvers

  • tolgauge::Float64: tolerance for gauging algorithm

  • gaugemaxiter::Int64: maximal amount of iterations for gauging algorithm

  • trscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

References

source
MPSKit.TaylorClusterType
struct TaylorCluster <: MPSKit.Algorithm

Algorithm for constructing the Nth order time evolution MPO using the Taylor cluster expansion.

Fields

  • N::Int64: order of the Taylor expansion

  • extension::Bool: include higher-order corrections

  • compression::Bool: approximate compression of corrections, accurate up to order N

References

source
MPSKit.TimedOperatorType
Structure representing a time-dependent operator. Consists of
     - An operator op (MPO, Hamiltonian, ...)
-    - An function f that gives the time-dependence according to op(t) = f(t)*op
source
MPSKit.UnionAlgType
struct UnionAlg{A, B} <: MPSKit.Algorithm

Algorithm wrapper representing the sequential application of two algorithms.

Fields

  • alg1::Any: first algorithm

  • alg2::Any: second algorithm

source
MPSKit.UntimedOperatorType
Structure representing a time-independent operator that will be multiplied with a constant coefficient. Consists of
+    - An function f that gives the time-dependence according to op(t) = f(t)*op
source
MPSKit.UnionAlgType
struct UnionAlg{A, B} <: MPSKit.Algorithm

Algorithm wrapper representing the sequential application of two algorithms.

Fields

  • alg1::Any: first algorithm

  • alg2::Any: second algorithm

source
MPSKit.UntimedOperatorType
Structure representing a time-independent operator that will be multiplied with a constant coefficient. Consists of
     - An operator (MPO, Hamiltonian, ...)
-    - A number f that gets multiplied with the operator
source
MPSKit.VOMPSType
struct VOMPS{F} <: MPSKit.Algorithm

Power method algorithm for finding dominant eigenvectors of infinite MPOs. This method works by iteratively approximating the product of an operator and a state with a new state of the same bond dimension.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_gauge::Any: algorithm used for gauging the InfiniteMPS

  • alg_environments::Any: algorithm used for the MPS environments

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

References

source
MPSKit.VUMPSType
struct VUMPS{F} <: MPSKit.Algorithm

Variational optimization algorithm for uniform matrix product states, based on the combination of DMRG with matrix product state tangent space concepts.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_gauge::Any: algorithm used for gauging the InfiniteMPS

  • alg_eigsolve::Any: algorithm used for the eigenvalue solvers

  • alg_environments::Any: algorithm used for the MPS environments

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

References

source
MPSKit.VUMPSSvdCutType
struct VUMPSSvdCut <: MPSKit.Algorithm

An algorithm that uses a two-site update step to change the bond dimension of a state.

Fields

  • tol_gauge::Any: tolerance for gauging algorithm

  • tol_eigenval::Any: tolerance for the eigenvalue solver

  • trscheme::TensorKit.TruncationScheme: algorithm used for [truncation][@extref TensorKit.tsvd] of the two-site update

source
MPSKit.WindowArrayType
WindowArray{T} <: AbstractVector{T}

A vector embedded in a periodic environment to the left and right, which can be accessed with arbitrary integer indices. The middle part is a regular Vector{T} and the left and right parts are PeriodicVector{T}s.

This vector inherits most of its properties from the middle part, including its length and axes. Nevertheless, indexing operations are overloaded to allow for out-of-bounds access, which is resolved by the periodic enviroments.

See also PeriodicVector.

source
MPSKit.WindowMPSType
WindowMPS{A<:GenericMPSTensor,B<:MPSBondTensor} <: AbstractFiniteMPS

Type that represents a finite Matrix Product State embedded in an infinte Matrix Product State.

Fields

  • left_gs::InfiniteMPS – left infinite environment
  • window::FiniteMPS – finite window Matrix Product State
  • right_gs::InfiniteMPS – right infinite environment

Constructors

WindowMPS(left_gs::InfiniteMPS, window_state::FiniteMPS, [right_gs::InfiniteMPS])
+    - A number f that gets multiplied with the operator
source
MPSKit.VOMPSType
struct VOMPS{F} <: MPSKit.Algorithm

Power method algorithm for finding dominant eigenvectors of infinite MPOs. This method works by iteratively approximating the product of an operator and a state with a new state of the same bond dimension.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_gauge::Any: algorithm used for gauging the InfiniteMPS

  • alg_environments::Any: algorithm used for the MPS environments

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

References

source
MPSKit.VUMPSType
struct VUMPS{F} <: MPSKit.Algorithm

Variational optimization algorithm for uniform matrix product states, based on the combination of DMRG with matrix product state tangent space concepts.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_gauge::Any: algorithm used for gauging the InfiniteMPS

  • alg_eigsolve::Any: algorithm used for the eigenvalue solvers

  • alg_environments::Any: algorithm used for the MPS environments

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

References

source
MPSKit.VUMPSSvdCutType
struct VUMPSSvdCut <: MPSKit.Algorithm

An algorithm that uses a two-site update step to change the bond dimension of a state.

Fields

  • tol_gauge::Any: tolerance for gauging algorithm

  • tol_eigenval::Any: tolerance for the eigenvalue solver

  • trscheme::TensorKit.TruncationScheme: algorithm used for [truncation][@extref TensorKit.tsvd] of the two-site update

source
MPSKit.WindowArrayType
WindowArray{T} <: AbstractVector{T}

A vector embedded in a periodic environment to the left and right, which can be accessed with arbitrary integer indices. The middle part is a regular Vector{T} and the left and right parts are PeriodicVector{T}s.

This vector inherits most of its properties from the middle part, including its length and axes. Nevertheless, indexing operations are overloaded to allow for out-of-bounds access, which is resolved by the periodic enviroments.

See also PeriodicVector.

source
MPSKit.WindowMPSType
WindowMPS{A<:GenericMPSTensor,B<:MPSBondTensor} <: AbstractFiniteMPS

Type that represents a finite Matrix Product State embedded in an infinte Matrix Product State.

Fields

  • left_gs::InfiniteMPS – left infinite environment
  • window::FiniteMPS – finite window Matrix Product State
  • right_gs::InfiniteMPS – right infinite environment

Constructors

WindowMPS(left_gs::InfiniteMPS, window_state::FiniteMPS, [right_gs::InfiniteMPS])
 WindowMPS(left_gs::InfiniteMPS, window_tensors::AbstractVector, [right_gs::InfiniteMPS])
 WindowMPS([f, eltype], physicalspaces::Vector{<:Union{S, CompositeSpace{S}},
           virtualspaces::Vector{<:Union{S, CompositeSpace{S}}, left_gs::InfiniteMPS,
           [right_gs::InfiniteMPS])
 WindowMPS([f, eltype], physicalspaces::Vector{<:Union{S,CompositeSpace{S}}},
-          maxvirtualspace::S, left_gs::InfiniteMPS, [right_gs::InfiniteMPS])

Construct a WindowMPS via a specification of left and right infinite environment, and either a window state or a vector of tensors to construct the window. Alternatively, it is possible to supply the same arguments as for the constructor of FiniteMPS, followed by a left (and right) environment to construct the WindowMPS in one step.

Note

By default, the right environment is chosen to be equal to the left, however no copy is made. In this case, changing the left state will also affect the right state.

WindowMPS(state::InfiniteMPS, L::Int)

Construct a WindowMPS from an InfiniteMPS, by promoting a region of length L to a FiniteMPS.

source
MPSKit._gaugecenterMethod
_gaugecenter(ψ::FiniteMPS)::HalfInt

Return the location of the MPS center.

center::HalfInt:

  • isinteger(center)center is a whole number and indicates the location of the first AC tensor present in ψ.ACs
  • ishalfodd(center)center is a half-odd-integer, meaning that there are no AC tensors, and indicating between which sites the bond tensor lives.

Example

ψ = FiniteMPS(3, ℂ^2, ℂ^16)
+          maxvirtualspace::S, left_gs::InfiniteMPS, [right_gs::InfiniteMPS])

Construct a WindowMPS via a specification of left and right infinite environment, and either a window state or a vector of tensors to construct the window. Alternatively, it is possible to supply the same arguments as for the constructor of FiniteMPS, followed by a left (and right) environment to construct the WindowMPS in one step.

Note

By default, the right environment is chosen to be equal to the left, however no copy is made. In this case, changing the left state will also affect the right state.

WindowMPS(state::InfiniteMPS, L::Int)

Construct a WindowMPS from an InfiniteMPS, by promoting a region of length L to a FiniteMPS.

source
MPSKit._gaugecenterMethod
_gaugecenter(ψ::FiniteMPS)::HalfInt

Return the location of the MPS center.

center::HalfInt:

  • isinteger(center)center is a whole number and indicates the location of the first AC tensor present in ψ.ACs
  • ishalfodd(center)center is a half-odd-integer, meaning that there are no AC tensors, and indicating between which sites the bond tensor lives.

Example

ψ = FiniteMPS(3, ℂ^2, ℂ^16)
 ψ.center # returns 7/2, bond tensor is to the right of the 3rd site
 ψ.AC[1]   # moves center to first site
-ψ.center # returns 1
source
MPSKit.add_util_legMethod
add_util_leg(tensor::AbstractTensorMap{S,N1,N2}) where {S,N1,N2}
-    -> AbstractTensorMap{S,N1+1,N2+1}

Add trivial one-dimensional utility spaces with trivial sector to the left and right of a given tensor map, i.e. as the first space of the codomain and the last space of the domain.

source
MPSKit.approximateFunction
approximate(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)
-approximate!(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)

Compute an approximation to the application of an operator O to the state ψ in the form of an MPS ψ₀.

Arguments

  • ψ₀::AbstractMPS: initial guess of the approximated state
  • (O::AbstractMPO, ψ::AbstractMPS): operator O and state ψ to be approximated
  • algorithm: approximation algorithm. See below for a list of available algorithms.
  • [environments]: MPS environment manager

Keywords

  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: display progress information

Algorithms

  • DMRG: Alternating least square method for maximizing the fidelity with a single-site scheme.

  • DMRG2: Alternating least square method for maximizing the fidelity with a two-site scheme.

  • IDMRG: Variant of DMRG for maximizing fidelity density in the thermodynamic limit.

  • IDMRG2: Variant of DMRG2 for maximizing fidelity density in the thermodynamic limit.

  • VOMPS: Tangent space method for truncating uniform MPS.

source
MPSKit.approximate!Function
approximate(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)
-approximate!(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)

Compute an approximation to the application of an operator O to the state ψ in the form of an MPS ψ₀.

Arguments

  • ψ₀::AbstractMPS: initial guess of the approximated state
  • (O::AbstractMPO, ψ::AbstractMPS): operator O and state ψ to be approximated
  • algorithm: approximation algorithm. See below for a list of available algorithms.
  • [environments]: MPS environment manager

Keywords

  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: display progress information

Algorithms

  • DMRG: Alternating least square method for maximizing the fidelity with a single-site scheme.

  • DMRG2: Alternating least square method for maximizing the fidelity with a two-site scheme.

  • IDMRG: Variant of DMRG for maximizing fidelity density in the thermodynamic limit.

  • IDMRG2: Variant of DMRG2 for maximizing fidelity density in the thermodynamic limit.

  • VOMPS: Tangent space method for truncating uniform MPS.

source
MPSKit.bond_typeMethod
bond_type(ψ::AbstractMPS)
-bond_type(ψtype::Type{<:AbstractMPS})

Return the type of the bond tensors of an AbstractMPS.

source
MPSKit.calc_galerkinMethod
calc_galerkin(above, operator, below, envs)
-calc_galerkin(pos, above, operator, below, envs)

Calculate the Galerkin error, which is the error between the solution of the original problem, and the solution of the problem projected on the tangent space. Concretely, this is the overlap of the current state with the single-site derivative, projected onto the nullspace of the current state:

\[\epsilon = |VL * (VL' * \frac{above}{\partial AC_{pos}})|\]

source
MPSKit.correlation_lengthMethod
correlation_length(above::InfiniteMPS; kwargs...)

Compute the correlation length of a given InfiniteMPS based on the next-to-leading eigenvalue of the transfer matrix. The kwargs are passed to transfer_spectrum, and can for example be used to target the correlation length in a specific sector.

source
MPSKit.correlatorFunction
correlator(ψ, O1, O2, i, j)
-correlator(ψ, O12, i, j)

Compute the 2-point correlator <ψ|O1[i]O2[j]|ψ> for inserting O1 at i and O2 at j. Also accepts ranges for j.

source
MPSKit.entanglement_spectrumFunction
entanglement_spectrum(ψ, site::Int) -> SectorDict{sectortype(ψ),Vector{<:Real}}

Compute the entanglement spectrum at a given site, i.e. the singular values of the gauge matrix to the right of a given site. This is a dictionary mapping the charge to the singular values.

For InfiniteMPS and WindowMPS the default value for site is 0.

For FiniteMPS no default value for site is given, it is up to the user to specify.

source
MPSKit.entanglementplotFunction
entanglementplot(state; site=0[, kwargs...])

Plot the entanglement spectrum of a given MPS state.

Arguments

  • state: the MPS for which to compute the entanglement spectrum.

Keyword Arguments

  • site::Int=0: MPS index for multisite unit cells. The spectrum is computed for the bond between site and site + 1.
  • expand_symmetry::Logical=false: add quantum dimension degeneracies.
  • sortby=maximum: the method of sorting the sectors.
  • sector_margin=1//10: the amount of whitespace between sectors.
  • sector_formatter=string: how to convert sectors to strings.
  • kwargs...: other kwargs are passed on to the plotting backend.
Note

You will need to manually import Plots.jl to be able to use this function. MPSKit.jl defines its plots based on RecipesBase.jl, but the user still has to add using Plots to be able to actually produce the plots.

source
MPSKit.entropyMethod
entropy(state, [site::Int])

Calculate the Von Neumann entanglement entropy of a given MPS. If an integer site is given, the entropy is across the entanglement cut to the right of site site. Otherwise, a vector of entropies is returned, one for each site.

source
MPSKit.environment_algMethod
environment_alg(above, operator, below; kwargs...)

Determine an appropriate algorithm for computing the environments, based on the given kwargs....

source
MPSKit.add_util_legMethod
add_util_leg(tensor::AbstractTensorMap{S,N1,N2}) where {S,N1,N2}
+    -> AbstractTensorMap{S,N1+1,N2+1}

Add trivial one-dimensional utility spaces with trivial sector to the left and right of a given tensor map, i.e. as the first space of the codomain and the last space of the domain.

source
MPSKit.approximateFunction
approximate(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)
+approximate!(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)

Compute an approximation to the application of an operator O to the state ψ in the form of an MPS ψ₀.

Arguments

  • ψ₀::AbstractMPS: initial guess of the approximated state
  • (O::AbstractMPO, ψ::AbstractMPS): operator O and state ψ to be approximated
  • algorithm: approximation algorithm. See below for a list of available algorithms.
  • [environments]: MPS environment manager

Keywords

  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: display progress information

Algorithms

  • DMRG: Alternating least square method for maximizing the fidelity with a single-site scheme.

  • DMRG2: Alternating least square method for maximizing the fidelity with a two-site scheme.

  • IDMRG: Variant of DMRG for maximizing fidelity density in the thermodynamic limit.

  • IDMRG2: Variant of DMRG2 for maximizing fidelity density in the thermodynamic limit.

  • VOMPS: Tangent space method for truncating uniform MPS.

source
MPSKit.approximate!Function
approximate(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)
+approximate!(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)

Compute an approximation to the application of an operator O to the state ψ in the form of an MPS ψ₀.

Arguments

  • ψ₀::AbstractMPS: initial guess of the approximated state
  • (O::AbstractMPO, ψ::AbstractMPS): operator O and state ψ to be approximated
  • algorithm: approximation algorithm. See below for a list of available algorithms.
  • [environments]: MPS environment manager

Keywords

  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: display progress information

Algorithms

  • DMRG: Alternating least square method for maximizing the fidelity with a single-site scheme.

  • DMRG2: Alternating least square method for maximizing the fidelity with a two-site scheme.

  • IDMRG: Variant of DMRG for maximizing fidelity density in the thermodynamic limit.

  • IDMRG2: Variant of DMRG2 for maximizing fidelity density in the thermodynamic limit.

  • VOMPS: Tangent space method for truncating uniform MPS.

source
MPSKit.bond_typeMethod
bond_type(ψ::AbstractMPS)
+bond_type(ψtype::Type{<:AbstractMPS})

Return the type of the bond tensors of an AbstractMPS.

source
MPSKit.calc_galerkinMethod
calc_galerkin(above, operator, below, envs)
+calc_galerkin(pos, above, operator, below, envs)

Calculate the Galerkin error, which is the error between the solution of the original problem, and the solution of the problem projected on the tangent space. Concretely, this is the overlap of the current state with the single-site derivative, projected onto the nullspace of the current state:

\[\epsilon = |VL * (VL' * \frac{above}{\partial AC_{pos}})|\]

source
MPSKit.correlation_lengthMethod
correlation_length(above::InfiniteMPS; kwargs...)

Compute the correlation length of a given InfiniteMPS based on the next-to-leading eigenvalue of the transfer matrix. The kwargs are passed to transfer_spectrum, and can for example be used to target the correlation length in a specific sector.

source
MPSKit.correlatorFunction
correlator(ψ, O1, O2, i, j)
+correlator(ψ, O12, i, j)

Compute the 2-point correlator <ψ|O1[i]O2[j]|ψ> for inserting O1 at i and O2 at j. Also accepts ranges for j.

source
MPSKit.entanglement_spectrumFunction
entanglement_spectrum(ψ, site::Int) -> SectorDict{sectortype(ψ),Vector{<:Real}}

Compute the entanglement spectrum at a given site, i.e. the singular values of the gauge matrix to the right of a given site. This is a dictionary mapping the charge to the singular values.

For InfiniteMPS and WindowMPS the default value for site is 0.

For FiniteMPS no default value for site is given, it is up to the user to specify.

source
MPSKit.entanglementplotFunction
entanglementplot(state; site=0[, kwargs...])

Plot the entanglement spectrum of a given MPS state.

Arguments

  • state: the MPS for which to compute the entanglement spectrum.

Keyword Arguments

  • site::Int=0: MPS index for multisite unit cells. The spectrum is computed for the bond between site and site + 1.
  • expand_symmetry::Logical=false: add quantum dimension degeneracies.
  • sortby=maximum: the method of sorting the sectors.
  • sector_margin=1//10: the amount of whitespace between sectors.
  • sector_formatter=string: how to convert sectors to strings.
  • kwargs...: other kwargs are passed on to the plotting backend.
Note

You will need to manually import Plots.jl to be able to use this function. MPSKit.jl defines its plots based on RecipesBase.jl, but the user still has to add using Plots to be able to actually produce the plots.

source
MPSKit.entropyMethod
entropy(state, [site::Int])

Calculate the Von Neumann entanglement entropy of a given MPS. If an integer site is given, the entropy is across the entanglement cut to the right of site site. Otherwise, a vector of entropies is returned, one for each site.

source
MPSKit.environment_algMethod
environment_alg(above, operator, below; kwargs...)

Determine an appropriate algorithm for computing the environments, based on the given kwargs....

source
MPSKit.exact_diagonalizationMethod
exact_diagonalization(H::FiniteMPOHamiltonian;
                       sector=first(sectors(oneunit(physicalspace(H, 1)))),
                       len::Int=length(H), num::Int=1, which::Symbol=:SR,
                       alg=Defaults.alg_eigsolve(; dynamic_tols=false))
-                        -> vals, state_vecs, convhist

Use KrylovKit.eigsolve to perform exact diagonalization on a FiniteMPOHamiltonian to find its eigenvectors as FiniteMPS of maximal rank, essentially equivalent to dense eigenvectors.

Arguments

  • H::FiniteMPOHamiltonian: the Hamiltonian to diagonalize.

Keyword arguments

  • sector=first(sectors(oneunit(physicalspace(H, 1)))): the total charge of the eigenvectors, which is chosen trivial by default.
  • len::Int=length(H): the length of the system.
  • num::Int=1: the number of eigenvectors to find.
  • which::Symbol=:SR: the kind eigenvalues to find, see KrylovKit.eigsolve.
  • alg=Defaults.alg_eigsolve(; dynamic_tols=false): the diagonalization algorithm to use, see KrylovKit.eigsolve.
Valid `sector` values

The total charge of the eigenvectors is imposed by adding a charged auxiliary space as the leftmost virtualspace of each eigenvector. Specifically, this is achieved by passing left=Vect[typeof(sector)](sector => 1) to the FiniteMPS constructor. As such, the only valid sector values (i.e. sector values for which the corresponding eigenstates have valid fusion channels) are those that occur in the dual of the fusion of all the physical spaces in the system.

source
MPSKit.excitationsFunction
excitations(H, algorithm::QuasiparticleAnsatz, momentum::Union{Number, Vector{<:Number}},
+                        -> vals, state_vecs, convhist

Use KrylovKit.eigsolve to perform exact diagonalization on a FiniteMPOHamiltonian to find its eigenvectors as FiniteMPS of maximal rank, essentially equivalent to dense eigenvectors.

Arguments

  • H::FiniteMPOHamiltonian: the Hamiltonian to diagonalize.

Keyword arguments

  • sector=first(sectors(oneunit(physicalspace(H, 1)))): the total charge of the eigenvectors, which is chosen trivial by default.
  • len::Int=length(H): the length of the system.
  • num::Int=1: the number of eigenvectors to find.
  • which::Symbol=:SR: the kind eigenvalues to find, see KrylovKit.eigsolve.
  • alg=Defaults.alg_eigsolve(; dynamic_tols=false): the diagonalization algorithm to use, see KrylovKit.eigsolve.
Valid `sector` values

The total charge of the eigenvectors is imposed by adding a charged auxiliary space as the leftmost virtualspace of each eigenvector. Specifically, this is achieved by passing left=Vect[typeof(sector)](sector => 1) to the FiniteMPS constructor. As such, the only valid sector values (i.e. sector values for which the corresponding eigenstates have valid fusion channels) are those that occur in the dual of the fusion of all the physical spaces in the system.

source
MPSKit.excitationsFunction
excitations(H, algorithm::QuasiparticleAnsatz, momentum::Union{Number, Vector{<:Number}},
             left_ψ::InfiniteMPS, [left_environment],
             [right_ψ::InfiniteMPS], [right_environment];
-            kwargs...)

Create and optimise infinite quasiparticle states.

Arguments

  • H::AbstractMPO: operator for which to find the excitations
  • algorithm::QuasiparticleAnsatz: optimization algorithm
  • momentum::Union{Number, Vector{<:Number}}: momentum or list of momenta
  • left_ψ::InfiniteMPS: left groundstate
  • [left_environment]: left groundstate environment
  • [right_ψ::InfiniteMPS]: right groundstate
  • [right_environment]: right groundstate environment

Keywords

  • num::Int: number of excited states to compute
  • solver: algorithm for the linear solver of the quasiparticle environments
  • sector=one(sectortype(left_ψ)): charge of the quasiparticle state
  • parallel=true: enable multi-threading over different momenta
source
MPSKit.excitationsFunction
excitations(H, algorithm::QuasiparticleAnsatz, left_ψ::InfiniteMPS, [left_environment],
-            [right_ψ::InfiniteMPS], [right_environment]; kwargs...)

Create and optimise finite quasiparticle states.

Arguments

  • H::AbstractMPO: operator for which to find the excitations
  • algorithm::QuasiparticleAnsatz: optimization algorithm
  • left_ψ::FiniteMPS: left groundstate
  • [left_environment]: left groundstate environment
  • [right_ψ::FiniteMPS]: right groundstate
  • [right_environment]: right groundstate environment

Keywords

  • num::Int: number of excited states to compute
  • sector=one(sectortype(left_ψ)): charge of the quasiparticle state
source
MPSKit.excitationsFunction
excitations(H, algorithm::QuasiparticleAnsatz, ψ::FiniteQP, [left_environments],
+            kwargs...)

Create and optimise infinite quasiparticle states.

Arguments

  • H::AbstractMPO: operator for which to find the excitations
  • algorithm::QuasiparticleAnsatz: optimization algorithm
  • momentum::Union{Number, Vector{<:Number}}: momentum or list of momenta
  • left_ψ::InfiniteMPS: left groundstate
  • [left_environment]: left groundstate environment
  • [right_ψ::InfiniteMPS]: right groundstate
  • [right_environment]: right groundstate environment

Keywords

  • num::Int: number of excited states to compute
  • solver: algorithm for the linear solver of the quasiparticle environments
  • sector=one(sectortype(left_ψ)): charge of the quasiparticle state
  • parallel=true: enable multi-threading over different momenta
source
MPSKit.excitationsFunction
excitations(H, algorithm::QuasiparticleAnsatz, ψ::FiniteQP, [left_environments],
             [right_environments]; num=1) -> (energies, states)
 excitations(H, algorithm::QuasiparticleAnsatz, ψ::InfiniteQP, [left_environments],
             [right_environments]; num=1, solver=Defaults.solver) -> (energies, states)
@@ -84,7 +83,8 @@
 excitations(H, algorithm::ChepigaAnsatz, ψ::FiniteMPS, [envs];
             num=1, pos=length(ψ)÷2) -> (energies, states)
 excitations(H, algorithm::ChepigaAnsatz2, ψ::FiniteMPS, [envs];
-            num=1, pos=length(ψ)÷2) -> (energies, states)

Compute the first excited states and their energy gap above a groundstate.

Arguments

  • H::AbstractMPO: operator for which to find the excitations
  • algorithm: optimization algorithm
  • ψ::QP: initial quasiparticle guess
  • ψs::NTuple{N, <:FiniteMPS}: N first excited states
  • [left_environments]: left groundstate environment
  • [right_environments]: right groundstate environment

Keywords

  • num::Int: number of excited states to compute
  • solver: algorithm for the linear solver of the quasiparticle environments
  • init: initial excited state guess
  • pos: position of perturbation
source
MPSKit.expectation_valueFunction
expectation_value(ψ, O, [environments])
+            num=1, pos=length(ψ)÷2) -> (energies, states)

Compute the first excited states and their energy gap above a groundstate.

Arguments

  • H::AbstractMPO: operator for which to find the excitations
  • algorithm: optimization algorithm
  • ψ::QP: initial quasiparticle guess
  • ψs::NTuple{N, <:FiniteMPS}: N first excited states
  • [left_environments]: left groundstate environment
  • [right_environments]: right groundstate environment

Keywords

  • num::Int: number of excited states to compute
  • solver: algorithm for the linear solver of the quasiparticle environments
  • init: initial excited state guess
  • pos: position of perturbation
source
MPSKit.excitationsFunction
excitations(H, algorithm::QuasiparticleAnsatz, left_ψ::InfiniteMPS, [left_environment],
+            [right_ψ::InfiniteMPS], [right_environment]; kwargs...)

Create and optimise finite quasiparticle states.

Arguments

  • H::AbstractMPO: operator for which to find the excitations
  • algorithm::QuasiparticleAnsatz: optimization algorithm
  • left_ψ::FiniteMPS: left groundstate
  • [left_environment]: left groundstate environment
  • [right_ψ::FiniteMPS]: right groundstate
  • [right_environment]: right groundstate environment

Keywords

  • num::Int: number of excited states to compute
  • sector=one(sectortype(left_ψ)): charge of the quasiparticle state
source
MPSKit.expectation_valueFunction
expectation_value(ψ, O, [environments])
 expectation_value(ψ, inds => O)

Compute the expectation value of an operator O on a state ψ. Optionally, it is possible to make the computations more efficient by also passing in previously calculated environments.

In general, the operator O may consist of an arbitrary MPO O <: AbstractMPO that acts on all sites, or a local operator O = inds => operator acting on a subset of sites. In the latter case, inds is a tuple of indices that specify the sites on which the operator acts, while the operator is either a AbstractTensorMap or a FiniteMPO.

Arguments

  • ψ::AbstractMPS : the state on which to compute the expectation value
  • O::Union{AbstractMPO,Pair} : the operator to compute the expectation value of. This can either be an AbstractMPO, or a pair of indices and local operator..
  • environments::AbstractMPSEnvironments : the environments to use for the calculation. If not given, they will be calculated.

Examples

julia> ψ = FiniteMPS(ones(Float64, (ℂ^2)^4));
 
 julia> S_x = TensorMap(Float64[0 1; 1 0], ℂ^2, ℂ^2);
@@ -93,22 +93,22 @@
 1.0
 
 julia> round(expectation_value(ψ, (2, 3) => S_x ⊗ S_x))
-1.0
source
MPSKit.fidelity_susceptibilityMethod
fidelity_susceptibility(state::Union{FiniteMPS,InfiniteMPS}, H₀::T,
                         Vs::AbstractVector{T}, [henvs=environments(state, H₀)];
                         maxiter=Defaults.maxiter,
-                        tol=Defaults.tol) where {T<:MPOHamiltonian}

Computes the fidelity susceptibility of a the ground state state of a base Hamiltonian H₀ with respect to a set of perturbing Hamiltonians Vs. Each of the perturbing Hamiltonians can be interpreted as corresponding to a tuning parameter $aᵢ$ in a 'total' Hamiltonian $H = H₀ + ∑ᵢ aᵢ Vᵢ$.

Returns a matrix containing the overlaps of the elementary excitations on top of state corresponding to each of the perturbing Hamiltonians.

source
MPSKit.find_groundstateFunction
find_groundstate(ψ₀, H, [environments]; kwargs...) -> (ψ, environments, ϵ)
-find_groundstate(ψ₀, H, algorithm, environments) -> (ψ, environments, ϵ)

Compute the groundstate for Hamiltonian H with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.

Arguments

  • ψ₀::AbstractMPS: initial guess
  • H::AbstractMPO: operator for which to find the groundstate
  • [environments]: MPS environment manager
  • algorithm: optimization algorithm

Keywords

  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: display progress information

Returns

  • ψ::AbstractMPS: converged groundstate
  • environments: environments corresponding to the converged state
  • ϵ::Float64: final convergence error upon terminating the algorithm
source
MPSKit.fixedpointMethod
fixedpoint(A, x₀, which::Symbol; kwargs...) -> val, vec
-fixedpoint(A, x₀, which::Symbol, alg) -> val, vec

Compute the fixedpoint of a linear operator A using the specified eigensolver alg. The fixedpoint is assumed to be unique.

source
MPSKit.gaugefix!Function
gaugefix!(ψ::InfiniteMPS, A, C₀; kwargs...) -> ψ
-gaugefix!(ψ::InfiniteMPS, A, C₀, alg::Algorithm) -> ψ

Bring an InfiniteMPS into a uniform gauge, using the specified algorithm.

source
MPSKit.instantiate_operatorMethod
instantiate_operator(lattice::AbstractArray{<:VectorSpace}, O::Pair)

Instantiate a local operator O on a lattice lattice as a vector of MPO tensors, and a vector of linear site indices.

source
MPSKit.integrateFunction
integrate(f, y₀, t, dt, alg)

Integrate the differential equation $i dy/dt = f(y, t)$ over a time step 'dt' starting from $y(t₀)=y₀$, using the provided algorithm.

Arguments

  • f: driving function
  • y₀: object to integrate
  • t::Number: starting time of time-step
  • dt::Number: time-step magnitude
  • alg: integration scheme
source
MPSKit.isfullrankMethod
isfullrank(A::GenericMPSTensor; side=:both)

Determine whether the given tensor is full rank, i.e. whether both the map from the left virtual space and the physical space to the right virtual space, and the map from the right virtual space and the physical space to the left virtual space are injective.

source
MPSKit.l_LLMethod
l_LL(ψ, location)

Left dominant eigenvector of the AL-AL transfermatrix.

source
MPSKit.l_LRFunction
l_LR(ψ, location)

Left dominant eigenvector of the AL-AR transfermatrix.

source
MPSKit.l_RLFunction
l_RL(ψ, location)

Left dominant eigenvector of the AR-AL transfermatrix.

source
MPSKit.l_RRFunction
l_RR(ψ, location)

Left dominant eigenvector of the AR-AR transfermatrix.

source
MPSKit.leading_boundaryFunction
leading_boundary(ψ₀, O, [environments]; kwargs...) -> (ψ, environments, ϵ)
-leading_boundary(ψ₀, O, algorithm, environments) -> (ψ, environments, ϵ)

Compute the leading boundary MPS for operator O with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.

Arguments

  • ψ₀::AbstractMPS: initial guess
  • O::AbstractMPO: operator for which to find the leading_boundary
  • [environments]: MPS environment manager
  • algorithm: optimization algorithm

Keywords

  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: display progress information

Returns

  • ψ::AbstractMPS: converged leading boundary MPS
  • environments: environments corresponding to the converged boundary
  • ϵ::Float64: final convergence error upon terminating the algorithm
source
MPSKit.left_virtualspaceFunction
left_virtualspace(ψ::AbstractMPS, [pos=1:length(ψ)])

Return the virtual space of the bond to the left of sites pos.

Warning

In rare cases, the gauge tensor on the virtual space might not be square, and as a result it cannot always be guaranteed that right_virtualspace(ψ, i - 1) == left_virtualspace(ψ, i)

source
MPSKit.make_time_mpoFunction
make_time_mpo(H::MPOHamiltonian, dt::Number, alg) -> O::MPO

Construct an MPO that approximates $\exp(-iHdt)$.

source
MPSKit.makefullrank!Method
makefullrank!(A::PeriodicVector{<:GenericMPSTensor}; alg=QRpos())

Make the set of MPS tensors full rank by performing a series of orthogonalizations.

source
MPSKit.marek_gapMethod

Given an InfiniteMPS, compute the gap ϵ for the asymptotics of the transfer matrix, as well as the Marek gap δ as a scaling measure of the bond dimension.

source
MPSKit.max_DsMethod
max_Ds(ψ::FiniteMPS) -> Vector{Float64}

Compute the dimension of the maximal virtual space at a given site.

source
MPSKit.open_boundary_conditionsFunction
open_boundary_conditions(mpo::InfiniteMPOHamiltonian, L::Int) -> FiniteMPOHamiltonian

Convert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.

source
MPSKit.open_boundary_conditionsMethod
open_boundary_conditions(mpo::InfiniteMPO, L::Int) -> FiniteMPO

Convert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.

source
MPSKit.periodic_boundary_conditionsMethod
periodic_boundary_conditions(mpo::AbstractInfiniteMPO, L::Int)

Convert an infinite MPO into a finite MPO of length L, by mapping periodic boundary conditions onto an open system.

source
MPSKit.physicalspaceFunction
physicalspace(ψ::AbstractMPS, [pos=1:length(ψ)])

Return the physical space of the site tensor at site i.

source
MPSKit.propagatorFunction
propagator(ψ₀::AbstractFiniteMPS, z::Number, H::MPOHamiltonian, alg::DynamicalDMRG; init=copy(ψ₀))

Calculate the propagator $\frac{1}{E₀ + z - H}|ψ₀⟩$ using the dynamical DMRG algorithm.

source
MPSKit.r_LLFunction
r_LL(ψ, location)

Right dominant eigenvector of the AL-AL transfermatrix.

source
MPSKit.r_LRFunction
r_LR(ψ, location)

Right dominant eigenvector of the AL-AR transfermatrix.

source
MPSKit.r_RLFunction
r_RL(ψ, location)

Right dominant eigenvector of the AR-AL transfermatrix.

source
MPSKit.r_RRMethod
r_RR(ψ, location)

Right dominant eigenvector of the AR-AR transfermatrix.

source
MPSKit.regauge!Function
regauge!(AC::GenericMPSTensor, C::MPSBondTensor; alg=QRpos()) -> AL
-regauge!(CL::MPSBondTensor, AC::GenericMPSTensor; alg=LQpos()) -> AR

Bring updated AC and C tensors back into a consistent set of left or right canonical tensors. This minimizes ∥AC_i - AL_i * C_i∥ or ∥AC_i - C_{i-1} * AR_i∥. The optimal algorithm uses Polar() decompositions, but QR-based algorithms are typically more performant. Note that the first signature is slightly faster, as it avoids an intermediate transposition.

source
MPSKit.right_virtualspaceFunction
right_virtualspace(ψ::AbstractMPS, [pos=1:length(ψ)])

Return the virtual space of the bond to the right of site(s) pos.

Warning

In rare cases, the gauge tensor on the virtual space might not be square, and as a result it cannot always be guaranteed that right_virtualspace(ψ, i - 1) == left_virtualspace(ψ, i)

source
MPSKit.site_typeMethod
site_type(ψ::AbstractMPS)
-site_type(ψtype::Type{<:AbstractMPS})

Return the type of the site tensors of an AbstractMPS.

source
MPSKit.tensorexprMethod
tensorexpr(name, ind_out, [ind_in])

Generates expressions for use within @tensor environments of the form name[ind_out...; ind_in].

source
MPSKit.time_evolveFunction
time_evolve(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ, envs)
-time_evolve!(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ₀, envs)

Time-evolve the initial state ψ₀ with Hamiltonian H over a given time span by stepping through each of the time points obtained by iterating t_span.

Arguments

  • ψ₀::AbstractMPS: initial state
  • H::AbstractMPO: operator that generates the time evolution (can be time-dependent).
  • t_span::AbstractVector{<:Number}: time points over which the time evolution is stepped
  • [alg]: algorithm to use for the time evolution. Defaults to TDVP.
  • [envs]: MPS environment manager
source
MPSKit.time_evolve!Function
time_evolve(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ, envs)
-time_evolve!(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ₀, envs)

Time-evolve the initial state ψ₀ with Hamiltonian H over a given time span by stepping through each of the time points obtained by iterating t_span.

Arguments

  • ψ₀::AbstractMPS: initial state
  • H::AbstractMPO: operator that generates the time evolution (can be time-dependent).
  • t_span::AbstractVector{<:Number}: time points over which the time evolution is stepped
  • [alg]: algorithm to use for the time evolution. Defaults to TDVP.
  • [envs]: MPS environment manager
source
MPSKit.timestepFunction
timestep(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ, envs)
-timestep!(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ₀, envs)

Time-step the state ψ₀ with Hamiltonian H over a given time step dt at time t, solving the Schroedinger equation: $i ∂ψ/∂t = H ψ$.

Arguments

  • ψ₀::AbstractMPS: initial state
  • H::AbstractMPO: operator that generates the time evolution (can be time-dependent).
  • t::Number: starting time of time-step
  • dt::Number: time-step magnitude
  • [alg]: algorithm to use for the time evolution. Defaults to TDVP.
  • [envs]: MPS environment manager
source
MPSKit.timestep!Function
timestep(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ, envs)
-timestep!(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ₀, envs)

Time-step the state ψ₀ with Hamiltonian H over a given time step dt at time t, solving the Schroedinger equation: $i ∂ψ/∂t = H ψ$.

Arguments

  • ψ₀::AbstractMPS: initial state
  • H::AbstractMPO: operator that generates the time evolution (can be time-dependent).
  • t::Number: starting time of time-step
  • dt::Number: time-step magnitude
  • [alg]: algorithm to use for the time evolution. Defaults to TDVP.
  • [envs]: MPS environment manager
source
MPSKit.transfer_leftMethod
transfer_left(v, A, Ā)

apply a transfer matrix to the left.

 ┌─A─
+                        tol=Defaults.tol) where {T<:MPOHamiltonian}

Computes the fidelity susceptibility of a the ground state state of a base Hamiltonian H₀ with respect to a set of perturbing Hamiltonians Vs. Each of the perturbing Hamiltonians can be interpreted as corresponding to a tuning parameter $aᵢ$ in a 'total' Hamiltonian $H = H₀ + ∑ᵢ aᵢ Vᵢ$.

Returns a matrix containing the overlaps of the elementary excitations on top of state corresponding to each of the perturbing Hamiltonians.

source
MPSKit.find_groundstateFunction
find_groundstate(ψ₀, H, [environments]; kwargs...) -> (ψ, environments, ϵ)
+find_groundstate(ψ₀, H, algorithm, environments) -> (ψ, environments, ϵ)

Compute the groundstate for Hamiltonian H with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.

Arguments

  • ψ₀::AbstractMPS: initial guess
  • H::AbstractMPO: operator for which to find the groundstate
  • [environments]: MPS environment manager
  • algorithm: optimization algorithm

Keywords

  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: display progress information

Returns

  • ψ::AbstractMPS: converged groundstate
  • environments: environments corresponding to the converged state
  • ϵ::Float64: final convergence error upon terminating the algorithm
source
MPSKit.fixedpointMethod
fixedpoint(A, x₀, which::Symbol; kwargs...) -> val, vec
+fixedpoint(A, x₀, which::Symbol, alg) -> val, vec

Compute the fixedpoint of a linear operator A using the specified eigensolver alg. The fixedpoint is assumed to be unique.

source
MPSKit.gaugefix!Function
gaugefix!(ψ::InfiniteMPS, A, C₀; kwargs...) -> ψ
+gaugefix!(ψ::InfiniteMPS, A, C₀, alg::Algorithm) -> ψ

Bring an InfiniteMPS into a uniform gauge, using the specified algorithm.

source
MPSKit.instantiate_operatorMethod
instantiate_operator(lattice::AbstractArray{<:VectorSpace}, O::Pair)

Instantiate a local operator O on a lattice lattice as a vector of MPO tensors, and a vector of linear site indices.

source
MPSKit.integrateFunction
integrate(f, y₀, t, dt, alg)

Integrate the differential equation $i dy/dt = f(y, t)$ over a time step 'dt' starting from $y(t₀)=y₀$, using the provided algorithm.

Arguments

  • f: driving function
  • y₀: object to integrate
  • t::Number: starting time of time-step
  • dt::Number: time-step magnitude
  • alg: integration scheme
source
MPSKit.isfullrankMethod
isfullrank(A::GenericMPSTensor; side=:both)

Determine whether the given tensor is full rank, i.e. whether both the map from the left virtual space and the physical space to the right virtual space, and the map from the right virtual space and the physical space to the left virtual space are injective.

source
MPSKit.l_LLMethod
l_LL(ψ, location)

Left dominant eigenvector of the AL-AL transfermatrix.

source
MPSKit.l_LRFunction
l_LR(ψ, location)

Left dominant eigenvector of the AL-AR transfermatrix.

source
MPSKit.l_RLFunction
l_RL(ψ, location)

Left dominant eigenvector of the AR-AL transfermatrix.

source
MPSKit.l_RRFunction
l_RR(ψ, location)

Left dominant eigenvector of the AR-AR transfermatrix.

source
MPSKit.leading_boundaryFunction
leading_boundary(ψ₀, O, [environments]; kwargs...) -> (ψ, environments, ϵ)
+leading_boundary(ψ₀, O, algorithm, environments) -> (ψ, environments, ϵ)

Compute the leading boundary MPS for operator O with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.

Arguments

  • ψ₀::AbstractMPS: initial guess
  • O::AbstractMPO: operator for which to find the leading_boundary
  • [environments]: MPS environment manager
  • algorithm: optimization algorithm

Keywords

  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: display progress information

Returns

  • ψ::AbstractMPS: converged leading boundary MPS
  • environments: environments corresponding to the converged boundary
  • ϵ::Float64: final convergence error upon terminating the algorithm
source
MPSKit.left_virtualspaceFunction
left_virtualspace(ψ::AbstractMPS, [pos=1:length(ψ)])

Return the virtual space of the bond to the left of sites pos.

Warning

In rare cases, the gauge tensor on the virtual space might not be square, and as a result it cannot always be guaranteed that right_virtualspace(ψ, i - 1) == left_virtualspace(ψ, i)

source
MPSKit.make_time_mpoFunction
make_time_mpo(H::MPOHamiltonian, dt::Number, alg) -> O::MPO

Construct an MPO that approximates $\exp(-iHdt)$.

source
MPSKit.makefullrank!Method
makefullrank!(A::PeriodicVector{<:GenericMPSTensor}; alg=QRpos())

Make the set of MPS tensors full rank by performing a series of orthogonalizations.

source
MPSKit.marek_gapMethod

Given an InfiniteMPS, compute the gap ϵ for the asymptotics of the transfer matrix, as well as the Marek gap δ as a scaling measure of the bond dimension.

source
MPSKit.max_DsMethod
max_Ds(ψ::FiniteMPS) -> Vector{Float64}

Compute the dimension of the maximal virtual space at a given site.

source
MPSKit.open_boundary_conditionsFunction
open_boundary_conditions(mpo::InfiniteMPOHamiltonian, L::Int) -> FiniteMPOHamiltonian

Convert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.

source
MPSKit.open_boundary_conditionsMethod
open_boundary_conditions(mpo::InfiniteMPO, L::Int) -> FiniteMPO

Convert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.

source
MPSKit.periodic_boundary_conditionsMethod
periodic_boundary_conditions(mpo::AbstractInfiniteMPO, L::Int)

Convert an infinite MPO into a finite MPO of length L, by mapping periodic boundary conditions onto an open system.

source
MPSKit.physicalspaceFunction
physicalspace(ψ::AbstractMPS, [pos=1:length(ψ)])

Return the physical space of the site tensor at site i.

source
MPSKit.propagatorFunction
propagator(ψ₀::AbstractFiniteMPS, z::Number, H::MPOHamiltonian, alg::DynamicalDMRG; init=copy(ψ₀))

Calculate the propagator $\frac{1}{E₀ + z - H}|ψ₀⟩$ using the dynamical DMRG algorithm.

source
MPSKit.r_LLFunction
r_LL(ψ, location)

Right dominant eigenvector of the AL-AL transfermatrix.

source
MPSKit.r_LRFunction
r_LR(ψ, location)

Right dominant eigenvector of the AL-AR transfermatrix.

source
MPSKit.r_RLFunction
r_RL(ψ, location)

Right dominant eigenvector of the AR-AL transfermatrix.

source
MPSKit.r_RRMethod
r_RR(ψ, location)

Right dominant eigenvector of the AR-AR transfermatrix.

source
MPSKit.regauge!Function
regauge!(AC::GenericMPSTensor, C::MPSBondTensor; alg=QRpos()) -> AL
+regauge!(CL::MPSBondTensor, AC::GenericMPSTensor; alg=LQpos()) -> AR

Bring updated AC and C tensors back into a consistent set of left or right canonical tensors. This minimizes ∥AC_i - AL_i * C_i∥ or ∥AC_i - C_{i-1} * AR_i∥. The optimal algorithm uses Polar() decompositions, but QR-based algorithms are typically more performant. Note that the first signature is slightly faster, as it avoids an intermediate transposition.

source
MPSKit.right_virtualspaceFunction
right_virtualspace(ψ::AbstractMPS, [pos=1:length(ψ)])

Return the virtual space of the bond to the right of site(s) pos.

Warning

In rare cases, the gauge tensor on the virtual space might not be square, and as a result it cannot always be guaranteed that right_virtualspace(ψ, i - 1) == left_virtualspace(ψ, i)

source
MPSKit.site_typeMethod
site_type(ψ::AbstractMPS)
+site_type(ψtype::Type{<:AbstractMPS})

Return the type of the site tensors of an AbstractMPS.

source
MPSKit.tensorexprMethod
tensorexpr(name, ind_out, [ind_in])

Generates expressions for use within @tensor environments of the form name[ind_out...; ind_in].

source
MPSKit.time_evolveFunction
time_evolve(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ, envs)
+time_evolve!(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ₀, envs)

Time-evolve the initial state ψ₀ with Hamiltonian H over a given time span by stepping through each of the time points obtained by iterating t_span.

Arguments

  • ψ₀::AbstractMPS: initial state
  • H::AbstractMPO: operator that generates the time evolution (can be time-dependent).
  • t_span::AbstractVector{<:Number}: time points over which the time evolution is stepped
  • [alg]: algorithm to use for the time evolution. Defaults to TDVP.
  • [envs]: MPS environment manager
source
MPSKit.time_evolve!Function
time_evolve(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ, envs)
+time_evolve!(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ₀, envs)

Time-evolve the initial state ψ₀ with Hamiltonian H over a given time span by stepping through each of the time points obtained by iterating t_span.

Arguments

  • ψ₀::AbstractMPS: initial state
  • H::AbstractMPO: operator that generates the time evolution (can be time-dependent).
  • t_span::AbstractVector{<:Number}: time points over which the time evolution is stepped
  • [alg]: algorithm to use for the time evolution. Defaults to TDVP.
  • [envs]: MPS environment manager
source
MPSKit.timestepFunction
timestep(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ, envs)
+timestep!(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ₀, envs)

Time-step the state ψ₀ with Hamiltonian H over a given time step dt at time t, solving the Schroedinger equation: $i ∂ψ/∂t = H ψ$.

Arguments

  • ψ₀::AbstractMPS: initial state
  • H::AbstractMPO: operator that generates the time evolution (can be time-dependent).
  • t::Number: starting time of time-step
  • dt::Number: time-step magnitude
  • [alg]: algorithm to use for the time evolution. Defaults to TDVP.
  • [envs]: MPS environment manager
source
MPSKit.timestep!Function
timestep(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ, envs)
+timestep!(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ₀, envs)

Time-step the state ψ₀ with Hamiltonian H over a given time step dt at time t, solving the Schroedinger equation: $i ∂ψ/∂t = H ψ$.

Arguments

  • ψ₀::AbstractMPS: initial state
  • H::AbstractMPO: operator that generates the time evolution (can be time-dependent).
  • t::Number: starting time of time-step
  • dt::Number: time-step magnitude
  • [alg]: algorithm to use for the time evolution. Defaults to TDVP.
  • [envs]: MPS environment manager
source
MPSKit.transfer_leftMethod
transfer_left(v, A, Ā)

apply a transfer matrix to the left.

 ┌─A─
 -v │
- └─Ā─
source
MPSKit.transfer_spectrumMethod
transfer_spectrum(above::InfiniteMPS; below=above, tol=Defaults.tol, num_vals=20,
-                       sector=first(sectors(oneunit(left_virtualspace(above, 1)))))

Calculate the partial spectrum of the left mixed transfer matrix corresponding to the overlap of a given above state and a below state. The sector keyword argument can be used to specify a non-trivial total charge for the transfer matrix eigenvectors. Specifically, an auxiliary space ℂ[typeof(sector)](sector => 1)' will be added to the domain of each eigenvector. The tol and num_vals keyword arguments are passed to KrylovKit.eigolve

source
MPSKit.transferplotFunction
transferplot(above, below=above; sectors=[], transferkwargs=(;)[, kwargs...])

Plot the partial transfer matrix spectrum of two InfiniteMPS's.

Arguments

Keyword Arguments

  • sectors=[]: vector of sectors for which to compute the spectrum.
  • transferkwargs: kwargs for call to transfer_spectrum.
  • kwargs: other kwargs are passed on to the plotting backend.
  • thetaorigin=0: origin of the angle range.
  • sector_formatter=string: how to convert sectors to strings.
Note

You will need to manually import Plots.jl to be able to use this function. MPSKit.jl defines its plots based on RecipesBase.jl, but the user still has to add using Plots to be able to actually produce the plots.

source
MPSKit.varianceFunction
variance(state, hamiltonian, [envs=environments(state, hamiltonian)])

Compute the variance of the energy of the state with respect to the hamiltonian.

source
+─Ā─┘
source
MPSKit.transfer_spectrumMethod
transfer_spectrum(above::InfiniteMPS; below=above, tol=Defaults.tol, num_vals=20,
+                       sector=first(sectors(oneunit(left_virtualspace(above, 1)))))

Calculate the partial spectrum of the left mixed transfer matrix corresponding to the overlap of a given above state and a below state. The sector keyword argument can be used to specify a non-trivial total charge for the transfer matrix eigenvectors. Specifically, an auxiliary space ℂ[typeof(sector)](sector => 1)' will be added to the domain of each eigenvector. The tol and num_vals keyword arguments are passed to KrylovKit.eigolve

source
MPSKit.transferplotFunction
transferplot(above, below=above; sectors=[], transferkwargs=(;)[, kwargs...])

Plot the partial transfer matrix spectrum of two InfiniteMPS's.

Arguments

Keyword Arguments

  • sectors=[]: vector of sectors for which to compute the spectrum.
  • transferkwargs: kwargs for call to transfer_spectrum.
  • kwargs: other kwargs are passed on to the plotting backend.
  • thetaorigin=0: origin of the angle range.
  • sector_formatter=string: how to convert sectors to strings.
Note

You will need to manually import Plots.jl to be able to use this function. MPSKit.jl defines its plots based on RecipesBase.jl, but the user still has to add using Plots to be able to actually produce the plots.

source
MPSKit.varianceFunction
variance(state, hamiltonian, [envs=environments(state, hamiltonian)])

Compute the variance of the energy of the state with respect to the hamiltonian.

source
diff --git a/previews/PR261/man/algorithms/index.html b/previews/PR261/man/algorithms/index.html index e189adc4..1a0a383b 100644 --- a/previews/PR261/man/algorithms/index.html +++ b/previews/PR261/man/algorithms/index.html @@ -1,8 +1,8 @@ Algorithms · MPSKit.jl

Algorithms

Here is a collection of the algorithms that have been added to MPSKit.jl. If a particular algorithm is missing, feel free to let us know via an issue, or contribute via a PR.

Groundstates

One of the most prominent use-cases of MPS is to obtain the groundstate of a given (quasi-) one-dimensional quantum Hamiltonian. In MPSKit.jl, this can be achieved through find_groundstate:

MPSKit.find_groundstateFunction
find_groundstate(ψ₀, H, [environments]; kwargs...) -> (ψ, environments, ϵ)
-find_groundstate(ψ₀, H, algorithm, environments) -> (ψ, environments, ϵ)

Compute the groundstate for Hamiltonian H with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.

Arguments

  • ψ₀::AbstractMPS: initial guess
  • H::AbstractMPO: operator for which to find the groundstate
  • [environments]: MPS environment manager
  • algorithm: optimization algorithm

Keywords

  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: display progress information

Returns

  • ψ::AbstractMPS: converged groundstate
  • environments: environments corresponding to the converged state
  • ϵ::Float64: final convergence error upon terminating the algorithm
source

There is a variety of algorithms that have been developed over the years, and many of them have been implemented in MPSKit. Keep in mind that some of them are exclusive to finite or infinite systems, while others may work for both. Many of these algorithms have different advantages and disadvantages, and figuring out the optimal algorithm is not always straightforward, since this may strongly depend on the model. Here, we enumerate some of their properties in hopes of pointing you in the right direction.

DMRG

Probably the most widely used algorithm for optimizing groundstates with MPS is DMRG and its variants. This algorithm sweeps through the system, optimizing a single site while keeping all others fixed. Since this local problem can be solved efficiently, the global optimal state follows by alternating through the system. However, because of the single-site nature of this algorithm, this can never alter the bond dimension of the state, such that there is no way of dynamically increasing the precision. This can become particularly relevant in the cases where symmetries are involved, since then finding a good distribution of charges is also required. To circumvent this, it is also possible to optimize over two sites at the same time with DMRG2, followed by a truncation back to the single site states. This can dynamically change the bond dimension but comes at an increase in cost.

MPSKit.DMRGType
struct DMRG{A, F} <: MPSKit.Algorithm

Single-site DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

  • verbosity::Int64: setting for how much information is displayed

  • eigalg::Any: algorithm used for the eigenvalue solvers

source
MPSKit.DMRG2Type
struct DMRG2{A, F} <: MPSKit.Algorithm

Two-site DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

  • verbosity::Int64: setting for how much information is displayed

  • eigalg::Any: algorithm used for the eigenvalue solvers

  • trscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update

source

For infinite systems, a similar approach can be used by dynamically adding new sites to the middle of the system and optimizing over them. This gradually increases the system size until the boundary effects are no longer felt. However, because of this approach, for critical systems this algorithm can be quite slow to converge, since the number of steps needs to be larger than the correlation length of the system. Again, both a single-site and a two-site version are implemented, to have the option to dynamically increase the bonddimension at a higher cost.

MPSKit.IDMRGType
struct IDMRG{A} <: MPSKit.Algorithm

Single site infinite DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_gauge::Any: algorithm used for gauging the MPS

  • alg_eigsolve::Any: algorithm used for the eigenvalue solvers

source
MPSKit.IDMRG2Type
struct IDMRG2{A} <: MPSKit.Algorithm

Two-site infinite DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_gauge::Any: algorithm used for gauging the MPS

  • alg_eigsolve::Any: algorithm used for the eigenvalue solvers

  • trscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update

source

VUMPS

VUMPS is an (I)DMRG inspired algorithm that can be used to Variationally find the groundstate as a Uniform (infinite) Matrix Product State. In particular, a local update is followed by a re-gauging procedure that effectively replaces the entire network with the newly updated tensor. Compared to IDMRG, this often achieves a higher rate of convergence, since updates are felt throughout the system immediately. Nevertheless, this algorithm only works whenever the state is injective, i.e. there is a unique ground state. Since this is a single-site algorithm, this cannot alter the bond dimension.

MPSKit.VUMPSType
struct VUMPS{F} <: MPSKit.Algorithm

Variational optimization algorithm for uniform matrix product states, based on the combination of DMRG with matrix product state tangent space concepts.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_gauge::Any: algorithm used for gauging the InfiniteMPS

  • alg_eigsolve::Any: algorithm used for the eigenvalue solvers

  • alg_environments::Any: algorithm used for the MPS environments

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

References

source

Gradient descent

Both finite and infinite matrix product states can be parametrized by a set of isometric tensors, which we can optimize over. Making use of the geometry of the manifold (a Grassmann manifold), we can greatly outperform naive optimization strategies. Compared to the other algorithms, quite often the convergence rate in the tail of the optimization procedure is higher, such that often the fastest method combines a different algorithm far from convergence with this algorithm close to convergence. Since this is again a single-site algorithm, there is no way to alter the bond dimension.

MPSKit.GradientGrassmannType
struct GradientGrassmann{O<:OptimKit.OptimizationAlgorithm, F} <: MPSKit.Algorithm

Variational gradient-based optimization algorithm that keeps the MPS in left-canonical form, as points on a Grassmann manifold. The optimization is then a Riemannian gradient descent with a preconditioner to induce the metric from the Hilbert space inner product.

Fields

  • method::OptimKit.OptimizationAlgorithm: optimization algorithm

  • finalize!::Any: callback function applied after each iteration, of signature finalize!(x, f, g, numiter) -> x, f, g

References


Constructors

GradientGrassmann(; kwargs...)

Keywords

  • method=ConjugateGradient: instance of optimization algorithm, or type of optimization algorithm to construct
  • finalize!: finalizer algorithm
  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: level of information display
source

Time evolution

Given a particular state, it can also often be useful to have the ability to examine the evolution of certain properties over time. To that end, there are two main approaches to solving the Schrödinger equation in MPSKit.

\[i \hbar \frac{d}{dt} \Psi = H \Psi \implies \Psi(t) = \exp{\left(-iH(t - t_0)\right)} \Psi(t_0)\]

MPSKit.timestepFunction
timestep(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ, envs)
-timestep!(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ₀, envs)

Time-step the state ψ₀ with Hamiltonian H over a given time step dt at time t, solving the Schroedinger equation: $i ∂ψ/∂t = H ψ$.

Arguments

  • ψ₀::AbstractMPS: initial state
  • H::AbstractMPO: operator that generates the time evolution (can be time-dependent).
  • t::Number: starting time of time-step
  • dt::Number: time-step magnitude
  • [alg]: algorithm to use for the time evolution. Defaults to TDVP.
  • [envs]: MPS environment manager
source
MPSKit.time_evolveFunction
time_evolve(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ, envs)
-time_evolve!(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ₀, envs)

Time-evolve the initial state ψ₀ with Hamiltonian H over a given time span by stepping through each of the time points obtained by iterating t_span.

Arguments

  • ψ₀::AbstractMPS: initial state
  • H::AbstractMPO: operator that generates the time evolution (can be time-dependent).
  • t_span::AbstractVector{<:Number}: time points over which the time evolution is stepped
  • [alg]: algorithm to use for the time evolution. Defaults to TDVP.
  • [envs]: MPS environment manager
source
MPSKit.make_time_mpoFunction
make_time_mpo(H::MPOHamiltonian, dt::Number, alg) -> O::MPO

Construct an MPO that approximates $\exp(-iHdt)$.

source

TDVP

The first is focused around approximately solving the equation for a small timestep, and repeating this until the desired evolution is achieved. This can be achieved by projecting the equation onto the tangent space of the MPS, and then solving the results. This procedure is commonly referred to as the TDVP algorithm, which again has a two-site variant to allow for dynamically altering the bond dimension.

MPSKit.TDVPType
struct TDVP{A, F} <: MPSKit.Algorithm

Single site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.

Fields

  • integrator::Any: algorithm used in the exponential solvers

  • tolgauge::Float64: tolerance for gauging algorithm

  • gaugemaxiter::Int64: maximal amount of iterations for gauging algorithm

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

References

source
MPSKit.TDVP2Type
struct TDVP2{A, F} <: MPSKit.Algorithm

Two-site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.

Fields

  • integrator::Any: algorithm used in the exponential solvers

  • tolgauge::Float64: tolerance for gauging algorithm

  • gaugemaxiter::Int64: maximal amount of iterations for gauging algorithm

  • trscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

References

source

Time evolution MPO

The other approach instead tries to first approximately represent the evolution operator, and only then attempts to apply this operator to the initial state. Typically the first step happens through make_time_mpo, while the second can be achieved through approximate. Here, there are several algorithms available

MPSKit.WIConstant
const WI = TaylorCluster(; N=1, extension=false, compression=false)

First order Taylor expansion for a time-evolution MPO.

source
MPSKit.TaylorClusterType
struct TaylorCluster <: MPSKit.Algorithm

Algorithm for constructing the Nth order time evolution MPO using the Taylor cluster expansion.

Fields

  • N::Int64: order of the Taylor expansion

  • extension::Bool: include higher-order corrections

  • compression::Bool: approximate compression of corrections, accurate up to order N

References

source

Excitations

It might also be desirable to obtain information beyond the lowest energy state of a given system, and study the dispersion relation. While it is typically not feasible to resolve states in the middle of the energy spectrum, there are several ways to target a few of the lowest-lying energy states.

MPSKit.excitationsFunction
excitations(H, algorithm::QuasiparticleAnsatz, ψ::FiniteQP, [left_environments],
+find_groundstate(ψ₀, H, algorithm, environments) -> (ψ, environments, ϵ)

Compute the groundstate for Hamiltonian H with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.

Arguments

  • ψ₀::AbstractMPS: initial guess
  • H::AbstractMPO: operator for which to find the groundstate
  • [environments]: MPS environment manager
  • algorithm: optimization algorithm

Keywords

  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: display progress information

Returns

  • ψ::AbstractMPS: converged groundstate
  • environments: environments corresponding to the converged state
  • ϵ::Float64: final convergence error upon terminating the algorithm
source

There is a variety of algorithms that have been developed over the years, and many of them have been implemented in MPSKit. Keep in mind that some of them are exclusive to finite or infinite systems, while others may work for both. Many of these algorithms have different advantages and disadvantages, and figuring out the optimal algorithm is not always straightforward, since this may strongly depend on the model. Here, we enumerate some of their properties in hopes of pointing you in the right direction.

DMRG

Probably the most widely used algorithm for optimizing groundstates with MPS is DMRG and its variants. This algorithm sweeps through the system, optimizing a single site while keeping all others fixed. Since this local problem can be solved efficiently, the global optimal state follows by alternating through the system. However, because of the single-site nature of this algorithm, this can never alter the bond dimension of the state, such that there is no way of dynamically increasing the precision. This can become particularly relevant in the cases where symmetries are involved, since then finding a good distribution of charges is also required. To circumvent this, it is also possible to optimize over two sites at the same time with DMRG2, followed by a truncation back to the single site states. This can dynamically change the bond dimension but comes at an increase in cost.

MPSKit.DMRGType
struct DMRG{A, F} <: MPSKit.Algorithm

Single-site DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

  • verbosity::Int64: setting for how much information is displayed

  • eigalg::Any: algorithm used for the eigenvalue solvers

source
MPSKit.DMRG2Type
struct DMRG2{A, F} <: MPSKit.Algorithm

Two-site DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

  • verbosity::Int64: setting for how much information is displayed

  • eigalg::Any: algorithm used for the eigenvalue solvers

  • trscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update

source

For infinite systems, a similar approach can be used by dynamically adding new sites to the middle of the system and optimizing over them. This gradually increases the system size until the boundary effects are no longer felt. However, because of this approach, for critical systems this algorithm can be quite slow to converge, since the number of steps needs to be larger than the correlation length of the system. Again, both a single-site and a two-site version are implemented, to have the option to dynamically increase the bonddimension at a higher cost.

MPSKit.IDMRGType
struct IDMRG{A} <: MPSKit.Algorithm

Single site infinite DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_gauge::Any: algorithm used for gauging the MPS

  • alg_eigsolve::Any: algorithm used for the eigenvalue solvers

source
MPSKit.IDMRG2Type
struct IDMRG2{A} <: MPSKit.Algorithm

Two-site infinite DMRG algorithm for finding the dominant eigenvector.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_gauge::Any: algorithm used for gauging the MPS

  • alg_eigsolve::Any: algorithm used for the eigenvalue solvers

  • trscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update

source

VUMPS

VUMPS is an (I)DMRG inspired algorithm that can be used to Variationally find the groundstate as a Uniform (infinite) Matrix Product State. In particular, a local update is followed by a re-gauging procedure that effectively replaces the entire network with the newly updated tensor. Compared to IDMRG, this often achieves a higher rate of convergence, since updates are felt throughout the system immediately. Nevertheless, this algorithm only works whenever the state is injective, i.e. there is a unique ground state. Since this is a single-site algorithm, this cannot alter the bond dimension.

MPSKit.VUMPSType
struct VUMPS{F} <: MPSKit.Algorithm

Variational optimization algorithm for uniform matrix product states, based on the combination of DMRG with matrix product state tangent space concepts.

Fields

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

  • alg_gauge::Any: algorithm used for gauging the InfiniteMPS

  • alg_eigsolve::Any: algorithm used for the eigenvalue solvers

  • alg_environments::Any: algorithm used for the MPS environments

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

References

source

Gradient descent

Both finite and infinite matrix product states can be parametrized by a set of isometric tensors, which we can optimize over. Making use of the geometry of the manifold (a Grassmann manifold), we can greatly outperform naive optimization strategies. Compared to the other algorithms, quite often the convergence rate in the tail of the optimization procedure is higher, such that often the fastest method combines a different algorithm far from convergence with this algorithm close to convergence. Since this is again a single-site algorithm, there is no way to alter the bond dimension.

MPSKit.GradientGrassmannType
struct GradientGrassmann{O<:OptimKit.OptimizationAlgorithm, F} <: MPSKit.Algorithm

Variational gradient-based optimization algorithm that keeps the MPS in left-canonical form, as points on a Grassmann manifold. The optimization is then a Riemannian gradient descent with a preconditioner to induce the metric from the Hilbert space inner product.

Fields

  • method::OptimKit.OptimizationAlgorithm: optimization algorithm

  • finalize!::Any: callback function applied after each iteration, of signature finalize!(x, f, g, numiter) -> x, f, g

References


Constructors

GradientGrassmann(; kwargs...)

Keywords

  • method=ConjugateGradient: instance of optimization algorithm, or type of optimization algorithm to construct
  • finalize!: finalizer algorithm
  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: level of information display
source

Time evolution

Given a particular state, it can also often be useful to have the ability to examine the evolution of certain properties over time. To that end, there are two main approaches to solving the Schrödinger equation in MPSKit.

\[i \hbar \frac{d}{dt} \Psi = H \Psi \implies \Psi(t) = \exp{\left(-iH(t - t_0)\right)} \Psi(t_0)\]

MPSKit.timestepFunction
timestep(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ, envs)
+timestep!(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ₀, envs)

Time-step the state ψ₀ with Hamiltonian H over a given time step dt at time t, solving the Schroedinger equation: $i ∂ψ/∂t = H ψ$.

Arguments

  • ψ₀::AbstractMPS: initial state
  • H::AbstractMPO: operator that generates the time evolution (can be time-dependent).
  • t::Number: starting time of time-step
  • dt::Number: time-step magnitude
  • [alg]: algorithm to use for the time evolution. Defaults to TDVP.
  • [envs]: MPS environment manager
source
MPSKit.time_evolveFunction
time_evolve(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ, envs)
+time_evolve!(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ₀, envs)

Time-evolve the initial state ψ₀ with Hamiltonian H over a given time span by stepping through each of the time points obtained by iterating t_span.

Arguments

  • ψ₀::AbstractMPS: initial state
  • H::AbstractMPO: operator that generates the time evolution (can be time-dependent).
  • t_span::AbstractVector{<:Number}: time points over which the time evolution is stepped
  • [alg]: algorithm to use for the time evolution. Defaults to TDVP.
  • [envs]: MPS environment manager
source
MPSKit.make_time_mpoFunction
make_time_mpo(H::MPOHamiltonian, dt::Number, alg) -> O::MPO

Construct an MPO that approximates $\exp(-iHdt)$.

source

TDVP

The first is focused around approximately solving the equation for a small timestep, and repeating this until the desired evolution is achieved. This can be achieved by projecting the equation onto the tangent space of the MPS, and then solving the results. This procedure is commonly referred to as the TDVP algorithm, which again has a two-site variant to allow for dynamically altering the bond dimension.

MPSKit.TDVPType
struct TDVP{A, F} <: MPSKit.Algorithm

Single site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.

Fields

  • integrator::Any: algorithm used in the exponential solvers

  • tolgauge::Float64: tolerance for gauging algorithm

  • gaugemaxiter::Int64: maximal amount of iterations for gauging algorithm

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

References

source
MPSKit.TDVP2Type
struct TDVP2{A, F} <: MPSKit.Algorithm

Two-site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.

Fields

  • integrator::Any: algorithm used in the exponential solvers

  • tolgauge::Float64: tolerance for gauging algorithm

  • gaugemaxiter::Int64: maximal amount of iterations for gauging algorithm

  • trscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update

  • finalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs

References

source

Time evolution MPO

The other approach instead tries to first approximately represent the evolution operator, and only then attempts to apply this operator to the initial state. Typically the first step happens through make_time_mpo, while the second can be achieved through approximate. Here, there are several algorithms available

MPSKit.WIConstant
const WI = TaylorCluster(; N=1, extension=false, compression=false)

First order Taylor expansion for a time-evolution MPO.

source
MPSKit.TaylorClusterType
struct TaylorCluster <: MPSKit.Algorithm

Algorithm for constructing the Nth order time evolution MPO using the Taylor cluster expansion.

Fields

  • N::Int64: order of the Taylor expansion

  • extension::Bool: include higher-order corrections

  • compression::Bool: approximate compression of corrections, accurate up to order N

References

source

Excitations

It might also be desirable to obtain information beyond the lowest energy state of a given system, and study the dispersion relation. While it is typically not feasible to resolve states in the middle of the energy spectrum, there are several ways to target a few of the lowest-lying energy states.

MPSKit.excitationsFunction
excitations(H, algorithm::QuasiparticleAnsatz, ψ::FiniteQP, [left_environments],
             [right_environments]; num=1) -> (energies, states)
 excitations(H, algorithm::QuasiparticleAnsatz, ψ::InfiniteQP, [left_environments],
             [right_environments]; num=1, solver=Defaults.solver) -> (energies, states)
@@ -11,7 +11,7 @@
 excitations(H, algorithm::ChepigaAnsatz, ψ::FiniteMPS, [envs];
             num=1, pos=length(ψ)÷2) -> (energies, states)
 excitations(H, algorithm::ChepigaAnsatz2, ψ::FiniteMPS, [envs];
-            num=1, pos=length(ψ)÷2) -> (energies, states)

Compute the first excited states and their energy gap above a groundstate.

Arguments

  • H::AbstractMPO: operator for which to find the excitations
  • algorithm: optimization algorithm
  • ψ::QP: initial quasiparticle guess
  • ψs::NTuple{N, <:FiniteMPS}: N first excited states
  • [left_environments]: left groundstate environment
  • [right_environments]: right groundstate environment

Keywords

  • num::Int: number of excited states to compute
  • solver: algorithm for the linear solver of the quasiparticle environments
  • init: initial excited state guess
  • pos: position of perturbation
source

Quasiparticle Ansatz

The Quasiparticle Ansatz offers an approach to compute low-energy eigenstates in quantum systems, playing a key role in both finite and infinite systems. It leverages localized perturbations for approximations, as detailed in (Haegeman et al., 2013).

Finite Systems:

In finite systems, we approximate low-energy states by altering a single tensor in the Matrix Product State (MPS) for each site, and summing these across all sites. This method introduces additional gauge freedoms, utilized to ensure orthogonality to the ground state. Optimizing within this framework translates to solving an eigenvalue problem. For example, in the transverse field Ising model, we calculate the first excited state as shown in the provided code snippet, amd check the accuracy against theoretical values. Some deviations are expected, both due to finite-bond-dimension and finite-size effects.

# Model parameters
+            num=1, pos=length(ψ)÷2) -> (energies, states)

Compute the first excited states and their energy gap above a groundstate.

Arguments

  • H::AbstractMPO: operator for which to find the excitations
  • algorithm: optimization algorithm
  • ψ::QP: initial quasiparticle guess
  • ψs::NTuple{N, <:FiniteMPS}: N first excited states
  • [left_environments]: left groundstate environment
  • [right_environments]: right groundstate environment

Keywords

  • num::Int: number of excited states to compute
  • solver: algorithm for the linear solver of the quasiparticle environments
  • init: initial excited state guess
  • pos: position of perturbation
source

Quasiparticle Ansatz

The Quasiparticle Ansatz offers an approach to compute low-energy eigenstates in quantum systems, playing a key role in both finite and infinite systems. It leverages localized perturbations for approximations, as detailed in (Haegeman et al., 2013).

Finite Systems:

In finite systems, we approximate low-energy states by altering a single tensor in the Matrix Product State (MPS) for each site, and summing these across all sites. This method introduces additional gauge freedoms, utilized to ensure orthogonality to the ground state. Optimizing within this framework translates to solving an eigenvalue problem. For example, in the transverse field Ising model, we calculate the first excited state as shown in the provided code snippet, amd check the accuracy against theoretical values. Some deviations are expected, both due to finite-bond-dimension and finite-size effects.

# Model parameters
 g = 10.0
 L = 16
 H = transverse_field_ising(FiniteChain(L); g)
@@ -40,7 +40,7 @@
 Es, ϕs = excitations(H, QuasiparticleAnsatz(), ψ; num=1, sector=Z2Irrep(1))
 isapprox(Es[1], 2(g - 1); rtol=1e-2) # infinite analytical result
true
MPSKit.QuasiparticleAnsatzType
struct QuasiparticleAnsatz{A} <: MPSKit.Algorithm

Optimization algorithm for quasi-particle excitations on top of MPS groundstates.

Fields

  • alg::Any: algorithm used for the eigenvalue solvers

Constructors

QuasiparticleAnsatz()
 QuasiparticleAnsatz(; kwargs...)
-QuasiparticleAnsatz(alg)

Create a QuasiparticleAnsatz algorithm with the given algorithm, or by passing the keyword arguments to Arnoldi.

References

source

Finite excitations

For finite systems we can also do something else - find the groundstate of the hamiltonian + $\\text{weight} \sum_i | \\psi_i ⟩ ⟨ \\psi_i$. This is also supported by calling

# Model parameters
+QuasiparticleAnsatz(alg)

Create a QuasiparticleAnsatz algorithm with the given algorithm, or by passing the keyword arguments to Arnoldi.

References

source

Finite excitations

For finite systems we can also do something else - find the groundstate of the hamiltonian + $\\text{weight} \sum_i | \\psi_i ⟩ ⟨ \\psi_i$. This is also supported by calling

# Model parameters
 g = 10.0
 L = 16
 H = transverse_field_ising(FiniteChain(L); g)
@@ -50,7 +50,7 @@
 ψ, = find_groundstate(ψ₀, H; verbosity=0)
 
 Es, ϕs = excitations(H, FiniteExcited(), ψ; num=1)
-isapprox(Es[1], 2(g - 1); rtol=1e-2)
false
MPSKit.FiniteExcitedType
struct FiniteExcited{A} <: MPSKit.Algorithm

Variational optimization algorithm for excitations of finite MPS by minimizing the energy of

\[H - λᵢ |ψᵢ⟩⟨ψᵢ|\]

Fields

  • gsalg::Any: optimization algorithm

  • weight::Float64: energy penalty for enforcing orthogonality with previous states

source

"Chepiga Ansatz"

Computing excitations in critical systems poses a significant challenge due to the diverging correlation length, which requires very large bond dimensions. However, we can leverage this long-range correlation to effectively identify excitations. In this context, the left/right gauged MPS, serving as isometries, are effectively projecting the Hamiltonian into the low-energy sector. This projection method is particularly effective in long-range systems, where excitations are distributed throughout the entire system. Consequently, the low-lying energy spectrum can be extracted by diagonalizing the effective Hamiltonian (without any additional DMRG costs!). The states of these excitations are then represented by the ground state MPS, with one site substituted by the corresponding eigenvector. This approach is often referred to as the 'Chepiga ansatz', named after one of the authors of this paper (Chepiga and Mila, 2017).

This is supported via the following syntax:

g = 10.0
+isapprox(Es[1], 2(g - 1); rtol=1e-2)
false
MPSKit.FiniteExcitedType
struct FiniteExcited{A} <: MPSKit.Algorithm

Variational optimization algorithm for excitations of finite MPS by minimizing the energy of

\[H - λᵢ |ψᵢ⟩⟨ψᵢ|\]

Fields

  • gsalg::Any: optimization algorithm

  • weight::Float64: energy penalty for enforcing orthogonality with previous states

source

"Chepiga Ansatz"

Computing excitations in critical systems poses a significant challenge due to the diverging correlation length, which requires very large bond dimensions. However, we can leverage this long-range correlation to effectively identify excitations. In this context, the left/right gauged MPS, serving as isometries, are effectively projecting the Hamiltonian into the low-energy sector. This projection method is particularly effective in long-range systems, where excitations are distributed throughout the entire system. Consequently, the low-lying energy spectrum can be extracted by diagonalizing the effective Hamiltonian (without any additional DMRG costs!). The states of these excitations are then represented by the ground state MPS, with one site substituted by the corresponding eigenvector. This approach is often referred to as the 'Chepiga ansatz', named after one of the authors of this paper (Chepiga and Mila, 2017).

This is supported via the following syntax:

g = 10.0
 L = 16
 H = transverse_field_ising(FiniteChain(L); g)
 ψ₀ = FiniteMPS(L, ComplexSpace(2), ComplexSpace(32))
@@ -59,15 +59,15 @@
 Es, ϕs = excitations(H, ChepigaAnsatz(), ψ, envs; num=1)
 isapprox(Es[1] - E₀, 2(g - 1); rtol=1e-2) # infinite analytical result
true

In order to improve the accuracy, a two-site version also exists, which varies two neighbouring sites:

Es, ϕs = excitations(H, ChepigaAnsatz2(), ψ, envs; num=1)
 isapprox(Es[1] - E₀, 2(g - 1); rtol=1e-2) # infinite analytical result
true

changebonds

Many of the previously mentioned algorithms do not possess a way to dynamically change to bond dimension. This is often a problem, as the optimal bond dimension is often not a priori known, or needs to increase because of entanglement growth throughout the course of a simulation. changebonds exposes a way to change the bond dimension of a given state.

There are several different algorithms implemented, each having their own advantages and disadvantages:

  • SvdCut: The simplest method for changing the bonddimension is found by simply locally truncating the state using an SVD decomposition. This yields a (locally) optimal truncation, but clearly cannot be used to increase the bond dimension. Note that a globally optimal truncation can be obtained by using the SvdCut algorithm in combination with approximate. Since the output of this method might have a truncated bonddimension, the new state might not be identical to the input state. The truncation is controlled through trscheme, which dictates how the singular values of the original state are truncated.
  • OptimalExpand: This algorithm is based on the idea of expanding the bond dimension by investigating the two-site derivative, and adding the most important blocks which are orthogonal to the current state. From the point of view of a local two-site update, this procedure is optimal, but it requires to evaluate a two-site derivative, which can be costly when the physical space is large. The state will remain unchanged, but a one-site scheme will now be able to push the optimization further. The subspace used for expansion can be truncated through trscheme, which dictates how many singular values will be added.

  • RandExpand: This algorithm similarly adds blocks orthogonal to the current state, but does not attempt to select the most important ones, and rather just selects them at random. The advantage here is that this is much cheaper than the optimal expand, and if the bond dimension is grown slow enough, this still obtains a very good expansion scheme. Again, The state will remain unchanged and a one-site scheme will now be able to push the optimization further. The subspace used for expansion can be truncated through trscheme, which dictates how many singular values will be added.

  • VUMPSSvdCut: This algorithm is based on the VUMPS algorithm, and consists of performing a two-site update, and then truncating the state back down. Because of the two-site update, this can again become expensive, but the algorithm has the option of both expanding as well as truncating the bond dimension. Here, trscheme controls the truncation of the full state after the two-site update.

Leading boundary

For statistical mechanics partition functions we want to find the approximate leading boundary MPS. Again this can be done with VUMPS:

th = nonsym_ising_mpo()
+changebonds(ψ::AbstractMPS, alg) -> ψ′

Change the bond dimension of ψ using the algorithm alg, and return the new ψ and the new envs.

See also: SvdCut, RandExpand, VUMPSSvdCut, OptimalExpand

source

There are several different algorithms implemented, each having their own advantages and disadvantages:

  • SvdCut: The simplest method for changing the bonddimension is found by simply locally truncating the state using an SVD decomposition. This yields a (locally) optimal truncation, but clearly cannot be used to increase the bond dimension. Note that a globally optimal truncation can be obtained by using the SvdCut algorithm in combination with approximate. Since the output of this method might have a truncated bonddimension, the new state might not be identical to the input state. The truncation is controlled through trscheme, which dictates how the singular values of the original state are truncated.
  • OptimalExpand: This algorithm is based on the idea of expanding the bond dimension by investigating the two-site derivative, and adding the most important blocks which are orthogonal to the current state. From the point of view of a local two-site update, this procedure is optimal, but it requires to evaluate a two-site derivative, which can be costly when the physical space is large. The state will remain unchanged, but a one-site scheme will now be able to push the optimization further. The subspace used for expansion can be truncated through trscheme, which dictates how many singular values will be added.

  • RandExpand: This algorithm similarly adds blocks orthogonal to the current state, but does not attempt to select the most important ones, and rather just selects them at random. The advantage here is that this is much cheaper than the optimal expand, and if the bond dimension is grown slow enough, this still obtains a very good expansion scheme. Again, The state will remain unchanged and a one-site scheme will now be able to push the optimization further. The subspace used for expansion can be truncated through trscheme, which dictates how many singular values will be added.

  • VUMPSSvdCut: This algorithm is based on the VUMPS algorithm, and consists of performing a two-site update, and then truncating the state back down. Because of the two-site update, this can again become expensive, but the algorithm has the option of both expanding as well as truncating the bond dimension. Here, trscheme controls the truncation of the full state after the two-site update.

Leading boundary

For statistical mechanics partition functions we want to find the approximate leading boundary MPS. Again this can be done with VUMPS:

th = nonsym_ising_mpo()
 ts = InfiniteMPS([ℂ^2],[ℂ^20]);
 (ts,envs,_) = leading_boundary(ts,th,VUMPS(maxiter=400,verbosity=false));

If the mpo satisfies certain properties (positive and hermitian), it may also be possible to use GradientGrassmann.

MPSKit.leading_boundaryFunction
leading_boundary(ψ₀, O, [environments]; kwargs...) -> (ψ, environments, ϵ)
-leading_boundary(ψ₀, O, algorithm, environments) -> (ψ, environments, ϵ)

Compute the leading boundary MPS for operator O with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.

Arguments

  • ψ₀::AbstractMPS: initial guess
  • O::AbstractMPO: operator for which to find the leading_boundary
  • [environments]: MPS environment manager
  • algorithm: optimization algorithm

Keywords

  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: display progress information

Returns

  • ψ::AbstractMPS: converged leading boundary MPS
  • environments: environments corresponding to the converged boundary
  • ϵ::Float64: final convergence error upon terminating the algorithm
source

approximate

Often, it is useful to approximate a given MPS by another, typically by one of a different bond dimension. This is achieved by approximating an application of an MPO to the initial state, by a new state.

MPSKit.approximateFunction
approximate(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)
-approximate!(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)

Compute an approximation to the application of an operator O to the state ψ in the form of an MPS ψ₀.

Arguments

  • ψ₀::AbstractMPS: initial guess of the approximated state
  • (O::AbstractMPO, ψ::AbstractMPS): operator O and state ψ to be approximated
  • algorithm: approximation algorithm. See below for a list of available algorithms.
  • [environments]: MPS environment manager

Keywords

  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: display progress information

Algorithms

  • DMRG: Alternating least square method for maximizing the fidelity with a single-site scheme.

  • DMRG2: Alternating least square method for maximizing the fidelity with a two-site scheme.

  • IDMRG: Variant of DMRG for maximizing fidelity density in the thermodynamic limit.

  • IDMRG2: Variant of DMRG2 for maximizing fidelity density in the thermodynamic limit.

  • VOMPS: Tangent space method for truncating uniform MPS.

source

Varia

What follows is a medley of lesser known (or used) algorithms and don't entirely fit under one of the above categories.

Dynamical DMRG

Dynamical DMRG has been described in other papers and is a way to find the propagator. The basic idea is that to calculate $G(z) = ⟨ V | (H-z)^{-1} | V ⟩$ , one can variationally find $(H-z) |W ⟩ = | V ⟩$ and then the propagator simply equals $G(z) = ⟨ V | W ⟩$.

MPSKit.propagatorFunction
propagator(ψ₀::AbstractFiniteMPS, z::Number, H::MPOHamiltonian, alg::DynamicalDMRG; init=copy(ψ₀))

Calculate the propagator $\frac{1}{E₀ + z - H}|ψ₀⟩$ using the dynamical DMRG algorithm.

source
MPSKit.DynamicalDMRGType
struct DynamicalDMRG{F<:MPSKit.DDMRG_Flavour, S} <: MPSKit.Algorithm

A dynamical DMRG method for calculating dynamical properties and excited states, based on a variational principle for dynamical correlation functions.

Fields

  • flavour::MPSKit.DDMRG_Flavour: flavour of the algorithm to use, either of type NaiveInvert or Jeckelmann

  • solver::Any: algorithm used for the linear solvers

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

References

source
MPSKit.NaiveInvertType
struct NaiveInvert <: MPSKit.DDMRG_Flavour

An alternative approach to the dynamical DMRG algorithm, without quadratic terms but with a less controlled approximation. This algorithm minimizes the following cost function

\[⟨ψ|(H - E)|ψ⟩ - ⟨ψ|ψ₀⟩ - ⟨ψ₀|ψ⟩\]

which is equivalent to the original approach if

\[|ψ₀⟩ = (H - E)|ψ⟩\]

See also Jeckelmann for the original approach.

source

fidelity susceptibility

The fidelity susceptibility measures how much the groundstate changes when tuning a parameter in your hamiltonian. Divergences occur at phase transitions, making it a valuable measure when no order parameter is known.

MPSKit.fidelity_susceptibilityFunction
fidelity_susceptibility(state::Union{FiniteMPS,InfiniteMPS}, H₀::T,
+leading_boundary(ψ₀, O, algorithm, environments) -> (ψ, environments, ϵ)

Compute the leading boundary MPS for operator O with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.

Arguments

  • ψ₀::AbstractMPS: initial guess
  • O::AbstractMPO: operator for which to find the leading_boundary
  • [environments]: MPS environment manager
  • algorithm: optimization algorithm

Keywords

  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: display progress information

Returns

  • ψ::AbstractMPS: converged leading boundary MPS
  • environments: environments corresponding to the converged boundary
  • ϵ::Float64: final convergence error upon terminating the algorithm
source

approximate

Often, it is useful to approximate a given MPS by another, typically by one of a different bond dimension. This is achieved by approximating an application of an MPO to the initial state, by a new state.

MPSKit.approximateFunction
approximate(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)
+approximate!(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)

Compute an approximation to the application of an operator O to the state ψ in the form of an MPS ψ₀.

Arguments

  • ψ₀::AbstractMPS: initial guess of the approximated state
  • (O::AbstractMPO, ψ::AbstractMPS): operator O and state ψ to be approximated
  • algorithm: approximation algorithm. See below for a list of available algorithms.
  • [environments]: MPS environment manager

Keywords

  • tol::Float64: tolerance for convergence criterium
  • maxiter::Int: maximum amount of iterations
  • verbosity::Int: display progress information

Algorithms

  • DMRG: Alternating least square method for maximizing the fidelity with a single-site scheme.

  • DMRG2: Alternating least square method for maximizing the fidelity with a two-site scheme.

  • IDMRG: Variant of DMRG for maximizing fidelity density in the thermodynamic limit.

  • IDMRG2: Variant of DMRG2 for maximizing fidelity density in the thermodynamic limit.

  • VOMPS: Tangent space method for truncating uniform MPS.

source

Varia

What follows is a medley of lesser known (or used) algorithms and don't entirely fit under one of the above categories.

Dynamical DMRG

Dynamical DMRG has been described in other papers and is a way to find the propagator. The basic idea is that to calculate $G(z) = ⟨ V | (H-z)^{-1} | V ⟩$ , one can variationally find $(H-z) |W ⟩ = | V ⟩$ and then the propagator simply equals $G(z) = ⟨ V | W ⟩$.

MPSKit.propagatorFunction
propagator(ψ₀::AbstractFiniteMPS, z::Number, H::MPOHamiltonian, alg::DynamicalDMRG; init=copy(ψ₀))

Calculate the propagator $\frac{1}{E₀ + z - H}|ψ₀⟩$ using the dynamical DMRG algorithm.

source
MPSKit.DynamicalDMRGType
struct DynamicalDMRG{F<:MPSKit.DDMRG_Flavour, S} <: MPSKit.Algorithm

A dynamical DMRG method for calculating dynamical properties and excited states, based on a variational principle for dynamical correlation functions.

Fields

  • flavour::MPSKit.DDMRG_Flavour: flavour of the algorithm to use, either of type NaiveInvert or Jeckelmann

  • solver::Any: algorithm used for the linear solvers

  • tol::Float64: tolerance for convergence criterium

  • maxiter::Int64: maximal amount of iterations

  • verbosity::Int64: setting for how much information is displayed

References

source
MPSKit.NaiveInvertType
struct NaiveInvert <: MPSKit.DDMRG_Flavour

An alternative approach to the dynamical DMRG algorithm, without quadratic terms but with a less controlled approximation. This algorithm minimizes the following cost function

\[⟨ψ|(H - E)|ψ⟩ - ⟨ψ|ψ₀⟩ - ⟨ψ₀|ψ⟩\]

which is equivalent to the original approach if

\[|ψ₀⟩ = (H - E)|ψ⟩\]

See also Jeckelmann for the original approach.

source

fidelity susceptibility

The fidelity susceptibility measures how much the groundstate changes when tuning a parameter in your hamiltonian. Divergences occur at phase transitions, making it a valuable measure when no order parameter is known.

MPSKit.fidelity_susceptibilityFunction
fidelity_susceptibility(state::Union{FiniteMPS,InfiniteMPS}, H₀::T,
                         Vs::AbstractVector{T}, [henvs=environments(state, H₀)];
                         maxiter=Defaults.maxiter,
-                        tol=Defaults.tol) where {T<:MPOHamiltonian}

Computes the fidelity susceptibility of a the ground state state of a base Hamiltonian H₀ with respect to a set of perturbing Hamiltonians Vs. Each of the perturbing Hamiltonians can be interpreted as corresponding to a tuning parameter $aᵢ$ in a 'total' Hamiltonian $H = H₀ + ∑ᵢ aᵢ Vᵢ$.

Returns a matrix containing the overlaps of the elementary excitations on top of state corresponding to each of the perturbing Hamiltonians.

source

Boundary conditions

You can impose periodic or open boundary conditions on an infinite Hamiltonian, to generate a finite counterpart. In particular, for periodic boundary conditions we still return an MPO that does not form a closed loop, such that it can be used with regular matrix product states. This is straightforward to implement but, and while this effectively squares the bond dimension, it is still competitive with more advanced periodic MPS algorithms.

MPSKit.open_boundary_conditionsFunction
open_boundary_conditions(mpo::InfiniteMPO, L::Int) -> FiniteMPO

Convert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.

source
open_boundary_conditions(mpo::InfiniteMPOHamiltonian, L::Int) -> FiniteMPOHamiltonian

Convert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.

source
MPSKit.periodic_boundary_conditionsFunction
periodic_boundary_conditions(mpo::AbstractInfiniteMPO, L::Int)

Convert an infinite MPO into a finite MPO of length L, by mapping periodic boundary conditions onto an open system.

source

Exact diagonalization

As a side effect, our code support exact diagonalization. The idea is to construct a finite matrix product state with maximal bond dimension, and then optimize the middle site. Because we never truncated the bond dimension, this single site effectively parametrizes the entire hilbert space.

MPSKit.exact_diagonalizationFunction
exact_diagonalization(H::FiniteMPOHamiltonian;
+                        tol=Defaults.tol) where {T<:MPOHamiltonian}

Computes the fidelity susceptibility of a the ground state state of a base Hamiltonian H₀ with respect to a set of perturbing Hamiltonians Vs. Each of the perturbing Hamiltonians can be interpreted as corresponding to a tuning parameter $aᵢ$ in a 'total' Hamiltonian $H = H₀ + ∑ᵢ aᵢ Vᵢ$.

Returns a matrix containing the overlaps of the elementary excitations on top of state corresponding to each of the perturbing Hamiltonians.

source

Boundary conditions

You can impose periodic or open boundary conditions on an infinite Hamiltonian, to generate a finite counterpart. In particular, for periodic boundary conditions we still return an MPO that does not form a closed loop, such that it can be used with regular matrix product states. This is straightforward to implement but, and while this effectively squares the bond dimension, it is still competitive with more advanced periodic MPS algorithms.

MPSKit.open_boundary_conditionsFunction
open_boundary_conditions(mpo::InfiniteMPO, L::Int) -> FiniteMPO

Convert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.

source
open_boundary_conditions(mpo::InfiniteMPOHamiltonian, L::Int) -> FiniteMPOHamiltonian

Convert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.

source
MPSKit.periodic_boundary_conditionsFunction
periodic_boundary_conditions(mpo::AbstractInfiniteMPO, L::Int)

Convert an infinite MPO into a finite MPO of length L, by mapping periodic boundary conditions onto an open system.

source

Exact diagonalization

As a side effect, our code support exact diagonalization. The idea is to construct a finite matrix product state with maximal bond dimension, and then optimize the middle site. Because we never truncated the bond dimension, this single site effectively parametrizes the entire hilbert space.

MPSKit.exact_diagonalizationFunction
exact_diagonalization(H::FiniteMPOHamiltonian;
                       sector=first(sectors(oneunit(physicalspace(H, 1)))),
                       len::Int=length(H), num::Int=1, which::Symbol=:SR,
                       alg=Defaults.alg_eigsolve(; dynamic_tols=false))
-                        -> vals, state_vecs, convhist

Use KrylovKit.eigsolve to perform exact diagonalization on a FiniteMPOHamiltonian to find its eigenvectors as FiniteMPS of maximal rank, essentially equivalent to dense eigenvectors.

Arguments

  • H::FiniteMPOHamiltonian: the Hamiltonian to diagonalize.

Keyword arguments

  • sector=first(sectors(oneunit(physicalspace(H, 1)))): the total charge of the eigenvectors, which is chosen trivial by default.
  • len::Int=length(H): the length of the system.
  • num::Int=1: the number of eigenvectors to find.
  • which::Symbol=:SR: the kind eigenvalues to find, see KrylovKit.eigsolve.
  • alg=Defaults.alg_eigsolve(; dynamic_tols=false): the diagonalization algorithm to use, see KrylovKit.eigsolve.
Valid `sector` values

The total charge of the eigenvectors is imposed by adding a charged auxiliary space as the leftmost virtualspace of each eigenvector. Specifically, this is achieved by passing left=Vect[typeof(sector)](sector => 1) to the FiniteMPS constructor. As such, the only valid sector values (i.e. sector values for which the corresponding eigenstates have valid fusion channels) are those that occur in the dual of the fusion of all the physical spaces in the system.

source
+ -> vals, state_vecs, convhist

Use KrylovKit.eigsolve to perform exact diagonalization on a FiniteMPOHamiltonian to find its eigenvectors as FiniteMPS of maximal rank, essentially equivalent to dense eigenvectors.

Arguments

  • H::FiniteMPOHamiltonian: the Hamiltonian to diagonalize.

Keyword arguments

  • sector=first(sectors(oneunit(physicalspace(H, 1)))): the total charge of the eigenvectors, which is chosen trivial by default.
  • len::Int=length(H): the length of the system.
  • num::Int=1: the number of eigenvectors to find.
  • which::Symbol=:SR: the kind eigenvalues to find, see KrylovKit.eigsolve.
  • alg=Defaults.alg_eigsolve(; dynamic_tols=false): the diagonalization algorithm to use, see KrylovKit.eigsolve.
Valid `sector` values

The total charge of the eigenvectors is imposed by adding a charged auxiliary space as the leftmost virtualspace of each eigenvector. Specifically, this is achieved by passing left=Vect[typeof(sector)](sector => 1) to the FiniteMPS constructor. As such, the only valid sector values (i.e. sector values for which the corresponding eigenstates have valid fusion channels) are those that occur in the dual of the fusion of all the physical spaces in the system.

source diff --git a/previews/PR261/man/environments/index.html b/previews/PR261/man/environments/index.html index 95c2a029..5d6a3815 100644 --- a/previews/PR261/man/environments/index.html +++ b/previews/PR261/man/environments/index.html @@ -5,4 +5,4 @@ envs = environments(state, operator)

There are also some notable differences. Infinite environments typically require solving linear problems or eigenvalue problems iteratively with finite precision. To find out what precision we used we can type:

(cache.tol,cache.maxiter)

To recalculate with a different precision :

cache.tol=1e-8;
 recalculate!(cache,state)

Unlike their finite counterparts, recalculating is not done automatically. To get the environment for a different state one has to recalculate explicitly!

different_state = InfiniteMPS([ℂ^2],[ℂ^10]);
 recalculate!(cache,different_state)
-leftenv(cache,3,different_state)
+leftenv(cache,3,different_state) diff --git a/previews/PR261/man/intro/index.html b/previews/PR261/man/intro/index.html index b33fd8b9..d9c92d09 100644 --- a/previews/PR261/man/intro/index.html +++ b/previews/PR261/man/intro/index.html @@ -4,24 +4,24 @@ t1 = rand(Float64, V1 ⊗ V1 ⊗ V1) # all spaces in codomain t2 = rand(Float64, V1, V1 ⊗ V1) # one space in codomain, two in domain
TensorMap(ℂ^2 ← (ℂ^2 ⊗ ℂ^2)):
 [:, :, 1] =
- 0.7517834635898352   0.31594932163142664
- 0.37900246634123136  0.044326448383950834
+ 0.5709992287094856  0.06300609577649896
+ 0.6370872066089702  0.0267339591451764
 
 [:, :, 2] =
- 0.22206218692249002  0.3990912873711582
- 0.12004806462140649  0.28281042942278034
+ 0.5128504079015435    0.3837159262028954
+ 0.021932841853000373  0.5254127647845112
 

We can now no longer trivially add them together:

t1 + t2 # incompatible partition
SpaceMismatch("(ℂ^2 ⊗ ℂ^2 ⊗ ℂ^2) ← ProductSpace{TensorKit.ComplexSpace, 0}() ≠ ℂ^2 ← (ℂ^2 ⊗ ℂ^2)")

But this can be resolved by permutation:

t1 + permute(t2, (1, 2, 3), ()) # incompatible arrows
SpaceMismatch("(ℂ^2 ⊗ ℂ^2 ⊗ ℂ^2) ← ProductSpace{TensorKit.ComplexSpace, 0}() ≠ (ℂ^2 ⊗ (ℂ^2)' ⊗ (ℂ^2)') ← ProductSpace{TensorKit.ComplexSpace, 0}()")

These abstract objects can represent not only plain arrays but also symmetric tensors. The following creates a symmetric tensor with ℤ₂ symmetry, again with three legs of dimension two. However, now the dimension two is now split over even and odd sectors of ℤ₂.

V2 = Z2Space(0 => 1, 1 => 1)
 t3 = rand(Float64, V2 ⊗ V2, V2)
TensorMap((Rep[ℤ₂](0=>1, 1=>1) ⊗ Rep[ℤ₂](0=>1, 1=>1)) ← Rep[ℤ₂](0=>1, 1=>1)):
 * Data for sector (Irrep[ℤ₂](0), Irrep[ℤ₂](0)) ← (Irrep[ℤ₂](0),):
 [:, :, 1] =
- 0.8324901839111172
+ 0.306694425985494
 * Data for sector (Irrep[ℤ₂](1), Irrep[ℤ₂](1)) ← (Irrep[ℤ₂](0),):
 [:, :, 1] =
- 0.7686482364580671
+ 0.04556481061689377
 * Data for sector (Irrep[ℤ₂](1), Irrep[ℤ₂](0)) ← (Irrep[ℤ₂](1),):
 [:, :, 1] =
- 0.6360846426860993
+ 0.3166887868432521
 * Data for sector (Irrep[ℤ₂](0), Irrep[ℤ₂](1)) ← (Irrep[ℤ₂](1),):
 [:, :, 1] =
- 0.25791764535680606
-

For more information, check out the TensorKit documentation!

Conventions

The general definition of an MPS tensor is as follows:

convention MPSTensor

These tensors are allowed to have an arbitrary number of physical legs, and both FiniteMPS as well as InfiniteMPS will be able to handle the resulting objects. This allows for example for the definition of boundary tensors in PEPS code, which have two physical legs.

Similarly, the definition of a bond tensor, appearing in between two MPS tensors, is as follows:

convention BondTensor

Finally, the definition of a MPO tensor, which is used to represent statistical mechanics problems as well as quantum hamiltonians, is represented as:

convention MPOTensor

While this results at first glance in the not very intuitive ordering of spaces as $V_l \otimes P \leftarrow P \otimes V_r$, this is actually the most natural ordering for keeping the algorithms planar. In particular, this is relevant for dealing with fermionic systems, where additional crossings would lead to sign problems.

+ 0.0867369225177197 +

For more information, check out the TensorKit documentation!

Conventions

The general definition of an MPS tensor is as follows:

convention MPSTensor

These tensors are allowed to have an arbitrary number of physical legs, and both FiniteMPS as well as InfiniteMPS will be able to handle the resulting objects. This allows for example for the definition of boundary tensors in PEPS code, which have two physical legs.

Similarly, the definition of a bond tensor, appearing in between two MPS tensors, is as follows:

convention BondTensor

Finally, the definition of a MPO tensor, which is used to represent statistical mechanics problems as well as quantum hamiltonians, is represented as:

convention MPOTensor

While this results at first glance in the not very intuitive ordering of spaces as $V_l \otimes P \leftarrow P \otimes V_r$, this is actually the most natural ordering for keeping the algorithms planar. In particular, this is relevant for dealing with fermionic systems, where additional crossings would lead to sign problems.

diff --git a/previews/PR261/man/lattices/index.html b/previews/PR261/man/lattices/index.html index a87f4df3..78f28bcb 100644 --- a/previews/PR261/man/lattices/index.html +++ b/previews/PR261/man/lattices/index.html @@ -1,2 +1,2 @@ -Lattices · MPSKit.jl

Lattices

Warning

This section is still under construction. Coming soon!

+Lattices · MPSKit.jl

Lattices

Warning

This section is still under construction. Coming soon!

diff --git a/previews/PR261/man/operators/index.html b/previews/PR261/man/operators/index.html index 264f2046..4f9ae69f 100644 --- a/previews/PR261/man/operators/index.html +++ b/previews/PR261/man/operators/index.html @@ -117,4 +117,4 @@ \end{equation} \]

The FiniteMPOHamiltonian constructor can also be used to construct the operator from this most general form, by supplying a vector of BlockTensorMap objects to the constructor. Here, the vector specifies the sites in the unit cell, while the blocktensors contain the rows and columns of the matrix. We can verify this explicitly:

H_ising[2] # print the blocktensor
3×1×1×3 SparseBlockTensorMap{TensorKit.AbstractTensorMap{ComplexF64, TensorKit.ComplexSpace, 2, 2}}(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1))) with 5 stored entries:
 ⎡⠉⢈⎤
-⎣⠀⢀⎦

Working with MPOHamiltonian objects

Warning

This part is still a work in progress

Because of the discussion above, the FiniteMPOHamiltonian object is in fact just an AbstractMPO, with some additional structure. This means that similar operations and properties are available, such as the virtual spaces, or the individual tensors. However, the block structure of the operator means that now the virtual spaces are not just a single space, but a collection (direct sum) of spaces, one for each row/column.

left_virtualspace(H_ising, 1), right_virtualspace(H_ising, 1), physicalspace(H_ising, 1)
(⊕(ℂ^1), (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1), ℂ^2)
+⎣⠀⢀⎦

Working with MPOHamiltonian objects

Warning

This part is still a work in progress

Because of the discussion above, the FiniteMPOHamiltonian object is in fact just an AbstractMPO, with some additional structure. This means that similar operations and properties are available, such as the virtual spaces, or the individual tensors. However, the block structure of the operator means that now the virtual spaces are not just a single space, but a collection (direct sum) of spaces, one for each row/column.

left_virtualspace(H_ising, 1), right_virtualspace(H_ising, 1), physicalspace(H_ising, 1)
(⊕(ℂ^1), (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1), ℂ^2)
diff --git a/previews/PR261/man/parallelism/index.html b/previews/PR261/man/parallelism/index.html index 55920e8b..929c4493 100644 --- a/previews/PR261/man/parallelism/index.html +++ b/previews/PR261/man/parallelism/index.html @@ -39,4 +39,4 @@ └ @ ThreadPinning ~/.julia/packages/ThreadPinning/qV2Cd/src/threadinfo.jl:256 [ Info: jlthreads < cputhreads. Perhaps increase number of Julia threads to 16?

MPSKit multithreading

Within MPSKit, when Julia is started with multiple threads, by default the OhMyThreads.jl machinery will be used to parallelize the code as much as possible. In particular, this mostly occurs whenever there is a unitcell and local updates can take place at each site in parallel.

The multithreading behaviour can be controlled through a global scheduler, which can be set using the MPSKit.Defaults.set_scheduler!(arg; kwargs...) function. This function accepts either a Symbol, an OhMyThreads.Scheduler or keywords to determine a scheduler automatically.

MPSKit.Defaults.set_scheduler!(:serial) # disable multithreading
 MPSKit.Defaults.set_scheduler!(:greedy) # multithreading with greedy load-balancing
-MPSKit.Defaults.set_scheduler!(:dynamic) # default: multithreading with some load-balancing

For further reference on the available schedulers and finer control, please refer to the OhMyThreads.jl documentation

TensorKit multithreading

Finally, when dealing with tensors that have some internal symmetry, it is also possible to parallelize over the symmetry sectors. This is handled by TensorKit, and more information can be found in its documentation (Soon TM).

Memory management

Because of the way julia threads work, it is possible that the total memory usage of your program becomes rather high. This seems to be because of the fact that MPSKit spawns several tasks (in a nested way), which each allocate and deallocate quite a bit of memory in a tight loop. This seems to lead to a situation where the garbage collector is not able to keep up, and can even fail to clear the garbage before an OutOfMemory error occurs. In this case, often the best thing to do is disable the multithreading of MPSKit, specifically for the derivatives, as this seems to be the most memory intensive part. This is something that is under investigation, and hopefully will be fixed in the future.

+MPSKit.Defaults.set_scheduler!(:dynamic) # default: multithreading with some load-balancing

For further reference on the available schedulers and finer control, please refer to the OhMyThreads.jl documentation

TensorKit multithreading

Finally, when dealing with tensors that have some internal symmetry, it is also possible to parallelize over the symmetry sectors. This is handled by TensorKit, and more information can be found in its documentation (Soon TM).

Memory management

Because of the way julia threads work, it is possible that the total memory usage of your program becomes rather high. This seems to be because of the fact that MPSKit spawns several tasks (in a nested way), which each allocate and deallocate quite a bit of memory in a tight loop. This seems to lead to a situation where the garbage collector is not able to keep up, and can even fail to clear the garbage before an OutOfMemory error occurs. In this case, often the best thing to do is disable the multithreading of MPSKit, specifically for the derivatives, as this seems to be the most memory intensive part. This is something that is under investigation, and hopefully will be fixed in the future.

diff --git a/previews/PR261/man/states/index.html b/previews/PR261/man/states/index.html index fedbe058..79fb8d65 100644 --- a/previews/PR261/man/states/index.html +++ b/previews/PR261/man/states/index.html @@ -81,26 +81,26 @@ col = 2 al = state.AL[row, col];
TensorMap((ℂ^4 ⊗ ℂ^2) ← ℂ^4):
 [:, :, 1] =
-   0.40867091251729804 + 0.6012110646183271im    …     0.5202749452497475 + 0.43573258892870936im
-   0.05923773078722784 + 0.05941120510249571im        0.05057678949838469 - 0.025596489415169066im
- 0.0038415606879679915 + 0.010608093270373674im      0.013524202727741255 + 0.01663313743081508im
-  0.004203882801542828 + 0.007423334254581863im     0.0038539297450378104 + 0.007612853514146337im
+    0.434704480246064 + 0.34920116401912205im   …     0.6254501528385183 + 0.5142813518332287im
+  0.06498643696310541 - 0.014599845608567993im       0.13606625676012102 + 0.0838638491397092im
+ 0.018701168404006305 + 0.030767331635360134im       0.02734634805206197 + 0.03583939280378461im
+ 0.004564474596704537 + 0.007557287206428872im     0.0008447459209068413 + 0.005146613688493702im
 
 [:, :, 2] =
-    0.6622054402202968 - 0.09332260444714288im    …    -0.6387630767273039 + 0.28536484944189133im
- 0.0011193013405597085 - 0.05751111907134003im         0.06709265494871998 + 0.2263215481841863im
-  0.045031462145160586 - 0.0013264841914300122im      -0.03519835358400136 - 0.023321348387640183im
-  0.006710382167885661 + 0.00835912596510287im       -0.008851018413358815 - 0.016917018361985944im
+  -0.33935730365283445 + 0.7132677009135341im     …    0.2547490403129665 - 0.45800982229427933im
+   0.07257058796114824 + 0.19545589428720642im       -0.07071497635427701 - 0.21741434643099422im
+ -0.015533740293813401 + 0.0443334605151879im         0.03530031144619781 - 0.039705101291851154im
+ 0.0048745677092185595 + 0.0025013162571566484im      0.02434140141620094 - 0.004975136913360437im
 
 [:, :, 3] =
-   -0.1165351375792366 - 0.004258908157731516im  …   0.20797297041582036 - 0.03530932961350314im
-  -0.17527992222906713 - 0.1873964718964268im       0.030244099954457617 + 0.9079074963928123im
-   0.12102300728844351 - 0.012973796933538133im      0.11740610265822372 - 0.0932938039468538im
- -0.007165043820325293 - 0.05030452273859513im       0.09940840106530313 + 0.03292376445119358im
+  0.20581730607799684 - 0.09444937026149378im  …  -0.11044192092544108 + 0.1908250790346402im
+ -0.17892264100791597 + 0.5553192276969194im       -0.0729147510554666 - 0.721150589443941im
+   0.0693603148887405 - 0.08639744685387624im       0.0870915241378854 + 0.09568842936161084im
+  0.01439635558971204 - 0.02808246126274558im      0.04581031930855258 + 0.04720580857346565im
 
 [:, :, 4] =
- -0.047948186778718226 + 0.07934857199727045im   …  -0.01174523057740709 - 0.0038512300963609025im
-   0.21561895673609474 - 0.8954872815915853im        0.24819076330137274 - 0.1452999852064797im
-  0.015233877650669594 + 0.1597759504866464im       -0.04502882638532735 + 0.11113438986347264im
-  0.052359737550674135 - 0.047738698599344306im     0.013094032875686886 + 0.12174314786158173im
-

These objects are also used extensively in the context of PEPSKit.jl.

+ -0.05031243574617178 + 0.06348518976108924im … 0.04743782684555442 + 0.09521801219365711im + -0.28490820647596143 - 0.6552010389518773im -0.400322623853116 - 0.34795411632460277im + 0.3025051641680949 + 0.08304486210697122im 0.25705285869386635 - 0.06468874354643882im + 0.0806292445550143 + 0.030172955096591826im 0.1190803265426343 + 0.008478136008989277im +

These objects are also used extensively in the context of PEPSKit.jl.

diff --git a/previews/PR261/references/index.html b/previews/PR261/references/index.html index cc06ae95..cd946500 100644 --- a/previews/PR261/references/index.html +++ b/previews/PR261/references/index.html @@ -1,2 +1,2 @@ -References · MPSKit.jl

References

Publications using MPSKit

Below you can find a list of publications that have made use of MPSKit. If you have used this package and wish to have your publication added to this list, please open a pull request or an issue on the GitHub repository.

2025

2024

2023

2022

2021

2019

Full list of references

+References · MPSKit.jl

References

Publications using MPSKit

Below you can find a list of publications that have made use of MPSKit. If you have used this package and wish to have your publication added to this list, please open a pull request or an issue on the GitHub repository.

2025

2024

2023

2022

2021

2019

Full list of references

diff --git a/previews/PR261/search_index.js b/previews/PR261/search_index.js index 11b84921..7ad8534d 100644 --- a/previews/PR261/search_index.js +++ b/previews/PR261/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"EditURL = \"../../../../../examples/quantum1d/2.haldane/main.jl\"","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"(Image: ) (Image: ) (Image: )","category":"page"},{"location":"examples/quantum1d/2.haldane/#demo_haldane","page":"The Haldane gap","title":"The Haldane gap","text":"","category":"section"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"In this tutorial we will calculate the Haldane gap (the energy gap in the S = 1 Heisenberg model) in two different ways. To follow the tutorial you need the following packages:","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"using MPSKit, MPSKitModels, TensorKit, Plots, Polynomials","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"The Heisenberg model is defined by the following hamiltonian:","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"H = -J_ij (X_i X_j + Y_i Y_j + Z_i Z_j)","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"This hamiltonian has an SU(2) symmetry, which we can enforce by using SU(2)-symmetric tensors:","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"symmetry = SU2Irrep\nspin = 1\nJ = 1","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"1","category":"page"},{"location":"examples/quantum1d/2.haldane/#Finite-size-extrapolation","page":"The Haldane gap","title":"Finite size extrapolation","text":"","category":"section"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"We can start the analysis using finite-size methods. The groundstate of this model can be approximated using finite MPS through the use of DMRG.","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"The typical way to find excited states is to minimize the energy while adding an error term λ leftgsright left gsright Here we will instead use the quasiparticle ansatz.","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"In Steven White's original DMRG paper it was remarked that the S = 1 excitations correspond to edge states, and that one should define the Haldane gap as the difference in energy between the S = 2 and S = 1 states. This can be done as follows.","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"L = 11\nchain = FiniteChain(L)\nH = heisenberg_XXX(symmetry, chain; J, spin)\n\nphysical_space = SU2Space(1 => 1)\nvirtual_space = SU2Space(0 => 12, 1 => 12, 2 => 5, 3 => 3)\nψ₀ = FiniteMPS(L, physical_space, virtual_space)\nψ, envs, delta = find_groundstate(ψ₀, H, DMRG(; verbosity=0))\nE₀ = real(expectation_value(ψ, H))\nEn_1, st_1 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector=SU2Irrep(1))\nEn_2, st_2 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector=SU2Irrep(2))\nΔE_finite = real(En_2[1] - En_1[1])","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"0.7989253589480536","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"We can go even further and doublecheck the claim that S = 1 is an edge excitation, by plotting the energy density.","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"p_density = plot(; xaxis=\"position\", yaxis=\"energy density\")\nexcited_1 = convert(FiniteMPS, st_1[1])\nexcited_2 = convert(FiniteMPS, st_2[1])\nSS = -S_exchange(ComplexF64, SU2Irrep; spin=1)\ne₀ = [real(expectation_value(ψ, (i, i + 1) => SS)) for i in 1:(L - 1)]\ne₁ = [real(expectation_value(excited_1, (i, i + 1) => SS)) for i in 1:(L - 1)]\ne₂ = [real(expectation_value(excited_2, (i, i + 1) => SS)) for i in 1:(L - 1)]\nplot!(p_density, e₀; label=\"S = 0\")\nplot!(p_density, e₁; label=\"S = 1\")\nplot!(p_density, e₂; label=\"S = 2\")","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"Finally, we can obtain a value for the Haldane gap by extrapolating our results for different system sizes.","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"Ls = 12:4:30\nΔEs = map(Ls) do L\n @info \"computing L = $L\"\n ψ₀ = FiniteMPS(L, physical_space, virtual_space)\n H = heisenberg_XXX(symmetry, FiniteChain(L); J, spin)\n ψ, envs, delta = find_groundstate(ψ₀, H, DMRG(; verbosity=0))\n En_1, st_1 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector=SU2Irrep(1))\n En_2, st_2 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector=SU2Irrep(2))\n return real(En_2[1] - En_1[1])\nend\n\nf = fit(Ls .^ (-2), ΔEs, 1)\nΔE_extrapolated = f.coeffs[1]","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"0.45173401585831346","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"p_size_extrapolation = plot(; xaxis=\"L^(-2)\", yaxis=\"ΔE\", xlims=(0, 0.015))\nplot!(p_size_extrapolation, Ls .^ (-2), ΔEs; seriestype=:scatter, label=\"numerical\")\nplot!(p_size_extrapolation, x -> f(x); label=\"fit\")","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/2.haldane/#Thermodynamic-limit","page":"The Haldane gap","title":"Thermodynamic limit","text":"","category":"section"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"A much nicer way of obtaining the Haldane gap is by working directly in the thermodynamic limit. As was already hinted at by the edge modes, this model is in a non-trivial SPT phase. Thus, care must be taken when selecting the symmetry sectors. The groundstate has half-integer edge modes, thus the virtual spaces must also all carry half-integer charges.","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"In contrast with the finite size case, we now should specify a momentum label to the excitations. This way, it is possible to scan the dispersion relation over the entire momentum space.","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"chain = InfiniteChain(1)\nH = heisenberg_XXX(symmetry, chain; J, spin)\nvirtual_space_inf = Rep[SU₂](1 // 2 => 16, 3 // 2 => 16, 5 // 2 => 8, 7 // 2 => 4)\nψ₀_inf = InfiniteMPS([physical_space], [virtual_space_inf])\nψ_inf, envs_inf, delta_inf = find_groundstate(ψ₀_inf, H; verbosity=0)\n\nkspace = range(0, π, 16)\nEs, _ = excitations(H, QuasiparticleAnsatz(), kspace, ψ_inf, envs_inf; sector=SU2Irrep(1))\n\nΔE, idx = findmin(real.(Es))\nprintln(\"minimum @k = $(kspace[idx]):\\t ΔE = $(ΔE)\")","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"┌ Warning: resorting to η\n└ @ OptimKit ~/.julia/packages/OptimKit/xpmbV/src/cg.jl:139\n[ Info: Found excitations for momentum = 1.6755160819145563\n[ Info: Found excitations for momentum = 1.8849555921538759\n[ Info: Found excitations for momentum = 2.0943951023931953\n[ Info: Found excitations for momentum = 1.4660765716752369\n[ Info: Found excitations for momentum = 0.0\n[ Info: Found excitations for momentum = 0.20943951023931953\n[ Info: Found excitations for momentum = 1.2566370614359172\n[ Info: Found excitations for momentum = 0.41887902047863906\n[ Info: Found excitations for momentum = 2.9321531433504737\n[ Info: Found excitations for momentum = 2.303834612632515\n[ Info: Found excitations for momentum = 2.722713633111154\n[ Info: Found excitations for momentum = 2.5132741228718345\n[ Info: Found excitations for momentum = 3.141592653589793\n[ Info: Found excitations for momentum = 0.6283185307179586\n[ Info: Found excitations for momentum = 1.0471975511965976\n[ Info: Found excitations for momentum = 0.8377580409572781\nminimum @k = 3.141592653589793:\t ΔE = 0.4104792484203954\n","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"plot(kspace, real.(Es); xaxis=\"momentum\", yaxis=\"ΔE\", label=\"S = 1\")","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"This page was generated using Literate.jl.","category":"page"},{"location":"references/#References","page":"References","title":"References","text":"","category":"section"},{"location":"references/#Publications-using-MPSKit","page":"References","title":"Publications using MPSKit","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Below you can find a list of publications that have made use of MPSKit. If you have used this package and wish to have your publication added to this list, please open a pull request or an issue on the GitHub repository.","category":"page"},{"location":"references/#2025","page":"References","title":"2025","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Capponi, S.; Devos, L.; Lecheminant, P.; Totsuka, K. and Vanderstraeten, L. (2025). Non-Landau Quantum Phase Transition in Modulated SU(N) Heisenberg Spin Chains. Physical Review B 111, L020404.\n\n\n\nMortier, Q.; Devos, L.; Burgelman, L.; Vanhecke, B.; Bultinck, N.; Verstraete, F.; Haegeman, J. and Vanderstraeten, L. (2025). Fermionic Tensor Network Methods. SciPost Physics 18, 012.\n\n\n\n","category":"page"},{"location":"references/#2024","page":"References","title":"2024","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Belyansky, R.; Whitsitt, S.; Mueller, N.; Fahimniya, A.; Bennewitz, E. R.; Davoudi, Z. and Gorshkov, A. V. (2024). High-Energy Collision of Quarks and Mesons in the Schwinger Model: From Tensor Networks to Circuit QED. Physical Review Letters 132, 091903.\n\n\n\nCrotti, S.; Barthel, T. and Braunstein, A. (2024). Nonequilibrium Steady-State Dynamics of Markov Processes on Graphs, arXiv.2411.19100, arXiv:2411.19100 [cond-mat].\n\n\n\nRogerson, D. and Roy, A. (2024). Quantum Circuit Optimization Using Differentiable Programming of Tensor Network States, arXiv:2408.12583, arXiv:2408.12583 [quant-ph].\n\n\n\nUeda, A.; Inamura, K. and Ohmori, K. (2024). Chiral Edge States Emerging on Anyon-Net, arXiv:2408.02724, arXiv:2408.02724 [cond-mat].\n\n\n\nWeerda, E. L. and Rizzi, M. (2024). Fractional Quantum Hall States with Variational Projected Entangled-Pair States: A Study of the Bosonic Harper-Hofstadter Model. Physical Review B 109, L241117.\n\n\n\n","category":"page"},{"location":"references/#2023","page":"References","title":"2023","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Zhang, Y.; Hulsch, A.; Zhang, H.-C.; Tang, W.; Wang, L. and Tu, H.-H. (2023). Universal Scaling of Klein Bottle Entropy near Conformal Critical Points. Physical Review Letters 130, 151602.\n\n\n\n","category":"page"},{"location":"references/#2022","page":"References","title":"2022","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Devos, L.; Vanderstraeten, L. and Verstraete, F. (2022). Haldane Gap in the SU(3) [3 0 0] Heisenberg Chain. Physical Review B 106, 155103.\n\n\n\nHalimeh, J. C.; Damme, M. V.; Zache, T. V.; Banerjee, D. and Hauke, P. (2022). Achieving the Quantum Field Theory Limit in Far-from-Equilibrium Quantum Link Models. Quantum 6, 878.\n\n\n\nRoose, G.; Haegeman, J.; Van Acoleyen, K.; Vanderstraeten, L. and Bultinck, N. (2022). The Chiral Gross-Neveu Model on the Lattice via a Landau-forbidden Phase Transition. Journal of High Energy Physics 2022, 19.\n\n\n\nVan Damme, M.; Zache, T. V.; Banerjee, D.; Hauke, P. and Halimeh, J. C. (2022). Dynamical Quantum Phase Transitions in Spin-S U(1) Quantum Link Models. Physical Review B 106, 245110.\n\n\n\nVanhove, R.; Lootens, L.; Van Damme, M.; Wolf, R.; Osborne, T. J.; Haegeman, J. and Verstraete, F. (2022). Critical Lattice Model for a Haagerup Conformal Field Theory. Physical Review Letters 128, 231602.\n\n\n\n","category":"page"},{"location":"references/#2021","page":"References","title":"2021","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Halimeh, J. C.; Trapin, D.; Van Damme, M. and Heyl, M. (2021). Local Measures of Dynamical Quantum Phase Transitions. Physical Review B 104, 075130.\n\n\n\nHauru, M.; Van Damme, M. and Haegeman, J. (2021). Riemannian Optimization of Isometric Tensor Networks. SciPost Physics 10, 040.\n\n\n\nRoose, G.; Bultinck, N.; Vanderstraeten, L.; Verstraete, F.; Van Acoleyen, K. and Haegeman, J. (2021). Lattice Regularisation and Entanglement Structure of the Gross-Neveu Model. Journal of High Energy Physics 2021, 207.\n\n\n\nVan Damme, M.; Vanhove, R.; Haegeman, J.; Verstraete, F. and Vanderstraeten, L. (2021). Efficient Matrix Product State Methods for Extracting Spectral Information on Rings and Cylinders. Physical Review B 104, 115142.\n\n\n\nYu, C. and Lee, J.-W. (2021). Closing of the Haldane Gap in a Spin-1 XXZ Chain. Journal of the Korean Physical Society 79, 841–845.\n\n\n\n","category":"page"},{"location":"references/#2019","page":"References","title":"2019","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Roose, G.; Vanderstraeten, L.; Haegeman, J. and Bultinck, N. (2019). Anomalous Domain Wall Condensation in a Modified Ising Chain. Physical Review B 99, 195132.\n\n\n\n","category":"page"},{"location":"references/#Full-list-of-references","page":"References","title":"Full list of references","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Chepiga, N. and Mila, F. (2017). Excitation Spectrum and Density Matrix Renormalization Group Iterations. Physical Review B 96, 054425.\n\n\n\nHaegeman, J.; Cirac, J. I.; Osborne, T. J.; Pižorn, I.; Verschelde, H. and Verstraete, F. (2011). Time-Dependent Variational Principle for Quantum Lattices. Physical Review Letters 107, 070601.\n\n\n\nHaegeman, J.; Michalakis, S.; Nachtergaele, B.; Osborne, T. J.; Schuch, N. and Verstraete, F. (2013). Elementary Excitations in Gapped Quantum Spin Systems. Physical Review Letters 111, 080401.\n\n\n\nJeckelmann, E. (2002). Dynamical Density-Matrix Renormalization-Group Method. Physical Review B 66, 045114.\n\n\n\nPaeckel, S.; Köhler, T.; Swoboda, A.; Manmana, S. R.; Schollwöck, U. and Hubig, C. (2019). Time-Evolution Methods for Matrix-Product States. Annals of Physics 411, 167998.\n\n\n\nPollmann, F.; Mukerjee, S.; Turner, A. M. and Moore, J. E. (2009). Theory of Finite-Entanglement Scaling at One-Dimensional Quantum Critical Points. Physical Review Letters 102, 255701.\n\n\n\nVan Damme, M.; Haegeman, J.; McCulloch, I. and Vanderstraeten, L. (2024). Efficient Higher-Order Matrix Product Operators for Time Evolution. SciPost Physics 17, 135.\n\n\n\nVanderstraeten, L.; Haegeman, J. and Verstraete, F. (2019). Tangent-Space Methods for Uniform Matrix Product States. SciPost Physics Lecture Notes, 7.\n\n\n\nVanhecke, B.; Van Damme, M.; Haegeman, J.; Vanderstraeten, L. and Verstraete, F. (2021). Tangent-Space Methods for Truncating Uniform MPS. SciPost Physics Core 4, 004.\n\n\n\nZaletel, M. P.; Mong, R. S.; Karrasch, C.; Moore, J. E. and Pollmann, F. (2015). Time-Evolving a Matrix Product State with Long-Ranged Interactions. Physical Review B 91, 165112.\n\n\n\nZauner-Stauber, V.; Vanderstraeten, L.; Fishman, M. T.; Verstraete, F. and Haegeman, J. (2018). Variational Optimization Algorithms for Uniform Matrix Product States. Physical Review B 97, 045145.\n\n\n\n","category":"page"},{"location":"lib/lib/#Library-documentation","page":"Library","title":"Library documentation","text":"","category":"section"},{"location":"lib/lib/","page":"Library","title":"Library","text":"Modules = [MPSKit]","category":"page"},{"location":"lib/lib/#MPSKit.WI","page":"Library","title":"MPSKit.WI","text":"const WI = TaylorCluster(; N=1, extension=false, compression=false)\n\nFirst order Taylor expansion for a time-evolution MPO.\n\n\n\n\n\n","category":"constant"},{"location":"lib/lib/#MPSKit.AbstractMPO","page":"Library","title":"MPSKit.AbstractMPO","text":"abstract type AbstractMPO{O} <: AbstractVector{O} end\n\nAbstract supertype for Matrix Product Operators (MPOs).\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.AbstractMPSEnvironments","page":"Library","title":"MPSKit.AbstractMPSEnvironments","text":"abstract type AbstractEnvironments end\n\nAbstract supertype for all environment types.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.Algorithm","page":"Library","title":"MPSKit.Algorithm","text":"abstract type Algorithm\n\nAbstract supertype for all algorithm structs. These can be thought of as NamedTuples that hold the settings for a given algorithm, which can be used for dispatch. Additionally, the constructors can be used to provide default values and input sanitation.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.ChepigaAnsatz","page":"Library","title":"MPSKit.ChepigaAnsatz","text":"struct ChepigaAnsatz{A<:KrylovKit.KrylovAlgorithm} <: MPSKit.Algorithm\n\nSingle-site optimization algorithm for excitations on top of MPS groundstates.\n\nFields\n\nalg::KrylovKit.KrylovAlgorithm: algorithm used for the eigenvalue solvers\n\nConstructors\n\nChepigaAnsatz()\nChepigaAnsatz(; kwargs...)\nChepigaAnsatz(alg)\n\nCreate a ChepigaAnsatz algorithm with the given eigensolver, or by passing the keyword arguments to [Arnoldi][@extref KrylovKit.Arnoldi].\n\nReferences\n\nChepiga et al. Phys. Rev. B 96 (2017) \n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.ChepigaAnsatz2","page":"Library","title":"MPSKit.ChepigaAnsatz2","text":"ChepigaAnsatz2 <: Algorithm\n\nTwo-site optimization algorithm for excitations on top of MPS groundstates.\n\nFields\n\nalg::A = Defaults.eigsolver: algorithm to use for the eigenvalue problem.\ntrscheme = Defaults.trscheme: algorithm to use for truncation.\n\nConstructors\n\nChepigaAnsatz2()\nChepigaAnsatz2(; kwargs...)\nChepigaAnsatz2(alg, trscheme)\n\nCreate a ChepigaAnsatz2 algorithm with the given eigensolver and truncation, or by passing the keyword arguments to Arnoldi.\n\nReferences\n\nChepiga et al. Phys. Rev. B 96 (2017) \n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.DDMRG_Flavour","page":"Library","title":"MPSKit.DDMRG_Flavour","text":"abstract type DDMRG_Flavour\n\nAbstract supertype for the different flavours of dynamical DMRG.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.DMRG","page":"Library","title":"MPSKit.DMRG","text":"struct DMRG{A, F} <: MPSKit.Algorithm\n\nSingle-site DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\nverbosity::Int64: setting for how much information is displayed\neigalg::Any: algorithm used for the eigenvalue solvers\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.DMRG2","page":"Library","title":"MPSKit.DMRG2","text":"struct DMRG2{A, F} <: MPSKit.Algorithm\n\nTwo-site DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\nverbosity::Int64: setting for how much information is displayed\neigalg::Any: algorithm used for the eigenvalue solvers\ntrscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.DynamicalDMRG","page":"Library","title":"MPSKit.DynamicalDMRG","text":"struct DynamicalDMRG{F<:MPSKit.DDMRG_Flavour, S} <: MPSKit.Algorithm\n\nA dynamical DMRG method for calculating dynamical properties and excited states, based on a variational principle for dynamical correlation functions.\n\nFields\n\nflavour::MPSKit.DDMRG_Flavour: flavour of the algorithm to use, either of type NaiveInvert or Jeckelmann\nsolver::Any: algorithm used for the linear solvers\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\n\nReferences\n\nJeckelmann. Phys. Rev. B 66 (2002)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.FiniteEnvironments","page":"Library","title":"MPSKit.FiniteEnvironments","text":"struct FiniteEnvironments <: AbstractMPSEnvironments\n\nEnvironment manager for FiniteMPS and WindowMPS. This structure is responsable for automatically checking if the queried environment is still correctly cached and if not recalculates.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.FiniteExcited","page":"Library","title":"MPSKit.FiniteExcited","text":"struct FiniteExcited{A} <: MPSKit.Algorithm\n\nVariational optimization algorithm for excitations of finite MPS by minimizing the energy of\n\nH - λᵢ ψᵢψᵢ\n\nFields\n\ngsalg::Any: optimization algorithm\nweight::Float64: energy penalty for enforcing orthogonality with previous states\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.FiniteMPO","page":"Library","title":"MPSKit.FiniteMPO","text":"FiniteMPO(Os::Vector{O}) -> FiniteMPO{O}\nFiniteMPO(O::AbstractTensorMap{S,N,N}) where {S,N} -> FiniteMPO{O<:MPOTensor}\n\nMatrix Product Operator (MPO) acting on a finite tensor product space with a linear order.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.FiniteMPS","page":"Library","title":"MPSKit.FiniteMPS","text":"FiniteMPS{A<:GenericMPSTensor,B<:MPSBondTensor} <: AbstractFiniteMPS\n\nType that represents a finite Matrix Product State.\n\nProperties\n\nAL – left-gauged MPS tensors\nAR – right-gauged MPS tensors\nAC – center-gauged MPS tensors\nC – gauge tensors\ncenter – location of the gauge center\n\nThe center property returns center::HalfInt that indicates the location of the MPS center:\n\nisinteger(center) → center is a whole number and indicates the location of the first AC tensor present in the underlying ψ.ACs field.\nishalfodd(center) → center is a half-odd-integer, meaning that there are no AC tensors, and indicating between which sites the bond tensor lives.\n\ne.g mps.center = 7/2 means that the bond tensor is to the right of the 3rd site and can be accessed via mps.C[3].\n\nNotes\n\nBy convention, we have that:\n\nAL[i] * C[i] = AC[i] = C[i-1] * AR[i]\nAL[i]' * AL[i] = 1\nAR[i] * AR[i]' = 1\n\n\n\nConstructors\n\nFiniteMPS([f, eltype], physicalspaces::Vector{<:Union{S,CompositeSpace{S}}},\n maxvirtualspaces::Union{S,Vector{S}};\n normalize=true, left=oneunit(S), right=oneunit(S)) where {S<:ElementarySpace}\nFiniteMPS([f, eltype], N::Int, physicalspace::Union{S,CompositeSpace{S}},\n maxvirtualspaces::Union{S,Vector{S}};\n normalize=true, left=oneunit(S), right=oneunit(S)) where {S<:ElementarySpace}\nFiniteMPS(As::Vector{<:GenericMPSTensor}; normalize=false, overwrite=false)\n\nConstruct an MPS via a specification of physical and virtual spaces, or from a list of tensors As. All cases reduce to the latter. In particular, a state with a non-trivial total charge can be constructed by passing a non-trivially charged vector space as the left or right virtual spaces.\n\nArguments\n\nAs::Vector{<:GenericMPSTensor}: vector of site tensors\nf::Function=rand: initializer function for tensor data\neltype::Type{<:Number}=ComplexF64: scalar type of tensors\nphysicalspaces::Vector{<:Union{S, CompositeSpace{S}}: list of physical spaces\nN::Int: number of sites\nphysicalspace::Union{S,CompositeSpace{S}}: local physical space\nvirtualspaces::Vector{<:Union{S, CompositeSpace{S}}: list of virtual spaces\nmaxvirtualspace::S: maximum virtual space\n\nKeywords\n\nnormalize=true: normalize the constructed state\noverwrite=false: overwrite the given input tensors\nleft=oneunit(S): left-most virtual space\nright=oneunit(S): right-most virtual space\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.GradientGrassmann","page":"Library","title":"MPSKit.GradientGrassmann","text":"struct GradientGrassmann{O<:OptimKit.OptimizationAlgorithm, F} <: MPSKit.Algorithm\n\nVariational gradient-based optimization algorithm that keeps the MPS in left-canonical form, as points on a Grassmann manifold. The optimization is then a Riemannian gradient descent with a preconditioner to induce the metric from the Hilbert space inner product.\n\nFields\n\nmethod::OptimKit.OptimizationAlgorithm: optimization algorithm\nfinalize!::Any: callback function applied after each iteration, of signature finalize!(x, f, g, numiter) -> x, f, g\n\nReferences\n\nHauru et al. SciPost Phys. 10 (2021)\n\n\n\nConstructors\n\nGradientGrassmann(; kwargs...)\n\nKeywords\n\nmethod=ConjugateGradient: instance of optimization algorithm, or type of optimization algorithm to construct\nfinalize!: finalizer algorithm\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: level of information display\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.IDMRG","page":"Library","title":"MPSKit.IDMRG","text":"struct IDMRG{A} <: MPSKit.Algorithm\n\nSingle site infinite DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_gauge::Any: algorithm used for gauging the MPS\nalg_eigsolve::Any: algorithm used for the eigenvalue solvers\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.IDMRG2","page":"Library","title":"MPSKit.IDMRG2","text":"struct IDMRG2{A} <: MPSKit.Algorithm\n\nTwo-site infinite DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_gauge::Any: algorithm used for gauging the MPS\nalg_eigsolve::Any: algorithm used for the eigenvalue solvers\ntrscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.InfiniteEnvironments","page":"Library","title":"MPSKit.InfiniteEnvironments","text":"InfiniteEnvironments <: AbstractMPSEnvironments\n\nEnvironments for an infinite MPS-MPO-MPS combination. These solve the corresponding fixedpoint equations:\n\nGLsi * T_LLi = λ GLsi + 1\nT_RRi * GRsi = λ GRsi - 1\n\nwhere T_LL and T_RR are the (regularized) transfer matrix operators on a give site for AL-O-AL and AR-O-AR respectively.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.InfiniteMPO","page":"Library","title":"MPSKit.InfiniteMPO","text":"InfiniteMPO(Os::PeriodicVector{O}) -> InfiniteMPO{O}\n\nMatrix Product Operator (MPO) acting on an infinite tensor product space with a linear order.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.InfiniteMPS","page":"Library","title":"MPSKit.InfiniteMPS","text":"InfiniteMPS{A<:GenericMPSTensor,B<:MPSBondTensor} <: AbtractMPS\n\nType that represents an infinite Matrix Product State.\n\nFields\n\nAL – left-gauged MPS tensors\nAR – right-gauged MPS tensors\nAC – center-gauged MPS tensors\nC – gauge tensors\n\nNotes\n\nBy convention, we have that:\n\nAL[i] * C[i] = AC[i] = C[i-1] * AR[i]\nAL[i]' * AL[i] = 1\nAR[i] * AR[i]' = 1\n\n\n\nConstructors\n\nInfiniteMPS([f, eltype], physicalspaces::Vector{<:Union{S, CompositeSpace{S}},\n virtualspaces::Vector{<:Union{S, CompositeSpace{S}};\n kwargs...) where {S<:ElementarySpace}\nInfiniteMPS(As::AbstractVector{<:GenericMPSTensor}; kwargs...)\nInfiniteMPS(ALs::AbstractVector{<:GenericMPSTensor}, C₀::MPSBondTensor;\n kwargs...)\n\nConstruct an MPS via a specification of physical and virtual spaces, or from a list of tensors As, or a list of left-gauged tensors ALs.\n\nArguments\n\nAs::AbstractVector{<:GenericMPSTensor}: vector of site tensors\nALs::AbstractVector{<:GenericMPSTensor}: vector of left-gauged site tensors\nC₀::MPSBondTensor: initial gauge tensor\nf::Function=rand: initializer function for tensor data\neltype::Type{<:Number}=ComplexF64: scalar type of tensors\nphysicalspaces::AbstractVector{<:Union{S, CompositeSpace{S}}: list of physical spaces\nvirtualspaces::AbstractVector{<:Union{S, CompositeSpace{S}}: list of virtual spaces\n\nKeywords\n\ntol: gauge fixing tolerance\nmaxiter: gauge fixing maximum iterations\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.InfiniteQPEnvironments","page":"Library","title":"MPSKit.InfiniteQPEnvironments","text":"InfiniteQPEnvironments <: AbstractMPSEnvironments\n\nEnvironments for an infinite QP-MPO-QP combination. These solve the corresponding fixedpoint equations:\n\nGLsi * T_BLi + GBLsi * T_RLi = GBLsi + 1\nT_BRi * GRsi + T_LRi * GBRsi = GBRsi - 1\n\nwhere T_BL, T_BR, T_RL and T_LR are the (regularized) transfer matrix operators on a given site for B-O-AL, B-O-AR, AR-O-AL and AL-O-AR respectively.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.Jeckelmann","page":"Library","title":"MPSKit.Jeckelmann","text":"struct Jeckelmann <: MPSKit.DDMRG_Flavour\n\nThe original flavour of dynamical DMRG, which minimizes the following (quadratic) cost function:\n\n (H - E) ψ₀ - ψ \n\nSee also NaiveInvert for a less costly but less accurate alternative.\n\nReferences\n\nJeckelmann. Phys. Rev. B 66 (2002)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.LazySum","page":"Library","title":"MPSKit.LazySum","text":"LazySum{O} <: AbstractVector{O}\n\nType that represents a lazy sum i.e explicit summation is only done when needed. This type is basically an AbstractVector with some extra functionality to calculate things efficiently.\n\nFields\n\nops – Vector of summable objects\n\n\n\nConstructors\n\nLazySum(x::Vector)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.LeftCanonical","page":"Library","title":"MPSKit.LeftCanonical","text":"struct LeftCanonical <: MPSKit.Algorithm\n\nAlgorithm for bringing an InfiniteMPS into the left-canonical form.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_orth::Any: algorithm used for orthogonalization of the tensors\nalg_eigsolve::Any: algorithm used for the eigensolver\neig_miniter::Int64: minimal amount of iterations before using the eigensolver steps\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MPO","page":"Library","title":"MPSKit.MPO","text":"struct MPO{O,V<:AbstractVector{O}} <: AbstractMPO{O}\n\nMatrix Product Operator (MPO) acting on a tensor product space with a linear order.\n\nSee also: FiniteMPO, InfiniteMPO\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MPOHamiltonian","page":"Library","title":"MPSKit.MPOHamiltonian","text":"MPOHamiltonian(lattice::AbstractArray{<:VectorSpace}, local_operators...)\nMPOHamiltonian(lattice::AbstractArray{<:VectorSpace})\nMPOHamiltonian(x::AbstractArray{<:Any,3})\n\nMPO representation of a hamiltonian. This is a specific form of an AbstractMPO, where all the sites are represented by an upper triangular block matrix of the following form:\n\nbeginpmatrix\n1 C D \n0 A B \n0 0 1\nendpmatrix\n\nwhere A, B, C, and D are MPOTensors, or (sparse) blocks thereof.\n\nExamples\n\nFor example, constructing a nearest-neighbour Hamiltonian would look like this:\n\nlattice = fill(ℂ^2, 10)\nH = MPOHamiltonian(lattice, (i, i+1) => O for i in 1:length(lattice)-1)\n\nSee also instantiate_operator, which is responsable for instantiating the local operators in a form that is compatible with this constructor.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MPOTensor","page":"Library","title":"MPSKit.MPOTensor","text":"MPOTensor{S}\n\nTensor type for representing local MPO tensors, with the index convention W ⊗ S ← N ⊗ E, where N, E, S and W denote the north, east, south and west virtual spaces respectively.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MPO_∂∂C","page":"Library","title":"MPSKit.MPO_∂∂C","text":"Draft operators\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MPSTensor","page":"Library","title":"MPSKit.MPSTensor","text":"MPSTensor([f, eltype], d::Int, Dₗ::Int, [Dᵣ]::Int])\n\nConstruct an MPSTensor with given physical and virtual dimensions.\n\nArguments\n\nf::Function=rand: initializer function for tensor data\neltype::Type{<:Number}=ComplexF64: scalar type of tensors\nd::Int: physical dimension\nDₗ::Int: left virtual dimension\nDᵣ::Int: right virtual dimension\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MPSTensor-Union{Tuple{AbstractArray{T}}, Tuple{T}} where T<:Number","page":"Library","title":"MPSKit.MPSTensor","text":"MPSTensor(A::AbstractArray)\n\nConvert an array to an MPSTensor.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.MPSTensor-Union{Tuple{S}, Tuple{UndefInitializer, Any, Union{TensorKit.CompositeSpace{S}, S}, S}, Tuple{UndefInitializer, Any, Union{TensorKit.CompositeSpace{S}, S}, S, S}} where S<:TensorKit.ElementarySpace","page":"Library","title":"MPSKit.MPSTensor","text":"MPSTensor([f, eltype], d::Int, left_D::Int, [right_D]::Int])\nMPSTensor([f, eltype], physicalspace::Union{S,CompositeSpace{S}}, \n left_virtualspace::S, [right_virtualspace]::S) where {S<:ElementarySpace}\n\nConstruct an MPSTensor with given physical and virtual spaces.\n\nArguments\n\nf::Function=rand: initializer function for tensor data\neltype::Type{<:Number}=ComplexF64: scalar type of tensors\nphysicalspace::Union{S,CompositeSpace{S}}: physical space\nleft_virtualspace::S: left virtual space\nright_virtualspace::S: right virtual space, defaults to equal left\nd::Int: physical dimension\nleft_D::Int: left virtual dimension\nright_D::Int: right virtual dimension\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.MixedCanonical","page":"Library","title":"MPSKit.MixedCanonical","text":"struct MixedCanonical <: MPSKit.Algorithm\n\nAlgorithm for bringing an InfiniteMPS into the mixed-canonical form.\n\nFields\n\nalg_leftcanonical::MPSKit.LeftCanonical: algorithm for bringing an InfiniteMPS into left-canonical form.\nalg_rightcanonical::MPSKit.RightCanonical: algorithm for bringing an InfiniteMPS into right-canonical form.\norder::Symbol: order in which to apply the canonicalizations, should be :L, :R, :LR or :RL\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.Multiline","page":"Library","title":"MPSKit.Multiline","text":"struct Multiline{T}\n\nObject that represents multiple lines of objects of type T. Typically used to represent multiple lines of InfiniteMPS (MultilineMPS) or MPO (Multiline{<:AbstractMPO}).\n\nFields\n\ndata::PeriodicArray{T,1}: the data of the multiline object\n\nSee also: MultilineMPS and MultilineMPO\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MultilineMPO","page":"Library","title":"MPSKit.MultilineMPO","text":"const MultilineMPO = Multiline{<:AbstractMPO}\n\nType that represents multiple lines of MPO objects.\n\nConstructors\n\nMultilineMPO(mpos::AbstractVector{<:Union{SparseMPO,DenseMPO}})\nMultilineMPO(Os::AbstractMatrix{<:MPOTensor})\n\nSee also: Multiline, AbstractMPO\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MultilineMPS","page":"Library","title":"MPSKit.MultilineMPS","text":"const MultilineMPS = Multiline{<:InfiniteMPS}\n\nType that represents multiple lines of InfiniteMPS objects.\n\nConstructors\n\nMultilineMPS(mpss::AbstractVector{<:InfiniteMPS})\nMultilineMPS([f, eltype], physicalspaces::Matrix{<:Union{S, CompositeSpace{S}},\n virtualspaces::Matrix{<:Union{S, CompositeSpace{S}}) where\n {S<:ElementarySpace}\nMultilineMPS(As::AbstractMatrix{<:GenericMPSTensor}; kwargs...)\nMultilineMPS(ALs::AbstractMatrix{<:GenericMPSTensor}, \n C₀::AbstractVector{<:MPSBondTensor}; kwargs...)\n\nSee also: Multiline\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MultipliedOperator","page":"Library","title":"MPSKit.MultipliedOperator","text":"Structure representing a multiplied operator. Consists of\n - An operator op (MPO, Hamiltonian, ...)\n - An object f that gets multiplied with the operator (Number, function, ...)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.NaiveInvert","page":"Library","title":"MPSKit.NaiveInvert","text":"struct NaiveInvert <: MPSKit.DDMRG_Flavour\n\nAn alternative approach to the dynamical DMRG algorithm, without quadratic terms but with a less controlled approximation. This algorithm minimizes the following cost function\n\nψ(H - E)ψ - ψψ₀ - ψ₀ψ\n\nwhich is equivalent to the original approach if\n\nψ₀ = (H - E)ψ\n\nSee also Jeckelmann for the original approach.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.OptimalExpand","page":"Library","title":"MPSKit.OptimalExpand","text":"struct OptimalExpand <: MPSKit.Algorithm\n\nAn algorithm that expands the given mps as described in Zauner-Stauber et al. Phys. Rev. B 97 (2018), by selecting the dominant contributions of a two-site updated MPS tensor, orthogonal to the original ψ.\n\nFields\n\ntrscheme::TensorKit.TruncationScheme: algorithm used for truncating the expanded space\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.PeriodicArray","page":"Library","title":"MPSKit.PeriodicArray","text":"PeriodicArray{T,N} <: AbstractArray{T,N}\n\nArray wrapper with periodic boundary conditions.\n\nFields\n\ndata::Array{T,N}: the data of the array\n\nExamples\n\nA = PeriodicArray([1, 2, 3])\nA[0], A[2], A[4]\n\n# output\n\n(3, 2, 1)\n\nA = PeriodicArray([1 2; 3 4])\nA[-1, 1], A[1, 1], A[4, 5]\n\n# output\n\n(1, 1, 3)\n\nSee also PeriodicVector, PeriodicMatrix\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.PeriodicMatrix","page":"Library","title":"MPSKit.PeriodicMatrix","text":"PeriodicMatrix{T}\n\nTwo-dimensional dense array with elements of type T and periodic boundary conditions. Alias for PeriodicArray{T,2}.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.PeriodicVector","page":"Library","title":"MPSKit.PeriodicVector","text":"PeriodicVector{T}\n\nOne-dimensional dense array with elements of type T and periodic boundary conditions. Alias for PeriodicArray{T,1}.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.QuasiparticleAnsatz","page":"Library","title":"MPSKit.QuasiparticleAnsatz","text":"struct QuasiparticleAnsatz{A} <: MPSKit.Algorithm\n\nOptimization algorithm for quasi-particle excitations on top of MPS groundstates.\n\nFields\n\nalg::Any: algorithm used for the eigenvalue solvers\n\nConstructors\n\nQuasiparticleAnsatz()\nQuasiparticleAnsatz(; kwargs...)\nQuasiparticleAnsatz(alg)\n\nCreate a QuasiparticleAnsatz algorithm with the given algorithm, or by passing the keyword arguments to Arnoldi.\n\nReferences\n\nHaegeman et al. Phys. Rev. Let. 111 (2013)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.RandExpand","page":"Library","title":"MPSKit.RandExpand","text":"struct RandExpand <: MPSKit.Algorithm\n\nAn algorithm that expands the bond dimension by adding random unitary vectors that are orthogonal to the existing state. This is achieved by performing a truncated SVD on a random two-site MPS tensor, which is made orthogonal to the existing state.\n\nFields\n\ntrscheme::TensorKit.TruncationScheme: algorithm used for [truncation](@extref TensorKit.tsvd] the expanded space\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.RightCanonical","page":"Library","title":"MPSKit.RightCanonical","text":"struct RightCanonical <: MPSKit.Algorithm\n\nAlgorithm for bringing an InfiniteMPS into the right-canonical form.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_orth::Any: algorithm used for orthogonalization of the tensors\nalg_eigsolve::Any: algorithm used for the eigensolver\neig_miniter::Int64: minimal amount of iterations before using the eigensolver steps\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.SvdCut","page":"Library","title":"MPSKit.SvdCut","text":"struct SvdCut <: MPSKit.Algorithm\n\nAn algorithm that uses truncated SVD to change the bond dimension of a ψ.\n\nFields\n\ntrscheme::TensorKit.TruncationScheme: algorithm used for [truncation][@extref TensorKit.tsvd] of the gauge tensors\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.TDVP","page":"Library","title":"MPSKit.TDVP","text":"struct TDVP{A, F} <: MPSKit.Algorithm\n\nSingle site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.\n\nFields\n\nintegrator::Any: algorithm used in the exponential solvers\ntolgauge::Float64: tolerance for gauging algorithm\ngaugemaxiter::Int64: maximal amount of iterations for gauging algorithm\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\n\nReferences\n\nHaegeman et al. Phys. Rev. Lett. 107 (2011)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.TDVP2","page":"Library","title":"MPSKit.TDVP2","text":"struct TDVP2{A, F} <: MPSKit.Algorithm\n\nTwo-site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.\n\nFields\n\nintegrator::Any: algorithm used in the exponential solvers\ntolgauge::Float64: tolerance for gauging algorithm\ngaugemaxiter::Int64: maximal amount of iterations for gauging algorithm\ntrscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\n\nReferences\n\nHaegeman et al. Phys. Rev. Lett. 107 (2011)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.TaylorCluster","page":"Library","title":"MPSKit.TaylorCluster","text":"struct TaylorCluster <: MPSKit.Algorithm\n\nAlgorithm for constructing the Nth order time evolution MPO using the Taylor cluster expansion.\n\nFields\n\nN::Int64: order of the Taylor expansion\nextension::Bool: include higher-order corrections\ncompression::Bool: approximate compression of corrections, accurate up to order N\n\nReferences\n\nVan Damme et al. SciPost Phys. 17 (2024)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.TimedOperator","page":"Library","title":"MPSKit.TimedOperator","text":"Structure representing a time-dependent operator. Consists of\n - An operator op (MPO, Hamiltonian, ...)\n - An function f that gives the time-dependence according to op(t) = f(t)*op\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.UnionAlg","page":"Library","title":"MPSKit.UnionAlg","text":"struct UnionAlg{A, B} <: MPSKit.Algorithm\n\nAlgorithm wrapper representing the sequential application of two algorithms.\n\nFields\n\nalg1::Any: first algorithm\nalg2::Any: second algorithm\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.UntimedOperator","page":"Library","title":"MPSKit.UntimedOperator","text":"Structure representing a time-independent operator that will be multiplied with a constant coefficient. Consists of\n - An operator (MPO, Hamiltonian, ...)\n - A number f that gets multiplied with the operator\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.VOMPS","page":"Library","title":"MPSKit.VOMPS","text":"struct VOMPS{F} <: MPSKit.Algorithm\n\nPower method algorithm for finding dominant eigenvectors of infinite MPOs. This method works by iteratively approximating the product of an operator and a state with a new state of the same bond dimension.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_gauge::Any: algorithm used for gauging the InfiniteMPS\nalg_environments::Any: algorithm used for the MPS environments\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\n\nReferences\n\nVanhecke et al. SciPost Phys. Core 4 (2021)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.VUMPS","page":"Library","title":"MPSKit.VUMPS","text":"struct VUMPS{F} <: MPSKit.Algorithm\n\nVariational optimization algorithm for uniform matrix product states, based on the combination of DMRG with matrix product state tangent space concepts.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_gauge::Any: algorithm used for gauging the InfiniteMPS\nalg_eigsolve::Any: algorithm used for the eigenvalue solvers\nalg_environments::Any: algorithm used for the MPS environments\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\n\nReferences\n\nZauner-Stauber et al. Phys. Rev. B 97 (2018)\nVanderstraeten et al. SciPost Phys. Lect. Notes 7 (2019)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.VUMPSSvdCut","page":"Library","title":"MPSKit.VUMPSSvdCut","text":"struct VUMPSSvdCut <: MPSKit.Algorithm\n\nAn algorithm that uses a two-site update step to change the bond dimension of a state.\n\nFields\n\ntol_gauge::Any: tolerance for gauging algorithm\ntol_eigenval::Any: tolerance for the eigenvalue solver\ntrscheme::TensorKit.TruncationScheme: algorithm used for [truncation][@extref TensorKit.tsvd] of the two-site update\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.WII","page":"Library","title":"MPSKit.WII","text":"struct WII <: MPSKit.Algorithm\n\nGeneralization of the Euler approximation of the operator exponential for MPOs.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal number of iterations\n\nReferences\n\nZaletel et al. Phys. Rev. B 91 (2015)\nPaeckel et al. Ann. of Phys. 411 (2019)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.WindowArray","page":"Library","title":"MPSKit.WindowArray","text":"WindowArray{T} <: AbstractVector{T}\n\nA vector embedded in a periodic environment to the left and right, which can be accessed with arbitrary integer indices. The middle part is a regular Vector{T} and the left and right parts are PeriodicVector{T}s.\n\nThis vector inherits most of its properties from the middle part, including its length and axes. Nevertheless, indexing operations are overloaded to allow for out-of-bounds access, which is resolved by the periodic enviroments.\n\nSee also PeriodicVector.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.WindowMPS","page":"Library","title":"MPSKit.WindowMPS","text":"WindowMPS{A<:GenericMPSTensor,B<:MPSBondTensor} <: AbstractFiniteMPS\n\nType that represents a finite Matrix Product State embedded in an infinte Matrix Product State.\n\nFields\n\nleft_gs::InfiniteMPS – left infinite environment\nwindow::FiniteMPS – finite window Matrix Product State\nright_gs::InfiniteMPS – right infinite environment\n\n\n\nConstructors\n\nWindowMPS(left_gs::InfiniteMPS, window_state::FiniteMPS, [right_gs::InfiniteMPS])\nWindowMPS(left_gs::InfiniteMPS, window_tensors::AbstractVector, [right_gs::InfiniteMPS])\nWindowMPS([f, eltype], physicalspaces::Vector{<:Union{S, CompositeSpace{S}},\n virtualspaces::Vector{<:Union{S, CompositeSpace{S}}, left_gs::InfiniteMPS,\n [right_gs::InfiniteMPS])\nWindowMPS([f, eltype], physicalspaces::Vector{<:Union{S,CompositeSpace{S}}},\n maxvirtualspace::S, left_gs::InfiniteMPS, [right_gs::InfiniteMPS])\n\nConstruct a WindowMPS via a specification of left and right infinite environment, and either a window state or a vector of tensors to construct the window. Alternatively, it is possible to supply the same arguments as for the constructor of FiniteMPS, followed by a left (and right) environment to construct the WindowMPS in one step.\n\nnote: Note\nBy default, the right environment is chosen to be equal to the left, however no copy is made. In this case, changing the left state will also affect the right state.WindowMPS(state::InfiniteMPS, L::Int)\n\nConstruct a WindowMPS from an InfiniteMPS, by promoting a region of length L to a FiniteMPS.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit._gaugecenter-Tuple{FiniteMPS}","page":"Library","title":"MPSKit._gaugecenter","text":"_gaugecenter(ψ::FiniteMPS)::HalfInt\n\nReturn the location of the MPS center.\n\ncenter::HalfInt:\n\nisinteger(center) → center is a whole number and indicates the location of the first AC tensor present in ψ.ACs\nishalfodd(center) → center is a half-odd-integer, meaning that there are no AC tensors, and indicating between which sites the bond tensor lives.\n\nExample\n\nψ = FiniteMPS(3, ℂ^2, ℂ^16)\nψ.center # returns 7/2, bond tensor is to the right of the 3rd site\nψ.AC[1] # moves center to first site\nψ.center # returns 1\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.add_util_leg-Union{Tuple{TensorKit.AbstractTensorMap{T, S, N1, N2}}, Tuple{N2}, Tuple{N1}, Tuple{S}, Tuple{T}} where {T, S, N1, N2}","page":"Library","title":"MPSKit.add_util_leg","text":"add_util_leg(tensor::AbstractTensorMap{S,N1,N2}) where {S,N1,N2}\n -> AbstractTensorMap{S,N1+1,N2+1}\n\nAdd trivial one-dimensional utility spaces with trivial sector to the left and right of a given tensor map, i.e. as the first space of the codomain and the last space of the domain.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.approx_angles-Tuple{Any}","page":"Library","title":"MPSKit.approx_angles","text":"Find the closest fractions of π, differing at most tol_angle\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.approximate","page":"Library","title":"MPSKit.approximate","text":"approximate(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)\napproximate!(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)\n\nCompute an approximation to the application of an operator O to the state ψ in the form of an MPS ψ₀.\n\nArguments\n\nψ₀::AbstractMPS: initial guess of the approximated state\n(O::AbstractMPO, ψ::AbstractMPS): operator O and state ψ to be approximated\nalgorithm: approximation algorithm. See below for a list of available algorithms.\n[environments]: MPS environment manager\n\nKeywords\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: display progress information\n\nAlgorithms\n\nDMRG: Alternating least square method for maximizing the fidelity with a single-site scheme.\nDMRG2: Alternating least square method for maximizing the fidelity with a two-site scheme.\nIDMRG: Variant of DMRG for maximizing fidelity density in the thermodynamic limit.\nIDMRG2: Variant of DMRG2 for maximizing fidelity density in the thermodynamic limit.\nVOMPS: Tangent space method for truncating uniform MPS.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.approximate!","page":"Library","title":"MPSKit.approximate!","text":"approximate(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)\napproximate!(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)\n\nCompute an approximation to the application of an operator O to the state ψ in the form of an MPS ψ₀.\n\nArguments\n\nψ₀::AbstractMPS: initial guess of the approximated state\n(O::AbstractMPO, ψ::AbstractMPS): operator O and state ψ to be approximated\nalgorithm: approximation algorithm. See below for a list of available algorithms.\n[environments]: MPS environment manager\n\nKeywords\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: display progress information\n\nAlgorithms\n\nDMRG: Alternating least square method for maximizing the fidelity with a single-site scheme.\nDMRG2: Alternating least square method for maximizing the fidelity with a two-site scheme.\nIDMRG: Variant of DMRG for maximizing fidelity density in the thermodynamic limit.\nIDMRG2: Variant of DMRG2 for maximizing fidelity density in the thermodynamic limit.\nVOMPS: Tangent space method for truncating uniform MPS.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.bond_type-Tuple{MPSKit.AbstractMPS}","page":"Library","title":"MPSKit.bond_type","text":"bond_type(ψ::AbstractMPS)\nbond_type(ψtype::Type{<:AbstractMPS})\n\nReturn the type of the bond tensors of an AbstractMPS.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.calc_galerkin-Tuple{Int64, Union{FiniteMPS, InfiniteMPS, WindowMPS}, Any, Any, Any}","page":"Library","title":"MPSKit.calc_galerkin","text":"calc_galerkin(above, operator, below, envs)\ncalc_galerkin(pos, above, operator, below, envs)\n\nCalculate the Galerkin error, which is the error between the solution of the original problem, and the solution of the problem projected on the tangent space. Concretely, this is the overlap of the current state with the single-site derivative, projected onto the nullspace of the current state:\n\nepsilon = VL * (VL * fracabovepartial AC_pos)\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.changebonds","page":"Library","title":"MPSKit.changebonds","text":"changebonds(ψ::AbstractMPS, H, alg, envs) -> ψ′, envs′\nchangebonds(ψ::AbstractMPS, alg) -> ψ′\n\nChange the bond dimension of ψ using the algorithm alg, and return the new ψ and the new envs.\n\nSee also: SvdCut, RandExpand, VUMPSSvdCut, OptimalExpand\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.correlation_length-Tuple{InfiniteMPS}","page":"Library","title":"MPSKit.correlation_length","text":"correlation_length(above::InfiniteMPS; kwargs...)\n\nCompute the correlation length of a given InfiniteMPS based on the next-to-leading eigenvalue of the transfer matrix. The kwargs are passed to transfer_spectrum, and can for example be used to target the correlation length in a specific sector. \n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.correlator","page":"Library","title":"MPSKit.correlator","text":"correlator(ψ, O1, O2, i, j)\ncorrelator(ψ, O12, i, j)\n\nCompute the 2-point correlator <ψ|O1[i]O2[j]|ψ> for inserting O1 at i and O2 at j. Also accepts ranges for j.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.entanglement_spectrum","page":"Library","title":"MPSKit.entanglement_spectrum","text":"entanglement_spectrum(ψ, site::Int) -> SectorDict{sectortype(ψ),Vector{<:Real}}\n\nCompute the entanglement spectrum at a given site, i.e. the singular values of the gauge matrix to the right of a given site. This is a dictionary mapping the charge to the singular values.\n\nFor InfiniteMPS and WindowMPS the default value for site is 0.\n\nFor FiniteMPS no default value for site is given, it is up to the user to specify.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.entanglementplot","page":"Library","title":"MPSKit.entanglementplot","text":"entanglementplot(state; site=0[, kwargs...])\n\nPlot the entanglement spectrum of a given MPS state. \n\nArguments\n\nstate: the MPS for which to compute the entanglement spectrum.\n\nKeyword Arguments\n\nsite::Int=0: MPS index for multisite unit cells. The spectrum is computed for the bond between site and site + 1.\nexpand_symmetry::Logical=false: add quantum dimension degeneracies.\nsortby=maximum: the method of sorting the sectors.\nsector_margin=1//10: the amount of whitespace between sectors.\nsector_formatter=string: how to convert sectors to strings.\nkwargs...: other kwargs are passed on to the plotting backend.\n\nnote: Note\nYou will need to manually import Plots.jl to be able to use this function. MPSKit.jl defines its plots based on RecipesBase.jl, but the user still has to add using Plots to be able to actually produce the plots.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.entropy-Tuple{InfiniteMPS}","page":"Library","title":"MPSKit.entropy","text":"entropy(state, [site::Int])\n\nCalculate the Von Neumann entanglement entropy of a given MPS. If an integer site is given, the entropy is across the entanglement cut to the right of site site. Otherwise, a vector of entropies is returned, one for each site.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.environment_alg-Tuple{Union{InfiniteMPS, MultilineMPS}, Union{InfiniteMPO, MultilineMPO}, Union{InfiniteMPS, MultilineMPS}}","page":"Library","title":"MPSKit.environment_alg","text":"environment_alg(above, operator, below; kwargs...)\n\nDetermine an appropriate algorithm for computing the environments, based on the given kwargs....\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.exact_diagonalization-Tuple{FiniteMPOHamiltonian}","page":"Library","title":"MPSKit.exact_diagonalization","text":"exact_diagonalization(H::FiniteMPOHamiltonian;\n sector=first(sectors(oneunit(physicalspace(H, 1)))),\n len::Int=length(H), num::Int=1, which::Symbol=:SR,\n alg=Defaults.alg_eigsolve(; dynamic_tols=false))\n -> vals, state_vecs, convhist\n\nUse KrylovKit.eigsolve to perform exact diagonalization on a FiniteMPOHamiltonian to find its eigenvectors as FiniteMPS of maximal rank, essentially equivalent to dense eigenvectors.\n\nArguments\n\nH::FiniteMPOHamiltonian: the Hamiltonian to diagonalize.\n\nKeyword arguments\n\nsector=first(sectors(oneunit(physicalspace(H, 1)))): the total charge of the eigenvectors, which is chosen trivial by default.\nlen::Int=length(H): the length of the system.\nnum::Int=1: the number of eigenvectors to find.\nwhich::Symbol=:SR: the kind eigenvalues to find, see KrylovKit.eigsolve. \nalg=Defaults.alg_eigsolve(; dynamic_tols=false): the diagonalization algorithm to use, see KrylovKit.eigsolve.\n\nnote: Valid `sector` values\nThe total charge of the eigenvectors is imposed by adding a charged auxiliary space as the leftmost virtualspace of each eigenvector. Specifically, this is achieved by passing left=Vect[typeof(sector)](sector => 1) to the FiniteMPS constructor. As such, the only valid sector values (i.e. sector values for which the corresponding eigenstates have valid fusion channels) are those that occur in the dual of the fusion of all the physical spaces in the system.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.excitations","page":"Library","title":"MPSKit.excitations","text":"excitations(H, algorithm::QuasiparticleAnsatz, momentum::Union{Number, Vector{<:Number}},\n left_ψ::InfiniteMPS, [left_environment],\n [right_ψ::InfiniteMPS], [right_environment];\n kwargs...)\n\nCreate and optimise infinite quasiparticle states.\n\nArguments\n\nH::AbstractMPO: operator for which to find the excitations\nalgorithm::QuasiparticleAnsatz: optimization algorithm\nmomentum::Union{Number, Vector{<:Number}}: momentum or list of momenta\nleft_ψ::InfiniteMPS: left groundstate\n[left_environment]: left groundstate environment\n[right_ψ::InfiniteMPS]: right groundstate\n[right_environment]: right groundstate environment\n\nKeywords\n\nnum::Int: number of excited states to compute\nsolver: algorithm for the linear solver of the quasiparticle environments\nsector=one(sectortype(left_ψ)): charge of the quasiparticle state\nparallel=true: enable multi-threading over different momenta\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.excitations-2","page":"Library","title":"MPSKit.excitations","text":"excitations(H, algorithm::QuasiparticleAnsatz, left_ψ::InfiniteMPS, [left_environment],\n [right_ψ::InfiniteMPS], [right_environment]; kwargs...)\n\nCreate and optimise finite quasiparticle states.\n\nArguments\n\nH::AbstractMPO: operator for which to find the excitations\nalgorithm::QuasiparticleAnsatz: optimization algorithm\nleft_ψ::FiniteMPS: left groundstate\n[left_environment]: left groundstate environment\n[right_ψ::FiniteMPS]: right groundstate\n[right_environment]: right groundstate environment\n\nKeywords\n\nnum::Int: number of excited states to compute\nsector=one(sectortype(left_ψ)): charge of the quasiparticle state\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.excitations-3","page":"Library","title":"MPSKit.excitations","text":"excitations(H, algorithm::QuasiparticleAnsatz, ψ::FiniteQP, [left_environments],\n [right_environments]; num=1) -> (energies, states)\nexcitations(H, algorithm::QuasiparticleAnsatz, ψ::InfiniteQP, [left_environments],\n [right_environments]; num=1, solver=Defaults.solver) -> (energies, states)\nexcitations(H, algorithm::FiniteExcited, ψs::NTuple{<:Any, <:FiniteMPS};\n num=1, init=copy(first(ψs))) -> (energies, states)\nexcitations(H, algorithm::ChepigaAnsatz, ψ::FiniteMPS, [envs];\n num=1, pos=length(ψ)÷2) -> (energies, states)\nexcitations(H, algorithm::ChepigaAnsatz2, ψ::FiniteMPS, [envs];\n num=1, pos=length(ψ)÷2) -> (energies, states)\n\nCompute the first excited states and their energy gap above a groundstate.\n\nArguments\n\nH::AbstractMPO: operator for which to find the excitations\nalgorithm: optimization algorithm\nψ::QP: initial quasiparticle guess\nψs::NTuple{N, <:FiniteMPS}: N first excited states\n[left_environments]: left groundstate environment\n[right_environments]: right groundstate environment\n\nKeywords\n\nnum::Int: number of excited states to compute\nsolver: algorithm for the linear solver of the quasiparticle environments\ninit: initial excited state guess\npos: position of perturbation\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.expectation_value","page":"Library","title":"MPSKit.expectation_value","text":"expectation_value(ψ, O, [environments])\nexpectation_value(ψ, inds => O)\n\nCompute the expectation value of an operator O on a state ψ. Optionally, it is possible to make the computations more efficient by also passing in previously calculated environments.\n\nIn general, the operator O may consist of an arbitrary MPO O <: AbstractMPO that acts on all sites, or a local operator O = inds => operator acting on a subset of sites. In the latter case, inds is a tuple of indices that specify the sites on which the operator acts, while the operator is either a AbstractTensorMap or a FiniteMPO.\n\nArguments\n\nψ::AbstractMPS : the state on which to compute the expectation value\nO::Union{AbstractMPO,Pair} : the operator to compute the expectation value of. This can either be an AbstractMPO, or a pair of indices and local operator..\nenvironments::AbstractMPSEnvironments : the environments to use for the calculation. If not given, they will be calculated.\n\nExamples\n\njulia> ψ = FiniteMPS(ones(Float64, (ℂ^2)^4));\n\njulia> S_x = TensorMap(Float64[0 1; 1 0], ℂ^2, ℂ^2);\n\njulia> round(expectation_value(ψ, 2 => S_x))\n1.0\n\njulia> round(expectation_value(ψ, (2, 3) => S_x ⊗ S_x))\n1.0\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.fidelity_susceptibility-Union{Tuple{T}, Tuple{Union{FiniteMPS, InfiniteMPS}, T, AbstractVector{T}}, Tuple{Union{FiniteMPS, InfiniteMPS}, T, AbstractVector{T}, Any}} where T<:MPOHamiltonian","page":"Library","title":"MPSKit.fidelity_susceptibility","text":"fidelity_susceptibility(state::Union{FiniteMPS,InfiniteMPS}, H₀::T,\n Vs::AbstractVector{T}, [henvs=environments(state, H₀)];\n maxiter=Defaults.maxiter,\n tol=Defaults.tol) where {T<:MPOHamiltonian}\n\nComputes the fidelity susceptibility of a the ground state state of a base Hamiltonian H₀ with respect to a set of perturbing Hamiltonians Vs. Each of the perturbing Hamiltonians can be interpreted as corresponding to a tuning parameter aᵢ in a 'total' Hamiltonian H = H₀ + ᵢ aᵢ Vᵢ.\n\nReturns a matrix containing the overlaps of the elementary excitations on top of state corresponding to each of the perturbing Hamiltonians.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.find_groundstate","page":"Library","title":"MPSKit.find_groundstate","text":"find_groundstate(ψ₀, H, [environments]; kwargs...) -> (ψ, environments, ϵ)\nfind_groundstate(ψ₀, H, algorithm, environments) -> (ψ, environments, ϵ)\n\nCompute the groundstate for Hamiltonian H with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.\n\nArguments\n\nψ₀::AbstractMPS: initial guess\nH::AbstractMPO: operator for which to find the groundstate\n[environments]: MPS environment manager\nalgorithm: optimization algorithm\n\nKeywords\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: display progress information\n\nReturns\n\nψ::AbstractMPS: converged groundstate\nenvironments: environments corresponding to the converged state\nϵ::Float64: final convergence error upon terminating the algorithm\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.fixedpoint-Tuple{Any, Any, Symbol, KrylovKit.Lanczos}","page":"Library","title":"MPSKit.fixedpoint","text":"fixedpoint(A, x₀, which::Symbol; kwargs...) -> val, vec\nfixedpoint(A, x₀, which::Symbol, alg) -> val, vec\n\nCompute the fixedpoint of a linear operator A using the specified eigensolver alg. The fixedpoint is assumed to be unique.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.fuse_mul_mpo-Tuple{Any, Any}","page":"Library","title":"MPSKit.fuse_mul_mpo","text":"fuse_mul_mpo(O1, O2)\n\nCompute the mpo tensor that arises from multiplying MPOs.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.gaugefix!","page":"Library","title":"MPSKit.gaugefix!","text":"gaugefix!(ψ::InfiniteMPS, A, C₀; kwargs...) -> ψ\ngaugefix!(ψ::InfiniteMPS, A, C₀, alg::Algorithm) -> ψ\n\nBring an InfiniteMPS into a uniform gauge, using the specified algorithm.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.instantiate_operator-Tuple{AbstractArray{<:TensorKit.VectorSpace}, Pair}","page":"Library","title":"MPSKit.instantiate_operator","text":"instantiate_operator(lattice::AbstractArray{<:VectorSpace}, O::Pair)\n\nInstantiate a local operator O on a lattice lattice as a vector of MPO tensors, and a vector of linear site indices.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.integrate","page":"Library","title":"MPSKit.integrate","text":"integrate(f, y₀, t, dt, alg)\n\nIntegrate the differential equation i dydt = f(y t) over a time step 'dt' starting from y(t₀)=y₀, using the provided algorithm.\n\nArguments\n\nf: driving function\ny₀: object to integrate\nt::Number: starting time of time-step\ndt::Number: time-step magnitude\nalg: integration scheme\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.isfullrank-Tuple{TensorKit.AbstractTensorMap{T, S, N, 1} where {S, N, T}}","page":"Library","title":"MPSKit.isfullrank","text":"isfullrank(A::GenericMPSTensor; side=:both)\n\nDetermine whether the given tensor is full rank, i.e. whether both the map from the left virtual space and the physical space to the right virtual space, and the map from the right virtual space and the physical space to the left virtual space are injective.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.l_LL-Union{Tuple{InfiniteMPS{A}}, Tuple{A}, Tuple{InfiniteMPS{A}, Int64}} where A","page":"Library","title":"MPSKit.l_LL","text":"l_LL(ψ, location)\n\nLeft dominant eigenvector of the AL-AL transfermatrix.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.l_LR","page":"Library","title":"MPSKit.l_LR","text":"l_LR(ψ, location)\n\nLeft dominant eigenvector of the AL-AR transfermatrix.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.l_RL","page":"Library","title":"MPSKit.l_RL","text":"l_RL(ψ, location)\n\nLeft dominant eigenvector of the AR-AL transfermatrix.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.l_RR","page":"Library","title":"MPSKit.l_RR","text":"l_RR(ψ, location)\n\nLeft dominant eigenvector of the AR-AR transfermatrix.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.leading_boundary","page":"Library","title":"MPSKit.leading_boundary","text":"leading_boundary(ψ, opp, alg, envs=environments(ψ, opp))\n\nApproximate the leading eigenvector for opp.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.leading_boundary-2","page":"Library","title":"MPSKit.leading_boundary","text":"leading_boundary(ψ₀, O, [environments]; kwargs...) -> (ψ, environments, ϵ)\nleading_boundary(ψ₀, O, algorithm, environments) -> (ψ, environments, ϵ)\n\nCompute the leading boundary MPS for operator O with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.\n\nArguments\n\nψ₀::AbstractMPS: initial guess\nO::AbstractMPO: operator for which to find the leading_boundary\n[environments]: MPS environment manager\nalgorithm: optimization algorithm\n\nKeywords\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: display progress information\n\nReturns\n\nψ::AbstractMPS: converged leading boundary MPS\nenvironments: environments corresponding to the converged boundary\nϵ::Float64: final convergence error upon terminating the algorithm\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.left_virtualspace","page":"Library","title":"MPSKit.left_virtualspace","text":"left_virtualspace(ψ::AbstractMPS, [pos=1:length(ψ)])\n\nReturn the virtual space of the bond to the left of sites pos.\n\nwarning: Warning\nIn rare cases, the gauge tensor on the virtual space might not be square, and as a result it cannot always be guaranteed that right_virtualspace(ψ, i - 1) == left_virtualspace(ψ, i)\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.make_time_mpo","page":"Library","title":"MPSKit.make_time_mpo","text":"make_time_mpo(H::MPOHamiltonian, dt::Number, alg) -> O::MPO\n\nConstruct an MPO that approximates exp(-iHdt).\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.makefullrank!-Tuple{PeriodicVector{<:TensorKit.AbstractTensorMap{T, S, N, 1} where {S, N, T}}}","page":"Library","title":"MPSKit.makefullrank!","text":"makefullrank!(A::PeriodicVector{<:GenericMPSTensor}; alg=QRpos())\n\nMake the set of MPS tensors full rank by performing a series of orthogonalizations.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.marek_gap-Tuple{InfiniteMPS}","page":"Library","title":"MPSKit.marek_gap","text":"Given an InfiniteMPS, compute the gap ϵ for the asymptotics of the transfer matrix, as well as the Marek gap δ as a scaling measure of the bond dimension.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.max_Ds-Tuple{FiniteMPS}","page":"Library","title":"MPSKit.max_Ds","text":"max_Ds(ψ::FiniteMPS) -> Vector{Float64}\n\nCompute the dimension of the maximal virtual space at a given site.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.open_boundary_conditions","page":"Library","title":"MPSKit.open_boundary_conditions","text":"open_boundary_conditions(mpo::InfiniteMPOHamiltonian, L::Int) -> FiniteMPOHamiltonian\n\nConvert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.open_boundary_conditions-Union{Tuple{InfiniteMPO{O}}, Tuple{O}, Tuple{InfiniteMPO{O}, Any}} where O<:BlockTensorKit.SparseBlockTensorMap","page":"Library","title":"MPSKit.open_boundary_conditions","text":"open_boundary_conditions(mpo::InfiniteMPO, L::Int) -> FiniteMPO\n\nConvert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.periodic_boundary_conditions-Union{Tuple{InfiniteMPO{O}}, Tuple{O}, Tuple{InfiniteMPO{O}, Any}} where O","page":"Library","title":"MPSKit.periodic_boundary_conditions","text":"periodic_boundary_conditions(mpo::AbstractInfiniteMPO, L::Int)\n\nConvert an infinite MPO into a finite MPO of length L, by mapping periodic boundary conditions onto an open system.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.physicalspace","page":"Library","title":"MPSKit.physicalspace","text":"physicalspace(ψ::AbstractMPS, [pos=1:length(ψ)])\n\nReturn the physical space of the site tensor at site i.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.propagator","page":"Library","title":"MPSKit.propagator","text":"propagator(ψ₀::AbstractFiniteMPS, z::Number, H::MPOHamiltonian, alg::DynamicalDMRG; init=copy(ψ₀))\n\nCalculate the propagator frac1E₀ + z - Hψ₀ using the dynamical DMRG algorithm.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.r_LL","page":"Library","title":"MPSKit.r_LL","text":"r_LL(ψ, location)\n\nRight dominant eigenvector of the AL-AL transfermatrix.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.r_LR","page":"Library","title":"MPSKit.r_LR","text":"r_LR(ψ, location)\n\nRight dominant eigenvector of the AL-AR transfermatrix.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.r_RL","page":"Library","title":"MPSKit.r_RL","text":"r_RL(ψ, location)\n\nRight dominant eigenvector of the AR-AL transfermatrix.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.r_RR-Union{Tuple{InfiniteMPS{A}}, Tuple{A}, Tuple{InfiniteMPS{A}, Int64}} where A","page":"Library","title":"MPSKit.r_RR","text":"r_RR(ψ, location)\n\nRight dominant eigenvector of the AR-AR transfermatrix.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.recalculate!","page":"Library","title":"MPSKit.recalculate!","text":"Recalculate in-place each sub-env in MultipleEnvironments\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.regauge!","page":"Library","title":"MPSKit.regauge!","text":"regauge!(AC::GenericMPSTensor, C::MPSBondTensor; alg=QRpos()) -> AL\nregauge!(CL::MPSBondTensor, AC::GenericMPSTensor; alg=LQpos()) -> AR\n\nBring updated AC and C tensors back into a consistent set of left or right canonical tensors. This minimizes ∥AC_i - AL_i * C_i∥ or ∥AC_i - C_{i-1} * AR_i∥. The optimal algorithm uses Polar() decompositions, but QR-based algorithms are typically more performant. Note that the first signature is slightly faster, as it avoids an intermediate transposition.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.right_virtualspace","page":"Library","title":"MPSKit.right_virtualspace","text":"right_virtualspace(ψ::AbstractMPS, [pos=1:length(ψ)])\n\nReturn the virtual space of the bond to the right of site(s) pos.\n\nwarning: Warning\nIn rare cases, the gauge tensor on the virtual space might not be square, and as a result it cannot always be guaranteed that right_virtualspace(ψ, i - 1) == left_virtualspace(ψ, i)\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.site_type-Tuple{MPSKit.AbstractMPS}","page":"Library","title":"MPSKit.site_type","text":"site_type(ψ::AbstractMPS)\nsite_type(ψtype::Type{<:AbstractMPS})\n\nReturn the type of the site tensors of an AbstractMPS.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.tensorexpr-Tuple{Any, Any}","page":"Library","title":"MPSKit.tensorexpr","text":"tensorexpr(name, ind_out, [ind_in])\n\nGenerates expressions for use within @tensor environments of the form name[ind_out...; ind_in].\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.time_evolve","page":"Library","title":"MPSKit.time_evolve","text":"time_evolve(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ, envs)\ntime_evolve!(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ₀, envs)\n\nTime-evolve the initial state ψ₀ with Hamiltonian H over a given time span by stepping through each of the time points obtained by iterating t_span.\n\nArguments\n\nψ₀::AbstractMPS: initial state\nH::AbstractMPO: operator that generates the time evolution (can be time-dependent).\nt_span::AbstractVector{<:Number}: time points over which the time evolution is stepped\n[alg]: algorithm to use for the time evolution. Defaults to TDVP.\n[envs]: MPS environment manager\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.time_evolve!","page":"Library","title":"MPSKit.time_evolve!","text":"time_evolve(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ, envs)\ntime_evolve!(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ₀, envs)\n\nTime-evolve the initial state ψ₀ with Hamiltonian H over a given time span by stepping through each of the time points obtained by iterating t_span.\n\nArguments\n\nψ₀::AbstractMPS: initial state\nH::AbstractMPO: operator that generates the time evolution (can be time-dependent).\nt_span::AbstractVector{<:Number}: time points over which the time evolution is stepped\n[alg]: algorithm to use for the time evolution. Defaults to TDVP.\n[envs]: MPS environment manager\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.timestep","page":"Library","title":"MPSKit.timestep","text":"timestep(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ, envs)\ntimestep!(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ₀, envs)\n\nTime-step the state ψ₀ with Hamiltonian H over a given time step dt at time t, solving the Schroedinger equation: i ψt = H ψ.\n\nArguments\n\nψ₀::AbstractMPS: initial state\nH::AbstractMPO: operator that generates the time evolution (can be time-dependent).\nt::Number: starting time of time-step\ndt::Number: time-step magnitude\n[alg]: algorithm to use for the time evolution. Defaults to TDVP.\n[envs]: MPS environment manager\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.timestep!","page":"Library","title":"MPSKit.timestep!","text":"timestep(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ, envs)\ntimestep!(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ₀, envs)\n\nTime-step the state ψ₀ with Hamiltonian H over a given time step dt at time t, solving the Schroedinger equation: i ψt = H ψ.\n\nArguments\n\nψ₀::AbstractMPS: initial state\nH::AbstractMPO: operator that generates the time evolution (can be time-dependent).\nt::Number: starting time of time-step\ndt::Number: time-step magnitude\n[alg]: algorithm to use for the time evolution. Defaults to TDVP.\n[envs]: MPS environment manager\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.transfer_left-Union{Tuple{N₂}, Tuple{N₁}, Tuple{S}, Tuple{TensorKit.AbstractTensorMap{<:Any, S, 1, N₁}, TensorKit.AbstractTensorMap{T, S, N₂, 1} where T, TensorKit.AbstractTensorMap{T, S, N₂, 1} where T}} where {S, N₁, N₂}","page":"Library","title":"MPSKit.transfer_left","text":"transfer_left(v, A, Ā)\n\napply a transfer matrix to the left.\n\n ┌─A─\n-v │\n └─Ā─\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.transfer_right-Union{Tuple{N₂}, Tuple{N₁}, Tuple{S}, Tuple{TensorKit.AbstractTensorMap{<:Any, S, 1, N₁}, TensorKit.AbstractTensorMap{T, S, N₂, 1} where T, TensorKit.AbstractTensorMap{T, S, N₂, 1} where T}} where {S, N₁, N₂}","page":"Library","title":"MPSKit.transfer_right","text":"transfer_right(v, A, Ā)\n\napply a transfer matrix to the right.\n\n─A─┐\n │ v-\n─Ā─┘\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.transfer_spectrum-Tuple{InfiniteMPS}","page":"Library","title":"MPSKit.transfer_spectrum","text":"transfer_spectrum(above::InfiniteMPS; below=above, tol=Defaults.tol, num_vals=20,\n sector=first(sectors(oneunit(left_virtualspace(above, 1)))))\n\nCalculate the partial spectrum of the left mixed transfer matrix corresponding to the overlap of a given above state and a below state. The sector keyword argument can be used to specify a non-trivial total charge for the transfer matrix eigenvectors. Specifically, an auxiliary space ℂ[typeof(sector)](sector => 1)' will be added to the domain of each eigenvector. The tol and num_vals keyword arguments are passed to KrylovKit.eigolve\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.transferplot","page":"Library","title":"MPSKit.transferplot","text":"transferplot(above, below=above; sectors=[], transferkwargs=(;)[, kwargs...])\n\nPlot the partial transfer matrix spectrum of two InfiniteMPS's.\n\nArguments\n\nabove::InfiniteMPS: above mps for transfer_spectrum.\nbelow::InfiniteMPS=above: below mps for transfer_spectrum.\n\nKeyword Arguments\n\nsectors=[]: vector of sectors for which to compute the spectrum.\ntransferkwargs: kwargs for call to transfer_spectrum.\nkwargs: other kwargs are passed on to the plotting backend.\nthetaorigin=0: origin of the angle range.\nsector_formatter=string: how to convert sectors to strings.\n\nnote: Note\nYou will need to manually import Plots.jl to be able to use this function. MPSKit.jl defines its plots based on RecipesBase.jl, but the user still has to add using Plots to be able to actually produce the plots.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.variance","page":"Library","title":"MPSKit.variance","text":"variance(state, hamiltonian, [envs=environments(state, hamiltonian)])\n\nCompute the variance of the energy of the state with respect to the hamiltonian.\n\n\n\n\n\n","category":"function"},{"location":"man/lattices/#lattices","page":"Lattices","title":"Lattices","text":"","category":"section"},{"location":"man/lattices/","page":"Lattices","title":"Lattices","text":"warning: Warning\nThis section is still under construction. Coming soon!","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"EditURL = \"../../../../../examples/quantum1d/3.ising-dqpt/main.jl\"","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"(Image: ) (Image: ) (Image: )","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/#DQPT-in-the-Ising-model(@id-demo_dqpt)","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"","category":"section"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"In this tutorial we will try to reproduce the results from this paper. The needed packages are","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"using MPSKit, MPSKitModels, TensorKit","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"Dynamical quantum phase transitions (DQPT in short) are signatures of equilibrium phase transitions in a dynamical quantity - the loschmidth echo. This quantity is given by L(t) = frac-2N ln( psi(t) psi(0) ) where N is the system size. One typically starts from a groundstate and then quenches the hamiltonian to a different point. Non analycities in the loschmidth echo are called 'dynamical quantum phase transitions'.","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"In the mentioned paper they work with","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"H(g) = - sum^N-1_i=1 sigma^z_i sigma^z_i+1 + g sum_i=1^N sigma^x_i","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"and show that divergences occur when quenching across the critical point (g₀ → g₁) for t^*_n = t^*(n+frac12) with t^* = pie(g_1k^*), cos(k^*) = (1+g_0 g_1) (g_0 + g_1), e(gk) = sqrt(g-cos k)^2 + sin^2 k.","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"The outline of the tutorial is as follows. We will pick g₀ = 05, g₁ = 20, and perform the time evolution at different system sizes and compare with the thermodynamic limit. For those g we expect non-analicities to occur at t_n 235 (n + 12).","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"First we construct the hamiltonian in mpo form, and obtain the pre-quenched groundstate:","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"L = 20\nH₀ = transverse_field_ising(FiniteChain(L); g=-0.5)\nψ₀ = FiniteMPS(L, ℂ^2, ℂ^10)\nψ₀, _ = find_groundstate(ψ₀, H₀, DMRG());","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"[ Info: DMRG init:\tobj = +1.002387808585e+01\terr = 1.4432e-01\n[ Info: DMRG 1:\tobj = -2.040021714927e+01\terr = 4.0939235067e-03\ttime = 0.07 sec\n[ Info: DMRG 2:\tobj = -2.040021715177e+01\terr = 4.1045749328e-07\ttime = 0.02 sec\n[ Info: DMRG 3:\tobj = -2.040021782419e+01\terr = 4.0893119931e-05\ttime = 0.11 sec\n[ Info: DMRG 4:\tobj = -2.040021786700e+01\terr = 1.5231059570e-06\ttime = 0.12 sec\n[ Info: DMRG 5:\tobj = -2.040021786703e+01\terr = 1.1927466419e-07\ttime = 0.04 sec\n[ Info: DMRG 6:\tobj = -2.040021786703e+01\terr = 1.0958548921e-10\ttime = 0.02 sec\n[ Info: DMRG conv 7:\tobj = -2.040021786703e+01\terr = 2.1531775493e-12\ttime = 0.43 sec\n","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/#Finite-MPS-quenching","page":"DQPT in the Ising model(@id demo_dqpt)","title":"Finite MPS quenching","text":"","category":"section"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"We can define a helper function that measures the loschmith echo","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"echo(ψ₀::FiniteMPS, ψₜ::FiniteMPS) = -2 * log(abs(dot(ψ₀, ψₜ))) / length(ψ₀)\n@assert isapprox(echo(ψ₀, ψ₀), 0, atol=1e-10)","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"We will initially use a two-site TDVP scheme to dynamically increase the bond dimension while time evolving, and later on switch to a faster one-site scheme. A single timestep can be done using","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"H₁ = transverse_field_ising(FiniteChain(L); g=-2.0)\nψₜ = deepcopy(ψ₀)\ndt = 0.01\nψₜ, envs = timestep(ψₜ, H₁, 0, dt, TDVP2(; trscheme=truncdim(20)));","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"\"envs\" is a kind of cache object that keeps track of all environments in ψ. It is often advantageous to re-use the environment, so that mpskit doesn't need to recalculate everything.","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"Putting it all together, we get","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"function finite_sim(L; dt=0.05, finaltime=5.0)\n ψ₀ = FiniteMPS(L, ℂ^2, ℂ^10)\n H₀= transverse_field_ising(FiniteChain(L); g=-0.5)\n ψ₀, _ = find_groundstate(ψ₀, H₀, DMRG())\n\n H₁ = transverse_field_ising(FiniteChain(L); g=-2.0)\n ψₜ = deepcopy(ψ₀)\n envs = environments(ψₜ, H₁)\n\n echos = [echo(ψₜ, ψ₀)]\n times = collect(0:dt:finaltime)\n\n for t in times[2:end]\n alg = t > 3 * dt ? TDVP() : TDVP2(; trscheme=truncdim(50))\n ψₜ, envs = timestep(ψₜ, H₁, 0, dt, alg, envs)\n push!(echos, echo(ψₜ, ψ₀))\n end\n\n return times, echos\nend","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"finite_sim (generic function with 1 method)","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"(Image: )","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/#Infinite-MPS-quenching","page":"DQPT in the Ising model(@id demo_dqpt)","title":"Infinite MPS quenching","text":"","category":"section"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"Similarly we could start with an initial infinite state and find the pre-quench groundstate:","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"ψ₀ = InfiniteMPS([ℂ^2], [ℂ^10])\nH₀ = transverse_field_ising(; g=-0.5)\nψ₀, _ = find_groundstate(ψ₀, H₀, VUMPS());","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"[ Info: VUMPS init:\tobj = +4.829091166942e-01\terr = 3.8333e-01\n[ Info: VUMPS 1:\tobj = -1.062402142520e+00\terr = 2.6498065851e-02\ttime = 0.02 sec\n[ Info: VUMPS 2:\tobj = -1.063544409278e+00\terr = 2.4370573433e-05\ttime = 0.01 sec\n[ Info: VUMPS 3:\tobj = -1.063544409973e+00\terr = 1.2541001144e-07\ttime = 0.01 sec\n[ Info: VUMPS 4:\tobj = -1.063544409973e+00\terr = 2.2271390880e-09\ttime = 0.01 sec\n[ Info: VUMPS 5:\tobj = -1.063544409973e+00\terr = 1.3003499540e-10\ttime = 0.01 sec\n[ Info: VUMPS conv 6:\tobj = -1.063544409973e+00\terr = 1.2478380148e-11\ttime = 0.08 sec\n","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"The dot product of two infinite matrix product states scales as alpha ^N where α is the dominant eigenvalue of the transfer matrix. It is this α that is returned when calling","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"dot(ψ₀, ψ₀)","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"1.0000000000000004 + 1.6174779448250835e-16im","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"so the loschmidth echo takes on the pleasant form","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"echo(ψ₀::InfiniteMPS, ψₜ::InfiniteMPS) = -2 * log(abs(dot(ψ₀, ψₜ)))\n@assert isapprox(echo(ψ₀, ψ₀), 0, atol=1e-10)","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"This time we cannot use a two-site scheme to grow the bond dimension, as this isn't implemented (yet). Instead, we have to make use of the changebonds machinery. Multiple algorithms are available, but we will only focus on OptimalEpand(). Growing the bond dimension by 5 can be done by calling:","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"ψₜ = deepcopy(ψ₀)\nH₁ = transverse_field_ising(; g=-2.0)\nψₜ, envs = changebonds(ψₜ, H₁, OptimalExpand(; trscheme=truncdim(5)));","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"a single timestep is easy","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"dt = 0.01\nψₜ, envs = timestep(ψₜ, H₁, 0, dt, TDVP(), envs);","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"With performance in mind we should once again try to re-use these \"envs\" cache objects. The final code is","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"function infinite_sim(dt=0.05, finaltime=5.0)\n ψ₀ = InfiniteMPS([ℂ^2], [ℂ^10])\n ψ₀, _ = find_groundstate(ψ₀, H₀, VUMPS())\n\n ψₜ = deepcopy(ψ₀)\n envs = environments(ψₜ, H₁)\n\n echos = [echo(ψₜ, ψ₀)]\n times = collect(0:dt:finaltime)\n\n for t in times[2:end]\n if t < 50dt # if t is sufficiently small, we increase the bond dimension\n ψₜ, envs = changebonds(ψₜ, H₁, OptimalExpand(; trscheme=truncdim(1)), envs)\n end\n ψₜ, envs = timestep(ψₜ, H₁, 0, dt, TDVP(), envs)\n push!(echos, echo(ψₜ, ψ₀))\n end\n\n return times, echos\nend","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"infinite_sim (generic function with 3 methods)","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"(Image: )","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/parallelism/#Parallelism-in-julia","page":"Parallelism in julia","title":"Parallelism in julia","text":"","category":"section"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"Julia has great parallelism infrastructure, but there is a caveat that is relevant for all algorithms implemented in MPSKit. The Julia threads do not play nicely together with the BLAS threads, which are the threads used for many of the linear algebra routines, and in particular for gemm (general matrix-matrix multiplication). As this is a core routine in MPSKit, this has a significant impact on the overall performance.","category":"page"},{"location":"man/parallelism/#Julia-threads-vs-BLAS-threads","page":"Parallelism in julia","title":"Julia threads vs BLAS threads","text":"","category":"section"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"A lot of the confusion stems from the fact that the BLAS threading behaviour is not consistent between different vendors. Additionally, performance behaviour is severely dependent on hardware, the specifics of the problem, and the availability of other resources such as total memory, or memory bandwith. This means that there is no one size fits all solution, and that you will have to experiment with the settings to get optimal performance. Nevertheless, there are some general guidelines that can be followed, which seem to at least work well in most cases.","category":"page"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"The number of threads that are set by BLAS.set_num_threads(), in the case of OpenBLAS (the default vendor), is equal to the total number of BLAS threads that is kept in a pool, which is then shared by all Julia threads. This means that if you have 4 julia threads and 4 BLAS threads, then all julia threads will share the same 4 BLAS threads. On the other hand, using BLAS.set_num_threads(1), OpenBLAS will now utilize the julia threads to run the BLAS jobs. Thus, for OpenBLAS, very often setting the number of BLAS threads to 1 is the best option, which will then maximally utilize the julia threading infrastructure of MPSKit.","category":"page"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"In the case of MKL.jl, which often outperforms OpenBLAS, the situation is a bit different. Here, the number of BLAS threads corresponds to the number of threads that are spawned by each julia thread. Thus, if you have 4 julia threads and 4 BLAS threads, then each julia thread will spawn 4 BLAS threads, for a total of 16 BLAS threads. As such, it might become necessary to adapt the settings to avoid oversubscription of the cores.","category":"page"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"A careful analysis of the different cases and benefits can be inspected by making use of ThreadPinning.jl's tool threadinfo(; blas=true, info=true). In particular, the following might demonstrate the difference between OpenBLAS and MKL:","category":"page"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"julia> Threads.nthreads()\n4\n\njulia> using ThreadPinning; threadinfo(; blas=true, hints=true)\n\nSystem: 8 cores (2-way SMT), 1 sockets, 1 NUMA domains\n\n| 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | \n\n# = Julia thread, # = HT, # = Julia thread on HT, | = Socket seperator\n\nJulia threads: 4\n├ Occupied CPU-threads: 4\n└ Mapping (Thread => CPUID): 1 => 8, 2 => 5, 3 => 9, 4 => 2,\n\nBLAS: libopenblas64_.so\n└ openblas_get_num_threads: 8\n\n[ Info: jlthreads != 1 && blasthreads < cputhreads. You should either set BLAS.set_num_threads(1) (recommended!) or at least BLAS.set_num_threads(16).\n[ Info: jlthreads < cputhreads. Perhaps increase number of Julia threads to 16?\njulia> using MKL; threadinfo(; blas=true, hints=true)\n\nSystem: 8 cores (2-way SMT), 1 sockets, 1 NUMA domains\n\n| 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | \n\n# = Julia thread, # = HT, # = Julia thread on HT, | = Socket seperator\n\nJulia threads: 4\n├ Occupied CPU-threads: 4\n└ Mapping (Thread => CPUID): 1 => 11, 2 => 12, 3 => 1, 4 => 2,\n\nBLAS: libmkl_rt.so\n├ mkl_get_num_threads: 8\n└ mkl_get_dynamic: true\n\n┌ Warning: blasthreads_per_jlthread > cputhreads_per_jlthread. You should decrease the number of MKL threads, i.e. BLAS.set_num_threads(4).\n└ @ ThreadPinning ~/.julia/packages/ThreadPinning/qV2Cd/src/threadinfo.jl:256\n[ Info: jlthreads < cputhreads. Perhaps increase number of Julia threads to 16?","category":"page"},{"location":"man/parallelism/#MPSKit-multithreading","page":"Parallelism in julia","title":"MPSKit multithreading","text":"","category":"section"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"Within MPSKit, when Julia is started with multiple threads, by default the OhMyThreads.jl machinery will be used to parallelize the code as much as possible. In particular, this mostly occurs whenever there is a unitcell and local updates can take place at each site in parallel.","category":"page"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"The multithreading behaviour can be controlled through a global scheduler, which can be set using the MPSKit.Defaults.set_scheduler!(arg; kwargs...) function. This function accepts either a Symbol, an OhMyThreads.Scheduler or keywords to determine a scheduler automatically.","category":"page"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"MPSKit.Defaults.set_scheduler!(:serial) # disable multithreading\nMPSKit.Defaults.set_scheduler!(:greedy) # multithreading with greedy load-balancing\nMPSKit.Defaults.set_scheduler!(:dynamic) # default: multithreading with some load-balancing","category":"page"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"For further reference on the available schedulers and finer control, please refer to the OhMyThreads.jl documentation","category":"page"},{"location":"man/parallelism/#TensorKit-multithreading","page":"Parallelism in julia","title":"TensorKit multithreading","text":"","category":"section"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"Finally, when dealing with tensors that have some internal symmetry, it is also possible to parallelize over the symmetry sectors. This is handled by TensorKit, and more information can be found in its documentation (Soon TM).","category":"page"},{"location":"man/parallelism/#Memory-management","page":"Parallelism in julia","title":"Memory management","text":"","category":"section"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"Because of the way julia threads work, it is possible that the total memory usage of your program becomes rather high. This seems to be because of the fact that MPSKit spawns several tasks (in a nested way), which each allocate and deallocate quite a bit of memory in a tight loop. This seems to lead to a situation where the garbage collector is not able to keep up, and can even fail to clear the garbage before an OutOfMemory error occurs. In this case, often the best thing to do is disable the multithreading of MPSKit, specifically for the derivatives, as this seems to be the most memory intensive part. This is something that is under investigation, and hopefully will be fixed in the future.","category":"page"},{"location":"man/environments/#um_environments","page":"Environments","title":"Environments","text":"","category":"section"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"In many tensor network algorithms we encounter partially contracted tensor networks. In DMRG for example, one needs to know the sum of all the hamiltonian contributions left and right of the site that we want to optimize. If you then optimize the neighboring site to the right, you only need to add one new contribution to the previous sum of hamiltonian contributions.","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"This kind of information is stored in the environment objects. The goal is that the user should preferably never have to deal with these objects, but being aware of the inner workings may allow you to write more efficient code. That is why they are nonetheless included in the manual.","category":"page"},{"location":"man/environments/#Finite-Environments","page":"Environments","title":"Finite Environments","text":"","category":"section"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"When you create a state and a hamiltonian:","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"state = FiniteMPS(rand, ComplexF64, 20, ℂ^2, ℂ^10);\noperator = nonsym_ising_ham();","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"an environment object can be created by calling","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"envs = environments(state, operator)","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"The partially contracted mpohamiltonian left of site i can then be queried using:","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"@time leftenv(envs, i, state)","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"This may take some time, but a subsequent call should be a lot quicker","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"@time leftenv(envs, i - 1, state)","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"Behind the scenes the envs stored all tensors it used to calculate leftenv (state.AL[1 .. i]) and when queried again, it checks if the tensors it previously used are identical (using ===). If so, it can simply return the previously stored results. If not, it will recalculate again. If you update a tensor in-place, the caches cannot know using === that the actual tensors have changed. If you do this, you have to call poison!(state,i).","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"As an optional argument, many algorithms allow you to pass in an environment object, and they also return an updated one. Therefore, for time evolution code, it is more efficient to give it the updated caches every time step, instead of letting it recalculate.","category":"page"},{"location":"man/environments/#Infinite-Environments","page":"Environments","title":"Infinite Environments","text":"","category":"section"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"Infinite Environments are very similar :","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"state = InfiniteMPS(ℂ^2, ℂ^10)\noperator = transverse_field_ising()\nenvs = environments(state, operator)","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"There are also some notable differences. Infinite environments typically require solving linear problems or eigenvalue problems iteratively with finite precision. To find out what precision we used we can type:","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"(cache.tol,cache.maxiter)","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"To recalculate with a different precision :","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"cache.tol=1e-8;\nrecalculate!(cache,state)","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"Unlike their finite counterparts, recalculating is not done automatically. To get the environment for a different state one has to recalculate explicitly!","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"different_state = InfiniteMPS([ℂ^2],[ℂ^10]);\nrecalculate!(cache,different_state)\nleftenv(cache,3,different_state)","category":"page"},{"location":"examples/#Examples","page":"Examples","title":"Examples","text":"","category":"section"},{"location":"examples/#Quantum-(11)d","page":"Examples","title":"Quantum (1+1)d","text":"","category":"section"},{"location":"examples/","page":"Examples","title":"Examples","text":"Pages = map(file -> joinpath(\"quantum1d\", file, \"index.md\"), readdir(\"quantum1d\"))\nDepth = 1","category":"page"},{"location":"examples/#Classical-(20)d","page":"Examples","title":"Classical (2+0)d","text":"","category":"section"},{"location":"examples/","page":"Examples","title":"Examples","text":"Pages = map(file -> joinpath(\"classic2d\", file, \"index.md\"), readdir(\"classic2d\"))\nDepth = 1","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"EditURL = \"../../../../../examples/classic2d/1.hard-hexagon/main.jl\"","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"(Image: ) (Image: ) (Image: )","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/#demo_hardhexagon","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"","category":"section"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"(Image: logo)","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"Tensor networks are a natural way to do statistical mechanics on a lattice. As an example of this we will extract the central charge of the hard hexagon model. This model is known to have central charge 0.8, and has very peculiar non-local (anyonic) symmetries. Because TensorKit supports anyonic symmetries, so does MPSKit. To follow the tutorial you need the following packages.","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"using MPSKit, MPSKitModels, TensorKit, Plots, Polynomials","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"The hard hexagon model is a 2-dimensional lattice model of a gas, where particles are allowed to be on the vertices of a triangular lattice, but no two particles may be adjacent. This can be encoded in a transfer matrix with a local MPO tensor using anyonic symmetries, and the resulting MPO has been implemented in MPSKitModels.","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"In order to use these anyonic symmetries, we need to generalise the notion of the bond dimension and define how it interacts with the symmetry. Thus, we implement away of converting integers to symmetric spaces of the given dimension, which provides a crude guess for how the final MPS would distribute its Schmidt spectrum.","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"mpo = hard_hexagon()\nP = physicalspace(mpo, 1)\nfunction virtual_space(D::Integer)\n _D = round(Int, D / sum(dim, values(FibonacciAnyon)))\n return Vect[FibonacciAnyon](sector => _D for sector in (:I, :τ))\nend\n\n@assert isapprox(dim(virtual_space(100)), 100; atol=3)","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/#The-leading-boundary","page":"The Hard Hexagon model","title":"The leading boundary","text":"","category":"section"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"One way to study statistical mechanics in infinite systems with tensor networks is by approximating the dominant eigenvector of the transfer matrix by an MPS. This dominant eigenvector contains a lot of hidden information. For example, the free energy can be extracted by computing the expectation value of the mpo. Additionally, we can compute the entanglement entropy as well as the correlation length of the state:","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"D = 10\nV = virtual_space(D)\nψ₀ = InfiniteMPS([P], [V])\nψ, envs, = leading_boundary(ψ₀, mpo,\n VUMPS(; verbosity=0,\n alg_eigsolve=MPSKit.Defaults.alg_eigsolve(;\n ishermitian=false))) # use non-hermitian eigensolver\nF = real(expectation_value(ψ, mpo))\nS = real(first(entropy(ψ)))\nξ = correlation_length(ψ)\nprintln(\"F = $F\\tS = $S\\tξ = $ξ\")","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"F = 0.8839037051703851\tS = 1.280782962183673\tξ = 13.849682581369715\n","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/#The-scaling-hypothesis","page":"The Hard Hexagon model","title":"The scaling hypothesis","text":"","category":"section"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"The dominant eigenvector is of course only an approximation. The finite bond dimension enforces a finite correlation length, which effectively introduces a length scale in the system. This can be exploited to formulate a scaling hypothesis (Pollmann et al., 2009), which in turn allows to extract the central charge.","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"First we need to know the entropy and correlation length at a bunch of different bond dimensions. Our approach will be to re-use the previous approximated dominant eigenvector, and then expanding its bond dimension and re-running VUMPS. According to the scaling hypothesis we should have S propto fracc6 log(ξ). Therefore we should find c using","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"function scaling_simulations(ψ₀, mpo, Ds; verbosity=0, tol=1e-6,\n alg_eigsolve=MPSKit.Defaults.alg_eigsolve(; ishermitian=false))\n entropies = similar(Ds, Float64)\n correlations = similar(Ds, Float64)\n alg = VUMPS(; verbosity, tol, alg_eigsolve)\n\n ψ, envs, = leading_boundary(ψ₀, mpo, alg)\n entropies[1] = real(entropy(ψ)[1])\n correlations[1] = correlation_length(ψ)\n\n for (i, d) in enumerate(diff(Ds))\n ψ, envs = changebonds(ψ, mpo, OptimalExpand(; trscheme=truncdim(d)), envs)\n ψ, envs, = leading_boundary(ψ, mpo, alg, envs)\n entropies[i + 1] = real(entropy(ψ)[1])\n correlations[i + 1] = correlation_length(ψ)\n end\n return entropies, correlations\nend\n\nbond_dimensions = 10:5:25\nψ₀ = InfiniteMPS([P], [virtual_space(bond_dimensions[1])])\nSs, ξs = scaling_simulations(ψ₀, mpo, bond_dimensions)\n\nf = fit(log.(ξs), 6 * Ss, 1)\nc = f.coeffs[2]","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"0.8025216556799167","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"p = plot(; xlabel=\"logarithmic correlation length\", ylabel=\"entanglement entropy\")\np = plot(log.(ξs), Ss; seriestype=:scatter, label=nothing)\nplot!(p, ξ -> f(ξ) / 6; label=\"fit\")","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"This page was generated using Literate.jl.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"EditURL = \"../../../../../examples/quantum1d/5.haldane-spt/main.jl\"","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"(Image: ) (Image: ) (Image: )","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/#spin1heisenberg","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"","category":"section"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"The quantum Heisenberg model is a model often used in the study of critical points and phase transitions of magnetic systems, in which the spins are treated quantum mechanically. It models magnetic interactions between neighbouring spins through the so-called Heisenberg interaction term, which causes the spins to either align (J 0) or anti-align (J 0), thus modeling a (anti-) ferromagnetic system. Here, we will focus on the case of S = 1, with anti-ferromagnetic interactions.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"H = -J sum_langle i j rangle vecS_i cdot vecS_j","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"Importantly, the Hamiltonian of the isotropic model is invariant under SU(2) rotations, which can be exploited to increase efficiency, as well as interpretability of the MPS simulations. To see this, we can make use of the following derivation for the interaction term:","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"(vecS_i + vecS_j)^2 = vecS_i^2 + 2 vecS_i cdot vecS_j + vecS_j^2\nimplies vecS_i cdot vecS_j = frac12 left( (vecS_i + vecS_j)^2 - vecS_i^2 - vecS_j^2 right)","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"Here, we recognize the quadratic Casimir element vecS^2, which commutes with the elements of SU(2). Consequently, the Hamiltonian also commutes with all elements of SU(2).","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"using TensorKit\nusing MPSKit\nusing Plots\n\ncasimir(s::SU2Irrep) = s.j * (s.j + 1)\n\nfunction heisenberg_hamiltonian(; J=-1.0)\n s = SU2Irrep(1)\n ℋ = SU2Space(1 => 1)\n SS = zeros(ComplexF64, ℋ ⊗ ℋ ← ℋ ⊗ ℋ)\n for (S, data) in blocks(SS)\n data .= -0.5J * (casimir(S) - casimir(s) - casimir(s))\n end\n return InfiniteMPOHamiltonian(SS)\nend\nH = heisenberg_hamiltonian()","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"single site InfiniteMPOHamiltonian{BlockTensorKit.SparseBlockTensorMap{TensorKit.AbstractTensorMap{ComplexF64, TensorKit.GradedSpace{TensorKitSectors.SU2Irrep, TensorKit.SortedVectorDict{TensorKitSectors.SU2Irrep, Int64}}, 2, 2}, ComplexF64, TensorKit.GradedSpace{TensorKitSectors.SU2Irrep, TensorKit.SortedVectorDict{TensorKitSectors.SU2Irrep, Int64}}, 2, 2, 4}}:\n╷ ⋮\n┼ W[1]: 3×1×1×3 SparseBlockTensorMap(((Rep[SU₂](0=>1) ⊕ Rep[SU₂](1=>1) ⊕ Rep[SU₂](0=>1)) ⊗ ⊕(Rep[SU₂](1=>1))) ← (⊕(Rep[SU₂](1=>1)) ⊗ (Rep[SU₂](0=>1) ⊕ Rep[SU₂](1=>1) ⊕ Rep[SU₂](0=>1))))\n╵ ⋮\n","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/#Symmetry-Protected-Topological-Order","page":"Spin 1 Heisenberg model","title":"Symmetry-Protected Topological Order","text":"","category":"section"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"The representations of SU(2) possess additional structure, known as a mathbbZ_2-grading. This means, that they can be partitioned in integer (+) and half-integer (-) spins, and the fusion rules will respect this grading. In other words, the following table holds:","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"s_1 s_2 s_1 otimes s_2\n+ + +\n+ - -\n- + -\n- - +","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"This has important consequences for the MPS representation of an SU(2)-symmetric state. If the physical spin consists of only integer representations, this means that the left and right virtual spaces of the MPS tensor belong to the same grading, i.e. are either both integer, or both half-integer. Thus, naively constructing a MPS tensor which contains spins from both classes, will necessarily be the direct sum of the two, which yields a non-injective MPS.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"ketpsi = ketpsi_+ oplus ketpsi_-","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"Because of this direct sum, many of the usual MPS algorithms will fail, as they typically cannot deal with non-injective MPS. The resulting MPS will have multiple values of the transfer matrix spectrum that have a magnitude close to 1, which is a clear sign of a non-injective MPS.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"ℋ = SU2Space(1 => 1)\nV_wrong = SU2Space(0 => 8, 1 // 2 => 8, 1 => 3, 3 // 2 => 3)\nψ = InfiniteMPS(ℋ, V_wrong)\nψ, environments, δ = find_groundstate(ψ, H, VUMPS(; maxiter=10))\nsectors = SU2Irrep[0, 1 // 2, 1, 3 // 2]\ntransferplot(ψ; sectors, title=\"Transfer matrix spectrum\", legend=:outertop)","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"Nevertheless, using the symmetry, this can be remedied rather easily, by imposing the groundstate to belong to a single class, and comparing the results. We can readily obtain 3 different criteria for determining the SPT phase of the groundstate.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"Firstly, we can compare variational energies for states of similar bond dimensions. As we expect the state of the wrong SPT phase to have to expend some of its expressiveness in correcting the SPT, it should have a harder time reaching lower energies.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"Secondly, when inspecting the spectrum of the transfer matrix, we should see that the wrong SPT phase has a dominant value that is not in the trivial sector, which leads to a non-injective MPS.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"Finally, the entanglement spectrum of the wrong SPT phase will show degeneracies of all singular values, which can again be attributed to an attempt to mimick the spectrum of the right SPT phase.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"V_plus = SU2Space(0 => 10, 1 => 5, 2 => 3)\nψ_plus = InfiniteMPS(ℋ, V_plus)\nψ_plus, = find_groundstate(ψ_plus, H, VUMPS(; maxiter=100))\nE_plus = expectation_value(ψ_plus, H)","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"-1.4014193313393006 - 2.039461603293807e-17im","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"V_minus = SU2Space(1 // 2 => 10, 3 // 2 => 5, 5 // 2 => 3)\nψ_minus = InfiniteMPS(ℋ, V_minus)\nψ_minus, = find_groundstate(ψ_minus, H, VUMPS(; maxiter=100))\nE_minus = expectation_value(ψ_minus, H)","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"-1.4014839739630813 + 7.825406802551059e-17im","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"transferp_plus = transferplot(ψ_plus; sectors=SU2Irrep[0, 1, 2], title=\"ψ_plus\",\n legend=:outertop)\ntransferp_minus = transferplot(ψ_minus; sectors=SU2Irrep[0, 1, 2], title=\"ψ_minus\",\n legend=:outertop)\nplot(transferp_plus, transferp_minus; layout=(1, 2), size=(800, 400))","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"entanglementp_plus = entanglementplot(ψ_plus; title=\"ψ_plus\", legend=:outertop)\nentanglementp_minus = entanglementplot(ψ_minus; title=\"ψ_minus\", legend=:outertop)\nplot(entanglementp_plus, entanglementp_minus; layout=(1, 2), size=(800, 400))","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"As we can see, the groundstate can be found in the non-trivial SPT phase, ketpsi_-. We can obtain an intuitive understanding of ketpsi_+ by considering the following diagram. If we denote the MPS tensors that make up the groundstate as A_-, we can construct a state in the trivial SPT phase that approximates the groundstate as follows:","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"(Image: spt-tensors.svg)","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"In other words, we can factorize a purely virtual isomorphism of S = 12 in order to obtain the groundstate. This then also explains the degeneracies in the entanglement spectrum as well as in the transfer matrix spectrum. Finally, we can further confirm this intuition by looking at the entanglement entropy of the groundstate. As we can see, the entanglement entropy of the state in the wrong SPT phase is exactly log(2) higher than the one in the right SPT phase, which is exactly what we would expect from the diagram above.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"S_minus = sum(real, entropy(ψ_minus))\nS_plus = sum(real, entropy(ψ_plus))\nprintln(\"S_minus + log(2) = $(S_minus + log(2))\")\nprintln(\"S_plus = $S_plus\")","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"S_minus + log(2) = 1.0155125212288219\nS_plus = 0.7327304247852098\n","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/states/#um_states","page":"States","title":"States","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"using MPSKit\nusing TensorKit\nusing LinearAlgebra: dot","category":"page"},{"location":"man/states/#FiniteMPS","page":"States","title":"FiniteMPS","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"A FiniteMPS is - at its core - a chain of mps tensors.","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"(Image: )","category":"page"},{"location":"man/states/#Usage","page":"States","title":"Usage","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"A FiniteMPS can be created by passing in a vector of tensormaps:","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"L = 10\ndata = [rand(ComplexF64, ℂ^1 ⊗ ℂ^2 ← ℂ^1) for _ in 1:L];\nstate = FiniteMPS(data)","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"Or alternatively by specifying its structure","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"max_bond_dimension = ℂ^4\nphysical_space = ℂ^2\nstate = FiniteMPS(rand, ComplexF64, L, physical_space, max_bond_dimension)","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"You can take dot products, renormalize!, expectation values,....","category":"page"},{"location":"man/states/#Gauging-and-canonical-forms","page":"States","title":"Gauging and canonical forms","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"An MPS representation is not unique: for every virtual bond we can insert C cdot C^-1 without altering the state. Then, by redefining the tensors on both sides of the bond to include one factor each, we can change the representation.","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"(Image: )","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"There are two particularly convenient choices for the gauge at a site, the so-called left and right canonical form. For the left canonical form, all tensors to the left of a site are gauged such that they become left-isometries. By convention, we call these tensors AL.","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"al = state.AL[3]\nal' * al ≈ id(right_virtualspace(al))","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"Similarly, the right canonical form turns the tensors into right-isometries. By convention, these are called AR.","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"ar = state.AR[3]\nrepartition(ar, 1, 2) * repartition(ar, 1, 2)' ≈ id(left_virtualspace(ar))","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"It is also possible to mix and match these two forms, where all tensors to the left of a given site are in the left gauge, while all tensors to the right are in the right gauge. In this case, the final gauge transformation tensor can no longer be absorbed, since that would spoil the gauge either to the left or the right. This center-gauged tensor is called C, which is also the gauge transformation to relate left- and right-gauged tensors. Finally, for convenience it is also possible to leave a single MPS tensor in the center gauge, which we call AC = AL * C","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"c = state.C[3] # to the right of site 3\nc′ = state.C[2] # to the left of site 3\nal * c ≈ state.AC[3] ≈ repartition(c′ * repartition(ar, 1, 2), 2, 1)","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"These forms are often used throughout MPS algorithms, and the FiniteMPS object acts as an automatic manager for this. It will automatically compute and cache the different forms, and detect when to recompute whenever needed. For example, in order to compute the overlap of an MPS with itself, we can choose any site and bring that into the center gauge. Since then both the left and right side simplify to the identity, this simply becomes the overlap of the gauge tensors:","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"d = dot(state, state)\nall(c -> dot(c, c) ≈ d, state.C)","category":"page"},{"location":"man/states/#Implementation-details","page":"States","title":"Implementation details","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"Behind the scenes, a FiniteMPS has 4 fields","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"ALs::Vector{Union{Missing,A}}\nARs::Vector{Union{Missing,A}}\nACs::Vector{Union{Missing,A}}\nCs::Vector{Union{Missing,B}}","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"and calling AL, AR, C or AC returns lazy views over these vectors that instantiate the tensors whenever they are requested. Similarly, changing a tensor will poison the ARs to the left of that tensor, and the ALs to the right. The idea behind this construction is that one never has to worry about how the state is gauged, as this gets handled automagically.","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"warning: Warning\nWhile a FiniteMPS can automatically detect when to recompute the different gauges, this requires that one of the tensors is set using an indexing operation. In particular, in-place changes to the different tensors will not trigger the recomputation.","category":"page"},{"location":"man/states/#InfiniteMPS","page":"States","title":"InfiniteMPS","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"An InfiniteMPS can be thought of as being very similar to a finite mps, where the set of tensors is repeated periodically.","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"It can also be created by passing in a vector of TensorMaps:","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"data = [rand(ComplexF64, ℂ^4 ⊗ ℂ^2 ← ℂ^4) for _ in 1:2]\nstate = InfiniteMPS(data)","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"or by initializing it from given spaces","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"phys_spaces = fill(ℂ^2, 2)\nvirt_spaces = [ℂ^4, ℂ^5] # by convention to the right of a site\nstate = InfiniteMPS(phys_spaces, virt_spaces)","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"Note that the code above creates an InfiniteMPS with a two-site unit cell, where the given virtual spaces are located to the right of their respective sites.","category":"page"},{"location":"man/states/#Gauging-and-canonical-forms-2","page":"States","title":"Gauging and canonical forms","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"Much like for FiniteMPS, we can again query the gauged tensors AL, AR, C and AC. Here however, the implementation is much easier, since they all have to be recomputed whenever a single tensor changes. This is a result of periodically repeating the tensors, every AL is to the right of the changed site, and every AR is to the left. As a result, the fields are simply","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"AL::PeriodicArray{A,1}\nAR::PeriodicArray{A,1}\nC::PeriodicArray{B,1}\nAC::PeriodicArray{A,1}","category":"page"},{"location":"man/states/#WindowMPS","page":"States","title":"WindowMPS","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"A WindowMPS or segment MPS can be seen as a mix between an InfiniteMPS and a FiniteMPS. It represents a window of mutable tensors (a finite MPS), embedded in an infinite environment (two infinite MPSs). It can therefore be created accordingly, ensuring that the edges match:","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"infinite_state = InfiniteMPS(ℂ^2, ℂ^4)\nfinite_state = FiniteMPS(5, ℂ^2, ℂ^4; left=ℂ^4, right=ℂ^4)\nwindow = WindowMPS(infinite_state, finite_state, infinite_state)","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"Algorithms will then act on this window of tensors, while leaving the left and right infinite states invariant.","category":"page"},{"location":"man/states/#MultilineMPS","page":"States","title":"MultilineMPS","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"A two-dimensional classical partition function can often be represented by an infinite tensor network. There are many ways to evaluate such a network, but here we focus on the so-called boundary MPS methods. These first reduce the problem from contracting a two-dimensional network to the contraction of a one-dimensional MPS, by finding the fixed point of the row-to-row (or column-to-column) transfer matrix. In these cases however, there might be a non-trivial periodicity in both the horizontal as well as vertical direction. Therefore, in MPSKit they are represented by MultilineMPS, which are simply a repeating set of InfiniteMPS.","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"state = MultilineMPS(fill(infinite_state, 2))","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"They offer some convenience functionality for using cartesian indexing (row - column):","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"You can access properties by calling","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"row = 2\ncol = 2\nal = state.AL[row, col];","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"These objects are also used extensively in the context of PEPSKit.jl.","category":"page"},{"location":"man/intro/#Prerequisites","page":"Prerequisites","title":"Prerequisites","text":"","category":"section"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"The following sections describe the prerequisites for using MPSKit. If you are already familiar with the concepts of MPSKit and TensorKit, you can skip to the Conventions sections.","category":"page"},{"location":"man/intro/#TensorKit","page":"Prerequisites","title":"TensorKit","text":"","category":"section"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"using TensorKit","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"MPSKit uses the tensors defined in TensorKit.jl as its underlying data structure. This is what allows the library to be generic with respect to the symmetry of the tensors. The main difference with regular multi-dimensional arrays is the notion of a partition of the dimensions in incoming and outgoing, which are respectively called domain and codomain. In other words, a TensorMap can be interpreted as a linear map from its domain to its codomain. Additionally, as generic symmetries are supported, in general the structure of the indices are not just integers, but are given by spaces.","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"The general syntax for creating a tensor is similar to the creation of arrays, where the axes or size specifiers are replaced with VectorSpace objects:","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"zeros(scalartype, codomain, domain)\nrand(scalartype, codomain ← domain) # ← is the `\\leftarrow` operator","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"For example, the following creates a random tensor with three legs, each of which has dimension two, however with different partitions.","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"V1 = ℂ^2 # ℂ is the `\\bbC` operator, equivalent to ComplexSpace(10)\nt1 = rand(Float64, V1 ⊗ V1 ⊗ V1) # all spaces in codomain\nt2 = rand(Float64, V1, V1 ⊗ V1) # one space in codomain, two in domain","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"We can now no longer trivially add them together:","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"try #hide\nt1 + t2 # incompatible partition\ncatch err; Base.showerror(stderr, err); end #hide","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"But this can be resolved by permutation:","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"try #hide\nt1 + permute(t2, (1, 2, 3), ()) # incompatible arrows\ncatch err; Base.showerror(stderr, err); end #hide","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"These abstract objects can represent not only plain arrays but also symmetric tensors. The following creates a symmetric tensor with ℤ₂ symmetry, again with three legs of dimension two. However, now the dimension two is now split over even and odd sectors of ℤ₂.","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"V2 = Z2Space(0 => 1, 1 => 1)\nt3 = rand(Float64, V2 ⊗ V2, V2)","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"For more information, check out the TensorKit documentation!","category":"page"},{"location":"man/intro/#Conventions","page":"Prerequisites","title":"Conventions","text":"","category":"section"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"The general definition of an MPS tensor is as follows:","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"(Image: convention MPSTensor)","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"These tensors are allowed to have an arbitrary number of physical legs, and both FiniteMPS as well as InfiniteMPS will be able to handle the resulting objects. This allows for example for the definition of boundary tensors in PEPS code, which have two physical legs.","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"Similarly, the definition of a bond tensor, appearing in between two MPS tensors, is as follows:","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"(Image: convention BondTensor)","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"Finally, the definition of a MPO tensor, which is used to represent statistical mechanics problems as well as quantum hamiltonians, is represented as:","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"(Image: convention MPOTensor)","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"While this results at first glance in the not very intuitive ordering of spaces as V_l otimes P leftarrow P otimes V_r, this is actually the most natural ordering for keeping the algorithms planar. In particular, this is relevant for dealing with fermionic systems, where additional crossings would lead to sign problems.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"EditURL = \"../../../../../examples/quantum1d/4.xxz-heisenberg/main.jl\"","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"(Image: ) (Image: ) (Image: )","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/#The-XXZ-model","page":"The XXZ model","title":"The XXZ model","text":"","category":"section"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"In this file we will give step by step instructions on how to analyze the spin 1/2 XXZ model. The necessary packages to follow this tutorial are:","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"using MPSKit, MPSKitModels, TensorKit, Plots","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/#Failure","page":"The XXZ model","title":"Failure","text":"","category":"section"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"First we should define the hamiltonian we want to work with. Then we specify an initial guess, which we then further optimize. Working directly in the thermodynamic limit, this is achieved as follows:","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"H = heisenberg_XXX(; spin=1 // 2)","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"single site InfiniteMPOHamiltonian{BlockTensorKit.SparseBlockTensorMap{TensorKit.AbstractTensorMap{ComplexF64, TensorKit.ComplexSpace, 2, 2}, ComplexF64, TensorKit.ComplexSpace, 2, 2, 4}}:\n╷ ⋮\n┼ W[1]: 3×1×1×3 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^3 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^3 ⊕ ℂ^1)))\n╵ ⋮\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"We then need an intial state, which we shall later optimize. In this example we work directly in the thermodynamic limit.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"state = InfiniteMPS(2, 20)","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"single site InfiniteMPS:\n│ ⋮\n│ C[1]: TensorMap(ℂ^20 ← ℂ^20)\n├── AL[1]: TensorMap((ℂ^20 ⊗ ℂ^2) ← ℂ^20)\n│ ⋮\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"The groundstate can then be found by calling find_groundstate.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"groundstate, cache, delta = find_groundstate(state, H, VUMPS());","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"[ Info: VUMPS init:\tobj = +2.499932270895e-01\terr = 7.3488e-03\n[ Info: VUMPS 1:\tobj = -2.684294662883e-01\terr = 3.4887991618e-01\ttime = 0.04 sec\n[ Info: VUMPS 2:\tobj = -3.908732509075e-01\terr = 2.4346308901e-01\ttime = 0.09 sec\n[ Info: VUMPS 3:\tobj = -4.103272462718e-01\terr = 2.2211707874e-01\ttime = 0.04 sec\n[ Info: VUMPS 4:\tobj = +2.763771623319e-02\terr = 4.0601070717e-01\ttime = 0.06 sec\n[ Info: VUMPS 5:\tobj = -1.278912388343e-01\terr = 4.0024753668e-01\ttime = 0.04 sec\n[ Info: VUMPS 6:\tobj = -6.128684560655e-02\terr = 3.9554377744e-01\ttime = 0.05 sec\n[ Info: VUMPS 7:\tobj = -2.019229524257e-01\terr = 3.9507954388e-01\ttime = 0.03 sec\n[ Info: VUMPS 8:\tobj = -3.385836978728e-01\terr = 3.1206810658e-01\ttime = 0.06 sec\n[ Info: VUMPS 9:\tobj = -4.217712628117e-01\terr = 1.9266010859e-01\ttime = 0.05 sec\n[ Info: VUMPS 10:\tobj = +3.119439956568e-02\terr = 4.0307569557e-01\ttime = 0.05 sec\n[ Info: VUMPS 11:\tobj = -1.453987450329e-01\terr = 3.7892383130e-01\ttime = 0.03 sec\n[ Info: VUMPS 12:\tobj = -3.122541983387e-01\terr = 3.4361928372e-01\ttime = 0.05 sec\n[ Info: VUMPS 13:\tobj = -3.175415058698e-01\terr = 3.4372788072e-01\ttime = 0.06 sec\n[ Info: VUMPS 14:\tobj = -9.281281368249e-02\terr = 3.8082690832e-01\ttime = 0.04 sec\n[ Info: VUMPS 15:\tobj = -1.118289260232e-01\terr = 3.9703529501e-01\ttime = 0.04 sec\n[ Info: VUMPS 16:\tobj = -3.392299177529e-02\terr = 3.8653278445e-01\ttime = 0.04 sec\n[ Info: VUMPS 17:\tobj = -8.859386904872e-02\terr = 3.7559265639e-01\ttime = 0.06 sec\n[ Info: VUMPS 18:\tobj = -2.660652072169e-01\terr = 3.4535690909e-01\ttime = 0.06 sec\n[ Info: VUMPS 19:\tobj = +1.581362017845e-01\terr = 3.6728199421e-01\ttime = 0.02 sec\n[ Info: VUMPS 20:\tobj = -2.614275413781e-03\terr = 3.5210479173e-01\ttime = 0.04 sec\n[ Info: VUMPS 21:\tobj = -1.404557974268e-01\terr = 3.8727147114e-01\ttime = 0.02 sec\n[ Info: VUMPS 22:\tobj = -1.922542821356e-01\terr = 3.6768505428e-01\ttime = 0.05 sec\n[ Info: VUMPS 23:\tobj = +8.174391358782e-02\terr = 3.9158252120e-01\ttime = 0.02 sec\n[ Info: VUMPS 24:\tobj = +4.347184217158e-02\terr = 3.3940461711e-01\ttime = 0.05 sec\n[ Info: VUMPS 25:\tobj = -2.122928828839e-01\terr = 3.6816674483e-01\ttime = 0.02 sec\n[ Info: VUMPS 26:\tobj = -3.750381325917e-02\terr = 4.4510656286e-01\ttime = 0.06 sec\n[ Info: VUMPS 27:\tobj = -9.698985317742e-02\terr = 4.0266067497e-01\ttime = 0.05 sec\n[ Info: VUMPS 28:\tobj = -2.160914808205e-01\terr = 3.6590508687e-01\ttime = 0.03 sec\n[ Info: VUMPS 29:\tobj = +4.936490579149e-02\terr = 3.7234044270e-01\ttime = 0.05 sec\n[ Info: VUMPS 30:\tobj = -1.148676233851e-01\terr = 4.1462641635e-01\ttime = 0.02 sec\n[ Info: VUMPS 31:\tobj = -1.519618595135e-01\terr = 3.7492975708e-01\ttime = 0.05 sec\n[ Info: VUMPS 32:\tobj = -1.890862522082e-01\terr = 3.7659388392e-01\ttime = 0.03 sec\n[ Info: VUMPS 33:\tobj = -7.477276890967e-02\terr = 3.9194272124e-01\ttime = 0.05 sec\n[ Info: VUMPS 34:\tobj = -1.940989007410e-01\terr = 3.9403330192e-01\ttime = 0.03 sec\n[ Info: VUMPS 35:\tobj = -3.502934869819e-01\terr = 3.0111969128e-01\ttime = 0.05 sec\n[ Info: VUMPS 36:\tobj = -3.442085541276e-01\terr = 3.2611257359e-01\ttime = 0.04 sec\n[ Info: VUMPS 37:\tobj = -2.312483202161e-01\terr = 3.7396977836e-01\ttime = 0.06 sec\n[ Info: VUMPS 38:\tobj = -2.282920202884e-01\terr = 3.5801388290e-01\ttime = 0.06 sec\n[ Info: VUMPS 39:\tobj = -3.434233746212e-01\terr = 3.3005413456e-01\ttime = 0.05 sec\n[ Info: VUMPS 40:\tobj = -3.700311228608e-01\terr = 2.8698807789e-01\ttime = 0.05 sec\n[ Info: VUMPS 41:\tobj = -2.287419146432e-01\terr = 3.7652136991e-01\ttime = 0.08 sec\n[ Info: VUMPS 42:\tobj = -1.848386897474e-01\terr = 3.9410789712e-01\ttime = 0.07 sec\n[ Info: VUMPS 43:\tobj = -4.151049475911e-02\terr = 3.6614428192e-01\ttime = 0.04 sec\n[ Info: VUMPS 44:\tobj = +4.278404791371e-02\terr = 3.8999971963e-01\ttime = 0.06 sec\n[ Info: VUMPS 45:\tobj = +4.133615949384e-02\terr = 3.7259192609e-01\ttime = 0.04 sec\n[ Info: VUMPS 46:\tobj = -1.755417704686e-01\terr = 3.8281160487e-01\ttime = 0.06 sec\n[ Info: VUMPS 47:\tobj = -3.433301511715e-01\terr = 3.1797681990e-01\ttime = 0.03 sec\n[ Info: VUMPS 48:\tobj = +8.038768523644e-02\terr = 3.5190647487e-01\ttime = 0.05 sec\n[ Info: VUMPS 49:\tobj = -6.209071290954e-02\terr = 3.4368443495e-01\ttime = 0.07 sec\n[ Info: VUMPS 50:\tobj = +1.373233695943e-01\terr = 3.4584780766e-01\ttime = 0.04 sec\n[ Info: VUMPS 51:\tobj = -1.298395809866e-02\terr = 3.7394444037e-01\ttime = 0.06 sec\n[ Info: VUMPS 52:\tobj = -1.849662152303e-01\terr = 4.0186739319e-01\ttime = 0.04 sec\n[ Info: VUMPS 53:\tobj = -2.535592561522e-01\terr = 3.6315928824e-01\ttime = 0.05 sec\n[ Info: VUMPS 54:\tobj = -2.078073506292e-01\terr = 3.8862703529e-01\ttime = 0.03 sec\n[ Info: VUMPS 55:\tobj = -2.648807481312e-01\terr = 3.5935081624e-01\ttime = 0.05 sec\n[ Info: VUMPS 56:\tobj = +3.508321588679e-02\terr = 3.5155300157e-01\ttime = 0.06 sec\n[ Info: VUMPS 57:\tobj = +2.587094014595e-02\terr = 3.7426723561e-01\ttime = 0.05 sec\n[ Info: VUMPS 58:\tobj = +6.099768411641e-02\terr = 3.6261231989e-01\ttime = 0.06 sec\n[ Info: VUMPS 59:\tobj = +6.085060881519e-02\terr = 3.5718570541e-01\ttime = 0.02 sec\n[ Info: VUMPS 60:\tobj = -4.856039331256e-02\terr = 3.9347118222e-01\ttime = 0.06 sec\n[ Info: VUMPS 61:\tobj = -5.072268826867e-02\terr = 3.8271040330e-01\ttime = 0.04 sec\n[ Info: VUMPS 62:\tobj = +1.769142598093e-02\terr = 4.0183932016e-01\ttime = 0.05 sec\n[ Info: VUMPS 63:\tobj = +5.913223876388e-02\terr = 4.0964563195e-01\ttime = 0.06 sec\n[ Info: VUMPS 64:\tobj = -2.478892754727e-01\terr = 3.8032380630e-01\ttime = 0.04 sec\n[ Info: VUMPS 65:\tobj = -3.071655369627e-01\terr = 3.4522086404e-01\ttime = 0.05 sec\n[ Info: VUMPS 66:\tobj = -3.204977019062e-01\terr = 3.2905910740e-01\ttime = 0.05 sec\n[ Info: VUMPS 67:\tobj = -2.546816866134e-01\terr = 3.8561093133e-01\ttime = 0.07 sec\n[ Info: VUMPS 68:\tobj = -2.393554685021e-01\terr = 3.5880361408e-01\ttime = 0.05 sec\n[ Info: VUMPS 69:\tobj = -1.327133696952e-01\terr = 4.0101733932e-01\ttime = 0.06 sec\n[ Info: VUMPS 70:\tobj = -1.041902383608e-01\terr = 4.1285042628e-01\ttime = 0.05 sec\n[ Info: VUMPS 71:\tobj = -1.993915263334e-01\terr = 3.6003918734e-01\ttime = 0.04 sec\n[ Info: VUMPS 72:\tobj = -1.940520154241e-01\terr = 3.4570202542e-01\ttime = 0.02 sec\n[ Info: VUMPS 73:\tobj = -8.071173596559e-02\terr = 3.9919344455e-01\ttime = 0.04 sec\n[ Info: VUMPS 74:\tobj = -1.370928589038e-01\terr = 3.8043789146e-01\ttime = 0.02 sec\n[ Info: VUMPS 75:\tobj = -2.590488646429e-01\terr = 3.6030703598e-01\ttime = 0.05 sec\n[ Info: VUMPS 76:\tobj = -4.074845294173e-01\terr = 2.2747635384e-01\ttime = 0.03 sec\n[ Info: VUMPS 77:\tobj = -4.083741658015e-01\terr = 2.2604491079e-01\ttime = 0.05 sec\n[ Info: VUMPS 78:\tobj = +1.005627309383e-01\terr = 3.4879269264e-01\ttime = 0.05 sec\n[ Info: VUMPS 79:\tobj = -1.534111629484e-01\terr = 4.0398980845e-01\ttime = 0.04 sec\n[ Info: VUMPS 80:\tobj = -1.185244700305e-01\terr = 4.1527071676e-01\ttime = 0.05 sec\n[ Info: VUMPS 81:\tobj = -2.203348020820e-01\terr = 3.4143151318e-01\ttime = 0.04 sec\n[ Info: VUMPS 82:\tobj = -5.889431350950e-02\terr = 3.9822663932e-01\ttime = 0.05 sec\n[ Info: VUMPS 83:\tobj = -1.737018741265e-01\terr = 3.8538020144e-01\ttime = 0.04 sec\n[ Info: VUMPS 84:\tobj = -1.582331643179e-01\terr = 3.6506684092e-01\ttime = 0.02 sec\n[ Info: VUMPS 85:\tobj = -2.020317867236e-01\terr = 3.7807390527e-01\ttime = 0.05 sec\n[ Info: VUMPS 86:\tobj = -6.233681285915e-02\terr = 3.7406473722e-01\ttime = 0.02 sec\n[ Info: VUMPS 87:\tobj = -1.314218634692e-01\terr = 3.8818132852e-01\ttime = 0.06 sec\n[ Info: VUMPS 88:\tobj = -2.302777507565e-01\terr = 3.6235120973e-01\ttime = 0.04 sec\n[ Info: VUMPS 89:\tobj = +1.777592295373e-02\terr = 3.1886054992e-01\ttime = 0.06 sec\n[ Info: VUMPS 90:\tobj = -9.137389133038e-02\terr = 3.6650533950e-01\ttime = 0.05 sec\n[ Info: VUMPS 91:\tobj = -1.522621453585e-01\terr = 3.7520570789e-01\ttime = 0.04 sec\n[ Info: VUMPS 92:\tobj = -2.067248068564e-01\terr = 3.8667875904e-01\ttime = 0.05 sec\n[ Info: VUMPS 93:\tobj = +2.047786471459e-02\terr = 3.7528645946e-01\ttime = 0.04 sec\n[ Info: VUMPS 94:\tobj = -2.196126737735e-01\terr = 3.7361837770e-01\ttime = 0.06 sec\n[ Info: VUMPS 95:\tobj = -3.148681836053e-01\terr = 3.3877001456e-01\ttime = 0.03 sec\n[ Info: VUMPS 96:\tobj = -3.632549896064e-01\terr = 3.1063135089e-01\ttime = 0.05 sec\n[ Info: VUMPS 97:\tobj = -2.359487524961e-01\terr = 3.4983505936e-01\ttime = 0.05 sec\n[ Info: VUMPS 98:\tobj = -2.085648662363e-01\terr = 3.6646074907e-01\ttime = 0.04 sec\n[ Info: VUMPS 99:\tobj = -3.378709599647e-01\terr = 3.1090195525e-01\ttime = 0.03 sec\n[ Info: VUMPS 100:\tobj = +1.697054331465e-01\terr = 3.3318043865e-01\ttime = 0.03 sec\n[ Info: VUMPS 101:\tobj = -1.372336728300e-01\terr = 3.9831002380e-01\ttime = 0.03 sec\n[ Info: VUMPS 102:\tobj = -2.025796302451e-01\terr = 3.6198000343e-01\ttime = 0.05 sec\n[ Info: VUMPS 103:\tobj = -2.078176354072e-01\terr = 3.8150634396e-01\ttime = 0.03 sec\n[ Info: VUMPS 104:\tobj = -2.923528623190e-01\terr = 3.3199471479e-01\ttime = 0.09 sec\n[ Info: VUMPS 105:\tobj = -2.895261890513e-02\terr = 3.9381156810e-01\ttime = 0.06 sec\n[ Info: VUMPS 106:\tobj = +1.102282311350e-01\terr = 3.6753101837e-01\ttime = 0.02 sec\n[ Info: VUMPS 107:\tobj = -3.457075224669e-03\terr = 3.8935262670e-01\ttime = 0.05 sec\n[ Info: VUMPS 108:\tobj = -1.401802303936e-01\terr = 3.5477482436e-01\ttime = 0.07 sec\n[ Info: VUMPS 109:\tobj = -2.773177515742e-01\terr = 3.5618814609e-01\ttime = 0.04 sec\n[ Info: VUMPS 110:\tobj = -2.980497929052e-01\terr = 3.3973067915e-01\ttime = 0.07 sec\n[ Info: VUMPS 111:\tobj = -3.666221447505e-01\terr = 2.9612511089e-01\ttime = 0.04 sec\n[ Info: VUMPS 112:\tobj = -3.406894034780e-01\terr = 3.1838335674e-01\ttime = 0.07 sec\n[ Info: VUMPS 113:\tobj = -4.117451756841e-01\terr = 2.1229269280e-01\ttime = 0.05 sec\n[ Info: VUMPS 114:\tobj = +3.472393021263e-02\terr = 4.2138653263e-01\ttime = 0.04 sec\n[ Info: VUMPS 115:\tobj = +6.929635845720e-03\terr = 4.0042995319e-01\ttime = 0.02 sec\n[ Info: VUMPS 116:\tobj = +1.198686632180e-01\terr = 3.5017433469e-01\ttime = 0.04 sec\n[ Info: VUMPS 117:\tobj = -1.271079129807e-01\terr = 3.7101933225e-01\ttime = 0.02 sec\n[ Info: VUMPS 118:\tobj = -1.834088729116e-01\terr = 3.6678418731e-01\ttime = 0.03 sec\n[ Info: VUMPS 119:\tobj = -3.363021880354e-01\terr = 3.1503549193e-01\ttime = 0.02 sec\n[ Info: VUMPS 120:\tobj = -4.275043892741e-01\terr = 1.5610761856e-01\ttime = 0.06 sec\n[ Info: VUMPS 121:\tobj = +3.978743301000e-02\terr = 3.1230305054e-01\ttime = 0.08 sec\n[ Info: VUMPS 122:\tobj = -1.990612171666e-01\terr = 3.6200810172e-01\ttime = 0.04 sec\n[ Info: VUMPS 123:\tobj = +1.050122944992e-01\terr = 3.4198140893e-01\ttime = 0.04 sec\n[ Info: VUMPS 124:\tobj = -5.398579365216e-02\terr = 4.1624422030e-01\ttime = 0.04 sec\n[ Info: VUMPS 125:\tobj = -1.003705443385e-01\terr = 3.7636491379e-01\ttime = 0.02 sec\n[ Info: VUMPS 126:\tobj = +8.454616496648e-02\terr = 3.5803981901e-01\ttime = 0.04 sec\n[ Info: VUMPS 127:\tobj = -1.128523326267e-01\terr = 3.8181570938e-01\ttime = 0.03 sec\n[ Info: VUMPS 128:\tobj = -2.150635416320e-01\terr = 3.5780210657e-01\ttime = 0.04 sec\n[ Info: VUMPS 129:\tobj = -1.312465126627e-01\terr = 3.8405159732e-01\ttime = 0.06 sec\n[ Info: VUMPS 130:\tobj = -3.846997189431e-02\terr = 4.2623757858e-01\ttime = 0.05 sec\n[ Info: VUMPS 131:\tobj = +2.473200047618e-02\terr = 3.5905352543e-01\ttime = 0.05 sec\n[ Info: VUMPS 132:\tobj = +7.006948564206e-02\terr = 3.4845271565e-01\ttime = 0.04 sec\n[ Info: VUMPS 133:\tobj = -2.383461944993e-01\terr = 3.7052130221e-01\ttime = 0.06 sec\n[ Info: VUMPS 134:\tobj = -2.062217898227e-01\terr = 3.6937256423e-01\ttime = 0.04 sec\n[ Info: VUMPS 135:\tobj = -2.274384652936e-01\terr = 3.4724295244e-01\ttime = 0.07 sec\n[ Info: VUMPS 136:\tobj = -2.622435856918e-01\terr = 3.4143263011e-01\ttime = 0.05 sec\n[ Info: VUMPS 137:\tobj = -1.368393705006e-01\terr = 3.9505761386e-01\ttime = 0.04 sec\n[ Info: VUMPS 138:\tobj = -2.365952891363e-01\terr = 3.6070782003e-01\ttime = 0.05 sec\n[ Info: VUMPS 139:\tobj = -3.285892419662e-01\terr = 3.2510337702e-01\ttime = 0.06 sec\n[ Info: VUMPS 140:\tobj = -2.897155176623e-01\terr = 3.4971272209e-01\ttime = 0.05 sec\n[ Info: VUMPS 141:\tobj = -5.613172601920e-02\terr = 4.0280146205e-01\ttime = 0.06 sec\n[ Info: VUMPS 142:\tobj = -1.912055510339e-01\terr = 3.8086840086e-01\ttime = 0.06 sec\n[ Info: VUMPS 143:\tobj = -2.522493416812e-01\terr = 3.7780461889e-01\ttime = 0.03 sec\n[ Info: VUMPS 144:\tobj = -1.448388260442e-01\terr = 3.9735778286e-01\ttime = 0.06 sec\n[ Info: VUMPS 145:\tobj = +2.133811571892e-02\terr = 3.6767706542e-01\ttime = 0.05 sec\n[ Info: VUMPS 146:\tobj = -1.021149430836e-01\terr = 4.1518428940e-01\ttime = 0.04 sec\n[ Info: VUMPS 147:\tobj = +3.345423157498e-02\terr = 3.7487854814e-01\ttime = 0.06 sec\n[ Info: VUMPS 148:\tobj = -1.519027769061e-01\terr = 3.7323297896e-01\ttime = 0.04 sec\n[ Info: VUMPS 149:\tobj = -1.015157315769e-01\terr = 3.9037495750e-01\ttime = 0.07 sec\n[ Info: VUMPS 150:\tobj = -7.525226965218e-02\terr = 4.0412444789e-01\ttime = 0.05 sec\n[ Info: VUMPS 151:\tobj = -1.435426260194e-01\terr = 4.0959006551e-01\ttime = 0.08 sec\n[ Info: VUMPS 152:\tobj = -1.234168209435e-01\terr = 4.0252461632e-01\ttime = 0.02 sec\n[ Info: VUMPS 153:\tobj = -1.582356991859e-01\terr = 4.0856159774e-01\ttime = 0.07 sec\n[ Info: VUMPS 154:\tobj = -2.611502661937e-02\terr = 3.7361316068e-01\ttime = 0.02 sec\n[ Info: VUMPS 155:\tobj = -1.903742563432e-02\terr = 3.6268799414e-01\ttime = 0.05 sec\n[ Info: VUMPS 156:\tobj = -1.660075702137e-01\terr = 3.6001499475e-01\ttime = 0.04 sec\n[ Info: VUMPS 157:\tobj = -1.750801644509e-01\terr = 3.5799477869e-01\ttime = 0.03 sec\n[ Info: VUMPS 158:\tobj = -3.185357562769e-01\terr = 3.4039580564e-01\ttime = 0.04 sec\n[ Info: VUMPS 159:\tobj = -3.462765635183e-01\terr = 3.0750748489e-01\ttime = 0.03 sec\n[ Info: VUMPS 160:\tobj = -3.906343752662e-01\terr = 2.7025958372e-01\ttime = 0.05 sec\n[ Info: VUMPS 161:\tobj = +6.478821525323e-02\terr = 4.1194192280e-01\ttime = 0.05 sec\n[ Info: VUMPS 162:\tobj = -2.303254431617e-02\terr = 3.8071990310e-01\ttime = 0.04 sec\n[ Info: VUMPS 163:\tobj = -2.010080764751e-01\terr = 3.7801881819e-01\ttime = 0.04 sec\n[ Info: VUMPS 164:\tobj = -3.545532748718e-01\terr = 2.8772339262e-01\ttime = 0.04 sec\n[ Info: VUMPS 165:\tobj = -3.269217578981e-01\terr = 3.3116005000e-01\ttime = 0.05 sec\n[ Info: VUMPS 166:\tobj = -7.763273380566e-02\terr = 4.4233452292e-01\ttime = 0.05 sec\n[ Info: VUMPS 167:\tobj = -6.297628554394e-02\terr = 4.0291320901e-01\ttime = 0.02 sec\n[ Info: VUMPS 168:\tobj = -6.509753260918e-02\terr = 3.7453292998e-01\ttime = 0.04 sec\n[ Info: VUMPS 169:\tobj = -1.479501367088e-01\terr = 3.7646685662e-01\ttime = 0.06 sec\n[ Info: VUMPS 170:\tobj = -1.936550011338e-01\terr = 3.9968563965e-01\ttime = 0.05 sec\n[ Info: VUMPS 171:\tobj = -2.407761747630e-01\terr = 3.8299383049e-01\ttime = 0.05 sec\n[ Info: VUMPS 172:\tobj = +2.261073305309e-02\terr = 4.0104933806e-01\ttime = 0.03 sec\n[ Info: VUMPS 173:\tobj = -7.166260900992e-02\terr = 3.9840210145e-01\ttime = 0.04 sec\n[ Info: VUMPS 174:\tobj = -1.839330523396e-01\terr = 3.7559526845e-01\ttime = 0.03 sec\n[ Info: VUMPS 175:\tobj = -3.059547394952e-01\terr = 3.3999396097e-01\ttime = 0.04 sec\n[ Info: VUMPS 176:\tobj = -2.995029313597e-01\terr = 3.4151945139e-01\ttime = 0.06 sec\n[ Info: VUMPS 177:\tobj = -1.628200467586e-01\terr = 3.9581213200e-01\ttime = 0.03 sec\n[ Info: VUMPS 178:\tobj = -2.771745987181e-02\terr = 3.7799012327e-01\ttime = 0.04 sec\n[ Info: VUMPS 179:\tobj = -2.450722764418e-01\terr = 3.6283636173e-01\ttime = 0.03 sec\n[ Info: VUMPS 180:\tobj = +2.249435492935e-02\terr = 3.8247790534e-01\ttime = 0.07 sec\n[ Info: VUMPS 181:\tobj = -2.354825221975e-02\terr = 4.1422828465e-01\ttime = 0.03 sec\n[ Info: VUMPS 182:\tobj = -1.142934591710e-01\terr = 3.8986670495e-01\ttime = 0.04 sec\n[ Info: VUMPS 183:\tobj = -1.567308697369e-01\terr = 3.9700243050e-01\ttime = 0.03 sec\n[ Info: VUMPS 184:\tobj = -1.842499532379e-01\terr = 3.6532838941e-01\ttime = 0.05 sec\n[ Info: VUMPS 185:\tobj = -2.514877837893e-01\terr = 3.6637072380e-01\ttime = 0.03 sec\n[ Info: VUMPS 186:\tobj = -5.058982255378e-02\terr = 4.0946736692e-01\ttime = 0.06 sec\n[ Info: VUMPS 187:\tobj = -3.684615096066e-03\terr = 4.0659110148e-01\ttime = 0.03 sec\n[ Info: VUMPS 188:\tobj = -1.225767651180e-01\terr = 4.2689031391e-01\ttime = 0.05 sec\n[ Info: VUMPS 189:\tobj = -2.461679320853e-01\terr = 3.6120729961e-01\ttime = 0.04 sec\n[ Info: VUMPS 190:\tobj = +6.763190603494e-02\terr = 3.8401937650e-01\ttime = 0.03 sec\n[ Info: VUMPS 191:\tobj = +6.358079111108e-02\terr = 3.8794532554e-01\ttime = 0.04 sec\n[ Info: VUMPS 192:\tobj = -2.591627687434e-01\terr = 3.4498062399e-01\ttime = 0.03 sec\n[ Info: VUMPS 193:\tobj = -3.469647117223e-01\terr = 3.1920950928e-01\ttime = 0.07 sec\n[ Info: VUMPS 194:\tobj = -2.328255401437e-01\terr = 3.7087112305e-01\ttime = 0.05 sec\n[ Info: VUMPS 195:\tobj = -1.059181306961e-01\terr = 3.9644832676e-01\ttime = 0.06 sec\n[ Info: VUMPS 196:\tobj = +3.165492219560e-02\terr = 3.4664317312e-01\ttime = 0.04 sec\n[ Info: VUMPS 197:\tobj = -1.060919702177e-01\terr = 4.0404073514e-01\ttime = 0.06 sec\n[ Info: VUMPS 198:\tobj = -7.551485865858e-02\terr = 4.1482067043e-01\ttime = 0.03 sec\n[ Info: VUMPS 199:\tobj = -8.128843893232e-02\terr = 3.8193109836e-01\ttime = 0.07 sec\n┌ Warning: VUMPS cancel 200:\tobj = -1.297030723726e-01\terr = 3.8203051738e-01\ttime = 9.08 sec\n└ @ MPSKit ~/Projects/MPSKit.jl/src/algorithms/groundstate/vumps.jl:71\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"As you can see, VUMPS struggles to converge. On it's own, that is already quite curious. Maybe we can do better using another algorithm, such as gradient descent.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"groundstate, cache, delta = find_groundstate(state, H, GradientGrassmann(; maxiter=20));","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"[ Info: CG: initializing with f = 0.249993227089, ‖∇f‖ = 5.1973e-03\n[ Info: CG: iter 1: f = -0.104179418829, ‖∇f‖ = 3.1103e-01, α = 1.34e+04, β = 0.00e+00, nfg = 5\n[ Info: CG: iter 2: f = -0.168230521916, ‖∇f‖ = 3.1218e-01, α = 1.73e+00, β = 4.36e+01, nfg = 25\n[ Info: CG: iter 3: f = -0.279139021454, ‖∇f‖ = 2.5424e-01, α = 1.12e+00, β = 6.09e-01, nfg = 3\n[ Info: CG: iter 4: f = -0.351436956991, ‖∇f‖ = 1.8762e-01, α = 8.32e-01, β = 2.88e-01, nfg = 3\n[ Info: CG: iter 5: f = -0.394810706473, ‖∇f‖ = 1.5263e-01, α = 7.39e-01, β = 2.23e-01, nfg = 2\n[ Info: CG: iter 6: f = -0.421934998173, ‖∇f‖ = 1.1117e-01, α = 6.51e-01, β = 3.64e-01, nfg = 2\n[ Info: CG: iter 7: f = -0.432301255729, ‖∇f‖ = 6.0604e-02, α = 5.15e-01, β = 3.63e-01, nfg = 2\n[ Info: CG: iter 8: f = -0.436376560912, ‖∇f‖ = 4.3154e-02, α = 3.66e-01, β = 3.53e-01, nfg = 2\n[ Info: CG: iter 9: f = -0.438323587926, ‖∇f‖ = 3.4866e-02, α = 2.49e-01, β = 5.20e-01, nfg = 2\n[ Info: CG: iter 10: f = -0.439871747915, ‖∇f‖ = 2.4460e-02, α = 3.84e-01, β = 4.02e-01, nfg = 2\n[ Info: CG: iter 11: f = -0.440833392787, ‖∇f‖ = 1.7872e-02, α = 3.89e-01, β = 3.60e-01, nfg = 2\n[ Info: CG: iter 12: f = -0.441105694369, ‖∇f‖ = 1.6493e-02, α = 1.27e-01, β = 6.83e-01, nfg = 2\n[ Info: CG: iter 13: f = -0.441491345325, ‖∇f‖ = 1.4925e-02, α = 1.90e-01, β = 8.48e-01, nfg = 2\n[ Info: CG: iter 14: f = -0.441792424830, ‖∇f‖ = 1.2359e-02, α = 2.98e-01, β = 3.23e-01, nfg = 2\n[ Info: CG: iter 15: f = -0.442153471150, ‖∇f‖ = 1.0004e-02, α = 4.72e-01, β = 3.45e-01, nfg = 2\n[ Info: CG: iter 16: f = -0.442265625493, ‖∇f‖ = 9.2135e-03, α = 1.70e-01, β = 6.20e-01, nfg = 2\n[ Info: CG: iter 17: f = -0.442409712129, ‖∇f‖ = 7.1718e-03, α = 3.16e-01, β = 5.69e-01, nfg = 2\n[ Info: CG: iter 18: f = -0.442533970670, ‖∇f‖ = 5.9509e-03, α = 3.59e-01, β = 4.16e-01, nfg = 2\n[ Info: CG: iter 19: f = -0.442582601670, ‖∇f‖ = 5.6643e-03, α = 1.19e-01, β = 8.47e-01, nfg = 2\n┌ Warning: CG: not converged to requested tol: f = -0.442655552067, ‖∇f‖ = 6.1012e-03\n└ @ OptimKit ~/.julia/packages/OptimKit/xpmbV/src/cg.jl:103\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"Convergence is quite slow and even fails after sufficiently many iterations. To understand why, we can look at the transfer matrix spectrum.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"transferplot(groundstate, groundstate)","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"We can clearly see multiple eigenvalues close to the unit circle. Our state is close to being non-injective, and represents the sum of multiple injective states. This is numerically very problematic, but also indicates that we used an incorrect ansatz to approximate the groundstate. We should retry with a larger unit cell.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/#Success","page":"The XXZ model","title":"Success","text":"","category":"section"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"Let's initialize a different initial state, this time with a 2-site unit cell:","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"state = InfiniteMPS(fill(2, 2), fill(20, 2))","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"2-site InfiniteMPS:\n│ ⋮\n│ C[2]: TensorMap(ℂ^20 ← ℂ^20)\n├── AL[2]: TensorMap((ℂ^20 ⊗ ℂ^2) ← ℂ^20)\n├── AL[1]: TensorMap((ℂ^20 ⊗ ℂ^2) ← ℂ^20)\n│ ⋮\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"In MPSKit, we require that the periodicity of the hamiltonian equals that of the state it is applied to. This is not a big obstacle, you can simply repeat the original hamiltonian. Alternatively, the hamiltonian can be constructed directly on a two-site unitcell by making use of MPSKitModels.jl's @mpoham.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"# H2 = repeat(H, 2); -- copies the one-site version\nH2 = heisenberg_XXX(ComplexF64, Trivial, InfiniteChain(2); spin=1 // 2)\ngroundstate, envs, delta = find_groundstate(state, H2,\n VUMPS(; maxiter=100, tol=1e-12));","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"[ Info: VUMPS init:\tobj = +4.994527818488e-01\terr = 4.7959e-02\n[ Info: VUMPS 1:\tobj = -5.224213331967e-01\terr = 3.1869497986e-01\ttime = 0.07 sec\n[ Info: VUMPS 2:\tobj = -8.703292449817e-01\terr = 9.7881092516e-02\ttime = 0.04 sec\n[ Info: VUMPS 3:\tobj = -8.853872271509e-01\terr = 1.1633880994e-02\ttime = 0.05 sec\n[ Info: VUMPS 4:\tobj = -8.859759226381e-01\terr = 5.0303292009e-03\ttime = 0.06 sec\n[ Info: VUMPS 5:\tobj = -8.861272827748e-01\terr = 4.0977568854e-03\ttime = 0.03 sec\n[ Info: VUMPS 6:\tobj = -8.861876892553e-01\terr = 2.8143569786e-03\ttime = 0.06 sec\n[ Info: VUMPS 7:\tobj = -8.862118265423e-01\terr = 2.4768815055e-03\ttime = 0.07 sec\n[ Info: VUMPS 8:\tobj = -8.862240634280e-01\terr = 2.1529722171e-03\ttime = 0.07 sec\n[ Info: VUMPS 9:\tobj = -8.862295952770e-01\terr = 2.0143660733e-03\ttime = 0.08 sec\n[ Info: VUMPS 10:\tobj = -8.862325590423e-01\terr = 1.9696799082e-03\ttime = 0.07 sec\n[ Info: VUMPS 11:\tobj = -8.862339539915e-01\terr = 1.9072844137e-03\ttime = 0.07 sec\n[ Info: VUMPS 12:\tobj = -8.862347209414e-01\terr = 1.9329517027e-03\ttime = 0.04 sec\n[ Info: VUMPS 13:\tobj = -8.862350788779e-01\terr = 1.8912383017e-03\ttime = 0.08 sec\n[ Info: VUMPS 14:\tobj = -8.862353072621e-01\terr = 1.9119217581e-03\ttime = 0.07 sec\n[ Info: VUMPS 15:\tobj = -8.862354080095e-01\terr = 1.8651910333e-03\ttime = 0.07 sec\n[ Info: VUMPS 16:\tobj = -8.862354997154e-01\terr = 1.8780338112e-03\ttime = 0.07 sec\n[ Info: VUMPS 17:\tobj = -8.862355500667e-01\terr = 1.8132834599e-03\ttime = 0.06 sec\n[ Info: VUMPS 18:\tobj = -8.862356079518e-01\terr = 1.8176447019e-03\ttime = 0.07 sec\n[ Info: VUMPS 19:\tobj = -8.862356026529e-01\terr = 1.7897346650e-03\ttime = 0.06 sec\n[ Info: VUMPS 20:\tobj = -8.862356494807e-01\terr = 1.7869452100e-03\ttime = 0.05 sec\n[ Info: VUMPS 21:\tobj = -8.862357156491e-01\terr = 1.7171781823e-03\ttime = 0.07 sec\n[ Info: VUMPS 22:\tobj = -8.862356705107e-01\terr = 1.7618627080e-03\ttime = 0.05 sec\n[ Info: VUMPS 23:\tobj = -8.862356847446e-01\terr = 1.7345893329e-03\ttime = 0.06 sec\n[ Info: VUMPS 24:\tobj = -8.862356597631e-01\terr = 1.7698180368e-03\ttime = 0.06 sec\n[ Info: VUMPS 25:\tobj = -8.862356369663e-01\terr = 1.7832515198e-03\ttime = 0.07 sec\n[ Info: VUMPS 26:\tobj = -8.862355639238e-01\terr = 1.8610433054e-03\ttime = 0.07 sec\n[ Info: VUMPS 27:\tobj = -8.862355966939e-01\terr = 1.8414491439e-03\ttime = 0.07 sec\n[ Info: VUMPS 28:\tobj = -8.862354448304e-01\terr = 1.9601069224e-03\ttime = 0.07 sec\n[ Info: VUMPS 29:\tobj = -8.862353997121e-01\terr = 2.0323064685e-03\ttime = 0.04 sec\n[ Info: VUMPS 30:\tobj = -8.862352867417e-01\terr = 2.0852298701e-03\ttime = 0.06 sec\n[ Info: VUMPS 31:\tobj = -8.862350688513e-01\terr = 2.3296901858e-03\ttime = 0.08 sec\n[ Info: VUMPS 32:\tobj = -8.862348370300e-01\terr = 2.4308916811e-03\ttime = 0.08 sec\n[ Info: VUMPS 33:\tobj = -8.862348650705e-01\terr = 2.5264912559e-03\ttime = 0.07 sec\n[ Info: VUMPS 34:\tobj = -8.862341340353e-01\terr = 2.8806808793e-03\ttime = 0.07 sec\n[ Info: VUMPS 35:\tobj = -8.862340510957e-01\terr = 3.1043746978e-03\ttime = 0.07 sec\n[ Info: VUMPS 36:\tobj = -8.862334585911e-01\terr = 3.2535241129e-03\ttime = 0.07 sec\n[ Info: VUMPS 37:\tobj = -8.862322313415e-01\terr = 4.0963820560e-03\ttime = 0.05 sec\n[ Info: VUMPS 38:\tobj = -8.862328105793e-01\terr = 3.5663760522e-03\ttime = 0.05 sec\n[ Info: VUMPS 39:\tobj = -8.862317650974e-01\terr = 4.3666283036e-03\ttime = 0.08 sec\n[ Info: VUMPS 40:\tobj = -8.862334734959e-01\terr = 3.2172539857e-03\ttime = 0.06 sec\n[ Info: VUMPS 41:\tobj = -8.862328031496e-01\terr = 4.0602562223e-03\ttime = 0.07 sec\n[ Info: VUMPS 42:\tobj = -8.862348928428e-01\terr = 2.8096230226e-03\ttime = 0.06 sec\n[ Info: VUMPS 43:\tobj = -8.862354347226e-01\terr = 2.9469451252e-03\ttime = 0.07 sec\n[ Info: VUMPS 44:\tobj = -8.862369582324e-01\terr = 2.0065666373e-03\ttime = 0.03 sec\n[ Info: VUMPS 45:\tobj = -8.862376214330e-01\terr = 1.5332753632e-03\ttime = 0.07 sec\n[ Info: VUMPS 46:\tobj = -8.862381576736e-01\terr = 9.5235621400e-04\ttime = 0.07 sec\n[ Info: VUMPS 47:\tobj = -8.862383675148e-01\terr = 5.9064456193e-04\ttime = 0.06 sec\n[ Info: VUMPS 48:\tobj = -8.862384608233e-01\terr = 3.4391997505e-04\ttime = 0.08 sec\n[ Info: VUMPS 49:\tobj = -8.862384963189e-01\terr = 1.9914113331e-04\ttime = 0.07 sec\n[ Info: VUMPS 50:\tobj = -8.862385106659e-01\terr = 1.1648442343e-04\ttime = 0.06 sec\n[ Info: VUMPS 51:\tobj = -8.862385173677e-01\terr = 7.0216183061e-05\ttime = 0.05 sec\n[ Info: VUMPS 52:\tobj = -8.862385211516e-01\terr = 5.4936268184e-05\ttime = 0.07 sec\n[ Info: VUMPS 53:\tobj = -8.862385239261e-01\terr = 5.0775181524e-05\ttime = 0.05 sec\n[ Info: VUMPS 54:\tobj = -8.862385263536e-01\terr = 4.9093824356e-05\ttime = 0.06 sec\n[ Info: VUMPS 55:\tobj = -8.862385287510e-01\terr = 4.7160784987e-05\ttime = 0.05 sec\n[ Info: VUMPS 56:\tobj = -8.862385312350e-01\terr = 4.7356857246e-05\ttime = 0.06 sec\n[ Info: VUMPS 57:\tobj = -8.862385338978e-01\terr = 4.6554878190e-05\ttime = 0.07 sec\n[ Info: VUMPS 58:\tobj = -8.862385367826e-01\terr = 4.7893015679e-05\ttime = 0.05 sec\n[ Info: VUMPS 59:\tobj = -8.862385399464e-01\terr = 4.7866639440e-05\ttime = 0.08 sec\n[ Info: VUMPS 60:\tobj = -8.862385434317e-01\terr = 5.0108148399e-05\ttime = 0.08 sec\n[ Info: VUMPS 61:\tobj = -8.862385472946e-01\terr = 5.0701719642e-05\ttime = 0.06 sec\n[ Info: VUMPS 62:\tobj = -8.862385515924e-01\terr = 5.3747205154e-05\ttime = 0.06 sec\n[ Info: VUMPS 63:\tobj = -8.862385563928e-01\terr = 5.4917836680e-05\ttime = 0.07 sec\n[ Info: VUMPS 64:\tobj = -8.862385617762e-01\terr = 5.8736952243e-05\ttime = 0.07 sec\n[ Info: VUMPS 65:\tobj = -8.862385678319e-01\terr = 6.0517251626e-05\ttime = 0.04 sec\n[ Info: VUMPS 66:\tobj = -8.862385746724e-01\terr = 6.5122279370e-05\ttime = 0.05 sec\n[ Info: VUMPS 67:\tobj = -8.862385824209e-01\terr = 6.7603807255e-05\ttime = 0.08 sec\n[ Info: VUMPS 68:\tobj = -8.862385912344e-01\terr = 7.3037975820e-05\ttime = 0.06 sec\n[ Info: VUMPS 69:\tobj = -8.862386012855e-01\terr = 7.6356824733e-05\ttime = 0.06 sec\n[ Info: VUMPS 70:\tobj = -8.862386127926e-01\terr = 8.2675024543e-05\ttime = 0.08 sec\n[ Info: VUMPS 71:\tobj = -8.862386259979e-01\terr = 8.7080551030e-05\ttime = 0.08 sec\n[ Info: VUMPS 72:\tobj = -8.862386412013e-01\terr = 9.4240413691e-05\ttime = 0.07 sec\n[ Info: VUMPS 73:\tobj = -8.862386587357e-01\terr = 1.0001061678e-04\ttime = 0.06 sec\n[ Info: VUMPS 74:\tobj = -8.862386790008e-01\terr = 1.0787560414e-04\ttime = 0.05 sec\n[ Info: VUMPS 75:\tobj = -8.862387024327e-01\terr = 1.1491628128e-04\ttime = 0.07 sec\n[ Info: VUMPS 76:\tobj = -8.862387295295e-01\terr = 1.2350014063e-04\ttime = 0.07 sec\n[ Info: VUMPS 77:\tobj = -8.862387608070e-01\terr = 1.3154045663e-04\ttime = 0.08 sec\n[ Info: VUMPS 78:\tobj = -8.862387968010e-01\terr = 1.4054217709e-04\ttime = 0.08 sec\n[ Info: VUMPS 79:\tobj = -8.862388379935e-01\terr = 1.4918434598e-04\ttime = 0.08 sec\n[ Info: VUMPS 80:\tobj = -8.862388847728e-01\terr = 1.5756496092e-04\ttime = 0.06 sec\n[ Info: VUMPS 81:\tobj = -8.862389373185e-01\terr = 1.6556206078e-04\ttime = 0.05 sec\n[ Info: VUMPS 82:\tobj = -8.862389955195e-01\terr = 1.7207041444e-04\ttime = 0.05 sec\n[ Info: VUMPS 83:\tobj = -8.862390588490e-01\terr = 1.7709969160e-04\ttime = 0.06 sec\n[ Info: VUMPS 84:\tobj = -8.862391263089e-01\terr = 1.8017689240e-04\ttime = 0.07 sec\n[ Info: VUMPS 85:\tobj = -8.862391964083e-01\terr = 1.8083364727e-04\ttime = 0.06 sec\n[ Info: VUMPS 86:\tobj = -8.862392672643e-01\terr = 1.7896061249e-04\ttime = 0.06 sec\n[ Info: VUMPS 87:\tobj = -8.862393367843e-01\terr = 1.7435281981e-04\ttime = 0.07 sec\n[ Info: VUMPS 88:\tobj = -8.862394029305e-01\terr = 1.6733550307e-04\ttime = 0.07 sec\n[ Info: VUMPS 89:\tobj = -8.862394639791e-01\terr = 1.5822580553e-04\ttime = 0.08 sec\n[ Info: VUMPS 90:\tobj = -8.862395187139e-01\terr = 1.4763647565e-04\ttime = 0.05 sec\n[ Info: VUMPS 91:\tobj = -8.862395665083e-01\terr = 1.3613348343e-04\ttime = 0.07 sec\n[ Info: VUMPS 92:\tobj = -8.862396072866e-01\terr = 1.2433109567e-04\ttime = 0.06 sec\n[ Info: VUMPS 93:\tobj = -8.862396414074e-01\terr = 1.1271049944e-04\ttime = 0.09 sec\n[ Info: VUMPS 94:\tobj = -8.862396695130e-01\terr = 1.0166193044e-04\ttime = 0.08 sec\n[ Info: VUMPS 95:\tobj = -8.862396923871e-01\terr = 9.1428430976e-05\ttime = 0.09 sec\n[ Info: VUMPS 96:\tobj = -8.862397108436e-01\terr = 8.2152207117e-05\ttime = 0.08 sec\n[ Info: VUMPS 97:\tobj = -8.862397256537e-01\terr = 7.3876229899e-05\ttime = 0.06 sec\n[ Info: VUMPS 98:\tobj = -8.862397375053e-01\terr = 6.6584753895e-05\ttime = 0.07 sec\n[ Info: VUMPS 99:\tobj = -8.862397469874e-01\terr = 6.0216703928e-05\ttime = 0.07 sec\n┌ Warning: VUMPS cancel 100:\tobj = -8.862397545895e-01\terr = 5.4690768674e-05\ttime = 6.50 sec\n└ @ MPSKit ~/Projects/MPSKit.jl/src/algorithms/groundstate/vumps.jl:71\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"We get convergence, but it takes an enormous amount of iterations. The reason behind this becomes more obvious at higher bond dimensions:","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"groundstate, envs, delta = find_groundstate(state, H2,\n IDMRG2(; trscheme=truncdim(50), maxiter=20,\n tol=1e-12));\nentanglementplot(groundstate)","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"We see that some eigenvalues clearly belong to a group, and are almost degenerate. This implies 2 things:","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"there is superfluous information, if those eigenvalues are the same anyway\npoor convergence if we cut off within such a subspace","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"It are precisely those problems that we can solve by using symmetries.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/#Symmetries","page":"The XXZ model","title":"Symmetries","text":"","category":"section"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"The XXZ Heisenberg hamiltonian is SU(2) symmetric and we can exploit this to greatly speed up the simulation.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"It is cumbersome to construct symmetric hamiltonians, but luckily su(2) symmetric XXZ is already implemented:","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"H2 = heisenberg_XXX(ComplexF64, SU2Irrep, InfiniteChain(2); spin=1 // 2);","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"Our initial state should also be SU(2) symmetric. It now becomes apparent why we have to use a two-site periodic state. The physical space carries a half-integer charge and the first tensor maps the first virtual_space ⊗ the physical_space to the second virtual_space. Half-integer virtual charges will therefore map only to integer charges, and vice versa. The staggering thus happens on the virtual level.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"An alternative constructor for the initial state is","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"P = Rep[SU₂](1 // 2 => 1)\nV1 = Rep[SU₂](1 // 2 => 10, 3 // 2 => 5, 5 // 2 => 2)\nV2 = Rep[SU₂](0 => 15, 1 => 10, 2 => 5)\nstate = InfiniteMPS([P, P], [V1, V2]);","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"┌ Warning: Constructing an MPS from tensors that are not full rank\n└ @ MPSKit ~/Projects/MPSKit.jl/src/states/infinitemps.jl:149\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"Even though the bond dimension is higher than in the example without symmetry, convergence is reached much faster:","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"println(dim(V1))\nprintln(dim(V2))\ngroundstate, cache, delta = find_groundstate(state, H2,\n VUMPS(; maxiter=400, tol=1e-12));","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"52\n70\n[ Info: VUMPS init:\tobj = +8.571475316991e-02\terr = 4.0869e-01\n[ Info: VUMPS 1:\tobj = -8.841768943048e-01\terr = 3.0962778235e-02\ttime = 8.39 sec\n[ Info: VUMPS 2:\tobj = -8.858941441948e-01\terr = 6.8861549505e-03\ttime = 0.08 sec\n[ Info: VUMPS 3:\tobj = -8.861591970700e-01\terr = 3.1438981011e-03\ttime = 0.19 sec\n[ Info: VUMPS 4:\tobj = -8.862373586553e-01\terr = 1.5694150974e-03\ttime = 0.08 sec\n[ Info: VUMPS 5:\tobj = -8.862665008570e-01\terr = 9.6720118128e-04\ttime = 0.10 sec\n[ Info: VUMPS 6:\tobj = -8.862780790113e-01\terr = 7.6876116694e-04\ttime = 0.11 sec\n[ Info: VUMPS 7:\tobj = -8.862831659742e-01\terr = 6.6877783316e-04\ttime = 0.19 sec\n[ Info: VUMPS 8:\tobj = -8.862855860323e-01\terr = 5.3599376124e-04\ttime = 0.11 sec\n[ Info: VUMPS 9:\tobj = -8.862867663190e-01\terr = 4.0660286466e-04\ttime = 0.16 sec\n[ Info: VUMPS 10:\tobj = -8.862873424424e-01\terr = 3.0566269459e-04\ttime = 0.32 sec\n[ Info: VUMPS 11:\tobj = -8.862876251526e-01\terr = 2.2687597738e-04\ttime = 0.14 sec\n[ Info: VUMPS 12:\tobj = -8.862877641798e-01\terr = 1.6630235595e-04\ttime = 0.28 sec\n[ Info: VUMPS 13:\tobj = -8.862878324776e-01\terr = 1.2065962982e-04\ttime = 0.17 sec\n[ Info: VUMPS 14:\tobj = -8.862878659705e-01\terr = 8.6847532670e-05\ttime = 0.13 sec\n[ Info: VUMPS 15:\tobj = -8.862878823733e-01\terr = 6.2151682727e-05\ttime = 0.16 sec\n[ Info: VUMPS 16:\tobj = -8.862878903974e-01\terr = 4.4290628543e-05\ttime = 0.18 sec\n[ Info: VUMPS 17:\tobj = -8.862878943223e-01\terr = 3.1467696209e-05\ttime = 0.14 sec\n[ Info: VUMPS 18:\tobj = -8.862878962425e-01\terr = 2.2309311401e-05\ttime = 0.17 sec\n[ Info: VUMPS 19:\tobj = -8.862878971826e-01\terr = 1.5794437549e-05\ttime = 0.17 sec\n[ Info: VUMPS 20:\tobj = -8.862878976433e-01\terr = 1.1169983677e-05\ttime = 0.15 sec\n[ Info: VUMPS 21:\tobj = -8.862878978692e-01\terr = 7.8938125044e-06\ttime = 0.17 sec\n[ Info: VUMPS 22:\tobj = -8.862878979802e-01\terr = 5.5754187069e-06\ttime = 0.14 sec\n[ Info: VUMPS 23:\tobj = -8.862878980347e-01\terr = 3.9363165672e-06\ttime = 0.17 sec\n[ Info: VUMPS 24:\tobj = -8.862878980615e-01\terr = 2.7782600761e-06\ttime = 0.18 sec\n[ Info: VUMPS 25:\tobj = -8.862878980747e-01\terr = 1.9605416898e-06\ttime = 0.14 sec\n[ Info: VUMPS 26:\tobj = -8.862878980813e-01\terr = 1.3831566356e-06\ttime = 0.17 sec\n[ Info: VUMPS 27:\tobj = -8.862878980845e-01\terr = 9.7563836730e-07\ttime = 0.17 sec\n[ Info: VUMPS 28:\tobj = -8.862878980861e-01\terr = 6.8808237712e-07\ttime = 0.14 sec\n[ Info: VUMPS 29:\tobj = -8.862878980868e-01\terr = 4.8521326515e-07\ttime = 0.17 sec\n[ Info: VUMPS 30:\tobj = -8.862878980872e-01\terr = 3.4211403050e-07\ttime = 0.18 sec\n[ Info: VUMPS 31:\tobj = -8.862878980874e-01\terr = 2.4118986474e-07\ttime = 0.14 sec\n[ Info: VUMPS 32:\tobj = -8.862878980875e-01\terr = 1.7001487151e-07\ttime = 0.17 sec\n[ Info: VUMPS 33:\tobj = -8.862878980876e-01\terr = 1.1983516999e-07\ttime = 0.16 sec\n[ Info: VUMPS 34:\tobj = -8.862878980876e-01\terr = 8.4458211885e-08\ttime = 0.14 sec\n[ Info: VUMPS 35:\tobj = -8.862878980876e-01\terr = 5.9519779420e-08\ttime = 0.18 sec\n[ Info: VUMPS 36:\tobj = -8.862878980876e-01\terr = 4.1941570268e-08\ttime = 0.14 sec\n[ Info: VUMPS 37:\tobj = -8.862878980877e-01\terr = 2.9552481662e-08\ttime = 0.17 sec\n[ Info: VUMPS 38:\tobj = -8.862878980877e-01\terr = 2.0821461973e-08\ttime = 0.17 sec\n[ Info: VUMPS 39:\tobj = -8.862878980877e-01\terr = 1.4668928777e-08\ttime = 0.13 sec\n[ Info: VUMPS 40:\tobj = -8.862878980877e-01\terr = 1.0333740629e-08\ttime = 0.16 sec\n[ Info: VUMPS 41:\tobj = -8.862878980877e-01\terr = 7.2793133017e-09\ttime = 0.19 sec\n[ Info: VUMPS 42:\tobj = -8.862878980877e-01\terr = 5.1274193990e-09\ttime = 0.14 sec\n[ Info: VUMPS 43:\tobj = -8.862878980877e-01\terr = 3.6115696251e-09\ttime = 0.16 sec\n[ Info: VUMPS 44:\tobj = -8.862878980877e-01\terr = 2.5436748324e-09\ttime = 0.18 sec\n[ Info: VUMPS 45:\tobj = -8.862878980877e-01\terr = 1.7914400554e-09\ttime = 0.13 sec\n[ Info: VUMPS 46:\tobj = -8.862878980877e-01\terr = 1.2616075130e-09\ttime = 0.17 sec\n[ Info: VUMPS 47:\tobj = -8.862878980877e-01\terr = 8.8844294429e-10\ttime = 0.18 sec\n[ Info: VUMPS 48:\tobj = -8.862878980877e-01\terr = 6.2563200343e-10\ttime = 0.14 sec\n[ Info: VUMPS 49:\tobj = -8.862878980877e-01\terr = 4.4055009956e-10\ttime = 0.17 sec\n[ Info: VUMPS 50:\tobj = -8.862878980877e-01\terr = 3.1021022428e-10\ttime = 0.17 sec\n[ Info: VUMPS 51:\tobj = -8.862878980877e-01\terr = 2.1842377352e-10\ttime = 0.13 sec\n[ Info: VUMPS 52:\tobj = -8.862878980877e-01\terr = 1.5378883830e-10\ttime = 0.17 sec\n[ Info: VUMPS 53:\tobj = -8.862878980877e-01\terr = 1.0827914915e-10\ttime = 0.13 sec\n[ Info: VUMPS 54:\tobj = -8.862878980877e-01\terr = 7.6233561627e-11\ttime = 0.17 sec\n[ Info: VUMPS 55:\tobj = -8.862878980878e-01\terr = 5.3670361265e-11\ttime = 0.17 sec\n[ Info: VUMPS 56:\tobj = -8.862878980878e-01\terr = 3.7785296901e-11\ttime = 0.12 sec\n[ Info: VUMPS 57:\tobj = -8.862878980878e-01\terr = 2.6597183661e-11\ttime = 0.15 sec\n[ Info: VUMPS 58:\tobj = -8.862878980878e-01\terr = 1.8724144528e-11\ttime = 0.15 sec\n[ Info: VUMPS 59:\tobj = -8.862878980878e-01\terr = 1.3177752530e-11\ttime = 0.12 sec\n[ Info: VUMPS 60:\tobj = -8.862878980878e-01\terr = 9.2726977215e-12\ttime = 0.15 sec\n[ Info: VUMPS 61:\tobj = -8.862878980878e-01\terr = 6.5267922494e-12\ttime = 0.10 sec\n[ Info: VUMPS 62:\tobj = -8.862878980878e-01\terr = 4.5890864081e-12\ttime = 0.14 sec\n[ Info: VUMPS 63:\tobj = -8.862878980878e-01\terr = 3.2289295438e-12\ttime = 0.10 sec\n[ Info: VUMPS 64:\tobj = -8.862878980878e-01\terr = 2.2706304983e-12\ttime = 0.13 sec\n[ Info: VUMPS 65:\tobj = -8.862878980878e-01\terr = 1.5950561789e-12\ttime = 0.09 sec\n[ Info: VUMPS 66:\tobj = -8.862878980878e-01\terr = 1.1189780150e-12\ttime = 0.09 sec\n[ Info: VUMPS conv 67:\tobj = -8.862878980878e-01\terr = 7.7998640130e-13\ttime = 18.42 sec\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"This page was generated using Literate.jl.","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"EditURL = \"../../../../../examples/quantum1d/1.ising-cft/main.jl\"","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"(Image: ) (Image: ) (Image: )","category":"page"},{"location":"examples/quantum1d/1.ising-cft/#The-Ising-CFT-spectrum","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"","category":"section"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"This tutorial is meant to show the finite size CFT spectrum for the quantum Ising model. We do this by first employing an exact diagonalization technique, and then extending the analysis to larger system sizes through the use of MPS techniques.","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"using MPSKit, MPSKitModels, TensorKit, Plots, KrylovKit\nusing LinearAlgebra: eigen, diagm, Hermitian","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"The hamiltonian is defined on a finite lattice with periodic boundary conditions, which can be implemented as follows:","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"L = 12\nH = periodic_boundary_conditions(transverse_field_ising(), L)","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"12-site FiniteMPOHamiltonian{BlockTensorKit.SparseBlockTensorMap{AbstractTensorMap{ComplexF64, ComplexSpace, 2, 2}, ComplexF64, ComplexSpace, 2, 2, 4}}:\n┬ W[12]: 4×1×1×1 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ ⊕(ℂ^1)))\n┼ W[11]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[10]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[9]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[8]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[7]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[6]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[5]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[4]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[3]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[2]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┴ W[1]: 1×1×1×4 SparseBlockTensorMap((⊕(ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n","category":"page"},{"location":"examples/quantum1d/1.ising-cft/#Exact-diagonalisation","page":"The Ising CFT spectrum","title":"Exact diagonalisation","text":"","category":"section"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"In MPSKit, there is support for exact diagonalisation by leveraging the fact that applying the hamiltonian to an untruncated MPS will result in an effective hamiltonian on the center site which implements the action of the entire hamiltonian. Thus, optimizing the middle tensor is equivalent to optimixing a state in the entire Hilbert space, as all other tensors are just unitary matrices that mix the basis.","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"energies, states = exact_diagonalization(H; num=18, alg=Lanczos(; krylovdim=200));\nplot(real.(energies);\n seriestype=:scatter,\n legend=false,\n ylabel=\"energy\",\n xlabel=\"#eigenvalue\")","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"note: Krylov dimension\nNote that we have specified a large Krylov dimension as degenerate eigenvalues are notoriously difficult for iterative methods.","category":"page"},{"location":"examples/quantum1d/1.ising-cft/#Extracting-momentum","page":"The Ising CFT spectrum","title":"Extracting momentum","text":"","category":"section"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"Given a state, it is possible to assign a momentum label through the use of the translation operator. This operator can be defined in MPO language either diagramatically as","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"(Image: translation operator MPO)","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"or in the code as:","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"id = complex(isomorphism(ℂ^2, ℂ^2))\n@tensor O[-1 -2; -3 -4] := id[-1, -3] * id[-2, -4]\nT = periodic_boundary_conditions(InfiniteMPO([O]), L)","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"12-site FiniteMPO{TensorMap{ComplexF64, ComplexSpace, 2, 2, Vector{ComplexF64}}}:\n┬ O[12]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^1))\n┼ O[11]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[10]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[9]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[8]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[7]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[6]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[5]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[4]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[3]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[2]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┴ O[1]: TensorMap((ℂ^1 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"We can then calculate the momentum of the groundstate as the expectation value of this operator. However, there is a subtlety because of the degeneracies in the energy eigenvalues. The eigensolver will find an orthonormal basis within each energy subspace, but this basis is not necessarily a basis of eigenstates of the translation operator. In order to fix this, we diagonalize the translation operator within each energy subspace.","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"momentum(ψᵢ, ψⱼ=ψᵢ) = angle(dot(ψᵢ, T * ψⱼ))\n\nfunction fix_degeneracies(basis)\n N = zeros(ComplexF64, length(basis), length(basis))\n M = zeros(ComplexF64, length(basis), length(basis))\n for i in eachindex(basis), j in eachindex(basis)\n N[i, j] = dot(basis[i], basis[j])\n M[i, j] = momentum(basis[i], basis[j])\n end\n\n vals, vecs = eigen(Hermitian(N))\n M = (vecs' * M * vecs)\n M /= diagm(vals)\n\n vals, vecs = eigen(M)\n return angle.(vals)\nend\n\nmomenta = Float64[]\nappend!(momenta, fix_degeneracies(states[1:1]))\nappend!(momenta, fix_degeneracies(states[2:2]))\nappend!(momenta, fix_degeneracies(states[3:3]))\nappend!(momenta, fix_degeneracies(states[4:5]))\nappend!(momenta, fix_degeneracies(states[6:9]))\nappend!(momenta, fix_degeneracies(states[10:11]))\nappend!(momenta, fix_degeneracies(states[12:12]))\nappend!(momenta, fix_degeneracies(states[13:16]))\nappend!(momenta, fix_degeneracies(states[17:18]))\n\nplot(momenta,\n real.(energies[1:18]);\n seriestype=:scatter,\n xlabel=\"momentum\",\n ylabel=\"energy\",\n legend=false)","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/1.ising-cft/#Finite-bond-dimension","page":"The Ising CFT spectrum","title":"Finite bond dimension","text":"","category":"section"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"If we limit the maximum bond dimension of the MPS, we get an approximate solution, but we can reach higher system sizes.","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"L_mps = 20\nH_mps = periodic_boundary_conditions(transverse_field_ising(), L_mps)\nD = 64\nψ, envs, δ = find_groundstate(FiniteMPS(L_mps, ℂ^2, ℂ^D), H_mps, DMRG());","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"[ Info: DMRG init:\tobj = -1.965713989954e+01\terr = 7.3678e-02\n[ Info: DMRG 1:\tobj = -2.549098940727e+01\terr = 8.5575894990e-03\ttime = 1.91 sec\n[ Info: DMRG 2:\tobj = -2.549098968634e+01\terr = 1.0873003217e-06\ttime = 0.42 sec\n[ Info: DMRG 3:\tobj = -2.549098968636e+01\terr = 1.5192202571e-07\ttime = 0.77 sec\n[ Info: DMRG 4:\tobj = -2.549098968636e+01\terr = 1.5544174988e-08\ttime = 0.43 sec\n[ Info: DMRG 5:\tobj = -2.549098968636e+01\terr = 5.1424541508e-09\ttime = 0.50 sec\n[ Info: DMRG 6:\tobj = -2.549098968636e+01\terr = 3.1050577980e-09\ttime = 0.69 sec\n[ Info: DMRG 7:\tobj = -2.549098968636e+01\terr = 2.4204053165e-09\ttime = 0.51 sec\n[ Info: DMRG 8:\tobj = -2.549098968636e+01\terr = 1.8047148184e-09\ttime = 0.49 sec\n[ Info: DMRG 9:\tobj = -2.549098968636e+01\terr = 1.6394519024e-09\ttime = 0.50 sec\n[ Info: DMRG 10:\tobj = -2.549098968636e+01\terr = 1.4659869070e-09\ttime = 0.52 sec\n[ Info: DMRG 11:\tobj = -2.549098968636e+01\terr = 1.2937794213e-09\ttime = 0.48 sec\n[ Info: DMRG 12:\tobj = -2.549098968636e+01\terr = 1.1305465951e-09\ttime = 0.50 sec\n[ Info: DMRG 13:\tobj = -2.549098968636e+01\terr = 9.8105345140e-10\ttime = 0.48 sec\n[ Info: DMRG 14:\tobj = -2.549098968636e+01\terr = 8.4744870806e-10\ttime = 0.49 sec\n[ Info: DMRG 15:\tobj = -2.549098968636e+01\terr = 7.3002865985e-10\ttime = 0.47 sec\n[ Info: DMRG 16:\tobj = -2.549098968636e+01\terr = 6.2797272801e-10\ttime = 0.47 sec\n[ Info: DMRG 17:\tobj = -2.549098968636e+01\terr = 5.3989369084e-10\ttime = 0.49 sec\n[ Info: DMRG 18:\tobj = -2.549098968636e+01\terr = 4.6419603523e-10\ttime = 0.48 sec\n[ Info: DMRG 19:\tobj = -2.549098968636e+01\terr = 3.9928506227e-10\ttime = 0.47 sec\n[ Info: DMRG 20:\tobj = -2.549098968636e+01\terr = 3.4367538602e-10\ttime = 0.47 sec\n[ Info: DMRG 21:\tobj = -2.549098968636e+01\terr = 2.9603764456e-10\ttime = 0.48 sec\n[ Info: DMRG 22:\tobj = -2.549098968636e+01\terr = 2.5521006751e-10\ttime = 0.48 sec\n[ Info: DMRG 23:\tobj = -2.549098968636e+01\terr = 2.2019176590e-10\ttime = 0.49 sec\n[ Info: DMRG 24:\tobj = -2.549098968636e+01\terr = 1.9012763182e-10\ttime = 0.49 sec\n[ Info: DMRG 25:\tobj = -2.549098968636e+01\terr = 1.6429047853e-10\ttime = 0.49 sec\n[ Info: DMRG 26:\tobj = -2.549098968636e+01\terr = 1.4206315819e-10\ttime = 0.54 sec\n[ Info: DMRG 27:\tobj = -2.549098968636e+01\terr = 1.2292232477e-10\ttime = 0.54 sec\n[ Info: DMRG 28:\tobj = -2.549098968636e+01\terr = 1.0642379465e-10\ttime = 0.54 sec\n[ Info: DMRG conv 29:\tobj = -2.549098968636e+01\terr = 9.2190265994e-11\ttime = 16.18 sec\n","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"Excitations on top of the groundstate can be found through the use of the quasiparticle ansatz. This returns quasiparticle states, which can be converted to regular FiniteMPS objects.","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"E_ex, qps = excitations(H_mps, QuasiparticleAnsatz(), ψ, envs; num=16)\nstates_mps = vcat(ψ, map(qp -> convert(FiniteMPS, qp), qps))\nE_mps = map(x -> expectation_value(x, H_mps), states_mps)\n\nT_mps = periodic_boundary_conditions(InfiniteMPO([O]), L_mps)\nmomenta_mps = Float64[]\nappend!(momenta_mps, fix_degeneracies(states[1:1]))\nappend!(momenta_mps, fix_degeneracies(states[2:2]))\nappend!(momenta_mps, fix_degeneracies(states[3:3]))\nappend!(momenta_mps, fix_degeneracies(states[4:5]))\nappend!(momenta_mps, fix_degeneracies(states[6:9]))\nappend!(momenta_mps, fix_degeneracies(states[10:11]))\nappend!(momenta_mps, fix_degeneracies(states[12:12]))\nappend!(momenta_mps, fix_degeneracies(states[13:16]))\n\nplot(momenta_mps,\n real.(energies[1:16]);\n seriestype=:scatter,\n xlabel=\"momentum\",\n ylabel=\"energy\",\n legend=false)","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"DocTestSetup = :(using MPSKit, TensorKit, MPSKitModels)","category":"page"},{"location":"man/algorithms/#um_algorithms","page":"Algorithms","title":"Algorithms","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Here is a collection of the algorithms that have been added to MPSKit.jl. If a particular algorithm is missing, feel free to let us know via an issue, or contribute via a PR.","category":"page"},{"location":"man/algorithms/#Groundstates","page":"Algorithms","title":"Groundstates","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"One of the most prominent use-cases of MPS is to obtain the groundstate of a given (quasi-) one-dimensional quantum Hamiltonian. In MPSKit.jl, this can be achieved through find_groundstate:","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"find_groundstate","category":"page"},{"location":"man/algorithms/#MPSKit.find_groundstate-man-algorithms","page":"Algorithms","title":"MPSKit.find_groundstate","text":"find_groundstate(ψ₀, H, [environments]; kwargs...) -> (ψ, environments, ϵ)\nfind_groundstate(ψ₀, H, algorithm, environments) -> (ψ, environments, ϵ)\n\nCompute the groundstate for Hamiltonian H with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.\n\nArguments\n\nψ₀::AbstractMPS: initial guess\nH::AbstractMPO: operator for which to find the groundstate\n[environments]: MPS environment manager\nalgorithm: optimization algorithm\n\nKeywords\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: display progress information\n\nReturns\n\nψ::AbstractMPS: converged groundstate\nenvironments: environments corresponding to the converged state\nϵ::Float64: final convergence error upon terminating the algorithm\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"There is a variety of algorithms that have been developed over the years, and many of them have been implemented in MPSKit. Keep in mind that some of them are exclusive to finite or infinite systems, while others may work for both. Many of these algorithms have different advantages and disadvantages, and figuring out the optimal algorithm is not always straightforward, since this may strongly depend on the model. Here, we enumerate some of their properties in hopes of pointing you in the right direction.","category":"page"},{"location":"man/algorithms/#DMRG","page":"Algorithms","title":"DMRG","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Probably the most widely used algorithm for optimizing groundstates with MPS is DMRG and its variants. This algorithm sweeps through the system, optimizing a single site while keeping all others fixed. Since this local problem can be solved efficiently, the global optimal state follows by alternating through the system. However, because of the single-site nature of this algorithm, this can never alter the bond dimension of the state, such that there is no way of dynamically increasing the precision. This can become particularly relevant in the cases where symmetries are involved, since then finding a good distribution of charges is also required. To circumvent this, it is also possible to optimize over two sites at the same time with DMRG2, followed by a truncation back to the single site states. This can dynamically change the bond dimension but comes at an increase in cost.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"DMRG\nDMRG2","category":"page"},{"location":"man/algorithms/#MPSKit.DMRG-man-algorithms","page":"Algorithms","title":"MPSKit.DMRG","text":"struct DMRG{A, F} <: MPSKit.Algorithm\n\nSingle-site DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\nverbosity::Int64: setting for how much information is displayed\neigalg::Any: algorithm used for the eigenvalue solvers\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#MPSKit.DMRG2-man-algorithms","page":"Algorithms","title":"MPSKit.DMRG2","text":"struct DMRG2{A, F} <: MPSKit.Algorithm\n\nTwo-site DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\nverbosity::Int64: setting for how much information is displayed\neigalg::Any: algorithm used for the eigenvalue solvers\ntrscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"For infinite systems, a similar approach can be used by dynamically adding new sites to the middle of the system and optimizing over them. This gradually increases the system size until the boundary effects are no longer felt. However, because of this approach, for critical systems this algorithm can be quite slow to converge, since the number of steps needs to be larger than the correlation length of the system. Again, both a single-site and a two-site version are implemented, to have the option to dynamically increase the bonddimension at a higher cost.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"IDMRG\nIDMRG2","category":"page"},{"location":"man/algorithms/#MPSKit.IDMRG-man-algorithms","page":"Algorithms","title":"MPSKit.IDMRG","text":"struct IDMRG{A} <: MPSKit.Algorithm\n\nSingle site infinite DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_gauge::Any: algorithm used for gauging the MPS\nalg_eigsolve::Any: algorithm used for the eigenvalue solvers\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#MPSKit.IDMRG2-man-algorithms","page":"Algorithms","title":"MPSKit.IDMRG2","text":"struct IDMRG2{A} <: MPSKit.Algorithm\n\nTwo-site infinite DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_gauge::Any: algorithm used for gauging the MPS\nalg_eigsolve::Any: algorithm used for the eigenvalue solvers\ntrscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#VUMPS","page":"Algorithms","title":"VUMPS","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"VUMPS is an (I)DMRG inspired algorithm that can be used to Variationally find the groundstate as a Uniform (infinite) Matrix Product State. In particular, a local update is followed by a re-gauging procedure that effectively replaces the entire network with the newly updated tensor. Compared to IDMRG, this often achieves a higher rate of convergence, since updates are felt throughout the system immediately. Nevertheless, this algorithm only works whenever the state is injective, i.e. there is a unique ground state. Since this is a single-site algorithm, this cannot alter the bond dimension.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"VUMPS","category":"page"},{"location":"man/algorithms/#MPSKit.VUMPS-man-algorithms","page":"Algorithms","title":"MPSKit.VUMPS","text":"struct VUMPS{F} <: MPSKit.Algorithm\n\nVariational optimization algorithm for uniform matrix product states, based on the combination of DMRG with matrix product state tangent space concepts.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_gauge::Any: algorithm used for gauging the InfiniteMPS\nalg_eigsolve::Any: algorithm used for the eigenvalue solvers\nalg_environments::Any: algorithm used for the MPS environments\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\n\nReferences\n\nZauner-Stauber et al. Phys. Rev. B 97 (2018)\nVanderstraeten et al. SciPost Phys. Lect. Notes 7 (2019)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#Gradient-descent","page":"Algorithms","title":"Gradient descent","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Both finite and infinite matrix product states can be parametrized by a set of isometric tensors, which we can optimize over. Making use of the geometry of the manifold (a Grassmann manifold), we can greatly outperform naive optimization strategies. Compared to the other algorithms, quite often the convergence rate in the tail of the optimization procedure is higher, such that often the fastest method combines a different algorithm far from convergence with this algorithm close to convergence. Since this is again a single-site algorithm, there is no way to alter the bond dimension.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"GradientGrassmann","category":"page"},{"location":"man/algorithms/#MPSKit.GradientGrassmann-man-algorithms","page":"Algorithms","title":"MPSKit.GradientGrassmann","text":"struct GradientGrassmann{O<:OptimKit.OptimizationAlgorithm, F} <: MPSKit.Algorithm\n\nVariational gradient-based optimization algorithm that keeps the MPS in left-canonical form, as points on a Grassmann manifold. The optimization is then a Riemannian gradient descent with a preconditioner to induce the metric from the Hilbert space inner product.\n\nFields\n\nmethod::OptimKit.OptimizationAlgorithm: optimization algorithm\nfinalize!::Any: callback function applied after each iteration, of signature finalize!(x, f, g, numiter) -> x, f, g\n\nReferences\n\nHauru et al. SciPost Phys. 10 (2021)\n\n\n\nConstructors\n\nGradientGrassmann(; kwargs...)\n\nKeywords\n\nmethod=ConjugateGradient: instance of optimization algorithm, or type of optimization algorithm to construct\nfinalize!: finalizer algorithm\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: level of information display\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#Time-evolution","page":"Algorithms","title":"Time evolution","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Given a particular state, it can also often be useful to have the ability to examine the evolution of certain properties over time. To that end, there are two main approaches to solving the Schrödinger equation in MPSKit.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"i hbar fracddt Psi = H Psi implies Psi(t) = expleft(-iH(t - t_0)right) Psi(t_0)","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"timestep\ntime_evolve\nmake_time_mpo","category":"page"},{"location":"man/algorithms/#MPSKit.timestep-man-algorithms","page":"Algorithms","title":"MPSKit.timestep","text":"timestep(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ, envs)\ntimestep!(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ₀, envs)\n\nTime-step the state ψ₀ with Hamiltonian H over a given time step dt at time t, solving the Schroedinger equation: i ψt = H ψ.\n\nArguments\n\nψ₀::AbstractMPS: initial state\nH::AbstractMPO: operator that generates the time evolution (can be time-dependent).\nt::Number: starting time of time-step\ndt::Number: time-step magnitude\n[alg]: algorithm to use for the time evolution. Defaults to TDVP.\n[envs]: MPS environment manager\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#MPSKit.time_evolve-man-algorithms","page":"Algorithms","title":"MPSKit.time_evolve","text":"time_evolve(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ, envs)\ntime_evolve!(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ₀, envs)\n\nTime-evolve the initial state ψ₀ with Hamiltonian H over a given time span by stepping through each of the time points obtained by iterating t_span.\n\nArguments\n\nψ₀::AbstractMPS: initial state\nH::AbstractMPO: operator that generates the time evolution (can be time-dependent).\nt_span::AbstractVector{<:Number}: time points over which the time evolution is stepped\n[alg]: algorithm to use for the time evolution. Defaults to TDVP.\n[envs]: MPS environment manager\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#MPSKit.make_time_mpo-man-algorithms","page":"Algorithms","title":"MPSKit.make_time_mpo","text":"make_time_mpo(H::MPOHamiltonian, dt::Number, alg) -> O::MPO\n\nConstruct an MPO that approximates exp(-iHdt).\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#TDVP","page":"Algorithms","title":"TDVP","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"The first is focused around approximately solving the equation for a small timestep, and repeating this until the desired evolution is achieved. This can be achieved by projecting the equation onto the tangent space of the MPS, and then solving the results. This procedure is commonly referred to as the TDVP algorithm, which again has a two-site variant to allow for dynamically altering the bond dimension.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"TDVP\nTDVP2","category":"page"},{"location":"man/algorithms/#MPSKit.TDVP-man-algorithms","page":"Algorithms","title":"MPSKit.TDVP","text":"struct TDVP{A, F} <: MPSKit.Algorithm\n\nSingle site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.\n\nFields\n\nintegrator::Any: algorithm used in the exponential solvers\ntolgauge::Float64: tolerance for gauging algorithm\ngaugemaxiter::Int64: maximal amount of iterations for gauging algorithm\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\n\nReferences\n\nHaegeman et al. Phys. Rev. Lett. 107 (2011)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#MPSKit.TDVP2-man-algorithms","page":"Algorithms","title":"MPSKit.TDVP2","text":"struct TDVP2{A, F} <: MPSKit.Algorithm\n\nTwo-site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.\n\nFields\n\nintegrator::Any: algorithm used in the exponential solvers\ntolgauge::Float64: tolerance for gauging algorithm\ngaugemaxiter::Int64: maximal amount of iterations for gauging algorithm\ntrscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\n\nReferences\n\nHaegeman et al. Phys. Rev. Lett. 107 (2011)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#Time-evolution-MPO","page":"Algorithms","title":"Time evolution MPO","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"The other approach instead tries to first approximately represent the evolution operator, and only then attempts to apply this operator to the initial state. Typically the first step happens through make_time_mpo, while the second can be achieved through approximate. Here, there are several algorithms available","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"WI\nWII\nTaylorCluster","category":"page"},{"location":"man/algorithms/#MPSKit.WI-man-algorithms","page":"Algorithms","title":"MPSKit.WI","text":"const WI = TaylorCluster(; N=1, extension=false, compression=false)\n\nFirst order Taylor expansion for a time-evolution MPO.\n\n\n\n\n\n","category":"constant"},{"location":"man/algorithms/#MPSKit.WII-man-algorithms","page":"Algorithms","title":"MPSKit.WII","text":"struct WII <: MPSKit.Algorithm\n\nGeneralization of the Euler approximation of the operator exponential for MPOs.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal number of iterations\n\nReferences\n\nZaletel et al. Phys. Rev. B 91 (2015)\nPaeckel et al. Ann. of Phys. 411 (2019)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#MPSKit.TaylorCluster-man-algorithms","page":"Algorithms","title":"MPSKit.TaylorCluster","text":"struct TaylorCluster <: MPSKit.Algorithm\n\nAlgorithm for constructing the Nth order time evolution MPO using the Taylor cluster expansion.\n\nFields\n\nN::Int64: order of the Taylor expansion\nextension::Bool: include higher-order corrections\ncompression::Bool: approximate compression of corrections, accurate up to order N\n\nReferences\n\nVan Damme et al. SciPost Phys. 17 (2024)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#Excitations","page":"Algorithms","title":"Excitations","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"It might also be desirable to obtain information beyond the lowest energy state of a given system, and study the dispersion relation. While it is typically not feasible to resolve states in the middle of the energy spectrum, there are several ways to target a few of the lowest-lying energy states.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"excitations","category":"page"},{"location":"man/algorithms/#MPSKit.excitations-man-algorithms","page":"Algorithms","title":"MPSKit.excitations","text":"excitations(H, algorithm::QuasiparticleAnsatz, ψ::FiniteQP, [left_environments],\n [right_environments]; num=1) -> (energies, states)\nexcitations(H, algorithm::QuasiparticleAnsatz, ψ::InfiniteQP, [left_environments],\n [right_environments]; num=1, solver=Defaults.solver) -> (energies, states)\nexcitations(H, algorithm::FiniteExcited, ψs::NTuple{<:Any, <:FiniteMPS};\n num=1, init=copy(first(ψs))) -> (energies, states)\nexcitations(H, algorithm::ChepigaAnsatz, ψ::FiniteMPS, [envs];\n num=1, pos=length(ψ)÷2) -> (energies, states)\nexcitations(H, algorithm::ChepigaAnsatz2, ψ::FiniteMPS, [envs];\n num=1, pos=length(ψ)÷2) -> (energies, states)\n\nCompute the first excited states and their energy gap above a groundstate.\n\nArguments\n\nH::AbstractMPO: operator for which to find the excitations\nalgorithm: optimization algorithm\nψ::QP: initial quasiparticle guess\nψs::NTuple{N, <:FiniteMPS}: N first excited states\n[left_environments]: left groundstate environment\n[right_environments]: right groundstate environment\n\nKeywords\n\nnum::Int: number of excited states to compute\nsolver: algorithm for the linear solver of the quasiparticle environments\ninit: initial excited state guess\npos: position of perturbation\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"using TensorKit, MPSKit, MPSKitModels","category":"page"},{"location":"man/algorithms/#Quasiparticle-Ansatz","page":"Algorithms","title":"Quasiparticle Ansatz","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"The Quasiparticle Ansatz offers an approach to compute low-energy eigenstates in quantum systems, playing a key role in both finite and infinite systems. It leverages localized perturbations for approximations, as detailed in (Haegeman et al., 2013).","category":"page"},{"location":"man/algorithms/#Finite-Systems:","page":"Algorithms","title":"Finite Systems:","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"In finite systems, we approximate low-energy states by altering a single tensor in the Matrix Product State (MPS) for each site, and summing these across all sites. This method introduces additional gauge freedoms, utilized to ensure orthogonality to the ground state. Optimizing within this framework translates to solving an eigenvalue problem. For example, in the transverse field Ising model, we calculate the first excited state as shown in the provided code snippet, amd check the accuracy against theoretical values. Some deviations are expected, both due to finite-bond-dimension and finite-size effects.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"# Model parameters\ng = 10.0\nL = 16\nH = transverse_field_ising(FiniteChain(L); g)\n\n# Finding the ground state\nψ₀ = FiniteMPS(L, ℂ^2, ℂ^32)\nψ, = find_groundstate(ψ₀, H; verbosity=0)\n\n# Computing excitations using the Quasiparticle Ansatz\nEs, ϕs = excitations(H, QuasiparticleAnsatz(), ψ; num=1)\nisapprox(Es[1], 2(g - 1); rtol=1e-2)","category":"page"},{"location":"man/algorithms/#Infinite-Systems:","page":"Algorithms","title":"Infinite Systems:","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"The ansatz in infinite systems maintains translational invariance by perturbing every site in the unit cell in a plane-wave superposition, requiring momentum specification. The Haldane gap computation in the Heisenberg model illustrates this approach.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"# Setting up the model and momentum\nmomentum = π\nH = heisenberg_XXX()\n\n# Ground state computation\nψ₀ = InfiniteMPS(ℂ^3, ℂ^48)\nψ, = find_groundstate(ψ₀, H; verbosity=0)\n\n# Excitation calculations\nEs, ϕs = excitations(H, QuasiparticleAnsatz(), momentum, ψ)\nisapprox(Es[1], 0.41047925; atol=1e-4)","category":"page"},{"location":"man/algorithms/#Charged-excitations:","page":"Algorithms","title":"Charged excitations:","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"When dealing with symmetric systems, the default optimization is for eigenvectors with trivial total charge. However, quasiparticles with different charges can be obtained using the sector keyword. For instance, in the transverse field Ising model, we consider an excitation built up of flipping a single spin, aligning with Z2Irrep(1).","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"g = 10.0\nL = 16\nH = transverse_field_ising(Z2Irrep, FiniteChain(L); g)\nψ₀ = FiniteMPS(L, Z2Space(0 => 1, 1 => 1), Z2Space(0 => 16, 1 => 16))\nψ, = find_groundstate(ψ₀, H; verbosity=0)\nEs, ϕs = excitations(H, QuasiparticleAnsatz(), ψ; num=1, sector=Z2Irrep(1))\nisapprox(Es[1], 2(g - 1); rtol=1e-2) # infinite analytical result","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"QuasiparticleAnsatz","category":"page"},{"location":"man/algorithms/#MPSKit.QuasiparticleAnsatz-man-algorithms","page":"Algorithms","title":"MPSKit.QuasiparticleAnsatz","text":"struct QuasiparticleAnsatz{A} <: MPSKit.Algorithm\n\nOptimization algorithm for quasi-particle excitations on top of MPS groundstates.\n\nFields\n\nalg::Any: algorithm used for the eigenvalue solvers\n\nConstructors\n\nQuasiparticleAnsatz()\nQuasiparticleAnsatz(; kwargs...)\nQuasiparticleAnsatz(alg)\n\nCreate a QuasiparticleAnsatz algorithm with the given algorithm, or by passing the keyword arguments to Arnoldi.\n\nReferences\n\nHaegeman et al. Phys. Rev. Let. 111 (2013)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#Finite-excitations","page":"Algorithms","title":"Finite excitations","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"For finite systems we can also do something else - find the groundstate of the hamiltonian + textweight sum_i psi_i psi_i. This is also supported by calling","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"# Model parameters\ng = 10.0\nL = 16\nH = transverse_field_ising(FiniteChain(L); g)\n\n# Finding the ground state\nψ₀ = FiniteMPS(L, ℂ^2, ℂ^32)\nψ, = find_groundstate(ψ₀, H; verbosity=0)\n\nEs, ϕs = excitations(H, FiniteExcited(), ψ; num=1)\nisapprox(Es[1], 2(g - 1); rtol=1e-2)","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"FiniteExcited","category":"page"},{"location":"man/algorithms/#MPSKit.FiniteExcited-man-algorithms","page":"Algorithms","title":"MPSKit.FiniteExcited","text":"struct FiniteExcited{A} <: MPSKit.Algorithm\n\nVariational optimization algorithm for excitations of finite MPS by minimizing the energy of\n\nH - λᵢ ψᵢψᵢ\n\nFields\n\ngsalg::Any: optimization algorithm\nweight::Float64: energy penalty for enforcing orthogonality with previous states\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#\"Chepiga-Ansatz\"","page":"Algorithms","title":"\"Chepiga Ansatz\"","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Computing excitations in critical systems poses a significant challenge due to the diverging correlation length, which requires very large bond dimensions. However, we can leverage this long-range correlation to effectively identify excitations. In this context, the left/right gauged MPS, serving as isometries, are effectively projecting the Hamiltonian into the low-energy sector. This projection method is particularly effective in long-range systems, where excitations are distributed throughout the entire system. Consequently, the low-lying energy spectrum can be extracted by diagonalizing the effective Hamiltonian (without any additional DMRG costs!). The states of these excitations are then represented by the ground state MPS, with one site substituted by the corresponding eigenvector. This approach is often referred to as the 'Chepiga ansatz', named after one of the authors of this paper (Chepiga and Mila, 2017).","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"This is supported via the following syntax:","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"g = 10.0\nL = 16\nH = transverse_field_ising(FiniteChain(L); g)\nψ₀ = FiniteMPS(L, ComplexSpace(2), ComplexSpace(32))\nψ, envs, = find_groundstate(ψ₀, H; verbosity=0)\nE₀ = real(sum(expectation_value(ψ, H, envs)))\nEs, ϕs = excitations(H, ChepigaAnsatz(), ψ, envs; num=1)\nisapprox(Es[1] - E₀, 2(g - 1); rtol=1e-2) # infinite analytical result","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"In order to improve the accuracy, a two-site version also exists, which varies two neighbouring sites:","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Es, ϕs = excitations(H, ChepigaAnsatz2(), ψ, envs; num=1)\nisapprox(Es[1] - E₀, 2(g - 1); rtol=1e-2) # infinite analytical result","category":"page"},{"location":"man/algorithms/#changebonds","page":"Algorithms","title":"changebonds","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Many of the previously mentioned algorithms do not possess a way to dynamically change to bond dimension. This is often a problem, as the optimal bond dimension is often not a priori known, or needs to increase because of entanglement growth throughout the course of a simulation. changebonds exposes a way to change the bond dimension of a given state.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"changebonds","category":"page"},{"location":"man/algorithms/#MPSKit.changebonds-man-algorithms","page":"Algorithms","title":"MPSKit.changebonds","text":"changebonds(ψ::AbstractMPS, H, alg, envs) -> ψ′, envs′\nchangebonds(ψ::AbstractMPS, alg) -> ψ′\n\nChange the bond dimension of ψ using the algorithm alg, and return the new ψ and the new envs.\n\nSee also: SvdCut, RandExpand, VUMPSSvdCut, OptimalExpand\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"There are several different algorithms implemented, each having their own advantages and disadvantages:","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"SvdCut: The simplest method for changing the bonddimension is found by simply locally truncating the state using an SVD decomposition. This yields a (locally) optimal truncation, but clearly cannot be used to increase the bond dimension. Note that a globally optimal truncation can be obtained by using the SvdCut algorithm in combination with approximate. Since the output of this method might have a truncated bonddimension, the new state might not be identical to the input state. The truncation is controlled through trscheme, which dictates how the singular values of the original state are truncated.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"OptimalExpand: This algorithm is based on the idea of expanding the bond dimension by investigating the two-site derivative, and adding the most important blocks which are orthogonal to the current state. From the point of view of a local two-site update, this procedure is optimal, but it requires to evaluate a two-site derivative, which can be costly when the physical space is large. The state will remain unchanged, but a one-site scheme will now be able to push the optimization further. The subspace used for expansion can be truncated through trscheme, which dictates how many singular values will be added.\nRandExpand: This algorithm similarly adds blocks orthogonal to the current state, but does not attempt to select the most important ones, and rather just selects them at random. The advantage here is that this is much cheaper than the optimal expand, and if the bond dimension is grown slow enough, this still obtains a very good expansion scheme. Again, The state will remain unchanged and a one-site scheme will now be able to push the optimization further. The subspace used for expansion can be truncated through trscheme, which dictates how many singular values will be added.\nVUMPSSvdCut: This algorithm is based on the VUMPS algorithm, and consists of performing a two-site update, and then truncating the state back down. Because of the two-site update, this can again become expensive, but the algorithm has the option of both expanding as well as truncating the bond dimension. Here, trscheme controls the truncation of the full state after the two-site update.","category":"page"},{"location":"man/algorithms/#Leading-boundary","page":"Algorithms","title":"Leading boundary","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"For statistical mechanics partition functions we want to find the approximate leading boundary MPS. Again this can be done with VUMPS:","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"th = nonsym_ising_mpo()\nts = InfiniteMPS([ℂ^2],[ℂ^20]);\n(ts,envs,_) = leading_boundary(ts,th,VUMPS(maxiter=400,verbosity=false));","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"If the mpo satisfies certain properties (positive and hermitian), it may also be possible to use GradientGrassmann.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"leading_boundary","category":"page"},{"location":"man/algorithms/#MPSKit.leading_boundary-man-algorithms","page":"Algorithms","title":"MPSKit.leading_boundary","text":"leading_boundary(ψ₀, O, [environments]; kwargs...) -> (ψ, environments, ϵ)\nleading_boundary(ψ₀, O, algorithm, environments) -> (ψ, environments, ϵ)\n\nCompute the leading boundary MPS for operator O with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.\n\nArguments\n\nψ₀::AbstractMPS: initial guess\nO::AbstractMPO: operator for which to find the leading_boundary\n[environments]: MPS environment manager\nalgorithm: optimization algorithm\n\nKeywords\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: display progress information\n\nReturns\n\nψ::AbstractMPS: converged leading boundary MPS\nenvironments: environments corresponding to the converged boundary\nϵ::Float64: final convergence error upon terminating the algorithm\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#approximate","page":"Algorithms","title":"approximate","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Often, it is useful to approximate a given MPS by another, typically by one of a different bond dimension. This is achieved by approximating an application of an MPO to the initial state, by a new state.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"approximate","category":"page"},{"location":"man/algorithms/#MPSKit.approximate-man-algorithms","page":"Algorithms","title":"MPSKit.approximate","text":"approximate(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)\napproximate!(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)\n\nCompute an approximation to the application of an operator O to the state ψ in the form of an MPS ψ₀.\n\nArguments\n\nψ₀::AbstractMPS: initial guess of the approximated state\n(O::AbstractMPO, ψ::AbstractMPS): operator O and state ψ to be approximated\nalgorithm: approximation algorithm. See below for a list of available algorithms.\n[environments]: MPS environment manager\n\nKeywords\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: display progress information\n\nAlgorithms\n\nDMRG: Alternating least square method for maximizing the fidelity with a single-site scheme.\nDMRG2: Alternating least square method for maximizing the fidelity with a two-site scheme.\nIDMRG: Variant of DMRG for maximizing fidelity density in the thermodynamic limit.\nIDMRG2: Variant of DMRG2 for maximizing fidelity density in the thermodynamic limit.\nVOMPS: Tangent space method for truncating uniform MPS.\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#Varia","page":"Algorithms","title":"Varia","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"What follows is a medley of lesser known (or used) algorithms and don't entirely fit under one of the above categories.","category":"page"},{"location":"man/algorithms/#Dynamical-DMRG","page":"Algorithms","title":"Dynamical DMRG","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Dynamical DMRG has been described in other papers and is a way to find the propagator. The basic idea is that to calculate G(z) = V (H-z)^-1 V , one can variationally find (H-z) W = V and then the propagator simply equals G(z) = V W .","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"propagator\nDynamicalDMRG\nNaiveInvert\nJeckelmann","category":"page"},{"location":"man/algorithms/#MPSKit.propagator-man-algorithms","page":"Algorithms","title":"MPSKit.propagator","text":"propagator(ψ₀::AbstractFiniteMPS, z::Number, H::MPOHamiltonian, alg::DynamicalDMRG; init=copy(ψ₀))\n\nCalculate the propagator frac1E₀ + z - Hψ₀ using the dynamical DMRG algorithm.\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#MPSKit.DynamicalDMRG-man-algorithms","page":"Algorithms","title":"MPSKit.DynamicalDMRG","text":"struct DynamicalDMRG{F<:MPSKit.DDMRG_Flavour, S} <: MPSKit.Algorithm\n\nA dynamical DMRG method for calculating dynamical properties and excited states, based on a variational principle for dynamical correlation functions.\n\nFields\n\nflavour::MPSKit.DDMRG_Flavour: flavour of the algorithm to use, either of type NaiveInvert or Jeckelmann\nsolver::Any: algorithm used for the linear solvers\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\n\nReferences\n\nJeckelmann. Phys. Rev. B 66 (2002)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#MPSKit.NaiveInvert-man-algorithms","page":"Algorithms","title":"MPSKit.NaiveInvert","text":"struct NaiveInvert <: MPSKit.DDMRG_Flavour\n\nAn alternative approach to the dynamical DMRG algorithm, without quadratic terms but with a less controlled approximation. This algorithm minimizes the following cost function\n\nψ(H - E)ψ - ψψ₀ - ψ₀ψ\n\nwhich is equivalent to the original approach if\n\nψ₀ = (H - E)ψ\n\nSee also Jeckelmann for the original approach.\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#MPSKit.Jeckelmann-man-algorithms","page":"Algorithms","title":"MPSKit.Jeckelmann","text":"struct Jeckelmann <: MPSKit.DDMRG_Flavour\n\nThe original flavour of dynamical DMRG, which minimizes the following (quadratic) cost function:\n\n (H - E) ψ₀ - ψ \n\nSee also NaiveInvert for a less costly but less accurate alternative.\n\nReferences\n\nJeckelmann. Phys. Rev. B 66 (2002)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#fidelity-susceptibility","page":"Algorithms","title":"fidelity susceptibility","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"The fidelity susceptibility measures how much the groundstate changes when tuning a parameter in your hamiltonian. Divergences occur at phase transitions, making it a valuable measure when no order parameter is known.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"fidelity_susceptibility","category":"page"},{"location":"man/algorithms/#MPSKit.fidelity_susceptibility-man-algorithms","page":"Algorithms","title":"MPSKit.fidelity_susceptibility","text":"fidelity_susceptibility(state::Union{FiniteMPS,InfiniteMPS}, H₀::T,\n Vs::AbstractVector{T}, [henvs=environments(state, H₀)];\n maxiter=Defaults.maxiter,\n tol=Defaults.tol) where {T<:MPOHamiltonian}\n\nComputes the fidelity susceptibility of a the ground state state of a base Hamiltonian H₀ with respect to a set of perturbing Hamiltonians Vs. Each of the perturbing Hamiltonians can be interpreted as corresponding to a tuning parameter aᵢ in a 'total' Hamiltonian H = H₀ + ᵢ aᵢ Vᵢ.\n\nReturns a matrix containing the overlaps of the elementary excitations on top of state corresponding to each of the perturbing Hamiltonians.\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#Boundary-conditions","page":"Algorithms","title":"Boundary conditions","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"You can impose periodic or open boundary conditions on an infinite Hamiltonian, to generate a finite counterpart. In particular, for periodic boundary conditions we still return an MPO that does not form a closed loop, such that it can be used with regular matrix product states. This is straightforward to implement but, and while this effectively squares the bond dimension, it is still competitive with more advanced periodic MPS algorithms.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"open_boundary_conditions\nperiodic_boundary_conditions","category":"page"},{"location":"man/algorithms/#MPSKit.open_boundary_conditions-man-algorithms","page":"Algorithms","title":"MPSKit.open_boundary_conditions","text":"open_boundary_conditions(mpo::InfiniteMPO, L::Int) -> FiniteMPO\n\nConvert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.\n\n\n\n\n\nopen_boundary_conditions(mpo::InfiniteMPOHamiltonian, L::Int) -> FiniteMPOHamiltonian\n\nConvert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#MPSKit.periodic_boundary_conditions-man-algorithms","page":"Algorithms","title":"MPSKit.periodic_boundary_conditions","text":"periodic_boundary_conditions(mpo::AbstractInfiniteMPO, L::Int)\n\nConvert an infinite MPO into a finite MPO of length L, by mapping periodic boundary conditions onto an open system.\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#Exact-diagonalization","page":"Algorithms","title":"Exact diagonalization","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"As a side effect, our code support exact diagonalization. The idea is to construct a finite matrix product state with maximal bond dimension, and then optimize the middle site. Because we never truncated the bond dimension, this single site effectively parametrizes the entire hilbert space.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"exact_diagonalization","category":"page"},{"location":"man/algorithms/#MPSKit.exact_diagonalization-man-algorithms","page":"Algorithms","title":"MPSKit.exact_diagonalization","text":"exact_diagonalization(H::FiniteMPOHamiltonian;\n sector=first(sectors(oneunit(physicalspace(H, 1)))),\n len::Int=length(H), num::Int=1, which::Symbol=:SR,\n alg=Defaults.alg_eigsolve(; dynamic_tols=false))\n -> vals, state_vecs, convhist\n\nUse KrylovKit.eigsolve to perform exact diagonalization on a FiniteMPOHamiltonian to find its eigenvectors as FiniteMPS of maximal rank, essentially equivalent to dense eigenvectors.\n\nArguments\n\nH::FiniteMPOHamiltonian: the Hamiltonian to diagonalize.\n\nKeyword arguments\n\nsector=first(sectors(oneunit(physicalspace(H, 1)))): the total charge of the eigenvectors, which is chosen trivial by default.\nlen::Int=length(H): the length of the system.\nnum::Int=1: the number of eigenvectors to find.\nwhich::Symbol=:SR: the kind eigenvalues to find, see KrylovKit.eigsolve. \nalg=Defaults.alg_eigsolve(; dynamic_tols=false): the diagonalization algorithm to use, see KrylovKit.eigsolve.\n\nnote: Valid `sector` values\nThe total charge of the eigenvectors is imposed by adding a charged auxiliary space as the leftmost virtualspace of each eigenvector. Specifically, this is achieved by passing left=Vect[typeof(sector)](sector => 1) to the FiniteMPS constructor. As such, the only valid sector values (i.e. sector values for which the corresponding eigenstates have valid fusion channels) are those that occur in the dual of the fusion of all the physical spaces in the system.\n\n\n\n\n\n","category":"function"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"EditURL = \"../../../../../examples/quantum1d/6.hubbard/main.jl\"","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"(Image: ) (Image: ) (Image: )","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"using Markdown","category":"page"},{"location":"examples/quantum1d/6.hubbard/#hubbard","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"","category":"section"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"The Hubbard model is a model of interacting fermions on a lattice, which is often used as a somewhat realistic model for electrons in a solid. The Hamiltonian consists of two terms that describe competing forces of each electron: a kinetic term that allows electrons to hop between neighboring sites, and a potential term reflecting on-site interactions between electrons. Often, a third term is included which serves as a chemical potential to control the number of electrons in the system.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"H = -t sum_langle i j rangle sigma c^dagger_isigma c_jsigma + U sum_i n_iuparrow n_idownarrow - mu sum_isigma n_isigma","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"At half-filling, the system exhibits particle-hole symmetry, which can be made explicit by rewriting the Hamiltonian slightly. First, we fix the overall energy scale by setting t = 1, and then shift the total energy by adding a constant U / 4, as well as shifting the chemical potential to N U / 2. This results in the following Hamiltonian:","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"H = - sum_langle i j rangle sigma c^dagger_isigma c_jsigma + U 4 sum_i (1 - 2 n_iuparrow) (1 - 2 n_idownarrow) - mu sum_isigma n_isigma","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"Finally, setting \\mu = 0 and defining u = U / 4 we obtain the Hubbard model at half-filling.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"H = - sum_langle i j rangle sigma c^dagger_isigma c_jsigma + u sum_i (1 - 2 n_iuparrow) (1 - 2 n_idownarrow)","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"using TensorKit\nusing MPSKit\nusing MPSKitModels\nusing SpecialFunctions: besselj0, besselj1\nusing QuadGK: quadgk\nusing Plots\nusing Interpolations\nusing Optim\n\nconst t = 1.0\nconst mu = 0.0\nconst U = 3.0","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"3.0","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"For this case, the groundstate energy has an analytic solution, which can be used to benchmark the numerical results. It follows from Eq. (6.82) in .","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"e(u) = - u - 4 int_0^infty fracdomegaomega fracJ_0(omega) J_1(omega)1 + exp(2u omega)","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"We can easily verify this by comparing the numerical results to the analytic solution.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"function hubbard_energy(u; rtol=1e-12)\n integrandum(ω) = besselj0(ω) * besselj1(ω) / (1 + exp(2u * ω)) / ω\n int, err = quadgk(integrandum, 0, Inf; rtol=rtol)\n return -u - 4 * int\nend\n\nfunction compute_groundstate(psi, H;\n svalue=5e-3,\n expansionfactor=(1 / 3),\n expansioniter=10)\n verbosity = 1\n psi, = find_groundstate(psi, H; tol=svalue * 10, verbosity)\n for _ in 1:expansioniter\n D = maximum(x -> dim(left_virtualspace(psi, x)), 1:length(psi))\n D′ = max(2, round(Int, D * expansionfactor))\n trscheme = truncbelow(svalue / 10) & truncdim(D′)\n psi′, = changebonds(psi, H, OptimalExpand(; trscheme=trscheme))\n all(left_virtualspace.(Ref(psi), 1:length(psi)) .==\n left_virtualspace.(Ref(psi′), 1:length(psi))) && break\n psi, = find_groundstate(psi′, H, VUMPS(; tol=svalue / 5, verbosity))\n end\n\n # convergence steps\n psi, = changebonds(psi, H, SvdCut(; trscheme=truncbelow(svalue)))\n psi, = find_groundstate(psi, H,\n VUMPS(; tol=svalue, verbosity) &\n GradientGrassmann(; tol=svalue / 100, verbosity))\n\n return psi\nend\n\nH = hubbard_model(InfiniteChain(2); U, t, mu=U / 2)\npsi = InfiniteMPS(physicalspace.(Ref(H), 1:2), physicalspace.(Ref(H), 1:2))\npsi = compute_groundstate(psi, H)\nE = real(expectation_value(psi, H)) / 2\n@info \"\"\"\nGroundstate energy:\n * numerical: $E\n * analytic: $(hubbard_energy(U / 4) - U / 4)\n\"\"\"","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"[ Info: CG: converged after 31 iterations: f = -6.301391216254, ‖∇f‖ = 4.8769e-05\n┌ Info: Groundstate energy:\n│ * numerical: -3.151624340589464\n└ * analytic: -2.190038374277775\n","category":"page"},{"location":"examples/quantum1d/6.hubbard/#Symmetries","page":"Hubbard chain at half filling","title":"Symmetries","text":"","category":"section"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"The Hubbard model has a rich symmetry structure, which can be exploited to speed up simulations. Apart from the fermionic parity, the model also has a U(1) particle number symmetry, along with a SU(2) spin symmetry. Explicitly imposing these symmetries on the tensors can greatly reduce the computational cost of the simulation.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"Naively imposing these symmetries however, is not compatible with our desire to work at half-filling. By construction, imposing symmetries restricts the optimization procedure to a single symmetry sector, which is the trivial sector. In order to work at half-filling, we need to effectively inject one particle per site. In MPSKit, this is achieved by the add_physical_charge function, which shifts the physical spaces of the tensors to the desired charge sector.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"H_u1_su2 = hubbard_model(ComplexF64, U1Irrep, SU2Irrep, InfiniteChain(2); U, t, mu=U / 2);\ncharges = fill(FermionParity(1) ⊠ U1Irrep(1) ⊠ SU2Irrep(0), 2);\nH_u1_su2 = MPSKit.add_physical_charge(H_u1_su2, dual.(charges));\n\npspaces = physicalspace.(Ref(H_u1_su2), 1:2)\nvspaces = [oneunit(eltype(pspaces)), first(pspaces)]\npsi = InfiniteMPS(pspaces, vspaces)\npsi = compute_groundstate(psi, H_u1_su2)\nE = real(expectation_value(psi, H_u1_su2)) / 2\n@info \"\"\"\nGroundstate energy:\n * numerical: $E\n * analytic: $(hubbard_energy(U / 4) - U / 4)\n\"\"\"","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"[ Info: CG: converged after 11 iterations: f = -5.472570186874, ‖∇f‖ = 2.3603e-05\n┌ Info: Groundstate energy:\n│ * numerical: -2.7362850934366705\n└ * analytic: -2.190038374277775\n","category":"page"},{"location":"examples/quantum1d/6.hubbard/#Excitations","page":"Hubbard chain at half filling","title":"Excitations","text":"","category":"section"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"Because of the integrability, it is known that the Hubbard model has a rich excitation spectrum. The elementary excitations are known as spinons and holons, which are domain walls in the spin and charge sectors, respectively. The fact that the spin and charge sectors are separate is a phenomenon known as spin-charge separation.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"The domain walls can be constructed by noticing that there are two equivalent groundstates, which differ by a translation over a single site. In other words, the groundstates are psi_AB and\\psi_{BA} whereAandB`` are the two sites. These excitations can be constructed as follows:","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"alg = QuasiparticleAnsatz(; tol=1e-3)\nmomenta = range(-π, π; length=33)\npsi_AB = psi\nenvs_AB = environments(psi_AB, H_u1_su2);\npsi_BA = circshift(psi, 1)\nenvs_BA = environments(psi_BA, H_u1_su2);\n\nspinon_charge = FermionParity(0) ⊠ U1Irrep(0) ⊠ SU2Irrep(1 // 2)\nE_spinon, ϕ_spinon = excitations(H_u1_su2, alg, momenta,\n psi_AB, envs_AB, psi_BA, envs_BA;\n sector=spinon_charge, num=1);\n\nholon_charge = FermionParity(1) ⊠ U1Irrep(1) ⊠ SU2Irrep(0)\nE_holon, ϕ_holon = excitations(H_u1_su2, alg, momenta,\n psi_AB, envs_AB, psi_BA, envs_BA;\n sector=holon_charge, num=1);","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"[ Info: Found excitations for momentum = -1.5707963267948966\n[ Info: Found excitations for momentum = 0.0\n[ Info: Found excitations for momentum = 1.5707963267948966\n[ Info: Found excitations for momentum = 3.141592653589793\n[ Info: Found excitations for momentum = -1.3744467859455345\n[ Info: Found excitations for momentum = -3.141592653589793\n[ Info: Found excitations for momentum = -1.7671458676442586\n[ Info: Found excitations for momentum = 1.3744467859455345\n[ Info: Found excitations for momentum = 1.7671458676442586\n[ Info: Found excitations for momentum = -1.9634954084936207\n[ Info: Found excitations for momentum = 1.9634954084936207\n[ Info: Found excitations for momentum = 0.19634954084936207\n[ Info: Found excitations for momentum = -2.945243112740431\n[ Info: Found excitations for momentum = 2.945243112740431\n[ Info: Found excitations for momentum = -2.1598449493429825\n[ Info: Found excitations for momentum = 1.1780972450961724\n[ Info: Found excitations for momentum = -1.1780972450961724\n[ Info: Found excitations for momentum = 2.1598449493429825\n[ Info: Found excitations for momentum = -0.9817477042468103\n[ Info: Found excitations for momentum = 0.9817477042468103\n[ Info: Found excitations for momentum = 2.356194490192345\n[ Info: Found excitations for momentum = 0.7853981633974483\n[ Info: Found excitations for momentum = -2.356194490192345\n[ Info: Found excitations for momentum = -0.7853981633974483\n[ Info: Found excitations for momentum = 2.552544031041707\n[ Info: Found excitations for momentum = -0.5890486225480862\n[ Info: Found excitations for momentum = -2.552544031041707\n[ Info: Found excitations for momentum = 0.5890486225480862\n[ Info: Found excitations for momentum = 2.748893571891069\n[ Info: Found excitations for momentum = -2.748893571891069\n[ Info: Found excitations for momentum = -0.39269908169872414\n[ Info: Found excitations for momentum = 0.39269908169872414\n[ Info: Found excitations for momentum = -0.19634954084936207\n[ Info: Found excitations for momentum = 3.141592653589793\n[ Info: Found excitations for momentum = -3.141592653589793\n[ Info: Found excitations for momentum = -2.945243112740431\n[ Info: Found excitations for momentum = -0.19634954084936207\n[ Info: Found excitations for momentum = 2.748893571891069\n[ Info: Found excitations for momentum = 2.945243112740431\n[ Info: Found excitations for momentum = 0.19634954084936207\n[ Info: Found excitations for momentum = 2.552544031041707\n[ Info: Found excitations for momentum = 0.0\n[ Info: Found excitations for momentum = -2.748893571891069\n[ Info: Found excitations for momentum = -0.39269908169872414\n[ Info: Found excitations for momentum = -2.552544031041707\n[ Info: Found excitations for momentum = 2.356194490192345\n[ Info: Found excitations for momentum = 0.5890486225480862\n[ Info: Found excitations for momentum = -0.5890486225480862\n[ Info: Found excitations for momentum = -2.356194490192345\n[ Info: Found excitations for momentum = 0.39269908169872414\n[ Info: Found excitations for momentum = 1.9634954084936207\n[ Info: Found excitations for momentum = -0.7853981633974483\n[ Info: Found excitations for momentum = 0.7853981633974483\n[ Info: Found excitations for momentum = -2.1598449493429825\n[ Info: Found excitations for momentum = 2.1598449493429825\n[ Info: Found excitations for momentum = 1.7671458676442586\n[ Info: Found excitations for momentum = 1.5707963267948966\n[ Info: Found excitations for momentum = -0.9817477042468103\n[ Info: Found excitations for momentum = -1.9634954084936207\n[ Info: Found excitations for momentum = -1.1780972450961724\n[ Info: Found excitations for momentum = -1.5707963267948966\n[ Info: Found excitations for momentum = -1.7671458676442586\n[ Info: Found excitations for momentum = 1.3744467859455345\n[ Info: Found excitations for momentum = 0.9817477042468103\n[ Info: Found excitations for momentum = -1.3744467859455345\n[ Info: Found excitations for momentum = 1.1780972450961724\n","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"Again, we can compare the numerical results to the analytic solution. Here, the formulae for the excitation energies are expressed in terms of dressed momenta:","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"function spinon_momentum(Λ, u; rtol=1e-12)\n integrandum(ω) = besselj0(ω) * sin(ω * Λ) / ω / cosh(ω * u)\n return π / 2 - quadgk(integrandum, 0, Inf; rtol=rtol)[1]\nend\nfunction spinon_energy(Λ, u; rtol=1e-12)\n integrandum(ω) = besselj1(ω) * cos(ω * Λ) / ω / cosh(ω * u)\n return 2 * quadgk(integrandum, 0, Inf; rtol=rtol)[1]\nend\n\nfunction holon_momentum(k, u; rtol=1e-12)\n integrandum(ω) = besselj0(ω) * sin(ω * sin(k)) / ω / (1 + exp(2u * abs(ω)))\n return π / 2 - k - 2 * quadgk(integrandum, 0, Inf; rtol=rtol)[1]\nend\nfunction holon_energy(k, u; rtol=1e-12)\n integrandum(ω) = besselj1(ω) * cos(ω * sin(k)) * exp(-ω * u) / ω / cosh(ω * u)\n return 2 * cos(k) + 2u + 2 * quadgk(integrandum, 0, Inf; rtol=rtol)[1]\nend\n\nΛs = range(-10, 10; length=51)\nP_spinon_analytic = rem2pi.(spinon_momentum.(Λs, U / 4), RoundNearest)\nE_spinon_analytic = spinon_energy.(Λs, U / 4)\nI_spinon = sortperm(P_spinon_analytic)\nP_spinon_analytic = P_spinon_analytic[I_spinon]\nE_spinon_analytic = E_spinon_analytic[I_spinon]\nP_spinon_analytic = [reverse(-P_spinon_analytic); P_spinon_analytic]\nE_spinon_analytic = [reverse(E_spinon_analytic); E_spinon_analytic];\n\nks = range(0, 2π; length=51)\nP_holon_analytic = rem2pi.(holon_momentum.(ks, U / 4), RoundNearest)\nE_holon_analytic = holon_energy.(ks, U / 4)\nI_holon = sortperm(P_holon_analytic)\nP_holon_analytic = P_holon_analytic[I_holon]\nE_holon_analytic = E_holon_analytic[I_holon];\n\np = let p_excitations = plot(; xaxis=\"momentum\", yaxis=\"energy\")\n scatter!(p_excitations, momenta, real(E_spinon); label=\"spinon\")\n plot!(p_excitations, P_spinon_analytic, E_spinon_analytic; label=\"spinon (analytic)\")\n\n scatter!(p_excitations, momenta, real(E_holon); label=\"holon\")\n plot!(p_excitations, P_holon_analytic, E_holon_analytic; label=\"holon (analytic)\")\n\n p_excitations\nend","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"The plot shows some discrepancies between the numerical and analytic results. First and foremost, we must realize that in the thermodynamic limit, the momentum of a domain wall is actually not well-defined. Concretely, only the difference in momentum between the two groundstates is well-defined, as we can always shift the momentum by multiplying one of the groundstates by a phase. Here, we can fix this shift by realizing that our choice of shifting the groundstates by a single site, differs from the formula by a factor pi2.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"momenta_shifted = rem2pi.(momenta .- π / 2, RoundNearest)\np = let p_excitations = plot(; xaxis=\"momentum\", yaxis=\"energy\", xlims=(-π, π))\n scatter!(p_excitations, momenta_shifted, real(E_spinon); label=\"spinon\")\n plot!(p_excitations, P_spinon_analytic, E_spinon_analytic; label=\"spinon (analytic)\")\n\n scatter!(p_excitations, momenta_shifted, real(E_holon); label=\"holon\")\n plot!(p_excitations, P_holon_analytic, E_holon_analytic; label=\"holon (analytic)\")\n\n p_excitations\nend","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"The second discrepancy is that while the spinon dispersion is well-reproduced, the holon dispersion is not. This is due to the fact that the excitation ansatz captures the lowest-energy excitation, and not the elementary single-particle excitation. To make this explicit, we can consider the scattering states comprising of a holon and two spinons. If these are truly scattering states, the energy of the scattering state should be the sum of the energies of the individual excitations, and the momentum is the sum of the momenta. Thus, we can find the lowest-energy scattering states by minimizing the energy over the combination of momenta for the constituent elementary excitations.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"holon_dispersion_itp = linear_interpolation(P_holon_analytic, E_holon_analytic;\n extrapolation_bc=Line())\nspinon_dispersion_itp = linear_interpolation(P_spinon_analytic, E_spinon_analytic;\n extrapolation_bc=Line())\nfunction scattering_energy(p1, p2, p3)\n p1, p2, p3 = rem2pi.((p1, p2, p3), RoundNearest)\n return holon_dispersion_itp(p1) + spinon_dispersion_itp(p2) + spinon_dispersion_itp(p3)\nend;\n\nE_scattering_min = map(momenta_shifted) do p\n e = Inf\n for i in 1:10 # repeat for stability\n res = optimize((rand(2) .* (2π) .- π)) do (p₁, p₂)\n p₃ = p - p₁ - p₂\n return scattering_energy(p₁, p₂, p₃)\n end\n\n e = min(Optim.minimum(res), e)\n end\n return e\nend\nE_scattering_max = map(momenta_shifted) do p\n e = -Inf\n for i in 1:10 # repeat for stability\n res = optimize((rand(Float64, 2) .* (2π) .- π)) do (p₁, p₂)\n p₃ = p - p₁ - p₂\n return -scattering_energy(p₁, p₂, p₃)\n end\n\n e = max(-Optim.minimum(res), e)\n end\n return e\nend;\n\np = let p_excitations = plot(; xaxis=\"momentum\", yaxis=\"energy\", xlims=(-π, π),\n ylims=(-0.1, 5))\n scatter!(p_excitations, momenta_shifted, real(E_spinon); label=\"spinon\")\n plot!(p_excitations, P_spinon_analytic, E_spinon_analytic; label=\"spinon (analytic)\")\n\n scatter!(p_excitations, momenta_shifted, real(E_holon); label=\"holon\")\n plot!(p_excitations, P_holon_analytic, E_holon_analytic; label=\"holon (analytic)\")\n\n I = sortperm(momenta_shifted)\n plot!(p_excitations, momenta_shifted[I], E_scattering_min[I]; label=\"scattering states\",\n fillrange=E_scattering_max[I], fillalpha=0.3, fillstyle=:x)\n\n p_excitations\nend","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/operators/#um_operators","page":"Operators","title":"Operators","text":"","category":"section"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"In analogy to how we can define matrix product states as a contraction of local tensors, a similar construction exist for operators. To that end, a Matrix Product Operator (MPO) is nothing more than a collection of local MPOTensor objects, contracted along a line. Again, we can distinguish between finite and infinite operators, with the latter being represented by a periodic array of MPO tensors.","category":"page"},{"location":"man/operators/#FiniteMPO","page":"Operators","title":"FiniteMPO","text":"","category":"section"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"Starting off with the simplest case, a basic FiniteMPO is a vector of MPOTensor objects. These objects can be created either directly from a vector of MPOTensors, or starting from a dense operator (a subtype of AbstractTensorMap), which is then decomposed into a product of local tensors.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"(Image: )","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"using TensorKit, MPSKit, MPSKitModels","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"S_x = TensorMap(ComplexF64[0 1; 1 0], ℂ^2 ← ℂ^2)\nS_z = TensorMap(ComplexF64[1 0; 0 -1], ℂ^2 ← ℂ^2)\nO_xzx = FiniteMPO(S_x ⊗ S_x ⊗ S_x);","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"The individual tensors are accessible via regular indexing. Note that the tensors are internally converted to the MPOTensor objects, thus having four indices. In this specific case, the left- and right virtual spaces are trivial, but this is not a requirement.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"O_xzx[1]","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"warning: Warning\nThe local tensors are defined only up to a gauge transformation of the virtual spaces. This means that the tensors are not uniquely defined, and special care must be taken when comparing MPOs on an element-wise basis.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"For convenience, a number of utility functions are defined for probing the structure of the constructed MPO. For example, the spaces can be queried as follows:","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"left_virtualspace(O_xzx, 2)\nright_virtualspace(O_xzx, 2)\nphysicalspace(O_xzx, 2)","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"MPOs also support a range of linear algebra operations, such as addition, subtraction and multiplication, either among themselves or with a finite MPS. Here, it is important to note that these operations will increase the virtual dimension of the resulting MPO or MPS, and this naive application is thus typically not optimal. For approximate operations that do not increase the virtual dimension, the more advanced algorithms in the um_algorithms sections should be used.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"O_xzx² = O_xzx * O_xzx\nprintln(\"Virtual dimension of O_xzx²: \", left_virtualspace(O_xzx², 2))\nO_xzx_sum = 0.1 * O_xzx + O_xzx²\nprintln(\"Virtual dimension of O_xzx_sum: \", left_virtualspace(O_xzx_sum, 2))","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"O_xzx_sum * FiniteMPS(3, ℂ^2, ℂ^4)","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"note: Note\nThe virtual spaces of the resulting MPOs typically grow exponentially with the number of multiplications. Nevertheless, a number of optimizations are in place that make sure that the virtual spaces do not increase past the maximal virtual space that is dictated by the requirement of being full-rank tensors.","category":"page"},{"location":"man/operators/#InfiniteMPO","page":"Operators","title":"InfiniteMPO","text":"","category":"section"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"This construction can again be extended to the infinite case, where the tensors are repeated periodically. Therefore, an InfiniteMPO is simply a PeriodicVector of MPOTensor objects. These can only be constructed from vectors of MPOTensors, since it is impossible to create the infinite operators directly.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"mpo = InfiniteMPO(O_xzx[1:2])","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"Otherwise, their behavior is mostly similar to that of their finite counterparts.","category":"page"},{"location":"man/operators/#FiniteMPOHamiltonian","page":"Operators","title":"FiniteMPOHamiltonian","text":"","category":"section"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"We can also represent quantum Hamiltonians in the same form. This is done by converting a sum of local operators into a single MPO operator. The resulting operator has a very specific structure, and is often referred to as a Jordan block MPO.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"This object can be constructed as an MPO by using the FiniteMPOHamiltonian constructor, which takes two crucial pieces of information:","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"An array of VectorSpace objects, which determines the local Hilbert spaces of the system. The resulting MPO will snake through the array in linear indexing order.\nA set of local operators, which are characterised by a number of indices that specify on which sites the operator acts, along with an operator to define the action. These are specified as a inds => operator pairs, or any other iterable collection thereof. The inds should be tuples of valid indices for the array of VectorSpace objects, or a single integer for single-site operators.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"As a concrete example, we consider the Transverse-field Ising model defined by the Hamiltonian","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"H = -J sum_langle i j rangle X_i X_j - h sum_j Z_j","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"J = 1.0\nh = 0.5\nchain = fill(ℂ^2, 3) # a finite chain of 4 sites, each with a 2-dimensional Hilbert space\nsingle_site_operators = [1 => -h * S_z, 2 => -h * S_z, 3 => -h * S_z]\ntwo_site_operators = [(1, 2) => -J * S_x ⊗ S_x, (2, 3) => -J * S_x ⊗ S_x]\nH_ising = FiniteMPOHamiltonian(chain, single_site_operators..., two_site_operators...)","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"Various alternative constructions are possible, such as using a Dict with key-value pairs that specify the operators, or using generator expressions to simplify the construction.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"H_ising′ = -J * FiniteMPOHamiltonian(chain,\n (i, i + 1) => S_x ⊗ S_x for i in 1:(length(chain) - 1)) -\n h * FiniteMPOHamiltonian(chain, i => S_z for i in 1:length(chain))\nisapprox(H_ising, H_ising′; atol=1e-6)","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"Note that this construction is not limited to nearest-neighbour interactions, or 1D systems. In particular, it is possible to construct quasi-1D realisations of 2D systems, by using different arrays of VectorSpace objects. For example, the 2D Ising model on a square lattice can be constructed as follows:","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"square = fill(ℂ^2, 3, 3) # a 3x3 square lattice\noperators = Dict()\n\nlocal_operators = Dict()\nfor I in eachindex(square)\n local_operators[(I,)] = -h * S_z # single site operators still require tuples of indices\nend\n\n# horizontal and vertical interactions are easier using Cartesian indices\nhorizontal_operators = Dict()\nI_horizontal = CartesianIndex(0, 1)\nfor I in eachindex(IndexCartesian(), square)\n if I[2] < size(square, 2)\n horizontal_operators[(I, I + I_horizontal)] = -J * S_x ⊗ S_x\n end\nend\n\nvertical_operators = Dict()\nI_vertical = CartesianIndex(1, 0)\nfor I in eachindex(IndexCartesian(), square)\n if I[1] < size(square, 1)\n vertical_operators[(I, I + I_vertical)] = -J * S_x ⊗ S_x\n end\nend\n\nH_ising_2d = FiniteMPOHamiltonian(square, local_operators) +\n FiniteMPOHamiltonian(square, horizontal_operators) +\n FiniteMPOHamiltonian(square, vertical_operators);","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"There are various utility functions available for constructing more advanced lattices, for which the lattices section should be consulted.","category":"page"},{"location":"man/operators/#InfiniteMPOHamiltonian","page":"Operators","title":"InfiniteMPOHamiltonian","text":"","category":"section"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"Again, this construction can be extended straightforwardly to the infinite case. To that end, we simply need to specify all interactions per unit cell. In particular, an InfiniteMPOHamiltonian for the Ising model is obtained via","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"J = 1.0\nh = 0.5\ninfinite_chain = PeriodicVector([ℂ^2]) # an infinite chain of a local 2-dimensional Hilbert space\nH_ising_infinite = InfiniteMPOHamiltonian(infinite_chain, 1 => -h * S_z, (1, 2) => -J * S_x ⊗ S_x)","category":"page"},{"location":"man/operators/#Expert-mode","page":"Operators","title":"Expert mode","text":"","category":"section"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"The MPOHamiltonian constructor is in fact an automated way of constructing the aforementioned Jordan block MPO. In its most general form, the matrix W takes on the form of the following block matrix:","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"beginpmatrix\n1 C D \n0 A B \n0 0 1\nendpmatrix","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"which generates all single-site local operators D, all two-site operators CB, three-site operators CAB, and so on. Additionally, this machinery can also be used to construct interaction that are of (exponentially decaying) infinite range, and to approximate power-law interactions.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"In order to illustrate this, consider the following explicit example of the Transverse-field Ising model:","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"W = beginpmatrix\n1 X -hZ \n0 0 -JX \n0 0 1\nendpmatrix","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"If we add in the left and right boundary vectors","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"v_L = beginpmatrix\n1 0 0\nendpmatrix\n qquad \nv_R = beginpmatrix\n0 0 1\nendpmatrix","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"One can easily check that the Hamiltonian on N sites is given by the contraction","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"H = V_L W^otimes N V_R","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"We can even verify this symbolically:","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"using Symbolics\nL = 4\n# generate W matrices\n@variables A[1:L] B[1:L] C[1:L] D[1:L]\nWs = map(1:L) do l\n return [1 C[l] D[l]\n 0 A[l] B[l]\n 0 0 1]\nend\n\n# generate boundary vectors\nVₗ = [1, 0, 0]'\nVᵣ = [0, 0, 1]\n\n# expand the MPO\nexpand(Vₗ * prod(Ws) * Vᵣ)","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"The FiniteMPOHamiltonian constructor can also be used to construct the operator from this most general form, by supplying a vector of BlockTensorMap objects to the constructor. Here, the vector specifies the sites in the unit cell, while the blocktensors contain the rows and columns of the matrix. We can verify this explicitly:","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"H_ising[2] # print the blocktensor","category":"page"},{"location":"man/operators/#Working-with-MPOHamiltonian-objects","page":"Operators","title":"Working with MPOHamiltonian objects","text":"","category":"section"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"warning: Warning\nThis part is still a work in progress","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"Because of the discussion above, the FiniteMPOHamiltonian object is in fact just an AbstractMPO, with some additional structure. This means that similar operations and properties are available, such as the virtual spaces, or the individual tensors. However, the block structure of the operator means that now the virtual spaces are not just a single space, but a collection (direct sum) of spaces, one for each row/column.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"left_virtualspace(H_ising, 1), right_virtualspace(H_ising, 1), physicalspace(H_ising, 1)","category":"page"},{"location":"#MPSKit.jl","page":"Home","title":"MPSKit.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Efficient and versatile tools for working with matrix product states","category":"page"},{"location":"#Table-of-contents","page":"Home","title":"Table of contents","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Pages = [\"man/intro.md\",\"man/conventions.md\",\"man/states.md\",\"man/operators.md\",\"man/algorithms.md\",\"man/parallelism.md\", \"man/lattices.md\"]\nDepth = 1","category":"page"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"MPSKit.jl is a part of the general registry, and can be installed via the package manager as:","category":"page"},{"location":"","page":"Home","title":"Home","text":"pkg> add MPSKit","category":"page"},{"location":"#Key-Features","page":"Home","title":"Key Features","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Construction and manipulation of Matrix Product States (MPS)\nCalculation of observables and expectation values\nVarious optimization methods for obtaining MPS fixed points\nSupport for both finite and infinite MPS\nSupport for wide variety of symmetries, including Abelian, non-Abelian, fermionic and anyonic symmetries","category":"page"},{"location":"#Usage","page":"Home","title":"Usage","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"To get started with MPSKit, we recommend also including TensorKit.jl and MPSKitModels.jl. The former defines the tensor backend which is used throughout MPSKit, while the latter includes some common operators and models.","category":"page"},{"location":"","page":"Home","title":"Home","text":"using TensorOperations\nusing TensorKit\nusing MPSKit\nusing LinearAlgebra: norm","category":"page"},{"location":"#Finite-Matrix-Product-States","page":"Home","title":"Finite Matrix Product States","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"using LinearAlgebra\nusing TensorOperations\nusing TensorKit\nusing MPSKit","category":"page"},{"location":"","page":"Home","title":"Home","text":"Finite MPS are characterised by a set of tensors, one for each site, which each have 3 legs. They can be constructed by specifying the virtual spaces and the physical spaces, i.e. the dimensions of each of the legs. These are then contracted to form the MPS. In MPSKit, they are represented by FiniteMPS, which can be constructed either by passing in the tensors directly, or by specifying the dimensions of the legs.","category":"page"},{"location":"","page":"Home","title":"Home","text":"d = 2 # physical dimension\nD = 5 # virtual dimension\nL = 10 # number of sites\n\nmps = FiniteMPS(L, ComplexSpace(d), ComplexSpace(D)) # random MPS with maximal bond dimension D","category":"page"},{"location":"","page":"Home","title":"Home","text":"The FiniteMPS object then handles the gauging of the MPS, which is necessary for many of the algorithms. This is done automatically when needed, and the user can access the gauged tensors by getting and setting the AL, AR, CR/CL and AC fields, which each represent a vector of these tensors.","category":"page"},{"location":"","page":"Home","title":"Home","text":"al = mps.AL[3] # left gauged tensor of the third site\n@tensor E[a; b] := al[c, d, b] * conj(al[c, d, a])\n@show isapprox(E, id(right_virtualspace(mps, 3)))","category":"page"},{"location":"","page":"Home","title":"Home","text":"ar = mps.AR[3] # right gauged tensor of the third site\n@tensor E[a; b] := ar[a, d, c] * conj(ar[b, d, c])\n@show isapprox(E, id(left_virtualspace(mps, 3)))","category":"page"},{"location":"","page":"Home","title":"Home","text":"As the mps will be kept in a gauged form, updating a tensor will also update the gauged tensors. For example, we can set the tensor of the third site to the identity, and the gauged tensors will be updated accordingly.","category":"page"},{"location":"","page":"Home","title":"Home","text":"mps.C[3] = id(domain(mps.C[3]))\nmps","category":"page"},{"location":"","page":"Home","title":"Home","text":"These objects can then be used to compute observables and expectation values. For example, the expectation value of the identity operator at the third site, which is equal to the norm of the MPS, can be computed as:","category":"page"},{"location":"","page":"Home","title":"Home","text":"N1 = LinearAlgebra.norm(mps)\nN2 = expectation_value(mps, 3 => id(physicalspace(mps, 3)))\nprintln(\"‖mps‖ = $N1\")\nprintln(\" = $N2\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"Finally, the MPS can be optimized in order to determine groundstates of given Hamiltonians. Using the pre-defined models in MPSKitModels, we can construct the groundstate for the transverse field Ising model:","category":"page"},{"location":"","page":"Home","title":"Home","text":"J = 1.0\ng = 0.5\nlattice = fill(ComplexSpace(2), 10)\nX = TensorMap(ComplexF64[0 1; 1 0], ComplexSpace(2), ComplexSpace(2))\nZ = TensorMap(ComplexF64[1 0; 0 -1], space(X))\nH = FiniteMPOHamiltonian(lattice, (i, i+1) => -J * X ⊗ X for i in 1:length(lattice)-1) +\n FiniteMPOHamiltonian(lattice, (i,) => - g * Z for i in 1:length(lattice))\nfind_groundstate!(mps, H, DMRG(; maxiter=10))\nE0 = expectation_value(mps, H)\nprintln(\" = $real(E0)\")","category":"page"},{"location":"#Infinite-Matrix-Product-States","page":"Home","title":"Infinite Matrix Product States","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"using LinearAlgebra\nusing TensorOperations\nusing TensorKit\nusing MPSKit","category":"page"},{"location":"","page":"Home","title":"Home","text":"Similarly, an infinite MPS can be constructed by specifying the tensors for the unit cell, characterised by the spaces (dimensions) thereof.","category":"page"},{"location":"","page":"Home","title":"Home","text":"d = 2 # physical dimension\nD = 5 # virtual dimension\nmps = InfiniteMPS(d, D) # random MPS","category":"page"},{"location":"","page":"Home","title":"Home","text":"The InfiniteMPS object then handles the gauging of the MPS, which is necessary for many of the algorithms. This is done automatically upon creation of the object, and the user can access the gauged tensors by getting and setting the AL, AR, C and AC fields, which each represent a (periodic) vector of these tensors.","category":"page"},{"location":"","page":"Home","title":"Home","text":"al = mps.AL[1] # left gauged tensor of the first site\n@tensor E[a; b] := al[c, d, b] * conj(al[c, d, a])\n@show isapprox(E, id(left_virtualspace(mps, 1)))","category":"page"},{"location":"","page":"Home","title":"Home","text":"ar = mps.AR[1] # right gauged tensor of the first site\n@tensor E[a; b] := ar[a, d, c] * conj(ar[b, d, c])\n@show isapprox(E, id(right_virtualspace(mps, 2)))","category":"page"},{"location":"","page":"Home","title":"Home","text":"As regauging the MPS is not possible without recomputing all the tensors, setting a single tensor is not supported. Instead, the user should construct a new mps object with the desired tensor, which will then be gauged upon construction.","category":"page"},{"location":"","page":"Home","title":"Home","text":"als = 3 .* mps.AL\nmps = InfiniteMPS(als)","category":"page"},{"location":"","page":"Home","title":"Home","text":"These objects can then be used to compute observables and expectation values. For example, the norm of the MPS, which is equal to the expectation value of the identity operator can be computed by:","category":"page"},{"location":"","page":"Home","title":"Home","text":"N1 = norm(mps)\nN2 = expectation_value(mps, 1 => id(physicalspace(mps, 1)))\nprintln(\"‖mps‖ = $N1\")\nprintln(\" = $N2\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"note: Normalization of infinite MPS\nBecause infinite MPS cannot sensibly be normalized to anything but 1, the norm of an infinite MPS is always set to be 1 at construction. If this were not the case, any observable computed from the MPS would either blow up to infinity or vanish to zero.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Finally, the MPS can be optimized in order to determine groundstates of given Hamiltonians. There are plenty of pre-defined models in MPSKitModels, but we can also manually construct the groundstate for the transverse field Ising model:","category":"page"},{"location":"","page":"Home","title":"Home","text":"J = 1.0\ng = 0.5\nlattice = PeriodicVector([ComplexSpace(2)])\nX = TensorMap(ComplexF64[0 1; 1 0], ComplexSpace(2), ComplexSpace(2))\nZ = TensorMap(ComplexF64[1 0; 0 -1], space(X))\nH = InfiniteMPOHamiltonian(lattice, (1, 2) => -J * X ⊗ X, (1,) => - g * Z)\nmps, = find_groundstate(mps, H, VUMPS(; maxiter=10))\nE0 = expectation_value(mps, H)\nprintln(\" = $(sum(real(E0)) / length(mps))\")","category":"page"},{"location":"#Additional-Resources","page":"Home","title":"Additional Resources","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"For more detailed information on the functionality and capabilities of MPSKit, refer to the Manual section, or have a look at the Examples page.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Keep in mind that the documentation is still a work in progress, and that some features may not be fully documented yet. If you encounter any issues or have questions, please check the library's issue tracker on the GitHub repository and open a new issue.","category":"page"}] +[{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"EditURL = \"../../../../../examples/quantum1d/2.haldane/main.jl\"","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"(Image: ) (Image: ) (Image: )","category":"page"},{"location":"examples/quantum1d/2.haldane/#demo_haldane","page":"The Haldane gap","title":"The Haldane gap","text":"","category":"section"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"In this tutorial we will calculate the Haldane gap (the energy gap in the S = 1 Heisenberg model) in two different ways. To follow the tutorial you need the following packages:","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"using MPSKit, MPSKitModels, TensorKit, Plots, Polynomials","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"The Heisenberg model is defined by the following hamiltonian:","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"H = -J_ij (X_i X_j + Y_i Y_j + Z_i Z_j)","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"This hamiltonian has an SU(2) symmetry, which we can enforce by using SU(2)-symmetric tensors:","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"symmetry = SU2Irrep\nspin = 1\nJ = 1","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"1","category":"page"},{"location":"examples/quantum1d/2.haldane/#Finite-size-extrapolation","page":"The Haldane gap","title":"Finite size extrapolation","text":"","category":"section"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"We can start the analysis using finite-size methods. The groundstate of this model can be approximated using finite MPS through the use of DMRG.","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"The typical way to find excited states is to minimize the energy while adding an error term λ leftgsright left gsright Here we will instead use the quasiparticle ansatz.","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"In Steven White's original DMRG paper it was remarked that the S = 1 excitations correspond to edge states, and that one should define the Haldane gap as the difference in energy between the S = 2 and S = 1 states. This can be done as follows.","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"L = 11\nchain = FiniteChain(L)\nH = heisenberg_XXX(symmetry, chain; J, spin)\n\nphysical_space = SU2Space(1 => 1)\nvirtual_space = SU2Space(0 => 12, 1 => 12, 2 => 5, 3 => 3)\nψ₀ = FiniteMPS(L, physical_space, virtual_space)\nψ, envs, delta = find_groundstate(ψ₀, H, DMRG(; verbosity=0))\nE₀ = real(expectation_value(ψ, H))\nEn_1, st_1 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector=SU2Irrep(1))\nEn_2, st_2 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector=SU2Irrep(2))\nΔE_finite = real(En_2[1] - En_1[1])","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"0.7989253589480536","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"We can go even further and doublecheck the claim that S = 1 is an edge excitation, by plotting the energy density.","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"p_density = plot(; xaxis=\"position\", yaxis=\"energy density\")\nexcited_1 = convert(FiniteMPS, st_1[1])\nexcited_2 = convert(FiniteMPS, st_2[1])\nSS = -S_exchange(ComplexF64, SU2Irrep; spin=1)\ne₀ = [real(expectation_value(ψ, (i, i + 1) => SS)) for i in 1:(L - 1)]\ne₁ = [real(expectation_value(excited_1, (i, i + 1) => SS)) for i in 1:(L - 1)]\ne₂ = [real(expectation_value(excited_2, (i, i + 1) => SS)) for i in 1:(L - 1)]\nplot!(p_density, e₀; label=\"S = 0\")\nplot!(p_density, e₁; label=\"S = 1\")\nplot!(p_density, e₂; label=\"S = 2\")","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"Finally, we can obtain a value for the Haldane gap by extrapolating our results for different system sizes.","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"Ls = 12:4:30\nΔEs = map(Ls) do L\n @info \"computing L = $L\"\n ψ₀ = FiniteMPS(L, physical_space, virtual_space)\n H = heisenberg_XXX(symmetry, FiniteChain(L); J, spin)\n ψ, envs, delta = find_groundstate(ψ₀, H, DMRG(; verbosity=0))\n En_1, st_1 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector=SU2Irrep(1))\n En_2, st_2 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector=SU2Irrep(2))\n return real(En_2[1] - En_1[1])\nend\n\nf = fit(Ls .^ (-2), ΔEs, 1)\nΔE_extrapolated = f.coeffs[1]","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"0.45173401585831346","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"p_size_extrapolation = plot(; xaxis=\"L^(-2)\", yaxis=\"ΔE\", xlims=(0, 0.015))\nplot!(p_size_extrapolation, Ls .^ (-2), ΔEs; seriestype=:scatter, label=\"numerical\")\nplot!(p_size_extrapolation, x -> f(x); label=\"fit\")","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/2.haldane/#Thermodynamic-limit","page":"The Haldane gap","title":"Thermodynamic limit","text":"","category":"section"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"A much nicer way of obtaining the Haldane gap is by working directly in the thermodynamic limit. As was already hinted at by the edge modes, this model is in a non-trivial SPT phase. Thus, care must be taken when selecting the symmetry sectors. The groundstate has half-integer edge modes, thus the virtual spaces must also all carry half-integer charges.","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"In contrast with the finite size case, we now should specify a momentum label to the excitations. This way, it is possible to scan the dispersion relation over the entire momentum space.","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"chain = InfiniteChain(1)\nH = heisenberg_XXX(symmetry, chain; J, spin)\nvirtual_space_inf = Rep[SU₂](1 // 2 => 16, 3 // 2 => 16, 5 // 2 => 8, 7 // 2 => 4)\nψ₀_inf = InfiniteMPS([physical_space], [virtual_space_inf])\nψ_inf, envs_inf, delta_inf = find_groundstate(ψ₀_inf, H; verbosity=0)\n\nkspace = range(0, π, 16)\nEs, _ = excitations(H, QuasiparticleAnsatz(), kspace, ψ_inf, envs_inf; sector=SU2Irrep(1))\n\nΔE, idx = findmin(real.(Es))\nprintln(\"minimum @k = $(kspace[idx]):\\t ΔE = $(ΔE)\")","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"┌ Warning: resorting to η\n└ @ OptimKit ~/.julia/packages/OptimKit/xpmbV/src/cg.jl:139\n[ Info: Found excitations for momentum = 1.6755160819145563\n[ Info: Found excitations for momentum = 1.8849555921538759\n[ Info: Found excitations for momentum = 2.0943951023931953\n[ Info: Found excitations for momentum = 1.4660765716752369\n[ Info: Found excitations for momentum = 0.0\n[ Info: Found excitations for momentum = 0.20943951023931953\n[ Info: Found excitations for momentum = 1.2566370614359172\n[ Info: Found excitations for momentum = 0.41887902047863906\n[ Info: Found excitations for momentum = 2.9321531433504737\n[ Info: Found excitations for momentum = 2.303834612632515\n[ Info: Found excitations for momentum = 2.722713633111154\n[ Info: Found excitations for momentum = 2.5132741228718345\n[ Info: Found excitations for momentum = 3.141592653589793\n[ Info: Found excitations for momentum = 0.6283185307179586\n[ Info: Found excitations for momentum = 1.0471975511965976\n[ Info: Found excitations for momentum = 0.8377580409572781\nminimum @k = 3.141592653589793:\t ΔE = 0.4104792484203954\n","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"plot(kspace, real.(Es); xaxis=\"momentum\", yaxis=\"ΔE\", label=\"S = 1\")","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"","category":"page"},{"location":"examples/quantum1d/2.haldane/","page":"The Haldane gap","title":"The Haldane gap","text":"This page was generated using Literate.jl.","category":"page"},{"location":"references/#References","page":"References","title":"References","text":"","category":"section"},{"location":"references/#Publications-using-MPSKit","page":"References","title":"Publications using MPSKit","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Below you can find a list of publications that have made use of MPSKit. If you have used this package and wish to have your publication added to this list, please open a pull request or an issue on the GitHub repository.","category":"page"},{"location":"references/#2025","page":"References","title":"2025","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Capponi, S.; Devos, L.; Lecheminant, P.; Totsuka, K. and Vanderstraeten, L. (2025). Non-Landau Quantum Phase Transition in Modulated SU(N) Heisenberg Spin Chains. Physical Review B 111, L020404.\n\n\n\nMortier, Q.; Devos, L.; Burgelman, L.; Vanhecke, B.; Bultinck, N.; Verstraete, F.; Haegeman, J. and Vanderstraeten, L. (2025). Fermionic Tensor Network Methods. SciPost Physics 18, 012.\n\n\n\n","category":"page"},{"location":"references/#2024","page":"References","title":"2024","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Belyansky, R.; Whitsitt, S.; Mueller, N.; Fahimniya, A.; Bennewitz, E. R.; Davoudi, Z. and Gorshkov, A. V. (2024). High-Energy Collision of Quarks and Mesons in the Schwinger Model: From Tensor Networks to Circuit QED. Physical Review Letters 132, 091903.\n\n\n\nCrotti, S.; Barthel, T. and Braunstein, A. (2024). Nonequilibrium Steady-State Dynamics of Markov Processes on Graphs, arXiv.2411.19100, arXiv:2411.19100 [cond-mat].\n\n\n\nRogerson, D. and Roy, A. (2024). Quantum Circuit Optimization Using Differentiable Programming of Tensor Network States, arXiv:2408.12583, arXiv:2408.12583 [quant-ph].\n\n\n\nUeda, A.; Inamura, K. and Ohmori, K. (2024). Chiral Edge States Emerging on Anyon-Net, arXiv:2408.02724, arXiv:2408.02724 [cond-mat].\n\n\n\nWeerda, E. L. and Rizzi, M. (2024). Fractional Quantum Hall States with Variational Projected Entangled-Pair States: A Study of the Bosonic Harper-Hofstadter Model. Physical Review B 109, L241117.\n\n\n\n","category":"page"},{"location":"references/#2023","page":"References","title":"2023","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Zhang, Y.; Hulsch, A.; Zhang, H.-C.; Tang, W.; Wang, L. and Tu, H.-H. (2023). Universal Scaling of Klein Bottle Entropy near Conformal Critical Points. Physical Review Letters 130, 151602.\n\n\n\n","category":"page"},{"location":"references/#2022","page":"References","title":"2022","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Devos, L.; Vanderstraeten, L. and Verstraete, F. (2022). Haldane Gap in the SU(3) [3 0 0] Heisenberg Chain. Physical Review B 106, 155103.\n\n\n\nHalimeh, J. C.; Damme, M. V.; Zache, T. V.; Banerjee, D. and Hauke, P. (2022). Achieving the Quantum Field Theory Limit in Far-from-Equilibrium Quantum Link Models. Quantum 6, 878.\n\n\n\nRoose, G.; Haegeman, J.; Van Acoleyen, K.; Vanderstraeten, L. and Bultinck, N. (2022). The Chiral Gross-Neveu Model on the Lattice via a Landau-forbidden Phase Transition. Journal of High Energy Physics 2022, 19.\n\n\n\nVan Damme, M.; Zache, T. V.; Banerjee, D.; Hauke, P. and Halimeh, J. C. (2022). Dynamical Quantum Phase Transitions in Spin-S U(1) Quantum Link Models. Physical Review B 106, 245110.\n\n\n\nVanhove, R.; Lootens, L.; Van Damme, M.; Wolf, R.; Osborne, T. J.; Haegeman, J. and Verstraete, F. (2022). Critical Lattice Model for a Haagerup Conformal Field Theory. Physical Review Letters 128, 231602.\n\n\n\n","category":"page"},{"location":"references/#2021","page":"References","title":"2021","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Halimeh, J. C.; Trapin, D.; Van Damme, M. and Heyl, M. (2021). Local Measures of Dynamical Quantum Phase Transitions. Physical Review B 104, 075130.\n\n\n\nHauru, M.; Van Damme, M. and Haegeman, J. (2021). Riemannian Optimization of Isometric Tensor Networks. SciPost Physics 10, 040.\n\n\n\nRoose, G.; Bultinck, N.; Vanderstraeten, L.; Verstraete, F.; Van Acoleyen, K. and Haegeman, J. (2021). Lattice Regularisation and Entanglement Structure of the Gross-Neveu Model. Journal of High Energy Physics 2021, 207.\n\n\n\nVan Damme, M.; Vanhove, R.; Haegeman, J.; Verstraete, F. and Vanderstraeten, L. (2021). Efficient Matrix Product State Methods for Extracting Spectral Information on Rings and Cylinders. Physical Review B 104, 115142.\n\n\n\nYu, C. and Lee, J.-W. (2021). Closing of the Haldane Gap in a Spin-1 XXZ Chain. Journal of the Korean Physical Society 79, 841–845.\n\n\n\n","category":"page"},{"location":"references/#2019","page":"References","title":"2019","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Roose, G.; Vanderstraeten, L.; Haegeman, J. and Bultinck, N. (2019). Anomalous Domain Wall Condensation in a Modified Ising Chain. Physical Review B 99, 195132.\n\n\n\n","category":"page"},{"location":"references/#Full-list-of-references","page":"References","title":"Full list of references","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Chepiga, N. and Mila, F. (2017). Excitation Spectrum and Density Matrix Renormalization Group Iterations. Physical Review B 96, 054425.\n\n\n\nHaegeman, J.; Cirac, J. I.; Osborne, T. J.; Pižorn, I.; Verschelde, H. and Verstraete, F. (2011). Time-Dependent Variational Principle for Quantum Lattices. Physical Review Letters 107, 070601.\n\n\n\nHaegeman, J.; Michalakis, S.; Nachtergaele, B.; Osborne, T. J.; Schuch, N. and Verstraete, F. (2013). Elementary Excitations in Gapped Quantum Spin Systems. Physical Review Letters 111, 080401.\n\n\n\nJeckelmann, E. (2002). Dynamical Density-Matrix Renormalization-Group Method. Physical Review B 66, 045114.\n\n\n\nPaeckel, S.; Köhler, T.; Swoboda, A.; Manmana, S. R.; Schollwöck, U. and Hubig, C. (2019). Time-Evolution Methods for Matrix-Product States. Annals of Physics 411, 167998.\n\n\n\nPollmann, F.; Mukerjee, S.; Turner, A. M. and Moore, J. E. (2009). Theory of Finite-Entanglement Scaling at One-Dimensional Quantum Critical Points. Physical Review Letters 102, 255701.\n\n\n\nVan Damme, M.; Haegeman, J.; McCulloch, I. and Vanderstraeten, L. (2024). Efficient Higher-Order Matrix Product Operators for Time Evolution. SciPost Physics 17, 135.\n\n\n\nVanderstraeten, L.; Haegeman, J. and Verstraete, F. (2019). Tangent-Space Methods for Uniform Matrix Product States. SciPost Physics Lecture Notes, 7.\n\n\n\nVanhecke, B.; Van Damme, M.; Haegeman, J.; Vanderstraeten, L. and Verstraete, F. (2021). Tangent-Space Methods for Truncating Uniform MPS. SciPost Physics Core 4, 004.\n\n\n\nZaletel, M. P.; Mong, R. S.; Karrasch, C.; Moore, J. E. and Pollmann, F. (2015). Time-Evolving a Matrix Product State with Long-Ranged Interactions. Physical Review B 91, 165112.\n\n\n\nZauner-Stauber, V.; Vanderstraeten, L.; Fishman, M. T.; Verstraete, F. and Haegeman, J. (2018). Variational Optimization Algorithms for Uniform Matrix Product States. Physical Review B 97, 045145.\n\n\n\n","category":"page"},{"location":"lib/lib/#Library-documentation","page":"Library","title":"Library documentation","text":"","category":"section"},{"location":"lib/lib/","page":"Library","title":"Library","text":"Modules = [MPSKit]","category":"page"},{"location":"lib/lib/#MPSKit.WI","page":"Library","title":"MPSKit.WI","text":"const WI = TaylorCluster(; N=1, extension=false, compression=false)\n\nFirst order Taylor expansion for a time-evolution MPO.\n\n\n\n\n\n","category":"constant"},{"location":"lib/lib/#MPSKit.AbstractMPO","page":"Library","title":"MPSKit.AbstractMPO","text":"abstract type AbstractMPO{O} <: AbstractVector{O} end\n\nAbstract supertype for Matrix Product Operators (MPOs).\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.AbstractMPSEnvironments","page":"Library","title":"MPSKit.AbstractMPSEnvironments","text":"abstract type AbstractEnvironments end\n\nAbstract supertype for all environment types.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.Algorithm","page":"Library","title":"MPSKit.Algorithm","text":"abstract type Algorithm\n\nAbstract supertype for all algorithm structs. These can be thought of as NamedTuples that hold the settings for a given algorithm, which can be used for dispatch. Additionally, the constructors can be used to provide default values and input sanitation.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.ChepigaAnsatz","page":"Library","title":"MPSKit.ChepigaAnsatz","text":"struct ChepigaAnsatz{A<:KrylovKit.KrylovAlgorithm} <: MPSKit.Algorithm\n\nSingle-site optimization algorithm for excitations on top of MPS groundstates.\n\nFields\n\nalg::KrylovKit.KrylovAlgorithm: algorithm used for the eigenvalue solvers\n\nConstructors\n\nChepigaAnsatz()\nChepigaAnsatz(; kwargs...)\nChepigaAnsatz(alg)\n\nCreate a ChepigaAnsatz algorithm with the given eigensolver, or by passing the keyword arguments to [Arnoldi][@extref KrylovKit.Arnoldi].\n\nReferences\n\nChepiga et al. Phys. Rev. B 96 (2017) \n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.ChepigaAnsatz2","page":"Library","title":"MPSKit.ChepigaAnsatz2","text":"ChepigaAnsatz2 <: Algorithm\n\nTwo-site optimization algorithm for excitations on top of MPS groundstates.\n\nFields\n\nalg::A = Defaults.eigsolver: algorithm to use for the eigenvalue problem.\ntrscheme = Defaults.trscheme: algorithm to use for truncation.\n\nConstructors\n\nChepigaAnsatz2()\nChepigaAnsatz2(; kwargs...)\nChepigaAnsatz2(alg, trscheme)\n\nCreate a ChepigaAnsatz2 algorithm with the given eigensolver and truncation, or by passing the keyword arguments to Arnoldi.\n\nReferences\n\nChepiga et al. Phys. Rev. B 96 (2017) \n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.DDMRG_Flavour","page":"Library","title":"MPSKit.DDMRG_Flavour","text":"abstract type DDMRG_Flavour\n\nAbstract supertype for the different flavours of dynamical DMRG.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.DMRG","page":"Library","title":"MPSKit.DMRG","text":"struct DMRG{A, F} <: MPSKit.Algorithm\n\nSingle-site DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\nverbosity::Int64: setting for how much information is displayed\neigalg::Any: algorithm used for the eigenvalue solvers\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.DMRG2","page":"Library","title":"MPSKit.DMRG2","text":"struct DMRG2{A, F} <: MPSKit.Algorithm\n\nTwo-site DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\nverbosity::Int64: setting for how much information is displayed\neigalg::Any: algorithm used for the eigenvalue solvers\ntrscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.DynamicalDMRG","page":"Library","title":"MPSKit.DynamicalDMRG","text":"struct DynamicalDMRG{F<:MPSKit.DDMRG_Flavour, S} <: MPSKit.Algorithm\n\nA dynamical DMRG method for calculating dynamical properties and excited states, based on a variational principle for dynamical correlation functions.\n\nFields\n\nflavour::MPSKit.DDMRG_Flavour: flavour of the algorithm to use, either of type NaiveInvert or Jeckelmann\nsolver::Any: algorithm used for the linear solvers\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\n\nReferences\n\nJeckelmann. Phys. Rev. B 66 (2002)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.FiniteEnvironments","page":"Library","title":"MPSKit.FiniteEnvironments","text":"struct FiniteEnvironments <: AbstractMPSEnvironments\n\nEnvironment manager for FiniteMPS and WindowMPS. This structure is responsable for automatically checking if the queried environment is still correctly cached and if not recalculates.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.FiniteExcited","page":"Library","title":"MPSKit.FiniteExcited","text":"struct FiniteExcited{A} <: MPSKit.Algorithm\n\nVariational optimization algorithm for excitations of finite MPS by minimizing the energy of\n\nH - λᵢ ψᵢψᵢ\n\nFields\n\ngsalg::Any: optimization algorithm\nweight::Float64: energy penalty for enforcing orthogonality with previous states\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.FiniteMPO","page":"Library","title":"MPSKit.FiniteMPO","text":"FiniteMPO(Os::Vector{O}) -> FiniteMPO{O}\nFiniteMPO(O::AbstractTensorMap{S,N,N}) where {S,N} -> FiniteMPO{O<:MPOTensor}\n\nMatrix Product Operator (MPO) acting on a finite tensor product space with a linear order.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.FiniteMPS","page":"Library","title":"MPSKit.FiniteMPS","text":"FiniteMPS{A<:GenericMPSTensor,B<:MPSBondTensor} <: AbstractFiniteMPS\n\nType that represents a finite Matrix Product State.\n\nProperties\n\nAL – left-gauged MPS tensors\nAR – right-gauged MPS tensors\nAC – center-gauged MPS tensors\nC – gauge tensors\ncenter – location of the gauge center\n\nThe center property returns center::HalfInt that indicates the location of the MPS center:\n\nisinteger(center) → center is a whole number and indicates the location of the first AC tensor present in the underlying ψ.ACs field.\nishalfodd(center) → center is a half-odd-integer, meaning that there are no AC tensors, and indicating between which sites the bond tensor lives.\n\ne.g mps.center = 7/2 means that the bond tensor is to the right of the 3rd site and can be accessed via mps.C[3].\n\nNotes\n\nBy convention, we have that:\n\nAL[i] * C[i] = AC[i] = C[i-1] * AR[i]\nAL[i]' * AL[i] = 1\nAR[i] * AR[i]' = 1\n\n\n\nConstructors\n\nFiniteMPS([f, eltype], physicalspaces::Vector{<:Union{S,CompositeSpace{S}}},\n maxvirtualspaces::Union{S,Vector{S}};\n normalize=true, left=oneunit(S), right=oneunit(S)) where {S<:ElementarySpace}\nFiniteMPS([f, eltype], N::Int, physicalspace::Union{S,CompositeSpace{S}},\n maxvirtualspaces::Union{S,Vector{S}};\n normalize=true, left=oneunit(S), right=oneunit(S)) where {S<:ElementarySpace}\nFiniteMPS(As::Vector{<:GenericMPSTensor}; normalize=false, overwrite=false)\n\nConstruct an MPS via a specification of physical and virtual spaces, or from a list of tensors As. All cases reduce to the latter. In particular, a state with a non-trivial total charge can be constructed by passing a non-trivially charged vector space as the left or right virtual spaces.\n\nArguments\n\nAs::Vector{<:GenericMPSTensor}: vector of site tensors\nf::Function=rand: initializer function for tensor data\neltype::Type{<:Number}=ComplexF64: scalar type of tensors\nphysicalspaces::Vector{<:Union{S, CompositeSpace{S}}: list of physical spaces\nN::Int: number of sites\nphysicalspace::Union{S,CompositeSpace{S}}: local physical space\nvirtualspaces::Vector{<:Union{S, CompositeSpace{S}}: list of virtual spaces\nmaxvirtualspace::S: maximum virtual space\n\nKeywords\n\nnormalize=true: normalize the constructed state\noverwrite=false: overwrite the given input tensors\nleft=oneunit(S): left-most virtual space\nright=oneunit(S): right-most virtual space\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.GradientGrassmann","page":"Library","title":"MPSKit.GradientGrassmann","text":"struct GradientGrassmann{O<:OptimKit.OptimizationAlgorithm, F} <: MPSKit.Algorithm\n\nVariational gradient-based optimization algorithm that keeps the MPS in left-canonical form, as points on a Grassmann manifold. The optimization is then a Riemannian gradient descent with a preconditioner to induce the metric from the Hilbert space inner product.\n\nFields\n\nmethod::OptimKit.OptimizationAlgorithm: optimization algorithm\nfinalize!::Any: callback function applied after each iteration, of signature finalize!(x, f, g, numiter) -> x, f, g\n\nReferences\n\nHauru et al. SciPost Phys. 10 (2021)\n\n\n\nConstructors\n\nGradientGrassmann(; kwargs...)\n\nKeywords\n\nmethod=ConjugateGradient: instance of optimization algorithm, or type of optimization algorithm to construct\nfinalize!: finalizer algorithm\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: level of information display\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.IDMRG","page":"Library","title":"MPSKit.IDMRG","text":"struct IDMRG{A} <: MPSKit.Algorithm\n\nSingle site infinite DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_gauge::Any: algorithm used for gauging the MPS\nalg_eigsolve::Any: algorithm used for the eigenvalue solvers\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.IDMRG2","page":"Library","title":"MPSKit.IDMRG2","text":"struct IDMRG2{A} <: MPSKit.Algorithm\n\nTwo-site infinite DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_gauge::Any: algorithm used for gauging the MPS\nalg_eigsolve::Any: algorithm used for the eigenvalue solvers\ntrscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.InfiniteEnvironments","page":"Library","title":"MPSKit.InfiniteEnvironments","text":"InfiniteEnvironments <: AbstractMPSEnvironments\n\nEnvironments for an infinite MPS-MPO-MPS combination. These solve the corresponding fixedpoint equations:\n\nGLsi * T_LLi = λ GLsi + 1\nT_RRi * GRsi = λ GRsi - 1\n\nwhere T_LL and T_RR are the (regularized) transfer matrix operators on a give site for AL-O-AL and AR-O-AR respectively.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.InfiniteMPO","page":"Library","title":"MPSKit.InfiniteMPO","text":"InfiniteMPO(Os::PeriodicVector{O}) -> InfiniteMPO{O}\n\nMatrix Product Operator (MPO) acting on an infinite tensor product space with a linear order.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.InfiniteMPS","page":"Library","title":"MPSKit.InfiniteMPS","text":"InfiniteMPS{A<:GenericMPSTensor,B<:MPSBondTensor} <: AbtractMPS\n\nType that represents an infinite Matrix Product State.\n\nFields\n\nAL – left-gauged MPS tensors\nAR – right-gauged MPS tensors\nAC – center-gauged MPS tensors\nC – gauge tensors\n\nNotes\n\nBy convention, we have that:\n\nAL[i] * C[i] = AC[i] = C[i-1] * AR[i]\nAL[i]' * AL[i] = 1\nAR[i] * AR[i]' = 1\n\n\n\nConstructors\n\nInfiniteMPS([f, eltype], physicalspaces::Vector{<:Union{S, CompositeSpace{S}},\n virtualspaces::Vector{<:Union{S, CompositeSpace{S}};\n kwargs...) where {S<:ElementarySpace}\nInfiniteMPS(As::AbstractVector{<:GenericMPSTensor}; kwargs...)\nInfiniteMPS(ALs::AbstractVector{<:GenericMPSTensor}, C₀::MPSBondTensor;\n kwargs...)\n\nConstruct an MPS via a specification of physical and virtual spaces, or from a list of tensors As, or a list of left-gauged tensors ALs.\n\nArguments\n\nAs::AbstractVector{<:GenericMPSTensor}: vector of site tensors\nALs::AbstractVector{<:GenericMPSTensor}: vector of left-gauged site tensors\nC₀::MPSBondTensor: initial gauge tensor\nf::Function=rand: initializer function for tensor data\neltype::Type{<:Number}=ComplexF64: scalar type of tensors\nphysicalspaces::AbstractVector{<:Union{S, CompositeSpace{S}}: list of physical spaces\nvirtualspaces::AbstractVector{<:Union{S, CompositeSpace{S}}: list of virtual spaces\n\nKeywords\n\ntol: gauge fixing tolerance\nmaxiter: gauge fixing maximum iterations\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.InfiniteQPEnvironments","page":"Library","title":"MPSKit.InfiniteQPEnvironments","text":"InfiniteQPEnvironments <: AbstractMPSEnvironments\n\nEnvironments for an infinite QP-MPO-QP combination. These solve the corresponding fixedpoint equations:\n\nGLsi * T_BLi + GBLsi * T_RLi = GBLsi + 1\nT_BRi * GRsi + T_LRi * GBRsi = GBRsi - 1\n\nwhere T_BL, T_BR, T_RL and T_LR are the (regularized) transfer matrix operators on a given site for B-O-AL, B-O-AR, AR-O-AL and AL-O-AR respectively.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.Jeckelmann","page":"Library","title":"MPSKit.Jeckelmann","text":"struct Jeckelmann <: MPSKit.DDMRG_Flavour\n\nThe original flavour of dynamical DMRG, which minimizes the following (quadratic) cost function:\n\n (H - E) ψ₀ - ψ \n\nSee also NaiveInvert for a less costly but less accurate alternative.\n\nReferences\n\nJeckelmann. Phys. Rev. B 66 (2002)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.LazySum","page":"Library","title":"MPSKit.LazySum","text":"LazySum{O} <: AbstractVector{O}\n\nType that represents a lazy sum i.e explicit summation is only done when needed. This type is basically an AbstractVector with some extra functionality to calculate things efficiently.\n\nFields\n\nops – Vector of summable objects\n\n\n\nConstructors\n\nLazySum(x::Vector)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.LeftCanonical","page":"Library","title":"MPSKit.LeftCanonical","text":"struct LeftCanonical <: MPSKit.Algorithm\n\nAlgorithm for bringing an InfiniteMPS into the left-canonical form.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_orth::Any: algorithm used for orthogonalization of the tensors\nalg_eigsolve::Any: algorithm used for the eigensolver\neig_miniter::Int64: minimal amount of iterations before using the eigensolver steps\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MPO","page":"Library","title":"MPSKit.MPO","text":"struct MPO{O,V<:AbstractVector{O}} <: AbstractMPO{O}\n\nMatrix Product Operator (MPO) acting on a tensor product space with a linear order.\n\nSee also: FiniteMPO, InfiniteMPO\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MPOHamiltonian","page":"Library","title":"MPSKit.MPOHamiltonian","text":"MPOHamiltonian(lattice::AbstractArray{<:VectorSpace}, local_operators...)\nMPOHamiltonian(lattice::AbstractArray{<:VectorSpace})\nMPOHamiltonian(x::AbstractArray{<:Any,3})\n\nMPO representation of a hamiltonian. This is a specific form of an AbstractMPO, where all the sites are represented by an upper triangular block matrix of the following form:\n\nbeginpmatrix\n1 C D \n0 A B \n0 0 1\nendpmatrix\n\nwhere A, B, C, and D are MPOTensors, or (sparse) blocks thereof.\n\nExamples\n\nFor example, constructing a nearest-neighbour Hamiltonian would look like this:\n\nlattice = fill(ℂ^2, 10)\nH = MPOHamiltonian(lattice, (i, i+1) => O for i in 1:length(lattice)-1)\n\nSee also instantiate_operator, which is responsable for instantiating the local operators in a form that is compatible with this constructor.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MPOTensor","page":"Library","title":"MPSKit.MPOTensor","text":"MPOTensor{S}\n\nTensor type for representing local MPO tensors, with the index convention W ⊗ S ← N ⊗ E, where N, E, S and W denote the north, east, south and west virtual spaces respectively.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MPO_∂∂C","page":"Library","title":"MPSKit.MPO_∂∂C","text":"Draft operators\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MPSTensor","page":"Library","title":"MPSKit.MPSTensor","text":"MPSTensor([f, eltype], d::Int, Dₗ::Int, [Dᵣ]::Int])\n\nConstruct an MPSTensor with given physical and virtual dimensions.\n\nArguments\n\nf::Function=rand: initializer function for tensor data\neltype::Type{<:Number}=ComplexF64: scalar type of tensors\nd::Int: physical dimension\nDₗ::Int: left virtual dimension\nDᵣ::Int: right virtual dimension\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MPSTensor-Union{Tuple{AbstractArray{T}}, Tuple{T}} where T<:Number","page":"Library","title":"MPSKit.MPSTensor","text":"MPSTensor(A::AbstractArray)\n\nConvert an array to an MPSTensor.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.MPSTensor-Union{Tuple{S}, Tuple{UndefInitializer, Any, Union{TensorKit.CompositeSpace{S}, S}, S}, Tuple{UndefInitializer, Any, Union{TensorKit.CompositeSpace{S}, S}, S, S}} where S<:TensorKit.ElementarySpace","page":"Library","title":"MPSKit.MPSTensor","text":"MPSTensor([f, eltype], d::Int, left_D::Int, [right_D]::Int])\nMPSTensor([f, eltype], physicalspace::Union{S,CompositeSpace{S}}, \n left_virtualspace::S, [right_virtualspace]::S) where {S<:ElementarySpace}\n\nConstruct an MPSTensor with given physical and virtual spaces.\n\nArguments\n\nf::Function=rand: initializer function for tensor data\neltype::Type{<:Number}=ComplexF64: scalar type of tensors\nphysicalspace::Union{S,CompositeSpace{S}}: physical space\nleft_virtualspace::S: left virtual space\nright_virtualspace::S: right virtual space, defaults to equal left\nd::Int: physical dimension\nleft_D::Int: left virtual dimension\nright_D::Int: right virtual dimension\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.MixedCanonical","page":"Library","title":"MPSKit.MixedCanonical","text":"struct MixedCanonical <: MPSKit.Algorithm\n\nAlgorithm for bringing an InfiniteMPS into the mixed-canonical form.\n\nFields\n\nalg_leftcanonical::MPSKit.LeftCanonical: algorithm for bringing an InfiniteMPS into left-canonical form.\nalg_rightcanonical::MPSKit.RightCanonical: algorithm for bringing an InfiniteMPS into right-canonical form.\norder::Symbol: order in which to apply the canonicalizations, should be :L, :R, :LR or :RL\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.Multiline","page":"Library","title":"MPSKit.Multiline","text":"struct Multiline{T}\n\nObject that represents multiple lines of objects of type T. Typically used to represent multiple lines of InfiniteMPS (MultilineMPS) or MPO (Multiline{<:AbstractMPO}).\n\nFields\n\ndata::PeriodicArray{T,1}: the data of the multiline object\n\nSee also: MultilineMPS and MultilineMPO\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MultilineMPO","page":"Library","title":"MPSKit.MultilineMPO","text":"const MultilineMPO = Multiline{<:AbstractMPO}\n\nType that represents multiple lines of MPO objects.\n\nConstructors\n\nMultilineMPO(mpos::AbstractVector{<:Union{SparseMPO,DenseMPO}})\nMultilineMPO(Os::AbstractMatrix{<:MPOTensor})\n\nSee also: Multiline, AbstractMPO\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MultilineMPS","page":"Library","title":"MPSKit.MultilineMPS","text":"const MultilineMPS = Multiline{<:InfiniteMPS}\n\nType that represents multiple lines of InfiniteMPS objects.\n\nConstructors\n\nMultilineMPS(mpss::AbstractVector{<:InfiniteMPS})\nMultilineMPS([f, eltype], physicalspaces::Matrix{<:Union{S, CompositeSpace{S}},\n virtualspaces::Matrix{<:Union{S, CompositeSpace{S}}) where\n {S<:ElementarySpace}\nMultilineMPS(As::AbstractMatrix{<:GenericMPSTensor}; kwargs...)\nMultilineMPS(ALs::AbstractMatrix{<:GenericMPSTensor}, \n C₀::AbstractVector{<:MPSBondTensor}; kwargs...)\n\nSee also: Multiline\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.MultipliedOperator","page":"Library","title":"MPSKit.MultipliedOperator","text":"Structure representing a multiplied operator. Consists of\n - An operator op (MPO, Hamiltonian, ...)\n - An object f that gets multiplied with the operator (Number, function, ...)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.NaiveInvert","page":"Library","title":"MPSKit.NaiveInvert","text":"struct NaiveInvert <: MPSKit.DDMRG_Flavour\n\nAn alternative approach to the dynamical DMRG algorithm, without quadratic terms but with a less controlled approximation. This algorithm minimizes the following cost function\n\nψ(H - E)ψ - ψψ₀ - ψ₀ψ\n\nwhich is equivalent to the original approach if\n\nψ₀ = (H - E)ψ\n\nSee also Jeckelmann for the original approach.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.OptimalExpand","page":"Library","title":"MPSKit.OptimalExpand","text":"struct OptimalExpand <: MPSKit.Algorithm\n\nAn algorithm that expands the given mps as described in Zauner-Stauber et al. Phys. Rev. B 97 (2018), by selecting the dominant contributions of a two-site updated MPS tensor, orthogonal to the original ψ.\n\nFields\n\ntrscheme::TensorKit.TruncationScheme: algorithm used for truncating the expanded space\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.PeriodicArray","page":"Library","title":"MPSKit.PeriodicArray","text":"PeriodicArray{T,N} <: AbstractArray{T,N}\n\nArray wrapper with periodic boundary conditions.\n\nFields\n\ndata::Array{T,N}: the data of the array\n\nExamples\n\nA = PeriodicArray([1, 2, 3])\nA[0], A[2], A[4]\n\n# output\n\n(3, 2, 1)\n\nA = PeriodicArray([1 2; 3 4])\nA[-1, 1], A[1, 1], A[4, 5]\n\n# output\n\n(1, 1, 3)\n\nSee also PeriodicVector, PeriodicMatrix\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.PeriodicMatrix","page":"Library","title":"MPSKit.PeriodicMatrix","text":"PeriodicMatrix{T}\n\nTwo-dimensional dense array with elements of type T and periodic boundary conditions. Alias for PeriodicArray{T,2}.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.PeriodicVector","page":"Library","title":"MPSKit.PeriodicVector","text":"PeriodicVector{T}\n\nOne-dimensional dense array with elements of type T and periodic boundary conditions. Alias for PeriodicArray{T,1}.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.QuasiparticleAnsatz","page":"Library","title":"MPSKit.QuasiparticleAnsatz","text":"struct QuasiparticleAnsatz{A} <: MPSKit.Algorithm\n\nOptimization algorithm for quasi-particle excitations on top of MPS groundstates.\n\nFields\n\nalg::Any: algorithm used for the eigenvalue solvers\n\nConstructors\n\nQuasiparticleAnsatz()\nQuasiparticleAnsatz(; kwargs...)\nQuasiparticleAnsatz(alg)\n\nCreate a QuasiparticleAnsatz algorithm with the given algorithm, or by passing the keyword arguments to Arnoldi.\n\nReferences\n\nHaegeman et al. Phys. Rev. Let. 111 (2013)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.RandExpand","page":"Library","title":"MPSKit.RandExpand","text":"struct RandExpand <: MPSKit.Algorithm\n\nAn algorithm that expands the bond dimension by adding random unitary vectors that are orthogonal to the existing state. This is achieved by performing a truncated SVD on a random two-site MPS tensor, which is made orthogonal to the existing state.\n\nFields\n\ntrscheme::TensorKit.TruncationScheme: algorithm used for [truncation](@extref TensorKit.tsvd] the expanded space\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.RightCanonical","page":"Library","title":"MPSKit.RightCanonical","text":"struct RightCanonical <: MPSKit.Algorithm\n\nAlgorithm for bringing an InfiniteMPS into the right-canonical form.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_orth::Any: algorithm used for orthogonalization of the tensors\nalg_eigsolve::Any: algorithm used for the eigensolver\neig_miniter::Int64: minimal amount of iterations before using the eigensolver steps\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.SvdCut","page":"Library","title":"MPSKit.SvdCut","text":"struct SvdCut <: MPSKit.Algorithm\n\nAn algorithm that uses truncated SVD to change the bond dimension of a ψ.\n\nFields\n\ntrscheme::TensorKit.TruncationScheme: algorithm used for [truncation][@extref TensorKit.tsvd] of the gauge tensors\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.TDVP","page":"Library","title":"MPSKit.TDVP","text":"struct TDVP{A, F} <: MPSKit.Algorithm\n\nSingle site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.\n\nFields\n\nintegrator::Any: algorithm used in the exponential solvers\ntolgauge::Float64: tolerance for gauging algorithm\ngaugemaxiter::Int64: maximal amount of iterations for gauging algorithm\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\n\nReferences\n\nHaegeman et al. Phys. Rev. Lett. 107 (2011)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.TDVP2","page":"Library","title":"MPSKit.TDVP2","text":"struct TDVP2{A, F} <: MPSKit.Algorithm\n\nTwo-site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.\n\nFields\n\nintegrator::Any: algorithm used in the exponential solvers\ntolgauge::Float64: tolerance for gauging algorithm\ngaugemaxiter::Int64: maximal amount of iterations for gauging algorithm\ntrscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\n\nReferences\n\nHaegeman et al. Phys. Rev. Lett. 107 (2011)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.TaylorCluster","page":"Library","title":"MPSKit.TaylorCluster","text":"struct TaylorCluster <: MPSKit.Algorithm\n\nAlgorithm for constructing the Nth order time evolution MPO using the Taylor cluster expansion.\n\nFields\n\nN::Int64: order of the Taylor expansion\nextension::Bool: include higher-order corrections\ncompression::Bool: approximate compression of corrections, accurate up to order N\n\nReferences\n\nVan Damme et al. SciPost Phys. 17 (2024)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.TimedOperator","page":"Library","title":"MPSKit.TimedOperator","text":"Structure representing a time-dependent operator. Consists of\n - An operator op (MPO, Hamiltonian, ...)\n - An function f that gives the time-dependence according to op(t) = f(t)*op\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.UnionAlg","page":"Library","title":"MPSKit.UnionAlg","text":"struct UnionAlg{A, B} <: MPSKit.Algorithm\n\nAlgorithm wrapper representing the sequential application of two algorithms.\n\nFields\n\nalg1::Any: first algorithm\nalg2::Any: second algorithm\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.UntimedOperator","page":"Library","title":"MPSKit.UntimedOperator","text":"Structure representing a time-independent operator that will be multiplied with a constant coefficient. Consists of\n - An operator (MPO, Hamiltonian, ...)\n - A number f that gets multiplied with the operator\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.VOMPS","page":"Library","title":"MPSKit.VOMPS","text":"struct VOMPS{F} <: MPSKit.Algorithm\n\nPower method algorithm for finding dominant eigenvectors of infinite MPOs. This method works by iteratively approximating the product of an operator and a state with a new state of the same bond dimension.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_gauge::Any: algorithm used for gauging the InfiniteMPS\nalg_environments::Any: algorithm used for the MPS environments\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\n\nReferences\n\nVanhecke et al. SciPost Phys. Core 4 (2021)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.VUMPS","page":"Library","title":"MPSKit.VUMPS","text":"struct VUMPS{F} <: MPSKit.Algorithm\n\nVariational optimization algorithm for uniform matrix product states, based on the combination of DMRG with matrix product state tangent space concepts.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_gauge::Any: algorithm used for gauging the InfiniteMPS\nalg_eigsolve::Any: algorithm used for the eigenvalue solvers\nalg_environments::Any: algorithm used for the MPS environments\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\n\nReferences\n\nZauner-Stauber et al. Phys. Rev. B 97 (2018)\nVanderstraeten et al. SciPost Phys. Lect. Notes 7 (2019)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.VUMPSSvdCut","page":"Library","title":"MPSKit.VUMPSSvdCut","text":"struct VUMPSSvdCut <: MPSKit.Algorithm\n\nAn algorithm that uses a two-site update step to change the bond dimension of a state.\n\nFields\n\ntol_gauge::Any: tolerance for gauging algorithm\ntol_eigenval::Any: tolerance for the eigenvalue solver\ntrscheme::TensorKit.TruncationScheme: algorithm used for [truncation][@extref TensorKit.tsvd] of the two-site update\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.WII","page":"Library","title":"MPSKit.WII","text":"struct WII <: MPSKit.Algorithm\n\nGeneralization of the Euler approximation of the operator exponential for MPOs.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal number of iterations\n\nReferences\n\nZaletel et al. Phys. Rev. B 91 (2015)\nPaeckel et al. Ann. of Phys. 411 (2019)\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.WindowArray","page":"Library","title":"MPSKit.WindowArray","text":"WindowArray{T} <: AbstractVector{T}\n\nA vector embedded in a periodic environment to the left and right, which can be accessed with arbitrary integer indices. The middle part is a regular Vector{T} and the left and right parts are PeriodicVector{T}s.\n\nThis vector inherits most of its properties from the middle part, including its length and axes. Nevertheless, indexing operations are overloaded to allow for out-of-bounds access, which is resolved by the periodic enviroments.\n\nSee also PeriodicVector.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit.WindowMPS","page":"Library","title":"MPSKit.WindowMPS","text":"WindowMPS{A<:GenericMPSTensor,B<:MPSBondTensor} <: AbstractFiniteMPS\n\nType that represents a finite Matrix Product State embedded in an infinte Matrix Product State.\n\nFields\n\nleft_gs::InfiniteMPS – left infinite environment\nwindow::FiniteMPS – finite window Matrix Product State\nright_gs::InfiniteMPS – right infinite environment\n\n\n\nConstructors\n\nWindowMPS(left_gs::InfiniteMPS, window_state::FiniteMPS, [right_gs::InfiniteMPS])\nWindowMPS(left_gs::InfiniteMPS, window_tensors::AbstractVector, [right_gs::InfiniteMPS])\nWindowMPS([f, eltype], physicalspaces::Vector{<:Union{S, CompositeSpace{S}},\n virtualspaces::Vector{<:Union{S, CompositeSpace{S}}, left_gs::InfiniteMPS,\n [right_gs::InfiniteMPS])\nWindowMPS([f, eltype], physicalspaces::Vector{<:Union{S,CompositeSpace{S}}},\n maxvirtualspace::S, left_gs::InfiniteMPS, [right_gs::InfiniteMPS])\n\nConstruct a WindowMPS via a specification of left and right infinite environment, and either a window state or a vector of tensors to construct the window. Alternatively, it is possible to supply the same arguments as for the constructor of FiniteMPS, followed by a left (and right) environment to construct the WindowMPS in one step.\n\nnote: Note\nBy default, the right environment is chosen to be equal to the left, however no copy is made. In this case, changing the left state will also affect the right state.WindowMPS(state::InfiniteMPS, L::Int)\n\nConstruct a WindowMPS from an InfiniteMPS, by promoting a region of length L to a FiniteMPS.\n\n\n\n\n\n","category":"type"},{"location":"lib/lib/#MPSKit._gaugecenter-Tuple{FiniteMPS}","page":"Library","title":"MPSKit._gaugecenter","text":"_gaugecenter(ψ::FiniteMPS)::HalfInt\n\nReturn the location of the MPS center.\n\ncenter::HalfInt:\n\nisinteger(center) → center is a whole number and indicates the location of the first AC tensor present in ψ.ACs\nishalfodd(center) → center is a half-odd-integer, meaning that there are no AC tensors, and indicating between which sites the bond tensor lives.\n\nExample\n\nψ = FiniteMPS(3, ℂ^2, ℂ^16)\nψ.center # returns 7/2, bond tensor is to the right of the 3rd site\nψ.AC[1] # moves center to first site\nψ.center # returns 1\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.add_util_leg-Union{Tuple{TensorKit.AbstractTensorMap{T, S, N1, N2}}, Tuple{N2}, Tuple{N1}, Tuple{S}, Tuple{T}} where {T, S, N1, N2}","page":"Library","title":"MPSKit.add_util_leg","text":"add_util_leg(tensor::AbstractTensorMap{S,N1,N2}) where {S,N1,N2}\n -> AbstractTensorMap{S,N1+1,N2+1}\n\nAdd trivial one-dimensional utility spaces with trivial sector to the left and right of a given tensor map, i.e. as the first space of the codomain and the last space of the domain.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.approx_angles-Tuple{Any}","page":"Library","title":"MPSKit.approx_angles","text":"Find the closest fractions of π, differing at most tol_angle\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.approximate","page":"Library","title":"MPSKit.approximate","text":"approximate(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)\napproximate!(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)\n\nCompute an approximation to the application of an operator O to the state ψ in the form of an MPS ψ₀.\n\nArguments\n\nψ₀::AbstractMPS: initial guess of the approximated state\n(O::AbstractMPO, ψ::AbstractMPS): operator O and state ψ to be approximated\nalgorithm: approximation algorithm. See below for a list of available algorithms.\n[environments]: MPS environment manager\n\nKeywords\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: display progress information\n\nAlgorithms\n\nDMRG: Alternating least square method for maximizing the fidelity with a single-site scheme.\nDMRG2: Alternating least square method for maximizing the fidelity with a two-site scheme.\nIDMRG: Variant of DMRG for maximizing fidelity density in the thermodynamic limit.\nIDMRG2: Variant of DMRG2 for maximizing fidelity density in the thermodynamic limit.\nVOMPS: Tangent space method for truncating uniform MPS.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.approximate!","page":"Library","title":"MPSKit.approximate!","text":"approximate(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)\napproximate!(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)\n\nCompute an approximation to the application of an operator O to the state ψ in the form of an MPS ψ₀.\n\nArguments\n\nψ₀::AbstractMPS: initial guess of the approximated state\n(O::AbstractMPO, ψ::AbstractMPS): operator O and state ψ to be approximated\nalgorithm: approximation algorithm. See below for a list of available algorithms.\n[environments]: MPS environment manager\n\nKeywords\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: display progress information\n\nAlgorithms\n\nDMRG: Alternating least square method for maximizing the fidelity with a single-site scheme.\nDMRG2: Alternating least square method for maximizing the fidelity with a two-site scheme.\nIDMRG: Variant of DMRG for maximizing fidelity density in the thermodynamic limit.\nIDMRG2: Variant of DMRG2 for maximizing fidelity density in the thermodynamic limit.\nVOMPS: Tangent space method for truncating uniform MPS.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.bond_type-Tuple{MPSKit.AbstractMPS}","page":"Library","title":"MPSKit.bond_type","text":"bond_type(ψ::AbstractMPS)\nbond_type(ψtype::Type{<:AbstractMPS})\n\nReturn the type of the bond tensors of an AbstractMPS.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.calc_galerkin-Tuple{Int64, Union{FiniteMPS, InfiniteMPS, WindowMPS}, Any, Any, Any}","page":"Library","title":"MPSKit.calc_galerkin","text":"calc_galerkin(above, operator, below, envs)\ncalc_galerkin(pos, above, operator, below, envs)\n\nCalculate the Galerkin error, which is the error between the solution of the original problem, and the solution of the problem projected on the tangent space. Concretely, this is the overlap of the current state with the single-site derivative, projected onto the nullspace of the current state:\n\nepsilon = VL * (VL * fracabovepartial AC_pos)\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.changebonds","page":"Library","title":"MPSKit.changebonds","text":"changebonds(ψ::AbstractMPS, H, alg, envs) -> ψ′, envs′\nchangebonds(ψ::AbstractMPS, alg) -> ψ′\n\nChange the bond dimension of ψ using the algorithm alg, and return the new ψ and the new envs.\n\nSee also: SvdCut, RandExpand, VUMPSSvdCut, OptimalExpand\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.correlation_length-Tuple{InfiniteMPS}","page":"Library","title":"MPSKit.correlation_length","text":"correlation_length(above::InfiniteMPS; kwargs...)\n\nCompute the correlation length of a given InfiniteMPS based on the next-to-leading eigenvalue of the transfer matrix. The kwargs are passed to transfer_spectrum, and can for example be used to target the correlation length in a specific sector. \n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.correlator","page":"Library","title":"MPSKit.correlator","text":"correlator(ψ, O1, O2, i, j)\ncorrelator(ψ, O12, i, j)\n\nCompute the 2-point correlator <ψ|O1[i]O2[j]|ψ> for inserting O1 at i and O2 at j. Also accepts ranges for j.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.entanglement_spectrum","page":"Library","title":"MPSKit.entanglement_spectrum","text":"entanglement_spectrum(ψ, site::Int) -> SectorDict{sectortype(ψ),Vector{<:Real}}\n\nCompute the entanglement spectrum at a given site, i.e. the singular values of the gauge matrix to the right of a given site. This is a dictionary mapping the charge to the singular values.\n\nFor InfiniteMPS and WindowMPS the default value for site is 0.\n\nFor FiniteMPS no default value for site is given, it is up to the user to specify.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.entanglementplot","page":"Library","title":"MPSKit.entanglementplot","text":"entanglementplot(state; site=0[, kwargs...])\n\nPlot the entanglement spectrum of a given MPS state. \n\nArguments\n\nstate: the MPS for which to compute the entanglement spectrum.\n\nKeyword Arguments\n\nsite::Int=0: MPS index for multisite unit cells. The spectrum is computed for the bond between site and site + 1.\nexpand_symmetry::Logical=false: add quantum dimension degeneracies.\nsortby=maximum: the method of sorting the sectors.\nsector_margin=1//10: the amount of whitespace between sectors.\nsector_formatter=string: how to convert sectors to strings.\nkwargs...: other kwargs are passed on to the plotting backend.\n\nnote: Note\nYou will need to manually import Plots.jl to be able to use this function. MPSKit.jl defines its plots based on RecipesBase.jl, but the user still has to add using Plots to be able to actually produce the plots.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.entropy-Tuple{InfiniteMPS}","page":"Library","title":"MPSKit.entropy","text":"entropy(state, [site::Int])\n\nCalculate the Von Neumann entanglement entropy of a given MPS. If an integer site is given, the entropy is across the entanglement cut to the right of site site. Otherwise, a vector of entropies is returned, one for each site.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.environment_alg-Tuple{Union{InfiniteMPS, MultilineMPS}, Union{InfiniteMPO, MultilineMPO}, Union{InfiniteMPS, MultilineMPS}}","page":"Library","title":"MPSKit.environment_alg","text":"environment_alg(above, operator, below; kwargs...)\n\nDetermine an appropriate algorithm for computing the environments, based on the given kwargs....\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.exact_diagonalization-Tuple{FiniteMPOHamiltonian}","page":"Library","title":"MPSKit.exact_diagonalization","text":"exact_diagonalization(H::FiniteMPOHamiltonian;\n sector=first(sectors(oneunit(physicalspace(H, 1)))),\n len::Int=length(H), num::Int=1, which::Symbol=:SR,\n alg=Defaults.alg_eigsolve(; dynamic_tols=false))\n -> vals, state_vecs, convhist\n\nUse KrylovKit.eigsolve to perform exact diagonalization on a FiniteMPOHamiltonian to find its eigenvectors as FiniteMPS of maximal rank, essentially equivalent to dense eigenvectors.\n\nArguments\n\nH::FiniteMPOHamiltonian: the Hamiltonian to diagonalize.\n\nKeyword arguments\n\nsector=first(sectors(oneunit(physicalspace(H, 1)))): the total charge of the eigenvectors, which is chosen trivial by default.\nlen::Int=length(H): the length of the system.\nnum::Int=1: the number of eigenvectors to find.\nwhich::Symbol=:SR: the kind eigenvalues to find, see KrylovKit.eigsolve. \nalg=Defaults.alg_eigsolve(; dynamic_tols=false): the diagonalization algorithm to use, see KrylovKit.eigsolve.\n\nnote: Valid `sector` values\nThe total charge of the eigenvectors is imposed by adding a charged auxiliary space as the leftmost virtualspace of each eigenvector. Specifically, this is achieved by passing left=Vect[typeof(sector)](sector => 1) to the FiniteMPS constructor. As such, the only valid sector values (i.e. sector values for which the corresponding eigenstates have valid fusion channels) are those that occur in the dual of the fusion of all the physical spaces in the system.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.excitations","page":"Library","title":"MPSKit.excitations","text":"excitations(H, algorithm::QuasiparticleAnsatz, momentum::Union{Number, Vector{<:Number}},\n left_ψ::InfiniteMPS, [left_environment],\n [right_ψ::InfiniteMPS], [right_environment];\n kwargs...)\n\nCreate and optimise infinite quasiparticle states.\n\nArguments\n\nH::AbstractMPO: operator for which to find the excitations\nalgorithm::QuasiparticleAnsatz: optimization algorithm\nmomentum::Union{Number, Vector{<:Number}}: momentum or list of momenta\nleft_ψ::InfiniteMPS: left groundstate\n[left_environment]: left groundstate environment\n[right_ψ::InfiniteMPS]: right groundstate\n[right_environment]: right groundstate environment\n\nKeywords\n\nnum::Int: number of excited states to compute\nsolver: algorithm for the linear solver of the quasiparticle environments\nsector=one(sectortype(left_ψ)): charge of the quasiparticle state\nparallel=true: enable multi-threading over different momenta\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.excitations-2","page":"Library","title":"MPSKit.excitations","text":"excitations(H, algorithm::QuasiparticleAnsatz, ψ::FiniteQP, [left_environments],\n [right_environments]; num=1) -> (energies, states)\nexcitations(H, algorithm::QuasiparticleAnsatz, ψ::InfiniteQP, [left_environments],\n [right_environments]; num=1, solver=Defaults.solver) -> (energies, states)\nexcitations(H, algorithm::FiniteExcited, ψs::NTuple{<:Any, <:FiniteMPS};\n num=1, init=copy(first(ψs))) -> (energies, states)\nexcitations(H, algorithm::ChepigaAnsatz, ψ::FiniteMPS, [envs];\n num=1, pos=length(ψ)÷2) -> (energies, states)\nexcitations(H, algorithm::ChepigaAnsatz2, ψ::FiniteMPS, [envs];\n num=1, pos=length(ψ)÷2) -> (energies, states)\n\nCompute the first excited states and their energy gap above a groundstate.\n\nArguments\n\nH::AbstractMPO: operator for which to find the excitations\nalgorithm: optimization algorithm\nψ::QP: initial quasiparticle guess\nψs::NTuple{N, <:FiniteMPS}: N first excited states\n[left_environments]: left groundstate environment\n[right_environments]: right groundstate environment\n\nKeywords\n\nnum::Int: number of excited states to compute\nsolver: algorithm for the linear solver of the quasiparticle environments\ninit: initial excited state guess\npos: position of perturbation\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.excitations-3","page":"Library","title":"MPSKit.excitations","text":"excitations(H, algorithm::QuasiparticleAnsatz, left_ψ::InfiniteMPS, [left_environment],\n [right_ψ::InfiniteMPS], [right_environment]; kwargs...)\n\nCreate and optimise finite quasiparticle states.\n\nArguments\n\nH::AbstractMPO: operator for which to find the excitations\nalgorithm::QuasiparticleAnsatz: optimization algorithm\nleft_ψ::FiniteMPS: left groundstate\n[left_environment]: left groundstate environment\n[right_ψ::FiniteMPS]: right groundstate\n[right_environment]: right groundstate environment\n\nKeywords\n\nnum::Int: number of excited states to compute\nsector=one(sectortype(left_ψ)): charge of the quasiparticle state\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.expectation_value","page":"Library","title":"MPSKit.expectation_value","text":"expectation_value(ψ, O, [environments])\nexpectation_value(ψ, inds => O)\n\nCompute the expectation value of an operator O on a state ψ. Optionally, it is possible to make the computations more efficient by also passing in previously calculated environments.\n\nIn general, the operator O may consist of an arbitrary MPO O <: AbstractMPO that acts on all sites, or a local operator O = inds => operator acting on a subset of sites. In the latter case, inds is a tuple of indices that specify the sites on which the operator acts, while the operator is either a AbstractTensorMap or a FiniteMPO.\n\nArguments\n\nψ::AbstractMPS : the state on which to compute the expectation value\nO::Union{AbstractMPO,Pair} : the operator to compute the expectation value of. This can either be an AbstractMPO, or a pair of indices and local operator..\nenvironments::AbstractMPSEnvironments : the environments to use for the calculation. If not given, they will be calculated.\n\nExamples\n\njulia> ψ = FiniteMPS(ones(Float64, (ℂ^2)^4));\n\njulia> S_x = TensorMap(Float64[0 1; 1 0], ℂ^2, ℂ^2);\n\njulia> round(expectation_value(ψ, 2 => S_x))\n1.0\n\njulia> round(expectation_value(ψ, (2, 3) => S_x ⊗ S_x))\n1.0\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.fidelity_susceptibility-Union{Tuple{T}, Tuple{Union{FiniteMPS, InfiniteMPS}, T, AbstractVector{T}}, Tuple{Union{FiniteMPS, InfiniteMPS}, T, AbstractVector{T}, Any}} where T<:MPOHamiltonian","page":"Library","title":"MPSKit.fidelity_susceptibility","text":"fidelity_susceptibility(state::Union{FiniteMPS,InfiniteMPS}, H₀::T,\n Vs::AbstractVector{T}, [henvs=environments(state, H₀)];\n maxiter=Defaults.maxiter,\n tol=Defaults.tol) where {T<:MPOHamiltonian}\n\nComputes the fidelity susceptibility of a the ground state state of a base Hamiltonian H₀ with respect to a set of perturbing Hamiltonians Vs. Each of the perturbing Hamiltonians can be interpreted as corresponding to a tuning parameter aᵢ in a 'total' Hamiltonian H = H₀ + ᵢ aᵢ Vᵢ.\n\nReturns a matrix containing the overlaps of the elementary excitations on top of state corresponding to each of the perturbing Hamiltonians.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.find_groundstate","page":"Library","title":"MPSKit.find_groundstate","text":"find_groundstate(ψ₀, H, [environments]; kwargs...) -> (ψ, environments, ϵ)\nfind_groundstate(ψ₀, H, algorithm, environments) -> (ψ, environments, ϵ)\n\nCompute the groundstate for Hamiltonian H with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.\n\nArguments\n\nψ₀::AbstractMPS: initial guess\nH::AbstractMPO: operator for which to find the groundstate\n[environments]: MPS environment manager\nalgorithm: optimization algorithm\n\nKeywords\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: display progress information\n\nReturns\n\nψ::AbstractMPS: converged groundstate\nenvironments: environments corresponding to the converged state\nϵ::Float64: final convergence error upon terminating the algorithm\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.fixedpoint-Tuple{Any, Any, Symbol, KrylovKit.Lanczos}","page":"Library","title":"MPSKit.fixedpoint","text":"fixedpoint(A, x₀, which::Symbol; kwargs...) -> val, vec\nfixedpoint(A, x₀, which::Symbol, alg) -> val, vec\n\nCompute the fixedpoint of a linear operator A using the specified eigensolver alg. The fixedpoint is assumed to be unique.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.fuse_mul_mpo-Tuple{Any, Any}","page":"Library","title":"MPSKit.fuse_mul_mpo","text":"fuse_mul_mpo(O1, O2)\n\nCompute the mpo tensor that arises from multiplying MPOs.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.gaugefix!","page":"Library","title":"MPSKit.gaugefix!","text":"gaugefix!(ψ::InfiniteMPS, A, C₀; kwargs...) -> ψ\ngaugefix!(ψ::InfiniteMPS, A, C₀, alg::Algorithm) -> ψ\n\nBring an InfiniteMPS into a uniform gauge, using the specified algorithm.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.instantiate_operator-Tuple{AbstractArray{<:TensorKit.VectorSpace}, Pair}","page":"Library","title":"MPSKit.instantiate_operator","text":"instantiate_operator(lattice::AbstractArray{<:VectorSpace}, O::Pair)\n\nInstantiate a local operator O on a lattice lattice as a vector of MPO tensors, and a vector of linear site indices.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.integrate","page":"Library","title":"MPSKit.integrate","text":"integrate(f, y₀, t, dt, alg)\n\nIntegrate the differential equation i dydt = f(y t) over a time step 'dt' starting from y(t₀)=y₀, using the provided algorithm.\n\nArguments\n\nf: driving function\ny₀: object to integrate\nt::Number: starting time of time-step\ndt::Number: time-step magnitude\nalg: integration scheme\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.isfullrank-Tuple{TensorKit.AbstractTensorMap{T, S, N, 1} where {S, N, T}}","page":"Library","title":"MPSKit.isfullrank","text":"isfullrank(A::GenericMPSTensor; side=:both)\n\nDetermine whether the given tensor is full rank, i.e. whether both the map from the left virtual space and the physical space to the right virtual space, and the map from the right virtual space and the physical space to the left virtual space are injective.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.l_LL-Union{Tuple{InfiniteMPS{A}}, Tuple{A}, Tuple{InfiniteMPS{A}, Int64}} where A","page":"Library","title":"MPSKit.l_LL","text":"l_LL(ψ, location)\n\nLeft dominant eigenvector of the AL-AL transfermatrix.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.l_LR","page":"Library","title":"MPSKit.l_LR","text":"l_LR(ψ, location)\n\nLeft dominant eigenvector of the AL-AR transfermatrix.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.l_RL","page":"Library","title":"MPSKit.l_RL","text":"l_RL(ψ, location)\n\nLeft dominant eigenvector of the AR-AL transfermatrix.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.l_RR","page":"Library","title":"MPSKit.l_RR","text":"l_RR(ψ, location)\n\nLeft dominant eigenvector of the AR-AR transfermatrix.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.leading_boundary","page":"Library","title":"MPSKit.leading_boundary","text":"leading_boundary(ψ, opp, alg, envs=environments(ψ, opp))\n\nApproximate the leading eigenvector for opp.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.leading_boundary-2","page":"Library","title":"MPSKit.leading_boundary","text":"leading_boundary(ψ₀, O, [environments]; kwargs...) -> (ψ, environments, ϵ)\nleading_boundary(ψ₀, O, algorithm, environments) -> (ψ, environments, ϵ)\n\nCompute the leading boundary MPS for operator O with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.\n\nArguments\n\nψ₀::AbstractMPS: initial guess\nO::AbstractMPO: operator for which to find the leading_boundary\n[environments]: MPS environment manager\nalgorithm: optimization algorithm\n\nKeywords\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: display progress information\n\nReturns\n\nψ::AbstractMPS: converged leading boundary MPS\nenvironments: environments corresponding to the converged boundary\nϵ::Float64: final convergence error upon terminating the algorithm\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.left_virtualspace","page":"Library","title":"MPSKit.left_virtualspace","text":"left_virtualspace(ψ::AbstractMPS, [pos=1:length(ψ)])\n\nReturn the virtual space of the bond to the left of sites pos.\n\nwarning: Warning\nIn rare cases, the gauge tensor on the virtual space might not be square, and as a result it cannot always be guaranteed that right_virtualspace(ψ, i - 1) == left_virtualspace(ψ, i)\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.make_time_mpo","page":"Library","title":"MPSKit.make_time_mpo","text":"make_time_mpo(H::MPOHamiltonian, dt::Number, alg) -> O::MPO\n\nConstruct an MPO that approximates exp(-iHdt).\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.makefullrank!-Tuple{PeriodicVector{<:TensorKit.AbstractTensorMap{T, S, N, 1} where {S, N, T}}}","page":"Library","title":"MPSKit.makefullrank!","text":"makefullrank!(A::PeriodicVector{<:GenericMPSTensor}; alg=QRpos())\n\nMake the set of MPS tensors full rank by performing a series of orthogonalizations.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.marek_gap-Tuple{InfiniteMPS}","page":"Library","title":"MPSKit.marek_gap","text":"Given an InfiniteMPS, compute the gap ϵ for the asymptotics of the transfer matrix, as well as the Marek gap δ as a scaling measure of the bond dimension.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.max_Ds-Tuple{FiniteMPS}","page":"Library","title":"MPSKit.max_Ds","text":"max_Ds(ψ::FiniteMPS) -> Vector{Float64}\n\nCompute the dimension of the maximal virtual space at a given site.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.open_boundary_conditions","page":"Library","title":"MPSKit.open_boundary_conditions","text":"open_boundary_conditions(mpo::InfiniteMPOHamiltonian, L::Int) -> FiniteMPOHamiltonian\n\nConvert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.open_boundary_conditions-Union{Tuple{InfiniteMPO{O}}, Tuple{O}, Tuple{InfiniteMPO{O}, Any}} where O<:BlockTensorKit.SparseBlockTensorMap","page":"Library","title":"MPSKit.open_boundary_conditions","text":"open_boundary_conditions(mpo::InfiniteMPO, L::Int) -> FiniteMPO\n\nConvert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.periodic_boundary_conditions-Union{Tuple{InfiniteMPO{O}}, Tuple{O}, Tuple{InfiniteMPO{O}, Any}} where O","page":"Library","title":"MPSKit.periodic_boundary_conditions","text":"periodic_boundary_conditions(mpo::AbstractInfiniteMPO, L::Int)\n\nConvert an infinite MPO into a finite MPO of length L, by mapping periodic boundary conditions onto an open system.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.physicalspace","page":"Library","title":"MPSKit.physicalspace","text":"physicalspace(ψ::AbstractMPS, [pos=1:length(ψ)])\n\nReturn the physical space of the site tensor at site i.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.propagator","page":"Library","title":"MPSKit.propagator","text":"propagator(ψ₀::AbstractFiniteMPS, z::Number, H::MPOHamiltonian, alg::DynamicalDMRG; init=copy(ψ₀))\n\nCalculate the propagator frac1E₀ + z - Hψ₀ using the dynamical DMRG algorithm.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.r_LL","page":"Library","title":"MPSKit.r_LL","text":"r_LL(ψ, location)\n\nRight dominant eigenvector of the AL-AL transfermatrix.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.r_LR","page":"Library","title":"MPSKit.r_LR","text":"r_LR(ψ, location)\n\nRight dominant eigenvector of the AL-AR transfermatrix.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.r_RL","page":"Library","title":"MPSKit.r_RL","text":"r_RL(ψ, location)\n\nRight dominant eigenvector of the AR-AL transfermatrix.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.r_RR-Union{Tuple{InfiniteMPS{A}}, Tuple{A}, Tuple{InfiniteMPS{A}, Int64}} where A","page":"Library","title":"MPSKit.r_RR","text":"r_RR(ψ, location)\n\nRight dominant eigenvector of the AR-AR transfermatrix.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.recalculate!","page":"Library","title":"MPSKit.recalculate!","text":"Recalculate in-place each sub-env in MultipleEnvironments\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.regauge!","page":"Library","title":"MPSKit.regauge!","text":"regauge!(AC::GenericMPSTensor, C::MPSBondTensor; alg=QRpos()) -> AL\nregauge!(CL::MPSBondTensor, AC::GenericMPSTensor; alg=LQpos()) -> AR\n\nBring updated AC and C tensors back into a consistent set of left or right canonical tensors. This minimizes ∥AC_i - AL_i * C_i∥ or ∥AC_i - C_{i-1} * AR_i∥. The optimal algorithm uses Polar() decompositions, but QR-based algorithms are typically more performant. Note that the first signature is slightly faster, as it avoids an intermediate transposition.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.right_virtualspace","page":"Library","title":"MPSKit.right_virtualspace","text":"right_virtualspace(ψ::AbstractMPS, [pos=1:length(ψ)])\n\nReturn the virtual space of the bond to the right of site(s) pos.\n\nwarning: Warning\nIn rare cases, the gauge tensor on the virtual space might not be square, and as a result it cannot always be guaranteed that right_virtualspace(ψ, i - 1) == left_virtualspace(ψ, i)\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.site_type-Tuple{MPSKit.AbstractMPS}","page":"Library","title":"MPSKit.site_type","text":"site_type(ψ::AbstractMPS)\nsite_type(ψtype::Type{<:AbstractMPS})\n\nReturn the type of the site tensors of an AbstractMPS.\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.tensorexpr-Tuple{Any, Any}","page":"Library","title":"MPSKit.tensorexpr","text":"tensorexpr(name, ind_out, [ind_in])\n\nGenerates expressions for use within @tensor environments of the form name[ind_out...; ind_in].\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.time_evolve","page":"Library","title":"MPSKit.time_evolve","text":"time_evolve(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ, envs)\ntime_evolve!(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ₀, envs)\n\nTime-evolve the initial state ψ₀ with Hamiltonian H over a given time span by stepping through each of the time points obtained by iterating t_span.\n\nArguments\n\nψ₀::AbstractMPS: initial state\nH::AbstractMPO: operator that generates the time evolution (can be time-dependent).\nt_span::AbstractVector{<:Number}: time points over which the time evolution is stepped\n[alg]: algorithm to use for the time evolution. Defaults to TDVP.\n[envs]: MPS environment manager\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.time_evolve!","page":"Library","title":"MPSKit.time_evolve!","text":"time_evolve(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ, envs)\ntime_evolve!(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ₀, envs)\n\nTime-evolve the initial state ψ₀ with Hamiltonian H over a given time span by stepping through each of the time points obtained by iterating t_span.\n\nArguments\n\nψ₀::AbstractMPS: initial state\nH::AbstractMPO: operator that generates the time evolution (can be time-dependent).\nt_span::AbstractVector{<:Number}: time points over which the time evolution is stepped\n[alg]: algorithm to use for the time evolution. Defaults to TDVP.\n[envs]: MPS environment manager\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.timestep","page":"Library","title":"MPSKit.timestep","text":"timestep(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ, envs)\ntimestep!(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ₀, envs)\n\nTime-step the state ψ₀ with Hamiltonian H over a given time step dt at time t, solving the Schroedinger equation: i ψt = H ψ.\n\nArguments\n\nψ₀::AbstractMPS: initial state\nH::AbstractMPO: operator that generates the time evolution (can be time-dependent).\nt::Number: starting time of time-step\ndt::Number: time-step magnitude\n[alg]: algorithm to use for the time evolution. Defaults to TDVP.\n[envs]: MPS environment manager\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.timestep!","page":"Library","title":"MPSKit.timestep!","text":"timestep(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ, envs)\ntimestep!(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ₀, envs)\n\nTime-step the state ψ₀ with Hamiltonian H over a given time step dt at time t, solving the Schroedinger equation: i ψt = H ψ.\n\nArguments\n\nψ₀::AbstractMPS: initial state\nH::AbstractMPO: operator that generates the time evolution (can be time-dependent).\nt::Number: starting time of time-step\ndt::Number: time-step magnitude\n[alg]: algorithm to use for the time evolution. Defaults to TDVP.\n[envs]: MPS environment manager\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.transfer_left-Union{Tuple{N₂}, Tuple{N₁}, Tuple{S}, Tuple{TensorKit.AbstractTensorMap{<:Any, S, 1, N₁}, TensorKit.AbstractTensorMap{T, S, N₂, 1} where T, TensorKit.AbstractTensorMap{T, S, N₂, 1} where T}} where {S, N₁, N₂}","page":"Library","title":"MPSKit.transfer_left","text":"transfer_left(v, A, Ā)\n\napply a transfer matrix to the left.\n\n ┌─A─\n-v │\n └─Ā─\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.transfer_right-Union{Tuple{N₂}, Tuple{N₁}, Tuple{S}, Tuple{TensorKit.AbstractTensorMap{<:Any, S, 1, N₁}, TensorKit.AbstractTensorMap{T, S, N₂, 1} where T, TensorKit.AbstractTensorMap{T, S, N₂, 1} where T}} where {S, N₁, N₂}","page":"Library","title":"MPSKit.transfer_right","text":"transfer_right(v, A, Ā)\n\napply a transfer matrix to the right.\n\n─A─┐\n │ v-\n─Ā─┘\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.transfer_spectrum-Tuple{InfiniteMPS}","page":"Library","title":"MPSKit.transfer_spectrum","text":"transfer_spectrum(above::InfiniteMPS; below=above, tol=Defaults.tol, num_vals=20,\n sector=first(sectors(oneunit(left_virtualspace(above, 1)))))\n\nCalculate the partial spectrum of the left mixed transfer matrix corresponding to the overlap of a given above state and a below state. The sector keyword argument can be used to specify a non-trivial total charge for the transfer matrix eigenvectors. Specifically, an auxiliary space ℂ[typeof(sector)](sector => 1)' will be added to the domain of each eigenvector. The tol and num_vals keyword arguments are passed to KrylovKit.eigolve\n\n\n\n\n\n","category":"method"},{"location":"lib/lib/#MPSKit.transferplot","page":"Library","title":"MPSKit.transferplot","text":"transferplot(above, below=above; sectors=[], transferkwargs=(;)[, kwargs...])\n\nPlot the partial transfer matrix spectrum of two InfiniteMPS's.\n\nArguments\n\nabove::InfiniteMPS: above mps for transfer_spectrum.\nbelow::InfiniteMPS=above: below mps for transfer_spectrum.\n\nKeyword Arguments\n\nsectors=[]: vector of sectors for which to compute the spectrum.\ntransferkwargs: kwargs for call to transfer_spectrum.\nkwargs: other kwargs are passed on to the plotting backend.\nthetaorigin=0: origin of the angle range.\nsector_formatter=string: how to convert sectors to strings.\n\nnote: Note\nYou will need to manually import Plots.jl to be able to use this function. MPSKit.jl defines its plots based on RecipesBase.jl, but the user still has to add using Plots to be able to actually produce the plots.\n\n\n\n\n\n","category":"function"},{"location":"lib/lib/#MPSKit.variance","page":"Library","title":"MPSKit.variance","text":"variance(state, hamiltonian, [envs=environments(state, hamiltonian)])\n\nCompute the variance of the energy of the state with respect to the hamiltonian.\n\n\n\n\n\n","category":"function"},{"location":"man/lattices/#lattices","page":"Lattices","title":"Lattices","text":"","category":"section"},{"location":"man/lattices/","page":"Lattices","title":"Lattices","text":"warning: Warning\nThis section is still under construction. Coming soon!","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"EditURL = \"../../../../../examples/quantum1d/3.ising-dqpt/main.jl\"","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"(Image: ) (Image: ) (Image: )","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/#DQPT-in-the-Ising-model(@id-demo_dqpt)","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"","category":"section"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"In this tutorial we will try to reproduce the results from this paper. The needed packages are","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"using MPSKit, MPSKitModels, TensorKit","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"Dynamical quantum phase transitions (DQPT in short) are signatures of equilibrium phase transitions in a dynamical quantity - the loschmidth echo. This quantity is given by L(t) = frac-2N ln( psi(t) psi(0) ) where N is the system size. One typically starts from a groundstate and then quenches the hamiltonian to a different point. Non analycities in the loschmidth echo are called 'dynamical quantum phase transitions'.","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"In the mentioned paper they work with","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"H(g) = - sum^N-1_i=1 sigma^z_i sigma^z_i+1 + g sum_i=1^N sigma^x_i","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"and show that divergences occur when quenching across the critical point (g₀ → g₁) for t^*_n = t^*(n+frac12) with t^* = pie(g_1k^*), cos(k^*) = (1+g_0 g_1) (g_0 + g_1), e(gk) = sqrt(g-cos k)^2 + sin^2 k.","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"The outline of the tutorial is as follows. We will pick g₀ = 05, g₁ = 20, and perform the time evolution at different system sizes and compare with the thermodynamic limit. For those g we expect non-analicities to occur at t_n 235 (n + 12).","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"First we construct the hamiltonian in mpo form, and obtain the pre-quenched groundstate:","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"L = 20\nH₀ = transverse_field_ising(FiniteChain(L); g=-0.5)\nψ₀ = FiniteMPS(L, ℂ^2, ℂ^10)\nψ₀, _ = find_groundstate(ψ₀, H₀, DMRG());","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"[ Info: DMRG init:\tobj = +1.002387808585e+01\terr = 1.4432e-01\n[ Info: DMRG 1:\tobj = -2.040021714927e+01\terr = 4.0939235067e-03\ttime = 0.07 sec\n[ Info: DMRG 2:\tobj = -2.040021715177e+01\terr = 4.1045749328e-07\ttime = 0.02 sec\n[ Info: DMRG 3:\tobj = -2.040021782419e+01\terr = 4.0893119931e-05\ttime = 0.11 sec\n[ Info: DMRG 4:\tobj = -2.040021786700e+01\terr = 1.5231059570e-06\ttime = 0.12 sec\n[ Info: DMRG 5:\tobj = -2.040021786703e+01\terr = 1.1927466419e-07\ttime = 0.04 sec\n[ Info: DMRG 6:\tobj = -2.040021786703e+01\terr = 1.0958548921e-10\ttime = 0.02 sec\n[ Info: DMRG conv 7:\tobj = -2.040021786703e+01\terr = 2.1531775493e-12\ttime = 0.43 sec\n","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/#Finite-MPS-quenching","page":"DQPT in the Ising model(@id demo_dqpt)","title":"Finite MPS quenching","text":"","category":"section"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"We can define a helper function that measures the loschmith echo","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"echo(ψ₀::FiniteMPS, ψₜ::FiniteMPS) = -2 * log(abs(dot(ψ₀, ψₜ))) / length(ψ₀)\n@assert isapprox(echo(ψ₀, ψ₀), 0, atol=1e-10)","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"We will initially use a two-site TDVP scheme to dynamically increase the bond dimension while time evolving, and later on switch to a faster one-site scheme. A single timestep can be done using","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"H₁ = transverse_field_ising(FiniteChain(L); g=-2.0)\nψₜ = deepcopy(ψ₀)\ndt = 0.01\nψₜ, envs = timestep(ψₜ, H₁, 0, dt, TDVP2(; trscheme=truncdim(20)));","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"\"envs\" is a kind of cache object that keeps track of all environments in ψ. It is often advantageous to re-use the environment, so that mpskit doesn't need to recalculate everything.","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"Putting it all together, we get","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"function finite_sim(L; dt=0.05, finaltime=5.0)\n ψ₀ = FiniteMPS(L, ℂ^2, ℂ^10)\n H₀= transverse_field_ising(FiniteChain(L); g=-0.5)\n ψ₀, _ = find_groundstate(ψ₀, H₀, DMRG())\n\n H₁ = transverse_field_ising(FiniteChain(L); g=-2.0)\n ψₜ = deepcopy(ψ₀)\n envs = environments(ψₜ, H₁)\n\n echos = [echo(ψₜ, ψ₀)]\n times = collect(0:dt:finaltime)\n\n for t in times[2:end]\n alg = t > 3 * dt ? TDVP() : TDVP2(; trscheme=truncdim(50))\n ψₜ, envs = timestep(ψₜ, H₁, 0, dt, alg, envs)\n push!(echos, echo(ψₜ, ψ₀))\n end\n\n return times, echos\nend","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"finite_sim (generic function with 1 method)","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"(Image: )","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/#Infinite-MPS-quenching","page":"DQPT in the Ising model(@id demo_dqpt)","title":"Infinite MPS quenching","text":"","category":"section"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"Similarly we could start with an initial infinite state and find the pre-quench groundstate:","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"ψ₀ = InfiniteMPS([ℂ^2], [ℂ^10])\nH₀ = transverse_field_ising(; g=-0.5)\nψ₀, _ = find_groundstate(ψ₀, H₀, VUMPS());","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"[ Info: VUMPS init:\tobj = +4.829091166942e-01\terr = 3.8333e-01\n[ Info: VUMPS 1:\tobj = -1.062402142520e+00\terr = 2.6498065851e-02\ttime = 0.02 sec\n[ Info: VUMPS 2:\tobj = -1.063544409278e+00\terr = 2.4370573433e-05\ttime = 0.01 sec\n[ Info: VUMPS 3:\tobj = -1.063544409973e+00\terr = 1.2541001144e-07\ttime = 0.01 sec\n[ Info: VUMPS 4:\tobj = -1.063544409973e+00\terr = 2.2271390880e-09\ttime = 0.01 sec\n[ Info: VUMPS 5:\tobj = -1.063544409973e+00\terr = 1.3003499540e-10\ttime = 0.01 sec\n[ Info: VUMPS conv 6:\tobj = -1.063544409973e+00\terr = 1.2478380148e-11\ttime = 0.08 sec\n","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"The dot product of two infinite matrix product states scales as alpha ^N where α is the dominant eigenvalue of the transfer matrix. It is this α that is returned when calling","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"dot(ψ₀, ψ₀)","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"1.0000000000000004 + 1.6174779448250835e-16im","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"so the loschmidth echo takes on the pleasant form","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"echo(ψ₀::InfiniteMPS, ψₜ::InfiniteMPS) = -2 * log(abs(dot(ψ₀, ψₜ)))\n@assert isapprox(echo(ψ₀, ψ₀), 0, atol=1e-10)","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"This time we cannot use a two-site scheme to grow the bond dimension, as this isn't implemented (yet). Instead, we have to make use of the changebonds machinery. Multiple algorithms are available, but we will only focus on OptimalEpand(). Growing the bond dimension by 5 can be done by calling:","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"ψₜ = deepcopy(ψ₀)\nH₁ = transverse_field_ising(; g=-2.0)\nψₜ, envs = changebonds(ψₜ, H₁, OptimalExpand(; trscheme=truncdim(5)));","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"a single timestep is easy","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"dt = 0.01\nψₜ, envs = timestep(ψₜ, H₁, 0, dt, TDVP(), envs);","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"With performance in mind we should once again try to re-use these \"envs\" cache objects. The final code is","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"function infinite_sim(dt=0.05, finaltime=5.0)\n ψ₀ = InfiniteMPS([ℂ^2], [ℂ^10])\n ψ₀, _ = find_groundstate(ψ₀, H₀, VUMPS())\n\n ψₜ = deepcopy(ψ₀)\n envs = environments(ψₜ, H₁)\n\n echos = [echo(ψₜ, ψ₀)]\n times = collect(0:dt:finaltime)\n\n for t in times[2:end]\n if t < 50dt # if t is sufficiently small, we increase the bond dimension\n ψₜ, envs = changebonds(ψₜ, H₁, OptimalExpand(; trscheme=truncdim(1)), envs)\n end\n ψₜ, envs = timestep(ψₜ, H₁, 0, dt, TDVP(), envs)\n push!(echos, echo(ψₜ, ψ₀))\n end\n\n return times, echos\nend","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"infinite_sim (generic function with 3 methods)","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"(Image: )","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"","category":"page"},{"location":"examples/quantum1d/3.ising-dqpt/","page":"DQPT in the Ising model(@id demo_dqpt)","title":"DQPT in the Ising model(@id demo_dqpt)","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/parallelism/#Parallelism-in-julia","page":"Parallelism in julia","title":"Parallelism in julia","text":"","category":"section"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"Julia has great parallelism infrastructure, but there is a caveat that is relevant for all algorithms implemented in MPSKit. The Julia threads do not play nicely together with the BLAS threads, which are the threads used for many of the linear algebra routines, and in particular for gemm (general matrix-matrix multiplication). As this is a core routine in MPSKit, this has a significant impact on the overall performance.","category":"page"},{"location":"man/parallelism/#Julia-threads-vs-BLAS-threads","page":"Parallelism in julia","title":"Julia threads vs BLAS threads","text":"","category":"section"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"A lot of the confusion stems from the fact that the BLAS threading behaviour is not consistent between different vendors. Additionally, performance behaviour is severely dependent on hardware, the specifics of the problem, and the availability of other resources such as total memory, or memory bandwith. This means that there is no one size fits all solution, and that you will have to experiment with the settings to get optimal performance. Nevertheless, there are some general guidelines that can be followed, which seem to at least work well in most cases.","category":"page"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"The number of threads that are set by BLAS.set_num_threads(), in the case of OpenBLAS (the default vendor), is equal to the total number of BLAS threads that is kept in a pool, which is then shared by all Julia threads. This means that if you have 4 julia threads and 4 BLAS threads, then all julia threads will share the same 4 BLAS threads. On the other hand, using BLAS.set_num_threads(1), OpenBLAS will now utilize the julia threads to run the BLAS jobs. Thus, for OpenBLAS, very often setting the number of BLAS threads to 1 is the best option, which will then maximally utilize the julia threading infrastructure of MPSKit.","category":"page"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"In the case of MKL.jl, which often outperforms OpenBLAS, the situation is a bit different. Here, the number of BLAS threads corresponds to the number of threads that are spawned by each julia thread. Thus, if you have 4 julia threads and 4 BLAS threads, then each julia thread will spawn 4 BLAS threads, for a total of 16 BLAS threads. As such, it might become necessary to adapt the settings to avoid oversubscription of the cores.","category":"page"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"A careful analysis of the different cases and benefits can be inspected by making use of ThreadPinning.jl's tool threadinfo(; blas=true, info=true). In particular, the following might demonstrate the difference between OpenBLAS and MKL:","category":"page"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"julia> Threads.nthreads()\n4\n\njulia> using ThreadPinning; threadinfo(; blas=true, hints=true)\n\nSystem: 8 cores (2-way SMT), 1 sockets, 1 NUMA domains\n\n| 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | \n\n# = Julia thread, # = HT, # = Julia thread on HT, | = Socket seperator\n\nJulia threads: 4\n├ Occupied CPU-threads: 4\n└ Mapping (Thread => CPUID): 1 => 8, 2 => 5, 3 => 9, 4 => 2,\n\nBLAS: libopenblas64_.so\n└ openblas_get_num_threads: 8\n\n[ Info: jlthreads != 1 && blasthreads < cputhreads. You should either set BLAS.set_num_threads(1) (recommended!) or at least BLAS.set_num_threads(16).\n[ Info: jlthreads < cputhreads. Perhaps increase number of Julia threads to 16?\njulia> using MKL; threadinfo(; blas=true, hints=true)\n\nSystem: 8 cores (2-way SMT), 1 sockets, 1 NUMA domains\n\n| 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | \n\n# = Julia thread, # = HT, # = Julia thread on HT, | = Socket seperator\n\nJulia threads: 4\n├ Occupied CPU-threads: 4\n└ Mapping (Thread => CPUID): 1 => 11, 2 => 12, 3 => 1, 4 => 2,\n\nBLAS: libmkl_rt.so\n├ mkl_get_num_threads: 8\n└ mkl_get_dynamic: true\n\n┌ Warning: blasthreads_per_jlthread > cputhreads_per_jlthread. You should decrease the number of MKL threads, i.e. BLAS.set_num_threads(4).\n└ @ ThreadPinning ~/.julia/packages/ThreadPinning/qV2Cd/src/threadinfo.jl:256\n[ Info: jlthreads < cputhreads. Perhaps increase number of Julia threads to 16?","category":"page"},{"location":"man/parallelism/#MPSKit-multithreading","page":"Parallelism in julia","title":"MPSKit multithreading","text":"","category":"section"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"Within MPSKit, when Julia is started with multiple threads, by default the OhMyThreads.jl machinery will be used to parallelize the code as much as possible. In particular, this mostly occurs whenever there is a unitcell and local updates can take place at each site in parallel.","category":"page"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"The multithreading behaviour can be controlled through a global scheduler, which can be set using the MPSKit.Defaults.set_scheduler!(arg; kwargs...) function. This function accepts either a Symbol, an OhMyThreads.Scheduler or keywords to determine a scheduler automatically.","category":"page"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"MPSKit.Defaults.set_scheduler!(:serial) # disable multithreading\nMPSKit.Defaults.set_scheduler!(:greedy) # multithreading with greedy load-balancing\nMPSKit.Defaults.set_scheduler!(:dynamic) # default: multithreading with some load-balancing","category":"page"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"For further reference on the available schedulers and finer control, please refer to the OhMyThreads.jl documentation","category":"page"},{"location":"man/parallelism/#TensorKit-multithreading","page":"Parallelism in julia","title":"TensorKit multithreading","text":"","category":"section"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"Finally, when dealing with tensors that have some internal symmetry, it is also possible to parallelize over the symmetry sectors. This is handled by TensorKit, and more information can be found in its documentation (Soon TM).","category":"page"},{"location":"man/parallelism/#Memory-management","page":"Parallelism in julia","title":"Memory management","text":"","category":"section"},{"location":"man/parallelism/","page":"Parallelism in julia","title":"Parallelism in julia","text":"Because of the way julia threads work, it is possible that the total memory usage of your program becomes rather high. This seems to be because of the fact that MPSKit spawns several tasks (in a nested way), which each allocate and deallocate quite a bit of memory in a tight loop. This seems to lead to a situation where the garbage collector is not able to keep up, and can even fail to clear the garbage before an OutOfMemory error occurs. In this case, often the best thing to do is disable the multithreading of MPSKit, specifically for the derivatives, as this seems to be the most memory intensive part. This is something that is under investigation, and hopefully will be fixed in the future.","category":"page"},{"location":"man/environments/#um_environments","page":"Environments","title":"Environments","text":"","category":"section"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"In many tensor network algorithms we encounter partially contracted tensor networks. In DMRG for example, one needs to know the sum of all the hamiltonian contributions left and right of the site that we want to optimize. If you then optimize the neighboring site to the right, you only need to add one new contribution to the previous sum of hamiltonian contributions.","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"This kind of information is stored in the environment objects. The goal is that the user should preferably never have to deal with these objects, but being aware of the inner workings may allow you to write more efficient code. That is why they are nonetheless included in the manual.","category":"page"},{"location":"man/environments/#Finite-Environments","page":"Environments","title":"Finite Environments","text":"","category":"section"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"When you create a state and a hamiltonian:","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"state = FiniteMPS(rand, ComplexF64, 20, ℂ^2, ℂ^10);\noperator = nonsym_ising_ham();","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"an environment object can be created by calling","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"envs = environments(state, operator)","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"The partially contracted mpohamiltonian left of site i can then be queried using:","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"@time leftenv(envs, i, state)","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"This may take some time, but a subsequent call should be a lot quicker","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"@time leftenv(envs, i - 1, state)","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"Behind the scenes the envs stored all tensors it used to calculate leftenv (state.AL[1 .. i]) and when queried again, it checks if the tensors it previously used are identical (using ===). If so, it can simply return the previously stored results. If not, it will recalculate again. If you update a tensor in-place, the caches cannot know using === that the actual tensors have changed. If you do this, you have to call poison!(state,i).","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"As an optional argument, many algorithms allow you to pass in an environment object, and they also return an updated one. Therefore, for time evolution code, it is more efficient to give it the updated caches every time step, instead of letting it recalculate.","category":"page"},{"location":"man/environments/#Infinite-Environments","page":"Environments","title":"Infinite Environments","text":"","category":"section"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"Infinite Environments are very similar :","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"state = InfiniteMPS(ℂ^2, ℂ^10)\noperator = transverse_field_ising()\nenvs = environments(state, operator)","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"There are also some notable differences. Infinite environments typically require solving linear problems or eigenvalue problems iteratively with finite precision. To find out what precision we used we can type:","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"(cache.tol,cache.maxiter)","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"To recalculate with a different precision :","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"cache.tol=1e-8;\nrecalculate!(cache,state)","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"Unlike their finite counterparts, recalculating is not done automatically. To get the environment for a different state one has to recalculate explicitly!","category":"page"},{"location":"man/environments/","page":"Environments","title":"Environments","text":"different_state = InfiniteMPS([ℂ^2],[ℂ^10]);\nrecalculate!(cache,different_state)\nleftenv(cache,3,different_state)","category":"page"},{"location":"examples/#Examples","page":"Examples","title":"Examples","text":"","category":"section"},{"location":"examples/#Quantum-(11)d","page":"Examples","title":"Quantum (1+1)d","text":"","category":"section"},{"location":"examples/","page":"Examples","title":"Examples","text":"Pages = map(file -> joinpath(\"quantum1d\", file, \"index.md\"), readdir(\"quantum1d\"))\nDepth = 1","category":"page"},{"location":"examples/#Classical-(20)d","page":"Examples","title":"Classical (2+0)d","text":"","category":"section"},{"location":"examples/","page":"Examples","title":"Examples","text":"Pages = map(file -> joinpath(\"classic2d\", file, \"index.md\"), readdir(\"classic2d\"))\nDepth = 1","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"EditURL = \"../../../../../examples/classic2d/1.hard-hexagon/main.jl\"","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"(Image: ) (Image: ) (Image: )","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/#demo_hardhexagon","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"","category":"section"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"(Image: logo)","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"Tensor networks are a natural way to do statistical mechanics on a lattice. As an example of this we will extract the central charge of the hard hexagon model. This model is known to have central charge 0.8, and has very peculiar non-local (anyonic) symmetries. Because TensorKit supports anyonic symmetries, so does MPSKit. To follow the tutorial you need the following packages.","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"using MPSKit, MPSKitModels, TensorKit, Plots, Polynomials","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"The hard hexagon model is a 2-dimensional lattice model of a gas, where particles are allowed to be on the vertices of a triangular lattice, but no two particles may be adjacent. This can be encoded in a transfer matrix with a local MPO tensor using anyonic symmetries, and the resulting MPO has been implemented in MPSKitModels.","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"In order to use these anyonic symmetries, we need to generalise the notion of the bond dimension and define how it interacts with the symmetry. Thus, we implement away of converting integers to symmetric spaces of the given dimension, which provides a crude guess for how the final MPS would distribute its Schmidt spectrum.","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"mpo = hard_hexagon()\nP = physicalspace(mpo, 1)\nfunction virtual_space(D::Integer)\n _D = round(Int, D / sum(dim, values(FibonacciAnyon)))\n return Vect[FibonacciAnyon](sector => _D for sector in (:I, :τ))\nend\n\n@assert isapprox(dim(virtual_space(100)), 100; atol=3)","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/#The-leading-boundary","page":"The Hard Hexagon model","title":"The leading boundary","text":"","category":"section"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"One way to study statistical mechanics in infinite systems with tensor networks is by approximating the dominant eigenvector of the transfer matrix by an MPS. This dominant eigenvector contains a lot of hidden information. For example, the free energy can be extracted by computing the expectation value of the mpo. Additionally, we can compute the entanglement entropy as well as the correlation length of the state:","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"D = 10\nV = virtual_space(D)\nψ₀ = InfiniteMPS([P], [V])\nψ, envs, = leading_boundary(ψ₀, mpo,\n VUMPS(; verbosity=0,\n alg_eigsolve=MPSKit.Defaults.alg_eigsolve(;\n ishermitian=false))) # use non-hermitian eigensolver\nF = real(expectation_value(ψ, mpo))\nS = real(first(entropy(ψ)))\nξ = correlation_length(ψ)\nprintln(\"F = $F\\tS = $S\\tξ = $ξ\")","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"F = 0.8839037051703851\tS = 1.280782962183673\tξ = 13.849682581369715\n","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/#The-scaling-hypothesis","page":"The Hard Hexagon model","title":"The scaling hypothesis","text":"","category":"section"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"The dominant eigenvector is of course only an approximation. The finite bond dimension enforces a finite correlation length, which effectively introduces a length scale in the system. This can be exploited to formulate a scaling hypothesis (Pollmann et al., 2009), which in turn allows to extract the central charge.","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"First we need to know the entropy and correlation length at a bunch of different bond dimensions. Our approach will be to re-use the previous approximated dominant eigenvector, and then expanding its bond dimension and re-running VUMPS. According to the scaling hypothesis we should have S propto fracc6 log(ξ). Therefore we should find c using","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"function scaling_simulations(ψ₀, mpo, Ds; verbosity=0, tol=1e-6,\n alg_eigsolve=MPSKit.Defaults.alg_eigsolve(; ishermitian=false))\n entropies = similar(Ds, Float64)\n correlations = similar(Ds, Float64)\n alg = VUMPS(; verbosity, tol, alg_eigsolve)\n\n ψ, envs, = leading_boundary(ψ₀, mpo, alg)\n entropies[1] = real(entropy(ψ)[1])\n correlations[1] = correlation_length(ψ)\n\n for (i, d) in enumerate(diff(Ds))\n ψ, envs = changebonds(ψ, mpo, OptimalExpand(; trscheme=truncdim(d)), envs)\n ψ, envs, = leading_boundary(ψ, mpo, alg, envs)\n entropies[i + 1] = real(entropy(ψ)[1])\n correlations[i + 1] = correlation_length(ψ)\n end\n return entropies, correlations\nend\n\nbond_dimensions = 10:5:25\nψ₀ = InfiniteMPS([P], [virtual_space(bond_dimensions[1])])\nSs, ξs = scaling_simulations(ψ₀, mpo, bond_dimensions)\n\nf = fit(log.(ξs), 6 * Ss, 1)\nc = f.coeffs[2]","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"0.8025216556799167","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"p = plot(; xlabel=\"logarithmic correlation length\", ylabel=\"entanglement entropy\")\np = plot(log.(ξs), Ss; seriestype=:scatter, label=nothing)\nplot!(p, ξ -> f(ξ) / 6; label=\"fit\")","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"","category":"page"},{"location":"examples/classic2d/1.hard-hexagon/","page":"The Hard Hexagon model","title":"The Hard Hexagon model","text":"This page was generated using Literate.jl.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"EditURL = \"../../../../../examples/quantum1d/5.haldane-spt/main.jl\"","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"(Image: ) (Image: ) (Image: )","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/#spin1heisenberg","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"","category":"section"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"The quantum Heisenberg model is a model often used in the study of critical points and phase transitions of magnetic systems, in which the spins are treated quantum mechanically. It models magnetic interactions between neighbouring spins through the so-called Heisenberg interaction term, which causes the spins to either align (J 0) or anti-align (J 0), thus modeling a (anti-) ferromagnetic system. Here, we will focus on the case of S = 1, with anti-ferromagnetic interactions.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"H = -J sum_langle i j rangle vecS_i cdot vecS_j","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"Importantly, the Hamiltonian of the isotropic model is invariant under SU(2) rotations, which can be exploited to increase efficiency, as well as interpretability of the MPS simulations. To see this, we can make use of the following derivation for the interaction term:","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"(vecS_i + vecS_j)^2 = vecS_i^2 + 2 vecS_i cdot vecS_j + vecS_j^2\nimplies vecS_i cdot vecS_j = frac12 left( (vecS_i + vecS_j)^2 - vecS_i^2 - vecS_j^2 right)","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"Here, we recognize the quadratic Casimir element vecS^2, which commutes with the elements of SU(2). Consequently, the Hamiltonian also commutes with all elements of SU(2).","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"using TensorKit\nusing MPSKit\nusing Plots\n\ncasimir(s::SU2Irrep) = s.j * (s.j + 1)\n\nfunction heisenberg_hamiltonian(; J=-1.0)\n s = SU2Irrep(1)\n ℋ = SU2Space(1 => 1)\n SS = zeros(ComplexF64, ℋ ⊗ ℋ ← ℋ ⊗ ℋ)\n for (S, data) in blocks(SS)\n data .= -0.5J * (casimir(S) - casimir(s) - casimir(s))\n end\n return InfiniteMPOHamiltonian(SS)\nend\nH = heisenberg_hamiltonian()","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"single site InfiniteMPOHamiltonian{BlockTensorKit.SparseBlockTensorMap{TensorKit.AbstractTensorMap{ComplexF64, TensorKit.GradedSpace{TensorKitSectors.SU2Irrep, TensorKit.SortedVectorDict{TensorKitSectors.SU2Irrep, Int64}}, 2, 2}, ComplexF64, TensorKit.GradedSpace{TensorKitSectors.SU2Irrep, TensorKit.SortedVectorDict{TensorKitSectors.SU2Irrep, Int64}}, 2, 2, 4}}:\n╷ ⋮\n┼ W[1]: 3×1×1×3 SparseBlockTensorMap(((Rep[SU₂](0=>1) ⊕ Rep[SU₂](1=>1) ⊕ Rep[SU₂](0=>1)) ⊗ ⊕(Rep[SU₂](1=>1))) ← (⊕(Rep[SU₂](1=>1)) ⊗ (Rep[SU₂](0=>1) ⊕ Rep[SU₂](1=>1) ⊕ Rep[SU₂](0=>1))))\n╵ ⋮\n","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/#Symmetry-Protected-Topological-Order","page":"Spin 1 Heisenberg model","title":"Symmetry-Protected Topological Order","text":"","category":"section"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"The representations of SU(2) possess additional structure, known as a mathbbZ_2-grading. This means, that they can be partitioned in integer (+) and half-integer (-) spins, and the fusion rules will respect this grading. In other words, the following table holds:","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"s_1 s_2 s_1 otimes s_2\n+ + +\n+ - -\n- + -\n- - +","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"This has important consequences for the MPS representation of an SU(2)-symmetric state. If the physical spin consists of only integer representations, this means that the left and right virtual spaces of the MPS tensor belong to the same grading, i.e. are either both integer, or both half-integer. Thus, naively constructing a MPS tensor which contains spins from both classes, will necessarily be the direct sum of the two, which yields a non-injective MPS.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"ketpsi = ketpsi_+ oplus ketpsi_-","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"Because of this direct sum, many of the usual MPS algorithms will fail, as they typically cannot deal with non-injective MPS. The resulting MPS will have multiple values of the transfer matrix spectrum that have a magnitude close to 1, which is a clear sign of a non-injective MPS.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"ℋ = SU2Space(1 => 1)\nV_wrong = SU2Space(0 => 8, 1 // 2 => 8, 1 => 3, 3 // 2 => 3)\nψ = InfiniteMPS(ℋ, V_wrong)\nψ, environments, δ = find_groundstate(ψ, H, VUMPS(; maxiter=10))\nsectors = SU2Irrep[0, 1 // 2, 1, 3 // 2]\ntransferplot(ψ; sectors, title=\"Transfer matrix spectrum\", legend=:outertop)","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"Nevertheless, using the symmetry, this can be remedied rather easily, by imposing the groundstate to belong to a single class, and comparing the results. We can readily obtain 3 different criteria for determining the SPT phase of the groundstate.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"Firstly, we can compare variational energies for states of similar bond dimensions. As we expect the state of the wrong SPT phase to have to expend some of its expressiveness in correcting the SPT, it should have a harder time reaching lower energies.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"Secondly, when inspecting the spectrum of the transfer matrix, we should see that the wrong SPT phase has a dominant value that is not in the trivial sector, which leads to a non-injective MPS.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"Finally, the entanglement spectrum of the wrong SPT phase will show degeneracies of all singular values, which can again be attributed to an attempt to mimick the spectrum of the right SPT phase.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"V_plus = SU2Space(0 => 10, 1 => 5, 2 => 3)\nψ_plus = InfiniteMPS(ℋ, V_plus)\nψ_plus, = find_groundstate(ψ_plus, H, VUMPS(; maxiter=100))\nE_plus = expectation_value(ψ_plus, H)","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"-1.4014193313393006 - 2.039461603293807e-17im","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"V_minus = SU2Space(1 // 2 => 10, 3 // 2 => 5, 5 // 2 => 3)\nψ_minus = InfiniteMPS(ℋ, V_minus)\nψ_minus, = find_groundstate(ψ_minus, H, VUMPS(; maxiter=100))\nE_minus = expectation_value(ψ_minus, H)","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"-1.4014839739630813 + 7.825406802551059e-17im","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"transferp_plus = transferplot(ψ_plus; sectors=SU2Irrep[0, 1, 2], title=\"ψ_plus\",\n legend=:outertop)\ntransferp_minus = transferplot(ψ_minus; sectors=SU2Irrep[0, 1, 2], title=\"ψ_minus\",\n legend=:outertop)\nplot(transferp_plus, transferp_minus; layout=(1, 2), size=(800, 400))","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"entanglementp_plus = entanglementplot(ψ_plus; title=\"ψ_plus\", legend=:outertop)\nentanglementp_minus = entanglementplot(ψ_minus; title=\"ψ_minus\", legend=:outertop)\nplot(entanglementp_plus, entanglementp_minus; layout=(1, 2), size=(800, 400))","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"As we can see, the groundstate can be found in the non-trivial SPT phase, ketpsi_-. We can obtain an intuitive understanding of ketpsi_+ by considering the following diagram. If we denote the MPS tensors that make up the groundstate as A_-, we can construct a state in the trivial SPT phase that approximates the groundstate as follows:","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"(Image: spt-tensors.svg)","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"In other words, we can factorize a purely virtual isomorphism of S = 12 in order to obtain the groundstate. This then also explains the degeneracies in the entanglement spectrum as well as in the transfer matrix spectrum. Finally, we can further confirm this intuition by looking at the entanglement entropy of the groundstate. As we can see, the entanglement entropy of the state in the wrong SPT phase is exactly log(2) higher than the one in the right SPT phase, which is exactly what we would expect from the diagram above.","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"S_minus = sum(real, entropy(ψ_minus))\nS_plus = sum(real, entropy(ψ_plus))\nprintln(\"S_minus + log(2) = $(S_minus + log(2))\")\nprintln(\"S_plus = $S_plus\")","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"S_minus + log(2) = 1.0155125212288219\nS_plus = 0.7327304247852098\n","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"","category":"page"},{"location":"examples/quantum1d/5.haldane-spt/","page":"Spin 1 Heisenberg model","title":"Spin 1 Heisenberg model","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/states/#um_states","page":"States","title":"States","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"using MPSKit\nusing TensorKit\nusing LinearAlgebra: dot","category":"page"},{"location":"man/states/#FiniteMPS","page":"States","title":"FiniteMPS","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"A FiniteMPS is - at its core - a chain of mps tensors.","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"(Image: )","category":"page"},{"location":"man/states/#Usage","page":"States","title":"Usage","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"A FiniteMPS can be created by passing in a vector of tensormaps:","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"L = 10\ndata = [rand(ComplexF64, ℂ^1 ⊗ ℂ^2 ← ℂ^1) for _ in 1:L];\nstate = FiniteMPS(data)","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"Or alternatively by specifying its structure","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"max_bond_dimension = ℂ^4\nphysical_space = ℂ^2\nstate = FiniteMPS(rand, ComplexF64, L, physical_space, max_bond_dimension)","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"You can take dot products, renormalize!, expectation values,....","category":"page"},{"location":"man/states/#Gauging-and-canonical-forms","page":"States","title":"Gauging and canonical forms","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"An MPS representation is not unique: for every virtual bond we can insert C cdot C^-1 without altering the state. Then, by redefining the tensors on both sides of the bond to include one factor each, we can change the representation.","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"(Image: )","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"There are two particularly convenient choices for the gauge at a site, the so-called left and right canonical form. For the left canonical form, all tensors to the left of a site are gauged such that they become left-isometries. By convention, we call these tensors AL.","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"al = state.AL[3]\nal' * al ≈ id(right_virtualspace(al))","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"Similarly, the right canonical form turns the tensors into right-isometries. By convention, these are called AR.","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"ar = state.AR[3]\nrepartition(ar, 1, 2) * repartition(ar, 1, 2)' ≈ id(left_virtualspace(ar))","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"It is also possible to mix and match these two forms, where all tensors to the left of a given site are in the left gauge, while all tensors to the right are in the right gauge. In this case, the final gauge transformation tensor can no longer be absorbed, since that would spoil the gauge either to the left or the right. This center-gauged tensor is called C, which is also the gauge transformation to relate left- and right-gauged tensors. Finally, for convenience it is also possible to leave a single MPS tensor in the center gauge, which we call AC = AL * C","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"c = state.C[3] # to the right of site 3\nc′ = state.C[2] # to the left of site 3\nal * c ≈ state.AC[3] ≈ repartition(c′ * repartition(ar, 1, 2), 2, 1)","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"These forms are often used throughout MPS algorithms, and the FiniteMPS object acts as an automatic manager for this. It will automatically compute and cache the different forms, and detect when to recompute whenever needed. For example, in order to compute the overlap of an MPS with itself, we can choose any site and bring that into the center gauge. Since then both the left and right side simplify to the identity, this simply becomes the overlap of the gauge tensors:","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"d = dot(state, state)\nall(c -> dot(c, c) ≈ d, state.C)","category":"page"},{"location":"man/states/#Implementation-details","page":"States","title":"Implementation details","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"Behind the scenes, a FiniteMPS has 4 fields","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"ALs::Vector{Union{Missing,A}}\nARs::Vector{Union{Missing,A}}\nACs::Vector{Union{Missing,A}}\nCs::Vector{Union{Missing,B}}","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"and calling AL, AR, C or AC returns lazy views over these vectors that instantiate the tensors whenever they are requested. Similarly, changing a tensor will poison the ARs to the left of that tensor, and the ALs to the right. The idea behind this construction is that one never has to worry about how the state is gauged, as this gets handled automagically.","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"warning: Warning\nWhile a FiniteMPS can automatically detect when to recompute the different gauges, this requires that one of the tensors is set using an indexing operation. In particular, in-place changes to the different tensors will not trigger the recomputation.","category":"page"},{"location":"man/states/#InfiniteMPS","page":"States","title":"InfiniteMPS","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"An InfiniteMPS can be thought of as being very similar to a finite mps, where the set of tensors is repeated periodically.","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"It can also be created by passing in a vector of TensorMaps:","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"data = [rand(ComplexF64, ℂ^4 ⊗ ℂ^2 ← ℂ^4) for _ in 1:2]\nstate = InfiniteMPS(data)","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"or by initializing it from given spaces","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"phys_spaces = fill(ℂ^2, 2)\nvirt_spaces = [ℂ^4, ℂ^5] # by convention to the right of a site\nstate = InfiniteMPS(phys_spaces, virt_spaces)","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"Note that the code above creates an InfiniteMPS with a two-site unit cell, where the given virtual spaces are located to the right of their respective sites.","category":"page"},{"location":"man/states/#Gauging-and-canonical-forms-2","page":"States","title":"Gauging and canonical forms","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"Much like for FiniteMPS, we can again query the gauged tensors AL, AR, C and AC. Here however, the implementation is much easier, since they all have to be recomputed whenever a single tensor changes. This is a result of periodically repeating the tensors, every AL is to the right of the changed site, and every AR is to the left. As a result, the fields are simply","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"AL::PeriodicArray{A,1}\nAR::PeriodicArray{A,1}\nC::PeriodicArray{B,1}\nAC::PeriodicArray{A,1}","category":"page"},{"location":"man/states/#WindowMPS","page":"States","title":"WindowMPS","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"A WindowMPS or segment MPS can be seen as a mix between an InfiniteMPS and a FiniteMPS. It represents a window of mutable tensors (a finite MPS), embedded in an infinite environment (two infinite MPSs). It can therefore be created accordingly, ensuring that the edges match:","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"infinite_state = InfiniteMPS(ℂ^2, ℂ^4)\nfinite_state = FiniteMPS(5, ℂ^2, ℂ^4; left=ℂ^4, right=ℂ^4)\nwindow = WindowMPS(infinite_state, finite_state, infinite_state)","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"Algorithms will then act on this window of tensors, while leaving the left and right infinite states invariant.","category":"page"},{"location":"man/states/#MultilineMPS","page":"States","title":"MultilineMPS","text":"","category":"section"},{"location":"man/states/","page":"States","title":"States","text":"A two-dimensional classical partition function can often be represented by an infinite tensor network. There are many ways to evaluate such a network, but here we focus on the so-called boundary MPS methods. These first reduce the problem from contracting a two-dimensional network to the contraction of a one-dimensional MPS, by finding the fixed point of the row-to-row (or column-to-column) transfer matrix. In these cases however, there might be a non-trivial periodicity in both the horizontal as well as vertical direction. Therefore, in MPSKit they are represented by MultilineMPS, which are simply a repeating set of InfiniteMPS.","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"state = MultilineMPS(fill(infinite_state, 2))","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"They offer some convenience functionality for using cartesian indexing (row - column):","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"You can access properties by calling","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"row = 2\ncol = 2\nal = state.AL[row, col];","category":"page"},{"location":"man/states/","page":"States","title":"States","text":"These objects are also used extensively in the context of PEPSKit.jl.","category":"page"},{"location":"man/intro/#Prerequisites","page":"Prerequisites","title":"Prerequisites","text":"","category":"section"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"The following sections describe the prerequisites for using MPSKit. If you are already familiar with the concepts of MPSKit and TensorKit, you can skip to the Conventions sections.","category":"page"},{"location":"man/intro/#TensorKit","page":"Prerequisites","title":"TensorKit","text":"","category":"section"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"using TensorKit","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"MPSKit uses the tensors defined in TensorKit.jl as its underlying data structure. This is what allows the library to be generic with respect to the symmetry of the tensors. The main difference with regular multi-dimensional arrays is the notion of a partition of the dimensions in incoming and outgoing, which are respectively called domain and codomain. In other words, a TensorMap can be interpreted as a linear map from its domain to its codomain. Additionally, as generic symmetries are supported, in general the structure of the indices are not just integers, but are given by spaces.","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"The general syntax for creating a tensor is similar to the creation of arrays, where the axes or size specifiers are replaced with VectorSpace objects:","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"zeros(scalartype, codomain, domain)\nrand(scalartype, codomain ← domain) # ← is the `\\leftarrow` operator","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"For example, the following creates a random tensor with three legs, each of which has dimension two, however with different partitions.","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"V1 = ℂ^2 # ℂ is the `\\bbC` operator, equivalent to ComplexSpace(10)\nt1 = rand(Float64, V1 ⊗ V1 ⊗ V1) # all spaces in codomain\nt2 = rand(Float64, V1, V1 ⊗ V1) # one space in codomain, two in domain","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"We can now no longer trivially add them together:","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"try #hide\nt1 + t2 # incompatible partition\ncatch err; Base.showerror(stderr, err); end #hide","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"But this can be resolved by permutation:","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"try #hide\nt1 + permute(t2, (1, 2, 3), ()) # incompatible arrows\ncatch err; Base.showerror(stderr, err); end #hide","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"These abstract objects can represent not only plain arrays but also symmetric tensors. The following creates a symmetric tensor with ℤ₂ symmetry, again with three legs of dimension two. However, now the dimension two is now split over even and odd sectors of ℤ₂.","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"V2 = Z2Space(0 => 1, 1 => 1)\nt3 = rand(Float64, V2 ⊗ V2, V2)","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"For more information, check out the TensorKit documentation!","category":"page"},{"location":"man/intro/#Conventions","page":"Prerequisites","title":"Conventions","text":"","category":"section"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"The general definition of an MPS tensor is as follows:","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"(Image: convention MPSTensor)","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"These tensors are allowed to have an arbitrary number of physical legs, and both FiniteMPS as well as InfiniteMPS will be able to handle the resulting objects. This allows for example for the definition of boundary tensors in PEPS code, which have two physical legs.","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"Similarly, the definition of a bond tensor, appearing in between two MPS tensors, is as follows:","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"(Image: convention BondTensor)","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"Finally, the definition of a MPO tensor, which is used to represent statistical mechanics problems as well as quantum hamiltonians, is represented as:","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"(Image: convention MPOTensor)","category":"page"},{"location":"man/intro/","page":"Prerequisites","title":"Prerequisites","text":"While this results at first glance in the not very intuitive ordering of spaces as V_l otimes P leftarrow P otimes V_r, this is actually the most natural ordering for keeping the algorithms planar. In particular, this is relevant for dealing with fermionic systems, where additional crossings would lead to sign problems.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"EditURL = \"../../../../../examples/quantum1d/4.xxz-heisenberg/main.jl\"","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"(Image: ) (Image: ) (Image: )","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/#The-XXZ-model","page":"The XXZ model","title":"The XXZ model","text":"","category":"section"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"In this file we will give step by step instructions on how to analyze the spin 1/2 XXZ model. The necessary packages to follow this tutorial are:","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"using MPSKit, MPSKitModels, TensorKit, Plots","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/#Failure","page":"The XXZ model","title":"Failure","text":"","category":"section"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"First we should define the hamiltonian we want to work with. Then we specify an initial guess, which we then further optimize. Working directly in the thermodynamic limit, this is achieved as follows:","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"H = heisenberg_XXX(; spin=1 // 2)","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"single site InfiniteMPOHamiltonian{BlockTensorKit.SparseBlockTensorMap{TensorKit.AbstractTensorMap{ComplexF64, TensorKit.ComplexSpace, 2, 2}, ComplexF64, TensorKit.ComplexSpace, 2, 2, 4}}:\n╷ ⋮\n┼ W[1]: 3×1×1×3 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^3 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^3 ⊕ ℂ^1)))\n╵ ⋮\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"We then need an intial state, which we shall later optimize. In this example we work directly in the thermodynamic limit.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"state = InfiniteMPS(2, 20)","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"single site InfiniteMPS:\n│ ⋮\n│ C[1]: TensorMap(ℂ^20 ← ℂ^20)\n├── AL[1]: TensorMap((ℂ^20 ⊗ ℂ^2) ← ℂ^20)\n│ ⋮\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"The groundstate can then be found by calling find_groundstate.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"groundstate, cache, delta = find_groundstate(state, H, VUMPS());","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"[ Info: VUMPS init:\tobj = +2.499932270895e-01\terr = 7.3488e-03\n[ Info: VUMPS 1:\tobj = -2.684294662883e-01\terr = 3.4887991618e-01\ttime = 0.04 sec\n[ Info: VUMPS 2:\tobj = -3.908732509075e-01\terr = 2.4346308901e-01\ttime = 0.09 sec\n[ Info: VUMPS 3:\tobj = -4.103272462718e-01\terr = 2.2211707874e-01\ttime = 0.04 sec\n[ Info: VUMPS 4:\tobj = +2.763771623319e-02\terr = 4.0601070717e-01\ttime = 0.06 sec\n[ Info: VUMPS 5:\tobj = -1.278912388343e-01\terr = 4.0024753668e-01\ttime = 0.04 sec\n[ Info: VUMPS 6:\tobj = -6.128684560655e-02\terr = 3.9554377744e-01\ttime = 0.05 sec\n[ Info: VUMPS 7:\tobj = -2.019229524257e-01\terr = 3.9507954388e-01\ttime = 0.03 sec\n[ Info: VUMPS 8:\tobj = -3.385836978728e-01\terr = 3.1206810658e-01\ttime = 0.06 sec\n[ Info: VUMPS 9:\tobj = -4.217712628117e-01\terr = 1.9266010859e-01\ttime = 0.05 sec\n[ Info: VUMPS 10:\tobj = +3.119439956568e-02\terr = 4.0307569557e-01\ttime = 0.05 sec\n[ Info: VUMPS 11:\tobj = -1.453987450329e-01\terr = 3.7892383130e-01\ttime = 0.03 sec\n[ Info: VUMPS 12:\tobj = -3.122541983387e-01\terr = 3.4361928372e-01\ttime = 0.05 sec\n[ Info: VUMPS 13:\tobj = -3.175415058698e-01\terr = 3.4372788072e-01\ttime = 0.06 sec\n[ Info: VUMPS 14:\tobj = -9.281281368249e-02\terr = 3.8082690832e-01\ttime = 0.04 sec\n[ Info: VUMPS 15:\tobj = -1.118289260232e-01\terr = 3.9703529501e-01\ttime = 0.04 sec\n[ Info: VUMPS 16:\tobj = -3.392299177529e-02\terr = 3.8653278445e-01\ttime = 0.04 sec\n[ Info: VUMPS 17:\tobj = -8.859386904872e-02\terr = 3.7559265639e-01\ttime = 0.06 sec\n[ Info: VUMPS 18:\tobj = -2.660652072169e-01\terr = 3.4535690909e-01\ttime = 0.06 sec\n[ Info: VUMPS 19:\tobj = +1.581362017845e-01\terr = 3.6728199421e-01\ttime = 0.02 sec\n[ Info: VUMPS 20:\tobj = -2.614275413781e-03\terr = 3.5210479173e-01\ttime = 0.04 sec\n[ Info: VUMPS 21:\tobj = -1.404557974268e-01\terr = 3.8727147114e-01\ttime = 0.02 sec\n[ Info: VUMPS 22:\tobj = -1.922542821356e-01\terr = 3.6768505428e-01\ttime = 0.05 sec\n[ Info: VUMPS 23:\tobj = +8.174391358782e-02\terr = 3.9158252120e-01\ttime = 0.02 sec\n[ Info: VUMPS 24:\tobj = +4.347184217158e-02\terr = 3.3940461711e-01\ttime = 0.05 sec\n[ Info: VUMPS 25:\tobj = -2.122928828839e-01\terr = 3.6816674483e-01\ttime = 0.02 sec\n[ Info: VUMPS 26:\tobj = -3.750381325917e-02\terr = 4.4510656286e-01\ttime = 0.06 sec\n[ Info: VUMPS 27:\tobj = -9.698985317742e-02\terr = 4.0266067497e-01\ttime = 0.05 sec\n[ Info: VUMPS 28:\tobj = -2.160914808205e-01\terr = 3.6590508687e-01\ttime = 0.03 sec\n[ Info: VUMPS 29:\tobj = +4.936490579149e-02\terr = 3.7234044270e-01\ttime = 0.05 sec\n[ Info: VUMPS 30:\tobj = -1.148676233851e-01\terr = 4.1462641635e-01\ttime = 0.02 sec\n[ Info: VUMPS 31:\tobj = -1.519618595135e-01\terr = 3.7492975708e-01\ttime = 0.05 sec\n[ Info: VUMPS 32:\tobj = -1.890862522082e-01\terr = 3.7659388392e-01\ttime = 0.03 sec\n[ Info: VUMPS 33:\tobj = -7.477276890967e-02\terr = 3.9194272124e-01\ttime = 0.05 sec\n[ Info: VUMPS 34:\tobj = -1.940989007410e-01\terr = 3.9403330192e-01\ttime = 0.03 sec\n[ Info: VUMPS 35:\tobj = -3.502934869819e-01\terr = 3.0111969128e-01\ttime = 0.05 sec\n[ Info: VUMPS 36:\tobj = -3.442085541276e-01\terr = 3.2611257359e-01\ttime = 0.04 sec\n[ Info: VUMPS 37:\tobj = -2.312483202161e-01\terr = 3.7396977836e-01\ttime = 0.06 sec\n[ Info: VUMPS 38:\tobj = -2.282920202884e-01\terr = 3.5801388290e-01\ttime = 0.06 sec\n[ Info: VUMPS 39:\tobj = -3.434233746212e-01\terr = 3.3005413456e-01\ttime = 0.05 sec\n[ Info: VUMPS 40:\tobj = -3.700311228608e-01\terr = 2.8698807789e-01\ttime = 0.05 sec\n[ Info: VUMPS 41:\tobj = -2.287419146432e-01\terr = 3.7652136991e-01\ttime = 0.08 sec\n[ Info: VUMPS 42:\tobj = -1.848386897474e-01\terr = 3.9410789712e-01\ttime = 0.07 sec\n[ Info: VUMPS 43:\tobj = -4.151049475911e-02\terr = 3.6614428192e-01\ttime = 0.04 sec\n[ Info: VUMPS 44:\tobj = +4.278404791371e-02\terr = 3.8999971963e-01\ttime = 0.06 sec\n[ Info: VUMPS 45:\tobj = +4.133615949384e-02\terr = 3.7259192609e-01\ttime = 0.04 sec\n[ Info: VUMPS 46:\tobj = -1.755417704686e-01\terr = 3.8281160487e-01\ttime = 0.06 sec\n[ Info: VUMPS 47:\tobj = -3.433301511715e-01\terr = 3.1797681990e-01\ttime = 0.03 sec\n[ Info: VUMPS 48:\tobj = +8.038768523644e-02\terr = 3.5190647487e-01\ttime = 0.05 sec\n[ Info: VUMPS 49:\tobj = -6.209071290954e-02\terr = 3.4368443495e-01\ttime = 0.07 sec\n[ Info: VUMPS 50:\tobj = +1.373233695943e-01\terr = 3.4584780766e-01\ttime = 0.04 sec\n[ Info: VUMPS 51:\tobj = -1.298395809866e-02\terr = 3.7394444037e-01\ttime = 0.06 sec\n[ Info: VUMPS 52:\tobj = -1.849662152303e-01\terr = 4.0186739319e-01\ttime = 0.04 sec\n[ Info: VUMPS 53:\tobj = -2.535592561522e-01\terr = 3.6315928824e-01\ttime = 0.05 sec\n[ Info: VUMPS 54:\tobj = -2.078073506292e-01\terr = 3.8862703529e-01\ttime = 0.03 sec\n[ Info: VUMPS 55:\tobj = -2.648807481312e-01\terr = 3.5935081624e-01\ttime = 0.05 sec\n[ Info: VUMPS 56:\tobj = +3.508321588679e-02\terr = 3.5155300157e-01\ttime = 0.06 sec\n[ Info: VUMPS 57:\tobj = +2.587094014595e-02\terr = 3.7426723561e-01\ttime = 0.05 sec\n[ Info: VUMPS 58:\tobj = +6.099768411641e-02\terr = 3.6261231989e-01\ttime = 0.06 sec\n[ Info: VUMPS 59:\tobj = +6.085060881519e-02\terr = 3.5718570541e-01\ttime = 0.02 sec\n[ Info: VUMPS 60:\tobj = -4.856039331256e-02\terr = 3.9347118222e-01\ttime = 0.06 sec\n[ Info: VUMPS 61:\tobj = -5.072268826867e-02\terr = 3.8271040330e-01\ttime = 0.04 sec\n[ Info: VUMPS 62:\tobj = +1.769142598093e-02\terr = 4.0183932016e-01\ttime = 0.05 sec\n[ Info: VUMPS 63:\tobj = +5.913223876388e-02\terr = 4.0964563195e-01\ttime = 0.06 sec\n[ Info: VUMPS 64:\tobj = -2.478892754727e-01\terr = 3.8032380630e-01\ttime = 0.04 sec\n[ Info: VUMPS 65:\tobj = -3.071655369627e-01\terr = 3.4522086404e-01\ttime = 0.05 sec\n[ Info: VUMPS 66:\tobj = -3.204977019062e-01\terr = 3.2905910740e-01\ttime = 0.05 sec\n[ Info: VUMPS 67:\tobj = -2.546816866134e-01\terr = 3.8561093133e-01\ttime = 0.07 sec\n[ Info: VUMPS 68:\tobj = -2.393554685021e-01\terr = 3.5880361408e-01\ttime = 0.05 sec\n[ Info: VUMPS 69:\tobj = -1.327133696952e-01\terr = 4.0101733932e-01\ttime = 0.06 sec\n[ Info: VUMPS 70:\tobj = -1.041902383608e-01\terr = 4.1285042628e-01\ttime = 0.05 sec\n[ Info: VUMPS 71:\tobj = -1.993915263334e-01\terr = 3.6003918734e-01\ttime = 0.04 sec\n[ Info: VUMPS 72:\tobj = -1.940520154241e-01\terr = 3.4570202542e-01\ttime = 0.02 sec\n[ Info: VUMPS 73:\tobj = -8.071173596559e-02\terr = 3.9919344455e-01\ttime = 0.04 sec\n[ Info: VUMPS 74:\tobj = -1.370928589038e-01\terr = 3.8043789146e-01\ttime = 0.02 sec\n[ Info: VUMPS 75:\tobj = -2.590488646429e-01\terr = 3.6030703598e-01\ttime = 0.05 sec\n[ Info: VUMPS 76:\tobj = -4.074845294173e-01\terr = 2.2747635384e-01\ttime = 0.03 sec\n[ Info: VUMPS 77:\tobj = -4.083741658015e-01\terr = 2.2604491079e-01\ttime = 0.05 sec\n[ Info: VUMPS 78:\tobj = +1.005627309383e-01\terr = 3.4879269264e-01\ttime = 0.05 sec\n[ Info: VUMPS 79:\tobj = -1.534111629484e-01\terr = 4.0398980845e-01\ttime = 0.04 sec\n[ Info: VUMPS 80:\tobj = -1.185244700305e-01\terr = 4.1527071676e-01\ttime = 0.05 sec\n[ Info: VUMPS 81:\tobj = -2.203348020820e-01\terr = 3.4143151318e-01\ttime = 0.04 sec\n[ Info: VUMPS 82:\tobj = -5.889431350950e-02\terr = 3.9822663932e-01\ttime = 0.05 sec\n[ Info: VUMPS 83:\tobj = -1.737018741265e-01\terr = 3.8538020144e-01\ttime = 0.04 sec\n[ Info: VUMPS 84:\tobj = -1.582331643179e-01\terr = 3.6506684092e-01\ttime = 0.02 sec\n[ Info: VUMPS 85:\tobj = -2.020317867236e-01\terr = 3.7807390527e-01\ttime = 0.05 sec\n[ Info: VUMPS 86:\tobj = -6.233681285915e-02\terr = 3.7406473722e-01\ttime = 0.02 sec\n[ Info: VUMPS 87:\tobj = -1.314218634692e-01\terr = 3.8818132852e-01\ttime = 0.06 sec\n[ Info: VUMPS 88:\tobj = -2.302777507565e-01\terr = 3.6235120973e-01\ttime = 0.04 sec\n[ Info: VUMPS 89:\tobj = +1.777592295373e-02\terr = 3.1886054992e-01\ttime = 0.06 sec\n[ Info: VUMPS 90:\tobj = -9.137389133038e-02\terr = 3.6650533950e-01\ttime = 0.05 sec\n[ Info: VUMPS 91:\tobj = -1.522621453585e-01\terr = 3.7520570789e-01\ttime = 0.04 sec\n[ Info: VUMPS 92:\tobj = -2.067248068564e-01\terr = 3.8667875904e-01\ttime = 0.05 sec\n[ Info: VUMPS 93:\tobj = +2.047786471459e-02\terr = 3.7528645946e-01\ttime = 0.04 sec\n[ Info: VUMPS 94:\tobj = -2.196126737735e-01\terr = 3.7361837770e-01\ttime = 0.06 sec\n[ Info: VUMPS 95:\tobj = -3.148681836053e-01\terr = 3.3877001456e-01\ttime = 0.03 sec\n[ Info: VUMPS 96:\tobj = -3.632549896064e-01\terr = 3.1063135089e-01\ttime = 0.05 sec\n[ Info: VUMPS 97:\tobj = -2.359487524961e-01\terr = 3.4983505936e-01\ttime = 0.05 sec\n[ Info: VUMPS 98:\tobj = -2.085648662363e-01\terr = 3.6646074907e-01\ttime = 0.04 sec\n[ Info: VUMPS 99:\tobj = -3.378709599647e-01\terr = 3.1090195525e-01\ttime = 0.03 sec\n[ Info: VUMPS 100:\tobj = +1.697054331465e-01\terr = 3.3318043865e-01\ttime = 0.03 sec\n[ Info: VUMPS 101:\tobj = -1.372336728300e-01\terr = 3.9831002380e-01\ttime = 0.03 sec\n[ Info: VUMPS 102:\tobj = -2.025796302451e-01\terr = 3.6198000343e-01\ttime = 0.05 sec\n[ Info: VUMPS 103:\tobj = -2.078176354072e-01\terr = 3.8150634396e-01\ttime = 0.03 sec\n[ Info: VUMPS 104:\tobj = -2.923528623190e-01\terr = 3.3199471479e-01\ttime = 0.09 sec\n[ Info: VUMPS 105:\tobj = -2.895261890513e-02\terr = 3.9381156810e-01\ttime = 0.06 sec\n[ Info: VUMPS 106:\tobj = +1.102282311350e-01\terr = 3.6753101837e-01\ttime = 0.02 sec\n[ Info: VUMPS 107:\tobj = -3.457075224669e-03\terr = 3.8935262670e-01\ttime = 0.05 sec\n[ Info: VUMPS 108:\tobj = -1.401802303936e-01\terr = 3.5477482436e-01\ttime = 0.07 sec\n[ Info: VUMPS 109:\tobj = -2.773177515742e-01\terr = 3.5618814609e-01\ttime = 0.04 sec\n[ Info: VUMPS 110:\tobj = -2.980497929052e-01\terr = 3.3973067915e-01\ttime = 0.07 sec\n[ Info: VUMPS 111:\tobj = -3.666221447505e-01\terr = 2.9612511089e-01\ttime = 0.04 sec\n[ Info: VUMPS 112:\tobj = -3.406894034780e-01\terr = 3.1838335674e-01\ttime = 0.07 sec\n[ Info: VUMPS 113:\tobj = -4.117451756841e-01\terr = 2.1229269280e-01\ttime = 0.05 sec\n[ Info: VUMPS 114:\tobj = +3.472393021263e-02\terr = 4.2138653263e-01\ttime = 0.04 sec\n[ Info: VUMPS 115:\tobj = +6.929635845720e-03\terr = 4.0042995319e-01\ttime = 0.02 sec\n[ Info: VUMPS 116:\tobj = +1.198686632180e-01\terr = 3.5017433469e-01\ttime = 0.04 sec\n[ Info: VUMPS 117:\tobj = -1.271079129807e-01\terr = 3.7101933225e-01\ttime = 0.02 sec\n[ Info: VUMPS 118:\tobj = -1.834088729116e-01\terr = 3.6678418731e-01\ttime = 0.03 sec\n[ Info: VUMPS 119:\tobj = -3.363021880354e-01\terr = 3.1503549193e-01\ttime = 0.02 sec\n[ Info: VUMPS 120:\tobj = -4.275043892741e-01\terr = 1.5610761856e-01\ttime = 0.06 sec\n[ Info: VUMPS 121:\tobj = +3.978743301000e-02\terr = 3.1230305054e-01\ttime = 0.08 sec\n[ Info: VUMPS 122:\tobj = -1.990612171666e-01\terr = 3.6200810172e-01\ttime = 0.04 sec\n[ Info: VUMPS 123:\tobj = +1.050122944992e-01\terr = 3.4198140893e-01\ttime = 0.04 sec\n[ Info: VUMPS 124:\tobj = -5.398579365216e-02\terr = 4.1624422030e-01\ttime = 0.04 sec\n[ Info: VUMPS 125:\tobj = -1.003705443385e-01\terr = 3.7636491379e-01\ttime = 0.02 sec\n[ Info: VUMPS 126:\tobj = +8.454616496648e-02\terr = 3.5803981901e-01\ttime = 0.04 sec\n[ Info: VUMPS 127:\tobj = -1.128523326267e-01\terr = 3.8181570938e-01\ttime = 0.03 sec\n[ Info: VUMPS 128:\tobj = -2.150635416320e-01\terr = 3.5780210657e-01\ttime = 0.04 sec\n[ Info: VUMPS 129:\tobj = -1.312465126627e-01\terr = 3.8405159732e-01\ttime = 0.06 sec\n[ Info: VUMPS 130:\tobj = -3.846997189431e-02\terr = 4.2623757858e-01\ttime = 0.05 sec\n[ Info: VUMPS 131:\tobj = +2.473200047618e-02\terr = 3.5905352543e-01\ttime = 0.05 sec\n[ Info: VUMPS 132:\tobj = +7.006948564206e-02\terr = 3.4845271565e-01\ttime = 0.04 sec\n[ Info: VUMPS 133:\tobj = -2.383461944993e-01\terr = 3.7052130221e-01\ttime = 0.06 sec\n[ Info: VUMPS 134:\tobj = -2.062217898227e-01\terr = 3.6937256423e-01\ttime = 0.04 sec\n[ Info: VUMPS 135:\tobj = -2.274384652936e-01\terr = 3.4724295244e-01\ttime = 0.07 sec\n[ Info: VUMPS 136:\tobj = -2.622435856918e-01\terr = 3.4143263011e-01\ttime = 0.05 sec\n[ Info: VUMPS 137:\tobj = -1.368393705006e-01\terr = 3.9505761386e-01\ttime = 0.04 sec\n[ Info: VUMPS 138:\tobj = -2.365952891363e-01\terr = 3.6070782003e-01\ttime = 0.05 sec\n[ Info: VUMPS 139:\tobj = -3.285892419662e-01\terr = 3.2510337702e-01\ttime = 0.06 sec\n[ Info: VUMPS 140:\tobj = -2.897155176623e-01\terr = 3.4971272209e-01\ttime = 0.05 sec\n[ Info: VUMPS 141:\tobj = -5.613172601920e-02\terr = 4.0280146205e-01\ttime = 0.06 sec\n[ Info: VUMPS 142:\tobj = -1.912055510339e-01\terr = 3.8086840086e-01\ttime = 0.06 sec\n[ Info: VUMPS 143:\tobj = -2.522493416812e-01\terr = 3.7780461889e-01\ttime = 0.03 sec\n[ Info: VUMPS 144:\tobj = -1.448388260442e-01\terr = 3.9735778286e-01\ttime = 0.06 sec\n[ Info: VUMPS 145:\tobj = +2.133811571892e-02\terr = 3.6767706542e-01\ttime = 0.05 sec\n[ Info: VUMPS 146:\tobj = -1.021149430836e-01\terr = 4.1518428940e-01\ttime = 0.04 sec\n[ Info: VUMPS 147:\tobj = +3.345423157498e-02\terr = 3.7487854814e-01\ttime = 0.06 sec\n[ Info: VUMPS 148:\tobj = -1.519027769061e-01\terr = 3.7323297896e-01\ttime = 0.04 sec\n[ Info: VUMPS 149:\tobj = -1.015157315769e-01\terr = 3.9037495750e-01\ttime = 0.07 sec\n[ Info: VUMPS 150:\tobj = -7.525226965218e-02\terr = 4.0412444789e-01\ttime = 0.05 sec\n[ Info: VUMPS 151:\tobj = -1.435426260194e-01\terr = 4.0959006551e-01\ttime = 0.08 sec\n[ Info: VUMPS 152:\tobj = -1.234168209435e-01\terr = 4.0252461632e-01\ttime = 0.02 sec\n[ Info: VUMPS 153:\tobj = -1.582356991859e-01\terr = 4.0856159774e-01\ttime = 0.07 sec\n[ Info: VUMPS 154:\tobj = -2.611502661937e-02\terr = 3.7361316068e-01\ttime = 0.02 sec\n[ Info: VUMPS 155:\tobj = -1.903742563432e-02\terr = 3.6268799414e-01\ttime = 0.05 sec\n[ Info: VUMPS 156:\tobj = -1.660075702137e-01\terr = 3.6001499475e-01\ttime = 0.04 sec\n[ Info: VUMPS 157:\tobj = -1.750801644509e-01\terr = 3.5799477869e-01\ttime = 0.03 sec\n[ Info: VUMPS 158:\tobj = -3.185357562769e-01\terr = 3.4039580564e-01\ttime = 0.04 sec\n[ Info: VUMPS 159:\tobj = -3.462765635183e-01\terr = 3.0750748489e-01\ttime = 0.03 sec\n[ Info: VUMPS 160:\tobj = -3.906343752662e-01\terr = 2.7025958372e-01\ttime = 0.05 sec\n[ Info: VUMPS 161:\tobj = +6.478821525323e-02\terr = 4.1194192280e-01\ttime = 0.05 sec\n[ Info: VUMPS 162:\tobj = -2.303254431617e-02\terr = 3.8071990310e-01\ttime = 0.04 sec\n[ Info: VUMPS 163:\tobj = -2.010080764751e-01\terr = 3.7801881819e-01\ttime = 0.04 sec\n[ Info: VUMPS 164:\tobj = -3.545532748718e-01\terr = 2.8772339262e-01\ttime = 0.04 sec\n[ Info: VUMPS 165:\tobj = -3.269217578981e-01\terr = 3.3116005000e-01\ttime = 0.05 sec\n[ Info: VUMPS 166:\tobj = -7.763273380566e-02\terr = 4.4233452292e-01\ttime = 0.05 sec\n[ Info: VUMPS 167:\tobj = -6.297628554394e-02\terr = 4.0291320901e-01\ttime = 0.02 sec\n[ Info: VUMPS 168:\tobj = -6.509753260918e-02\terr = 3.7453292998e-01\ttime = 0.04 sec\n[ Info: VUMPS 169:\tobj = -1.479501367088e-01\terr = 3.7646685662e-01\ttime = 0.06 sec\n[ Info: VUMPS 170:\tobj = -1.936550011338e-01\terr = 3.9968563965e-01\ttime = 0.05 sec\n[ Info: VUMPS 171:\tobj = -2.407761747630e-01\terr = 3.8299383049e-01\ttime = 0.05 sec\n[ Info: VUMPS 172:\tobj = +2.261073305309e-02\terr = 4.0104933806e-01\ttime = 0.03 sec\n[ Info: VUMPS 173:\tobj = -7.166260900992e-02\terr = 3.9840210145e-01\ttime = 0.04 sec\n[ Info: VUMPS 174:\tobj = -1.839330523396e-01\terr = 3.7559526845e-01\ttime = 0.03 sec\n[ Info: VUMPS 175:\tobj = -3.059547394952e-01\terr = 3.3999396097e-01\ttime = 0.04 sec\n[ Info: VUMPS 176:\tobj = -2.995029313597e-01\terr = 3.4151945139e-01\ttime = 0.06 sec\n[ Info: VUMPS 177:\tobj = -1.628200467586e-01\terr = 3.9581213200e-01\ttime = 0.03 sec\n[ Info: VUMPS 178:\tobj = -2.771745987181e-02\terr = 3.7799012327e-01\ttime = 0.04 sec\n[ Info: VUMPS 179:\tobj = -2.450722764418e-01\terr = 3.6283636173e-01\ttime = 0.03 sec\n[ Info: VUMPS 180:\tobj = +2.249435492935e-02\terr = 3.8247790534e-01\ttime = 0.07 sec\n[ Info: VUMPS 181:\tobj = -2.354825221975e-02\terr = 4.1422828465e-01\ttime = 0.03 sec\n[ Info: VUMPS 182:\tobj = -1.142934591710e-01\terr = 3.8986670495e-01\ttime = 0.04 sec\n[ Info: VUMPS 183:\tobj = -1.567308697369e-01\terr = 3.9700243050e-01\ttime = 0.03 sec\n[ Info: VUMPS 184:\tobj = -1.842499532379e-01\terr = 3.6532838941e-01\ttime = 0.05 sec\n[ Info: VUMPS 185:\tobj = -2.514877837893e-01\terr = 3.6637072380e-01\ttime = 0.03 sec\n[ Info: VUMPS 186:\tobj = -5.058982255378e-02\terr = 4.0946736692e-01\ttime = 0.06 sec\n[ Info: VUMPS 187:\tobj = -3.684615096066e-03\terr = 4.0659110148e-01\ttime = 0.03 sec\n[ Info: VUMPS 188:\tobj = -1.225767651180e-01\terr = 4.2689031391e-01\ttime = 0.05 sec\n[ Info: VUMPS 189:\tobj = -2.461679320853e-01\terr = 3.6120729961e-01\ttime = 0.04 sec\n[ Info: VUMPS 190:\tobj = +6.763190603494e-02\terr = 3.8401937650e-01\ttime = 0.03 sec\n[ Info: VUMPS 191:\tobj = +6.358079111108e-02\terr = 3.8794532554e-01\ttime = 0.04 sec\n[ Info: VUMPS 192:\tobj = -2.591627687434e-01\terr = 3.4498062399e-01\ttime = 0.03 sec\n[ Info: VUMPS 193:\tobj = -3.469647117223e-01\terr = 3.1920950928e-01\ttime = 0.07 sec\n[ Info: VUMPS 194:\tobj = -2.328255401437e-01\terr = 3.7087112305e-01\ttime = 0.05 sec\n[ Info: VUMPS 195:\tobj = -1.059181306961e-01\terr = 3.9644832676e-01\ttime = 0.06 sec\n[ Info: VUMPS 196:\tobj = +3.165492219560e-02\terr = 3.4664317312e-01\ttime = 0.04 sec\n[ Info: VUMPS 197:\tobj = -1.060919702177e-01\terr = 4.0404073514e-01\ttime = 0.06 sec\n[ Info: VUMPS 198:\tobj = -7.551485865858e-02\terr = 4.1482067043e-01\ttime = 0.03 sec\n[ Info: VUMPS 199:\tobj = -8.128843893232e-02\terr = 3.8193109836e-01\ttime = 0.07 sec\n┌ Warning: VUMPS cancel 200:\tobj = -1.297030723726e-01\terr = 3.8203051738e-01\ttime = 9.08 sec\n└ @ MPSKit ~/Projects/MPSKit.jl/src/algorithms/groundstate/vumps.jl:71\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"As you can see, VUMPS struggles to converge. On it's own, that is already quite curious. Maybe we can do better using another algorithm, such as gradient descent.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"groundstate, cache, delta = find_groundstate(state, H, GradientGrassmann(; maxiter=20));","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"[ Info: CG: initializing with f = 0.249993227089, ‖∇f‖ = 5.1973e-03\n[ Info: CG: iter 1: f = -0.104179418829, ‖∇f‖ = 3.1103e-01, α = 1.34e+04, β = 0.00e+00, nfg = 5\n[ Info: CG: iter 2: f = -0.168230521916, ‖∇f‖ = 3.1218e-01, α = 1.73e+00, β = 4.36e+01, nfg = 25\n[ Info: CG: iter 3: f = -0.279139021454, ‖∇f‖ = 2.5424e-01, α = 1.12e+00, β = 6.09e-01, nfg = 3\n[ Info: CG: iter 4: f = -0.351436956991, ‖∇f‖ = 1.8762e-01, α = 8.32e-01, β = 2.88e-01, nfg = 3\n[ Info: CG: iter 5: f = -0.394810706473, ‖∇f‖ = 1.5263e-01, α = 7.39e-01, β = 2.23e-01, nfg = 2\n[ Info: CG: iter 6: f = -0.421934998173, ‖∇f‖ = 1.1117e-01, α = 6.51e-01, β = 3.64e-01, nfg = 2\n[ Info: CG: iter 7: f = -0.432301255729, ‖∇f‖ = 6.0604e-02, α = 5.15e-01, β = 3.63e-01, nfg = 2\n[ Info: CG: iter 8: f = -0.436376560912, ‖∇f‖ = 4.3154e-02, α = 3.66e-01, β = 3.53e-01, nfg = 2\n[ Info: CG: iter 9: f = -0.438323587926, ‖∇f‖ = 3.4866e-02, α = 2.49e-01, β = 5.20e-01, nfg = 2\n[ Info: CG: iter 10: f = -0.439871747915, ‖∇f‖ = 2.4460e-02, α = 3.84e-01, β = 4.02e-01, nfg = 2\n[ Info: CG: iter 11: f = -0.440833392787, ‖∇f‖ = 1.7872e-02, α = 3.89e-01, β = 3.60e-01, nfg = 2\n[ Info: CG: iter 12: f = -0.441105694369, ‖∇f‖ = 1.6493e-02, α = 1.27e-01, β = 6.83e-01, nfg = 2\n[ Info: CG: iter 13: f = -0.441491345325, ‖∇f‖ = 1.4925e-02, α = 1.90e-01, β = 8.48e-01, nfg = 2\n[ Info: CG: iter 14: f = -0.441792424830, ‖∇f‖ = 1.2359e-02, α = 2.98e-01, β = 3.23e-01, nfg = 2\n[ Info: CG: iter 15: f = -0.442153471150, ‖∇f‖ = 1.0004e-02, α = 4.72e-01, β = 3.45e-01, nfg = 2\n[ Info: CG: iter 16: f = -0.442265625493, ‖∇f‖ = 9.2135e-03, α = 1.70e-01, β = 6.20e-01, nfg = 2\n[ Info: CG: iter 17: f = -0.442409712129, ‖∇f‖ = 7.1718e-03, α = 3.16e-01, β = 5.69e-01, nfg = 2\n[ Info: CG: iter 18: f = -0.442533970670, ‖∇f‖ = 5.9509e-03, α = 3.59e-01, β = 4.16e-01, nfg = 2\n[ Info: CG: iter 19: f = -0.442582601670, ‖∇f‖ = 5.6643e-03, α = 1.19e-01, β = 8.47e-01, nfg = 2\n┌ Warning: CG: not converged to requested tol: f = -0.442655552067, ‖∇f‖ = 6.1012e-03\n└ @ OptimKit ~/.julia/packages/OptimKit/xpmbV/src/cg.jl:103\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"Convergence is quite slow and even fails after sufficiently many iterations. To understand why, we can look at the transfer matrix spectrum.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"transferplot(groundstate, groundstate)","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"We can clearly see multiple eigenvalues close to the unit circle. Our state is close to being non-injective, and represents the sum of multiple injective states. This is numerically very problematic, but also indicates that we used an incorrect ansatz to approximate the groundstate. We should retry with a larger unit cell.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/#Success","page":"The XXZ model","title":"Success","text":"","category":"section"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"Let's initialize a different initial state, this time with a 2-site unit cell:","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"state = InfiniteMPS(fill(2, 2), fill(20, 2))","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"2-site InfiniteMPS:\n│ ⋮\n│ C[2]: TensorMap(ℂ^20 ← ℂ^20)\n├── AL[2]: TensorMap((ℂ^20 ⊗ ℂ^2) ← ℂ^20)\n├── AL[1]: TensorMap((ℂ^20 ⊗ ℂ^2) ← ℂ^20)\n│ ⋮\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"In MPSKit, we require that the periodicity of the hamiltonian equals that of the state it is applied to. This is not a big obstacle, you can simply repeat the original hamiltonian. Alternatively, the hamiltonian can be constructed directly on a two-site unitcell by making use of MPSKitModels.jl's @mpoham.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"# H2 = repeat(H, 2); -- copies the one-site version\nH2 = heisenberg_XXX(ComplexF64, Trivial, InfiniteChain(2); spin=1 // 2)\ngroundstate, envs, delta = find_groundstate(state, H2,\n VUMPS(; maxiter=100, tol=1e-12));","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"[ Info: VUMPS init:\tobj = +4.994527818488e-01\terr = 4.7959e-02\n[ Info: VUMPS 1:\tobj = -5.224213331967e-01\terr = 3.1869497986e-01\ttime = 0.07 sec\n[ Info: VUMPS 2:\tobj = -8.703292449817e-01\terr = 9.7881092516e-02\ttime = 0.04 sec\n[ Info: VUMPS 3:\tobj = -8.853872271509e-01\terr = 1.1633880994e-02\ttime = 0.05 sec\n[ Info: VUMPS 4:\tobj = -8.859759226381e-01\terr = 5.0303292009e-03\ttime = 0.06 sec\n[ Info: VUMPS 5:\tobj = -8.861272827748e-01\terr = 4.0977568854e-03\ttime = 0.03 sec\n[ Info: VUMPS 6:\tobj = -8.861876892553e-01\terr = 2.8143569786e-03\ttime = 0.06 sec\n[ Info: VUMPS 7:\tobj = -8.862118265423e-01\terr = 2.4768815055e-03\ttime = 0.07 sec\n[ Info: VUMPS 8:\tobj = -8.862240634280e-01\terr = 2.1529722171e-03\ttime = 0.07 sec\n[ Info: VUMPS 9:\tobj = -8.862295952770e-01\terr = 2.0143660733e-03\ttime = 0.08 sec\n[ Info: VUMPS 10:\tobj = -8.862325590423e-01\terr = 1.9696799082e-03\ttime = 0.07 sec\n[ Info: VUMPS 11:\tobj = -8.862339539915e-01\terr = 1.9072844137e-03\ttime = 0.07 sec\n[ Info: VUMPS 12:\tobj = -8.862347209414e-01\terr = 1.9329517027e-03\ttime = 0.04 sec\n[ Info: VUMPS 13:\tobj = -8.862350788779e-01\terr = 1.8912383017e-03\ttime = 0.08 sec\n[ Info: VUMPS 14:\tobj = -8.862353072621e-01\terr = 1.9119217581e-03\ttime = 0.07 sec\n[ Info: VUMPS 15:\tobj = -8.862354080095e-01\terr = 1.8651910333e-03\ttime = 0.07 sec\n[ Info: VUMPS 16:\tobj = -8.862354997154e-01\terr = 1.8780338112e-03\ttime = 0.07 sec\n[ Info: VUMPS 17:\tobj = -8.862355500667e-01\terr = 1.8132834599e-03\ttime = 0.06 sec\n[ Info: VUMPS 18:\tobj = -8.862356079518e-01\terr = 1.8176447019e-03\ttime = 0.07 sec\n[ Info: VUMPS 19:\tobj = -8.862356026529e-01\terr = 1.7897346650e-03\ttime = 0.06 sec\n[ Info: VUMPS 20:\tobj = -8.862356494807e-01\terr = 1.7869452100e-03\ttime = 0.05 sec\n[ Info: VUMPS 21:\tobj = -8.862357156491e-01\terr = 1.7171781823e-03\ttime = 0.07 sec\n[ Info: VUMPS 22:\tobj = -8.862356705107e-01\terr = 1.7618627080e-03\ttime = 0.05 sec\n[ Info: VUMPS 23:\tobj = -8.862356847446e-01\terr = 1.7345893329e-03\ttime = 0.06 sec\n[ Info: VUMPS 24:\tobj = -8.862356597631e-01\terr = 1.7698180368e-03\ttime = 0.06 sec\n[ Info: VUMPS 25:\tobj = -8.862356369663e-01\terr = 1.7832515198e-03\ttime = 0.07 sec\n[ Info: VUMPS 26:\tobj = -8.862355639238e-01\terr = 1.8610433054e-03\ttime = 0.07 sec\n[ Info: VUMPS 27:\tobj = -8.862355966939e-01\terr = 1.8414491439e-03\ttime = 0.07 sec\n[ Info: VUMPS 28:\tobj = -8.862354448304e-01\terr = 1.9601069224e-03\ttime = 0.07 sec\n[ Info: VUMPS 29:\tobj = -8.862353997121e-01\terr = 2.0323064685e-03\ttime = 0.04 sec\n[ Info: VUMPS 30:\tobj = -8.862352867417e-01\terr = 2.0852298701e-03\ttime = 0.06 sec\n[ Info: VUMPS 31:\tobj = -8.862350688513e-01\terr = 2.3296901858e-03\ttime = 0.08 sec\n[ Info: VUMPS 32:\tobj = -8.862348370300e-01\terr = 2.4308916811e-03\ttime = 0.08 sec\n[ Info: VUMPS 33:\tobj = -8.862348650705e-01\terr = 2.5264912559e-03\ttime = 0.07 sec\n[ Info: VUMPS 34:\tobj = -8.862341340353e-01\terr = 2.8806808793e-03\ttime = 0.07 sec\n[ Info: VUMPS 35:\tobj = -8.862340510957e-01\terr = 3.1043746978e-03\ttime = 0.07 sec\n[ Info: VUMPS 36:\tobj = -8.862334585911e-01\terr = 3.2535241129e-03\ttime = 0.07 sec\n[ Info: VUMPS 37:\tobj = -8.862322313415e-01\terr = 4.0963820560e-03\ttime = 0.05 sec\n[ Info: VUMPS 38:\tobj = -8.862328105793e-01\terr = 3.5663760522e-03\ttime = 0.05 sec\n[ Info: VUMPS 39:\tobj = -8.862317650974e-01\terr = 4.3666283036e-03\ttime = 0.08 sec\n[ Info: VUMPS 40:\tobj = -8.862334734959e-01\terr = 3.2172539857e-03\ttime = 0.06 sec\n[ Info: VUMPS 41:\tobj = -8.862328031496e-01\terr = 4.0602562223e-03\ttime = 0.07 sec\n[ Info: VUMPS 42:\tobj = -8.862348928428e-01\terr = 2.8096230226e-03\ttime = 0.06 sec\n[ Info: VUMPS 43:\tobj = -8.862354347226e-01\terr = 2.9469451252e-03\ttime = 0.07 sec\n[ Info: VUMPS 44:\tobj = -8.862369582324e-01\terr = 2.0065666373e-03\ttime = 0.03 sec\n[ Info: VUMPS 45:\tobj = -8.862376214330e-01\terr = 1.5332753632e-03\ttime = 0.07 sec\n[ Info: VUMPS 46:\tobj = -8.862381576736e-01\terr = 9.5235621400e-04\ttime = 0.07 sec\n[ Info: VUMPS 47:\tobj = -8.862383675148e-01\terr = 5.9064456193e-04\ttime = 0.06 sec\n[ Info: VUMPS 48:\tobj = -8.862384608233e-01\terr = 3.4391997505e-04\ttime = 0.08 sec\n[ Info: VUMPS 49:\tobj = -8.862384963189e-01\terr = 1.9914113331e-04\ttime = 0.07 sec\n[ Info: VUMPS 50:\tobj = -8.862385106659e-01\terr = 1.1648442343e-04\ttime = 0.06 sec\n[ Info: VUMPS 51:\tobj = -8.862385173677e-01\terr = 7.0216183061e-05\ttime = 0.05 sec\n[ Info: VUMPS 52:\tobj = -8.862385211516e-01\terr = 5.4936268184e-05\ttime = 0.07 sec\n[ Info: VUMPS 53:\tobj = -8.862385239261e-01\terr = 5.0775181524e-05\ttime = 0.05 sec\n[ Info: VUMPS 54:\tobj = -8.862385263536e-01\terr = 4.9093824356e-05\ttime = 0.06 sec\n[ Info: VUMPS 55:\tobj = -8.862385287510e-01\terr = 4.7160784987e-05\ttime = 0.05 sec\n[ Info: VUMPS 56:\tobj = -8.862385312350e-01\terr = 4.7356857246e-05\ttime = 0.06 sec\n[ Info: VUMPS 57:\tobj = -8.862385338978e-01\terr = 4.6554878190e-05\ttime = 0.07 sec\n[ Info: VUMPS 58:\tobj = -8.862385367826e-01\terr = 4.7893015679e-05\ttime = 0.05 sec\n[ Info: VUMPS 59:\tobj = -8.862385399464e-01\terr = 4.7866639440e-05\ttime = 0.08 sec\n[ Info: VUMPS 60:\tobj = -8.862385434317e-01\terr = 5.0108148399e-05\ttime = 0.08 sec\n[ Info: VUMPS 61:\tobj = -8.862385472946e-01\terr = 5.0701719642e-05\ttime = 0.06 sec\n[ Info: VUMPS 62:\tobj = -8.862385515924e-01\terr = 5.3747205154e-05\ttime = 0.06 sec\n[ Info: VUMPS 63:\tobj = -8.862385563928e-01\terr = 5.4917836680e-05\ttime = 0.07 sec\n[ Info: VUMPS 64:\tobj = -8.862385617762e-01\terr = 5.8736952243e-05\ttime = 0.07 sec\n[ Info: VUMPS 65:\tobj = -8.862385678319e-01\terr = 6.0517251626e-05\ttime = 0.04 sec\n[ Info: VUMPS 66:\tobj = -8.862385746724e-01\terr = 6.5122279370e-05\ttime = 0.05 sec\n[ Info: VUMPS 67:\tobj = -8.862385824209e-01\terr = 6.7603807255e-05\ttime = 0.08 sec\n[ Info: VUMPS 68:\tobj = -8.862385912344e-01\terr = 7.3037975820e-05\ttime = 0.06 sec\n[ Info: VUMPS 69:\tobj = -8.862386012855e-01\terr = 7.6356824733e-05\ttime = 0.06 sec\n[ Info: VUMPS 70:\tobj = -8.862386127926e-01\terr = 8.2675024543e-05\ttime = 0.08 sec\n[ Info: VUMPS 71:\tobj = -8.862386259979e-01\terr = 8.7080551030e-05\ttime = 0.08 sec\n[ Info: VUMPS 72:\tobj = -8.862386412013e-01\terr = 9.4240413691e-05\ttime = 0.07 sec\n[ Info: VUMPS 73:\tobj = -8.862386587357e-01\terr = 1.0001061678e-04\ttime = 0.06 sec\n[ Info: VUMPS 74:\tobj = -8.862386790008e-01\terr = 1.0787560414e-04\ttime = 0.05 sec\n[ Info: VUMPS 75:\tobj = -8.862387024327e-01\terr = 1.1491628128e-04\ttime = 0.07 sec\n[ Info: VUMPS 76:\tobj = -8.862387295295e-01\terr = 1.2350014063e-04\ttime = 0.07 sec\n[ Info: VUMPS 77:\tobj = -8.862387608070e-01\terr = 1.3154045663e-04\ttime = 0.08 sec\n[ Info: VUMPS 78:\tobj = -8.862387968010e-01\terr = 1.4054217709e-04\ttime = 0.08 sec\n[ Info: VUMPS 79:\tobj = -8.862388379935e-01\terr = 1.4918434598e-04\ttime = 0.08 sec\n[ Info: VUMPS 80:\tobj = -8.862388847728e-01\terr = 1.5756496092e-04\ttime = 0.06 sec\n[ Info: VUMPS 81:\tobj = -8.862389373185e-01\terr = 1.6556206078e-04\ttime = 0.05 sec\n[ Info: VUMPS 82:\tobj = -8.862389955195e-01\terr = 1.7207041444e-04\ttime = 0.05 sec\n[ Info: VUMPS 83:\tobj = -8.862390588490e-01\terr = 1.7709969160e-04\ttime = 0.06 sec\n[ Info: VUMPS 84:\tobj = -8.862391263089e-01\terr = 1.8017689240e-04\ttime = 0.07 sec\n[ Info: VUMPS 85:\tobj = -8.862391964083e-01\terr = 1.8083364727e-04\ttime = 0.06 sec\n[ Info: VUMPS 86:\tobj = -8.862392672643e-01\terr = 1.7896061249e-04\ttime = 0.06 sec\n[ Info: VUMPS 87:\tobj = -8.862393367843e-01\terr = 1.7435281981e-04\ttime = 0.07 sec\n[ Info: VUMPS 88:\tobj = -8.862394029305e-01\terr = 1.6733550307e-04\ttime = 0.07 sec\n[ Info: VUMPS 89:\tobj = -8.862394639791e-01\terr = 1.5822580553e-04\ttime = 0.08 sec\n[ Info: VUMPS 90:\tobj = -8.862395187139e-01\terr = 1.4763647565e-04\ttime = 0.05 sec\n[ Info: VUMPS 91:\tobj = -8.862395665083e-01\terr = 1.3613348343e-04\ttime = 0.07 sec\n[ Info: VUMPS 92:\tobj = -8.862396072866e-01\terr = 1.2433109567e-04\ttime = 0.06 sec\n[ Info: VUMPS 93:\tobj = -8.862396414074e-01\terr = 1.1271049944e-04\ttime = 0.09 sec\n[ Info: VUMPS 94:\tobj = -8.862396695130e-01\terr = 1.0166193044e-04\ttime = 0.08 sec\n[ Info: VUMPS 95:\tobj = -8.862396923871e-01\terr = 9.1428430976e-05\ttime = 0.09 sec\n[ Info: VUMPS 96:\tobj = -8.862397108436e-01\terr = 8.2152207117e-05\ttime = 0.08 sec\n[ Info: VUMPS 97:\tobj = -8.862397256537e-01\terr = 7.3876229899e-05\ttime = 0.06 sec\n[ Info: VUMPS 98:\tobj = -8.862397375053e-01\terr = 6.6584753895e-05\ttime = 0.07 sec\n[ Info: VUMPS 99:\tobj = -8.862397469874e-01\terr = 6.0216703928e-05\ttime = 0.07 sec\n┌ Warning: VUMPS cancel 100:\tobj = -8.862397545895e-01\terr = 5.4690768674e-05\ttime = 6.50 sec\n└ @ MPSKit ~/Projects/MPSKit.jl/src/algorithms/groundstate/vumps.jl:71\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"We get convergence, but it takes an enormous amount of iterations. The reason behind this becomes more obvious at higher bond dimensions:","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"groundstate, envs, delta = find_groundstate(state, H2,\n IDMRG2(; trscheme=truncdim(50), maxiter=20,\n tol=1e-12));\nentanglementplot(groundstate)","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"We see that some eigenvalues clearly belong to a group, and are almost degenerate. This implies 2 things:","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"there is superfluous information, if those eigenvalues are the same anyway\npoor convergence if we cut off within such a subspace","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"It are precisely those problems that we can solve by using symmetries.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/#Symmetries","page":"The XXZ model","title":"Symmetries","text":"","category":"section"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"The XXZ Heisenberg hamiltonian is SU(2) symmetric and we can exploit this to greatly speed up the simulation.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"It is cumbersome to construct symmetric hamiltonians, but luckily su(2) symmetric XXZ is already implemented:","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"H2 = heisenberg_XXX(ComplexF64, SU2Irrep, InfiniteChain(2); spin=1 // 2);","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"Our initial state should also be SU(2) symmetric. It now becomes apparent why we have to use a two-site periodic state. The physical space carries a half-integer charge and the first tensor maps the first virtual_space ⊗ the physical_space to the second virtual_space. Half-integer virtual charges will therefore map only to integer charges, and vice versa. The staggering thus happens on the virtual level.","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"An alternative constructor for the initial state is","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"P = Rep[SU₂](1 // 2 => 1)\nV1 = Rep[SU₂](1 // 2 => 10, 3 // 2 => 5, 5 // 2 => 2)\nV2 = Rep[SU₂](0 => 15, 1 => 10, 2 => 5)\nstate = InfiniteMPS([P, P], [V1, V2]);","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"┌ Warning: Constructing an MPS from tensors that are not full rank\n└ @ MPSKit ~/Projects/MPSKit.jl/src/states/infinitemps.jl:149\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"Even though the bond dimension is higher than in the example without symmetry, convergence is reached much faster:","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"println(dim(V1))\nprintln(dim(V2))\ngroundstate, cache, delta = find_groundstate(state, H2,\n VUMPS(; maxiter=400, tol=1e-12));","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"52\n70\n[ Info: VUMPS init:\tobj = +8.571475316991e-02\terr = 4.0869e-01\n[ Info: VUMPS 1:\tobj = -8.841768943048e-01\terr = 3.0962778235e-02\ttime = 8.39 sec\n[ Info: VUMPS 2:\tobj = -8.858941441948e-01\terr = 6.8861549505e-03\ttime = 0.08 sec\n[ Info: VUMPS 3:\tobj = -8.861591970700e-01\terr = 3.1438981011e-03\ttime = 0.19 sec\n[ Info: VUMPS 4:\tobj = -8.862373586553e-01\terr = 1.5694150974e-03\ttime = 0.08 sec\n[ Info: VUMPS 5:\tobj = -8.862665008570e-01\terr = 9.6720118128e-04\ttime = 0.10 sec\n[ Info: VUMPS 6:\tobj = -8.862780790113e-01\terr = 7.6876116694e-04\ttime = 0.11 sec\n[ Info: VUMPS 7:\tobj = -8.862831659742e-01\terr = 6.6877783316e-04\ttime = 0.19 sec\n[ Info: VUMPS 8:\tobj = -8.862855860323e-01\terr = 5.3599376124e-04\ttime = 0.11 sec\n[ Info: VUMPS 9:\tobj = -8.862867663190e-01\terr = 4.0660286466e-04\ttime = 0.16 sec\n[ Info: VUMPS 10:\tobj = -8.862873424424e-01\terr = 3.0566269459e-04\ttime = 0.32 sec\n[ Info: VUMPS 11:\tobj = -8.862876251526e-01\terr = 2.2687597738e-04\ttime = 0.14 sec\n[ Info: VUMPS 12:\tobj = -8.862877641798e-01\terr = 1.6630235595e-04\ttime = 0.28 sec\n[ Info: VUMPS 13:\tobj = -8.862878324776e-01\terr = 1.2065962982e-04\ttime = 0.17 sec\n[ Info: VUMPS 14:\tobj = -8.862878659705e-01\terr = 8.6847532670e-05\ttime = 0.13 sec\n[ Info: VUMPS 15:\tobj = -8.862878823733e-01\terr = 6.2151682727e-05\ttime = 0.16 sec\n[ Info: VUMPS 16:\tobj = -8.862878903974e-01\terr = 4.4290628543e-05\ttime = 0.18 sec\n[ Info: VUMPS 17:\tobj = -8.862878943223e-01\terr = 3.1467696209e-05\ttime = 0.14 sec\n[ Info: VUMPS 18:\tobj = -8.862878962425e-01\terr = 2.2309311401e-05\ttime = 0.17 sec\n[ Info: VUMPS 19:\tobj = -8.862878971826e-01\terr = 1.5794437549e-05\ttime = 0.17 sec\n[ Info: VUMPS 20:\tobj = -8.862878976433e-01\terr = 1.1169983677e-05\ttime = 0.15 sec\n[ Info: VUMPS 21:\tobj = -8.862878978692e-01\terr = 7.8938125044e-06\ttime = 0.17 sec\n[ Info: VUMPS 22:\tobj = -8.862878979802e-01\terr = 5.5754187069e-06\ttime = 0.14 sec\n[ Info: VUMPS 23:\tobj = -8.862878980347e-01\terr = 3.9363165672e-06\ttime = 0.17 sec\n[ Info: VUMPS 24:\tobj = -8.862878980615e-01\terr = 2.7782600761e-06\ttime = 0.18 sec\n[ Info: VUMPS 25:\tobj = -8.862878980747e-01\terr = 1.9605416898e-06\ttime = 0.14 sec\n[ Info: VUMPS 26:\tobj = -8.862878980813e-01\terr = 1.3831566356e-06\ttime = 0.17 sec\n[ Info: VUMPS 27:\tobj = -8.862878980845e-01\terr = 9.7563836730e-07\ttime = 0.17 sec\n[ Info: VUMPS 28:\tobj = -8.862878980861e-01\terr = 6.8808237712e-07\ttime = 0.14 sec\n[ Info: VUMPS 29:\tobj = -8.862878980868e-01\terr = 4.8521326515e-07\ttime = 0.17 sec\n[ Info: VUMPS 30:\tobj = -8.862878980872e-01\terr = 3.4211403050e-07\ttime = 0.18 sec\n[ Info: VUMPS 31:\tobj = -8.862878980874e-01\terr = 2.4118986474e-07\ttime = 0.14 sec\n[ Info: VUMPS 32:\tobj = -8.862878980875e-01\terr = 1.7001487151e-07\ttime = 0.17 sec\n[ Info: VUMPS 33:\tobj = -8.862878980876e-01\terr = 1.1983516999e-07\ttime = 0.16 sec\n[ Info: VUMPS 34:\tobj = -8.862878980876e-01\terr = 8.4458211885e-08\ttime = 0.14 sec\n[ Info: VUMPS 35:\tobj = -8.862878980876e-01\terr = 5.9519779420e-08\ttime = 0.18 sec\n[ Info: VUMPS 36:\tobj = -8.862878980876e-01\terr = 4.1941570268e-08\ttime = 0.14 sec\n[ Info: VUMPS 37:\tobj = -8.862878980877e-01\terr = 2.9552481662e-08\ttime = 0.17 sec\n[ Info: VUMPS 38:\tobj = -8.862878980877e-01\terr = 2.0821461973e-08\ttime = 0.17 sec\n[ Info: VUMPS 39:\tobj = -8.862878980877e-01\terr = 1.4668928777e-08\ttime = 0.13 sec\n[ Info: VUMPS 40:\tobj = -8.862878980877e-01\terr = 1.0333740629e-08\ttime = 0.16 sec\n[ Info: VUMPS 41:\tobj = -8.862878980877e-01\terr = 7.2793133017e-09\ttime = 0.19 sec\n[ Info: VUMPS 42:\tobj = -8.862878980877e-01\terr = 5.1274193990e-09\ttime = 0.14 sec\n[ Info: VUMPS 43:\tobj = -8.862878980877e-01\terr = 3.6115696251e-09\ttime = 0.16 sec\n[ Info: VUMPS 44:\tobj = -8.862878980877e-01\terr = 2.5436748324e-09\ttime = 0.18 sec\n[ Info: VUMPS 45:\tobj = -8.862878980877e-01\terr = 1.7914400554e-09\ttime = 0.13 sec\n[ Info: VUMPS 46:\tobj = -8.862878980877e-01\terr = 1.2616075130e-09\ttime = 0.17 sec\n[ Info: VUMPS 47:\tobj = -8.862878980877e-01\terr = 8.8844294429e-10\ttime = 0.18 sec\n[ Info: VUMPS 48:\tobj = -8.862878980877e-01\terr = 6.2563200343e-10\ttime = 0.14 sec\n[ Info: VUMPS 49:\tobj = -8.862878980877e-01\terr = 4.4055009956e-10\ttime = 0.17 sec\n[ Info: VUMPS 50:\tobj = -8.862878980877e-01\terr = 3.1021022428e-10\ttime = 0.17 sec\n[ Info: VUMPS 51:\tobj = -8.862878980877e-01\terr = 2.1842377352e-10\ttime = 0.13 sec\n[ Info: VUMPS 52:\tobj = -8.862878980877e-01\terr = 1.5378883830e-10\ttime = 0.17 sec\n[ Info: VUMPS 53:\tobj = -8.862878980877e-01\terr = 1.0827914915e-10\ttime = 0.13 sec\n[ Info: VUMPS 54:\tobj = -8.862878980877e-01\terr = 7.6233561627e-11\ttime = 0.17 sec\n[ Info: VUMPS 55:\tobj = -8.862878980878e-01\terr = 5.3670361265e-11\ttime = 0.17 sec\n[ Info: VUMPS 56:\tobj = -8.862878980878e-01\terr = 3.7785296901e-11\ttime = 0.12 sec\n[ Info: VUMPS 57:\tobj = -8.862878980878e-01\terr = 2.6597183661e-11\ttime = 0.15 sec\n[ Info: VUMPS 58:\tobj = -8.862878980878e-01\terr = 1.8724144528e-11\ttime = 0.15 sec\n[ Info: VUMPS 59:\tobj = -8.862878980878e-01\terr = 1.3177752530e-11\ttime = 0.12 sec\n[ Info: VUMPS 60:\tobj = -8.862878980878e-01\terr = 9.2726977215e-12\ttime = 0.15 sec\n[ Info: VUMPS 61:\tobj = -8.862878980878e-01\terr = 6.5267922494e-12\ttime = 0.10 sec\n[ Info: VUMPS 62:\tobj = -8.862878980878e-01\terr = 4.5890864081e-12\ttime = 0.14 sec\n[ Info: VUMPS 63:\tobj = -8.862878980878e-01\terr = 3.2289295438e-12\ttime = 0.10 sec\n[ Info: VUMPS 64:\tobj = -8.862878980878e-01\terr = 2.2706304983e-12\ttime = 0.13 sec\n[ Info: VUMPS 65:\tobj = -8.862878980878e-01\terr = 1.5950561789e-12\ttime = 0.09 sec\n[ Info: VUMPS 66:\tobj = -8.862878980878e-01\terr = 1.1189780150e-12\ttime = 0.09 sec\n[ Info: VUMPS conv 67:\tobj = -8.862878980878e-01\terr = 7.7998640130e-13\ttime = 18.42 sec\n","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"","category":"page"},{"location":"examples/quantum1d/4.xxz-heisenberg/","page":"The XXZ model","title":"The XXZ model","text":"This page was generated using Literate.jl.","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"EditURL = \"../../../../../examples/quantum1d/1.ising-cft/main.jl\"","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"(Image: ) (Image: ) (Image: )","category":"page"},{"location":"examples/quantum1d/1.ising-cft/#The-Ising-CFT-spectrum","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"","category":"section"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"This tutorial is meant to show the finite size CFT spectrum for the quantum Ising model. We do this by first employing an exact diagonalization technique, and then extending the analysis to larger system sizes through the use of MPS techniques.","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"using MPSKit, MPSKitModels, TensorKit, Plots, KrylovKit\nusing LinearAlgebra: eigen, diagm, Hermitian","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"The hamiltonian is defined on a finite lattice with periodic boundary conditions, which can be implemented as follows:","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"L = 12\nH = periodic_boundary_conditions(transverse_field_ising(), L)","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"12-site FiniteMPOHamiltonian{BlockTensorKit.SparseBlockTensorMap{AbstractTensorMap{ComplexF64, ComplexSpace, 2, 2}, ComplexF64, ComplexSpace, 2, 2, 4}}:\n┬ W[12]: 4×1×1×1 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ ⊕(ℂ^1)))\n┼ W[11]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[10]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[9]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[8]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[7]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[6]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[5]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[4]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[3]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┼ W[2]: 4×1×1×4 SparseBlockTensorMap(((ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n┴ W[1]: 1×1×1×4 SparseBlockTensorMap((⊕(ℂ^1) ⊗ ⊕(ℂ^2)) ← (⊕(ℂ^2) ⊗ (ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1 ⊕ ℂ^1)))\n","category":"page"},{"location":"examples/quantum1d/1.ising-cft/#Exact-diagonalisation","page":"The Ising CFT spectrum","title":"Exact diagonalisation","text":"","category":"section"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"In MPSKit, there is support for exact diagonalisation by leveraging the fact that applying the hamiltonian to an untruncated MPS will result in an effective hamiltonian on the center site which implements the action of the entire hamiltonian. Thus, optimizing the middle tensor is equivalent to optimixing a state in the entire Hilbert space, as all other tensors are just unitary matrices that mix the basis.","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"energies, states = exact_diagonalization(H; num=18, alg=Lanczos(; krylovdim=200));\nplot(real.(energies);\n seriestype=:scatter,\n legend=false,\n ylabel=\"energy\",\n xlabel=\"#eigenvalue\")","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"note: Krylov dimension\nNote that we have specified a large Krylov dimension as degenerate eigenvalues are notoriously difficult for iterative methods.","category":"page"},{"location":"examples/quantum1d/1.ising-cft/#Extracting-momentum","page":"The Ising CFT spectrum","title":"Extracting momentum","text":"","category":"section"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"Given a state, it is possible to assign a momentum label through the use of the translation operator. This operator can be defined in MPO language either diagramatically as","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"(Image: translation operator MPO)","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"or in the code as:","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"id = complex(isomorphism(ℂ^2, ℂ^2))\n@tensor O[-1 -2; -3 -4] := id[-1, -3] * id[-2, -4]\nT = periodic_boundary_conditions(InfiniteMPO([O]), L)","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"12-site FiniteMPO{TensorMap{ComplexF64, ComplexSpace, 2, 2, Vector{ComplexF64}}}:\n┬ O[12]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^1))\n┼ O[11]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[10]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[9]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[8]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[7]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[6]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[5]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[4]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[3]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┼ O[2]: TensorMap((ℂ^4 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n┴ O[1]: TensorMap((ℂ^1 ⊗ ℂ^2) ← (ℂ^2 ⊗ ℂ^4))\n","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"We can then calculate the momentum of the groundstate as the expectation value of this operator. However, there is a subtlety because of the degeneracies in the energy eigenvalues. The eigensolver will find an orthonormal basis within each energy subspace, but this basis is not necessarily a basis of eigenstates of the translation operator. In order to fix this, we diagonalize the translation operator within each energy subspace.","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"momentum(ψᵢ, ψⱼ=ψᵢ) = angle(dot(ψᵢ, T * ψⱼ))\n\nfunction fix_degeneracies(basis)\n N = zeros(ComplexF64, length(basis), length(basis))\n M = zeros(ComplexF64, length(basis), length(basis))\n for i in eachindex(basis), j in eachindex(basis)\n N[i, j] = dot(basis[i], basis[j])\n M[i, j] = momentum(basis[i], basis[j])\n end\n\n vals, vecs = eigen(Hermitian(N))\n M = (vecs' * M * vecs)\n M /= diagm(vals)\n\n vals, vecs = eigen(M)\n return angle.(vals)\nend\n\nmomenta = Float64[]\nappend!(momenta, fix_degeneracies(states[1:1]))\nappend!(momenta, fix_degeneracies(states[2:2]))\nappend!(momenta, fix_degeneracies(states[3:3]))\nappend!(momenta, fix_degeneracies(states[4:5]))\nappend!(momenta, fix_degeneracies(states[6:9]))\nappend!(momenta, fix_degeneracies(states[10:11]))\nappend!(momenta, fix_degeneracies(states[12:12]))\nappend!(momenta, fix_degeneracies(states[13:16]))\nappend!(momenta, fix_degeneracies(states[17:18]))\n\nplot(momenta,\n real.(energies[1:18]);\n seriestype=:scatter,\n xlabel=\"momentum\",\n ylabel=\"energy\",\n legend=false)","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/1.ising-cft/#Finite-bond-dimension","page":"The Ising CFT spectrum","title":"Finite bond dimension","text":"","category":"section"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"If we limit the maximum bond dimension of the MPS, we get an approximate solution, but we can reach higher system sizes.","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"L_mps = 20\nH_mps = periodic_boundary_conditions(transverse_field_ising(), L_mps)\nD = 64\nψ, envs, δ = find_groundstate(FiniteMPS(L_mps, ℂ^2, ℂ^D), H_mps, DMRG());","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"[ Info: DMRG init:\tobj = -1.965713989954e+01\terr = 7.3678e-02\n[ Info: DMRG 1:\tobj = -2.549098940727e+01\terr = 8.5575894990e-03\ttime = 1.91 sec\n[ Info: DMRG 2:\tobj = -2.549098968634e+01\terr = 1.0873003217e-06\ttime = 0.42 sec\n[ Info: DMRG 3:\tobj = -2.549098968636e+01\terr = 1.5192202571e-07\ttime = 0.77 sec\n[ Info: DMRG 4:\tobj = -2.549098968636e+01\terr = 1.5544174988e-08\ttime = 0.43 sec\n[ Info: DMRG 5:\tobj = -2.549098968636e+01\terr = 5.1424541508e-09\ttime = 0.50 sec\n[ Info: DMRG 6:\tobj = -2.549098968636e+01\terr = 3.1050577980e-09\ttime = 0.69 sec\n[ Info: DMRG 7:\tobj = -2.549098968636e+01\terr = 2.4204053165e-09\ttime = 0.51 sec\n[ Info: DMRG 8:\tobj = -2.549098968636e+01\terr = 1.8047148184e-09\ttime = 0.49 sec\n[ Info: DMRG 9:\tobj = -2.549098968636e+01\terr = 1.6394519024e-09\ttime = 0.50 sec\n[ Info: DMRG 10:\tobj = -2.549098968636e+01\terr = 1.4659869070e-09\ttime = 0.52 sec\n[ Info: DMRG 11:\tobj = -2.549098968636e+01\terr = 1.2937794213e-09\ttime = 0.48 sec\n[ Info: DMRG 12:\tobj = -2.549098968636e+01\terr = 1.1305465951e-09\ttime = 0.50 sec\n[ Info: DMRG 13:\tobj = -2.549098968636e+01\terr = 9.8105345140e-10\ttime = 0.48 sec\n[ Info: DMRG 14:\tobj = -2.549098968636e+01\terr = 8.4744870806e-10\ttime = 0.49 sec\n[ Info: DMRG 15:\tobj = -2.549098968636e+01\terr = 7.3002865985e-10\ttime = 0.47 sec\n[ Info: DMRG 16:\tobj = -2.549098968636e+01\terr = 6.2797272801e-10\ttime = 0.47 sec\n[ Info: DMRG 17:\tobj = -2.549098968636e+01\terr = 5.3989369084e-10\ttime = 0.49 sec\n[ Info: DMRG 18:\tobj = -2.549098968636e+01\terr = 4.6419603523e-10\ttime = 0.48 sec\n[ Info: DMRG 19:\tobj = -2.549098968636e+01\terr = 3.9928506227e-10\ttime = 0.47 sec\n[ Info: DMRG 20:\tobj = -2.549098968636e+01\terr = 3.4367538602e-10\ttime = 0.47 sec\n[ Info: DMRG 21:\tobj = -2.549098968636e+01\terr = 2.9603764456e-10\ttime = 0.48 sec\n[ Info: DMRG 22:\tobj = -2.549098968636e+01\terr = 2.5521006751e-10\ttime = 0.48 sec\n[ Info: DMRG 23:\tobj = -2.549098968636e+01\terr = 2.2019176590e-10\ttime = 0.49 sec\n[ Info: DMRG 24:\tobj = -2.549098968636e+01\terr = 1.9012763182e-10\ttime = 0.49 sec\n[ Info: DMRG 25:\tobj = -2.549098968636e+01\terr = 1.6429047853e-10\ttime = 0.49 sec\n[ Info: DMRG 26:\tobj = -2.549098968636e+01\terr = 1.4206315819e-10\ttime = 0.54 sec\n[ Info: DMRG 27:\tobj = -2.549098968636e+01\terr = 1.2292232477e-10\ttime = 0.54 sec\n[ Info: DMRG 28:\tobj = -2.549098968636e+01\terr = 1.0642379465e-10\ttime = 0.54 sec\n[ Info: DMRG conv 29:\tobj = -2.549098968636e+01\terr = 9.2190265994e-11\ttime = 16.18 sec\n","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"Excitations on top of the groundstate can be found through the use of the quasiparticle ansatz. This returns quasiparticle states, which can be converted to regular FiniteMPS objects.","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"E_ex, qps = excitations(H_mps, QuasiparticleAnsatz(), ψ, envs; num=16)\nstates_mps = vcat(ψ, map(qp -> convert(FiniteMPS, qp), qps))\nE_mps = map(x -> expectation_value(x, H_mps), states_mps)\n\nT_mps = periodic_boundary_conditions(InfiniteMPO([O]), L_mps)\nmomenta_mps = Float64[]\nappend!(momenta_mps, fix_degeneracies(states[1:1]))\nappend!(momenta_mps, fix_degeneracies(states[2:2]))\nappend!(momenta_mps, fix_degeneracies(states[3:3]))\nappend!(momenta_mps, fix_degeneracies(states[4:5]))\nappend!(momenta_mps, fix_degeneracies(states[6:9]))\nappend!(momenta_mps, fix_degeneracies(states[10:11]))\nappend!(momenta_mps, fix_degeneracies(states[12:12]))\nappend!(momenta_mps, fix_degeneracies(states[13:16]))\n\nplot(momenta_mps,\n real.(energies[1:16]);\n seriestype=:scatter,\n xlabel=\"momentum\",\n ylabel=\"energy\",\n legend=false)","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"","category":"page"},{"location":"examples/quantum1d/1.ising-cft/","page":"The Ising CFT spectrum","title":"The Ising CFT spectrum","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"DocTestSetup = :(using MPSKit, TensorKit, MPSKitModels)","category":"page"},{"location":"man/algorithms/#um_algorithms","page":"Algorithms","title":"Algorithms","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Here is a collection of the algorithms that have been added to MPSKit.jl. If a particular algorithm is missing, feel free to let us know via an issue, or contribute via a PR.","category":"page"},{"location":"man/algorithms/#Groundstates","page":"Algorithms","title":"Groundstates","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"One of the most prominent use-cases of MPS is to obtain the groundstate of a given (quasi-) one-dimensional quantum Hamiltonian. In MPSKit.jl, this can be achieved through find_groundstate:","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"find_groundstate","category":"page"},{"location":"man/algorithms/#MPSKit.find_groundstate-man-algorithms","page":"Algorithms","title":"MPSKit.find_groundstate","text":"find_groundstate(ψ₀, H, [environments]; kwargs...) -> (ψ, environments, ϵ)\nfind_groundstate(ψ₀, H, algorithm, environments) -> (ψ, environments, ϵ)\n\nCompute the groundstate for Hamiltonian H with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.\n\nArguments\n\nψ₀::AbstractMPS: initial guess\nH::AbstractMPO: operator for which to find the groundstate\n[environments]: MPS environment manager\nalgorithm: optimization algorithm\n\nKeywords\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: display progress information\n\nReturns\n\nψ::AbstractMPS: converged groundstate\nenvironments: environments corresponding to the converged state\nϵ::Float64: final convergence error upon terminating the algorithm\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"There is a variety of algorithms that have been developed over the years, and many of them have been implemented in MPSKit. Keep in mind that some of them are exclusive to finite or infinite systems, while others may work for both. Many of these algorithms have different advantages and disadvantages, and figuring out the optimal algorithm is not always straightforward, since this may strongly depend on the model. Here, we enumerate some of their properties in hopes of pointing you in the right direction.","category":"page"},{"location":"man/algorithms/#DMRG","page":"Algorithms","title":"DMRG","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Probably the most widely used algorithm for optimizing groundstates with MPS is DMRG and its variants. This algorithm sweeps through the system, optimizing a single site while keeping all others fixed. Since this local problem can be solved efficiently, the global optimal state follows by alternating through the system. However, because of the single-site nature of this algorithm, this can never alter the bond dimension of the state, such that there is no way of dynamically increasing the precision. This can become particularly relevant in the cases where symmetries are involved, since then finding a good distribution of charges is also required. To circumvent this, it is also possible to optimize over two sites at the same time with DMRG2, followed by a truncation back to the single site states. This can dynamically change the bond dimension but comes at an increase in cost.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"DMRG\nDMRG2","category":"page"},{"location":"man/algorithms/#MPSKit.DMRG-man-algorithms","page":"Algorithms","title":"MPSKit.DMRG","text":"struct DMRG{A, F} <: MPSKit.Algorithm\n\nSingle-site DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\nverbosity::Int64: setting for how much information is displayed\neigalg::Any: algorithm used for the eigenvalue solvers\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#MPSKit.DMRG2-man-algorithms","page":"Algorithms","title":"MPSKit.DMRG2","text":"struct DMRG2{A, F} <: MPSKit.Algorithm\n\nTwo-site DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\nverbosity::Int64: setting for how much information is displayed\neigalg::Any: algorithm used for the eigenvalue solvers\ntrscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"For infinite systems, a similar approach can be used by dynamically adding new sites to the middle of the system and optimizing over them. This gradually increases the system size until the boundary effects are no longer felt. However, because of this approach, for critical systems this algorithm can be quite slow to converge, since the number of steps needs to be larger than the correlation length of the system. Again, both a single-site and a two-site version are implemented, to have the option to dynamically increase the bonddimension at a higher cost.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"IDMRG\nIDMRG2","category":"page"},{"location":"man/algorithms/#MPSKit.IDMRG-man-algorithms","page":"Algorithms","title":"MPSKit.IDMRG","text":"struct IDMRG{A} <: MPSKit.Algorithm\n\nSingle site infinite DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_gauge::Any: algorithm used for gauging the MPS\nalg_eigsolve::Any: algorithm used for the eigenvalue solvers\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#MPSKit.IDMRG2-man-algorithms","page":"Algorithms","title":"MPSKit.IDMRG2","text":"struct IDMRG2{A} <: MPSKit.Algorithm\n\nTwo-site infinite DMRG algorithm for finding the dominant eigenvector.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_gauge::Any: algorithm used for gauging the MPS\nalg_eigsolve::Any: algorithm used for the eigenvalue solvers\ntrscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#VUMPS","page":"Algorithms","title":"VUMPS","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"VUMPS is an (I)DMRG inspired algorithm that can be used to Variationally find the groundstate as a Uniform (infinite) Matrix Product State. In particular, a local update is followed by a re-gauging procedure that effectively replaces the entire network with the newly updated tensor. Compared to IDMRG, this often achieves a higher rate of convergence, since updates are felt throughout the system immediately. Nevertheless, this algorithm only works whenever the state is injective, i.e. there is a unique ground state. Since this is a single-site algorithm, this cannot alter the bond dimension.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"VUMPS","category":"page"},{"location":"man/algorithms/#MPSKit.VUMPS-man-algorithms","page":"Algorithms","title":"MPSKit.VUMPS","text":"struct VUMPS{F} <: MPSKit.Algorithm\n\nVariational optimization algorithm for uniform matrix product states, based on the combination of DMRG with matrix product state tangent space concepts.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\nalg_gauge::Any: algorithm used for gauging the InfiniteMPS\nalg_eigsolve::Any: algorithm used for the eigenvalue solvers\nalg_environments::Any: algorithm used for the MPS environments\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\n\nReferences\n\nZauner-Stauber et al. Phys. Rev. B 97 (2018)\nVanderstraeten et al. SciPost Phys. Lect. Notes 7 (2019)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#Gradient-descent","page":"Algorithms","title":"Gradient descent","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Both finite and infinite matrix product states can be parametrized by a set of isometric tensors, which we can optimize over. Making use of the geometry of the manifold (a Grassmann manifold), we can greatly outperform naive optimization strategies. Compared to the other algorithms, quite often the convergence rate in the tail of the optimization procedure is higher, such that often the fastest method combines a different algorithm far from convergence with this algorithm close to convergence. Since this is again a single-site algorithm, there is no way to alter the bond dimension.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"GradientGrassmann","category":"page"},{"location":"man/algorithms/#MPSKit.GradientGrassmann-man-algorithms","page":"Algorithms","title":"MPSKit.GradientGrassmann","text":"struct GradientGrassmann{O<:OptimKit.OptimizationAlgorithm, F} <: MPSKit.Algorithm\n\nVariational gradient-based optimization algorithm that keeps the MPS in left-canonical form, as points on a Grassmann manifold. The optimization is then a Riemannian gradient descent with a preconditioner to induce the metric from the Hilbert space inner product.\n\nFields\n\nmethod::OptimKit.OptimizationAlgorithm: optimization algorithm\nfinalize!::Any: callback function applied after each iteration, of signature finalize!(x, f, g, numiter) -> x, f, g\n\nReferences\n\nHauru et al. SciPost Phys. 10 (2021)\n\n\n\nConstructors\n\nGradientGrassmann(; kwargs...)\n\nKeywords\n\nmethod=ConjugateGradient: instance of optimization algorithm, or type of optimization algorithm to construct\nfinalize!: finalizer algorithm\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: level of information display\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#Time-evolution","page":"Algorithms","title":"Time evolution","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Given a particular state, it can also often be useful to have the ability to examine the evolution of certain properties over time. To that end, there are two main approaches to solving the Schrödinger equation in MPSKit.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"i hbar fracddt Psi = H Psi implies Psi(t) = expleft(-iH(t - t_0)right) Psi(t_0)","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"timestep\ntime_evolve\nmake_time_mpo","category":"page"},{"location":"man/algorithms/#MPSKit.timestep-man-algorithms","page":"Algorithms","title":"MPSKit.timestep","text":"timestep(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ, envs)\ntimestep!(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ₀, envs)\n\nTime-step the state ψ₀ with Hamiltonian H over a given time step dt at time t, solving the Schroedinger equation: i ψt = H ψ.\n\nArguments\n\nψ₀::AbstractMPS: initial state\nH::AbstractMPO: operator that generates the time evolution (can be time-dependent).\nt::Number: starting time of time-step\ndt::Number: time-step magnitude\n[alg]: algorithm to use for the time evolution. Defaults to TDVP.\n[envs]: MPS environment manager\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#MPSKit.time_evolve-man-algorithms","page":"Algorithms","title":"MPSKit.time_evolve","text":"time_evolve(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ, envs)\ntime_evolve!(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ₀, envs)\n\nTime-evolve the initial state ψ₀ with Hamiltonian H over a given time span by stepping through each of the time points obtained by iterating t_span.\n\nArguments\n\nψ₀::AbstractMPS: initial state\nH::AbstractMPO: operator that generates the time evolution (can be time-dependent).\nt_span::AbstractVector{<:Number}: time points over which the time evolution is stepped\n[alg]: algorithm to use for the time evolution. Defaults to TDVP.\n[envs]: MPS environment manager\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#MPSKit.make_time_mpo-man-algorithms","page":"Algorithms","title":"MPSKit.make_time_mpo","text":"make_time_mpo(H::MPOHamiltonian, dt::Number, alg) -> O::MPO\n\nConstruct an MPO that approximates exp(-iHdt).\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#TDVP","page":"Algorithms","title":"TDVP","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"The first is focused around approximately solving the equation for a small timestep, and repeating this until the desired evolution is achieved. This can be achieved by projecting the equation onto the tangent space of the MPS, and then solving the results. This procedure is commonly referred to as the TDVP algorithm, which again has a two-site variant to allow for dynamically altering the bond dimension.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"TDVP\nTDVP2","category":"page"},{"location":"man/algorithms/#MPSKit.TDVP-man-algorithms","page":"Algorithms","title":"MPSKit.TDVP","text":"struct TDVP{A, F} <: MPSKit.Algorithm\n\nSingle site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.\n\nFields\n\nintegrator::Any: algorithm used in the exponential solvers\ntolgauge::Float64: tolerance for gauging algorithm\ngaugemaxiter::Int64: maximal amount of iterations for gauging algorithm\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\n\nReferences\n\nHaegeman et al. Phys. Rev. Lett. 107 (2011)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#MPSKit.TDVP2-man-algorithms","page":"Algorithms","title":"MPSKit.TDVP2","text":"struct TDVP2{A, F} <: MPSKit.Algorithm\n\nTwo-site MPS time-evolution algorithm based on the Time-Dependent Variational Principle.\n\nFields\n\nintegrator::Any: algorithm used in the exponential solvers\ntolgauge::Float64: tolerance for gauging algorithm\ngaugemaxiter::Int64: maximal amount of iterations for gauging algorithm\ntrscheme::TensorKit.TruncationScheme: algorithm used for truncation of the two-site update\nfinalize::Any: callback function applied after each iteration, of signature finalize(iter, ψ, H, envs) -> ψ, envs\n\nReferences\n\nHaegeman et al. Phys. Rev. Lett. 107 (2011)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#Time-evolution-MPO","page":"Algorithms","title":"Time evolution MPO","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"The other approach instead tries to first approximately represent the evolution operator, and only then attempts to apply this operator to the initial state. Typically the first step happens through make_time_mpo, while the second can be achieved through approximate. Here, there are several algorithms available","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"WI\nWII\nTaylorCluster","category":"page"},{"location":"man/algorithms/#MPSKit.WI-man-algorithms","page":"Algorithms","title":"MPSKit.WI","text":"const WI = TaylorCluster(; N=1, extension=false, compression=false)\n\nFirst order Taylor expansion for a time-evolution MPO.\n\n\n\n\n\n","category":"constant"},{"location":"man/algorithms/#MPSKit.WII-man-algorithms","page":"Algorithms","title":"MPSKit.WII","text":"struct WII <: MPSKit.Algorithm\n\nGeneralization of the Euler approximation of the operator exponential for MPOs.\n\nFields\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal number of iterations\n\nReferences\n\nZaletel et al. Phys. Rev. B 91 (2015)\nPaeckel et al. Ann. of Phys. 411 (2019)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#MPSKit.TaylorCluster-man-algorithms","page":"Algorithms","title":"MPSKit.TaylorCluster","text":"struct TaylorCluster <: MPSKit.Algorithm\n\nAlgorithm for constructing the Nth order time evolution MPO using the Taylor cluster expansion.\n\nFields\n\nN::Int64: order of the Taylor expansion\nextension::Bool: include higher-order corrections\ncompression::Bool: approximate compression of corrections, accurate up to order N\n\nReferences\n\nVan Damme et al. SciPost Phys. 17 (2024)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#Excitations","page":"Algorithms","title":"Excitations","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"It might also be desirable to obtain information beyond the lowest energy state of a given system, and study the dispersion relation. While it is typically not feasible to resolve states in the middle of the energy spectrum, there are several ways to target a few of the lowest-lying energy states.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"excitations","category":"page"},{"location":"man/algorithms/#MPSKit.excitations-man-algorithms","page":"Algorithms","title":"MPSKit.excitations","text":"excitations(H, algorithm::QuasiparticleAnsatz, ψ::FiniteQP, [left_environments],\n [right_environments]; num=1) -> (energies, states)\nexcitations(H, algorithm::QuasiparticleAnsatz, ψ::InfiniteQP, [left_environments],\n [right_environments]; num=1, solver=Defaults.solver) -> (energies, states)\nexcitations(H, algorithm::FiniteExcited, ψs::NTuple{<:Any, <:FiniteMPS};\n num=1, init=copy(first(ψs))) -> (energies, states)\nexcitations(H, algorithm::ChepigaAnsatz, ψ::FiniteMPS, [envs];\n num=1, pos=length(ψ)÷2) -> (energies, states)\nexcitations(H, algorithm::ChepigaAnsatz2, ψ::FiniteMPS, [envs];\n num=1, pos=length(ψ)÷2) -> (energies, states)\n\nCompute the first excited states and their energy gap above a groundstate.\n\nArguments\n\nH::AbstractMPO: operator for which to find the excitations\nalgorithm: optimization algorithm\nψ::QP: initial quasiparticle guess\nψs::NTuple{N, <:FiniteMPS}: N first excited states\n[left_environments]: left groundstate environment\n[right_environments]: right groundstate environment\n\nKeywords\n\nnum::Int: number of excited states to compute\nsolver: algorithm for the linear solver of the quasiparticle environments\ninit: initial excited state guess\npos: position of perturbation\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"using TensorKit, MPSKit, MPSKitModels","category":"page"},{"location":"man/algorithms/#Quasiparticle-Ansatz","page":"Algorithms","title":"Quasiparticle Ansatz","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"The Quasiparticle Ansatz offers an approach to compute low-energy eigenstates in quantum systems, playing a key role in both finite and infinite systems. It leverages localized perturbations for approximations, as detailed in (Haegeman et al., 2013).","category":"page"},{"location":"man/algorithms/#Finite-Systems:","page":"Algorithms","title":"Finite Systems:","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"In finite systems, we approximate low-energy states by altering a single tensor in the Matrix Product State (MPS) for each site, and summing these across all sites. This method introduces additional gauge freedoms, utilized to ensure orthogonality to the ground state. Optimizing within this framework translates to solving an eigenvalue problem. For example, in the transverse field Ising model, we calculate the first excited state as shown in the provided code snippet, amd check the accuracy against theoretical values. Some deviations are expected, both due to finite-bond-dimension and finite-size effects.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"# Model parameters\ng = 10.0\nL = 16\nH = transverse_field_ising(FiniteChain(L); g)\n\n# Finding the ground state\nψ₀ = FiniteMPS(L, ℂ^2, ℂ^32)\nψ, = find_groundstate(ψ₀, H; verbosity=0)\n\n# Computing excitations using the Quasiparticle Ansatz\nEs, ϕs = excitations(H, QuasiparticleAnsatz(), ψ; num=1)\nisapprox(Es[1], 2(g - 1); rtol=1e-2)","category":"page"},{"location":"man/algorithms/#Infinite-Systems:","page":"Algorithms","title":"Infinite Systems:","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"The ansatz in infinite systems maintains translational invariance by perturbing every site in the unit cell in a plane-wave superposition, requiring momentum specification. The Haldane gap computation in the Heisenberg model illustrates this approach.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"# Setting up the model and momentum\nmomentum = π\nH = heisenberg_XXX()\n\n# Ground state computation\nψ₀ = InfiniteMPS(ℂ^3, ℂ^48)\nψ, = find_groundstate(ψ₀, H; verbosity=0)\n\n# Excitation calculations\nEs, ϕs = excitations(H, QuasiparticleAnsatz(), momentum, ψ)\nisapprox(Es[1], 0.41047925; atol=1e-4)","category":"page"},{"location":"man/algorithms/#Charged-excitations:","page":"Algorithms","title":"Charged excitations:","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"When dealing with symmetric systems, the default optimization is for eigenvectors with trivial total charge. However, quasiparticles with different charges can be obtained using the sector keyword. For instance, in the transverse field Ising model, we consider an excitation built up of flipping a single spin, aligning with Z2Irrep(1).","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"g = 10.0\nL = 16\nH = transverse_field_ising(Z2Irrep, FiniteChain(L); g)\nψ₀ = FiniteMPS(L, Z2Space(0 => 1, 1 => 1), Z2Space(0 => 16, 1 => 16))\nψ, = find_groundstate(ψ₀, H; verbosity=0)\nEs, ϕs = excitations(H, QuasiparticleAnsatz(), ψ; num=1, sector=Z2Irrep(1))\nisapprox(Es[1], 2(g - 1); rtol=1e-2) # infinite analytical result","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"QuasiparticleAnsatz","category":"page"},{"location":"man/algorithms/#MPSKit.QuasiparticleAnsatz-man-algorithms","page":"Algorithms","title":"MPSKit.QuasiparticleAnsatz","text":"struct QuasiparticleAnsatz{A} <: MPSKit.Algorithm\n\nOptimization algorithm for quasi-particle excitations on top of MPS groundstates.\n\nFields\n\nalg::Any: algorithm used for the eigenvalue solvers\n\nConstructors\n\nQuasiparticleAnsatz()\nQuasiparticleAnsatz(; kwargs...)\nQuasiparticleAnsatz(alg)\n\nCreate a QuasiparticleAnsatz algorithm with the given algorithm, or by passing the keyword arguments to Arnoldi.\n\nReferences\n\nHaegeman et al. Phys. Rev. Let. 111 (2013)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#Finite-excitations","page":"Algorithms","title":"Finite excitations","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"For finite systems we can also do something else - find the groundstate of the hamiltonian + textweight sum_i psi_i psi_i. This is also supported by calling","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"# Model parameters\ng = 10.0\nL = 16\nH = transverse_field_ising(FiniteChain(L); g)\n\n# Finding the ground state\nψ₀ = FiniteMPS(L, ℂ^2, ℂ^32)\nψ, = find_groundstate(ψ₀, H; verbosity=0)\n\nEs, ϕs = excitations(H, FiniteExcited(), ψ; num=1)\nisapprox(Es[1], 2(g - 1); rtol=1e-2)","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"FiniteExcited","category":"page"},{"location":"man/algorithms/#MPSKit.FiniteExcited-man-algorithms","page":"Algorithms","title":"MPSKit.FiniteExcited","text":"struct FiniteExcited{A} <: MPSKit.Algorithm\n\nVariational optimization algorithm for excitations of finite MPS by minimizing the energy of\n\nH - λᵢ ψᵢψᵢ\n\nFields\n\ngsalg::Any: optimization algorithm\nweight::Float64: energy penalty for enforcing orthogonality with previous states\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#\"Chepiga-Ansatz\"","page":"Algorithms","title":"\"Chepiga Ansatz\"","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Computing excitations in critical systems poses a significant challenge due to the diverging correlation length, which requires very large bond dimensions. However, we can leverage this long-range correlation to effectively identify excitations. In this context, the left/right gauged MPS, serving as isometries, are effectively projecting the Hamiltonian into the low-energy sector. This projection method is particularly effective in long-range systems, where excitations are distributed throughout the entire system. Consequently, the low-lying energy spectrum can be extracted by diagonalizing the effective Hamiltonian (without any additional DMRG costs!). The states of these excitations are then represented by the ground state MPS, with one site substituted by the corresponding eigenvector. This approach is often referred to as the 'Chepiga ansatz', named after one of the authors of this paper (Chepiga and Mila, 2017).","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"This is supported via the following syntax:","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"g = 10.0\nL = 16\nH = transverse_field_ising(FiniteChain(L); g)\nψ₀ = FiniteMPS(L, ComplexSpace(2), ComplexSpace(32))\nψ, envs, = find_groundstate(ψ₀, H; verbosity=0)\nE₀ = real(sum(expectation_value(ψ, H, envs)))\nEs, ϕs = excitations(H, ChepigaAnsatz(), ψ, envs; num=1)\nisapprox(Es[1] - E₀, 2(g - 1); rtol=1e-2) # infinite analytical result","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"In order to improve the accuracy, a two-site version also exists, which varies two neighbouring sites:","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Es, ϕs = excitations(H, ChepigaAnsatz2(), ψ, envs; num=1)\nisapprox(Es[1] - E₀, 2(g - 1); rtol=1e-2) # infinite analytical result","category":"page"},{"location":"man/algorithms/#changebonds","page":"Algorithms","title":"changebonds","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Many of the previously mentioned algorithms do not possess a way to dynamically change to bond dimension. This is often a problem, as the optimal bond dimension is often not a priori known, or needs to increase because of entanglement growth throughout the course of a simulation. changebonds exposes a way to change the bond dimension of a given state.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"changebonds","category":"page"},{"location":"man/algorithms/#MPSKit.changebonds-man-algorithms","page":"Algorithms","title":"MPSKit.changebonds","text":"changebonds(ψ::AbstractMPS, H, alg, envs) -> ψ′, envs′\nchangebonds(ψ::AbstractMPS, alg) -> ψ′\n\nChange the bond dimension of ψ using the algorithm alg, and return the new ψ and the new envs.\n\nSee also: SvdCut, RandExpand, VUMPSSvdCut, OptimalExpand\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"There are several different algorithms implemented, each having their own advantages and disadvantages:","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"SvdCut: The simplest method for changing the bonddimension is found by simply locally truncating the state using an SVD decomposition. This yields a (locally) optimal truncation, but clearly cannot be used to increase the bond dimension. Note that a globally optimal truncation can be obtained by using the SvdCut algorithm in combination with approximate. Since the output of this method might have a truncated bonddimension, the new state might not be identical to the input state. The truncation is controlled through trscheme, which dictates how the singular values of the original state are truncated.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"OptimalExpand: This algorithm is based on the idea of expanding the bond dimension by investigating the two-site derivative, and adding the most important blocks which are orthogonal to the current state. From the point of view of a local two-site update, this procedure is optimal, but it requires to evaluate a two-site derivative, which can be costly when the physical space is large. The state will remain unchanged, but a one-site scheme will now be able to push the optimization further. The subspace used for expansion can be truncated through trscheme, which dictates how many singular values will be added.\nRandExpand: This algorithm similarly adds blocks orthogonal to the current state, but does not attempt to select the most important ones, and rather just selects them at random. The advantage here is that this is much cheaper than the optimal expand, and if the bond dimension is grown slow enough, this still obtains a very good expansion scheme. Again, The state will remain unchanged and a one-site scheme will now be able to push the optimization further. The subspace used for expansion can be truncated through trscheme, which dictates how many singular values will be added.\nVUMPSSvdCut: This algorithm is based on the VUMPS algorithm, and consists of performing a two-site update, and then truncating the state back down. Because of the two-site update, this can again become expensive, but the algorithm has the option of both expanding as well as truncating the bond dimension. Here, trscheme controls the truncation of the full state after the two-site update.","category":"page"},{"location":"man/algorithms/#Leading-boundary","page":"Algorithms","title":"Leading boundary","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"For statistical mechanics partition functions we want to find the approximate leading boundary MPS. Again this can be done with VUMPS:","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"th = nonsym_ising_mpo()\nts = InfiniteMPS([ℂ^2],[ℂ^20]);\n(ts,envs,_) = leading_boundary(ts,th,VUMPS(maxiter=400,verbosity=false));","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"If the mpo satisfies certain properties (positive and hermitian), it may also be possible to use GradientGrassmann.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"leading_boundary","category":"page"},{"location":"man/algorithms/#MPSKit.leading_boundary-man-algorithms","page":"Algorithms","title":"MPSKit.leading_boundary","text":"leading_boundary(ψ₀, O, [environments]; kwargs...) -> (ψ, environments, ϵ)\nleading_boundary(ψ₀, O, algorithm, environments) -> (ψ, environments, ϵ)\n\nCompute the leading boundary MPS for operator O with initial guess ψ. If not specified, an optimization algorithm will be attempted based on the supplied keywords.\n\nArguments\n\nψ₀::AbstractMPS: initial guess\nO::AbstractMPO: operator for which to find the leading_boundary\n[environments]: MPS environment manager\nalgorithm: optimization algorithm\n\nKeywords\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: display progress information\n\nReturns\n\nψ::AbstractMPS: converged leading boundary MPS\nenvironments: environments corresponding to the converged boundary\nϵ::Float64: final convergence error upon terminating the algorithm\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#approximate","page":"Algorithms","title":"approximate","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Often, it is useful to approximate a given MPS by another, typically by one of a different bond dimension. This is achieved by approximating an application of an MPO to the initial state, by a new state.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"approximate","category":"page"},{"location":"man/algorithms/#MPSKit.approximate-man-algorithms","page":"Algorithms","title":"MPSKit.approximate","text":"approximate(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)\napproximate!(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments)\n\nCompute an approximation to the application of an operator O to the state ψ in the form of an MPS ψ₀.\n\nArguments\n\nψ₀::AbstractMPS: initial guess of the approximated state\n(O::AbstractMPO, ψ::AbstractMPS): operator O and state ψ to be approximated\nalgorithm: approximation algorithm. See below for a list of available algorithms.\n[environments]: MPS environment manager\n\nKeywords\n\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int: maximum amount of iterations\nverbosity::Int: display progress information\n\nAlgorithms\n\nDMRG: Alternating least square method for maximizing the fidelity with a single-site scheme.\nDMRG2: Alternating least square method for maximizing the fidelity with a two-site scheme.\nIDMRG: Variant of DMRG for maximizing fidelity density in the thermodynamic limit.\nIDMRG2: Variant of DMRG2 for maximizing fidelity density in the thermodynamic limit.\nVOMPS: Tangent space method for truncating uniform MPS.\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#Varia","page":"Algorithms","title":"Varia","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"What follows is a medley of lesser known (or used) algorithms and don't entirely fit under one of the above categories.","category":"page"},{"location":"man/algorithms/#Dynamical-DMRG","page":"Algorithms","title":"Dynamical DMRG","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"Dynamical DMRG has been described in other papers and is a way to find the propagator. The basic idea is that to calculate G(z) = V (H-z)^-1 V , one can variationally find (H-z) W = V and then the propagator simply equals G(z) = V W .","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"propagator\nDynamicalDMRG\nNaiveInvert\nJeckelmann","category":"page"},{"location":"man/algorithms/#MPSKit.propagator-man-algorithms","page":"Algorithms","title":"MPSKit.propagator","text":"propagator(ψ₀::AbstractFiniteMPS, z::Number, H::MPOHamiltonian, alg::DynamicalDMRG; init=copy(ψ₀))\n\nCalculate the propagator frac1E₀ + z - Hψ₀ using the dynamical DMRG algorithm.\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#MPSKit.DynamicalDMRG-man-algorithms","page":"Algorithms","title":"MPSKit.DynamicalDMRG","text":"struct DynamicalDMRG{F<:MPSKit.DDMRG_Flavour, S} <: MPSKit.Algorithm\n\nA dynamical DMRG method for calculating dynamical properties and excited states, based on a variational principle for dynamical correlation functions.\n\nFields\n\nflavour::MPSKit.DDMRG_Flavour: flavour of the algorithm to use, either of type NaiveInvert or Jeckelmann\nsolver::Any: algorithm used for the linear solvers\ntol::Float64: tolerance for convergence criterium\nmaxiter::Int64: maximal amount of iterations\nverbosity::Int64: setting for how much information is displayed\n\nReferences\n\nJeckelmann. Phys. Rev. B 66 (2002)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#MPSKit.NaiveInvert-man-algorithms","page":"Algorithms","title":"MPSKit.NaiveInvert","text":"struct NaiveInvert <: MPSKit.DDMRG_Flavour\n\nAn alternative approach to the dynamical DMRG algorithm, without quadratic terms but with a less controlled approximation. This algorithm minimizes the following cost function\n\nψ(H - E)ψ - ψψ₀ - ψ₀ψ\n\nwhich is equivalent to the original approach if\n\nψ₀ = (H - E)ψ\n\nSee also Jeckelmann for the original approach.\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#MPSKit.Jeckelmann-man-algorithms","page":"Algorithms","title":"MPSKit.Jeckelmann","text":"struct Jeckelmann <: MPSKit.DDMRG_Flavour\n\nThe original flavour of dynamical DMRG, which minimizes the following (quadratic) cost function:\n\n (H - E) ψ₀ - ψ \n\nSee also NaiveInvert for a less costly but less accurate alternative.\n\nReferences\n\nJeckelmann. Phys. Rev. B 66 (2002)\n\n\n\n\n\n","category":"type"},{"location":"man/algorithms/#fidelity-susceptibility","page":"Algorithms","title":"fidelity susceptibility","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"The fidelity susceptibility measures how much the groundstate changes when tuning a parameter in your hamiltonian. Divergences occur at phase transitions, making it a valuable measure when no order parameter is known.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"fidelity_susceptibility","category":"page"},{"location":"man/algorithms/#MPSKit.fidelity_susceptibility-man-algorithms","page":"Algorithms","title":"MPSKit.fidelity_susceptibility","text":"fidelity_susceptibility(state::Union{FiniteMPS,InfiniteMPS}, H₀::T,\n Vs::AbstractVector{T}, [henvs=environments(state, H₀)];\n maxiter=Defaults.maxiter,\n tol=Defaults.tol) where {T<:MPOHamiltonian}\n\nComputes the fidelity susceptibility of a the ground state state of a base Hamiltonian H₀ with respect to a set of perturbing Hamiltonians Vs. Each of the perturbing Hamiltonians can be interpreted as corresponding to a tuning parameter aᵢ in a 'total' Hamiltonian H = H₀ + ᵢ aᵢ Vᵢ.\n\nReturns a matrix containing the overlaps of the elementary excitations on top of state corresponding to each of the perturbing Hamiltonians.\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#Boundary-conditions","page":"Algorithms","title":"Boundary conditions","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"You can impose periodic or open boundary conditions on an infinite Hamiltonian, to generate a finite counterpart. In particular, for periodic boundary conditions we still return an MPO that does not form a closed loop, such that it can be used with regular matrix product states. This is straightforward to implement but, and while this effectively squares the bond dimension, it is still competitive with more advanced periodic MPS algorithms.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"open_boundary_conditions\nperiodic_boundary_conditions","category":"page"},{"location":"man/algorithms/#MPSKit.open_boundary_conditions-man-algorithms","page":"Algorithms","title":"MPSKit.open_boundary_conditions","text":"open_boundary_conditions(mpo::InfiniteMPO, L::Int) -> FiniteMPO\n\nConvert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.\n\n\n\n\n\nopen_boundary_conditions(mpo::InfiniteMPOHamiltonian, L::Int) -> FiniteMPOHamiltonian\n\nConvert an infinite MPO into a finite MPO of length L, by applying open boundary conditions.\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#MPSKit.periodic_boundary_conditions-man-algorithms","page":"Algorithms","title":"MPSKit.periodic_boundary_conditions","text":"periodic_boundary_conditions(mpo::AbstractInfiniteMPO, L::Int)\n\nConvert an infinite MPO into a finite MPO of length L, by mapping periodic boundary conditions onto an open system.\n\n\n\n\n\n","category":"function"},{"location":"man/algorithms/#Exact-diagonalization","page":"Algorithms","title":"Exact diagonalization","text":"","category":"section"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"As a side effect, our code support exact diagonalization. The idea is to construct a finite matrix product state with maximal bond dimension, and then optimize the middle site. Because we never truncated the bond dimension, this single site effectively parametrizes the entire hilbert space.","category":"page"},{"location":"man/algorithms/","page":"Algorithms","title":"Algorithms","text":"exact_diagonalization","category":"page"},{"location":"man/algorithms/#MPSKit.exact_diagonalization-man-algorithms","page":"Algorithms","title":"MPSKit.exact_diagonalization","text":"exact_diagonalization(H::FiniteMPOHamiltonian;\n sector=first(sectors(oneunit(physicalspace(H, 1)))),\n len::Int=length(H), num::Int=1, which::Symbol=:SR,\n alg=Defaults.alg_eigsolve(; dynamic_tols=false))\n -> vals, state_vecs, convhist\n\nUse KrylovKit.eigsolve to perform exact diagonalization on a FiniteMPOHamiltonian to find its eigenvectors as FiniteMPS of maximal rank, essentially equivalent to dense eigenvectors.\n\nArguments\n\nH::FiniteMPOHamiltonian: the Hamiltonian to diagonalize.\n\nKeyword arguments\n\nsector=first(sectors(oneunit(physicalspace(H, 1)))): the total charge of the eigenvectors, which is chosen trivial by default.\nlen::Int=length(H): the length of the system.\nnum::Int=1: the number of eigenvectors to find.\nwhich::Symbol=:SR: the kind eigenvalues to find, see KrylovKit.eigsolve. \nalg=Defaults.alg_eigsolve(; dynamic_tols=false): the diagonalization algorithm to use, see KrylovKit.eigsolve.\n\nnote: Valid `sector` values\nThe total charge of the eigenvectors is imposed by adding a charged auxiliary space as the leftmost virtualspace of each eigenvector. Specifically, this is achieved by passing left=Vect[typeof(sector)](sector => 1) to the FiniteMPS constructor. As such, the only valid sector values (i.e. sector values for which the corresponding eigenstates have valid fusion channels) are those that occur in the dual of the fusion of all the physical spaces in the system.\n\n\n\n\n\n","category":"function"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"EditURL = \"../../../../../examples/quantum1d/6.hubbard/main.jl\"","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"(Image: ) (Image: ) (Image: )","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"using Markdown","category":"page"},{"location":"examples/quantum1d/6.hubbard/#hubbard","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"","category":"section"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"The Hubbard model is a model of interacting fermions on a lattice, which is often used as a somewhat realistic model for electrons in a solid. The Hamiltonian consists of two terms that describe competing forces of each electron: a kinetic term that allows electrons to hop between neighboring sites, and a potential term reflecting on-site interactions between electrons. Often, a third term is included which serves as a chemical potential to control the number of electrons in the system.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"H = -t sum_langle i j rangle sigma c^dagger_isigma c_jsigma + U sum_i n_iuparrow n_idownarrow - mu sum_isigma n_isigma","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"At half-filling, the system exhibits particle-hole symmetry, which can be made explicit by rewriting the Hamiltonian slightly. First, we fix the overall energy scale by setting t = 1, and then shift the total energy by adding a constant U / 4, as well as shifting the chemical potential to N U / 2. This results in the following Hamiltonian:","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"H = - sum_langle i j rangle sigma c^dagger_isigma c_jsigma + U 4 sum_i (1 - 2 n_iuparrow) (1 - 2 n_idownarrow) - mu sum_isigma n_isigma","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"Finally, setting \\mu = 0 and defining u = U / 4 we obtain the Hubbard model at half-filling.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"H = - sum_langle i j rangle sigma c^dagger_isigma c_jsigma + u sum_i (1 - 2 n_iuparrow) (1 - 2 n_idownarrow)","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"using TensorKit\nusing MPSKit\nusing MPSKitModels\nusing SpecialFunctions: besselj0, besselj1\nusing QuadGK: quadgk\nusing Plots\nusing Interpolations\nusing Optim\n\nconst t = 1.0\nconst mu = 0.0\nconst U = 3.0","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"3.0","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"For this case, the groundstate energy has an analytic solution, which can be used to benchmark the numerical results. It follows from Eq. (6.82) in .","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"e(u) = - u - 4 int_0^infty fracdomegaomega fracJ_0(omega) J_1(omega)1 + exp(2u omega)","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"We can easily verify this by comparing the numerical results to the analytic solution.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"function hubbard_energy(u; rtol=1e-12)\n integrandum(ω) = besselj0(ω) * besselj1(ω) / (1 + exp(2u * ω)) / ω\n int, err = quadgk(integrandum, 0, Inf; rtol=rtol)\n return -u - 4 * int\nend\n\nfunction compute_groundstate(psi, H;\n svalue=5e-3,\n expansionfactor=(1 / 3),\n expansioniter=10)\n verbosity = 1\n psi, = find_groundstate(psi, H; tol=svalue * 10, verbosity)\n for _ in 1:expansioniter\n D = maximum(x -> dim(left_virtualspace(psi, x)), 1:length(psi))\n D′ = max(2, round(Int, D * expansionfactor))\n trscheme = truncbelow(svalue / 10) & truncdim(D′)\n psi′, = changebonds(psi, H, OptimalExpand(; trscheme=trscheme))\n all(left_virtualspace.(Ref(psi), 1:length(psi)) .==\n left_virtualspace.(Ref(psi′), 1:length(psi))) && break\n psi, = find_groundstate(psi′, H, VUMPS(; tol=svalue / 5, verbosity))\n end\n\n # convergence steps\n psi, = changebonds(psi, H, SvdCut(; trscheme=truncbelow(svalue)))\n psi, = find_groundstate(psi, H,\n VUMPS(; tol=svalue, verbosity) &\n GradientGrassmann(; tol=svalue / 100, verbosity))\n\n return psi\nend\n\nH = hubbard_model(InfiniteChain(2); U, t, mu=U / 2)\npsi = InfiniteMPS(physicalspace.(Ref(H), 1:2), physicalspace.(Ref(H), 1:2))\npsi = compute_groundstate(psi, H)\nE = real(expectation_value(psi, H)) / 2\n@info \"\"\"\nGroundstate energy:\n * numerical: $E\n * analytic: $(hubbard_energy(U / 4) - U / 4)\n\"\"\"","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"[ Info: CG: converged after 31 iterations: f = -6.301391216254, ‖∇f‖ = 4.8769e-05\n┌ Info: Groundstate energy:\n│ * numerical: -3.151624340589464\n└ * analytic: -2.190038374277775\n","category":"page"},{"location":"examples/quantum1d/6.hubbard/#Symmetries","page":"Hubbard chain at half filling","title":"Symmetries","text":"","category":"section"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"The Hubbard model has a rich symmetry structure, which can be exploited to speed up simulations. Apart from the fermionic parity, the model also has a U(1) particle number symmetry, along with a SU(2) spin symmetry. Explicitly imposing these symmetries on the tensors can greatly reduce the computational cost of the simulation.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"Naively imposing these symmetries however, is not compatible with our desire to work at half-filling. By construction, imposing symmetries restricts the optimization procedure to a single symmetry sector, which is the trivial sector. In order to work at half-filling, we need to effectively inject one particle per site. In MPSKit, this is achieved by the add_physical_charge function, which shifts the physical spaces of the tensors to the desired charge sector.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"H_u1_su2 = hubbard_model(ComplexF64, U1Irrep, SU2Irrep, InfiniteChain(2); U, t, mu=U / 2);\ncharges = fill(FermionParity(1) ⊠ U1Irrep(1) ⊠ SU2Irrep(0), 2);\nH_u1_su2 = MPSKit.add_physical_charge(H_u1_su2, dual.(charges));\n\npspaces = physicalspace.(Ref(H_u1_su2), 1:2)\nvspaces = [oneunit(eltype(pspaces)), first(pspaces)]\npsi = InfiniteMPS(pspaces, vspaces)\npsi = compute_groundstate(psi, H_u1_su2)\nE = real(expectation_value(psi, H_u1_su2)) / 2\n@info \"\"\"\nGroundstate energy:\n * numerical: $E\n * analytic: $(hubbard_energy(U / 4) - U / 4)\n\"\"\"","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"[ Info: CG: converged after 11 iterations: f = -5.472570186874, ‖∇f‖ = 2.3603e-05\n┌ Info: Groundstate energy:\n│ * numerical: -2.7362850934366705\n└ * analytic: -2.190038374277775\n","category":"page"},{"location":"examples/quantum1d/6.hubbard/#Excitations","page":"Hubbard chain at half filling","title":"Excitations","text":"","category":"section"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"Because of the integrability, it is known that the Hubbard model has a rich excitation spectrum. The elementary excitations are known as spinons and holons, which are domain walls in the spin and charge sectors, respectively. The fact that the spin and charge sectors are separate is a phenomenon known as spin-charge separation.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"The domain walls can be constructed by noticing that there are two equivalent groundstates, which differ by a translation over a single site. In other words, the groundstates are psi_AB and\\psi_{BA} whereAandB`` are the two sites. These excitations can be constructed as follows:","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"alg = QuasiparticleAnsatz(; tol=1e-3)\nmomenta = range(-π, π; length=33)\npsi_AB = psi\nenvs_AB = environments(psi_AB, H_u1_su2);\npsi_BA = circshift(psi, 1)\nenvs_BA = environments(psi_BA, H_u1_su2);\n\nspinon_charge = FermionParity(0) ⊠ U1Irrep(0) ⊠ SU2Irrep(1 // 2)\nE_spinon, ϕ_spinon = excitations(H_u1_su2, alg, momenta,\n psi_AB, envs_AB, psi_BA, envs_BA;\n sector=spinon_charge, num=1);\n\nholon_charge = FermionParity(1) ⊠ U1Irrep(1) ⊠ SU2Irrep(0)\nE_holon, ϕ_holon = excitations(H_u1_su2, alg, momenta,\n psi_AB, envs_AB, psi_BA, envs_BA;\n sector=holon_charge, num=1);","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"[ Info: Found excitations for momentum = -1.5707963267948966\n[ Info: Found excitations for momentum = 0.0\n[ Info: Found excitations for momentum = 1.5707963267948966\n[ Info: Found excitations for momentum = 3.141592653589793\n[ Info: Found excitations for momentum = -1.3744467859455345\n[ Info: Found excitations for momentum = -3.141592653589793\n[ Info: Found excitations for momentum = -1.7671458676442586\n[ Info: Found excitations for momentum = 1.3744467859455345\n[ Info: Found excitations for momentum = 1.7671458676442586\n[ Info: Found excitations for momentum = -1.9634954084936207\n[ Info: Found excitations for momentum = 1.9634954084936207\n[ Info: Found excitations for momentum = 0.19634954084936207\n[ Info: Found excitations for momentum = -2.945243112740431\n[ Info: Found excitations for momentum = 2.945243112740431\n[ Info: Found excitations for momentum = -2.1598449493429825\n[ Info: Found excitations for momentum = 1.1780972450961724\n[ Info: Found excitations for momentum = -1.1780972450961724\n[ Info: Found excitations for momentum = 2.1598449493429825\n[ Info: Found excitations for momentum = -0.9817477042468103\n[ Info: Found excitations for momentum = 0.9817477042468103\n[ Info: Found excitations for momentum = 2.356194490192345\n[ Info: Found excitations for momentum = 0.7853981633974483\n[ Info: Found excitations for momentum = -2.356194490192345\n[ Info: Found excitations for momentum = -0.7853981633974483\n[ Info: Found excitations for momentum = 2.552544031041707\n[ Info: Found excitations for momentum = -0.5890486225480862\n[ Info: Found excitations for momentum = -2.552544031041707\n[ Info: Found excitations for momentum = 0.5890486225480862\n[ Info: Found excitations for momentum = 2.748893571891069\n[ Info: Found excitations for momentum = -2.748893571891069\n[ Info: Found excitations for momentum = -0.39269908169872414\n[ Info: Found excitations for momentum = 0.39269908169872414\n[ Info: Found excitations for momentum = -0.19634954084936207\n[ Info: Found excitations for momentum = 3.141592653589793\n[ Info: Found excitations for momentum = -3.141592653589793\n[ Info: Found excitations for momentum = -2.945243112740431\n[ Info: Found excitations for momentum = -0.19634954084936207\n[ Info: Found excitations for momentum = 2.748893571891069\n[ Info: Found excitations for momentum = 2.945243112740431\n[ Info: Found excitations for momentum = 0.19634954084936207\n[ Info: Found excitations for momentum = 2.552544031041707\n[ Info: Found excitations for momentum = 0.0\n[ Info: Found excitations for momentum = -2.748893571891069\n[ Info: Found excitations for momentum = -0.39269908169872414\n[ Info: Found excitations for momentum = -2.552544031041707\n[ Info: Found excitations for momentum = 2.356194490192345\n[ Info: Found excitations for momentum = 0.5890486225480862\n[ Info: Found excitations for momentum = -0.5890486225480862\n[ Info: Found excitations for momentum = -2.356194490192345\n[ Info: Found excitations for momentum = 0.39269908169872414\n[ Info: Found excitations for momentum = 1.9634954084936207\n[ Info: Found excitations for momentum = -0.7853981633974483\n[ Info: Found excitations for momentum = 0.7853981633974483\n[ Info: Found excitations for momentum = -2.1598449493429825\n[ Info: Found excitations for momentum = 2.1598449493429825\n[ Info: Found excitations for momentum = 1.7671458676442586\n[ Info: Found excitations for momentum = 1.5707963267948966\n[ Info: Found excitations for momentum = -0.9817477042468103\n[ Info: Found excitations for momentum = -1.9634954084936207\n[ Info: Found excitations for momentum = -1.1780972450961724\n[ Info: Found excitations for momentum = -1.5707963267948966\n[ Info: Found excitations for momentum = -1.7671458676442586\n[ Info: Found excitations for momentum = 1.3744467859455345\n[ Info: Found excitations for momentum = 0.9817477042468103\n[ Info: Found excitations for momentum = -1.3744467859455345\n[ Info: Found excitations for momentum = 1.1780972450961724\n","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"Again, we can compare the numerical results to the analytic solution. Here, the formulae for the excitation energies are expressed in terms of dressed momenta:","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"function spinon_momentum(Λ, u; rtol=1e-12)\n integrandum(ω) = besselj0(ω) * sin(ω * Λ) / ω / cosh(ω * u)\n return π / 2 - quadgk(integrandum, 0, Inf; rtol=rtol)[1]\nend\nfunction spinon_energy(Λ, u; rtol=1e-12)\n integrandum(ω) = besselj1(ω) * cos(ω * Λ) / ω / cosh(ω * u)\n return 2 * quadgk(integrandum, 0, Inf; rtol=rtol)[1]\nend\n\nfunction holon_momentum(k, u; rtol=1e-12)\n integrandum(ω) = besselj0(ω) * sin(ω * sin(k)) / ω / (1 + exp(2u * abs(ω)))\n return π / 2 - k - 2 * quadgk(integrandum, 0, Inf; rtol=rtol)[1]\nend\nfunction holon_energy(k, u; rtol=1e-12)\n integrandum(ω) = besselj1(ω) * cos(ω * sin(k)) * exp(-ω * u) / ω / cosh(ω * u)\n return 2 * cos(k) + 2u + 2 * quadgk(integrandum, 0, Inf; rtol=rtol)[1]\nend\n\nΛs = range(-10, 10; length=51)\nP_spinon_analytic = rem2pi.(spinon_momentum.(Λs, U / 4), RoundNearest)\nE_spinon_analytic = spinon_energy.(Λs, U / 4)\nI_spinon = sortperm(P_spinon_analytic)\nP_spinon_analytic = P_spinon_analytic[I_spinon]\nE_spinon_analytic = E_spinon_analytic[I_spinon]\nP_spinon_analytic = [reverse(-P_spinon_analytic); P_spinon_analytic]\nE_spinon_analytic = [reverse(E_spinon_analytic); E_spinon_analytic];\n\nks = range(0, 2π; length=51)\nP_holon_analytic = rem2pi.(holon_momentum.(ks, U / 4), RoundNearest)\nE_holon_analytic = holon_energy.(ks, U / 4)\nI_holon = sortperm(P_holon_analytic)\nP_holon_analytic = P_holon_analytic[I_holon]\nE_holon_analytic = E_holon_analytic[I_holon];\n\np = let p_excitations = plot(; xaxis=\"momentum\", yaxis=\"energy\")\n scatter!(p_excitations, momenta, real(E_spinon); label=\"spinon\")\n plot!(p_excitations, P_spinon_analytic, E_spinon_analytic; label=\"spinon (analytic)\")\n\n scatter!(p_excitations, momenta, real(E_holon); label=\"holon\")\n plot!(p_excitations, P_holon_analytic, E_holon_analytic; label=\"holon (analytic)\")\n\n p_excitations\nend","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"The plot shows some discrepancies between the numerical and analytic results. First and foremost, we must realize that in the thermodynamic limit, the momentum of a domain wall is actually not well-defined. Concretely, only the difference in momentum between the two groundstates is well-defined, as we can always shift the momentum by multiplying one of the groundstates by a phase. Here, we can fix this shift by realizing that our choice of shifting the groundstates by a single site, differs from the formula by a factor pi2.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"momenta_shifted = rem2pi.(momenta .- π / 2, RoundNearest)\np = let p_excitations = plot(; xaxis=\"momentum\", yaxis=\"energy\", xlims=(-π, π))\n scatter!(p_excitations, momenta_shifted, real(E_spinon); label=\"spinon\")\n plot!(p_excitations, P_spinon_analytic, E_spinon_analytic; label=\"spinon (analytic)\")\n\n scatter!(p_excitations, momenta_shifted, real(E_holon); label=\"holon\")\n plot!(p_excitations, P_holon_analytic, E_holon_analytic; label=\"holon (analytic)\")\n\n p_excitations\nend","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"The second discrepancy is that while the spinon dispersion is well-reproduced, the holon dispersion is not. This is due to the fact that the excitation ansatz captures the lowest-energy excitation, and not the elementary single-particle excitation. To make this explicit, we can consider the scattering states comprising of a holon and two spinons. If these are truly scattering states, the energy of the scattering state should be the sum of the energies of the individual excitations, and the momentum is the sum of the momenta. Thus, we can find the lowest-energy scattering states by minimizing the energy over the combination of momenta for the constituent elementary excitations.","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"holon_dispersion_itp = linear_interpolation(P_holon_analytic, E_holon_analytic;\n extrapolation_bc=Line())\nspinon_dispersion_itp = linear_interpolation(P_spinon_analytic, E_spinon_analytic;\n extrapolation_bc=Line())\nfunction scattering_energy(p1, p2, p3)\n p1, p2, p3 = rem2pi.((p1, p2, p3), RoundNearest)\n return holon_dispersion_itp(p1) + spinon_dispersion_itp(p2) + spinon_dispersion_itp(p3)\nend;\n\nE_scattering_min = map(momenta_shifted) do p\n e = Inf\n for i in 1:10 # repeat for stability\n res = optimize((rand(2) .* (2π) .- π)) do (p₁, p₂)\n p₃ = p - p₁ - p₂\n return scattering_energy(p₁, p₂, p₃)\n end\n\n e = min(Optim.minimum(res), e)\n end\n return e\nend\nE_scattering_max = map(momenta_shifted) do p\n e = -Inf\n for i in 1:10 # repeat for stability\n res = optimize((rand(Float64, 2) .* (2π) .- π)) do (p₁, p₂)\n p₃ = p - p₁ - p₂\n return -scattering_energy(p₁, p₂, p₃)\n end\n\n e = max(-Optim.minimum(res), e)\n end\n return e\nend;\n\np = let p_excitations = plot(; xaxis=\"momentum\", yaxis=\"energy\", xlims=(-π, π),\n ylims=(-0.1, 5))\n scatter!(p_excitations, momenta_shifted, real(E_spinon); label=\"spinon\")\n plot!(p_excitations, P_spinon_analytic, E_spinon_analytic; label=\"spinon (analytic)\")\n\n scatter!(p_excitations, momenta_shifted, real(E_holon); label=\"holon\")\n plot!(p_excitations, P_holon_analytic, E_holon_analytic; label=\"holon (analytic)\")\n\n I = sortperm(momenta_shifted)\n plot!(p_excitations, momenta_shifted[I], E_scattering_min[I]; label=\"scattering states\",\n fillrange=E_scattering_max[I], fillalpha=0.3, fillstyle=:x)\n\n p_excitations\nend","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"","category":"page"},{"location":"examples/quantum1d/6.hubbard/","page":"Hubbard chain at half filling","title":"Hubbard chain at half filling","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/operators/#um_operators","page":"Operators","title":"Operators","text":"","category":"section"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"In analogy to how we can define matrix product states as a contraction of local tensors, a similar construction exist for operators. To that end, a Matrix Product Operator (MPO) is nothing more than a collection of local MPOTensor objects, contracted along a line. Again, we can distinguish between finite and infinite operators, with the latter being represented by a periodic array of MPO tensors.","category":"page"},{"location":"man/operators/#FiniteMPO","page":"Operators","title":"FiniteMPO","text":"","category":"section"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"Starting off with the simplest case, a basic FiniteMPO is a vector of MPOTensor objects. These objects can be created either directly from a vector of MPOTensors, or starting from a dense operator (a subtype of AbstractTensorMap), which is then decomposed into a product of local tensors.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"(Image: )","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"using TensorKit, MPSKit, MPSKitModels","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"S_x = TensorMap(ComplexF64[0 1; 1 0], ℂ^2 ← ℂ^2)\nS_z = TensorMap(ComplexF64[1 0; 0 -1], ℂ^2 ← ℂ^2)\nO_xzx = FiniteMPO(S_x ⊗ S_x ⊗ S_x);","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"The individual tensors are accessible via regular indexing. Note that the tensors are internally converted to the MPOTensor objects, thus having four indices. In this specific case, the left- and right virtual spaces are trivial, but this is not a requirement.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"O_xzx[1]","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"warning: Warning\nThe local tensors are defined only up to a gauge transformation of the virtual spaces. This means that the tensors are not uniquely defined, and special care must be taken when comparing MPOs on an element-wise basis.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"For convenience, a number of utility functions are defined for probing the structure of the constructed MPO. For example, the spaces can be queried as follows:","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"left_virtualspace(O_xzx, 2)\nright_virtualspace(O_xzx, 2)\nphysicalspace(O_xzx, 2)","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"MPOs also support a range of linear algebra operations, such as addition, subtraction and multiplication, either among themselves or with a finite MPS. Here, it is important to note that these operations will increase the virtual dimension of the resulting MPO or MPS, and this naive application is thus typically not optimal. For approximate operations that do not increase the virtual dimension, the more advanced algorithms in the um_algorithms sections should be used.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"O_xzx² = O_xzx * O_xzx\nprintln(\"Virtual dimension of O_xzx²: \", left_virtualspace(O_xzx², 2))\nO_xzx_sum = 0.1 * O_xzx + O_xzx²\nprintln(\"Virtual dimension of O_xzx_sum: \", left_virtualspace(O_xzx_sum, 2))","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"O_xzx_sum * FiniteMPS(3, ℂ^2, ℂ^4)","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"note: Note\nThe virtual spaces of the resulting MPOs typically grow exponentially with the number of multiplications. Nevertheless, a number of optimizations are in place that make sure that the virtual spaces do not increase past the maximal virtual space that is dictated by the requirement of being full-rank tensors.","category":"page"},{"location":"man/operators/#InfiniteMPO","page":"Operators","title":"InfiniteMPO","text":"","category":"section"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"This construction can again be extended to the infinite case, where the tensors are repeated periodically. Therefore, an InfiniteMPO is simply a PeriodicVector of MPOTensor objects. These can only be constructed from vectors of MPOTensors, since it is impossible to create the infinite operators directly.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"mpo = InfiniteMPO(O_xzx[1:2])","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"Otherwise, their behavior is mostly similar to that of their finite counterparts.","category":"page"},{"location":"man/operators/#FiniteMPOHamiltonian","page":"Operators","title":"FiniteMPOHamiltonian","text":"","category":"section"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"We can also represent quantum Hamiltonians in the same form. This is done by converting a sum of local operators into a single MPO operator. The resulting operator has a very specific structure, and is often referred to as a Jordan block MPO.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"This object can be constructed as an MPO by using the FiniteMPOHamiltonian constructor, which takes two crucial pieces of information:","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"An array of VectorSpace objects, which determines the local Hilbert spaces of the system. The resulting MPO will snake through the array in linear indexing order.\nA set of local operators, which are characterised by a number of indices that specify on which sites the operator acts, along with an operator to define the action. These are specified as a inds => operator pairs, or any other iterable collection thereof. The inds should be tuples of valid indices for the array of VectorSpace objects, or a single integer for single-site operators.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"As a concrete example, we consider the Transverse-field Ising model defined by the Hamiltonian","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"H = -J sum_langle i j rangle X_i X_j - h sum_j Z_j","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"J = 1.0\nh = 0.5\nchain = fill(ℂ^2, 3) # a finite chain of 4 sites, each with a 2-dimensional Hilbert space\nsingle_site_operators = [1 => -h * S_z, 2 => -h * S_z, 3 => -h * S_z]\ntwo_site_operators = [(1, 2) => -J * S_x ⊗ S_x, (2, 3) => -J * S_x ⊗ S_x]\nH_ising = FiniteMPOHamiltonian(chain, single_site_operators..., two_site_operators...)","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"Various alternative constructions are possible, such as using a Dict with key-value pairs that specify the operators, or using generator expressions to simplify the construction.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"H_ising′ = -J * FiniteMPOHamiltonian(chain,\n (i, i + 1) => S_x ⊗ S_x for i in 1:(length(chain) - 1)) -\n h * FiniteMPOHamiltonian(chain, i => S_z for i in 1:length(chain))\nisapprox(H_ising, H_ising′; atol=1e-6)","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"Note that this construction is not limited to nearest-neighbour interactions, or 1D systems. In particular, it is possible to construct quasi-1D realisations of 2D systems, by using different arrays of VectorSpace objects. For example, the 2D Ising model on a square lattice can be constructed as follows:","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"square = fill(ℂ^2, 3, 3) # a 3x3 square lattice\noperators = Dict()\n\nlocal_operators = Dict()\nfor I in eachindex(square)\n local_operators[(I,)] = -h * S_z # single site operators still require tuples of indices\nend\n\n# horizontal and vertical interactions are easier using Cartesian indices\nhorizontal_operators = Dict()\nI_horizontal = CartesianIndex(0, 1)\nfor I in eachindex(IndexCartesian(), square)\n if I[2] < size(square, 2)\n horizontal_operators[(I, I + I_horizontal)] = -J * S_x ⊗ S_x\n end\nend\n\nvertical_operators = Dict()\nI_vertical = CartesianIndex(1, 0)\nfor I in eachindex(IndexCartesian(), square)\n if I[1] < size(square, 1)\n vertical_operators[(I, I + I_vertical)] = -J * S_x ⊗ S_x\n end\nend\n\nH_ising_2d = FiniteMPOHamiltonian(square, local_operators) +\n FiniteMPOHamiltonian(square, horizontal_operators) +\n FiniteMPOHamiltonian(square, vertical_operators);","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"There are various utility functions available for constructing more advanced lattices, for which the lattices section should be consulted.","category":"page"},{"location":"man/operators/#InfiniteMPOHamiltonian","page":"Operators","title":"InfiniteMPOHamiltonian","text":"","category":"section"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"Again, this construction can be extended straightforwardly to the infinite case. To that end, we simply need to specify all interactions per unit cell. In particular, an InfiniteMPOHamiltonian for the Ising model is obtained via","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"J = 1.0\nh = 0.5\ninfinite_chain = PeriodicVector([ℂ^2]) # an infinite chain of a local 2-dimensional Hilbert space\nH_ising_infinite = InfiniteMPOHamiltonian(infinite_chain, 1 => -h * S_z, (1, 2) => -J * S_x ⊗ S_x)","category":"page"},{"location":"man/operators/#Expert-mode","page":"Operators","title":"Expert mode","text":"","category":"section"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"The MPOHamiltonian constructor is in fact an automated way of constructing the aforementioned Jordan block MPO. In its most general form, the matrix W takes on the form of the following block matrix:","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"beginpmatrix\n1 C D \n0 A B \n0 0 1\nendpmatrix","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"which generates all single-site local operators D, all two-site operators CB, three-site operators CAB, and so on. Additionally, this machinery can also be used to construct interaction that are of (exponentially decaying) infinite range, and to approximate power-law interactions.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"In order to illustrate this, consider the following explicit example of the Transverse-field Ising model:","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"W = beginpmatrix\n1 X -hZ \n0 0 -JX \n0 0 1\nendpmatrix","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"If we add in the left and right boundary vectors","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"v_L = beginpmatrix\n1 0 0\nendpmatrix\n qquad \nv_R = beginpmatrix\n0 0 1\nendpmatrix","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"One can easily check that the Hamiltonian on N sites is given by the contraction","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"H = V_L W^otimes N V_R","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"We can even verify this symbolically:","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"using Symbolics\nL = 4\n# generate W matrices\n@variables A[1:L] B[1:L] C[1:L] D[1:L]\nWs = map(1:L) do l\n return [1 C[l] D[l]\n 0 A[l] B[l]\n 0 0 1]\nend\n\n# generate boundary vectors\nVₗ = [1, 0, 0]'\nVᵣ = [0, 0, 1]\n\n# expand the MPO\nexpand(Vₗ * prod(Ws) * Vᵣ)","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"The FiniteMPOHamiltonian constructor can also be used to construct the operator from this most general form, by supplying a vector of BlockTensorMap objects to the constructor. Here, the vector specifies the sites in the unit cell, while the blocktensors contain the rows and columns of the matrix. We can verify this explicitly:","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"H_ising[2] # print the blocktensor","category":"page"},{"location":"man/operators/#Working-with-MPOHamiltonian-objects","page":"Operators","title":"Working with MPOHamiltonian objects","text":"","category":"section"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"warning: Warning\nThis part is still a work in progress","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"Because of the discussion above, the FiniteMPOHamiltonian object is in fact just an AbstractMPO, with some additional structure. This means that similar operations and properties are available, such as the virtual spaces, or the individual tensors. However, the block structure of the operator means that now the virtual spaces are not just a single space, but a collection (direct sum) of spaces, one for each row/column.","category":"page"},{"location":"man/operators/","page":"Operators","title":"Operators","text":"left_virtualspace(H_ising, 1), right_virtualspace(H_ising, 1), physicalspace(H_ising, 1)","category":"page"},{"location":"#MPSKit.jl","page":"Home","title":"MPSKit.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Efficient and versatile tools for working with matrix product states","category":"page"},{"location":"#Table-of-contents","page":"Home","title":"Table of contents","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Pages = [\"man/intro.md\",\"man/conventions.md\",\"man/states.md\",\"man/operators.md\",\"man/algorithms.md\",\"man/parallelism.md\", \"man/lattices.md\"]\nDepth = 1","category":"page"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"MPSKit.jl is a part of the general registry, and can be installed via the package manager as:","category":"page"},{"location":"","page":"Home","title":"Home","text":"pkg> add MPSKit","category":"page"},{"location":"#Key-Features","page":"Home","title":"Key Features","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Construction and manipulation of Matrix Product States (MPS)\nCalculation of observables and expectation values\nVarious optimization methods for obtaining MPS fixed points\nSupport for both finite and infinite MPS\nSupport for wide variety of symmetries, including Abelian, non-Abelian, fermionic and anyonic symmetries","category":"page"},{"location":"#Usage","page":"Home","title":"Usage","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"To get started with MPSKit, we recommend also including TensorKit.jl and MPSKitModels.jl. The former defines the tensor backend which is used throughout MPSKit, while the latter includes some common operators and models.","category":"page"},{"location":"","page":"Home","title":"Home","text":"using TensorOperations\nusing TensorKit\nusing MPSKit\nusing LinearAlgebra: norm","category":"page"},{"location":"#Finite-Matrix-Product-States","page":"Home","title":"Finite Matrix Product States","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"using LinearAlgebra\nusing TensorOperations\nusing TensorKit\nusing MPSKit","category":"page"},{"location":"","page":"Home","title":"Home","text":"Finite MPS are characterised by a set of tensors, one for each site, which each have 3 legs. They can be constructed by specifying the virtual spaces and the physical spaces, i.e. the dimensions of each of the legs. These are then contracted to form the MPS. In MPSKit, they are represented by FiniteMPS, which can be constructed either by passing in the tensors directly, or by specifying the dimensions of the legs.","category":"page"},{"location":"","page":"Home","title":"Home","text":"d = 2 # physical dimension\nD = 5 # virtual dimension\nL = 10 # number of sites\n\nmps = FiniteMPS(L, ComplexSpace(d), ComplexSpace(D)) # random MPS with maximal bond dimension D","category":"page"},{"location":"","page":"Home","title":"Home","text":"The FiniteMPS object then handles the gauging of the MPS, which is necessary for many of the algorithms. This is done automatically when needed, and the user can access the gauged tensors by getting and setting the AL, AR, CR/CL and AC fields, which each represent a vector of these tensors.","category":"page"},{"location":"","page":"Home","title":"Home","text":"al = mps.AL[3] # left gauged tensor of the third site\n@tensor E[a; b] := al[c, d, b] * conj(al[c, d, a])\n@show isapprox(E, id(right_virtualspace(mps, 3)))","category":"page"},{"location":"","page":"Home","title":"Home","text":"ar = mps.AR[3] # right gauged tensor of the third site\n@tensor E[a; b] := ar[a, d, c] * conj(ar[b, d, c])\n@show isapprox(E, id(left_virtualspace(mps, 3)))","category":"page"},{"location":"","page":"Home","title":"Home","text":"As the mps will be kept in a gauged form, updating a tensor will also update the gauged tensors. For example, we can set the tensor of the third site to the identity, and the gauged tensors will be updated accordingly.","category":"page"},{"location":"","page":"Home","title":"Home","text":"mps.C[3] = id(domain(mps.C[3]))\nmps","category":"page"},{"location":"","page":"Home","title":"Home","text":"These objects can then be used to compute observables and expectation values. For example, the expectation value of the identity operator at the third site, which is equal to the norm of the MPS, can be computed as:","category":"page"},{"location":"","page":"Home","title":"Home","text":"N1 = LinearAlgebra.norm(mps)\nN2 = expectation_value(mps, 3 => id(physicalspace(mps, 3)))\nprintln(\"‖mps‖ = $N1\")\nprintln(\" = $N2\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"Finally, the MPS can be optimized in order to determine groundstates of given Hamiltonians. Using the pre-defined models in MPSKitModels, we can construct the groundstate for the transverse field Ising model:","category":"page"},{"location":"","page":"Home","title":"Home","text":"J = 1.0\ng = 0.5\nlattice = fill(ComplexSpace(2), 10)\nX = TensorMap(ComplexF64[0 1; 1 0], ComplexSpace(2), ComplexSpace(2))\nZ = TensorMap(ComplexF64[1 0; 0 -1], space(X))\nH = FiniteMPOHamiltonian(lattice, (i, i+1) => -J * X ⊗ X for i in 1:length(lattice)-1) +\n FiniteMPOHamiltonian(lattice, (i,) => - g * Z for i in 1:length(lattice))\nfind_groundstate!(mps, H, DMRG(; maxiter=10))\nE0 = expectation_value(mps, H)\nprintln(\" = $real(E0)\")","category":"page"},{"location":"#Infinite-Matrix-Product-States","page":"Home","title":"Infinite Matrix Product States","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"using LinearAlgebra\nusing TensorOperations\nusing TensorKit\nusing MPSKit","category":"page"},{"location":"","page":"Home","title":"Home","text":"Similarly, an infinite MPS can be constructed by specifying the tensors for the unit cell, characterised by the spaces (dimensions) thereof.","category":"page"},{"location":"","page":"Home","title":"Home","text":"d = 2 # physical dimension\nD = 5 # virtual dimension\nmps = InfiniteMPS(d, D) # random MPS","category":"page"},{"location":"","page":"Home","title":"Home","text":"The InfiniteMPS object then handles the gauging of the MPS, which is necessary for many of the algorithms. This is done automatically upon creation of the object, and the user can access the gauged tensors by getting and setting the AL, AR, C and AC fields, which each represent a (periodic) vector of these tensors.","category":"page"},{"location":"","page":"Home","title":"Home","text":"al = mps.AL[1] # left gauged tensor of the first site\n@tensor E[a; b] := al[c, d, b] * conj(al[c, d, a])\n@show isapprox(E, id(left_virtualspace(mps, 1)))","category":"page"},{"location":"","page":"Home","title":"Home","text":"ar = mps.AR[1] # right gauged tensor of the first site\n@tensor E[a; b] := ar[a, d, c] * conj(ar[b, d, c])\n@show isapprox(E, id(right_virtualspace(mps, 2)))","category":"page"},{"location":"","page":"Home","title":"Home","text":"As regauging the MPS is not possible without recomputing all the tensors, setting a single tensor is not supported. Instead, the user should construct a new mps object with the desired tensor, which will then be gauged upon construction.","category":"page"},{"location":"","page":"Home","title":"Home","text":"als = 3 .* mps.AL\nmps = InfiniteMPS(als)","category":"page"},{"location":"","page":"Home","title":"Home","text":"These objects can then be used to compute observables and expectation values. For example, the norm of the MPS, which is equal to the expectation value of the identity operator can be computed by:","category":"page"},{"location":"","page":"Home","title":"Home","text":"N1 = norm(mps)\nN2 = expectation_value(mps, 1 => id(physicalspace(mps, 1)))\nprintln(\"‖mps‖ = $N1\")\nprintln(\" = $N2\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"note: Normalization of infinite MPS\nBecause infinite MPS cannot sensibly be normalized to anything but 1, the norm of an infinite MPS is always set to be 1 at construction. If this were not the case, any observable computed from the MPS would either blow up to infinity or vanish to zero.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Finally, the MPS can be optimized in order to determine groundstates of given Hamiltonians. There are plenty of pre-defined models in MPSKitModels, but we can also manually construct the groundstate for the transverse field Ising model:","category":"page"},{"location":"","page":"Home","title":"Home","text":"J = 1.0\ng = 0.5\nlattice = PeriodicVector([ComplexSpace(2)])\nX = TensorMap(ComplexF64[0 1; 1 0], ComplexSpace(2), ComplexSpace(2))\nZ = TensorMap(ComplexF64[1 0; 0 -1], space(X))\nH = InfiniteMPOHamiltonian(lattice, (1, 2) => -J * X ⊗ X, (1,) => - g * Z)\nmps, = find_groundstate(mps, H, VUMPS(; maxiter=10))\nE0 = expectation_value(mps, H)\nprintln(\" = $(sum(real(E0)) / length(mps))\")","category":"page"},{"location":"#Additional-Resources","page":"Home","title":"Additional Resources","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"For more detailed information on the functionality and capabilities of MPSKit, refer to the Manual section, or have a look at the Examples page.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Keep in mind that the documentation is still a work in progress, and that some features may not be fully documented yet. If you encounter any issues or have questions, please check the library's issue tracker on the GitHub repository and open a new issue.","category":"page"}] }