JuliaArrays / JuliaArrays/StaticArrays.jl

reinterpret SVector as Vector{SVector}

Open
#634 8 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

fix-in-base
Dominant language
Julia
Stars
844
Forks
159
Avg merge
3d 21h
Merged PRs (30d)
3

Description

Last year, I had code to reinterpret an SVector with length N*3 as a Vector{SVector{3}} like reinterpret(SVector{3, Float64}, SVector{12}(1.0:12.0)). However this now errors:

julia> reinterpret(SVector{3, Float64}, SVector{12}(1.0:12.0))
DimensionMismatch("1:4 is inconsistent with SOneTo{12}")

Stacktrace:
 [1] (::getfield(StaticArrays, Symbol("#errmsg#1")){12})(::UnitRange{Int64}) at ~/.julia/packages/StaticArrays/3KEjZ/src/SOneTo.jl:14
 [2] Type at ~/.julia/packages/StaticArrays/3KEjZ/src/SOneTo.jl:15 [inlined]
 [3] convert at ./range.jl:143 [inlined]
 [4] oftype at ./essentials.jl:370 [inlined]
 [5] axes at ./reinterpretarray.jl:112 [inlined]
 [6] summary at ./show.jl:1863 [inlined]
 [7] show(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::MIME{Symbol("text/plain")}, ::Base.ReinterpretArray{SArray{Tuple{3},Float64,1,3},1,Float64,SArray{Tuple{12},Float64,1,12}}) at ./arrayshow.jl:316
 [8] limitstringmime(::MIME{Symbol("text/plain")}, ::Base.ReinterpretArray{SArray{Tuple{3},Float64,1,3},1,Float64,SArray{Tuple{12},Float64,1,12}}) at ~/.julia/packages/IJulia/gI2uA/src/inline.jl:37
 [9] display_mimestring(::MIME{Symbol("text/plain")}, ::Base.ReinterpretArray{SArray{Tuple{3},Float64,1,3},1,Float64,SArray{Tuple{12},Float64,1,12}}) at ~/.julia/packages/IJulia/gI2uA/src/display.jl:67
 [10] display_dict(::Base.ReinterpretArray{SArray{Tuple{3},Float64,1,3},1,Float64,SArray{Tuple{12},Float64,1,12}}) at ~/.julia/packages/IJulia/gI2uA/src/display.jl:96
 [11] #invokelatest#1 at ./essentials.jl:790 [inlined]
 [12] invokelatest at ./essentials.jl:789 [inlined]

The issue being that SOneTo will only convert identical UnitRanges (e.g. SOneTo{4} == 1:4, this is due to a requirement in the constructor at src/SOneTo.jl:12), so the axes are unable to be properly constructed. It seems reasonable to me that if somebody is trying to convert a unit range to an SOneTo, the range of the argument is most likely the intentional one, so relaxing the constructor to something like:

diff --git a/src/SOneTo.jl b/src/SOneTo.jl
index 96c1ad2..3dd29ba 100644
--- a/src/SOneTo.jl
+++ b/src/SOneTo.jl
@@ -9,10 +9,7 @@ end

 SOneTo(n::Int) = SOneTo{n}()
 function SOneTo{n}(r::AbstractUnitRange) where n
-    ((first(r) == 1) & (last(r) == n)) && return SOneTo{n}()
-
-    errmsg(r) = throw(DimensionMismatch("$r is inconsistent with SOneTo{$n}")) # avoid GC frame
-    errmsg(r)
+    (first(r) == 1) && return SOneTo{last(r)}()
 end

 Base.axes(s::SOneTo) = (s,)

Such a change makes my original example work again, and I will note that my example is also quite similar to the example given in #554. I wonder what the original intent behind this restriction was and/or if there are possible negatives to relaxing this? pinging @timholy as the author of that PR

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/SOneTo.jl, especially the SOneTo{n} constructor and its range validation, then reproduce the reinterpret(SVector{3, Float64}, SVector{12}(1.0:12.0)) example. Compare the behavior with the discussion in issue #554; done means the example constructs its axes without DimensionMismatch while preserving valid SOneTo behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
data
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.