# Multiplying a 3d array by a scalar?

**URL:** https://discourse.julialang.org/t/multiplying-a-3d-array-by-a-scalar/47376
**Category:** General Usage
**Created:** [September 27, 2020, 10:12pm UTC](https://discourse.julialang.org/t/multiplying-a-3d-array-by-a-scalar/47376 "2020-09-27T22:12:55Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![amca01](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amca01/32/5853_2.png) [@amca01](https://discourse.julialang.org/u/amca01)
#### Post date: [September 27, 2020, 10:12pm UTC](https://discourse.julialang.org/t/multiplying-a-3d-array-by-a-scalar/47376/1 "2020-09-27T22:12:56Z")

</div>

I have an array A of size M,N,P, and a vector v of size P. And I want to multiply each “plane” `A[:,:,i]` of the array by `v[i]`. I can do this in a loop, or with two calls to `reshape`. But is there any way of doing it directly?

If the “P” dimension was first; that is, if the array had size P,M,N, then I could:

`v' .* A`

I’m just wondering if there’s something similar for when the “P” dimension is last; that is, a scalar multiplication in which you can choose the dimension of the array to be used, Thanks!

---

<div class="post-metadata">

### Author: ![briochemc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/briochemc/32/4209_2.png) [@briochemc](https://discourse.julialang.org/u/briochemc)
#### Post date: [September 28, 2020, 4:07am UTC](https://discourse.julialang.org/t/multiplying-a-3d-array-by-a-scalar/47376/2 "2020-09-28T04:07:14Z")

</div>

I don’t know if you can, but an explicit loop is probably (IMHO) the best choice because it should be both efficient and readable.

---

<div class="post-metadata">

### Author: ![briochemc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/briochemc/32/4209_2.png) [@briochemc](https://discourse.julialang.org/u/briochemc)
#### Post date: [September 28, 2020, 4:10am UTC](https://discourse.julialang.org/t/multiplying-a-3d-array-by-a-scalar/47376/3 "2020-09-28T04:10:32Z")

</div>

Otherwise I guess you could try [https://github.com/Jutho/TensorOperations.jl](https://github.com/Jutho/TensorOperations.jl)?

---

<div class="post-metadata">

### Author: ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)
#### Post date: [September 28, 2020, 6:01am UTC](https://discourse.julialang.org/t/multiplying-a-3d-array-by-a-scalar/47376/4 "2020-09-28T06:01:55Z")

</div>

A loop is the best way. You can use Einsum.jl or Tullio.jl for syntax (and performance in many cases)

```julia
using Tullio

@tullio A[i, j, k] = v[k] * A[i, j, k]

```

---

<div class="post-metadata">

### Author: ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)
#### Post date: [September 28, 2020, 6:39am UTC](https://discourse.julialang.org/t/multiplying-a-3d-array-by-a-scalar/47376/5 "2020-09-28T06:39:06Z")

</div>

There’s also the un-exported `Base.PermutedDimsArray`

```julia
julia> A = collect(reshape(1:12, 2, 2, 3));

julia> B = Base.PermutedDimsArray(A, (3,1,2));

julia> v = ones(3) .* 2;

julia> Base.PermutedDimsArray(v .* B, (2,3,1))
2×2×3 PermutedDimsArray(::Array{Float64,3}, (2, 3, 1)) with eltype Float64:
[:, :, 1] =
 2.0 6.0
 4.0 8.0

[:, :, 2] =
 10.0 14.0
 12.0 16.0

[:, :, 3] =
 18.0 22.0
 20.0 24.0

```

---

<div class="post-metadata">

### Author: ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)
#### Post date: [September 28, 2020, 7:12am UTC](https://discourse.julialang.org/t/multiplying-a-3d-array-by-a-scalar/47376/6 "2020-09-28T07:12:44Z")

</div>

Broadcasting is good for this, and you only need one reshape to put `v` along the 3rd dimension. I made a package which keeps track of these reshapes & permutations for me, instead of writing comments explaining which dimension was 3rd, or 4th, and wondering if it should be (2,3,1) or (3,1,2):

```julia
using TensorCast
@cast B[m,n,i] := A[m,n,i] * v[i] # A .* reshape(v, 1,1,:)

@cast B[i,m,n] := A[i,m,n] * v[i] # A .* v 
@cast B[i,m,n] := A[m,n,i] * v[i] # PermutedDimsArray(A, (3,1,2)) .* v

```

---

<div class="post-metadata">

### Author: ![amca01](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amca01/32/5853_2.png) [@amca01](https://discourse.julialang.org/u/amca01)
#### Post date: [September 28, 2020, 1:56pm UTC](https://discourse.julialang.org/t/multiplying-a-3d-array-by-a-scalar/47376/7 "2020-09-28T13:56:42Z")

</div>

Thanks, everyone. It seems that once I get into multidimensional arrays I fall into the world of tensors, in which as you say something like `einsum.jl` may do the job. Or write a loop myself… or re-write my code so that my “dimension of interest” (as it were) is first. This is what I’m currently doing as it is simple, requires no extra packages or macros, and seems to work fine. But it’s also somewhat inflexible, so I will indeed explore the other options! Again, many thanks.
