Skip to content

Commit 1c0b673

Browse files
authored
Ensure inverse of Symmetric{<:,Diagonal} returns same type (#1439)
1 parent fa00b3c commit 1c0b673

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

src/diagonal.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,10 @@ function inv(D::Diagonal{T}) where T
970970
Diagonal(Di)
971971
end
972972

973+
# Ensure doubly wrapped matrices use efficient diagonal methods and return a Symmetric/Hermitian type
974+
inv(A::Symmetric{<:Number,<:Diagonal}) = Symmetric(inv(A.data), sym_uplo(A.uplo))
975+
inv(A::Hermitian{<:Number,<:Diagonal}) = Hermitian(inv(real(A.data)), sym_uplo(A.uplo))
976+
973977
function pinv(D::Diagonal{T}) where T
974978
Di = similar(D.diag, typeof(inv(oneunit(T))))
975979
for i = 1:length(D.diag)

test/symmetric.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,21 @@ end
874874
@test det(Hermitian(A))::Float64 == det(A) == 0.0
875875
end
876876

877+
@testset "issue #1437: inverse of Symmetric|Hermitian{<:Any,<:Diagonal} returns of Symmetric|Hermitian{<:Any,<:Diagonal}" begin
878+
Dreal = Diagonal(randn(3))
879+
Dcomplex = Diagonal(randn(ComplexF64, 3))
880+
# without wrapper
881+
invDreal = inv(Dreal)
882+
invDcomplex = inv(real(Dcomplex)) # because Hermitian implies a real diagonal
883+
# with wrapper
884+
SDreal = Symmetric(Dreal)
885+
HDcomplex = Hermitian(Dcomplex)
886+
@test inv(SDreal)::Symmetric{Float64,typeof(Dreal)} invDreal
887+
@test inv(HDcomplex)::Hermitian{Float64,typeof(Dreal)} invDcomplex
888+
Dcomplex[2,2] = 0
889+
@test_throws SingularException inv(HDcomplex)
890+
end
891+
877892
@testset "symmetric()/hermitian() for Numbers" begin
878893
@test LinearAlgebra.symmetric(1) == LinearAlgebra.symmetric(1, :U) == 1
879894
@test LinearAlgebra.symmetric_type(Int) == Int

0 commit comments

Comments
 (0)