Sweeping through the MPS

At a lower level of abstraction, TenNetLib.jl allows to control each fullsweep (left-to-right and right-to-left) manually to update StateEnvs.

Skip this part if you want to avoid lower-level abstraction.

SweepData

TenNetLib.jl defines a struct, called SweepData, to store essential data after each fullsweep.

TenNetLib.SweepDataType
mutable struct SweepData
    sweepcount::Int
    maxchi::Vector{Int}
    energy::Vector{Float64}
    entropy::Vector{Float64}
    maxtruncerr::Vector{Float64}
    lasteigs::Vector{Vector{Float64}}
end

Holds historical data after each (full)sweep. Requires for convergence check etc.

  • sweepcount::Int: Number of fullsweeps performed.
  • maxchi::Vector{Int}: Maximum MPS bond/link dimensions after every sweep.
  • energy::Vector{Float64}: Energies after every sweep.
  • entropy::Vector{Float64}: Mid-chain entropies after every sweep.
  • maxtrucerr::Vector{Float64}: Maximum truncation error after every sweep.
  • lasteigs::Vector{Vector{Float64}}: Spectrum of eigenvalues at each bond after previous halfsweep.

Default constructor:

  • SweepData(): Initialize an empty SweepData object.
source
Base.copyMethod
Base.copy(swdata::SweepData)

Shallow copy of SweepData.

source

Perform a fullsweep

TenNetLib.fullsweep!Method
function fullsweep!(sysenv::StateEnvs, solver, nsite::Int, swdata::SweepData;
                    kwargs...)

Perform a fullsweep (left-to-right and right-to-left) by solver.

Arguments:

  • sysenv::StateEnvs.
  • solver: Solver for update. Available ones: eig_solver and exp_solver.
  • nsite::Int of the environment. Either 1 or 2 for one-site or two-site update respectively.
  • swdata::SweepData.

Named arguments and their default values:

  • time_step::Union{Float64, ComplexF64, Nothing} = nothing: Time step for TDVP.
  • normalize::Bool = true: Whether to normalize after update.
  • maxdim::Int = typemax(Int): Maximum bond dimension after SVD truncation.
  • mindim::Int = 1: Minimum bond dimension after SVD truncation.
  • cutoff::Float64 = Float64_threshold(): Cutoff for SVD truncation.
  • svd_alg::String = "divide_and_conquer".
  • noise::Float64 = 0.0.
  • reverse_step::Bool = false if time_step = nothing, true otherwise.
  • outputlevel::Int = 1. If 0 prints no information, for 1 outputs after every fullsweep, if 2 prints at every update step.

Named arguments for solver and their default values:

See the documentation of KrylovKit.jl.

  • ishermitian::Bool = true.
  • solver_tol::Float64 = 1E-14 if eig_solver, 1E-12 if exp_solver.
  • solver_krylovdim::Int = 5 if eig_solver, 30 if exp_solver.
  • solver_maxiter::Int = 2 if eig_solver, 100 if exp_solver.
  • solver_outputlevel::Int = 0: See verbosity in KrylovKit.jl.
  • solver_eager::Bool = false if eig_solver, true if exp_solver.
  • solver_check_convergence::Bool = false if eig_solver, true if exp_solver.

Return values:

  • ::Float64: Change in Energy ΔE
  • ::Float64: Change in Entropy ΔS

swdata::SweepData gets updated.

source

Perform a dynamical fullsweep

TenNetLib.jl defines the following function to dynamically decide whether to perform single- or two-site update at each bond, depending on the entropy growth at the previous halfsweep.

TenNetLib.dynamic_fullsweep!Method
function dynamic_fullsweep!(sysenv::StateEnvs, solver, swdata::SweepData;
                            kwargs...)

Perform a dynamic fullsweep (left-to-right and right-to-left) by solver. The very first sweep, as dictated by swdata.sweepcount=0, Global Subspace Expansion (see below) is performed followed by a pure one-site sweep if typeof(sysenv) == StateEnvs{ProjMPO}, else performs a full two-site sweep. At each bond, if the lowest eigenvalue is below eigthreshold or the bond dimension at that bond has reached maxdim at a particular halfsweep, performs single-site update across that bond in the subsequent halfsweep, otherwise performs two-site update.

Arguments:

  • sysenv::StateEnvs.
  • solver: Solver for update. Available ones: eig_solver and exp_solver.
  • swdata::SweepData.

Named arguments and their default values:

  • time_step::Union{Float64, ComplexF64, Nothing} = nothing: Time step for TDVP.
  • normalize::Bool = true: Whether to normalize after update.
  • maxdim::Int = typemax(Int): Maximum bond dimension after SVD truncation.
  • mindim::Int = 1: Minimum bond dimension after SVD truncation.
  • cutoff::Float64 = Float64_threshold(): Cutoff for SVD truncation.
  • svd_alg::String = "divide_and_conquer".
  • noise::Float64 = 0.0.
  • reverse_step::Bool = false if time_step = nothing, true otherwise.
  • outputlevel::Int = 1. If 0 prints no information, for 1 outputs after every fullsweep, if 2 prints at every update step.
  • eigthreshold::Float64 = 1E-12.
  • extendat::Union{Nothing, Int} = nothing: If specified, at every extendatth sweep, Global Subspace Expansion is performed followed by a pure one-site sweep if typeof(sysenv) == StateEnvs{ProjMPO}, else performs a full two-site sweep.

Named arguments for solver and their default values:

See the documentation of KrylovKit.jl.

  • ishermitian::Bool = true.
  • solver_tol::Float64 = 1E-14 if eig_solver, 1E-12 if exp_solver.
  • solver_krylovdim::Int = 3 if eig_solver, 30 if exp_solver.
  • solver_maxiter::Int = 1 if eig_solver, 100 if exp_solver.
  • solver_outputlevel::Int = 0: See verbosity in KrylovKit.jl.
  • solver_eager::Bool = false if eig_solver, true if exp_solver.
  • solver_check_convergence::Bool = false if eig_solver, true if exp_solver.

Arguments for Global Subspace Expansion and their default values:

  • extension_krylovdim::Int = 3: Number of Krylov vectors used for GSE.
  • extension_applyH_cutoff::Float64 = 0.0: Cutoff for the application of the MPO to the MPS.
  • extension_applyH_maxdim::Int = maxlinkdim(psi) + 1: Maximum bond/link dimension for the application of the MPO to the MPS.
  • extension_cutoff::Float64 = 1E-10: Cutoff for the basis extension step in GSE.

Return values:

  • ::Float64: Change in Energy ΔE
  • ::Float64: Change in Entropy ΔS

swdata::SweepData gets updated.

source

Global Subspace Expansion

Following Phys. Rev. B 102, 094315 (2020), a Global Subspace Expansion can be performed using Krylov subspace if the environments are created by a single MPO.

TenNetLib.krylov_extend!Method
function krylov_extend!(psi::MPS, H::MPO; kwargs...)

Performs Global Subspace Expansion.

Named arguments and their default values:

  • extension_krylovdim::Int = 3: Number of Krylov vectors used for GSE.
  • extension_applyH_cutoff::Float64 = Float64_threshold(): Cutoff for the application the MPO to the MPS.
  • extension_applyH_maxdim::Int = maxlinkdim(psi) + 1: Maximum bond/link dimension of the resulting MPS after the application of the MPO to the MPS.
  • extension_cutoff::Float64 = 1E-10: Cutoff for the basis extension step in GSE.
source
TenNetLib.krylov_extend!Method
function krylov_extend!(sysenv::StateEnvs{ProjMPO}; kwargs...)

Performs Global Subspace Expansion. The StateEnvs must be created by a single MPO.

Named arguments and their default values:

  • extension_krylovdim::Int = 3: Number of Krylov vectors used for GSE.
  • extension_applyH_cutoff::Float64 = Float64_threshold(): Cutoff for the application the MPO to the MPS.
  • extension_applyH_maxdim::Int = maxlinkdim(psi) + 1: Maximum bond/link dimension of the resulting MPS after the application of the MPO to the MPS.
  • extension_cutoff::Float64 = 1E-10: Cutoff for the basis extension step in GSE.
source
Info

Apart from TDVP, Global Subspace Expansion is also very useful for DMRG to get rid of nasty local minimas.