@@ -42,18 +42,21 @@ mutable struct GMRESIterable{preclT, precrT, solT, rhsT, vecT, arnoldiT <: Arnol
42
42
restart:: Int
43
43
k:: Int
44
44
maxiter:: Int
45
- reltol :: resT
45
+ tol :: resT
46
46
β:: resT
47
47
end
48
48
49
- converged (g:: GMRESIterable ) = g. residual. current ≤ g. reltol
49
+ converged (g:: GMRESIterable ) = g. residual. current ≤ g. tol
50
50
51
51
start (:: GMRESIterable ) = 0
52
52
53
53
done (g:: GMRESIterable , iteration:: Int ) = iteration ≥ g. maxiter || converged (g)
54
54
55
55
function iterate (g:: GMRESIterable , iteration:: Int = start (g))
56
- if done (g, iteration) return nothing end
56
+ # Check for termination first
57
+ if done (g, iteration)
58
+ return nothing
59
+ end
57
60
58
61
# Arnoldi step: expand
59
62
expand! (g. arnoldi, g. Pl, g. Pr, g. k, g. Ax)
@@ -100,15 +103,22 @@ function iterate(g::GMRESIterable, iteration::Int=start(g))
100
103
end
101
104
102
105
function gmres_iterable! (x, A, b;
103
- Pl = Identity (),
104
- Pr = Identity (),
105
- tol = sqrt (eps (real (eltype (b)))),
106
- restart:: Int = min (20 , size (A, 2 )),
107
- maxiter:: Int = size (A, 2 ),
108
- initially_zero:: Bool = false
109
- )
106
+ Pl = Identity (),
107
+ Pr = Identity (),
108
+ abstol:: Real = zero (real (eltype (b))),
109
+ reltol:: Real = sqrt (eps (real (eltype (b)))),
110
+ tol = nothing , # TODO : Deprecations introduced in v0.8
111
+ restart:: Int = min (20 , size (A, 2 )),
112
+ maxiter:: Int = size (A, 2 ),
113
+ initially_zero:: Bool = false )
110
114
T = eltype (x)
111
115
116
+ # TODO : Deprecations introduced in v0.8
117
+ if tol != = nothing
118
+ Base. depwarn (" The keyword argument `tol` is deprecated, use `reltol` instead." , :gmres_iterable! )
119
+ reltol = tol
120
+ end
121
+
112
122
# Approximate solution
113
123
arnoldi = ArnoldiDecomp (A, restart, T)
114
124
residual = Residual (restart, T)
@@ -119,11 +129,11 @@ function gmres_iterable!(x, A, b;
119
129
residual. current = init! (arnoldi, x, b, Pl, Ax, initially_zero = initially_zero)
120
130
init_residual! (residual, residual. current)
121
131
122
- reltol = tol * residual. current
132
+ tolerance = max (reltol * residual. current, abstol)
123
133
124
134
GMRESIterable (Pl, Pr, x, b, Ax,
125
135
arnoldi, residual,
126
- mv_products, restart, 1 , maxiter, reltol , residual. current
136
+ mv_products, restart, 1 , maxiter, tolerance , residual. current
127
137
)
128
138
end
129
139
@@ -150,7 +160,10 @@ Solves the problem ``Ax = b`` with restarted GMRES.
150
160
- `initially_zero::Bool`: If `true` assumes that `iszero(x)` so that one
151
161
matrix-vector product can be saved when computing the initial
152
162
residual vector;
153
- - `tol`: relative tolerance;
163
+ - `abstol::Real = zero(real(eltype(b)))`,
164
+ `reltol::Real = sqrt(eps(real(eltype(b))))`: absolute and relative
165
+ tolerance for the stopping condition
166
+ `|r_k| / |r_0| ≤ max(reltol * resnorm, abstol)`, where `r_k = A * x_k - b`
154
167
- `restart::Int = min(20, size(A, 2))`: restarts GMRES after specified number of iterations;
155
168
- `maxiter::Int = size(A, 2)`: maximum number of inner iterations of GMRES;
156
169
- `Pl`: left preconditioner;
@@ -170,20 +183,29 @@ Solves the problem ``Ax = b`` with restarted GMRES.
170
183
- `history`: convergence history.
171
184
"""
172
185
function gmres! (x, A, b;
173
- Pl = Identity (),
174
- Pr = Identity (),
175
- tol = sqrt (eps (real (eltype (b)))),
176
- restart:: Int = min (20 , size (A, 2 )),
177
- maxiter:: Int = size (A, 2 ),
178
- log:: Bool = false ,
179
- initially_zero:: Bool = false ,
180
- verbose:: Bool = false
181
- )
186
+ Pl = Identity (),
187
+ Pr = Identity (),
188
+ abstol:: Real = zero (real (eltype (b))),
189
+ reltol:: Real = sqrt (eps (real (eltype (b)))),
190
+ tol = nothing , # TODO : Deprecations introduced in v0.8
191
+ restart:: Int = min (20 , size (A, 2 )),
192
+ maxiter:: Int = size (A, 2 ),
193
+ log:: Bool = false ,
194
+ initially_zero:: Bool = false ,
195
+ verbose:: Bool = false )
182
196
history = ConvergenceHistory (partial = ! log, restart = restart)
183
197
history[:tol ] = tol
184
198
log && reserve! (history, :resnorm , maxiter)
185
199
186
- iterable = gmres_iterable! (x, A, b; Pl = Pl, Pr = Pr, tol = tol, maxiter = maxiter, restart = restart, initially_zero = initially_zero)
200
+ # TODO : Deprecations introduced in v0.8
201
+ if tol != = nothing
202
+ Base. depwarn (" The keyword argument `tol` is deprecated, use `reltol` instead." , :cg! )
203
+ reltol = tol
204
+ end
205
+
206
+ iterable = gmres_iterable! (x, A, b; Pl = Pl, Pr = Pr,
207
+ abstol = abstol, reltol = reltol, maxiter = maxiter,
208
+ restart = restart, initially_zero = initially_zero)
187
209
188
210
verbose && @printf (" === gmres ===\n %4s\t %4s\t %7s\n " ," rest" ," iter" ," resnorm" )
189
211
0 commit comments