From c7840efd80d107448f5000873c7f62b7c0711254 Mon Sep 17 00:00:00 2001 From: VinceNeede Date: Tue, 21 Jul 2026 11:01:00 +0200 Subject: [PATCH 1/4] feat: implement keyword-based approximate --- src/algorithms/approximate/approximate.jl | 67 +++++++++++++++++++---- src/algorithms/unionalg.jl | 5 ++ 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src/algorithms/approximate/approximate.jl b/src/algorithms/approximate/approximate.jl index f28e67e6b..3c3b1c17d 100644 --- a/src/algorithms/approximate/approximate.jl +++ b/src/algorithms/approximate/approximate.jl @@ -1,13 +1,17 @@ @doc """ - approximate(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments) - approximate!(ψ₀, (O, ψ), algorithm, [environments]; kwargs...) -> (ψ, environments) - approximate(ψ₀, ψ, algorithm, [environments]; kwargs...) -> (ψ, environments) - approximate!(ψ₀, ψ, algorithm, [environments]; kwargs...) -> (ψ, environments) + approximate(ψ₀, (O, ψ), [environments]; kwargs...) -> (ψ, environments, ϵ) + approximate(ψ₀, (O, ψ), algorithm, [environments]) -> (ψ, environments, ϵ) + approximate!(ψ₀, (O, ψ), algorithm, [environments]) -> (ψ, environments, ϵ) + approximate(ψ₀, ψ, algorithm, [environments]) -> (ψ, environments, ϵ) + approximate!(ψ₀, ψ, algorithm, [environments]) -> (ψ, environments, ϵ) Compute an approximation to the application of an operator `O` to the state `ψ` in the form of an MPS `ψ₀`. If only a state `ψ` is supplied instead of the `(O, ψ)` pair, `ψ₀` is approximated directly to `ψ` (i.e. `O` is taken to be the identity). +**Not every algorithm supports every combination of arguments below** — see the per-algorithm +notes at the end of this docstring before picking one. + ## Arguments - `ψ₀::AbstractMPS`: initial guess of the approximated state - `(O::AbstractMPO, ψ::AbstractMPS)`: operator `O` and state `ψ` to be approximated @@ -16,17 +20,33 @@ approximated directly to `ψ` (i.e. `O` is taken to be the identity). - `[environments]`: MPS environment manager ## Keywords +The keyword-based call (no explicit `algorithm`) is a convenience method that picks an +algorithm for you based on the type of `ψ₀` (`DMRG`/`DMRG2` for a finite MPS, `VOMPS`/`IDMRG`/ +`IDMRG2` for an infinite MPS) and only accepts the `(O, ψ)` tuple form of `toapprox`. Once you +pass an explicit `algorithm`, keywords are no longer accepted here — configure the algorithm +struct itself instead (e.g. `DMRG(; tol, maxiter, verbosity)`). - `tol::Float64`: tolerance for convergence criterium - `maxiter::Int`: maximum amount of iterations - `verbosity::Int`: display progress information +- `trscheme`: if supplied, a truncated two-site sweep (`DMRG2`/`IDMRG2`) is prepended to + refine the bond dimension before the single-site algorithm polishes the result. ## 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. +Each algorithm below only supports a subset of the general interface. Check this table before +picking one — in particular, note that **only `DMRG`/`DMRG2` accept a bare state `ψ`**; the +infinite algorithms always require an explicit `(O, ψ)` tuple, and **`VOMPS` has no in-place +`approximate!`** at all. + +| Algorithm | Scheme | State `ψ₀` | bare `ψ` allowed? | `approximate!` | +|:--------- |:----------------------------- |:---------------------------------- |:------------------:|:--------------:| +| `DMRG` | single-site, fixes bond dim | `AbstractFiniteMPS` | ✅ | ✅ | +| `DMRG2` | two-site, truncates via `trscheme` | `AbstractFiniteMPS` | ✅ | ✅ | +| `IDMRG` | single-site, thermodynamic limit | `InfiniteMPS` / `MultilineMPS` | ❌ (tuple only) | ✅ | +| `IDMRG2` | two-site, thermodynamic limit, needs unit cell ≥ 2 | `InfiniteMPS` / `MultilineMPS` | ❌ (tuple only) | ✅ | +| `VOMPS` | tangent-space truncation | `InfiniteMPS` / `MultilineMPS` | ❌ (tuple only) | ❌ (out-of-place only) | -- `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. +`InfiniteMPS`/`InfiniteMPO` inputs are converted internally to `MultilineMPS`/`MultilineMPO` +for `IDMRG`, `IDMRG2`, and `VOMPS`; you can also pass those types directly. """ approximate, approximate! @@ -35,6 +55,33 @@ approximate, approximate! _environment_args(Oϕ::Tuple) = Oϕ _environment_args(ϕ) = (ϕ,) +function approximate( + ψ::AbstractMPS, toapprox::Tuple{<:AbstractMPO, <:AbstractMPS}, + envs = environments(ψ, toapprox...), + tol = Defaults.tol, maxiter=Defaults.maxiter, + verbosity=Defaults.verbosity, trscheme=nothing + ) + if isa(ψ, InfiniteMPS) + alg = VOMPS(; tol = max(1.0e-4, tol), verbosity, maxiter) + if tol < 1.0e-4 + alg = alg & IDMRG(; tol = tol, maxiter, verbosity) + end + if !isnothing(trscheme) + alg = IDMRG2(; tol = min(1.0e-2, 100tol), verbosity, trscheme) & alg + end + elseif isa(ψ, AbstractFiniteMPS) + alg = DMRG(; tol, maxiter, verbosity) + if !isnothing(trscheme) + alg = DMRG2(; tol = min(1.0e-2, 100tol), verbosity, trscheme) & alg + end + else + throw(ArgumentError("Unknown input state type")) + end + + return approximate(ψ, H, alg, envs) +end + + # implementation in terms of Multiline function approximate( ψ::InfiniteMPS, toapprox::Tuple{<:InfiniteMPO, <:InfiniteMPS}, algorithm, @@ -70,4 +117,4 @@ function approximate( ) ψ = convert(InfiniteMPS, multi) return ψ, envs, δ -end +end \ No newline at end of file diff --git a/src/algorithms/unionalg.jl b/src/algorithms/unionalg.jl index 3e37f67f4..5234e5aec 100644 --- a/src/algorithms/unionalg.jl +++ b/src/algorithms/unionalg.jl @@ -32,3 +32,8 @@ function find_groundstate(state, H, alg::UnionAlg, envs = environments(state, H, state, envs = find_groundstate(state, H, alg.alg1, envs) return find_groundstate(state, H, alg.alg2, envs) end + +function approximate(state, toapprox, alg::UnionAlg, envs=enviroments(state, toapprox...)) + state, envs = approximate(state, toapprox, alg.alg1, envs) + return approximate(state, toapprox, alg.alg2, envs) +end \ No newline at end of file From ad109f495daf34c92bdb61dae9a7b3745ab5a4fd Mon Sep 17 00:00:00 2001 From: VinceNeede Date: Tue, 21 Jul 2026 11:15:18 +0200 Subject: [PATCH 2/4] runic style --- src/algorithms/approximate/approximate.jl | 8 ++++---- src/algorithms/unionalg.jl | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/algorithms/approximate/approximate.jl b/src/algorithms/approximate/approximate.jl index 3c3b1c17d..a83504f60 100644 --- a/src/algorithms/approximate/approximate.jl +++ b/src/algorithms/approximate/approximate.jl @@ -56,10 +56,10 @@ _environment_args(Oϕ::Tuple) = Oϕ _environment_args(ϕ) = (ϕ,) function approximate( - ψ::AbstractMPS, toapprox::Tuple{<:AbstractMPO, <:AbstractMPS}, + ψ::AbstractMPS, toapprox::Tuple{<:AbstractMPO, <:AbstractMPS}, envs = environments(ψ, toapprox...), - tol = Defaults.tol, maxiter=Defaults.maxiter, - verbosity=Defaults.verbosity, trscheme=nothing + tol = Defaults.tol, maxiter = Defaults.maxiter, + verbosity = Defaults.verbosity, trscheme = nothing ) if isa(ψ, InfiniteMPS) alg = VOMPS(; tol = max(1.0e-4, tol), verbosity, maxiter) @@ -117,4 +117,4 @@ function approximate( ) ψ = convert(InfiniteMPS, multi) return ψ, envs, δ -end \ No newline at end of file +end diff --git a/src/algorithms/unionalg.jl b/src/algorithms/unionalg.jl index 5234e5aec..9ef7f722a 100644 --- a/src/algorithms/unionalg.jl +++ b/src/algorithms/unionalg.jl @@ -33,7 +33,7 @@ function find_groundstate(state, H, alg::UnionAlg, envs = environments(state, H, return find_groundstate(state, H, alg.alg2, envs) end -function approximate(state, toapprox, alg::UnionAlg, envs=enviroments(state, toapprox...)) +function approximate(state, toapprox, alg::UnionAlg, envs = enviroments(state, toapprox...)) state, envs = approximate(state, toapprox, alg.alg1, envs) return approximate(state, toapprox, alg.alg2, envs) -end \ No newline at end of file +end From 19b7841033a32db964a52f2ce8fc57d3794f866f Mon Sep 17 00:00:00 2001 From: VinceNeede Date: Tue, 21 Jul 2026 16:33:40 +0200 Subject: [PATCH 3/4] fix: specialize envs to disambiguate --- src/algorithms/approximate/approximate.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/algorithms/approximate/approximate.jl b/src/algorithms/approximate/approximate.jl index a83504f60..e441b0597 100644 --- a/src/algorithms/approximate/approximate.jl +++ b/src/algorithms/approximate/approximate.jl @@ -57,7 +57,7 @@ _environment_args(ϕ) = (ϕ,) function approximate( ψ::AbstractMPS, toapprox::Tuple{<:AbstractMPO, <:AbstractMPS}, - envs = environments(ψ, toapprox...), + envs::AbstractMPSEnvironments = environments(ψ, toapprox...); tol = Defaults.tol, maxiter = Defaults.maxiter, verbosity = Defaults.verbosity, trscheme = nothing ) @@ -78,7 +78,7 @@ function approximate( throw(ArgumentError("Unknown input state type")) end - return approximate(ψ, H, alg, envs) + return approximate(ψ, toapprox, alg, envs) end From c044f7dbfffb7466eff306c26dfcb8b9ada73e68 Mon Sep 17 00:00:00 2001 From: VinceNeede Date: Tue, 21 Jul 2026 16:46:12 +0200 Subject: [PATCH 4/4] converge with VOMPS directly, without using IDMRG --- src/algorithms/approximate/approximate.jl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/algorithms/approximate/approximate.jl b/src/algorithms/approximate/approximate.jl index e441b0597..6967dcef0 100644 --- a/src/algorithms/approximate/approximate.jl +++ b/src/algorithms/approximate/approximate.jl @@ -62,10 +62,7 @@ function approximate( verbosity = Defaults.verbosity, trscheme = nothing ) if isa(ψ, InfiniteMPS) - alg = VOMPS(; tol = max(1.0e-4, tol), verbosity, maxiter) - if tol < 1.0e-4 - alg = alg & IDMRG(; tol = tol, maxiter, verbosity) - end + alg = VOMPS(; tol, verbosity, maxiter) if !isnothing(trscheme) alg = IDMRG2(; tol = min(1.0e-2, 100tol), verbosity, trscheme) & alg end