@@ -97,9 +97,14 @@ Parameters specific to inexact GMRES:
9797 w .= b .- Ax
9898 ldiv! (r, precon, w) # Apply preconditioner
9999 end
100- y[1 ] = β = norm (r)
100+ y[1 ] = β = residual_norm = norm (r)
101101
102- while (n_iter < maxiter && k < m) # Arnoldi loop
102+ # Prevent iterations when the initial guess or the restarted guess are already sufficiently
103+ # accurate. We check residual_norm < 2/3 tol since ||b-Ax|| < ||b-Ãx|| + ||Ax-Ãx||,
104+ # where à is the inexact operator used in mul_approximate, which is accurate to tol/3.
105+ converged = residual_norm < 2 tol/ 3
106+
107+ while (! converged && n_iter < maxiter && k < m) # Arnoldi loop
103108 n_iter += 1
104109
105110 # Push new Krylov vector
@@ -124,15 +129,20 @@ Parameters specific to inexact GMRES:
124129 # Update right-hand side in Krylov subspace and new residual norm estimate
125130 y[k + 1 ] = zero (T)
126131 lmul! (Gs[k], y)
127- resid_history[n_iter] = abs (y[k + 1 ])
132+ resid_history[n_iter] = residual_norm = abs (y[k + 1 ])
128133
129134 info = (; y, V, H, R, resid_history= resid_history[1 : n_iter], converged, n_iter,
130- residual_norm= resid_history[n_iter] , maxiter, tol, s, residual = r ,
135+ residual_norm, maxiter, tol, s,
131136 restart_history, stage= :iterate , krylovdim, k, Axinfos)
132137 callback (info)
133138 Axinfos = []
134139
135- if resid_history[n_iter] < tol
140+ # Note: Although in [^Herbst2025] we have tol / 3 in the following convergence check,
141+ # our numerical tests still find that the requested tolerance is approximately
142+ # achieved when dropping the /3. This prevents the GMRES from potential over-iterating
143+ # when the `mul_approximate` calls happen to yield higher-accurate answers compared to
144+ # what has been requested.
145+ if residual_norm < tol
136146 # If the guess for s happens to over-estimate the σ(H_m) than we need to
137147 # restart, so convergence is only reached if this condition is true ...
138148 min_svdval_H = minimum (svdvals (H[1 : (k+ 1 ), 1 : k]))
@@ -149,7 +159,7 @@ Parameters specific to inexact GMRES:
149159
150160 if converged || n_iter ≥ maxiter
151161 info = (; x, resid_history= resid_history[1 : n_iter], converged, n_iter,
152- residual_norm= resid_history[n_iter] , maxiter, tol, s, residual = r ,
162+ residual_norm, maxiter, tol, s,
153163 restart_history, stage= :finalize , krylovdim, y, V, H, R)
154164 callback (info)
155165 return info
0 commit comments