Report truncation error in time evolution + clarify the role of every returned error - #512
Report truncation error in time evolution + clarify the role of every returned error#512borisdevos wants to merge 10 commits into
Conversation
…ns in time evolution
|
After the build completes, the updated documentation will be available here |
lkdvos
left a comment
There was a problem hiding this comment.
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 `ϵ²`. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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)). |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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 `ϵ`. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
as well as the truncation error I think?
| end | ||
|
|
||
| return ψ, envs | ||
| return ψ, envs, sqrt(ϵ²) |
There was a problem hiding this comment.
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)
Description
The main motivation started with
TDVP2not reporting its truncation error. I noticed it could just make use ofgauge2!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_evolvealso logs more correctly. Tests added for this.Something I noticed along the way with
changebondsis 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)SvdCutas the error there is genuinely a truncation error, but I didn't do that.Checklist
julia --project=test test/runtests.jl, or the relevant subset)docs/src/)[Unreleased]indocs/src/changelog.md, if this PR is user-facing (new feature, behavior change, bug fix, deprecation, or removal)