# Help defining a custom SVector

**URL:** <https://discourse.julialang.org/t/help-defining-a-custom-svector/85424>\
**Category:** General Usage\
**Tags:** question, arrays, staticarrays\
**Created:** [August 7, 2022, 2:38am UTC](https://discourse.julialang.org/t/help-defining-a-custom-svector/85424 "2022-08-07T02:38:40Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [August 7, 2022, 2:38am UTC](https://discourse.julialang.org/t/help-defining-a-custom-svector/85424/1 "2022-08-07T02:38:41Z")

</div>

The StaticArrays.jl documentation mentions the `FieldVector` abstract type that developers can use to inherit all the nice behavior of `SVector`:

```julia
using StaticArrays

struct Vec{T} <: FieldVector{3,T}
  x::T
  y::T
  z::T
end

```

Now, any instance `v = Vec{T}` will have `getindex` and `setindex!` properly defined as well as all the fast basic math operations with vectors and matrices. The docstring of `FieldVector` also mentions that it is nice to implement

```julia
StaticArrays.similar_type(::Type{<:Vec3}, ::Type{T}, s::Size{(3,)}) where {T} = Vec3{T}

```

to get the correct return type in array expressions. Is this still updated information? It seems that just the subtyping in the struct definition already handles everything?

My main question is actually the following: how to define a type `Vec{Dim,T}` that has length fixed at compile time but free as a variable in the code? I am looking into something like:

```julia
struct Vec{Dim,T} <: FieldVector{Dim,T}
  ... # what goes here?
end

```

To give some context, I am trying to write an exact replacement for `SVector`. In particular, it is possible to type `SVector(1,2,3)` and let the constructor figure out the length `3` and the type `Int`, or explicitly ask for `SVector{3,Float64}(1,2,3)` to convert to double precision.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 7, 2022, 2:52am UTC](https://discourse.julialang.org/t/help-defining-a-custom-svector/85424/2 "2022-08-07T02:52:49Z")

</div>

> [@juliohm](#):
>
> ```julia
> 
> ```

```julia
struct Vec{Dim,T} <: FieldVector{Dim,T}
   xs::Tuple{Dim, T}
end

Base.length(v::Vec{Dim, T}) where {Dim, T} = Dim

```

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [August 7, 2022, 10:27am UTC](https://discourse.julialang.org/t/help-defining-a-custom-svector/85424/3 "2022-08-07T10:27:48Z")

</div>

> [@jling](#):
>
> `Base.length(v::Vec{Dim, T}) where {Dim, T} = Dim`

Thank you @jling, can you provide a full example of usage? I tried instantiating the vector and it didn’t work saying that it has no static size.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [August 8, 2022, 5:13pm UTC](https://discourse.julialang.org/t/help-defining-a-custom-svector/85424/4 "2022-08-08T17:13:14Z")

</div>

> [@juliohm](#):
>
> My main question is actually the following: how to define a type `Vec{Dim,T}` that has length fixed at compile time but free as a variable in the code? I am looking into something like:
> 
> ```julia
> struct Vec{Dim,T} <: FieldVector{Dim,T}
> ... # what goes here?
> end
> 
> ```
> 
> To give some context, I am trying to write an exact replacement for `SVector`. In particular, it is possible to type `SVector(1,2,3)` and let the constructor figure out the length `3` and the type `Int`, or explicitly ask for `SVector{3,Float64}(1,2,3)` to convert to double precision.

What you’re looking for here is not a `FieldVector`, since the number of fields you want depends on the type parameter.

This will require a bit more work than using `FieldVector` but is probably a better idea anyways. I’d do something like:

```julia
using StaticArrays

struct Vec{L, T} <: StaticVector{L, T}
    v::SVector{L, T}
    Vec{L, T}(v::SVector{L, T}) where {L, T} = new{L, T}(v)
end

Base.getindex(v::Vec, i::Int) = getindex(v.v, i)
Base.size(v::Vec, i) = size(v, i)

Vec(args...) = Vec(SVector(args...))
Vec(sv::SVector{L, T}) where {L, T} = Vec{L,T}(sv)

```

and then just define whatever extra methods you end up needing.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [August 8, 2022, 9:45pm UTC](https://discourse.julialang.org/t/help-defining-a-custom-svector/85424/5 "2022-08-08T21:45:26Z")

</div>

Thank you @Mason, I will try to copy/paste many FieldVector definitions and wrap everything into a single generic Vec. Maybe that works?

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [August 8, 2022, 11:06pm UTC](https://discourse.julialang.org/t/help-defining-a-custom-svector/85424/6 "2022-08-08T23:06:24Z")

</div>

Isn’t what you want just the `SVector{N,T}` ? As I understand `FieldVector` allows the access of elements by name, but if you have a variable number of fields that does not make immediate sense.

(from the last part of your question, you want an exact reimplementation of `SVectors`, but with a different type signature, for some particular dispatch?

there has been a recent question about using something like `const Vec = SVector`, which does not work because it only defines an alias, and from what I remember there was no easy solution rather than re-implementing everyting again).

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [August 8, 2022, 11:30pm UTC](https://discourse.julialang.org/t/help-defining-a-custom-svector/85424/7 "2022-08-08T23:30:23Z")

</div>

Yes, I want everything that SVector provides but with a type that I own for two reasons:

1. I would be able to write outer constructors that always convert Integer coordinates to AbstractFloat.
2. This type would be isolated from other ecosystems and therefore even if someone starts adding methods for SVector out there in the wild, that would not interfere with the compilation of packages.

This is the GitHub issue behind this discussion:

> <https://github.com/JuliaGeometry/Meshes.jl/issues/207>
>
> Currently our \`Vec\` type is an alias to \`SVector\` and that helped us get off the… ground and move fast with implementations. The only problem with \`SVector\` is that it doesn't force \`AbstractFloat\` coordinates. When the user types \`Vec(1,2)\` this will generate a vector with integer coordinates and many algorithms will break assuming that the vectors live in R^n.
> 
> We need a new definition for \`Vec\` that is simply a new type of \`StaticVector\` from StaticArrays.jl. They provide an interface and parent types to inherit most of the behavior of \`SVector\`. We just need to do that and add an inner constructor like we did for \`Point\` to force \`AbstractFloat\` coordinates.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [August 8, 2022, 11:43pm UTC](https://discourse.julialang.org/t/help-defining-a-custom-svector/85424/8 "2022-08-08T23:43:06Z")

</div>

> [@juliohm](#):
>
> Thank you @Mason, I will try to copy/paste many FieldVector definitions and wrap everything into a single generic Vec. Maybe that works?

No, you shouldn’t use `FieldVector` for this. You should just make a type that wraps an `SVector`, since you aren’t actually accessing by field.
