From 66e941073f400b92a6d8cf4d6bce5a6cb2d00b6c Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Wed, 27 Dec 2023 12:06:28 +0530 Subject: [PATCH] Add a fully typed Diagonal constructor from `AbstractMatrix`es (#52487) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- stdlib/LinearAlgebra/src/diagonal.jl | 2 +- stdlib/LinearAlgebra/test/diagonal.jl | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/stdlib/LinearAlgebra/src/diagonal.jl b/stdlib/LinearAlgebra/src/diagonal.jl index bd2958d1b222b..e8638d3d7ff12 100644 --- a/stdlib/LinearAlgebra/src/diagonal.jl +++ b/stdlib/LinearAlgebra/src/diagonal.jl @@ -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}) @@ -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)) diff --git a/stdlib/LinearAlgebra/test/diagonal.jl b/stdlib/LinearAlgebra/test/diagonal.jl index 3de868a847b7c..9db7d8071931c 100644 --- a/stdlib/LinearAlgebra/test/diagonal.jl +++ b/stdlib/LinearAlgebra/test/diagonal.jl @@ -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])