Use combined tolerance for solved check#1079
Conversation
Replace the previous rNorm ≤ rtol check with rNorm ≤ ε (where ε = atol + rtol * β₁) when setting solved, solved_mach, and solved_lim. This makes the convergence/zero-residual detection consistent with the computed combined tolerance (absolute+relative) and prevents incorrect termination when atol or the initial scale β₁ are nonzero.
|
@dpo this is the issue, |
There was a problem hiding this comment.
Pull request overview
Updates MINRES’ initial “solved” detection to use the same combined absolute+relative tolerance used elsewhere (ε = atol + rtol * β₁), avoiding incorrect termination behavior when atol or the initial residual scale is nonzero.
Changes:
- Replace the initial
rNorm ≤ rtolsolved check withrNorm ≤ ε(combined tolerance). - Align initialization of
solved,solved_mach, andsolved_limwith the already-computedε.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
That seems right. It's also the test used in MINRES-QLP: https://github.com/JuliaSmoothOptimizers/Krylov.jl/blob/main/src/minres_qlp.jl#L480 |
|
@dpo I agree and also the same test in CR and CG, Also I don't agree with co-pilot review so I ignored it If it is good for you, should we merge it ? |
|
|
||
| ε = atol + rtol * β₁ | ||
| solved = solved_mach = solved_lim = (rNorm ≤ rtol) | ||
| solved = solved_mach = solved_lim = (rNorm ≤ ε) |
There was a problem hiding this comment.
We use 6 variables for the same stopping condition, maybe we should just removed a few of them.
What you want is already at line 273:
zero_resid = zero_resid_mach = zero_resid_lim = (rNorm ≤ ε).
I don't understand why we have so many variables.
There was a problem hiding this comment.
@dpo and @amontoison
I agree but the goal of this PR is just to fix the current issue that is blocking JSO solver from using MINREs
There was a problem hiding this comment.
Is it a typo? Should it be ArNorm in the line above?
There was a problem hiding this comment.
It will change the returned status at the end. With your modifications, we have two times the same stopping conditions but the related variables are used for different status.
There was a problem hiding this comment.
At the end of the main loop, solved is set based on
So I believe the line that @farhadrclass modified should instead be
solved = solved_mach = solved_lim = (ArNorm ≤ ε)There could also be an additional test
zero_resid = zero_resid_mach = zero_resid_linm = (rNorm ≤ ε)Those are stopping conditions of different natures.
There was a problem hiding this comment.
The condition with test2 is about ArNorm.
There was a problem hiding this comment.
At the end of the main loop,
solvedis set based on ‖ A r ‖ , not ‖ r ‖ : https://github.com/JuliaSmoothOptimizers/Krylov.jl/pull/1079/changes#diff-65c1dbcc771522673d6f0c4e47c90e950b2bcb251ceda42f6de20901c3055021R449So I believe the line that @farhadrclass modified should instead be
solved = solved_mach = solved_lim = (ArNorm ≤ ε)There could also be an additional test
zero_resid = zero_resid_mach = zero_resid_linm = (rNorm ≤ ε)Those are stopping conditions of different natures.
yes I agree but then why in minres_qlp we have
solved = zero_resid = zero_resid_lim = rNorm ≤ ε
There was a problem hiding this comment.
should we have solved = zero_resid?
There was a problem hiding this comment.
Also ArNorm is zero before the loop at line 254
There was a problem hiding this comment.
@dpo @amontoison I agree with about the difference between the exact solution (rNorm) and the least-squares solution (ArNorm).
@dpo, However, to handle the pre-loop initialization, I can't check (ArNorm ≤ ε) because ArNorm is initialized to 0 at line 254. Evaluating it before the loop would cause the solver to instantly terminate on every problem!
Instead of hardcoding the flags to false or calculating ‖Ab‖ before the loop, I think the cleanest fix is to just use (rNorm ≤ ε) for the pre-loop check. Mathematically, if the initial exact residual is below tolerance, it is also a valid least-squares solution (
@dpo what do you think?
I also think if we want to rethink the variables, that would be a bigger PR and should include more solvers not just MINRES and that would my attention away from JSOSolvers now
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1079 +/- ##
==========================================
+ Coverage 94.68% 97.69% +3.01%
==========================================
Files 45 50 +5
Lines 8027 10011 +1984
==========================================
+ Hits 7600 9780 +2180
+ Misses 427 231 -196 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Co-authored-by: Dominique <[email protected]>
|
Why is documentation failing? |
It is related to a tutorial with FFTW.jl for linear operators. I will fix it when I will be allowed to commit again. |
|
@dpo I think @amontoison is right I think the issue with LaplacianOperator being negative defined no? |
|
Thank you! |
Replace the previous rNorm ≤ rtol check with rNorm ≤ ε (where ε = atol + rtol * β₁) when setting solved, solved_mach, and solved_lim. This makes the convergence/zero-residual detection consistent with the computed combined tolerance (absolute+relative) and prevents incorrect termination when atol or the initial scale β₁ are nonzero.