Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LinearAlgebra] Add isdiag/isposdef for Diagonal and UniformScaling #29638

Merged
merged 10 commits into from Oct 16, 2018
@@ -123,6 +123,7 @@ factorize(D::Diagonal) = D
real(D::Diagonal) = Diagonal(real(D.diag))
imag(D::Diagonal) = Diagonal(imag(D.diag))

isdiag(D::Diagonal) = true

This comment has been minimized.

Copy link
@mcognetta

mcognetta Oct 15, 2018

Contributor

Sorry, one more thing. This fails when we have a block diagonal matrix in which not all blocks are diagonal.

MWE:

julia> D=Diagonal([[1 0; 0 1], [1 0; 1 1]])
2×2 Diagonal{Array{Int64,2},Array{Array{Int64,2},1}}:
 [1 0; 0 1]      ⋅     
     ⋅       [1 0; 1 1]

julia> isdiag(D)
true

I believe it should be
isdiag(D::Diagonal) = all(isdiag, D.diag)
isdiag(D::Diagonal{<:Number}) = true

But I am not so sure on what it means to be a matrix of matrices so maybe @fredrikekre can correct me.

This comment has been minimized.

Copy link
@dkarrasch

dkarrasch Oct 15, 2018

Author Contributor

I see, I only had the Number case in mind. I'll fix this.

This comment has been minimized.

Copy link
@dkarrasch

dkarrasch Oct 15, 2018

Author Contributor

... and add a test.

istriu(D::Diagonal) = true
istril(D::Diagonal) = true
function triu!(D::Diagonal,k::Integer=0)
@@ -74,10 +74,12 @@ oneunit(J::UniformScaling{T}) where {T} = oneunit(UniformScaling{T})
zero(::Type{UniformScaling{T}}) where {T} = UniformScaling(zero(T))
zero(J::UniformScaling{T}) where {T} = zero(UniformScaling{T})

isdiag(::UniformScaling) = true
istriu(::UniformScaling) = true
istril(::UniformScaling) = true
issymmetric(::UniformScaling) = true
ishermitian(J::UniformScaling) = isreal(J.λ)
isposdef(J::UniformScaling) = isposdef(J.λ)

(+)(J::UniformScaling, x::Number) = J.λ + x
(+)(x::Number, J::UniformScaling) = x + J.λ
@@ -50,6 +50,7 @@ Random.seed!(1)
@test D[1,2] == 0

@test issymmetric(D)
@test isdiag(D)
@test istriu(D)
@test istril(D)
if elty <: Real
@@ -30,13 +30,16 @@ end
@test conj(UniformScaling(1.0+1.0im))::UniformScaling{Complex{Float64}} == UniformScaling(1.0-1.0im)
end

@testset "istriu, istril, issymmetric, ishermitian, isapprox" begin
@testset "isdiag, istriu, istril, issymmetric, ishermitian, isposdef, isapprox" begin
@test isdiag(I)
@test istriu(I)
@test istril(I)
@test issymmetric(I)
@test issymmetric(UniformScaling(complex(1.0,1.0)))
@test ishermitian(I)
@test !ishermitian(UniformScaling(complex(1.0,1.0)))
@test isposdef(I)
@test !isposdef(-I)

This comment has been minimized.

Copy link
@fredrikekre

fredrikekre Oct 15, 2018

Member

Maybe test these for complex-valued UniformScalings as well?

This comment has been minimized.

Copy link
@dkarrasch

dkarrasch Oct 15, 2018

Author Contributor

Yes, I think that's what @mcognetta's suggestion above does, I believe. This is now included.

@test UniformScaling(4.00000000000001) ≈ UniformScaling(4.0)
@test UniformScaling(4.32) ≈ UniformScaling(4.3) rtol=0.1 atol=0.01
@test UniformScaling(4.32) ≈ 4.3 * [1 0; 0 1] rtol=0.1 atol=0.01
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.