JuliaArrays / JuliaArrays/StaticArrays.jl
reinterpret SVector as Vector{SVector}
Nobody has claimed this yet.
- 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
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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