# How to create an SVector of SVectors part II

**URL:** <https://discourse.julialang.org/t/how-to-create-an-svector-of-svectors-part-ii/61109>\
**Category:** General Usage\
**Tags:** question, staticarrays\
**Created:** [May 13, 2021, 9:13pm UTC](https://discourse.julialang.org/t/how-to-create-an-svector-of-svectors-part-ii/61109 "2021-05-13T21:13:32Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 13, 2021, 9:13pm UTC](https://discourse.julialang.org/t/how-to-create-an-svector-of-svectors-part-ii/61109/1 "2021-05-13T21:13:32Z")

</div>

I have the following code:

```julia
using BenchmarkTools, StaticArrays

if ! @isdefined SEGMENTS
    const SEGMENTS = 6
end

# Type definitions
const SimFloat = Float64
const Vec3 = MVector{3, SimFloat}

function create_state()
    pos = zeros(SVector{SEGMENTS+1, Vec3})
    pos[1] .= [1.0,2,3]
    vel = zeros(SVector{SEGMENTS+1, Vec3})
    y = reduce(vcat, vcat(pos, vel))
end

function unpack(y)
    part = reshape(y, Size(3, SEGMENTS+1, 2))
    pos1 = part[:,:,1]
    pos2 = [SVector(pos1[:,i]) for i in 1:SEGMENTS+1]
end

state = create_state()
display(unpack(state))

display(@benchmark unpack(y) setup = (y = create_state()))

```

It has the following output:

```julia
julia> include("src/test.jl")
7-element Vector{SVector{3, Float64}}:
 [1.0, 2.0, 3.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
BenchmarkTools.Trial: 
  memory estimate: 432 bytes
  allocs estimate: 2
  --------------
  minimum time: 52.806 ns (0.00% GC)
  median time: 55.680 ns (0.00% GC)
  mean time: 59.781 ns (4.43% GC)
  maximum time: 541.337 ns (77.31% GC)
  --------------
  samples: 10000
  evals/sample: 985

```

There are two things I want to improve:

1. the function unpack should return an SVector of SVectors. How can I achieve that?
2. the function unpack shall NOT allocate

Any ideas?

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [May 13, 2021, 9:23pm UTC](https://discourse.julialang.org/t/how-to-create-an-svector-of-svectors-part-ii/61109/2 "2021-05-13T21:23:13Z")

</div>

I am using HybridArrays.jl for similar tasks and it works really well. Maybe that package is interesting for you.

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [May 13, 2021, 10:03pm UTC](https://discourse.julialang.org/t/how-to-create-an-svector-of-svectors-part-ii/61109/3 "2021-05-13T22:03:44Z")

</div>

> [@ufechner7](#):
>
> the function unpack should return an SVector of SVectors. How can I achieve that?

`pos2 = SVector{SEGMENTS+1}(SVector(pos1[:,i]) for i in 1:SEGMENTS+1)`

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 13, 2021, 10:32pm UTC](https://discourse.julialang.org/t/how-to-create-an-svector-of-svectors-part-ii/61109/4 "2021-05-13T22:32:42Z")

</div>

This is already nice. It reduces the allocations to one:

```julia
julia> @time include("src/test.jl")
7-element SVector{7, SVector{3, Float64}} with indices SOneTo(7):
 [1.0, 2.0, 3.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
BenchmarkTools.Trial: 
  memory estimate: 176 bytes
  allocs estimate: 1
  --------------
  minimum time: 34.508 ns (0.00% GC)
  median time: 37.620 ns (0.00% GC)
  mean time: 39.708 ns (2.43% GC)
  maximum time: 427.749 ns (83.17% GC)
  --------------
  samples: 10000
  evals/sample: 993
  5.087095 seconds (20.65 M allocations: 2.269 GiB, 27.65% gc time)

```

Remaining question: How to eliminate the last allocation?

---

<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:** [May 13, 2021, 11:18pm UTC](https://discourse.julialang.org/t/how-to-create-an-svector-of-svectors-part-ii/61109/5 "2021-05-13T23:18:47Z")

</div>

> [@ufechner7](#):
>
> `pos1 = part[:,:,1]`

Maybe

```julia
pos1 = @view part[:,:,1]

```

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 13, 2021, 11:33pm UTC](https://discourse.julialang.org/t/how-to-create-an-svector-of-svectors-part-ii/61109/6 "2021-05-13T23:33:52Z")

</div>

That increases the number of allocations from one to eight. I think views do not work with SVectors.

---

<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:** [May 13, 2021, 11:46pm UTC](https://discourse.julialang.org/t/how-to-create-an-svector-of-svectors-part-ii/61109/7 "2021-05-13T23:46:13Z")

</div>

> [@ufechner7](#):
>
> `unpack(state)`

Change MVector to SVector and use:

```julia
using Setfield
function create_state()
           pos = zeros(SVector{SEGMENTS+1, Vec3})
           @set! pos[1] = @SVector [1.0,2,3]
           vel = zeros(SVector{SEGMENTS+1, Vec3})
           y = reduce(vcat, vcat(pos, vel))
       end

julia> function unpack(y)
           part = reshape(y, Size(3, SEGMENTS+1, 2))
           pos1 = part[:,:,1]
           pos2 = @SVector [SVector(pos1[:,i]) for i in 1:SEGMENTS+1]
       end
unpack (generic function with 1 method)

julia> @btime unpack(y) setup = (y = create_state())
  4.640 ns (0 allocations: 0 bytes)
7-element SVector{7, SVector{3, Float64}} with indices SOneTo(7):
 [1.0, 2.0, 3.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]

```

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 14, 2021, 12:15am UTC](https://discourse.julialang.org/t/how-to-create-an-svector-of-svectors-part-ii/61109/8 "2021-05-14T00:15:12Z")

</div>

I cannot change the type of the input parameter of the unpack function, because this is a callback function from an ODE solver.

But you inspired me to find the following solution:’

```julia
function unpack(y)
    part = reshape(SVector{6*(SEGMENTS+1)}(y), Size(3, SEGMENTS+1, 2))
    pos1 = part[:,:,1]
    SVector{SEGMENTS+1}(SVector(pos1[:,i]) for i in 1:SEGMENTS+1)
end

```

Output:

```julia
julia> include("src/test.jl")
7-element SVector{7, SVector{3, Float64}} with indices SOneTo(7):
 [1.0, 2.0, 3.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
 [0.0, 0.0, 0.0]
BenchmarkTools.Trial: 
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 6.581 ns (0.00% GC)
  median time: 6.699 ns (0.00% GC)
  mean time: 7.011 ns (0.00% GC)
  maximum time: 38.815 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1000

```
