@@ -8,7 +8,7 @@ mutable struct CGIterable{matT, solT, vecT, numT <: Real}
8
8
r:: vecT
9
9
c:: vecT
10
10
u:: vecT
11
- reltol :: numT
11
+ tol :: numT
12
12
residual:: numT
13
13
prev_residual:: numT
14
14
maxiter:: Int
@@ -22,14 +22,14 @@ mutable struct PCGIterable{precT, matT, solT, vecT, numT <: Real, paramT <: Numb
22
22
r:: vecT
23
23
c:: vecT
24
24
u:: vecT
25
- reltol :: numT
25
+ tol :: numT
26
26
residual:: numT
27
27
ρ:: paramT
28
28
maxiter:: Int
29
29
mv_products:: Int
30
30
end
31
31
32
- @inline converged (it:: Union{CGIterable, PCGIterable} ) = it. residual ≤ it. reltol
32
+ @inline converged (it:: Union{CGIterable, PCGIterable} ) = it. residual ≤ it. tol
33
33
34
34
@inline start (it:: Union{CGIterable, PCGIterable} ) = 0
35
35
41
41
# ##############
42
42
43
43
function iterate (it:: CGIterable , iteration:: Int = start (it))
44
- if done (it, iteration) return nothing end
44
+ # Check for termination first
45
+ if done (it, iteration)
46
+ return nothing
47
+ end
45
48
46
49
# u := r + βu (almost an axpy)
47
50
β = it. residual^ 2 / it. prev_residual^ 2
@@ -72,6 +75,7 @@ function iterate(it::PCGIterable, iteration::Int=start(it))
72
75
return nothing
73
76
end
74
77
78
+ # Apply left preconditioner
75
79
ldiv! (it. c, it. Pl, it. r)
76
80
77
81
ρ_prev = it. ρ
@@ -114,40 +118,48 @@ struct CGStateVariables{T,Tx<:AbstractArray{T}}
114
118
end
115
119
116
120
function cg_iterator! (x, A, b, Pl = Identity ();
117
- tol = sqrt (eps (real (eltype (b)))),
118
- maxiter:: Int = size (A, 2 ),
119
- statevars:: CGStateVariables = CGStateVariables (zero (x), similar (x), similar (x)),
120
- initially_zero:: 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
+ statevars:: CGStateVariables = CGStateVariables (zero (x), similar (x), similar (x)),
126
+ initially_zero:: Bool = false )
122
127
u = statevars. u
123
128
r = statevars. r
124
129
c = statevars. c
125
130
u .= zero (eltype (x))
126
131
copyto! (r, b)
127
132
133
+ # TODO : Deprecations introduced in v0.8
134
+ if tol != = nothing
135
+ Base. depwarn (" The keyword argument `tol` is deprecated, use `reltol` instead." , :cg_iterator! )
136
+ reltol = tol
137
+ end
138
+
128
139
# Compute r with an MV-product or not.
129
140
if initially_zero
130
141
mv_products = 0
131
- c = similar (x)
132
- residual = norm (b)
133
- reltol = residual * tol # Save one dot product
134
142
else
135
143
mv_products = 1
136
144
mul! (c, A, x)
137
145
r .- = c
138
- residual = norm (r)
139
- reltol = norm (b) * tol
140
146
end
147
+ residual = norm (r)
148
+ # TODO : According to the docs, the code below should use the initial residual
149
+ # instead of the norm of the RHS `b` to set the relative tolerance.
150
+ # See also https://github.com/JuliaMath/IterativeSolvers.jl/pull/244
151
+ # tolerance = max(reltol * residual, abstol)
152
+ tolerance = max (reltol * norm (b), abstol)
141
153
142
154
# Return the iterable
143
155
if isa (Pl, Identity)
144
156
return CGIterable (A, x, r, c, u,
145
- reltol , residual, one (residual),
157
+ tolerance , residual, one (residual),
146
158
maxiter, mv_products
147
159
)
148
160
else
149
161
return PCGIterable (Pl, A, x, r, c, u,
150
- reltol , residual, one (eltype (x)),
162
+ tolerance , residual, one (eltype (x)),
151
163
maxiter, mv_products
152
164
)
153
165
end
@@ -199,20 +211,28 @@ cg(A, b; kwargs...) = cg!(zerox(A, b), A, b; initially_zero = true, kwargs...)
199
211
- `:resnom` => `::Vector`: residual norm at each iteration.
200
212
"""
201
213
function cg! (x, A, b;
202
- tol = sqrt (eps (real (eltype (b)))),
203
- maxiter:: Int = size (A, 2 ),
204
- log:: Bool = false ,
205
- statevars:: CGStateVariables = CGStateVariables (zero (x), similar (x), similar (x)),
206
- verbose:: Bool = false ,
207
- Pl = Identity (),
208
- kwargs...
209
- )
214
+ abstol:: Real = zero (real (eltype (b))),
215
+ reltol:: Real = sqrt (eps (real (eltype (b)))),
216
+ tol = nothing , # TODO : Deprecations introduced in v0.8
217
+ maxiter:: Int = size (A, 2 ),
218
+ log:: Bool = false ,
219
+ statevars:: CGStateVariables = CGStateVariables (zero (x), similar (x), similar (x)),
220
+ verbose:: Bool = false ,
221
+ Pl = Identity (),
222
+ kwargs... )
210
223
history = ConvergenceHistory (partial = ! log)
211
224
history[:tol ] = tol
212
225
log && reserve! (history, :resnorm , maxiter + 1 )
213
226
227
+ # TODO : Deprecations introduced in v0.8
228
+ if tol != = nothing
229
+ Base. depwarn (" The keyword argument `tol` is deprecated, use `reltol` instead." , :cg! )
230
+ reltol = tol
231
+ end
232
+
214
233
# Actually perform CG
215
- iterable = cg_iterator! (x, A, b, Pl; tol = tol, maxiter = maxiter, statevars = statevars, kwargs... )
234
+ iterable = cg_iterator! (x, A, b, Pl; abstol = abstol, reltol = reltol, maxiter = maxiter,
235
+ statevars = statevars, kwargs... )
216
236
if log
217
237
history. mvps = iterable. mv_products
218
238
end
0 commit comments