# Create a vector of SVectors from a Matrix

**URL:** <https://discourse.julialang.org/t/create-a-vector-of-svectors-from-a-matrix/14324>\
**Category:** General Usage\
**Tags:** package\
**Created:** [August 30, 2018, 4:45pm UTC](https://discourse.julialang.org/t/create-a-vector-of-svectors-from-a-matrix/14324 "2018-08-30T16:45:41Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![dmbates](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmbates/32/44_2.png) [@dmbates](https://discourse.julialang.org/u/dmbates)\
**Post date:** [August 30, 2018, 4:45pm UTC](https://discourse.julialang.org/t/create-a-vector-of-svectors-from-a-matrix/14324/1 "2018-08-30T16:45:41Z")

</div>

In the [`MixedModels` package](https://github.com/dmbates/MixedModels.jl.git) one of the structs contains a short, wide matrix for which the primary usage is column-wise. (The struct is `VectorFactorReTerm` defined in `src/modelterms.jl` for those who want to play along at home.) To speed up such accesses I create a `Vector` of `Svector`s from the columns using

```julia
reinterpret(SVector{k,T}, vec(z))

```

where `z` is a `Matrix{T}` of size `k` by `n`. This is slightly modified from the suggested form in the documentation for [`StaticArrays`](https://github.com/JuliaArrays/StaticArrays.jl.git) under “Arrays of static arrays”.

Julia v0.6 was okay with this and I could define the field in the struct as `Vector{SVector{k,T}}`.

In Julia v0.7 I get an error about the type of the field

```julia
UBlk: Error During Test at /home/bates/.julia/dev/MixedModels/test/UniformBlockDiagonal.jl:7
  Got exception MethodError(VectorFactorReTerm, (UInt32[0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000003, 0x00000003, 0x00000003, 0x00000003], ["1", "2", "3"], [1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0; -1.0 1.0 -1.0 1.0 -1.0 1.0 -1.0 1.0 -1.0 1.0 -1.0 1.0], [1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0; -1.0 1.0 -1.0 1.0 -1.0 1.0 -1.0 1.0 -1.0 1.0 -1.0 1.0], StaticArrays.SArray{Tuple{2},Float64,1,2}[[1.0, -1.0], [1.0, 1.0], [1.0, -1.0], [1.0, 1.0], [1.0, -1.0], [1.0, 1.0], [1.0, -1.0], [1.0, 1.0], [1.0, -1.0], [1.0, 1.0], [1.0, -1.0], [1.0, 1.0]], :G, ["(Intercept)", "U"], [2], [1.0 0.0; 0.0 1.0], [1, 2, 4]), 0x0000000000006c74) outside of a @test
  MethodError: no method matching VectorFactorReTerm(::Array{UInt32,1}, ::Array{String,1}, ::Array{Float64,2}, ::Array{Float64,2}, ::Base.ReinterpretArray{StaticArrays.SArray{Tuple{2},Float64,1,2},1,Float64,Array{Float64,1}}, ::Symbol, ::Array{String,1}, ::Array{Int64,1}, ::LowerTriangular{Float64,Array{Float64,2}}, ::Array{Int64,1})
  Closest candidates are:
    VectorFactorReTerm(::Array{R,1}, ::Array{String,1}, ::Array{T,2}, ::Array{T,2}, !Matched::Array{StaticArrays.SArray{Tuple{S},T,1,S},1}, ::Symbol, ::Array{String,1}, ::Array{Int64,1}, ::LowerTriangular{T,Array{T,2}}, ::Array{Int64,1}) where {T, R, S} at /home/bates/.julia/dev/MixedModels/src/modelterms.jl:159
    VectorFactorReTerm(!Matched::CategoricalArray{T,1,V,C,U,U1} where U1 where U where C where V where T, !Matched::Array{T,2}, ::Any, ::Any, ::Any) where T at /home/bates/.julia/dev/MixedModels/src/modelterms.jl:171

```

apparently because the `reinterpret` is lazy.

So my question is how to instantiate the actual type after the lazy reinterpret. I appreciate that much of the linear algebra manipulations have become lazy and I certainly appreciate that change but I am not yet sure how to say, “I really mean it now - give me one of these instead of a delayed expression formulation.”

---

<div class="post-metadata">

**Author:** ![Seif\_Shebl](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Seif\_Shebl](https://discourse.julialang.org/u/Seif_Shebl)\
**Post date:** [August 30, 2018, 5:00pm UTC](https://discourse.julialang.org/t/create-a-vector-of-svectors-from-a-matrix/14324/2 "2018-08-30T17:00:42Z")

</div>

> [@dmbates](#):
>
> reinterpret(SVector{k,T}, vec(z))

Have you tried `copy( reinterpret(SVector{k,T}, vec(z)) )`? This should calculate it immediately!

---

<div class="post-metadata">

**Author:** ![dmbates](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmbates/32/44_2.png) [@dmbates](https://discourse.julialang.org/u/dmbates)\
**Post date:** [August 30, 2018, 5:31pm UTC](https://discourse.julialang.org/t/create-a-vector-of-svectors-from-a-matrix/14324/3 "2018-08-30T17:31:09Z")

</div>

@Seif_Shebl Thanks for the suggestion. I don’t think I want to copy it because I want the same memory locations to be accessible from the original matrix, `z`, and from the vector of `SVector`s. Some of the time I treat the structure as a matrix and some of the time I want to treat it as a collection of vectors.

Like most uses of StaticArrays the motivation is that I want some sections of the code to be very fast.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [August 30, 2018, 5:44pm UTC](https://discourse.julialang.org/t/create-a-vector-of-svectors-from-a-matrix/14324/4 "2018-08-30T17:44:41Z")

</div>

Is it feasible to just make your struct parametric?

On Julia 1.1-dev:

```julia
julia> x = randn(8,12);

julia> using StaticArrays
[Info: Precompiling StaticArrays [90137ffa-7385-5640-81b9-e52037218182]

julia> xsv = reinterpret(SVector{8,Float64}, x)
1×12 reinterpret(SArray{Tuple{8},Float64,1,8}, ::Array{Float64,2}):
 [-0.35087, 0.301005, -0.411572, -1.54172, -2.97874, 1.75922, -0.0696284, 0.196542] … [-0.42543, -0.951566, 0.273947, 0.653601, -0.954813, 1.81766, -0.671167, -0.00442]

julia> using BenchmarkTools

julia> xsv1 = xsv[1];

julia> @benchmark $xsv[1]
BenchmarkTools.Trial: 
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 4.077 ns (0.00% GC)
  median time: 4.098 ns (0.00% GC)
  mean time: 4.216 ns (0.00% GC)
  maximum time: 15.910 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1000

julia> @benchmark copy($xsv1)
BenchmarkTools.Trial: 
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 2.164 ns (0.00% GC)
  median time: 2.174 ns (0.00% GC)
  mean time: 2.212 ns (0.00% GC)
  maximum time: 7.805 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1000

```

Alternatively, if you’re not willing to pay a performance penalty, and can protect the original matrix:

```julia
julia> ptr_x = pointer(x);

julia> function getindex_ptr(ptr, ::Type{T}, i) where T
           unsafe_load(Base.unsafe_convert(Ptr{T}, ptr), i)
       end
getindex_ptr (generic function with 1 method)

julia> @benchmark getindex_ptr($ptr_x, SVector{8,Float64}, 1)
BenchmarkTools.Trial: 
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 2.404 ns (0.00% GC)
  median time: 2.414 ns (0.00% GC)
  mean time: 2.467 ns (0.00% GC)
  maximum time: 12.073 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1000

julia> @benchmark getindex_ptr($ptr_x, SVector{8,Float64}, 2)
BenchmarkTools.Trial: 
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 2.164 ns (0.00% GC)
  median time: 2.184 ns (0.00% GC)
  mean time: 2.229 ns (0.00% GC)
  maximum time: 19.747 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1000

```

---

<div class="post-metadata">

**Author:** ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)\
**Post date:** [August 30, 2018, 5:57pm UTC](https://discourse.julialang.org/t/create-a-vector-of-svectors-from-a-matrix/14324/5 "2018-08-30T17:57:39Z")

</div>

You can also consider @Keno’s “trick” of widening the definition of `VectorFactorReTerm` to accept a `reinterpret`ed matrix. Then your `Vector{SVector{k,T}}` is concrete and fast and you work with the lazy reinterpreted matrix in `MixedModels`.

---

<div class="post-metadata">

**Author:** ![dmbates](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmbates/32/44_2.png) [@dmbates](https://discourse.julialang.org/u/dmbates)\
**Post date:** [August 30, 2018, 8:29pm UTC](https://discourse.julialang.org/t/create-a-vector-of-svectors-from-a-matrix/14324/6 "2018-08-30T20:29:28Z")

</div>

Eventually I worked out that what I wanted was `collect`.

---

<div class="post-metadata">

**Author:** ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)\
**Post date:** [August 30, 2018, 8:45pm UTC](https://discourse.julialang.org/t/create-a-vector-of-svectors-from-a-matrix/14324/7 "2018-08-30T20:45:22Z")

</div>

But `collect` does the same here as `copy`?

---

<div class="post-metadata">

**Author:** ![simonbyrne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simonbyrne/32/19_2.png) [@simonbyrne](https://discourse.julialang.org/u/simonbyrne)\
**Post date:** [August 30, 2018, 9:02pm UTC](https://discourse.julialang.org/t/create-a-vector-of-svectors-from-a-matrix/14324/8 "2018-08-30T21:02:28Z")

</div>

Yes, `collect` will copy in this case as well. The only way to share memory would be to make the struct parametric.
