Skip to content

Commit e43e7c0

Browse files
committed
Fix division by zero due to exact off-diagonal zeros in the Hessenberg matrix
1 parent c8a2ec6 commit e43e7c0

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

src/gmres.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,14 @@ function gmres!(x, A, b;
205205
end
206206

207207
function update_residual!(r::Residual, arnoldi::ArnoldiDecomp, k::Int)
208-
# Cheaply computes the current residual
209-
r.nullvec[k + 1] = -conj(dot(view(r.nullvec, 1 : k), view(arnoldi.H, 1 : k, k)) / arnoldi.H[k + 1, k])
210-
r.accumulator += abs2(r.nullvec[k + 1])
211-
r.current = r.β / r.accumulator
208+
if iszero(arnoldi.H[k + 1, k])
209+
r.current = zero(r.current)
210+
else
211+
# Cheaply computes the current residual
212+
r.nullvec[k + 1] = -conj(dot(view(r.nullvec, 1 : k), view(arnoldi.H, 1 : k, k)) / arnoldi.H[k + 1, k])
213+
r.accumulator += abs2(r.nullvec[k + 1])
214+
r.current = r.β / r.accumulator
215+
end
212216
end
213217

214218
function init!(arnoldi::ArnoldiDecomp{T}, x, b, Pl, Ax; initially_zero::Bool = false) where {T}

test/gmres.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,11 @@ end
6262
x = gmres(A, b; tol=tol, maxiter=2000)
6363
@test norm(A * x - b) / norm(b) tol
6464
end
65+
66+
@testset "Off-diagonal in hessenberg matrix exactly zero" begin
67+
A = Matrix(1.0I, 2, 2)
68+
b = [1.0, 2.2]
69+
x = gmres(A, b)
70+
@test all(x .== b)
71+
end
6572
end

0 commit comments

Comments
 (0)