Skip to content

Conversion to AbstractArray not defined #746

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
daanhb opened this issue Feb 24, 2020 · 3 comments
Closed

Conversion to AbstractArray not defined #746

daanhb opened this issue Feb 24, 2020 · 3 comments
Labels
feature features and feature requests

Comments

@daanhb
Copy link

daanhb commented Feb 24, 2020

Conversion of static vectors and matrices to an AbstractVector or AbstractArray with a wider element type seems to fail with an error:

julia> using StaticArrays

julia> convert(AbstractVector{BigFloat}, SVector(1.0, 2.0))
ERROR: setindex!() with non-isbitstype eltype is not supported by StaticArrays. Consider using SizedArray.
...

Yet, a type-stable conversion is possible because:

julia> convert(SVector{2,BigFloat}, SVector(1.0, 2.0)) isa AbstractVector{BigFloat}
true

Conversion to an abstract vector or abstract array with the same element type succeeds (via a fallback in Base).

I use conversions like this elsewhere in generic code that updates the element type of a vector. Currently, I have to add special cases for static vectors.

Would this just be a matter of adding conversion routines that invoke the right static array constructor? E.g., though it should be more general than this:

julia> import Base.convert

julia> convert(::Type{AbstractArray{T}}, v::SVector{N,S}) where {N,S,T} = convert(SVector{N,T}, v)
convert (generic function with 205 methods)

julia> convert(::Type{AbstractVector{T}}, v::SVector{N,S}) where {N,S,T} = convert(SVector{N,T}, v)
convert (generic function with 206 methods)

julia> convert(AbstractVector{BigFloat}, SVector(1.0, 2.0))
2-element SArray{Tuple{2},BigFloat,1,2} with indices SOneTo(2):
 1.0
 2.0

julia> ans isa AbstractVector{BigFloat}
true

This is not as problematic as going in the other direction (converting from abstract vectors to static vectors).

@c42f c42f added the feature features and feature requests label Feb 25, 2020
@c42f
Copy link
Member

c42f commented Feb 25, 2020

This seems fairly clear cut — Base defines it so we should too.

A little use of similar_type and matching the AbstractArray{N} dimension N to the static array dimension will probably work.

@daanhb
Copy link
Author

daanhb commented Feb 25, 2020

Thanks! Judging by the definitions in base here, the conversions to AbstractArray{T} and AbstractArray{T,N} end up calling the AbstractArray{T} and AbstractArray{T,N} constructor. So, it seems nicer to define those.

Would adding the following lines to convert.jl in StaticArrays be sufficient for all cases? Is this the right way to do it?

AbstractArray{T}(sa::StaticArray{S,T}) where {S,T} = sa
AbstractArray{T,N}(sa::StaticArray{S,T,N}) where {S,T,N} = sa
AbstractArray{T}(sa::StaticArray{S,U}) where {S,T,U} = similar_type(typeof(sa),T,Size(sa))(Tuple(sa))
AbstractArray{T,N}(sa::StaticArray{S,U,N}) where {S,T,U,N} = similar_type(typeof(sa),T,Size(sa))(Tuple(sa))

It does work for the cases I've tried (SVector and SMatrix), but the StaticArrays codebase is larger than I was expecting and there are a lot of other cases. It would be very convenient indeed if similar_type just works like it seems to.

@c42f
Copy link
Member

c42f commented Mar 5, 2020

Fixed in #747 (thanks!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature features and feature requests
Projects
None yet
Development

No branches or pull requests

2 participants