### Perform Sequential Single-Site and Two-Site DMRG Updates Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/example_dmrg.md This snippet demonstrates performing sequential DMRG updates using the lower-level `StateEnvs` interface. It first performs a two-site update with noise for better convergence, followed by a single-site update without noise. This approach is often beneficial for achieving better results. ```julia sysenv = StateEnvs(psi0, H) params2 = DMRGParams(;nsweeps = [10, 10], maxdim = [20, 50], cutoff = 1e-14, noise = 1e-3, noisedecay = 2, disable_noise_after = 5) dmrg!(sysenv, params2, 2) params1 = DMRGParams(;nsweeps = [10], maxdim = [50], cutoff = 0.0) dmrg!(sysenv, params1, 1) ``` -------------------------------- ### Run Simple DMRG with TenNetLib.jl Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/index.md This example demonstrates a basic Density Matrix Renormalization Group (DMRG) calculation using TenNetLib.jl at the highest level of abstraction. It initializes a spin-1/2 chain, defines the Hamiltonian, and performs a DMRG sweep with specified parameters. ```julia using ITensors using ITensorMPS using TenNetLib let N = 32 sites = siteinds("S=1/2",N) os = OpSum() for j=1:N-1 os += 1, "Sz", j,"Sz", j+1 os += 0.5, "S+", j, "S-", j+1 os += 0.5, "S-", j, "S+", j+1 end H = MPO(os,sites) states = [isodd(n) ? "Up" : "Dn" for n in 1:N] psi0 = MPS(sites, states) params = DMRGParams(;nsweeps = [5, 5], maxdim = [20, 50], cutoff = 1e-14, noise = 1e-3, noisedecay = 2, disable_noise_after = 3) # dmrg2 for two-site DMRG en, psi = dmrg2(psi0, H, params) end ``` -------------------------------- ### Optimize TTN Excited State Search Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/ttn/example_optimize.md Demonstrates how to perform an excited state search with TTN optimization. It builds upon the ground state setup by providing an initial guess for the excited state (`psi_gr`) to the `optimize` function. This allows for finding excited state energies and wavefunctions. ```julia # Given a ground state `psi_gr`, initial TTN `psi0`, # and a Hamiltonian `H` en, psi = optimize(psi0, H, [psi_gr], params, sweeppath; weight = 10.0) ``` -------------------------------- ### Perform Ground State DMRG using OpStrings and CouplingModel Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/example_dmrg.md This snippet demonstrates a straightforward ground state DMRG calculation using the higher-level `OpStrings` and `CouplingModel` from TenNetLib.jl. It initializes sites, constructs the Hamiltonian, defines an initial state, and then runs the DMRG algorithm with specified parameters. It can use either `dmrg2` for two-site updates or `dmrg1` for single-site updates. ```julia using ITensors using ITensorMPS using TenNetLib let N = 32 sites = siteinds("S=1/2",N) os = OpStrings() for j=1:N-1 os += 1, "Sz" => j, "Sz" => j+1 os += 0.5, "S+" => j, "S-" => j+1 os += 0.5, "S-" => j, "S+" => j+1 end H = CouplingModel(os,sites) states = [isodd(n) ? "Up" : "Dn" for n in 1:N] psi0 = MPS(sites, states) params = DMRGParams(;nsweeps = [10, 10], maxdim = [20, 50], cutoff = 1e-14, noise = 1e-3, noisedecay = 2, disable_noise_after = 5) # dmrg2 for two-site DMRG en, psi = dmrg2(psi0, H, params) # or dmrg1 for single-site DMRG # en, psi = dmrg1(psi0, H, params) end ``` -------------------------------- ### Install TenNetLib.jl and Dependencies Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/index.md This snippet shows how to install the TenNetLib.jl library along with its core dependencies, ITensors.jl and ITensorMPS.jl, using the Julia package manager. ```julia julia> ] pkg> add ITensors pkg> add ITensorMPS pkg> add TenNetLib ``` -------------------------------- ### TDVP with Single-Site Updates using TenNetLib.jl Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/example_tdvp.md Performs time-evolution using TDVP with exclusively single-site updates. This is an alternative to the 'dynamic' sweep selection. It requires the ITensors and TenNetLib packages. Inputs include an initial state (psi0), a Hamiltonian (H), and time-step parameters. Outputs are the evolved state and error information. ```julia using ITensors using TenNetLib let N = 32 sites = siteinds("S=1/2",N) os = OpSum() for j=1:N-1 os += 1, "Sz", j, "Sz", j+1 os += 0.5, "S+", j, "S-", j+1 os += 0.5, "S-", j, "S+", j+1 end H = MPO(os,sites) states = [isodd(n) ? "Up" : "Dn" for n in 1:N] psi0 = MPS(sites, states) tau = -0.01im engine = TDVPEngine(psi0, H) for ii = 1:100 # GSE at every 5th sweep. if ii % 5 == 1 krylov_extend!(engine) end # `nsite = 1` for single-site update tdvpsweep!(engine, tau, nsite = 1; maxdim = 200, cutoff = 1E-12) # Errors in the last sweep and the total error till this point swerr = sweeperror(engine) totalerr = totalerror(engine) psi = getpsi(engine) # DO STUFF end end ``` -------------------------------- ### Perform Ground State DMRG using StateEnvs (Lower-Level) Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/example_dmrg.md This snippet shows how to perform a ground state DMRG calculation using the lower-level `StateEnvs` interface for more control. It initializes the `StateEnvs` with the initial state and Hamiltonian, then uses `dmrg!` to perform the update. The energy can be retrieved from the `Sweepdata`, and the resulting MPS can be obtained via `getpsi` or directly from `sysenv.psi` (with a caution). ```julia sysenv = StateEnvs(psi0, H) nsite = 2 # two-site update swdata = dmrg!(sysenv, params, nsite) # Get energy from `Sweepdata` energy = swdata.energy[end] # take a shallow copy of the MPS # if the `StateEnvs` will be updated later again psi = getpsi(sysenv) # Alternatively, take the psi from `StateEnvs` itself. # NOTE: This can crash the simulation, if the MPS is modified (e.g., in measurements) # and `StateEnvs` is going to be updated later on. # psi = sysenv.psi ``` -------------------------------- ### Time-Dependent Hamiltonian Evolution with TenNetLib.jl Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/example_tdvp.md Simulates time-evolution with a time-dependent Hamiltonian using TDVP. The Hamiltonian is updated at each time step using the `updateH!` function. This requires the ITensors and TenNetLib packages. Inputs include an initial state, an initial Hamiltonian, and time-step parameters. Outputs are the evolved state and error information. ```julia using ITensors using TenNetLib function makeHt(sites, t) os = OpSum() for j=1:N-1 os += 1, "Sz", j, "Sz", j+1 os += 0.5, "S+", j, "S-", j+1 os += 0.5, "S-", j, "S+", j+1 end for j=1:N os += t, "Sz", j end return MPO(os,sites) end let N = 32 sites = siteinds("S=1/2",N) states = [isodd(n) ? "Up" : "Dn" for n in 1:N] psi0 = MPS(sites, states) dt = 0.01 tau = -im * dt H0 = makeHt(sites, 0.0) engine = TDVPEngine(psi0, H0) for ii = 1:100 # `nsite = "dynamic"` for dynamical selection between # single- and two-site variants at different bonds tdvpsweep!(engine, tau, nsite = "dynamic"; maxdim = 200, cutoff = 1E-12, extendat = 5) # Errors in the last sweep and the total error till this point swerr = sweeperror(engine) totalerr = totalerror(engine) psi = getpsi(engine) # DO STUFF # update Hamiltonian for the next iteration Ht = makeHt(ii*dt) updateH!(engine, Ht) end end ``` -------------------------------- ### Optimize TTN Ground State Search with StateEnvsTTN Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/ttn/example_optimize.md Provides lower-level control for TTN ground state optimization using `StateEnvsTTN`. It initializes the state environment, performs the optimization using `optimize!`, and retrieves the final energy and TTN state. This method offers more granular control over the optimization process. ```julia sysenv = StateEnvsTTN(psi0, H) swdata = optimize!(sysenv, params, sweeppath) # Get energy from `Sweepdata` energy = swdata.energy[end] # take a shallow copy of the TTN # if the `StateEnvsTTN` will be updated later again psi = getpsi(sysenv) # Alternatively, take the psi from `StateEnvsTTN` itself. # NOTE: This can crash the simulation, if the TTN is modified (e.g., in measurements) # and `StateEnvsTTN` is going to be updated later on. # psi = sysenv.psi ``` -------------------------------- ### Run Simple TDVP with TenNetLib.jl Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/index.md This example illustrates a basic Time Dependent Variational Principle (TDVP) calculation using TenNetLib.jl. It sets up a spin-1/2 chain, defines the Hamiltonian, and then iteratively evolves the state using the TDVP engine with dynamic site selection. ```julia using ITensors using ITensorMPS using TenNetLib let N = 32 sites = siteinds("S=1/2",N) os = OpSum() for j=1:N-1 os += 1, "Sz", j,"Sz", j+1 os += 0.5, "S+", j, "S-", j+1 os += 0.5, "S-", j, "S+", j+1 end H = MPO(os,sites) states = [isodd(n) ? "Up" : "Dn" for n in 1:N] psi0 = MPS(sites, states) tau = -0.01im engine = TDVPEngine(psi0, H) for ii = 1:100 # `nsite = "dynamic"` for dynamical selection between # single- and two-site variants at different bonds tdvpsweep!(engine, tau, nsite = "dynamic"; maxdim = 200, cutoff = 1E-12, extendat = 5) psi = getpsi(engine) # DO STUFF end end ``` -------------------------------- ### Optimize TTN Excited State Search with StateEnvsTTN Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/ttn/example_optimize.md Illustrates excited state search using the lower-level `StateEnvsTTN`. Similar to the ground state version, it initializes `StateEnvsTTN` but includes an excited state guess (`[psi_gr]`) and a `weight` parameter. The `optimize!` function then computes the excited state properties. ```julia sysenv_ex = StateEnvsTTN(psi0, H, [psi_gr]; weight = 10.0) swdata_ex = optimize!(sysenv_ex, params, sweeppath) # Get energy from `Sweepdata` energy1 = swdata_ex.energy[end] # take a shallow copy of the TTN # if the `StateEnvsTTN` will be updated later again psi1 = getpsi(sysenv_ex) # Alternatively, take the psi from `StateEnvsTTN` itself. # NOTE: This can crash the simulation, if the TTN is modified (e.g., in measurements) # and `StateEnvsTTN` is going to be updated later. # psi1 = sysenv_ex.psi ``` -------------------------------- ### Apply Global Subspace Expansion to Avoid Local Minima Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/example_dmrg.md This snippet shows how to use Global Subspace Expansion with `krylov_extend!` to help overcome local minima in DMRG calculations. This method is applicable when the `StateEnvs` is built from a single MPO. It's important to carefully choose the parameters for `krylov_extend!` as it can significantly increase the MPS bond dimension. ```julia krylov_extend!(sysenv; extension_applyH_maxdim = 40) ``` -------------------------------- ### Perform Excited State DMRG using StateEnvs (Lower-Level) Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/example_dmrg.md This snippet illustrates performing an excited state DMRG calculation using the lower-level `StateEnvs` interface. The `StateEnvs` is initialized with the initial MPS, Hamiltonian, and a list of excited states (e.g., `[psi_gr]`), along with a `weight`. The `dmrg!` function is then used for the update, and results are accessed similarly to the ground state calculation. ```julia sysenv_ex = StateEnvs(psi0, H, [psi_gr]; weight = 10.0) nsite = 2 # two-site update swdata_ex = dmrg!(sysenv_ex, params, nsite) # Get energy from `Sweepdata` energy1 = swdata_ex.energy[end] # take a shallow copy of the MPS # if the `StateEnvs` will be updated later again psi1 = getpsi(sysenv_ex) # Alternatively, take the psi from `StateEnvs` itself. # NOTE: This can crash the simulation, if the MPS is modified (e.g., in measurements) # and `StateEnvs` is going to be updated later. # psi1 = sysenv_ex.psi ``` -------------------------------- ### Perform Excited State DMRG using OpStrings and CouplingModel Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/example_dmrg.md This snippet demonstrates how to perform an excited state DMRG calculation using the higher-level interface. It requires a ground state `psi_gr`, an initial MPS `psi0`, and a Hamiltonian `H`. The `weight` parameter controls the importance of the excited state. It supports both `dmrg2` (two-site) and `dmrg1` (single-site) updates. ```julia # Given a ground state `psi_gr`, initial MPS `psi0`, # and a Hamiltonian `H` # dmrg2 for two-site DMRG en, psi = dmrg2(psi0, H, [psi_gr], params; weight = 10.0) # or dmrg1 for single-site DMRG # en, psi = dmrg1(psi0, H, [psi_gr], params; weight = 10.0) ``` -------------------------------- ### Optimize TTN Ground State Search Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/ttn/example_optimize.md Performs a straightforward TTN optimization to find the ground state. It initializes sites, constructs a Hamiltonian from OpStrings, generates a random TTN, and defines optimization parameters and sweep path. The `optimize` function is then called to find the ground state energy and wavefunction. ```julia using ITensors using ITensorMPS using TenNetLib let N = 32 sites = siteinds("S=1/2",N) os = OpStrings() for j=1:N-1 os += 1, "Sz" => j, "Sz" => j+1 os += 0.5, "S+" => j, "S-" => j+1 os += 0.5, "S-" => j, "S+" => j+1 end H = CouplingModel(os,sites) psi0 = default_randomTTN(sites, 12, QN("Sz", 0)) sweeppath = default_sweeppath(psi0) params = OptimizeParamsTTN(; nsweeps = [10, 10], maxdim = [20, 50], cutoff = 1e-14, noise = 1e-3, noisedecay = 2, disable_noise_after = 5) en, psi = optimize(psi0, H, params, sweeppath) end ``` -------------------------------- ### Node and Edge Operations for Graph (Julia) Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/base/graph.md Provides functions to manage nodes and edges within the `Graph` object. This includes getting nodes, checking for node existence, adding nodes and edges, and verifying if two nodes are neighbors. ```julia getnodes(graph::Graph{T}) where T hasnode(graph::Graph{T}, node::T) where T addnode!(graph::Graph{T}, node::T) where T addedge!(graph::Graph{T}, node1::T, node2::T) where T isneighbor(graph::Graph{T}, node1::T, node2::T) where T ``` -------------------------------- ### TDVP with Dynamical Sweeps using TenNetLib.jl Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/example_tdvp.md Performs time-evolution using the Time-Dependent Variational Principle (TDVP) with dynamical sweeps. This method automatically selects between single- and two-site updates at different bonds for efficiency. It requires the ITensors and TenNetLib packages. Inputs include an initial state (psi0), a Hamiltonian (H), and time-step parameters. Outputs are the evolved state and error information. ```julia using ITensors using ITensorMPS using TenNetLib let N = 32 sites = siteinds("S=1/2",N) os = OpSum() for j=1:N-1 os += 1, "Sz", j, "Sz", j+1 os += 0.5, "S+", j, "S-", j+1 os += 0.5, "S-", j, "S+", j+1 end H = MPO(os,sites) states = [isodd(n) ? "Up" : "Dn" for n in 1:N] psi0 = MPS(sites, states) tau = -0.01im engine = TDVPEngine(psi0, H) for ii = 1:100 # `nsite = "dynamic"` for dynamical selection between # single- and two-site variants at different bonds tdvpsweep!(engine, tau, nsite = "dynamic"; maxdim = 200, cutoff = 1E-12, extendat = 5) # Errors in the last sweep and the total error till this point swerr = sweeperror(engine) totalerr = totalerror(engine) psi = getpsi(engine) # DO STUFF end end ``` -------------------------------- ### DMRG Single-Site Algorithm (dmrg1) in Julia Source: https://context7.com/titaschanda/tennetlib.jl/llms.txt Implements the single-site Density Matrix Renormalization Group algorithm, which updates one tensor at a time. This method is generally faster but may be more prone to getting stuck in local minima, making it suitable for refining results from two-site DMRG. Requires ITensors.jl, ITensorMPS.jl, and TenNetLib.jl. ```julia using ITensors using ITensorMPS using TenNetLib N = 64 sites = siteinds("S=1", N) # Spin-1 chain os = OpSum() for j = 1:N-1 os += 1, "Sz", j, "Sz", j+1 os += 0.5, "S+", j, "S-", j+1 os += 0.5, "S-", j, "S+", j+1 end H = MPO(os, sites) # Random initial state psi0 = random_mps(sites; linkdims=10) params = DMRGParams(; nsweeps = [20], maxdim = [200], cutoff = 1e-12 ) # Single-site DMRG (faster, fixed bond dimension) energy, psi = dmrg1(psi0, H, params; outputlevel = 1, solver_krylovdim = 5, solver_maxiter = 2 ) ``` -------------------------------- ### CouplingModel Constructors and Methods Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/base/couplingmodel.md This section details the constructors for the CouplingModel and its associated methods for length, copying, indexing, and retrieving site indices. ```APIDOC ## `CouplingModel` TenNetLib.jl defines a struct called `CouplingModel` to store Hamiltonian terms. In case of MPS based algorithms, `CouplingModel` can replace `MPO` without modifying the rest of the code. For Tree Tensor Network (TTN) codes, only `CouplingModel` can be used. Different elements of `CouplingModel` are contracted in parallel. ### Constructors #### `CouplingModel(os::OpStrings{T1}, sites::Vector{Index{T2}}; merge::Bool = true, maxdim::Int = typemax(Int), mindim::Int = 1, cutoff::Float64 = Float64_threashold(), svd_alg::String = "divide_and_conquer", chunksize::Int = 12) where {T1 <: Number, T2}` Creates a `CouplingModel` from `OpStrings` and a vector of `Index` objects representing the sites. #### `CouplingModel(os::OpStrings{T1}, mpo::MPO; merge::Bool = true, maxdim::Int = typemax(Int), mindim::Int = 1, cutoff::Float64 = Float64_threashold(), svd_alg::String = "divide_and_conquer", chunksize::Int = 12) where {T1 <: Number}` Creates a `CouplingModel` from `OpStrings` and an `MPO`. #### `CouplingModel(mpos::MPO...)` Creates a `CouplingModel` from a variadic list of `MPO` objects. ### Methods #### `Base.length(model::CouplingModel)` Returns the number of elements in the `CouplingModel`. #### `Base.copy(model::CouplingModel)` Creates a deep copy of the `CouplingModel`. #### `Base.getindex(model::CouplingModel, n)` Retrieves the element at the specified index `n` from the `CouplingModel`. #### `ITensorMPS.siteinds(model::CouplingModel)` Returns the site indices associated with the `CouplingModel`. ``` -------------------------------- ### Perform a dynamical fullsweep Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/sweep.md Documentation for the `dynamic_fullsweep!` function, which dynamically decides between single- or two-site updates based on entropy growth. ```APIDOC ## Perform a dynamical fullsweep ### Description The `dynamic_fullsweep!` function intelligently performs a fullsweep by dynamically choosing between single-site or two-site updates at each bond. This decision is based on the observed entropy growth from the preceding halfsweep, allowing for adaptive optimization. ### Method `dynamic_fullsweep!` ### Parameters - `sysenv::StateEnvs`: The state environment to be updated. - `solver`: The solver configuration. - `swdata::SweepData`: The `SweepData` object to store results. - `kwargs...`: Additional keyword arguments. ``` -------------------------------- ### MPO Construction from OpStrings (Julia) Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/base/opstrings.md Demonstrates how to construct a Matrix Product Operator (MPO) from OpStrings. This function allows for the conversion of an operator sum represented by OpStrings into an MPO format compatible with tensor network algorithms. ```julia ITensorMPS.MPO(os::OpStrings{T1}, sites::Vector{Index{T2}}; maxdim::Int = typemax(Int), mindim::Int = 1, cutoff::Float64 = Float64_threashold(), svd_alg::String = "divide_and_conquer", chunksize::Int = 12) where {T1 <: Number, T2} ``` -------------------------------- ### Perform Dynamical Fullsweep in TenNetLib.jl Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/sweep.md Details the dynamic_fullsweep! function in TenNetLib.jl, which adaptively chooses between single- or two-site updates based on entropy growth from the previous halfsweep. It requires system environments, a solver, and sweep data. ```julia ```@docs dynamic_fullsweep!(sysenv::StateEnvs, solver, swdata::SweepData; kwargs...) ``` ``` -------------------------------- ### Graph Traversal and Pathfinding Algorithms (Julia) Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/base/graph.md Implements graph traversal and pathfinding algorithms. Includes Breadth-First Search (BFS), finding nodes from BFS, shortest path calculation, and identifying the next node in a path. ```julia bfs(graph::Graph{T}, source::T, destination::Union{Nothing, T} = nothing) where T nodes_from_bfs(graph::Graph{T}, source::T;reverse::Bool = false) where T shortest_path(graph::Graph{T}, source::T, destination::T) where T nextnode_in_path(graph::Graph{T}, source::T, destination::T, n=1) where T ``` -------------------------------- ### Perform a fullsweep Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/sweep.md Documentation for the `fullsweep!` function, which performs a left-to-right and right-to-left sweep to update `StateEnvs`. ```APIDOC ## Perform a fullsweep ### Description The `fullsweep!` function executes a complete sweep operation, encompassing both left-to-right and right-to-left passes, to update the `StateEnvs`. ### Method `fullsweep!` ### Parameters - `sysenv::StateEnvs`: The state environment to be updated. - `solver`: The solver configuration. - `nsite::Int`: The number of sites for the sweep. - `swdata::SweepData`: The `SweepData` object to store results. - `kwargs...`: Additional keyword arguments. ``` -------------------------------- ### TDVPEngine Struct and Methods (Julia) Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/tdvp.md The TDVPEngine struct stores data for TDVP sweeps. It provides methods to access the quantum state (psi), sweep count, energy, entropy, maximum bond dimension (chi), total error, sweep error, and time. It also includes functions to update the Hamiltonian and copy the engine. ```julia struct TDVPEngine # ... fields for TDVP state ... end TDVPEngine(psi::MPS, H::T) where T <: Union{MPO, Vector{MPO}, CouplingModel} TDVPEngine(psi::MPS, H::T, Ms::Vector{MPS}; weight::Float64) getpsi(engine::TDVPEngine) sweepcount(engine::TDVPEngine) getenergy(engine::TDVPEngine) getentropy(engine::TDVPEngine) maxchi(engine::TDVPEngine) totalerror(engine::TDVPEngine) sweeperror(engine::TDVPEngine) krylov_extend!(engine::TDVPEngine{ProjMPO}; kwargs...) sweepdata(engine::TDVPEngine) abstime(engine::TDVPEngine) updateH!(engine::TDVPEngine, H::T; recalcEnv::Bool = true) where T <: Union{MPO, Vector{MPO}, CouplingModel} updateH!(engine::TDVPEngine, H::T, Ms::Vector{MPS}; weight::Float64, recalcEnv::Bool = true) where T <: Union{MPO, Vector{MPO}, CouplingModel} Base.copy(engine::TDVPEngine) ``` -------------------------------- ### TTN Ground-State Optimization with OpStrings and CouplingModel (Julia) Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/index.md This code performs a TTN ground-state optimization at the highest level of abstraction. It utilizes OpStrings and CouplingModel for Hamiltonian definition and TenNetLib's default functions for state initialization, sweep path generation, and optimization parameters. The output includes the optimized ground-state energy and the corresponding TTN state. ```julia using ITensors using ITensorMPS using TenNetLib let N = 32 sites = siteinds("S=1/2",N) os = OpStrings() for j=1:N-1 os += 1, "Sz" => j,"Sz" => j+1 os += 0.5, "S+" => j, "S-" => j+1 os += 0.5, "S-"=> j, "S+" => j+1 end H = CouplingModel(os,sites) psi0 = default_randomTTN(sites, 64, QN("Sz", 0)) sweeppath = default_sweeppath(psi0) params = OptimizeParamsTTN(; maxdim = [64, 128], nsweeps = [5, 10], cutoff = 1e-14, noise = 1e-2, noisedecay = 5, disable_noise_after = 5) en, psi = optimize(psi0, H, params, sweeppath) end ``` -------------------------------- ### Time Evolution with tdvpsweep! Source: https://context7.com/titaschanda/tennetlib.jl/llms.txt Performs time evolution using the TD-VP sweep algorithm. It takes an engine, a time step (tau), and various sweep parameters. The function updates the state of the engine over a specified number of steps, allowing for real-time evolution when tau is negative imaginary. ```julia dt = 0.05 tau = -im * dt # Run 100 time steps for step = 1:100 tdvpsweep!(engine, tau; nsite = "dynamic", # Dynamically choose 1-site or 2-site maxdim = 200, # Max bond dimension cutoff = 1e-12, # SVD cutoff extendat = 10, # Subspace expansion every 10 sweeps outputlevel = step % 10 == 0 ? 1 : 0 ) # Get current state and measurements psi = getpsi(engine) t = abstime(engine) E = getenergy(engine) if step % 20 == 0 println("t = $t, E = $E, chi = $(maxchi(engine))") end end ``` -------------------------------- ### StateEnvs for Custom Tensor Network Sweeps with TenNetLib Source: https://context7.com/titaschanda/tennetlib.jl/llms.txt Wraps an MPS and its environments to enable custom sweep algorithms, offering full control over the optimization process. It supports initialization with MPS and Hamiltonian or CouplingModel, setting the number of sites, positioning the environment, and utilizing `dmrg!` for custom sweep control. ```julia using ITensors using ITensorMPS using TenNetLib N = 32 sites = siteinds("S=1/2", N) os = OpSum() for j = 1:N-1 os += 1, "Sz", j, "Sz", j+1 os += 0.5, "S+", j, "S-", j+1 os += 0.5, "S-", j, "S+", j+1 end H = MPO(os, sites) psi0 = MPS(sites, [isodd(n) ? "Up" : "Dn" for n in 1:N]) # Create StateEnvs from MPS and Hamiltonian sysenv = StateEnvs(psi0, H) # Also works with CouplingModel os_op = OpStrings() for j = 1:N-1 os_op += 1, "Sz" => j, "Sz" => j+1 os_op += 0.5, "S+" => j, "S-" => j+1 os_op += 0.5, "S-" => j, "S+" => j+1 end H_cm = CouplingModel(os_op, sites) sysenv_cm = StateEnvs(psi0, H_cm) # Set number of sites for environment (1 or 2) set_nsite!(sysenv, 2) # Position environment at a bond position!(sysenv, 5) # Get current state psi = getpsi(sysenv) # Matrix-vector product with environment # phi = some ITensor at sites 5,6 # result = product(sysenv, phi) # Use dmrg! for custom sweep control swdata = SweepData() params = DMRGParams(; nsweeps=[5], maxdim=[50], cutoff=1e-10) dmrg!(sysenv, params, 2; # 2 for two-site outputlevel = 1, normalize = true ) final_psi = getpsi(sysenv) ``` -------------------------------- ### Define Hamiltonians with OpStrings and CouplingModel Source: https://context7.com/titaschanda/tennetlib.jl/llms.txt Defines Hamiltonians using the OpStrings syntax, which is an alternative to OpSum and particularly useful for TTN algorithms. CouplingModel converts these operator strings into an efficient tensor representation, automatically handling fermionic Jordan-Wigner strings if necessary. It supports merging terms and compression during conversion. ```julia using ITensors using ITensorMPS using TenNetLib N = 32 sites = siteinds("S=1/2", N) # Define Hamiltonian using OpStrings syntax os = OpStrings() for j = 1:N-1 os += 1, "Sz" => j, "Sz" => j+1 # Ising term os += 0.5, "S+" => j, "S-" => j+1 # XY terms os += 0.5, "S-" => j, "S+" => j+1 end # Add single-site terms (magnetic field) h = 0.5 for j = 1:N os += h, "Sz" => j end # Create CouplingModel (automatically handles fermionic JW strings) H = CouplingModel(os, sites; merge = true, # Merge terms with same support maxdim = 100, # Max auxiliary dimension cutoff = 1e-14 # SVD cutoff for compression ) # Can also combine with existing MPO os_extra = OpStrings() os_extra += 0.1, "Sz" => 1, "Sz" => N # Long-range term H_combined = CouplingModel(os_extra, MPO(OpSum() + (1, "Sz", 1), sites)) ``` -------------------------------- ### DMRG Two-Site Algorithm (dmrg2) in Julia Source: https://context7.com/titaschanda/tennetlib.jl/llms.txt Implements the two-site Density Matrix Renormalization Group algorithm to find ground or excited states of quantum many-body Hamiltonians. It optimizes an MPS by sweeping and updating two neighboring tensors, using variational energy minimization. Requires ITensors.jl, ITensorMPS.jl, and TenNetLib.jl. ```julia using ITensors using ITensorMPS using TenNetLib # Set up a 32-site spin-1/2 Heisenberg chain N = 32 sites = siteinds("S=1/2", N) # Build the Hamiltonian using OpSum os = OpSum() for j = 1:N-1 os += 1, "Sz", j, "Sz", j+1 os += 0.5, "S+", j, "S-", j+1 os += 0.5, "S-", j, "S+", j+1 end H = MPO(os, sites) # Initialize MPS with Neel state states = [isodd(n) ? "Up" : "Dn" for n in 1:N] psi0 = MPS(sites, states) # Configure DMRG parameters with staged optimization params = DMRGParams(; nsweeps = [5, 5, 10], # Sweeps per stage maxdim = [20, 50, 100], # Bond dimension per stage cutoff = 1e-14, # SVD truncation cutoff noise = 1e-3, # Initial noise level noisedecay = 2, # Noise decay factor per sweep disable_noise_after = 3 # Disable noise after N sweeps ) # Run two-site DMRG energy, psi = dmrg2(psi0, H, params; outputlevel = 1, # Print after each sweep energyErrGoal = 1e-10 # Early stopping criterion ) println("Ground state energy: $energy") println("Max bond dimension: $(maxlinkdim(psi))") ``` -------------------------------- ### StateEnvsTTN Documentation Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/ttn/state_envs_ttn.md This section details the StateEnvsTTN type and its associated functions for managing TTN states and environments. ```APIDOC ## StateEnvsTTN ### Description A container to store the TTN and its environments. Similar to the setup for MPS, at the lowest-level of abstraction, TenNetLib.jl defines `StateEnvs` to hold a TTN and its environments to be modified in place. Skip this part if you want to avoid lower-level abstraction. ### Methods - **`StateEnvsTTN`**: Constructor for the `StateEnvsTTN` type. - **`StateEnvsTTN(psi::TTN, M::CouplingModel)`**: Constructor initializing with a TTN and a CouplingModel. - **`StateEnvsTTN(psi::TTN, M::CouplingModel, psis::Vector{TTN}; weight::Float64)`**: Constructor with TTN, CouplingModel, a vector of TTN states, and an optional weight. - **`getpsi(sysenv::StateEnvsTTN)`**: Retrieves the TTN state from the `StateEnvsTTN` container. - **`getenv(sysenv::StateEnvsTTN)`**: Retrieves the environment from the `StateEnvsTTN` container. - **`position!(sysenv::StateEnvsTTN, node::Int2; maxdim::Int = typemax(Int), mindim::Int = 1, cutoff::Float64 = Float64_threshold(), svd_alg::String = "divide_and_conquer", normalize::Bool = false, node_to_skip::Union{Int2, Nothing} = nothing)`**: Positions the environment at a specified node with various optional parameters for controlling the operation. - **`TenNetLib.product(sysenv::StateEnvsTTN, v::ITensor)`**: Computes the product of the `StateEnvsTTN` with an ITensor. - **`Base.copy(sysenv::StateEnvsTTN)`**: Creates a copy of the `StateEnvsTTN` container. ``` -------------------------------- ### Perform Fullsweep in TenNetLib.jl Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/sweep.md Provides the function signature for performing a manual fullsweep operation in TenNetLib.jl. This function updates StateEnvs using a specified solver and sweep data. ```julia ```@docs fullsweep!(sysenv::StateEnvs, solver, nsite::Int, swdata::SweepData; kwargs...) ``` ``` -------------------------------- ### Global Subspace Expansion with Krylov in TenNetLib.jl Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/sweep.md Implements Global Subspace Expansion using Krylov subspaces, as described in Phys. Rev. B 102, 094315 (2020). This function can be applied to MPS or StateEnvs created by a single MPO, aiding in overcoming local minimas during DMRG. ```julia ```@docs krylov_extend!(psi::MPS, H::MPO; kwargs...) krylov_extend!(sysenv::StateEnvs{ProjMPO}; kwargs...) ``` ``` -------------------------------- ### Global Subspace Expansion Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/sweep.md Documentation for the `krylov_extend!` function, used for Global Subspace Expansion, particularly useful for DMRG to overcome local minimas. ```APIDOC ## Global Subspace Expansion ### Description Global Subspace Expansion, as described in Phys. Rev. B **102**, 094315 (2020), can be performed using Krylov subspace methods when the environments are generated by a single `MPO`. This technique is valuable for improving the accuracy of tensor network simulations, especially for DMRG, by helping to escape local minima. ### Methods - `krylov_extend!(psi::MPS, H::MPO; kwargs...) - `krylov_extend!(sysenv::StateEnvs{ProjMPO}; kwargs...) ### Parameters - `psi::MPS`: The Matrix Product State to extend. - `H::MPO`: The Matrix Product Operator defining the Hamiltonian. - `sysenv::StateEnvs{ProjMPO}`: The state environment for expansion. - `kwargs...`: Additional keyword arguments. ``` -------------------------------- ### OpString Type and Accessors (Julia) Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/base/opstrings.md Defines the OpString type and provides functions to access its components like coefficient, operators, and site indices. These are fundamental building blocks for representing operators in TenNetLib.jl. ```julia OpString TenNetLib.coefficient(opstr::OpString) operators(opstr::OpString) minsite(opstr::OpString) maxsite(opstr::OpString) removeIds(opstr::OpString{T}) where {T <: Number} bosonize(opstr::OpString{T1}, sites::Vector{Index{T2}}) where {T1 <: Number, T2} ``` -------------------------------- ### Graph Base Operations and Comparison (Julia) Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/base/graph.md Defines standard base operations for the `Graph` object, including copying, indexing, setting indices (neighbors), and equality comparison between two graphs. ```julia Base.copy(graph::Graph{T}) where T Base.getindex(graph::Graph{T}, node::T) where T Base.setindex!(graph::Graph{T}, neighbors::Set{T}, node::T) where T Base.:(==)(graph1::Graph{T}, graph2::Graph{T}) where T ``` -------------------------------- ### DMRGParams Struct and Constructor Source: https://github.com/titaschanda/tennetlib.jl/blob/main/docs/src/mps/dmrg.md Defines the `DMRGParams` struct used to control DMRG simulations. It includes parameters like maximum dimension, number of sweeps, cutoff, noise, and noise decay. A copy constructor is also provided. ```julia DMRGParams DMRGParams(;maxdim::Vector{Int}, nsweeps::Vector{Int}, cutoff::Union{Vector{Float64}, Float64} = _Float64_Threshold, noise::Union{Vector{Float64}, Float64, Int} = 0.0, noisedecay::Union{Vector{Float64}, Float64, Int} = 1.0, disable_noise_after::Union{Vector{Int}, Int} = typemax(Int)) Base.copy(params::DMRGParams) ```