# Problem with mutation and copying of Matrices/Vectors

**URL:** <https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221>\
**Category:** General Usage\
**Tags:** question, arrays, mutable-structure\
**Created:** [December 16, 2021, 6:56pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221 "2021-12-16T18:56:11Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [December 16, 2021, 6:56pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/1 "2021-12-16T18:56:12Z")

</div>

I have the below MWE of my code. Here, `R.I_prev = R.I;` is working as copy but I found that it works as mutation in my code, so any change of `R.I` will change directly `R.I_prev`. I faced this issue many times. Can any body guide me if there are some rules that I am missing?

```julia
Base.@kwdef mutable struct Rs
    I::Vector{Float64} = [2,2,2]
    I_prev::Vector{Float64} = [1,1,1]
end
R = Rs();
function CC(R)
    I_temp = [3;3;3]
    R.I_prev = R.I;
    R.I = I_temp;
end
CC(R);
julia> R
Rs([3.0, 3.0, 3.0], [2.0, 2.0, 2.0])

```

---

<div class="post-metadata">

**Author:** ![jipolanco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jipolanco/32/12129_2.png) [@jipolanco](https://discourse.julialang.org/u/jipolanco)\
**Post date:** [December 16, 2021, 8:10pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/2 "2021-12-16T20:10:24Z")

</div>

> [@Amro](#):
>
> Here, `R.I_prev = R.I;` is working as copy […]

This syntax does not copy data from one array into the other. Instead, it _replaces_ `R.I_prev` by `R.I`.

Broadcasting does what you want: `R.I_prev .= R.I`.

Note that, if you only want to move data around, you can actually make your struct immutable. This will still allow modifications to the elements of the `I` and `I_prev` arrays, while preventing precisely the issue that you’re seeing.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 16, 2021, 10:45pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/3 "2021-12-16T22:45:17Z")

</div>

> [@Amro](#):
>
> ```julia
> Base.@kwdef mutable struct Rs
> I::Vector{Float64} = [2,2,2]
> I_prev::Vector{Float64} = [1,1,1]
> end
> 
> ```

Note that if you are really working with lots of little 3-component vectors (e.g. representing positions in 3d), you might [consider using StaticArrays](https://docs.julialang.org/en/v1/manual/performance-tips/#Consider-StaticArrays.jl-for-small-fixed-size-vector/matrix-operations). (With `StaticArrays` you can use `=` for copying.)

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [December 16, 2021, 11:14pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/4 "2021-12-16T23:14:08Z")

</div>

Thank you!  
Actually, I dont really get the difference between `replace, broadcast, mutate, copy`. Can you support examples about them?

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [December 16, 2021, 11:14pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/5 "2021-12-16T23:14:43Z")

</div>

Got it and thank you for your help.

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [December 17, 2021, 3:36pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/6 "2021-12-17T15:36:12Z")

</div>

@stevengj  
I am using a vector of `Rs` to access as `R[index-1].field[index-2]`, as as in below (do you recommend another faster way?)

```julia
Base.@kwdef mutable struct Rs
    I::Vector{Float64} = [2,2,2]
    I_prev::Vector{Float64} = [1,1,1]
    Dot::Array{Float64, 2} = [0 0 0; 0 0 0; 0 0 0]
end
R = Rs[];
push!(R, Rs()); # the values of fields may change in the code
push!(R, Rs()); # the values of fields may change in the code
#=
do works on R[index-1].field[index-2]
=#

```

Does using `StaticArrays` also helps here such as in below?

```julia
Base.@kwdef mutable struct Rs
    I::MVector{Float64} = [2,2,2]
    I_prev::MVector{Float64} = [1,1,1]
    Dot::MArray{Float64, 2} = [0 0 0; 0 0 0; 0 0 0]
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:** [December 17, 2021, 4:07pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/7 "2021-12-17T16:07:35Z")

</div>

> [@Amro](#):
>
> ```julia
> I_temp = [3;3;3]
> R.I_prev = R.I;
> R.I = I_temp;
> 
> ```

After this, `R.I` and `R.I_prev` do not point to the same array, so changes to one should not affect the other.

---

<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 17, 2021, 4:10pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/8 "2021-12-17T16:10:47Z")

</div>

It is possibly overkill to have a mutable struct with mutable fields. Which parts (if any) of your type do you _really_ need to mutate?

Have you considered making the struct entirely _im_mutable with immutable fields? In some cases that can yield performance and safety improvements.

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [December 17, 2021, 4:14pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/9 "2021-12-17T16:14:30Z")

</div>

@DNF the format of fields (and struct) are not changing but the values inside the fields are changing as in below:

```julia
Base.@kwdef mutable struct Rs
    I::Vector{Float64} = [2,2,2]
    I_prev::Vector{Float64} = [1,1,1]
    Dot::Array{Float64, 2} = [0 0 0; 0 0 0; 0 0 0]
end
R = Rs[];
push!(R, Rs()); # the values of fields may change in the code
push!(R, Rs()); # the values of fields may change in the code
#=
do works on R[index-1].field[index-2]
=#

```

Do you think I can delete the `mutable` in front of `struct`?  
Maybe I dont really know the meaning of `mutable` in `struct`. For me, it means I can change the values inside the fields, am I right?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 17, 2021, 4:19pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/10 "2021-12-17T16:19:48Z")

</div>

> [@Amro](#):
>
> `push!(R, Rs()); # the values of fields may change in the code`

I’m confused, you’re not changing (“mutating”) any of the values of the fields of a given `Rs` struct here, you’re only adding a _new_ `Rs` struct to the array `R`. That is, you’re not showing any code that would require an `MVector` as opposed to an `SVector`.

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [December 17, 2021, 4:23pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/11 "2021-12-17T16:23:46Z")

</div>

@stevengj  
Here

> [@Amro](#):
>
> ```julia
> #=
> do works on R[index-1].field[index-2]
> =#
> 
> ```

for example,

```julia
#=
R[index-1].field1[index-2] = R[index-1].field2[index-2] + R[index-1].field3[index-2]
=#

```

---

<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 17, 2021, 4:27pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/12 "2021-12-17T16:27:37Z")

</div>

It looks to me like you may want mutable fields (i.e. `MVector`), but you don’t need `Rs` to be mutable. Just delete `mutable`, and see how it goes 😃

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [December 17, 2021, 4:36pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/13 "2021-12-17T16:36:41Z")

</div>

@DNF Mutable structure means its number, names, and values of its fields are changing, correct? So deleting the work `mutable` before structure means so this means its number, names, and values of its fields are not changing, correct?  
Since I only need to change he values of the fields then I can only follow the below suggestion, correct?

> [@DNF](#):
>
> It looks to me like you may want mutable fields (i.e. `MVector` ), but you don’t need `Rs` to be mutable. Just delete `mutable` , and see how it goes

What is about the `Dot` field, `MMatrix`?

```julia
Base.@kwdef mutable struct Rs
    I::MVector{Float64} = [2,2,2]
    I_prev::MVector{Float64} = [1,1,1]
    Dot::MMatrix{Float64, 2} = [0 0 0; 0 0 0; 0 0 0]
end

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 17, 2021, 4:45pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/14 "2021-12-17T16:45:14Z")

</div>

> [@Amro](#):
>
> `I::MVector{Float64} = [2,2,2]`

This is not how you declare an `MVector` (or an `SVector`) — the distinguishing fact about staticarrays is that the _size_ of the array is part of the _type_. This makes them fast for small fixed sizes, but also less flexible since you can’t change the size without changing the type. Also, to declare a literal `MVector` you can use `@MVector`:

```julia
julia> @MVector [2,2,2]
3-element MVector{3, Int64} with indices SOneTo(3):
 2
 2
 2

```

Note that this also helpfully shows the type. Similarly for `MArray`. I would start with something like:

```julia
Base.@kwdef struct Rs
    I::SVector{3, Float64} = @SVector [2,2,2]
    I_prev::SVector{3, Float64} = @SVector [1,1,1]
    Dot::SMatrix{3, 3, Float64, 9} = @SMatrix [0 0 0; 0 0 0; 0 0 0]
end

```

Here, nothing is mutable to start with. You should only make things mutable if you find that there is an operation you need to do that you can’t if it is immutable.

(And you should learn what `mutable struct` means vs mutable fields ala `MVector`, since it seems that you might be confused on this point.)

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 17, 2021, 4:50pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/15 "2021-12-17T16:50:17Z")

</div>

> [@stevengj](#):
>
> You should only make things mutable if you find that there is an operation you need to do that you can’t if it is immutable.

For example, an immutable version of your `CC` function from above is:

```julia
CC(R) = Rs(I = @SVector[3,3,3], I_prev = R.I, Dot = R.Dot)

```

which constructs a new `Rs` struct instead of mutating the old one.

(In general, immutable objects are more efficient in Julia; you should typically work with mutable objects only if you need to reference the _same_ object in two or more places, so that changing the object in one place alters it in the other place. In non performance-sensitive contexts, mutable objects can also sometimes be more convenient, since you don’t have to construct a new object just to change a single field.)

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 17, 2021, 4:53pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/16 "2021-12-17T16:53:23Z")

</div>

> [@stevengj](#):
>
> ```julia
> Base.@kwdef struct Rs
> I::SVector{3, Float64} = @SVector [2,2,2]
> I_prev::SVector{3, Float64} = @SVector [1,1,1]
> Dot::SMatrix{3, 3, Float64, 9} = @SMatrix [0 0 0; 0 0 0; 0 0 0]
> end
> 
> ```

Also, once you get even more Julia experience, you would tend to define this as a parameterized type, e.g.

```julia
Base.@kwdef struct Rs{T<:Number}
    I::SVector{3, T} = @SVector [2,2,2]
    I_prev::SVector{3, T} = @SVector [1,1,1]
    Dot::SMatrix{3, 3, T, 9} = @SMatrix [0 0 0; 0 0 0; 0 0 0]
end

```

which defines a whole “family” of types `Rs{T}` for any numeric type `T`. That way, you can use the same code for double precision (`Float64`), single precision (`Float32`), and even more exotic types like unitful values or dual numbers for automatic differentiation.

But I would recommend learning the basics first by hard-coding `Float64`; you can always upgrade your code to parameterized types later, and in the meantime they are trickier to work with.

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [December 17, 2021, 4:58pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/17 "2021-12-17T16:58:49Z")

</div>

@stevengj  
Thank you very much for your explanations. Starting from this version below

> [@stevengj](#):
>
> ```julia
> Base.@kwdef struct Rs
> I::SVector{3, Float64} = @SVector [2,2,2]
> I_prev::SVector{3, Float64} = @SVector [1,1,1]
> Dot::SMatrix{3, 3, Float64, 9} = @SMatrix [0 0 0; 0 0 0; 0 0 0]
> end
> 
> ```

and if I need to do some operations such as:

```julia
R = Rs[];
push!(R, Rs());
push!(R, Rs());
R[2].I .= R[1].I + R[1].I_prev

```

Then I need to define the structure from the beginning as below, correct?

```julia
Base.@kwdef struct Rs
    I::MVector{3, Float64} = @MVector [2,2,2]
    I_prev::MVector{3, Float64} = @MVector [1,1,1]
    Dot::MMatrix{3, 3, Float64, 9} = @MMatrix [0 0 0; 0 0 0; 0 0 0]
end

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 17, 2021, 7:04pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/18 "2021-12-17T19:04:52Z")

</div>

> [@Amro](#):
>
> Then I need to define the structure from the beginning as below, correct?

No. To change the value of `R[2].I`, you need a `mutable struct`, but you don’t need the field to be an `MVector`. If you just do

```julia
R[2].I = R[1].I + R[1].I_prev

```

then it will work with `SVector` — it is replacing the value of `I`, not overwriting the contents of a mutable object. (You don’t need `.=` with `SVector` because for `SVector` making a copy is essentially zero cost, since it’s not heap-allocated.)

However, you could also accomplish this with a non-mutable `struct` via

```julia
R[2] = Rs(I = R[1].I + R[1].I_prev, I_prev = R[2].I_prev, Dot = R[2].Dot)

```

(In many cases this will be more efficient because non-mutable structs are stored in-line in the array, not as pointers to locations elsewhere on the heap.)

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 17, 2021, 7:09pm UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/19 "2021-12-17T19:09:33Z")

</div>

For example, numbers are immutable in Julia. If you have `x = 3`, that doesn’t mean you can’t change the value of `x`! But if you do `x = 4` then you are making `x` refer to a new value — you aren’t changing the value of `3`! That is:

```julia
x = 3
y = x
x = 4
y # still 3!

```

In contrast, a `Vector` is mutable. If you have `x = [3,4,5]`, and you do `x[1] = 7`, then you are changing the contents of the array in-place:

```julia
x = [3,4,5]
y = x # not a copy — y "points" to the same object
x[1] = 7
y # contents are now [7,4,5]

```

The signature of a mutable object is that if you change it, then other references to the object (via `name = object`) “see” the change.

If `R.I` is an `SVector` in a mutable object `R`, then if you do:

```julia
y = R.I
R.I = @SVector [3,4,5] # only possible if R is a mutable struct
y # hasn't changed!

```

whereas if `R.I` is a mutable object like a `Vector` or an `MVector`, then _even if_ `R` is a (non-mutable) `struct`, you can change the _contents_ of `R.I`:

```julia
y = R.I
R.I .= @SVector [3,4,5] # .= changes the *contents* of R.I
R.I[1] = 2 # you can also change individual elements
y # prints [2,4,5] — it "sees" the change

```

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [December 18, 2021, 12:46am UTC](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221/20 "2021-12-18T00:46:54Z")

</div>

> [@Amro](#):
>
> Mutable structure means its number, names, and values of its fields are changing, correct?

What do you mean by “number” and “names”? You cannot add new fields to an existing `struct` or change the name of its fields, independently if the `struct` is `mutable` or not.

The keyword `mutable` just means you can replace the value/object stored in each field after the `struct` creation. For example, if you create an immutable `struct` with only `Int` values, then you cannot change anything, because you cannot change what the fields refer to (can’t change the `Int` object stored), nor you can change the `Int` objects themselves (`Int`s are immutable). However, if you create an immutable `struct` with an `Vector` inside, then you cannot replace the `Vector` object in the field by another `Vector` object that you have allocated after, **but** the stored `Vector` itself can be changed because it is mutable (you can call `push!`, `empty!`, or assign new values to specific positions). Both the `mutable` and its absence (the default immutability) are not recursive within the `struct`.

[Next page](https://discourse.julialang.org/t/problem-with-mutation-and-copying-of-matrices-vectors/73221.md?page=2)
