# Specifying StaticArray Types

**URL:** <https://discourse.julialang.org/t/specifying-staticarray-types/34204>\
**Category:** New to Julia\
**Created:** [February 5, 2020, 11:50am UTC](https://discourse.julialang.org/t/specifying-staticarray-types/34204 "2020-02-05T11:50:13Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![scj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scj/32/20488_2.png) [@scj](https://discourse.julialang.org/u/scj)\
**Post date:** [February 5, 2020, 11:50am UTC](https://discourse.julialang.org/t/specifying-staticarray-types/34204/1 "2020-02-05T11:50:13Z")

</div>

If a struct’s field is a StaticArray, then how do I (generically) specify its type? As seen below, not specifying the type has an effect on performance, but my attempt is obviously no good either, as it’s far to specific.

```julia
using BenchmarkTools, StaticArrays

mutable struct TypedModel
    A::SArray{Tuple{6,6},Float64,2,36}
    Atranspose::SArray{Tuple{6,6},Float64,2,36}
    u::SArray{Tuple{6},Float64,1,6}
    R::SArray{Tuple{6,6},Float64,2,36}
end

mutable struct Model
    A
    Atranspose
    u
    R
end

function multiplythings!(μ, Σ, A, Atranspose, u, R, n)
    for i = 1:n
        μ[i] = A * μ[i] + u
        Σ[i] = A * Σ[i] * Atranspose + R
    end
end

function multiplythings!(μ, Σ, model, n)
    for i = 1:n
        μ[i] = model.A * μ[i] + model.u
        Σ[i] = model.A * Σ[i] * model.Atranspose + model.R
    end
end

# Model
xdim = 6
n = 1000
A = @SMatrix rand(xdim, xdim)
Atranspose = A'
u = @SVector rand(xdim)
R = @SMatrix rand(xdim, xdim)
# State estimate parameters
μ = [@SVector rand(xdim) for _ = 1:n]
Σ = [@SMatrix rand(xdim, xdim) for _ = 1:n]
# Create models
model = Model(A, Atranspose, u, R)
typedmodel = TypedModel(A, Atranspose, u, R)
@btime multiplythings!($μ, $Σ, $A, $Atranspose, $u, $R, $n)
@btime multiplythings!($μ, $Σ, $typedmodel, $n)
@btime multiplythings!($μ, $Σ, $model, $n)

```

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [February 5, 2020, 12:46pm UTC](https://discourse.julialang.org/t/specifying-staticarray-types/34204/2 "2020-02-05T12:46:50Z")

</div>

A `StaticVector` is characterized by its length (`VecN`) and the element type (`VecT`). A `StaticMatrix` is characterized by its size (nrows `MatR`, ncolumns `MatC`) and the element type (`MatT`). These characterizing features can be given as parameters. That is likely the most general way to get most specific.

```julia
struct S{VecN, VecT, MatR, MatC, MatT}
  staticvec::SArray{Tuple{VecN}, VecT}
  staticmat::SArray{Tuple{MatR,MatC}, MatT}
end

function S(vec::Vector{VecT}, mat::Matrix{MatT}) where {VecT, MatT}
  VecN = length(vec)
  MatR, MatC = size(mat)
  return S{VecN, VecT, MatR, MatC, MatT}(vec, mat)
end

```

```julia
julia> test = S([1, 2, 3], [1 2; 3 4])
S{3,Int64,2,2,Int64}([1, 2, 3], [1 2; 3 4])

julia> test.staticvec
3-element SArray{Tuple{3},Int64,1,3} with indices SOneTo(3):
 1
 2
 3

julia> test.staticmat
2×2 SArray{Tuple{2,2},Int64,2,4} with indices SOneTo(2)×SOneTo(2):
 1 2
 3 4

```

To pass your vector as a tuple, define another constructor. To pass your matrix as a tuple with a two-tuple size (nrows, ncolumns) define another constructor.

---

<div class="post-metadata">

**Author:** ![scj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scj/32/20488_2.png) [@scj](https://discourse.julialang.org/u/scj)\
**Post date:** [February 5, 2020, 1:07pm UTC](https://discourse.julialang.org/t/specifying-staticarray-types/34204/3 "2020-02-05T13:07:40Z")

</div>

I tried this and it works, but my performance suffers. I tried:

```julia
mutable struct TypedModel{X, T}
    A::SArray{Tuple{X, X}, T}
    Atranspose::SArray{Tuple{X, X}, T}
    u::SArray{Tuple{X}, T}
    R::SArray{Tuple{X, X}, T}
end

typedmodel = TypedModel{xdim, Float64}(A, Atranspose, u, R)
@btime multiplythings!($μ, $Σ, $typedmodel, $n)
287.900 μs (7978 allocations: 1.48 MiB)

```

What is going wrong here?

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [February 5, 2020, 1:14pm UTC](https://discourse.julialang.org/t/specifying-staticarray-types/34204/4 "2020-02-05T13:14:38Z")

</div>

I don’t know what you are doing (see points 3 & 4 [here](https://discourse.julialang.org/t/psa-make-it-easier-to-help-you/14757)).  
Show me that the performance suffers using my minimal example (perhaps with a larger vector and a larger matrix). Include the vector and matrix explicitly, so we have something specific to compare.

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [February 5, 2020, 1:48pm UTC](https://discourse.julialang.org/t/specifying-staticarray-types/34204/5 "2020-02-05T13:48:13Z")

</div>

OK, I tracked it down. To get the performance you need to provide all the parameters. My oversight. `N` is the vector length, `N2` is N\*N, the matrix length, `T` is the shared element type.

```julia
mutable struct TypedModel3{N, N2, T}
   A::SArray{Tuple{N, N}, T, 2, N2}
   Atranspose::SArray{Tuple{N, N}, T, 2, N2}
   u::SArray{Tuple{N}, T, 1, N}
   R::SArray{Tuple{N, N}, T, 2, N2}
end

x2dim = xdim * xdim
typedmodel3 = TypedModel3{xdim, x2dim, Float64}(A, Atranspose, u, R)

julia> @btime multiplythings!($μ, $Σ, $typedmodel3, $n)
  46.600 μs (0 allocations: 0 bytes)

```

---

<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:** [February 5, 2020, 1:48pm UTC](https://discourse.julialang.org/t/specifying-staticarray-types/34204/6 "2020-02-05T13:48:44Z")

</div>

As far as I understand it is not enough to specify the length of the two dimensions of an `SMatrix`, you also have to give the number of elements. Even though it’s in principle trivial to calculate the latter from the former, the compiler isn’t able to.

Edit: oops, to late.
