# StaticArrays:construct a SMatrix from three vectors

**URL:** <https://discourse.julialang.org/t/staticarrays-construct-a-smatrix-from-three-vectors/6509>\
**Category:** General Usage\
**Tags:** question\
**Created:** [October 17, 2017, 3:33pm UTC](https://discourse.julialang.org/t/staticarrays-construct-a-smatrix-from-three-vectors/6509 "2017-10-17T15:33:33Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![phlavenk](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phlavenk/32/1873_2.png) [@phlavenk](https://discourse.julialang.org/u/phlavenk)\
**Post date:** [October 17, 2017, 3:33pm UTC](https://discourse.julialang.org/t/staticarrays-construct-a-smatrix-from-three-vectors/6509/1 "2017-10-17T15:33:33Z")

</div>

I’m using SMatrix from StaticArrays.jl for calculation of coordinate system transformation. In the hotspot, I’m running following (simplified) code:

```julia
using StaticArrays, BenchmarkTools
a = rand(3)
b = rand(3)
c = rand(3)
d = rand(3)
m = hcat((a-d),(b-d),(c-d))
sm = SMatrix{3,3}(hcat((a-d),(b-d),(c-d))...)
m==sm

f1(a,b,c,d) = SMatrix{3,3}(hcat((a-d),(b-d),(c-d))...)
f2(a,b,c,d) = SMatrix{3,3}((a-d)...,(b-d)...,(c-d)...)

@inline function smatrix33(a,b,c)
    @inbounds A = SMatrix{3,3}(a[1], a[2], a[3], b[1], b[2], b[3], c[1], c[2], c[3])
    A
end
f3(a,b,c,d) = smatrix33((a-d),(b-d),(c-d))

```

The result medians are for f1, f2 and f3 1.2 us, 780 ns and 174 ns.

Is there a better way to fill an SMatrix by column / row vectors, or is it necessary to write a helper function to get the full speed?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [October 17, 2017, 5:10pm UTC](https://discourse.julialang.org/t/staticarrays-construct-a-smatrix-from-three-vectors/6509/2 "2017-10-17T17:10:28Z")

</div>

```julia
julia> A = @SMatrix rand(3, 4)
3×4 StaticArrays.SArray{Tuple{3,4},Float64,2,12}:
 0.644328 0.225848 0.36689 0.243095
 0.590968 0.462177 0.206045 0.404283
 0.973567 0.342697 0.65298 0.901137

julia> f4(A) = A[:, SVector(1, 2, 3)] .- A[:, 4]

julia> @btime f4($A)
  10.637 ns (0 allocations: 0 bytes)
3×3 StaticArrays.SArray{Tuple{3,3},Float64,2,9}:
 0.401233 -0.0172464 0.123795
 0.186685 0.057894 -0.198239
 0.0724302 -0.55844 -0.248157

```

---

<div class="post-metadata">

**Author:** ![phlavenk](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phlavenk/32/1873_2.png) [@phlavenk](https://discourse.julialang.org/u/phlavenk)\
**Post date:** [October 17, 2017, 5:54pm UTC](https://discourse.julialang.org/t/staticarrays-construct-a-smatrix-from-three-vectors/6509/3 "2017-10-17T17:54:09Z")

</div>

I know the arithmetic operations between static arrays are amazingly fast. My concern is, how to effectively construct such a SMatrix out of plain vectors (arrays).

Actually if a,b,c,d are `SVector` already, then just using `hcat` seems the fastest approach. Got 100 ns for

```julia
a = @SVector rand(3)
b = @SVector rand(3)
c = @SVector rand(3)
d = @SVector rand(3)
f5(a,b,c,d) = hcat((a-d),(b-d),(c-d))

```

correctly returning a 3x3 SArray.

I didn’t know there is an optimized method for `hcat`ting `SVectors` but apparently there is. I really do appreciate Matt Bauman’s work on this package.

But with plain arrays, splatting is too slow and the explicit approach of smatrix33 is the winner so far.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [October 17, 2017, 7:07pm UTC](https://discourse.julialang.org/t/staticarrays-construct-a-smatrix-from-three-vectors/6509/4 "2017-10-17T19:07:12Z")

</div>

```julia
a = rand(3)
b = rand(3)
c = rand(3)
d = rand(3)

function f6(a, b, c, d)
    as = SVector{3}(a)
    bs = SVector{3}(b)
    cs = SVector{3}(c)
    ds = SVector{3}(d)
    return hcat(as-ds, bs-ds, cs-ds)
end

julia> @btime f6($a, $b, $c, $d)
  17.349 ns (0 allocations: 0 bytes)
3×3 StaticArrays.SArray{Tuple{3,3},Float64,2,9}:
 -0.543394 -0.545152 -0.275096 
  0.0925233 0.778087 -0.0803328
 -0.065766 0.832741 0.527109 

```

---

<div class="post-metadata">

**Author:** ![phlavenk](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phlavenk/32/1873_2.png) [@phlavenk](https://discourse.julialang.org/u/phlavenk)\
**Post date:** [October 18, 2017, 3:41pm UTC](https://discourse.julialang.org/t/staticarrays-construct-a-smatrix-from-three-vectors/6509/5 "2017-10-18T15:41:22Z")

</div>

Yes, this is the fastest and easiest way to accomplish this.

Thank you, @DNF, I’ve marked the correct answer. Its 30ns in my case, but that’s on a laptop…

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [October 18, 2017, 6:20pm UTC](https://discourse.julialang.org/t/staticarrays-construct-a-smatrix-from-three-vectors/6509/6 "2017-10-18T18:20:06Z")

</div>

My result is on a laptop too, four years old. Perhaps I’m getting SIMD vectorization, or something. Have you tried starting julia with the O3 option like this?

`$ julia -03`

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [October 18, 2017, 6:22pm UTC](https://discourse.julialang.org/t/staticarrays-construct-a-smatrix-from-three-vectors/6509/7 "2017-10-18T18:22:19Z")

</div>

Oh, and did you time it exactly like this:

```julia
julia> using BenchmarkTools
julia> @btime f6($a, $b, $c, $d)

```

?  
If I remove the `$` signs I get ~40ns.

---

<div class="post-metadata">

**Author:** ![phlavenk](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phlavenk/32/1873_2.png) [@phlavenk](https://discourse.julialang.org/u/phlavenk)\
**Post date:** [October 19, 2017, 7:39am UTC](https://discourse.julialang.org/t/staticarrays-construct-a-smatrix-from-three-vectors/6509/8 "2017-10-19T07:39:04Z")

</div>

Thank you for pointing me to the `$` use - I usually don’t forget it to use this for more expensive arguments, but here I forgot. Now with `-O3` and `$` I’m at 13 ns… on an i5-6300U 2.4GHz.

Still I doubt if SIMD was used. Do you know what to look for in the @code\_llvm or @code\_native output? Even for such an easy function as f6, I get lost in the output… Is there a specific instruction indicating a SIMD parallel subtract or parallel move?

Just by chance, do you know how to pass the -O3 option to Julia running as Jupyter backend?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [October 19, 2017, 8:07am UTC](https://discourse.julialang.org/t/staticarrays-construct-a-smatrix-from-three-vectors/6509/9 "2017-10-19T08:07:32Z")

</div>

> [@phlavenk](#):
>
> Do you know what to look for in the @code\_llvm or @code\_native output?

You can look for e.g. `fadd <4 x double> %6, %10`, basically anything that involves a `<q x type>` where `q` is usually 2, or 4, and `type` is the LLVM type.

> [@phlavenk](#):
>
> Just by chance, do you know how to pass the -O3 option to Julia running as Jupyter backend?

> **[GitHub - JuliaLang/IJulia.jl: Julia kernel for Jupyter](https://github.com/JuliaLang/IJulia.jl#installing-additional-julia-kernels)**
>
> Julia kernel for Jupyter. Contribute to JuliaLang/IJulia.jl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![phlavenk](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phlavenk/32/1873_2.png) [@phlavenk](https://discourse.julialang.org/u/phlavenk)\
**Post date:** [October 19, 2017, 11:42am UTC](https://discourse.julialang.org/t/staticarrays-construct-a-smatrix-from-three-vectors/6509/10 "2017-10-19T11:42:25Z")

</div>

Thank you, big help.  
Petr
