I get that the compiler cannot figure out the type of vs[1:3], but if I could tell it to “drop the last element of vs” somehow, then it would know to the return type SVector{3}.
I also need to do this for SVector{3}, SMatrix{4,4} and SMatrix{3,3}. I can of course write several methods like this:
That’s excellent! I’m still missing a step, though. Do you know how I could create an index vector 1:N-1 to be able to drop the last index for a size N vector. I tried this:
function droplast(v::SVector{N, <:Number}) where {N}
ind = @SVector [i for i in 1:N-1]
return v[ind]
end
but this looks for N in global scope, so doesn’t work. Interestingly, @SVector fill(1, N-1) and some others behave nicely inside functions, so perhaps adding something like @SVector 1:N-1 could be a feature request to StaticArrays.jl?
For now, perhaps a @generated function would do the trick?
julia> Base.@pure pure_sub(a::Int, b::Int) = a - b
pure_sub (generic function with 1 method)
julia> function droplast(v::SVector{N, <:Number}) where {N}
ind = SVector{pure_sub(N, 1)}(1:N-1)
return v[ind]
end
droplast (generic function with 1 method)
julia> @btime droplast($a)
6.216 ns (0 allocations: 0 bytes)
4-element SVector{4,Float64}:
0.945968
0.0451724
0.917798
0.368511
julia> droplast(x::Tuple) = argdroplast(x...)
droplast (generic function with 1 method)
julia> argdroplast(x) = ()
argdroplast (generic function with 1 method)
julia> argdroplast(x,y...) = (x,argdroplast(y...)...)
argdroplast (generic function with 2 methods)
julia> droplast(v::SVector) = SVector(droplast(v.data))
droplast (generic function with 2 methods)
Looks like the generated one and tuple is the same speed except for n > 15 when the tuple one gives up. Pure is slower but doesn’t freak out at n = 15.