Short version: Why can I create SVector of at least 2 SVectors of size 1, or a SVector of a single SVector of at least size 2, but cannot create SVector of a single SVector of size 1?:
julia> using StaticArrays
julia> my_vector_1d = SVector{1, Float64}(0.8)
1-element SVector{1, Float64} with indices SOneTo(1):
0.8
julia> my_vector_2d = SVector{2, Float64}(0.8, 0.9)
2-element SVector{2, Float64} with indices SOneTo(2):
0.8
0.9
julia> my_container_2d = SVector{1, SVector{2, Float64}}(my_vector_2d)
1-element SVector{1, SVector{2, Float64}} with indices SOneTo(1):
[0.8, 0.9]
julia> my_container_1d = SVector{2, SVector{1, Float64}}(my_vector_1d, my_vector_1d)
2-element SVector{2, SVector{1, Float64}} with indices SOneTo(2):
[0.8]
[0.8]
julia> my_other_container_1d = SVector{1, SVector{1, Float64}}(my_vector_1d)
ERROR: MethodError: Cannot `convert` an object of type Float64 to an object of type SVector{1, Float64}
Closest candidates are:
convert(::Type{SVector{N, T}}, ::CartesianIndex{N}) where {N, T} at ~/.julia/packages/StaticArrays/a4r2v/src/SVector.jl:8
convert(::Type{T}, ::Factorization) where T<:AbstractArray at /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/LinearAlgebra/src/factorization.jl:58
convert(::Type{SA}, ::Tuple) where SA<:StaticArray at ~/.julia/packages/StaticArrays/a4r2v/src/convert.jl:179
...
Stacktrace:
[1] macro expansion
@ ~/.julia/packages/StaticArraysCore/U2Z1K/src/StaticArraysCore.jl:81 [inlined]
[2] convert_ntuple
@ ~/.julia/packages/StaticArraysCore/U2Z1K/src/StaticArraysCore.jl:77 [inlined]
[3] SVector{1, SVector{1, Float64}}(x::Tuple{Float64})
@ StaticArraysCore ~/.julia/packages/StaticArraysCore/U2Z1K/src/StaticArraysCore.jl:113
[4] SVector{1, SVector{1, Float64}}(sa::SVector{1, Float64})
@ StaticArrays ~/.julia/packages/StaticArrays/a4r2v/src/convert.jl:167
[5] top-level scope
@ REPL[54]:1
Long version:
I have a model where I deal with points of a multidimensional space with a known and fixed dimension, and I use SVector{Dim, Float64}
to represent a point. I also deal with elements of (Cartesian) product spaces of N
of these spaces, again with known and fixed N
, and I represent these elements as SVector{N, SVector{Dim, Float64}}
. Of course I could have represented these elements as SMatrix
but conceptually it is more suitable to represent them as vectors (of vectors).
Now, I can define SVectors of SVectors as long as the collection consists of at least two SVectors, i.e. N >= 2. But I need to work on subspaces of the product space, which means that sometimes I need to create collections of lower sizes, which can be N=1. The problem is that if the original spaces are unidimensional, i.e. Dim=1, and the subset consists of a single space, i.e. N=1, I get the above error.
If indeed it is not allowed to create SVector{1, SVector{1, Float64}
objects, I can check this condition in compile-time and treat these objects as of type <: Real
, but then either:
- I have to add methods everywhere to work with
Real
s, - or perhaps define a Union type and let compiler to generate specialized methods, since the operations are purely arithmetic/algebraic.
Thank you!