Julia: isposdef not defined for symmetric matrices

Created on 26 Apr 2017  ·  5Comments  ·  Source: JuliaLang/julia

The standard linalg function isposdef does not work for symmetric matrices (recent git master):

x = rand(5, 5)
x = x*x'
isposdef(x)
isposdef(Symmetric(x))

The last line fails with an error:

ERROR: MethodError: no method matching isposdef!(::Symmetric{Float64,Array{Float64,2}})

which I guess is caused by a missing definition. One workaround is to access underlying matrix directly but it is inconvenient:

isposdef(Symmetric(x).data)

I think this behavior is not correct and surprising for each user, I have not found any mention of such limitation in the documentation. There is an additional implementation for Diagonal matrices and this works fine:

isposdef(Diagonal(rand(1, 5)))
linear algebra

Most helpful comment

I think the post 0.6 solution should be to store info in the Cholesky type and delay throwing. That is what we do for LU and BunchKaufman and then we could just have isposdef(F::Cholesky) = F.info == 0 and something like isposdef(A::AbstractMatrix) = ishermitian(A) && isposdef(cholfact(A)).

All 5 comments

The same applies for Hermitian. Something like this seems to be sufficient (for dense matrices at least):

isposdef!(A::HermOrSym{<:BlasFloat, <:StridedMatrix}) = ishermitian(A) && LAPACK.potrf!(A.uplo, A.data)[2] == 0

mirroring the definitions here (and here). I will submit a PR.

@fredrikekre Why is ishermitian(A) necessary here? You're just passing a Hermitian/Symmetric matrix, right?

For cases like this:

julia> A = complex.(rand(2, 2), rand(2, 2))
2×2 Array{Complex{Float64},2}:
 0.127036+0.875987im  0.702463+0.796754im
 0.631628+0.488688im  0.214832+0.825713im

julia> ishermitian(Symmetric(A))
false

@fredrikekre I see, thanks. I forgot that one can make a complex symmetric matrix.

I think the post 0.6 solution should be to store info in the Cholesky type and delay throwing. That is what we do for LU and BunchKaufman and then we could just have isposdef(F::Cholesky) = F.info == 0 and something like isposdef(A::AbstractMatrix) = ishermitian(A) && isposdef(cholfact(A)).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ararslan picture ararslan  ·  3Comments

dpsanders picture dpsanders  ·  3Comments

Keno picture Keno  ·  3Comments

sbromberger picture sbromberger  ·  3Comments

StefanKarpinski picture StefanKarpinski  ·  3Comments