tol, atol and rtol behavior of scipy.sparse.linalg solvers
Ilhan Polat <[email protected]> Mon, 1 May 2023 20:49:12 +0200
| Newsgroups | gmane.comp.python.scientific.devel |
|---|---|
| Message-ID | <CAEBuzr_6DTh5qAoT0memKbW47KVW-UU-7MHAYDCens_PubEg8w@mail.gmail.com> |
Dear all, Yet another mail about upcoming changes, so apologies for the seemingly repeating message lately. In [1], we started to remove all the FORTRAN code and rewrote all solvers in pure Python for various reasons too long to enumerate here. As a long waiting issue we want to also address the suboptimal state of providing tolerances for these solvers. As I wrote in [2], I'd like to mention it again to ask for feedback in case anyone has better ideas Currently, we have the following situation; We have a tol and a strange looking atol keywords. What internally happens is that all the inputs are now passed to a helper function called get_atol https://github.com/scipy/scipy/blob/maintenance/1.10.x/scipy/sparse/linalg/_isolve/iterative.py#L78-L116 1. User didn't provide atol then it first maps to None and that causes a warning and internally atol becomes legacy. This means: a. tol value is checked against the residual norm Ax - b. Note that matvec operation is costly. If the residual norm is already less than tol we exit. b. Then b norm is checked against 0. Since tol*norm(b) won't do any good we return tol c. And the typical case is to return tol*norm(b). 2. User passed legacy all the same as above except the warning. 3. If atol is actually set to something, then we return max(atol, tol*norm(b)). Why max is used I don't understand. Typically, atol, rtol pair is used as tol = atol + rtol*<some metric>. This is more or less what everybody expects from this pair and their naming is chosen to reflect this. But I'm a bit lost in all the issues I could read. What I propose is the following, 1. Make default atol=0. 2. If atol is set to string, fire a warning saying this is going away in version 1.13 (hence make the current deprecation on a definite schedule and assuming I can make it to 1.11 release). These are the users probably wanted to keep old behavior. Document how it can be done to match old behavior via atol, rtol. 3. Introduce a new keyword rtol and map current tol to rtol. Set tol=None as the default to weed out the ones who actually set tol value and fire deprecation warnings for them to use rtol. 4. Use the formula tol = atol + rtol*norm(b) All feedback is welcome. [1] : https://github.com/scipy/scipy/pull/18391 [2] : https://github.com/scipy/scipy/issues/15738 _______________________________________________ SciPy-Dev mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3/lists/scipy-dev.python.org/ Member address: [email protected]