Skip to content

Report truncation error in time evolution + clarify the role of every returned error - #512

Open
borisdevos wants to merge 10 commits into
mainfrom
bd/tdvp-errors
Open

Report truncation error in time evolution + clarify the role of every returned error#512
borisdevos wants to merge 10 commits into
mainfrom
bd/tdvp-errors

Conversation

@borisdevos

@borisdevos borisdevos commented Aug 14, 2026

Copy link
Copy Markdown
Member

Description

The main motivation started with TDVP2 not reporting its truncation error. I noticed it could just make use of gauge2! to remove duplication. While doing this, I realised multiple parts in the code didn't report their error, or didn't clarify clearly what the error actually means. In particular for the time evolution code which isn't variational, it made me realise that ϵ could mean anything. So this PR ended up expanding massively to also documenting per algorithm where relevant what the returned error represents.

Details of the changes are mentioned in the changelog, and motivation for the errors in the docstrings or documentation. Importantly:

  • timestep/timestep!/time_evolve/time_evolve! now return (ψ, envs, ϵ). time_evolve also logs more correctly. Tests added for this.
  • Documentation of what every reported error actually means.

Something I noticed along the way with changebonds is that the meaning of its truncations differ too strongly to unify and justify returning the error. There's an argument to returning it for (VUMPS)SvdCut as the error there is genuinely a truncation error, but I didn't do that.

Checklist

  • Tests pass locally (julia --project=test test/runtests.jl, or the relevant subset)
  • Documentation updated, if this PR changes public API (docstrings, docs/src/)
  • Runic formatter is run
  • Changelog entry added under [Unreleased] in docs/src/changelog.md, if this PR is user-facing (new feature, behavior change, bug fix, deprecation, or removal)

@borisdevos borisdevos added the documentation Improvements or additions to documentation label Aug 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

After the build completes, the updated documentation will be available here

@lkdvos lkdvos left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments throughout, but as a more general idea here, since this is breaking anyways:

I think the entire idea of psi, envs, eps is probably not great to begin with, precisely because it is hard (or important) to keep that to meaning the same in every part. If we are making breaking changes anyways, it might be a convenient time to just go to a more KrylovKit-related approach where we just return an info struct, where we are then actually free to return the different quantities, and name them appropriately. This both keeps the signature the same everywhere, without unwantedly promising meaning to the number.

Thanks for taking the time to properly document many of these things by the way, this is definitely a welcome addition. There are some subtleties about the prose not lining up with the theory or the implementation, since especially for the convergence measures being practical had higher priority than being rigorous, and it seems like the language kind of mixes between the two. I'm not sure if you wanted to describe the theory or the implementation?


### The error convention

Where `ϵ` is a *truncation* error, it is the 2-norm of the discarded singular values of a single factorisation, so that `ϵ²` is the discarded weight and the squared norm of the factorised tensor drops by exactly `ϵ²`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a bit of a strange wording, I'm not really sure there's a lot of benefit referring to the squared norm dropping by the squared epsilon. Is it not easier to just replace this entire paragraph with truncation error is |Aexact - Atrunc|? I'm also not entirely sure we are applying this to properly normalized reduced density matrices everywhere so while it makes sense to mention this, it seems a bit overstated to me.

### Ground-state accuracy

[`find_groundstate`](@ref), [`leading_boundary`](@ref) and the iterative [`approximate`](@ref) algorithms return the quantity their `tol` is compared against.
For the sweeping algorithms ([`DMRG`](@ref), [`DMRG2`](@ref), [`VUMPS`](@ref), [`IDMRG`](@ref), [`IDMRG2`](@ref)) this is the Galerkin error: the norm of the local gradient projected orthogonally to the current state.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you can really project a gradient orthogonally to a state, so maybe easier is: "the norm of the gradient projected onto the local MPS manifold" or something similar?

[`find_groundstate`](@ref), [`leading_boundary`](@ref) and the iterative [`approximate`](@ref) algorithms return the quantity their `tol` is compared against.
For the sweeping algorithms ([`DMRG`](@ref), [`DMRG2`](@ref), [`VUMPS`](@ref), [`IDMRG`](@ref), [`IDMRG2`](@ref)) this is the Galerkin error: the norm of the local gradient projected orthogonally to the current state.
It vanishes exactly at a variational fixed point.
[`GradientGrassmann`](@ref) instead reports the norm of the Riemannian gradient from its optimizer.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be wrong here, but is that not the same gradient, up to second order things?

[`DMRG`](@ref)/[`DMRG2`](@ref) account for this: their stopping test is `ϵ ≤ max(tol, maximum(ϵ_trunc))`, which reduces to the plain `ϵ ≤ tol` when nothing is truncated.

Neither measure is an error bar on an observable.
For that, the standard route is the energy variance ``\langle H^2 \rangle - \langle H \rangle^2`` and extrapolation of observables towards zero variance ([Hubig et al.](@cite hubig2018)).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I agree energy variance is a good independent error measure, that actually only tells you how far the state is from an exact eigenstate, which is somewhat unrelated to error bars on observables.

This is what a bond expansion (CBE) exists to reduce ([Li et al.](@cite li2024)).

* **Time-discretization error.**
The projector splitting is globally ``O(dt^2)`` for the symmetric back-and-forth sweep ([Lubich et al.](@cite lubich2015), [Paeckel et al.](@cite paeckel2019)), so it is controlled by `dt` alone.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I fully agree with the explanation/title combination here, I'd say the thing you are describing is the trotterization error, rather than a time-discretization error, although I agree this might be potato-potato 🙃

The projector splitting is globally ``O(dt^2)`` for the symmetric back-and-forth sweep ([Lubich et al.](@cite lubich2015), [Paeckel et al.](@cite paeckel2019)), so it is controlled by `dt` alone.
This can only be estimated by comparing one step of `dt` against two of `dt / 2`.

A trustworthy run needs all three under control, not just a small `ϵ`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might also be nice to add the usual explanation here that there usually is a sweet spot between choosing dt too small and too large?


* **Ansatz limitation.**
[`QuasiparticleAnsatz`](@ref) varies over the single-quasiparticle tangent space on top of a fixed ground state.
It is variational within that space and well suited to isolated quasiparticle branches, but multi-particle continua are not representable in it, so results there are not to be trusted.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe want to quote here: there is a result somewhere that says you get convergenc based on the gap between ground state and excitation and between excitation and next excitation

* **Ansatz limitation.**
[`QuasiparticleAnsatz`](@ref) varies over the single-quasiparticle tangent space on top of a fixed ground state.
It is variational within that space and well suited to isolated quasiparticle branches, but multi-particle continua are not representable in it, so results there are not to be trusted.
For infinite systems the momentum superposition itself is exact, so momentum is a good quantum number and no error enters through it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really know what this means?

"""
struct DMRG2{A, G, F, B} <: Algorithm
"tolerance for convergence criterium"
"convergence tolerance, compared against the Galerkin error (the tangent-space gradient

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as well as the truncation error I think?

end

return ψ, envs
return ψ, envs, sqrt(ϵ²)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not very consistent with the other reports, which try to keep most of the quantities size-independent. (This is also why the convergence measures actually don't measure the total gradient norm, and rather take the maximum of the local gradient norms)

@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 52.50000% with 19 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/algorithms/timestep/bug.jl 0.00% 10 Missing ⚠️
src/algorithms/timestep/time_evolve.jl 0.00% 8 Missing ⚠️
src/algorithms/timestep/tdvp.jl 92.85% 1 Missing ⚠️
Files with missing lines Coverage Δ
src/algorithms/approximate/approximate.jl 0.00% <ø> (ø)
src/algorithms/approximate/zipup.jl 0.00% <ø> (ø)
src/algorithms/groundstate/dmrg.jl 89.79% <100.00%> (ø)
src/algorithms/groundstate/find_groundstate.jl 0.00% <ø> (ø)
src/algorithms/groundstate/gradient_grassmann.jl 0.00% <ø> (ø)
src/algorithms/groundstate/idmrg.jl 96.85% <100.00%> (ø)
src/algorithms/groundstate/vumps.jl 90.78% <100.00%> (ø)
src/algorithms/propagator/corvector.jl 0.00% <ø> (ø)
src/algorithms/statmech/leading_boundary.jl 0.00% <ø> (ø)
src/algorithms/statmech/vomps.jl 0.00% <ø> (ø)
... and 6 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants