Thank you @longemen3000, SA
constructor does create nested SVectors even when both have Size
1 (i.e. N=1
and Dim=1
). But I would still like to understand what prevents the constructor with explicit type parameters (I have also tried directly using SArray
constructor, without using the SVector
alias, and got the same error). I checked the source code of StaticArraysCore.jl but couldn’t understand why:
A) SVector
of a Size
-2 Svector
(or Size
-2 SVector
of Size
-1 SVector
s) either (1) uses the first inner construct of SArray
, or (2) passes the convert_tuple
,
B) while a SVector
of a Size
-1 Svector
fails in the convert_tuple
.
Moreover, SA
constructor seems to be much slower when passed an existing SVector
and makes an extra allocation, compared to passing directly the type parameters of the inner SVector
. See a similar discussion on creating SVector of SVectors
julia> my_vector_2d
2-element SVector{2, Float64} with indices SOneTo(2):
0.8
0.9
julia> @benchmark SA[my_vector_2d]
BenchmarkTools.Trial: 10000 samples with 590 evaluations.
Range (min … max): 197.217 ns … 6.917 μs ┊ GC (min … max): 0.00% … 96.72%
Time (median): 209.234 ns ┊ GC (median): 0.00%
Time (mean ± σ): 230.900 ns ± 153.116 ns ┊ GC (mean ± σ): 1.39% ± 2.16%
▅▇█▇▃ ▂▂▁ ▁▁▂ ▁
█████▇████▇██████████▇▇▆█▇███▇▇▇▆▆▆▆▆▆▆▆▇▆▆▆▆▅▆▆▅▆▅▅▆▅▅▅▆▅▅▅▅ █
197 ns Histogram: log(frequency) by time 486 ns <
Memory estimate: 64 bytes, allocs estimate: 2.
julia> @benchmark SVector{1, SVector{2, Float64}}(my_vector_2d)
BenchmarkTools.Trial: 10000 samples with 942 evaluations.
Range (min … max): 79.872 ns … 4.579 μs ┊ GC (min … max): 0.00% … 98.13%
Time (median): 82.801 ns ┊ GC (median): 0.00%
Time (mean ± σ): 93.011 ns ± 85.076 ns ┊ GC (mean ± σ): 1.75% ± 1.95%
▇█▇▂ ▁▂▁▂▃ ▁▁ ▁ ▁
████▇▇▇▆█████▆▅▆▇████▇████▇▇▇██▆▆▆▅▆▆▇▇▇▆▆▅▅▅▅▆▅▆▆▅▆▅▅▄▄▄▅▅ █
79.9 ns Histogram: log(frequency) by time 201 ns <
Memory estimate: 32 bytes, allocs estimate: 1.
and here is an MWE without benchmarks:
using BenchmarkTools, StaticArrays
# Inner SVectors
my_vector_1d = SVector{1, Float64}(0.8)
my_vector_2d = SVector{2, Float64}(0.8, 0.9)
# Container SVectors
# Size-1 SVector of Size-1 SVector
# my_container_faulty = SVector{1, SVector{1, Float64}}(my_vector_1d) # gives error
my_container_a = SA[my_vector_1d]
# Size-2 SVector of Size-1 SVectors
my_container_b = SVector{2, SVector{1, Float64}}(my_vector_1d, my_other_vector_1d)
# Size-1 SVector of Size-2 Svector
my_container_c = SVector{1, SVector{2, Float64}}(my_vector_2d)