Static Vectors with Named Fields?

Say for example that I would like to represent a three dimensional point and I would like it to be easy to look up the values with the names x, y, z.

I could use a named tuple like,

t = (x=0.0, y=0.0, z=0.0)

This all works great util I would like to do some linear algebra. For example,

t = (x=1.0, y=2.0, z=3.0)
m = diagm(ones(3))
m*t

Any easy work around would be something like,

m*[t...]

but I presume this would reallocate new memory for the temporary vector [t...], when it is not really required? Is there a better way? Maybe a static array with some named fields provides an alternate option?

Looking for suggestions on the best way to approach something like this. I generally prefer solutions that only require Julia standard libraries.

1 Like

See FieldVector in the StaticArrays.jl docs, which seems to be exactly what you want.

julia> using StaticArrays, LinearAlgebra

julia> struct Point3D{T<:Number} <: FieldVector{3, T}
           x::T
           y::T
           z::T
       end

julia> t = Point3D(1.0,2.0,3.0)
3-element Point3D{Float64} with indices SOneTo(3):
 1.0
 2.0
 3.0

julia> M = diagm(@SVector [4,5,6])
3×3 SMatrix{3, 3, Int64, 9} with indices SOneTo(3)×SOneTo(3):
 4  0  0
 0  5  0
 0  0  6

julia> M * t
3-element Point3D{Float64} with indices SOneTo(3):
  4.0
 10.0
 18.0
3 Likes

StaticArrays.jl added access via .x etc recently, this PR, so:

julia> t = (x=0.1, y=2.0, z=3.3);

julia> using StaticArrays

julia> v = SA[t...]
3-element SVector{3, Float64} with indices SOneTo(3):
 0.1
 2.0
 3.3

julia> v.x
0.1
6 Likes

https://github.com/SciML/LabelledArrays.jl

FieldVector has the unfortunate drawback that because it requires a strict you can only define them in global scope. StaticArrays has built in .x .y and .z but it’s not customizable. LabelledArrays is a StaticArray with zero overhead static naming that just converts the names to indices at compile time, and the index list is type parameter information so they can be defined anywhere.

6 Likes

Thanks all for the suggestions. I will try these out and see how they go!