# How to mutate static arrays?

**URL:** <https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870>\
**Category:** General Usage\
**Tags:** question, array, staticarrays\
**Created:** [December 20, 2017, 5:07am UTC](https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870 "2017-12-20T05:07:13Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [December 20, 2017, 5:07am UTC](https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870/1 "2017-12-20T05:07:13Z")

</div>

From the README:

> The package provides a range of different useful built-in StaticArray types, which include mutable and immutable arrays based upon tuples, arrays based upon structs, and wrappers of Array. There is a relatively simple interface for creating your own, custom StaticArray types, too.

I tried I to mutate a simple SVector, but there is no `setindex!` defined for it:

```julia
using StaticArrays

v = @SVector [1,2,3]
v[1] = 0
julia> v[1] = 0

ERROR: setindex!(::SVector{3,Int64}, value, ::Int) is not defined.
Stacktrace:
 [1] setindex!(::SVector{3,Int64}, ::Int64, ::Int64) at /home/juliohm/.julia/v0.6/StaticArrays/src/indexing.jl:3

```

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [December 20, 2017, 5:24am UTC](https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870/2 "2017-12-20T05:24:15Z")

</div>

SVector is immutable. If you want a mutable container, you need an MVector

---

<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:** [December 20, 2017, 2:16pm UTC](https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870/3 "2017-12-20T14:16:29Z")

</div>

There is actually a `setindex` method for `SVector`s. It’s not in-place, but replaces the entire vector (note the absense of a `!`).

For short vectors `setindex(::SVector, val, ind)` has similar performance to `setindex!(::MVector, ...)`, but as the vector lengths grow performance degrades.

Try it out:

```julia
v = @SVector [1,2,3]
v = setindex(v, 0, 1)

```

This one is as fast as an `MVector`, so you can stick to `SVector`s.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [December 20, 2017, 3:38pm UTC](https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870/4 "2017-12-20T15:38:44Z")

</div>

Thank you @DNF, can you advise on the choice between `SVector` and `MVector`? What is their different in terms of application?

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [December 20, 2017, 4:06pm UTC](https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870/5 "2017-12-20T16:06:36Z")

</div>

In my application, these vectors will be of very small length like 3 in most cases. I have a normalization operation that I would like to perform in place, so I picked MVector for now:

```julia
"""
    Composition{D}(parts)
A D-part composition as defined by Aitchison 1986.
"""
struct Composition{D}
  parts::MVector{D,Float64}
end

Composition(parts) = Composition{length(parts)}(parts)

"""
Normalize composition `c` in place.
"""
function normalize!(c::Composition)
  p = c.parts
  s = sum(p)
  for i in eachindex(p)
    p[i] /= s
  end
end

```

---

<div class="post-metadata">

**Author:** ![miguelraz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/miguelraz/32/631_2.png) [@miguelraz](https://discourse.julialang.org/u/miguelraz)\
**Post date:** [December 20, 2017, 4:10pm UTC](https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870/6 "2017-12-20T16:10:40Z")

</div>

Perhaps this helps

> <https://stackoverflow.com/questions/47580303/incrementing-a-staticvector-at-an-index/47594994#47594994>

---

<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:** [December 20, 2017, 4:13pm UTC](https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870/7 "2017-12-20T16:13:55Z")

</div>

If you have many of these points stored in something like a Vector then I would use static vectors and just update in place as `a[i] = a[i] / sum(a) `, where `a` is the collection of points. Static vectors are stored inline and fetching memory is often a bottleneck in computation heavy code.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [December 20, 2017, 4:19pm UTC](https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870/8 "2017-12-20T16:19:08Z")

</div>

The big advantage of SVectors is that they are `isbits` types, so they can be cheaply allocated on the stack and stored inline in arrays. MVectors are mutable, and thus not `isbits`, so allocating them is more expensive. MVectors can still be useful, since their fixed size enables lots of specialized algorithms and loop unrolling, but I find that I almost always end up using SVectors in my work.

---

<div class="post-metadata">

**Author:** ![lewis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lewis/32/5217_2.png) [@lewis](https://discourse.julialang.org/u/lewis)\
**Post date:** [July 30, 2020, 3:50pm UTC](https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870/9 "2020-07-30T15:50:28Z")

</div>

But, how can this work? There is no setindex! for a staticarray. This causes an error. There is no way around immutibility that I can see.

---

<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:** [July 30, 2020, 7:06pm UTC](https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870/10 "2020-07-30T19:06:46Z")

</div>

`a` is a normal `Vector` and `a[i]` is a static vector. `a` is what is being mutated.

---

<div class="post-metadata">

**Author:** ![lewis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lewis/32/5217_2.png) [@lewis](https://discourse.julialang.org/u/lewis)\
**Post date:** [July 31, 2020, 12:53pm UTC](https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870/11 "2020-07-31T12:53:11Z")

</div>

That’s clearer than the docs. Shows why we can do comprehensions and zeros, ones, etc—that all replace the vector in place.

And do we replace the whole enchilada in place very quickly without allocations?

---

<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:** [July 31, 2020, 12:57pm UTC](https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870/12 "2020-07-31T12:57:10Z")

</div>

> [@lewis](#):
>
> And do we replace the whole enchilada in place very quickly without allocations?

Yes.

---

<div class="post-metadata">

**Author:** ![Dharik\_Arsath](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dharik_arsath/32/27461_2.png) [@Dharik\_Arsath](https://discourse.julialang.org/u/Dharik_Arsath)\
**Post date:** [February 17, 2022, 11:59am UTC](https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870/13 "2022-02-17T11:59:52Z")

</div>

I don’t understand this point, how can we mutate a static array??? without using MArray…

---

<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:** [February 17, 2022, 12:05pm UTC](https://discourse.julialang.org/t/how-to-mutate-static-arrays/7870/14 "2022-02-17T12:05:45Z")

</div>

What he meant is this:

```julia
julia> using StaticArrays

julia> x = [rand(SVector{2,Float64}) for _ in 1:2] # x is mutable
2-element Vector{SVector{2, Float64}}:
 [0.8394020601377467, 0.028511506698374878]
 [0.4393314594143619, 0.021740546734858035]

julia> x[1] = zeros(SVector{2,Float64}) # mutating the first element of x
2-element SVector{2, Float64} with indices SOneTo(2):
 0.0
 0.0

julia> x
2-element Vector{SVector{2, Float64}}:
 [0.0, 0.0]
 [0.4393314594143619, 0.021740546734858035]

```

`x[1]` was mutated, but the static array inside it was not, it was just replaced by another one.
