@@ -61,7 +61,9 @@ start(::LanczosDecomp) = 1
61
61
done (l:: LanczosDecomp , iteration:: Int ) = false
62
62
function iterate (l:: LanczosDecomp , iteration:: Int = start (l))
63
63
# Following Algorithm 7.1 of Saad
64
- if done (l, iteration) return nothing end
64
+ if done (l, iteration)
65
+ return nothing
66
+ end
65
67
66
68
mul! (l. v_next, l. A, l. v_curr)
67
69
@@ -79,7 +81,9 @@ function iterate(l::LanczosDecomp, iteration::Int=start(l))
79
81
80
82
vw = dot (l. v_next, l. w_next)
81
83
l. δ = sqrt (abs (vw))
82
- if iszero (l. δ) return nothing end
84
+ if iszero (l. δ)
85
+ return nothing
86
+ end
83
87
84
88
l. β_prev = l. β_curr
85
89
l. β_curr = vw / l. δ
@@ -98,11 +102,11 @@ mutable struct QMRIterable{T, xT, rT, lanczosT}
98
102
99
103
lanczos:: lanczosT
100
104
resnorm:: rT
101
- reltol :: rT
105
+ tol :: rT
102
106
maxiter:: Int
103
107
104
108
g:: Vector{T} # right-hand size following Hessenberg multiplication
105
- H:: Vector{T} # Hessenberg Matrix, computed on CPU
109
+ H:: Vector{T} # Hessenberg Matrix, computed on CPU
106
110
107
111
c_prev:: T
108
112
c_curr:: T
@@ -114,13 +118,20 @@ mutable struct QMRIterable{T, xT, rT, lanczosT}
114
118
end
115
119
116
120
function qmr_iterable! (x, A, b;
117
- tol = sqrt (eps (real (eltype (b)))),
118
- maxiter:: Int = size (A, 2 ),
119
- initially_zero:: Bool = false ,
120
- lookahead:: Bool = false
121
- )
121
+ abstol:: Real = zero (real (eltype (b))),
122
+ reltol:: Real = sqrt (eps (real (eltype (b)))),
123
+ tol = nothing , # TODO : Deprecations introduced in v0.8
124
+ maxiter:: Int = size (A, 2 ),
125
+ initially_zero:: Bool = false ,
126
+ lookahead:: Bool = false )
122
127
T = eltype (x)
123
128
129
+ # TODO : Deprecations introduced in v0.8
130
+ if tol != = nothing
131
+ Base. depwarn (" The keyword argument `tol` is deprecated, use `reltol` instead." , :qmr_iterable! )
132
+ reltol = tol
133
+ end
134
+
124
135
lanczos = LanczosDecomp (x, A, b, initially_zero = initially_zero)
125
136
126
137
resnorm = lanczos. resnorm
@@ -135,23 +146,26 @@ function qmr_iterable!(x, A, b;
135
146
p_prev = zero (x)
136
147
p_curr = zero (x)
137
148
138
- reltol = tol * lanczos. resnorm
149
+ tolerance = max (reltol * lanczos. resnorm, abstol)
139
150
140
151
QMRIterable (x,
141
- lanczos, resnorm, reltol ,
152
+ lanczos, resnorm, tolerance ,
142
153
maxiter,
143
154
g, H,
144
155
c_prev, c_curr, s_prev, s_curr,
145
156
p_prev, p_curr
146
157
)
147
158
end
148
159
149
- converged (q:: QMRIterable ) = q. resnorm ≤ q. reltol
160
+ converged (q:: QMRIterable ) = q. resnorm ≤ q. tol
150
161
start (:: QMRIterable ) = 1
151
162
done (q:: QMRIterable , iteration:: Int ) = iteration > q. maxiter || converged (q)
152
163
153
164
function iterate (q:: QMRIterable , iteration:: Int = start (q))
154
- if done (q, iteration) return nothing end
165
+ # Check for termination first
166
+ if done (q, iteration)
167
+ return nothing
168
+ end
155
169
156
170
iterate (q. lanczos, iteration)
157
171
@@ -230,7 +244,10 @@ Solves the problem ``Ax = b`` with the Quasi-Minimal Residual (QMR) method.
230
244
matrix-vector product can be saved when computing the initial residual
231
245
vector;
232
246
- `maxiter::Int = size(A, 2)`: maximum number of iterations;
233
- - `tol`: relative tolerance;
247
+ - `abstol::Real = zero(real(eltype(b)))`,
248
+ `reltol::Real = sqrt(eps(real(eltype(b))))`: absolute and relative
249
+ tolerance for the stopping condition
250
+ `|r_k| / |r_0| ≤ max(reltol * resnorm, abstol)`, where `r_k = A * x_k - b`
234
251
- `log::Bool`: keep track of the residual norm in each iteration;
235
252
- `verbose::Bool`: print convergence information during the iteration.
236
253
@@ -253,18 +270,27 @@ Solves the problem ``Ax = b`` with the Quasi-Minimal Residual (QMR) method.
253
270
Residual Linear Method Systems. (December).
254
271
"""
255
272
function qmr! (x, A, b;
256
- tol = sqrt (eps (real (eltype (b)))),
257
- maxiter:: Int = size (A, 2 ),
258
- lookahead:: Bool = false ,
259
- log:: Bool = false ,
260
- initially_zero:: Bool = false ,
261
- verbose:: Bool = false
262
- )
273
+ abstol:: Real = zero (real (eltype (b))),
274
+ reltol:: Real = sqrt (eps (real (eltype (b)))),
275
+ tol = nothing , # TODO : Deprecations introduced in v0.8
276
+ maxiter:: Int = size (A, 2 ),
277
+ lookahead:: Bool = false ,
278
+ log:: Bool = false ,
279
+ initially_zero:: Bool = false ,
280
+ verbose:: Bool = false )
263
281
history = ConvergenceHistory (partial = ! log)
264
- history[:tol ] = tol
282
+ history[:abstol ] = abstol
283
+ history[:reltol ] = reltol
265
284
log && reserve! (history, :resnorm , maxiter)
266
285
267
- iterable = qmr_iterable! (x, A, b; tol = tol, maxiter = maxiter, initially_zero = initially_zero)
286
+ # TODO : Deprecations introduced in v0.8
287
+ if tol != = nothing
288
+ Base. depwarn (" The keyword argument `tol` is deprecated, use `reltol` instead." , :qmr! )
289
+ reltol = tol
290
+ end
291
+
292
+ iterable = qmr_iterable! (x, A, b; abstol = abstol, reltol = reltol,
293
+ maxiter = maxiter, initially_zero = initially_zero)
268
294
269
295
verbose && @printf (" === qmr ===\n %4s\t %7s\n " ," iter" ," resnorm" )
270
296
0 commit comments