# Broadcasting in matrix multiplication

**URL:** https://discourse.julialang.org/t/broadcasting-in-matrix-multiplication/36498
**Category:** General Usage
**Tags:** broadcasting
**Created:** [March 25, 2020, 3:00pm UTC](https://discourse.julialang.org/t/broadcasting-in-matrix-multiplication/36498 "2020-03-25T15:00:13Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)
#### Post date: [March 25, 2020, 3:00pm UTC](https://discourse.julialang.org/t/broadcasting-in-matrix-multiplication/36498/1 "2020-03-25T15:00:13Z")

</div>

Consider a 1x2 matrix `A` and a 1d array of 2x2 matrices `B`:

```julia
A = [1 2]
B = [rand(2,2) for _ in 1:3]

```

Obviously, `B[1]` is a 2x2 matrix, `B[2]` and `B[3]` as well.

Now, I would like to get an array of matrix products `[A*B[1], A*B[2], ... A*B[end]]`. How can I get it? I am trying the dot in

```julia
julia> R = A.*B
3×2 Array{Array{Float64,2},2}:
 [0.460514 0.415326; 0.0842543 0.33096] [0.921028 0.830652; 0.168509 0.66192]
 [0.908421 0.342417; 0.103733 0.155627] [1.81684 0.684833; 0.207466 0.311255]
 [0.828274 0.451481; 0.053429 0.810234] [1.65655 0.902963; 0.106858 1.62047]

```

but obviously it is not the expected result

```julia
julia> R[1]
2×2 Array{Float64,2}:
 0.460514 0.415326
 0.0842543 0.33096

```

Instead, `R[1]` (and for other indices as well) is expected to be a 1x2 matrix.

---

<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: [March 25, 2020, 3:01pm UTC](https://discourse.julialang.org/t/broadcasting-in-matrix-multiplication/36498/2 "2020-03-25T15:01:55Z")

</div>

You want `Ref(A).*B`. `Ref` is a single element container, so broadcast will broadcast over it, not `A`.

---

<div class="post-metadata">

### Author: ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)
#### Post date: [March 25, 2020, 3:05pm UTC](https://discourse.julialang.org/t/broadcasting-in-matrix-multiplication/36498/3 "2020-03-25T15:05:54Z")

</div>

Wow, that was superfast 🙂 Thanks. Now that I have a solution, I still have to understand it. This [Ref](https://docs.julialang.org/en/v1/base/c/#Core.Ref) stuff is completely new to me. Thanks.

---

<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: [March 25, 2020, 3:20pm UTC](https://discourse.julialang.org/t/broadcasting-in-matrix-multiplication/36498/4 "2020-03-25T15:20:06Z")

</div>

It’s conceptually the same as `[A].*B` You are basically just creating a very low overhead container, so that `A` is treated as an element rather than a collection.

---

<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: [March 25, 2020, 3:57pm UTC](https://discourse.julialang.org/t/broadcasting-in-matrix-multiplication/36498/5 "2020-03-25T15:57:58Z")

</div>

You can also just use `(A,)` (a one element tuple). I personally like it better than `Ref` because I thought that was mostly meant for ccall usage.

---

<div class="post-metadata">

### Author: ![Seif\_Shebl](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Seif\_Shebl](https://discourse.julialang.org/u/Seif_Shebl)
#### Post date: [March 26, 2020, 12:40am UTC](https://discourse.julialang.org/t/broadcasting-in-matrix-multiplication/36498/6 "2020-03-26T00:40:26Z")

</div>

You could also use a comprehension, which is clearer, IMO, or even a generator if you don’t want to materialize.

```julia
julia> R = [A*b for b in B]
3-element Array{Array{Float64,2},1}:
 [1.1064518582166465 1.4257048365761784]
 [0.7462570773129014 0.2360058367114488]
 [0.2639640481443961 1.0567511644538756]

julia> R = (A*b for b in B)
Base.Generator{Array{Array{Float64,2},1},var"#11#12"}(var"#11#12"(), [[0.28439915229561796 0.024986306638530964; 0.41102635296051426 0.7003592649688237], [0.6502316144726392 0.15084252545701005; 0.04801273142013107 0.042581655627219384], [0.0710881212956167 0.14551768207448657; 0.0964379634243897 0.45561674118969453]])

```

---

<div class="post-metadata">

### Author: ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)
#### Post date: [March 26, 2020, 10:38am UTC](https://discourse.julialang.org/t/broadcasting-in-matrix-multiplication/36498/7 "2020-03-26T10:38:40Z")

</div>

Excellent, thanks. Indeed, it is clearer.

---

<div class="post-metadata">

### Author: ![RoyiAvital](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/royiavital/32/571_2.png) [@RoyiAvital](https://discourse.julialang.org/u/RoyiAvital)
#### Post date: [March 26, 2020, 12:21pm UTC](https://discourse.julialang.org/t/broadcasting-in-matrix-multiplication/36498/8 "2020-03-26T12:21:10Z")

</div>

> [@Seif\_Shebl](#):
>
> You could also use a comprehension, which is clearer, IMO, or even a generator if you don’t want to materialize
> 
> ```julia
> julia> R = [A*b for b in B]
> 
> ```

It is indeed clearer. In the case `A` and each element in `B` are square matrices, how could you do it inplace?

---

<div class="post-metadata">

### Author: ![lwabeke](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lwabeke/32/4005_2.png) [@lwabeke](https://discourse.julialang.org/u/lwabeke)
#### Post date: [March 26, 2020, 1:40pm UTC](https://discourse.julialang.org/t/broadcasting-in-matrix-multiplication/36498/9 "2020-03-26T13:40:36Z")

</div>

`B .= [A*b for b in B]` works, but does do some allocations

for 2x2 this seems to work

```julia
using LinearAlgebra
for b in B
       mul!(b,A,b)
end

```

but when it gets bigger it attempts calling BLAS which doesn’t like the output being an alias to the input

---

<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: [March 26, 2020, 2:01pm UTC](https://discourse.julialang.org/t/broadcasting-in-matrix-multiplication/36498/10 "2020-03-26T14:01:43Z")

</div>

> [@lwabeke](#):
>
> B .= [A\*b for b in B]

I suspect that this may actually be worse than `B = [A*b for b in B]`, because either way it allocates on the right-hand side, but then it additionally copies over to the left hand side instead of just rebinding the variable, which is basically free.

---

<div class="post-metadata">

### Author: ![lwabeke](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lwabeke/32/4005_2.png) [@lwabeke](https://discourse.julialang.org/u/lwabeke)
#### Post date: [March 26, 2020, 2:25pm UTC](https://discourse.julialang.org/t/broadcasting-in-matrix-multiplication/36498/11 "2020-03-26T14:25:26Z")

</div>

True, but it probably depends on the relative sizes of B and A and memory pressure etc. One big allocation for a new B, might or might not be relevant compared to the numerous “small” allocations for A.  
Also the inplace version might still be relevant if for example B is a view into a larger array. But now I’m probably reaching 🙂  
Either way, the request was for an inplace version and I was hoping someone would suggest a clever way to fix the allocations. (The fact that the for loop with the mul! gave different behaviour for different sizes also thought me something new today).

---

<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: [March 26, 2020, 2:48pm UTC](https://discourse.julialang.org/t/broadcasting-in-matrix-multiplication/36498/12 "2020-03-26T14:48:05Z")

</div>

Actually, my (untested) thesis is that the dotted assignment is _strictly_ worse than the undotted one, because the dotted one does everything that the undotted one does, _plus_ extra copying at the end. I _think_.
