# Replacing normal arrays with static arrays

**URL:** <https://discourse.julialang.org/t/replacing-normal-arrays-with-static-arrays/28230>\
**Category:** New to Julia\
**Tags:** linearalgebra\
**Created:** [August 31, 2019, 6:07am UTC](https://discourse.julialang.org/t/replacing-normal-arrays-with-static-arrays/28230 "2019-08-31T06:07:21Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![baptiste](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baptiste/32/9813_2.png) [@baptiste](https://discourse.julialang.org/u/baptiste)\
**Post date:** [August 31, 2019, 6:07am UTC](https://discourse.julialang.org/t/replacing-normal-arrays-with-static-arrays/28230/1 "2019-08-31T06:07:21Z")

</div>

I’m trying to perform a 3D rotation on a diagonal matrix, which seems to work with the code below.

```julia
using LinearAlgebra
using StaticArrays

function euler(φ, θ, ψ)

    R = Array{Float64}(undef,(3,3))
    cosφ = cos(φ); cosψ = cos(ψ); cosθ = cos(θ)
    sinφ = sin(φ); sinψ = sin(ψ); sinθ = sin(θ)

    R[1,1] = cosφ*cosθ*cosψ - sinφ*sinψ
    R[1,2] = sinφ*cosθ*cosψ + cosφ*sinψ
    R[1,3] = -sinθ*cosψ

    R[2,1] = -cosφ*cosθ*sinψ - sinφ*cosψ
    R[2,2] = -sinφ*cosθ*sinψ + cosφ*cosψ
    R[2,3] = sinθ*sinψ

    R[3,1] = cosφ*sinθ
    R[3,2] = sinφ*sinθ
    R[3,3] = cosθ

    return R

end

R = euler(pi,0.0,0.0)
v = [1.0; 2.0 ; 3.0]
m = transpose(R) * Diagonal(v) * R

```

It would seem a good case for static arrays, but I cannot seem to get the right syntax. Even basic things like

```julia

function euler(φ, θ, ψ)

    R = SMatrix{3,3,Float64,9}
    cosφ = cos(φ); cosψ = cos(ψ); cosθ = cos(θ)
    sinφ = sin(φ); sinψ = sin(ψ); sinθ = sin(θ)

    R[1,1] = cosφ*cosθ*cosψ - sinφ*sinψ
    R[1,2] = sinφ*cosθ*cosψ + cosφ*sinψ
    R[1,3] = -sinθ*cosψ

    R[2,1] = -cosφ*cosθ*sinψ - sinφ*cosψ
    R[2,2] = -sinφ*cosθ*sinψ + cosφ*cosψ
    R[2,3] = sinθ*sinψ

    R[3,1] = cosφ*sinθ
    R[3,2] = sinφ*sinθ
    R[3,3] = cosθ

    return R

end

```

returns an error as `R[1,1]` seemingly cannot be indexed. I’m also unable to create a diagonal matrix, or an identity matrix (`eye(SMatrix{3,3})` suggested in the docs fails for me, with “eye undefined”).

Basically, I have no idea how to work with StaticArrays – I assumed it was going to be the exact same code and syntax as regular arrays, only they’d have a fixed immutable size, but clearly I got this wrong.

Any clarifications or suggestions welcome!

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [August 31, 2019, 6:22am UTC](https://discourse.julialang.org/t/replacing-normal-arrays-with-static-arrays/28230/2 "2019-08-31T06:22:46Z")

</div>

`SMatrix` is immutable, but you can use `MMatrix` like this:

```julia
julia> function euler(φ, θ, ψ)
           R = MMatrix{3,3,Float64}(undef)
           cosφ = cos(φ); cosψ = cos(ψ); cosθ = cos(θ)
           sinφ = sin(φ); sinψ = sin(ψ); sinθ = sin(θ)

           R[1,1] = cosφ*cosθ*cosψ - sinφ*sinψ
           R[1,2] = sinφ*cosθ*cosψ + cosφ*sinψ
           R[1,3] = -sinθ*cosψ

           R[2,1] = -cosφ*cosθ*sinψ - sinφ*cosψ
           R[2,2] = -sinφ*cosθ*sinψ + cosφ*cosψ
           R[2,3] = sinθ*sinψ

           R[3,1] = cosφ*sinθ
           R[3,2] = sinφ*sinθ
           R[3,3] = cosθ

           return SMatrix(R)
       end

```

---

<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:** [August 31, 2019, 6:41am UTC](https://discourse.julialang.org/t/replacing-normal-arrays-with-static-arrays/28230/3 "2019-08-31T06:41:45Z")

</div>

> [@baptiste](#):
>
> `R = SMatrix{3,3,Float64,9}`

A couple of things. Firstly, as @foobar_lv2 said, you cannot mutate an `SMatrix` after it has been constructed; but `R` above isn’t an `SMatrix`, it’s a `DataType`, it’s like writing `x = Int` instead of `x = 3`.

You can use an `MMatrix` that you mutate, but that doesn’t seem necessary here, and might be slower. You can use an `SMatrix`, but you must create it ‘in one go’:

```julia
R = SMatrix{3,3,Float64}(cosφ*cosθ*cosψ - sinφ*sinψ, 
     sinφ*cosθ*cosψ + cosφ*sinψ, -sinθ*cosψ,
    -cosφ*cosθ*sinψ - sinφ*cosψ, -sinφ*cosθ*sinψ + cosφ*cosψ, 
    sinθ*sinψ, cosφ*sinθ, sinφ*sinθ, cosθ)

```

If you want to preserve readability, you can try this:

```julia
S = SMatrix{3,3,Float64}(
	#= [1,1] =# cosφ*cosθ*cosψ - sinφ*sinψ,
	#= [1,2] =# sinφ*cosθ*cosψ + cosφ*sinψ, 
	#= [1,3] =# -sinθ*cosψ,
	
	#= [2,1] =# -cosφ*cosθ*sinψ - sinφ*cosψ,
	#= [2,2] =# -sinφ*cosθ*sinψ + cosφ*cosψ,
	#= [2,3] =# sinθ*sinψ,

	#= [3,1] =# cosφ*sinθ,
	#= [3,2] =# sinφ*sinθ,
	#= [3,3] =# cosθ)

```

(This works in the REPL but not in Juno, for some reason.)

---

<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:** [August 31, 2019, 7:10am UTC](https://discourse.julialang.org/t/replacing-normal-arrays-with-static-arrays/28230/4 "2019-08-31T07:10:45Z")

</div>

> [@baptiste](#):
>
> . I’m also unable to create a diagonal matrix, or an identity matrix ( `eye(SMatrix{3,3})` suggested in the docs fails for me, with “eye undefined”).

The `eye` function has been removed from Julia, that’s not just a StaticArrays thing. It’s sort of a wasteful construct, to allocate a full matrix when you only have a constant along the diagonal. Instead you are encouraged to use the `UniformScaling` construct, `I`, from the LinearAlgebra stdlib.

For small StaticArrays, though, it might very occasionally be useful to actually instantiate one. Then you do:

```julia
using LinearAlgebra
R = MMatrix{3,3,Float64}(I)

```

You will run into the same issue if you want to create an identity matrix for normal arrays. In that case use

```julia
R = Matrix{Float64}(I, 3, 3)

```

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [August 31, 2019, 8:01am UTC](https://discourse.julialang.org/t/replacing-normal-arrays-with-static-arrays/28230/5 "2019-08-31T08:01:09Z")

</div>

> [@DNF](#):
>
> You can use an `MMatrix` that you mutate, but that doesn’t seem necessary here, and might be slower. You can use an `SMatrix` , but you must create it ‘in one go’:

The “must create in one go” used to annoy me to no end, until I finally saw the light: The compiler is really good at eliding heap allocs. Nowadays I just make an `ref=Base.RefValue{T}()` and then `unsafe_store!` into its `pointer_from_objref`. Even Base is using that pattern in `ReinterpretArray`, and `MArray` is implemented the same way. That’s just the current interface for `alloca` / mutation of immutables / local vars that have their address taken.

But yes, even if both compile to the same, I agree that this specific example looks clearer when written in one go.

---

<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:** [August 31, 2019, 8:05am UTC](https://discourse.julialang.org/t/replacing-normal-arrays-with-static-arrays/28230/6 "2019-08-31T08:05:17Z")

</div>

Ah, I didn’t see that you turned your `MMatrix` into an `SMatrix` at the end there.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [August 31, 2019, 12:21pm UTC](https://discourse.julialang.org/t/replacing-normal-arrays-with-static-arrays/28230/7 "2019-08-31T12:21:31Z")

</div>

Note that [https://github.com/FugroRoames/Rotations.jl](https://github.com/FugroRoames/Rotations.jl) already has this functionality and is based on StaticArrays.
