Julia: Converting a vector to `Diagonal` shouldn't work

Created on 23 Feb 2018  ยท  7Comments  ยท  Source: JuliaLang/julia

This new behaviour seems wrong:

julia> convert(Diagonal, rand(5))
5ร—5 Diagonal{Float64,Array{Float64,1}}:
 0.731736   โ‹…         โ‹…         โ‹…         โ‹…      
  โ‹…        0.501643   โ‹…         โ‹…         โ‹…      
  โ‹…         โ‹…        0.520562   โ‹…         โ‹…      
  โ‹…         โ‹…         โ‹…        0.390789   โ‹…      
  โ‹…         โ‹…         โ‹…         โ‹…        0.237735

I think the old behaviour of only supporting Diagonal(rand(5)) was correct.

arrays

Most helpful comment

Some discussion in #24595 :).

All 7 comments

I guess
https://github.com/JuliaLang/julia/blob/f4d82b2bb16704106d1d4ec4e9bc6cc08a50ebb9/base/abstractarray.jl#L15
should be restricted w.r.t the dimension of the array? Something like

diff --git a/base/abstractarray.jl b/base/abstractarray.jl
index ff81756..1077add 100644
--- a/base/abstractarray.jl
+++ b/base/abstractarray.jl
@@ -12,7 +12,7 @@ Supertype for `N`-dimensional arrays (or array-like types) with elements of type
 AbstractArray

 convert(::Type{T}, a::T) where {T<:AbstractArray} = a
-convert(::Type{T}, a::AbstractArray) where {T<:AbstractArray} = T(a)
+convert(::Type{T}, a::AbstractArray{<:Any,N}) where {N,T<:AbstractArray{<:Any,N}} = T(a)

 if nameof(@__MODULE__) === :Base  # avoid method overwrite
 # catch undefined constructors before the deprecation kicks in

?

I think that line should probably be removed completely, by the same logic that it was removed for general types.

This is a problem. We've been slowly moving to a world that supports T(a) where T <: AbstractArray and a isa AbstractArray to construct a new instance of T with the contents of a. LinearAlgebra's structured matrices do something totally different.

Some discussion in #24595 :).

I was involved in that discussion and I don't think there's another example in Base as egregiously confusing as Diagonal([1,2,3]).

One solution (which I used in BandedMatrices.jl) is to add an underscore _Diagonal([1,2,3]), but this should only be an internal solution.

This could be combined with an exported (and un-deprecated) diagm, so that diagm([1,2,3]) returns a Diagonal matrix.

We should narrow the convert definition only to cases that do the right thing (i.e. the input and output are sufficiently similar).

And we shouldn't require 1-argument constructors for AbstractArrays to construct a new array based upon the iteration of the argument filling all cartesian values of the array.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

StefanKarpinski picture StefanKarpinski  ยท  3Comments

m-j-w picture m-j-w  ยท  3Comments

sbromberger picture sbromberger  ยท  3Comments

felixrehren picture felixrehren  ยท  3Comments

musm picture musm  ยท  3Comments