SMatrix static slice

Is StaticArrays.SUnitRange (which is internal, cf StaticArrays.jl#474) the only way to get static slices for dimensions known at compile time?

MWE:

julia> using StaticArrays

julia> A = one(SMatrix{4,4})
4×4 SMatrix{4, 4, Float64, 16} with indices SOneTo(4)×SOneTo(4):
 1.0  0.0  0.0  0.0
 0.0  1.0  0.0  0.0
 0.0  0.0  1.0  0.0
 0.0  0.0  0.0  1.0

julia> s = StaticArrays.SUnitRange(1,2)
SUnitRange(1,2)

julia> A[s, s]
2×2 SMatrix{2, 2, Float64, 4} with indices SOneTo(2)×SOneTo(2):
 1.0  0.0
 0.0  1.0

Not always optimal, but one option you have is to just make SVectors of the range elements:

julia> srange(start, stop) = SVector(ntuple(i -> i+start-1, stop-start+1));

julia> s = srange(1, 2)
2-element SVector{2, Int64} with indices SOneTo(2):
 1
 2

julia> A[s, s]
2×2 SMatrix{2, 2, Float64, 4} with indices SOneTo(2)×SOneTo(2):
 1.0  0.0
 0.0  1.0

This is usually a bad idea, but for the sorts of small sizes typical to StaticArrays.jl, it might be fine.

You may use a SizedArray wrapper at present:

julia> s = SizedVector{2}(1:2)
2-element SizedVector{2, Int64, UnitRange{Int64}} with indices SOneTo(2):
 1
 2

julia> A[s,s]
2×2 SMatrix{2, 2, Float64, 4} with indices SOneTo(2)×SOneTo(2):
 1.0  0.0
 0.0  1.0
6 Likes

Is there something wrong with this solution (I’m asking because that’s what I would have done)?

julia> function test(a, ::Val{N}) where {N}
           b = SMatrix{N,N}(@view(a[1:N, 1:N]))
           return b
       end
test (generic function with 2 methods)

julia> @btime test($A, Val(2))
  1.858 ns (0 allocations: 0 bytes)
2×2 SMatrix{2, 2, Float64, 4} with indices SOneTo(2)×SOneTo(2):
 1.0  0.0
 0.0  1.0

julia> @btime test($A, Val(3))
  2.121 ns (0 allocations: 0 bytes)
3×3 SMatrix{3, 3, Float64, 9} with indices SOneTo(3)×SOneTo(3):
 1.0  0.0  0.0
 0.0  1.0  0.0
 0.0  0.0  1.0
2 Likes