# How to reset the elements of a 3x3 matrix without any memory allocation?

**URL:** <https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [June 13, 2023, 2:11am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257 "2023-06-13T02:11:45Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ethan\_Diao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ethan_diao/32/50713_2.png) [@Ethan\_Diao](https://discourse.julialang.org/u/Ethan_Diao)\
**Post date:** [June 13, 2023, 2:11am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/1 "2023-06-13T02:11:45Z")

</div>

I want to set the element value of a 3x3 matrix to newly calculated values in a small function that gets called a lot of times. I’ve tried broadcasted assignment to a temporary 3x3 matrix, but that seems to introduce a few allocations that the compiler won’t optimize away. So the question is that if there is any solutions to this problem other than manually setting the elment values one by one.

---

<div class="post-metadata">

**Author:** ![Ethan\_Diao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ethan_diao/32/50713_2.png) [@Ethan\_Diao](https://discourse.julialang.org/u/Ethan_Diao)\
**Post date:** [June 13, 2023, 2:13am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/2 "2023-06-13T02:13:42Z")

</div>

BTW I’ve tried these methods. The element-by-element assignment is too verbose.

```julia
A = zeros(3,3)
@time A .= [
    1 2 3;
    4 5 6;
    7 8 9;
]; # 3 allocations
@time A[:] .= (1,2,3,4,5,6,7,8,9); # 4 allocations
@time A[:] .= [1,2,3,4,5,6,7,8,9]; # 7 allocations
@time begin
A[1] = 1;
A[2] = 2;
A[3] = 3;
A[4] = 4;
A[5] = 5;
A[6] = 6;
A[7] = 7;
A[8] = 8;
A[9] = 9;
end # 0 allocations

```

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [June 13, 2023, 2:25am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/3 "2023-06-13T02:25:45Z")

</div>

`vec(A) .= (values...)` should be fast and minimally-allocating, but you’ll probably see a much bigger performance gain by switching to [static arrays](https://github.com/JuliaArrays/StaticArrays.jl) for small arrays modified in inner loops.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 13, 2023, 3:20am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/4 "2023-06-13T03:20:05Z")

</div>

Some of those allocations are you allocating an input array to write into `A`, some of those came from running `@time` in the global scope, and some came from `A[:] .= B` making a view that did an allocating `reshape` of the matrix `A` to a vector (though the allocation is small because the underlying buffer of values is reused). There was a [thread yesterday](https://discourse.julialang.org/t/why-does-the-following-setindex-call-allocate/100216) pointing out this allocating `reshape` happening for `view`s of matrices. `vec(A)` does `reshape(A, length(A))` so that does the small allocations too.

---

<div class="post-metadata">

**Author:** ![Ethan\_Diao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ethan_diao/32/50713_2.png) [@Ethan\_Diao](https://discourse.julialang.org/u/Ethan_Diao)\
**Post date:** [June 13, 2023, 3:31am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/5 "2023-06-13T03:31:56Z")

</div>

Thanks for all your helpfull advice! These are my new test results. Using immutable static array to reinitialize matrix A resulted in 0 allocations, which only requires an additional macro. I guess the problem is solved. Thanks again!

```julia
@time vec(A) .= (1,2,3,4,5,6,7,8,9); # 2 allocs
@time @view(A[:]) .= (1,2,3,4,5,6,7,8,9); # 3 allocs
@time @views A[:] .= (1,2,3,4,5,6,7,8,9); # 4 allocs
@time vec(A) .= [1,2,3,4,5,6,7,8,9]; # 4 allocs

@time vec(A) .= @SVector [1,2,3,4,5,6,7,8,9]; # 2 allocs
@time A .= @MMatrix [
    1 2 3;
    4 5 6;
    7 8 9;
]; # 2 allocs
@time A .= @SMatrix [
    1 2 3;
    4 5 6;
    7 8 9;
]; # 0 allocs

```

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 13, 2023, 3:39am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/6 "2023-06-13T03:39:34Z")

</div>

The key to 0 allocations there was that the input array is now a `Matrix`, so you did not have to make a vector view `A[:]`, which would’ve triggered an allocating vector reshape.  
I think stillyslalom was suggesting that `A` be an `MMatrix` too. You’d still need to preallocate, but the small fixed size can be useful.

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [June 13, 2023, 4:04am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/7 "2023-06-13T04:04:46Z")

</div>

Or, depending on the nature of the operations, a `SMatrix`! Even for cases where you’re replacing all the values in a small array in each loop, `SMatrix` can be marginally faster than `MMatrix`:

```julia
julia> using BenchmarkTools

julia> function f(A, n = 1000)
           s = zero(eltype(A))
           for i = 1:n
               A *= rand()
               s += sum(A)
           end
           s
       end
f (generic function with 2 methods)

julia> function g(A, n = 1000)
           s = zero(eltype(A))
           for i = 1:n
               A .*= rand()
               s += sum(A)
           end
           s
       end
g (generic function with 2 methods)

```

```julia
julia> @btime f(@SMatrix rand(3, 3))
  3.788 μs (0 allocations: 0 bytes)
0.9307550454767469

julia> @btime g(@MMatrix rand(3, 3))
  4.543 μs (1 allocation: 80 bytes)
2.402649106652987

```

---

<div class="post-metadata">

**Author:** ![Ethan\_Diao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ethan_diao/32/50713_2.png) [@Ethan\_Diao](https://discourse.julialang.org/u/Ethan_Diao)\
**Post date:** [June 13, 2023, 4:12am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/8 "2023-06-13T04:12:51Z")

</div>

Thanks for the helpful information. My function runs a lot faster now by simply switching to static arrays.

---

<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:** [June 13, 2023, 4:46am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/9 "2023-06-13T04:46:42Z")

</div>

StaticArrays seems like a fine solution, but in general I’d say just use a loop.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [June 13, 2023, 7:07am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/10 "2023-06-13T07:07:04Z")

</div>

This is a bit low-level but also allocation free:

```julia
copyto!(A, 1, (1, 2, 3, 4, 5, 6, 7, 8, 9), 1, 9)

```

---

<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:** [June 13, 2023, 8:37am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/11 "2023-06-13T08:37:59Z")

</div>

Actually, I misunderstood, and thought you were changing `A` to being an SMatrix. If `A` is a regular `Matrix`, and performance is the goal, then definitely use a loop, not `@SMatrix` or `copyto!` or anything like that.

```julia
function foo!(A)
    for i in 1:9
        A[i] = i;
    end
    return A
end

bar!(A) = copyto!(A, 1, (1, 2, 3, 4, 5, 6, 7, 8, 9), 1, 9)

function baz!(A)
    A .= @SMatrix [1 2 3; 4 5 6; 7 8 9]
    return A
end

```

Benchmarks:

```julia
julia> @btime foo!(A) setup=(A=zeros(3,3));
  6.400 ns (0 allocations: 0 bytes)

julia> @btime bar!(A) setup=(A=zeros(3,3));
  26.205 ns (0 allocations: 0 bytes)

julia> @btime baz!(A) setup=(A=zeros(3,3));
  10.010 ns (0 allocations: 0 bytes)

```

If you think that `@inbounds` is safe, you can do

```julia
function foo_inbounds!(A)
    for i in 1:9
        @inbounds A[i] = i;
    end
    return A
end

```

and get:

```julia
julia> @btime foo_inbounds!(A) setup=(A=zeros(3,3));
  2.800 ns (0 allocations: 0 bytes)

```

Most of the time, when you need optimal performance, use a loop.

---

<div class="post-metadata">

**Author:** ![Ethan\_Diao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ethan_diao/32/50713_2.png) [@Ethan\_Diao](https://discourse.julialang.org/u/Ethan_Diao)\
**Post date:** [June 14, 2023, 1:26am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/12 "2023-06-14T01:26:19Z")

</div>

Thanks for the infomation. It really helps me understand more of julia. But in my use case, I don’t think the new matrix value can be calculated in a for loop. I forgot to mention the details in my question. So my goal is to calculate 3x3 rotational matrices for each input angle, the code is something like this.

```julia
Rx = @SMatrix [
        1 0 0;
        0 cos(x) -sin(x);
        0 sin(x) cos(x);
]

```

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [June 14, 2023, 1:31am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/13 "2023-06-14T01:31:37Z")

</div>

Are you sure rotation matrices are actually what you want to use here? Quaternians are usually faster.

---

<div class="post-metadata">

**Author:** ![Ethan\_Diao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ethan_diao/32/50713_2.png) [@Ethan\_Diao](https://discourse.julialang.org/u/Ethan_Diao)\
**Post date:** [June 14, 2023, 2:34am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/14 "2023-06-14T02:34:33Z")

</div>

Well, the original code written in matlab that I’m referencing uses rotation matrices. I’m simply trying to reproduce the code in julia. So using rotational matrices saves a lot of trouble for me.

---

<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:** [June 14, 2023, 5:19am UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/15 "2023-06-14T05:19:11Z")

</div>

> [@Ethan\_Diao](#):
>
> But in my use case, I don’t think the new matrix value can be calculated in a for loop.

That is important information. It was not clear to me how the values were actually passed to the function.

But in that case I suggest that you _don’t_ use a SMatrix to _update_ the input matrix `A`, but instead _directly_ use the SMatrix itself:

```julia
function Rot(x) 
    return @SMatrix [
        1 0 0;
        0 cos(x) -sin(x);
        0 sin(x) cos(x)]
end

```

And then you write `A = Rot(value)`. Also make all your other vectors and matrices into SArrays.

---

<div class="post-metadata">

**Author:** ![PeterSimon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petersimon/32/25193_2.png) [@PeterSimon](https://discourse.julialang.org/u/PeterSimon)\
**Post date:** [June 14, 2023, 4:21pm UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/16 "2023-06-14T16:21:29Z")

</div>

If you’re using `Rot` in a hot loop, then you can make it faster:

```julia
julia> using StaticArrays

julia> function Rot(x)
           return @SMatrix [
                   1 0 0
                   0 cos(x) -sin(x)
                   0 sin(x) cos(x)]
       end
Rot (generic function with 1 method)

julia> function Rot2(x)
           s, c = sincos(x)
           return @SMatrix [
                   1 0 0
                   0 c -s
                   0 s c ]
       end
Rot2 (generic function with 1 method)

julia> using BenchmarkTools

julia> x = 1.3
1.3

julia> @btime Rot($x);
  18.857 ns (0 allocations: 0 bytes)

julia> @btime Rot2($x);
  8.100 ns (0 allocations: 0 bytes)

```

A nit: It is conventional in Julia for function names to be all lower case. Capitalized (actually, CamelCase) names are used to denote types and modules. See the [relevant portion](https://docs.julialang.org/en/v1/manual/style-guide/#Use-naming-conventions-consistent-with-Julia-base/) of the style guide.

---

<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:** [June 14, 2023, 4:44pm UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/17 "2023-06-14T16:44:32Z")

</div>

> [@PeterSimon](#):
>
> It is conventional in Julia for function names to be all lower case.

I know, and normally follow it. But whenever I write a function that ‘constructs’ a rotation matrix, I prefer uppercase, probably because it is conceptually a constructor of an object, even though it’s not a type constructor, _per se_.

---

<div class="post-metadata">

**Author:** ![PeterSimon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petersimon/32/25193_2.png) [@PeterSimon](https://discourse.julialang.org/u/PeterSimon)\
**Post date:** [June 14, 2023, 4:53pm UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/18 "2023-06-14T16:53:56Z")

</div>

My comment was for the benefit of the OP, who I assume is not familiar with standard Julia conventions. I respect your expertise, which greatly exceeds my own!

---

<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:** [June 14, 2023, 5:17pm UTC](https://discourse.julialang.org/t/how-to-reset-the-elements-of-a-3x3-matrix-without-any-memory-allocation/100257/19 "2023-06-14T17:17:54Z")

</div>

Ah, I see. Also, you are too kind😉
