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

Merged
merged 10 commits into from Oct 16, 2018
+18 −2
Merged

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

Commits
Show all changes
10 commits
Select commit Hold shift + click to select a range
Filter file types
Failed to load files and symbols.

#### Just for now

@@ -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

#### mcognetta Oct 15, 2018 • edited

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.

#### dkarrasch Oct 15, 2018

Author Contributor

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

#### dkarrasch Oct 15, 2018

Author Contributor

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)

#### fredrikekre Oct 15, 2018

Member

Maybe test these for complex-valued `UniformScaling`s as well?

#### 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.