Skip to content

Commit ec1b9a2

Browse files
committed
change CG to be in accordance with docs (reltol wrt initial residual instead of RHS) as suggested by @haampie
1 parent 4b192c0 commit ec1b9a2

File tree

2 files changed

+7
-12
lines changed

2 files changed

+7
-12
lines changed

src/cg.jl

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,7 @@ function cg_iterator!(x, A, b, Pl = Identity();
145145
r .-= c
146146
end
147147
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)
148+
tolerance = max(reltol * residual, abstol)
153149

154150
# Return the iterable
155151
if isa(Pl, Identity)

test/cg.jl

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ Random.seed!(1234321)
3434
@test ch.isconverged
3535

3636
# If you start from the exact solution, you should converge immediately
37-
x,ch = cg!(A \ b, A, b; reltol=10*reltol, log=true)
37+
x,ch = cg!(A \ b, A, b; abstol=2n*eps(real(T)), reltol=zero(real(T)), log=true)
3838
@test niters(ch) 1
3939
@test nprods(ch) 2
4040

41-
# Test with cholfact should converge immediately
41+
# Test with cholfact as preconditioner should converge immediately
4242
F = cholesky(A, Val(false))
4343
x,ch = cg(A, b; Pl=F, log=true)
4444
@test niters(ch) 2
@@ -56,6 +56,7 @@ end
5656

5757
rhs = randn(size(A, 2))
5858
rmul!(rhs, inv(norm(rhs)))
59+
abstol = 1e-5
5960
reltol = 1e-5
6061

6162
@testset "SparseMatrixCSC{$T, $Ti}" for T in (Float64, Float32), Ti in (Int64, Int32)
@@ -75,8 +76,8 @@ end
7576

7677
@testset "Function with specified starting guess" begin
7778
x0 = randn(size(rhs))
78-
xCG, hCG = cg!(copy(x0), Af, rhs; reltol=reltol, maxiter=100, log=true)
79-
xJAC, hJAC = cg!(copy(x0), Af, rhs; Pl=P, reltol=reltol, maxiter=100, log=true)
79+
xCG, hCG = cg!(copy(x0), Af, rhs; abstol=abstol, reltol=0.0, maxiter=100, log=true)
80+
xJAC, hJAC = cg!(copy(x0), Af, rhs; Pl=P, abstol=abstol, reltol=0.0, maxiter=100, log=true)
8081
@test norm(A * xCG - rhs) reltol
8182
@test norm(A * xJAC - rhs) reltol
8283
@test niters(hJAC) == niters(hCG)
@@ -107,9 +108,7 @@ end
107108
x = x0 + sqrt(eps(real(T))) * perturbation
108109
initial_residual = norm(A * x - b)
109110
x, ch = cg!(x, A, b, log=true)
110-
@test_broken 2 niters(ch) n
111-
# This test is currently broken since `norm(b)` is used in `cg_iterator!`
112-
# instead of the initial `residual` as described in the documentation.
111+
@test 2 niters(ch) n
113112

114113
# If the initial residual is small and a large absolute tolerance is used,
115114
# no iterations are necessary

0 commit comments

Comments
 (0)