Skip to content

Commit

Permalink
Add a fully typed Diagonal constructor from AbstractMatrixes (#52487)
Browse files Browse the repository at this point in the history
The following works after this PR:
```julia
julia> oftype(Diagonal(Float32[1,2]), [1 0; 0 2])
2×2 Diagonal{Float32, Vector{Float32}}:
 1.0   ⋅ 
  ⋅   2.0
```
This changes the behavior of the constructor to copy the diagonal, so
now
```julia
julia> D = Diagonal([1,2]);

julia> typeof(D)(D).diag === D.diag
false
```
whereas this used to be `true` previously. This probably doesn't matter
much, as in most non-trivial cases it'd be copied anyway, and this
conversion is unusual in the trivial case.

---------

Co-authored-by: Daniel Karrasch <daniel.karrasch@posteo.de>
  • Loading branch information
jishnub and dkarrasch authored Dec 27, 2023
1 parent b4eefd0 commit 66e9410
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 1 deletion.
2 changes: 1 addition & 1 deletion stdlib/LinearAlgebra/src/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ struct Diagonal{T,V<:AbstractVector{T}} <: AbstractMatrix{T}
new{T,V}(diag)
end
end
Diagonal{T,V}(d::Diagonal) where {T,V<:AbstractVector{T}} = Diagonal{T,V}(d.diag)
Diagonal(v::AbstractVector{T}) where {T} = Diagonal{T,typeof(v)}(v)
Diagonal{T}(v::AbstractVector) where {T} = Diagonal(convert(AbstractVector{T}, v)::AbstractVector{T})

Expand Down Expand Up @@ -102,6 +101,7 @@ julia> Diagonal(A)
"""
Diagonal(A::AbstractMatrix) = Diagonal(diag(A))
Diagonal{T}(A::AbstractMatrix) where T = Diagonal{T}(diag(A))
Diagonal{T,V}(A::AbstractMatrix) where {T,V<:AbstractVector{T}} = Diagonal{T,V}(diag(A))
function convert(::Type{T}, A::AbstractMatrix) where T<:Diagonal
checksquare(A)
isdiag(A) ? T(A) : throw(InexactError(:convert, T, A))
Expand Down
7 changes: 7 additions & 0 deletions stdlib/LinearAlgebra/test/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ Random.seed!(1)
DI = Diagonal([1,2,3,4])
@test Diagonal(DI) === DI
@test isa(Diagonal{elty}(DI), Diagonal{elty})

# diagonal matrices may be converted to Diagonal
local A = [1 0; 0 2]
local DA = convert(Diagonal{Float32,Vector{Float32}}, A)
@test DA isa Diagonal{Float32,Vector{Float32}}
@test DA == A

# issue #26178
@test_throws MethodError convert(Diagonal, [1,2,3,4])
@test_throws DimensionMismatch convert(Diagonal, [1 2 3 4])
Expand Down

0 comments on commit 66e9410

Please sign in to comment.