# Struct containing differently-sized Static Vectors

**URL:** <https://discourse.julialang.org/t/struct-containing-differently-sized-static-vectors/112231>\
**Category:** General Usage\
**Created:** [March 28, 2024, 1:19pm UTC](https://discourse.julialang.org/t/struct-containing-differently-sized-static-vectors/112231 "2024-03-28T13:19:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![leapsheep](https://avatars.discourse-cdn.com/v4/letter/l/ccd318/32.png) [@leapsheep](https://discourse.julialang.org/u/leapsheep)\
**Post date:** [March 28, 2024, 1:19pm UTC](https://discourse.julialang.org/t/struct-containing-differently-sized-static-vectors/112231/1 "2024-03-28T13:19:26Z")

</div>

I want to define a struct for a cluster of particles that each have a position and orientation in space. I would like my representation to work for both 2D and 3D, which is a bit tricky since in 2D I represent orientation as an angle with a `SVector{1}` and in 3D I need a quaternion, which is a `SVector{4}`. I would like to have a struct that only contains the dimensionality of space D as a type parameter, but not the number of orientation variables. That is, I would like to have is something that behaves like this:

```julia
struct Cluster{D,F<:Real}
    xs::Vector{SVector{D,F}}
    thetas::Vector{SVector{D == 2 ? 1 : 4,F}}
end

```

which obviously doesnt work since you cannot do arithmetic with typevars.

What would be a solution that gives me the closest behavior to this?

I specifically want to avoid having multiple type parameters, as in

```julia
struct Cluster{D,R,F<:Real}
    xs::Vector{SVector{D,F}}
    thetas::Vector{SVector{R,F}}
end

```

I only way I can think of would be to define an `AbstractCluster` and then a `Cluster2D <: AbstractCluster` and `Cluster3D <: AbstractCluster`, but that doesn’t seem super elegant to me.

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [March 28, 2024, 1:42pm UTC](https://discourse.julialang.org/t/struct-containing-differently-sized-static-vectors/112231/2 "2024-03-28T13:42:44Z")

</div>

> [@leapsheep](#):
>
> I specifically want to avoid having multiple type parameters

Why is this? Typevars are the main way, we can communicate constraints to the compiler. You could set the additional typevar within an inner constructor and you’d never really have to worry about.

> [@leapsheep](#):
>
> I only way I can think of would be to define an `AbstractCluster` and then a `Cluster2D <: AbstractCluster` and `Cluster3D <: AbstractCluster`, but that doesn’t seem super elegant to me.

And it is basically equivalent to having the extra typevar. The typevar would save you the typing. If you want to have structurally differences than you need multiple concrete types.

So if you really require a single concrete type to do both then I’d suggest either making two fields and using the correct one based on the type or making the field an `SVector{4}` where all values except the first one are 0 if `D==2`-

---

<div class="post-metadata">

**Author:** ![leapsheep](https://avatars.discourse-cdn.com/v4/letter/l/ccd318/32.png) [@leapsheep](https://discourse.julialang.org/u/leapsheep)\
**Post date:** [March 28, 2024, 1:54pm UTC](https://discourse.julialang.org/t/struct-containing-differently-sized-static-vectors/112231/3 "2024-03-28T13:54:57Z")

</div>

Thanks for the quick reply. Maybe there is just a simple thing I am missing: Is there a way to dispatch without writing out all the typevars all the time?

For example, say my full type signature is `Cluster{D,R,T<:Integer, F<:AbstractFloat}`, where `D` and `R` are the dimension of my static vectors.  
I will never dispatch on `R`, so is there a way of not having to write out the full type signature like below?

```julia
f(c::Cluster{D,R,T,F}) where {D,R,T,F} = ...

```

If there is, then just setting `R` with an inner constructor would be ideal. I just want to avoid having to sprinkle `R`s everywhere, basically.

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [March 28, 2024, 2:03pm UTC](https://discourse.julialang.org/t/struct-containing-differently-sized-static-vectors/112231/4 "2024-03-28T14:03:39Z")

</div>

You can partially provide typevars 🙂 E.g. `Array{Int}` really means `Array{Int, N} where N`.

So put the typevars you want to dispatch on to the left and all the other stuff further to the right 🙂

Edit: Of course you can also always use aliases like

```julia
Matrix{T} = Array{T,2} where T

```

and then dispatch on that.

---

<div class="post-metadata">

**Author:** ![leapsheep](https://avatars.discourse-cdn.com/v4/letter/l/ccd318/32.png) [@leapsheep](https://discourse.julialang.org/u/leapsheep)\
**Post date:** [March 28, 2024, 2:13pm UTC](https://discourse.julialang.org/t/struct-containing-differently-sized-static-vectors/112231/5 "2024-03-28T14:13:18Z")

</div>

That’s awesome (and I should have thought of that). Thanks a lot! 🙂
