Skip to content

Commit 281d229

Browse files
authored
Adding preconditioner to idrs (#297)
* Adding preconditioner to idrs * Update test/idrs.jl
1 parent ae01dfe commit 281d229

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

src/idrs.jl

+12-3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ shadow space.
2424
## Keywords
2525
2626
- `s::Integer = 8`: dimension of the shadow space;
27+
- `Pl::precT`: left preconditioner,
2728
- `abstol::Real = zero(real(eltype(b)))`,
2829
`reltol::Real = sqrt(eps(real(eltype(b))))`: absolute and relative
2930
tolerance for the stopping condition
@@ -46,6 +47,7 @@ shadow space.
4647
"""
4748
function idrs!(x, A, b;
4849
s = 8,
50+
Pl = Identity(),
4951
abstol::Real = zero(real(eltype(b))),
5052
reltol::Real = sqrt(eps(real(eltype(b)))),
5153
maxiter=size(A, 2),
@@ -55,7 +57,7 @@ function idrs!(x, A, b;
5557
history[:abstol] = abstol
5658
history[:reltol] = reltol
5759
log && reserve!(history, :resnorm, maxiter)
58-
idrs_method!(history, x, A, b, s, abstol, reltol, maxiter; kwargs...)
60+
idrs_method!(history, x, A, b, s, Pl, abstol, reltol, maxiter; kwargs...)
5961
log && shrink!(history)
6062
log ? (x, history) : x
6163
end
@@ -78,8 +80,8 @@ end
7880
end
7981

8082
function idrs_method!(log::ConvergenceHistory, X, A, C::T,
81-
s::Number, abstol::Real, reltol::Real, maxiter::Number; smoothing::Bool=false, verbose::Bool=false
82-
) where {T}
83+
s::Number, Pl::precT, abstol::Real, reltol::Real, maxiter::Number; smoothing::Bool=false, verbose::Bool=false
84+
) where {T, precT}
8385

8486
verbose && @printf("=== idrs ===\n%4s\t%7s\n","iter","resnorm")
8587
R = C - A*X
@@ -129,6 +131,9 @@ function idrs_method!(log::ConvergenceHistory, X, A, C::T,
129131
Q .+= c[i-k+1] .* U[i]
130132
end
131133

134+
# Preconditioning
135+
ldiv!(Pl, V)
136+
132137
# Compute new U[:,k] and G[:,k], G[:,k] is in space G_j
133138
V .= R .- V
134139

@@ -181,6 +186,10 @@ function idrs_method!(log::ConvergenceHistory, X, A, C::T,
181186
# Now we have sufficient vectors in G_j to compute residual in G_j+1
182187
# Note: r is already perpendicular to P so v = r
183188
copyto!(V, R)
189+
190+
# Preconditioning
191+
ldiv!(Pl, V)
192+
184193
mul!(Q, A, V)
185194
om = omega(Q, R)
186195
R .-= om .* Q

test/idrs.jl

+19
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,25 @@ end
4242
@test norm(A * x - b) / norm(b) reltol
4343
end
4444

45+
@testset "SparseMatrixCSC{$T, $Ti} with preconditioner" for T in (Float64, ComplexF64), Ti in (Int64, Int32)
46+
A = sprand(T, 1000, 1000, 0.1) + 30 * I
47+
b = rand(T, 1000)
48+
reltol = eps(real(T))
49+
50+
x, history = idrs(A, b, log=true)
51+
@test history.isconverged
52+
@test norm(A * x - b) / norm(b) reltol
53+
54+
Apre = lu(A)
55+
xpre, historypre = idrs(A, b, Pl = Apre, log=true)
56+
@test historypre.isconverged
57+
@test norm(A * xpre - b) / norm(b) reltol
58+
59+
@test isapprox(x, xpre, rtol = 1e-3)
60+
@test historypre.iters < history.iters
61+
62+
end
63+
4564
@testset "Maximum number of iterations" begin
4665
x, history = idrs(rand(5, 5), rand(5), log=true, maxiter=2)
4766
@test history.iters == 2

0 commit comments

Comments
 (0)