# Broadcasting matrix-vector multiplication over specific axis for n-dimensional arrays

**URL:** <https://discourse.julialang.org/t/broadcasting-matrix-vector-multiplication-over-specific-axis-for-n-dimensional-arrays/85533>\
**Category:** Performance\
**Created:** [August 9, 2022, 1:16pm UTC](https://discourse.julialang.org/t/broadcasting-matrix-vector-multiplication-over-specific-axis-for-n-dimensional-arrays/85533 "2022-08-09T13:16:09Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![b-fg](https://avatars.discourse-cdn.com/v4/letter/b/848f3c/32.png) [@b-fg](https://discourse.julialang.org/u/b-fg)\
**Post date:** [August 9, 2022, 1:16pm UTC](https://discourse.julialang.org/t/broadcasting-matrix-vector-multiplication-over-specific-axis-for-n-dimensional-arrays/85533/1 "2022-08-09T13:16:09Z")

</div>

I have a matrix-vector multiplication to fill `axis=2` of my 3D array `a` (where `basis` is type `Matrix`):

```julia
@inbounds for n ∈ 1:size(a, 1), s ∈ 1:size(a, 3)
    a[n, :, s] = @views basis * b[n, :, s]
end

```

The question is how can I broadcast this over `axis=3`, so that the loop only goes through `n ∈ 1:size(a, 1)`.  
Is there a performance benefit on doing so?

Thanks!

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [August 9, 2022, 1:44pm UTC](https://discourse.julialang.org/t/broadcasting-matrix-vector-multiplication-over-specific-axis-for-n-dimensional-arrays/85533/2 "2022-08-09T13:44:48Z")

</div>

There’s nothing wrong with writing a loop. Done properly, it is usually at least as fast as broadcasting. However, you’ll get better performance from in-place multiplication `mul!` here (since you already have the output space allocated). Also, as you were perhaps alluding to, there’s no need to loop over `s` as that part can be handled by using matrix-matrix multiplication instead of matrix-vector.

```julia
using LinearAlgebra
for n in axes(a,1)
    @views mul!(a[n,:,:], basis, b[n,:,:])
end

```

I removed `@inbounds` because there isn’t a check here to ensure that `axes(a,1) == axes(b,1)` and also because it is unlikely to significantly change performance.

You can write the above via a somewhat arcane broadcast:

```julia
using LinearAlgebra
mul!.(eachslice(a;dims=1), Ref(basis), eachslice(b;dims=1))

```

Although I wouldn’t say this is easier to read that the loop and I don’t expect it to perform noticeably differently. Note that I have broadcasted `mul!` by using `mul!.`, sliced the arrays by iterating the first dimension, and used `Ref(basis)` to _not_ broadcast over that.

---

<div class="post-metadata">

**Author:** ![b-fg](https://avatars.discourse-cdn.com/v4/letter/b/848f3c/32.png) [@b-fg](https://discourse.julialang.org/u/b-fg)\
**Post date:** [August 9, 2022, 2:45pm UTC](https://discourse.julialang.org/t/broadcasting-matrix-vector-multiplication-over-specific-axis-for-n-dimensional-arrays/85533/3 "2022-08-09T14:45:19Z")

</div>

Yeap, of course the matrix-matrix multiplication would do this already… my bad.  
And thanks for the insightful answer and the performance tips using `mul!` 🙂

---

<div class="post-metadata">

**Author:** ![xtalax](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xtalax/32/35293_2.png) [@xtalax](https://discourse.julialang.org/u/xtalax)\
**Post date:** [August 9, 2022, 2:58pm UTC](https://discourse.julialang.org/t/broadcasting-matrix-vector-multiplication-over-specific-axis-for-n-dimensional-arrays/85533/4 "2022-08-09T14:58:59Z")

</div>

Tangentially related, but [this](https://github.com/JuliaLang/julia/pull/32754) function may be useful to you. It is for selecting 1D slices in an ND array along a dimension.
