@@ -17,17 +17,20 @@ mutable struct ChebyshevIterable{precT, matT, solT, vecT, realT <: Real}
17
17
λ_diff:: realT
18
18
19
19
resnorm:: realT
20
- reltol :: realT
20
+ tol :: realT
21
21
maxiter:: Int
22
22
mv_products:: Int
23
23
end
24
24
25
- converged (c :: ChebyshevIterable ) = c . resnorm ≤ c . reltol
26
- start (:: ChebyshevIterable ) = 0
27
- done (c :: ChebyshevIterable , iteration:: Int ) = iteration ≥ c . maxiter || converged (c )
25
+ @inline converged (it :: ChebyshevIterable ) = it . resnorm ≤ it . tol
26
+ @inline start (:: ChebyshevIterable ) = 0
27
+ @inline done (it :: ChebyshevIterable , iteration:: Int ) = iteration ≥ it . maxiter || converged (it )
28
28
29
29
function iterate (cheb:: ChebyshevIterable , iteration:: Int = start (cheb))
30
- if done (cheb, iteration) return nothing end
30
+ # Check for termination first
31
+ if done (cheb, iteration)
32
+ return nothing
33
+ end
31
34
32
35
T = eltype (cheb. x)
33
36
@@ -54,7 +57,12 @@ function iterate(cheb::ChebyshevIterable, iteration::Int=start(cheb))
54
57
end
55
58
56
59
function chebyshev_iterable! (x, A, b, λmin:: Real , λmax:: Real ;
57
- tol = sqrt (eps (real (eltype (b)))), maxiter = size (A, 2 ), Pl = Identity (), initially_zero = false )
60
+ abstol:: Real = zero (real (eltype (b))),
61
+ reltol:: Real = sqrt (eps (real (eltype (b)))),
62
+ tol = nothing , # TODO : Deprecations introduced in v0.8
63
+ maxiter = size (A, 2 ),
64
+ Pl = Identity (),
65
+ initially_zero = false )
58
66
59
67
λ_avg = (λmax + λmin) / 2
60
68
λ_diff = (λmax - λmin) / 2
@@ -65,23 +73,30 @@ function chebyshev_iterable!(x, A, b, λmin::Real, λmax::Real;
65
73
u = zero (x)
66
74
c = similar (x)
67
75
76
+ # TODO : Deprecations introduced in v0.8
77
+ if tol != = nothing
78
+ Base. depwarn (" The keyword argument `tol` is deprecated, use `reltol` instead." , :chebyshev_iterable! )
79
+ reltol = tol
80
+ end
81
+
68
82
# One MV product less
69
83
if initially_zero
70
- resnorm = norm (r)
71
- reltol = tol * resnorm
72
84
mv_products = 0
73
85
else
86
+ mv_products = 1
74
87
mul! (c, A, x)
75
88
r .- = c
76
- resnorm = norm (r)
77
- reltol = tol * norm (b)
78
- mv_products = 1
79
89
end
90
+ resnorm = norm (r)
91
+ # TODO : According to the docs, the code below should use the initial residual
92
+ # instead of the norm of the RHS `b` to set the relative tolerance.
93
+ # tolerance = max(reltol * resnorm, abstol)
94
+ tolerance = max (reltol * norm (b), abstol)
80
95
81
96
ChebyshevIterable (Pl, A, x, r, u, c,
82
97
zero (real (T)),
83
98
λ_avg, λ_diff,
84
- resnorm, reltol , maxiter, mv_products
99
+ resnorm, tolerance , maxiter, mv_products
85
100
)
86
101
end
87
102
@@ -112,7 +127,11 @@ Solve Ax = b for symmetric, definite matrices A using Chebyshev iteration.
112
127
- `initially_zero::Bool = false`: if `true` assumes that `iszero(x)` so that one
113
128
matrix-vector product can be saved when computing the initial
114
129
residual vector;
115
- - `tol`: tolerance for stopping condition `|r_k| / |r_0| ≤ tol`.
130
+ - `abstol::Real = zero(real(eltype(b)))`,
131
+ `reltol::Real = sqrt(eps(real(eltype(b))))`: absolute and relative
132
+ tolerance for the stopping condition
133
+ `|r_k| / |r_0| ≤ max(reltol * resnorm, abstol)`, where `r_k = A * x_k - b`
134
+ is the residual in the `k`th iteration;
116
135
- `maxiter::Int = size(A, 2)`: maximum number of inner iterations of GMRES;
117
136
- `Pl = Identity()`: left preconditioner;
118
137
- `log::Bool = false`: keep track of the residual norm in each iteration;
@@ -130,20 +149,28 @@ Solve Ax = b for symmetric, definite matrices A using Chebyshev iteration.
130
149
- `history`: convergence history.
131
150
"""
132
151
function chebyshev! (x, A, b, λmin:: Real , λmax:: Real ;
133
- Pl = Identity (),
134
- tol:: Real = sqrt (eps (real (eltype (b)))),
135
- maxiter:: Int = size (A, 2 ),
136
- log:: Bool = false ,
137
- verbose:: Bool = false ,
138
- initially_zero:: Bool = false
139
- )
152
+ abstol:: Real = zero (real (eltype (b))),
153
+ reltol:: Real = sqrt (eps (real (eltype (b)))),
154
+ tol = nothing , # TODO : Deprecations introduced in v0.8
155
+ Pl = Identity (),
156
+ maxiter:: Int = size (A, 2 ),
157
+ log:: Bool = false ,
158
+ verbose:: Bool = false ,
159
+ initially_zero:: Bool = false )
140
160
history = ConvergenceHistory (partial= ! log)
141
161
history[:tol ] = tol
142
162
reserve! (history, :resnorm , maxiter)
143
163
144
164
verbose && @printf (" === chebyshev ===\n %4s\t %7s\n " ," iter" ," resnorm" )
145
165
146
- iterable = chebyshev_iterable! (x, A, b, λmin, λmax; tol= tol, maxiter= maxiter, Pl= Pl, initially_zero= initially_zero)
166
+ # TODO : Deprecations introduced in v0.8
167
+ if tol != = nothing
168
+ Base. depwarn (" The keyword argument `tol` is deprecated, use `reltol` instead." , :cg! )
169
+ reltol = tol
170
+ end
171
+
172
+ iterable = chebyshev_iterable! (x, A, b, λmin, λmax; abstol= abstol, reltol= reltol,
173
+ maxiter= maxiter, Pl= Pl, initially_zero= initially_zero)
147
174
history. mvps = iterable. mv_products
148
175
for (iteration, resnorm) = enumerate (iterable)
149
176
nextiter! (history)
0 commit comments