Closed emstoudenmire closed 2 years ago
Hi Miles, thanks for the report. I will take a look. Certainly this is very different then how tol
works for linear problems and eigenvalues, as for exponentiate
there is no notion of a residual. Hence, a particular error estimate is used (the details of which I will need to look up again); that is also why you can obtain unreasonably small values of the (estimated) error, below machine precision.
However, seeing your example, you are observing something else. It is indeed true that I currently don't have a mechanism to adaptively change the number of Krylov steps. Hence, I always compute a full Krylov subspace of the requested krylovdim
(unless it terminates prematurely, indicating an invariant subspace). The error model is then used to split the total time step in smaller steps which are accurate up to the requested tolerance, given the current krylov subspace. However, if, as in this case, the whole evolution is captured accurately (more accurately then requested) within that Krylov subspace, then the computation just finishes after this single outer iteration.
The same happens with eigsolve
, where by default I compute a full Krylov subspace, before assessing the norms of the residuals. However, there I have added an eager
mode to compute the residuals after every single expansion step of the Krylov subspace, which allows to terminate eagerly, at the expense of incurring a small overhead as the Schur decomposition of the Rayleigh quotient needs to be computed every time. Something similar can probably be done for exponentiate
.
Actually, it turns out the eager
mode was already implemented. My memory is terrible for these things. So just add eager=true
to your keywords and you will see the desired effect. The error is still smaller than the requested tolerance, but that's a consequence of the error model, and the fact that the error can be much bigger with one krylov vector less, and then improve dramatically with one additional Krylov vector.
Note though, that if you set krylovdim and maxiter too low, so that convergence is not obtained, the behaviour of exponentiate
will not be to approximate the full time evolution with a bigger error, but rather to evolve up to a smaller time within the requested tolerance. This is explained in the documentation.
The most recent commit adds documentation for the eager
behaviour in exponentiate
and expintegrator
. I will close this issue; feel free to reopen if you think anything else needs to be done.
I've reopened this for further discussion.
Regarding the tolerance, also note that (as mentioned in the docs) tol
is the requested accuracy per unit time. This means that, in your example with t=0.1
, the requested tol
on the result is 10 times smaller than the value that you enter. I don't know why I made that choice, but changing it would in principle be a breaking change, which is furthermore hard to have a deprecation/transition rule for.
Thanks for that helpful clarification. After thinking about it further, I believe that definition of tol
is actually the most sensible one. Our code inside C++ ITensor happened to make a different choice (tol being the absolute error) so we will translate between them in the way you said when making any comparisons.
I think this and your earlier comments does address (close) this issue.
Using the
exponentiate
interface toexpintegrator
, I have been finding that thetol
keyword does not behave as expected. Please see the minimal sample code to reproduce below.I was expecting that by setting
tol
the number of operationsnumops
would adaptively depend ontol
and the total timet
. Instead I am finding that the only thing which seems to reducenumops
is lowering thekrylovdim
to a value around 10 or so. The error I find after the code runs, by comparing the returned vector to an exact solution, is usually extremely small (< 1E-15) regardless of how high I make thetol
parameter (say if I set it to 1E-3 or even 0.1).Code to reproduce – the main thing I've been doing is adjusting
t
from 0.1 up to 1.0 while raising and loweringtol
and I see the behavior described above (the amount of linear operators, numops, is something like 22). Loweringkrylovdim
to 10 does make numops become smaller while still giving an accurate result.Typical output for the above settings: