# Inconsistent behaviour of Diagonal and Triangular matrix constructors

**URL:** https://discourse.julialang.org/t/inconsistent-behaviour-of-diagonal-and-triangular-matrix-constructors/22134
**Category:** Internals & Design
**Created:** [March 21, 2019, 7:56am UTC](https://discourse.julialang.org/t/inconsistent-behaviour-of-diagonal-and-triangular-matrix-constructors/22134 "2019-03-21T07:56:51Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![bsxfan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bsxfan/32/6914_2.png) [@bsxfan](https://discourse.julialang.org/u/bsxfan)
#### Post date: [March 21, 2019, 7:56am UTC](https://discourse.julialang.org/t/inconsistent-behaviour-of-diagonal-and-triangular-matrix-constructors/22134/1 "2019-03-21T07:56:51Z")

</div>

Let e.g.: `R=randn(2,2)`, (a general square matrix) then `U = UpperTriangular(R)` or `L = LowerTriangular(R)` would sucessfully return triangular matrices. Also, `D = Diagonal(R)` works similarly. In all these cases, some (in general) non-zero elements of the original R have been effectively zeroed, without throwing errors. (You can verify they are zero by doing `collect(U)` etc.)

However, `Diagonal(U)`, or `Diagonal(L)` throws `ArgumentError: matrix cannot be represented as Diagonal` because of the non-zero off-diagonal elements in the triangular inputs.

While the error can be avoided by explicitly doing `Diagonal(diag(L))` , I would argue that this behaviour of the `Diagonal` constructor is inconsistent between full and triangular arguments. It is also inconsistent with the UpperTriangular and LowerTriangular constructors.

My vote would be to resolve the inconsistencies by e.g.:

```julia
Diagonal(Tr::AbstractTriangular) = Diagonal(diag(Tr))

```

or something equivalent.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [March 21, 2019, 8:42am UTC](https://discourse.julialang.org/t/inconsistent-behaviour-of-diagonal-and-triangular-matrix-constructors/22134/2 "2019-03-21T08:42:26Z")

</div>

I think that this is a reasonable suggestion. There is already an open issue,

> <https://github.com/JuliaLang/julia/issues/28581>
>
> \`\`\` 
> | | |\_| | | | (\_| | | Version 1.1.0-DEV.10 (2018-08-11)
> \_/ |\\\_\_'\_|\_|…\_|\\\_\_'\_| | sparsearrays-triangular-operations/72f777ee96 (fork: 8 commits, 0 days)
> |\_\_/ |
> \`\`\`
> Whereas docu states:
> \`\`\`
> help?\> Diagonal
> Diagonal(A::AbstractMatrix)
> Construct a matrix from the diagonal of A.
> \`\`\`
> When applied to a subtype of \`AbstractMatrix\` we obtain the following results:
> \`\`\`
> julia\> A = UpperTriangular(sparse(\[1.0 0;20 0\]))
> 2×2 UpperTriangular{Float64,SparseMatrixCSC{Float64,Int64}}:
> 1.0 0.0
> ⋅ 0.0
> 
> julia\> Diagonal(A)
> 2×2 Diagonal{Float64,SparseVector{Float64,Int64}}:
> 1.0 ⋅ 
> ⋅ 0.0
> 
> julia\> A\[1,2\] = 1
> 1
> 
> julia\> Diagonal(A)
> ERROR: ArgumentError: matrix cannot be represented as Diagonal
> Stacktrace:
> \[1\] Diagonal(::UpperTriangular{Float64,SparseMatrixCSC{Float64,Int64}}) at /home/julia/julia/usr/share/julia/stdlib/v1.1/LinearAlgebra/src/special.jl:48
> \[2\] top-level scope at none:0
> \`\`\`
> That means, in this case the \`Diagonal\` is not constructed from the diagonal of \`A\`, but an error is thrown, if \`isdiag(A) == false\`.
> The same behavior applies for some other subtypes of \`AbstractMatrix\`, and not for others. 
> IMO the check for diagonality should be removed from the constructors, and in all cases 
> \`Diagonal(A::AbstractMatrix) = Diagonal(diag(A))\` should be true.
> Alternatively the docu string should warn the user about the error check in some and which cases.

which seems to be dormant. Perhaps revive it, ideally by making a small PR.
