-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Description
There were a bunch of long-outstanding changes regarding tol/atol/rtol
in scipy.sparse.linalg.*
, c.f. #15738, #18934, #18943 and #19702.
While preparing the latter (to try to make the imminent 1.12 more consistent), I fixed a couple outstanding functions, but noticed that lsmr
and lsqr
have a completely different setup for their tolerance arguments:
scipy/scipy/sparse/linalg/_isolve/lsmr.py
Lines 57 to 74 in c4ce0c4
atol, btol : float, optional | |
Stopping tolerances. `lsmr` continues iterations until a | |
certain backward error estimate is smaller than some quantity | |
depending on atol and btol. Let ``r = b - Ax`` be the | |
residual vector for the current approximate solution ``x``. | |
If ``Ax = b`` seems to be consistent, `lsmr` terminates | |
when ``norm(r) <= atol * norm(A) * norm(x) + btol * norm(b)``. | |
Otherwise, `lsmr` terminates when ``norm(A^H r) <= | |
atol * norm(A) * norm(r)``. If both tolerances are 1.0e-6 (default), | |
the final ``norm(r)`` should be accurate to about 6 | |
digits. (The final ``x`` will usually have fewer correct digits, | |
depending on ``cond(A)`` and the size of LAMBDA.) If `atol` | |
or `btol` is None, a default value of 1.0e-6 will be used. | |
Ideally, they should be estimates of the relative error in the | |
entries of ``A`` and ``b`` respectively. For example, if the entries | |
of ``A`` have 7 correct digits, set ``atol = 1e-7``. This prevents | |
the algorithm from doing unnecessary work beyond the | |
uncertainty of the input data. |
What's worse, it uses atol
-- a kwarg that's pretty universally used to mean absolute tolerance -- as a relative tolerance, which is IMO pretty bad as a footgun for users coming from any of the other scipy.sparse.linalg.*
functions.
I don't have a good suggestion how to fix this (much quickly enough for 1.12!), but perhaps we can find a way to harmonize this a bit better?
FWIW, as of SciPy 1.14, the other functions in scipy.sparse.linalg.*
should uniformly default to rtol=1.e-5
as relative tolerance and atol=0
as absolute tolerance (with any remaining tol=
usages removed).
CC @tupui who touched this in 3d53ac2, and CC @mdhaber for the related #7219