diff --git a/base/linalg/generic.jl b/base/linalg/generic.jl index 404f96e942285..af37d88723cfe 100644 --- a/base/linalg/generic.jl +++ b/base/linalg/generic.jl @@ -273,6 +273,17 @@ function issym(A::AbstractMatrix) return true end +function issym{T<:FloatingPoint}(A::Union(AbstractMatrix{Complex{T}}, AbstractMatrix{T})) + m, n = size(A) + m==n || return false + for i = 1:(n-1), j = (i+1):n + if !isapprox(A[i,j], transpose(A[j,i])) + return false + end + end + return true +end + issym(x::Number) = true function ishermitian(A::AbstractMatrix) @@ -286,6 +297,17 @@ function ishermitian(A::AbstractMatrix) return true end +function ishermitian{T<:FloatingPoint}(A::Union(AbstractMatrix{Complex{T}}, AbstractMatrix{T})) + m, n = size(A) + m==n || return false + for i = 1:n, j = i:n + if !isapprox(A[i,j], ctranspose(A[j,i])) + return false + end + end + return true +end + ishermitian(x::Number) = (x == conj(x)) function istriu(A::AbstractMatrix) diff --git a/base/linalg/symmetric.jl b/base/linalg/symmetric.jl index 5475c8c9433f0..46cafe6976c5c 100644 --- a/base/linalg/symmetric.jl +++ b/base/linalg/symmetric.jl @@ -35,6 +35,10 @@ issym(A::Symmetric) = true transpose(A::Symmetric) = A ctranspose(A::Hermitian) = A +#Test whether a matrix is positive-definite +isposdef!(A::HermOrSym) = isposdef!(A.data, symbol(A.uplo)) +isposdef{T}(A::HermOrSym{T}) = (S = typeof(sqrt(one(T))); isposdef!(S == T ? copy(A.data) : convert(AbstractMatrix{S}, A.data), symbol(A.uplo))) + ## Matvec A_mul_B!{T<:BlasFloat,S<:AbstractMatrix}(y::StridedVector{T}, A::Symmetric{T,S}, x::StridedVector{T}) = BLAS.symv!(A.uplo, one(T), A.data, x, zero(T), y) A_mul_B!{T<:BlasComplex,S<:AbstractMatrix}(y::StridedVector{T}, A::Hermitian{T,S}, x::StridedVector{T}) = BLAS.hemv!(A.uplo, one(T), A.data, x, zero(T), y) diff --git a/test/linalg4.jl b/test/linalg4.jl index 9187453c2a73f..86759a03f1f9d 100644 --- a/test/linalg4.jl +++ b/test/linalg4.jl @@ -244,3 +244,24 @@ end A = eye(4) @test diag(A) == ones(4) @test diag(sub(A, 1:3, 1:3)) == ones(3) + +# Tests for #10298 +for elT in [Float32, Float64] + A1 = ones(elT,10,10) + A = convert(Array{Complex{elT}}, A1) + A[end,1] = Complex{elT}(nextfloat((A[end,1].re)), A[end,1].im) + @test issym(A) + A = A + triu(A1)im - tril(A1)im + @test ishermitian(A) + + D=diagm(rand(100))*100 + D[end,1] = nextfloat((D[end,1])) + + for HOrS in [Hermitian, Symmetric] + @test isposdef(HOrS(D)) + @test isposdef!(copy(HOrS(D))) + end + @test ishermitian(D) + @test issym(D) + @test isposdef(D) +end