Skip to content

Commit

Permalink
use real diagonal in cholesky (#37382)
Browse files Browse the repository at this point in the history
  • Loading branch information
KlausC committed Sep 12, 2020
1 parent 7ecd1f9 commit eeffe57
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 4 deletions.
14 changes: 10 additions & 4 deletions stdlib/LinearAlgebra/src/cholesky.jl
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,15 @@ end
function _chol!(A::AbstractMatrix, ::Type{UpperTriangular})
require_one_based_indexing(A)
n = checksquare(A)
realdiag = eltype(A) <: Complex
@inbounds begin
for k = 1:n
Akk = realdiag ? real(A[k,k]) : A[k,k]
for i = 1:k - 1
A[k,k] -= A[i,k]'A[i,k]
Akk -= realdiag ? abs2(A[i,k]) : A[i,k]'A[i,k]
end
Akk, info = _chol!(A[k,k], UpperTriangular)
A[k,k] = Akk
Akk, info = _chol!(Akk, UpperTriangular)
if info != 0
return UpperTriangular(A), info
end
Expand All @@ -205,12 +208,15 @@ end
function _chol!(A::AbstractMatrix, ::Type{LowerTriangular})
require_one_based_indexing(A)
n = checksquare(A)
realdiag = eltype(A) <: Complex
@inbounds begin
for k = 1:n
Akk = realdiag ? real(A[k,k]) : A[k,k]
for i = 1:k - 1
A[k,k] -= A[k,i]*A[k,i]'
Akk -= realdiag ? abs2(A[k,i]) : A[k,i]*A[k,i]'
end
Akk, info = _chol!(A[k,k], LowerTriangular)
A[k,k] = Akk
Akk, info = _chol!(Akk, LowerTriangular)
if info != 0
return LowerTriangular(A), info
end
Expand Down
7 changes: 7 additions & 0 deletions stdlib/LinearAlgebra/test/cholesky.jl
Original file line number Diff line number Diff line change
Expand Up @@ -440,4 +440,11 @@ end
end
end

@testset "issue #37356, diagonal elements of hermitian generic matrix" begin
B = Hermitian(hcat([one(BigFloat) + im]))
@test Matrix(cholesky(B)) B
C = Hermitian(hcat([one(BigFloat) + im]), :L)
@test Matrix(cholesky(C)) C
end

end # module TestCholesky

0 comments on commit eeffe57

Please sign in to comment.