How to broadcast for 3d-array?

This is a very amateur question, but how can I make the code to output a three-dimensional array when I broadcast to a variable like the one in the image in julia? I want the element specified by [i,j,k] in the three-dimensional array to be the value when the i,j,kth element of each argument is assigned to the function.

You might be interested in Please read: make it easier to help you,
which shows how to use triple back-quotes to format code.

I want the element specified by [i,j,k] in the three-dimensional array to be the value when the i,j,kth element of each argument is assigned to the function.

This is something that can be done neatly with comprehensions
rather than broadcasting:

julia> v = [0.1, 0.2, 0.3, 0.4]

julia> func(a, b, c) = sin(a + b + c)

julia> [func(a, b, c) for a in v, b in v, c in v]
4×4×4 Array{Float64, 3}:
[:, :, 1] =
 0.29552   0.389418  0.479426  0.564642
 0.389418  0.479426  0.564642  0.644218
 0.479426  0.564642  0.644218  0.717356
 0.564642  0.644218  0.717356  0.783327

[:, :, 2] =
 0.389418  0.479426  0.564642  0.644218
 0.479426  0.564642  0.644218  0.717356
 0.564642  0.644218  0.717356  0.783327
 0.644218  0.717356  0.783327  0.841471

[:, :, 3] =
 0.479426  0.564642  0.644218  0.717356
 0.564642  0.644218  0.717356  0.783327
 0.644218  0.717356  0.783327  0.841471
 0.717356  0.783327  0.841471  0.891207

[:, :, 4] =
 0.564642  0.644218  0.717356  0.783327
 0.644218  0.717356  0.783327  0.841471
 0.717356  0.783327  0.841471  0.891207
 0.783327  0.841471  0.891207  0.932039
4 Likes

You have to reshape the inputs so that one argument lies along the first dimension, the second along the second dimension, and so on. Try

func.(x, y', reshape(z, 1, 1, :))
4 Likes

Here another approach.

julia> cis = CartesianIndices((4,4,4))
CartesianIndices((4, 4, 4))

julia> Tuple.(cis)
4×4×4 Array{Tuple{Int64, Int64, Int64}, 3}:
[:, :, 1] =
 (1, 1, 1)  (1, 2, 1)  (1, 3, 1)  (1, 4, 1)
 (2, 1, 1)  (2, 2, 1)  (2, 3, 1)  (2, 4, 1)
 (3, 1, 1)  (3, 2, 1)  (3, 3, 1)  (3, 4, 1)
 (4, 1, 1)  (4, 2, 1)  (4, 3, 1)  (4, 4, 1)

[:, :, 2] =
 (1, 1, 2)  (1, 2, 2)  (1, 3, 2)  (1, 4, 2)
 (2, 1, 2)  (2, 2, 2)  (2, 3, 2)  (2, 4, 2)
 (3, 1, 2)  (3, 2, 2)  (3, 3, 2)  (3, 4, 2)
 (4, 1, 2)  (4, 2, 2)  (4, 3, 2)  (4, 4, 2)

[:, :, 3] =
 (1, 1, 3)  (1, 2, 3)  (1, 3, 3)  (1, 4, 3)
 (2, 1, 3)  (2, 2, 3)  (2, 3, 3)  (2, 4, 3)
 (3, 1, 3)  (3, 2, 3)  (3, 3, 3)  (3, 4, 3)
 (4, 1, 3)  (4, 2, 3)  (4, 3, 3)  (4, 4, 3)

[:, :, 4] =
 (1, 1, 4)  (1, 2, 4)  (1, 3, 4)  (1, 4, 4)
 (2, 1, 4)  (2, 2, 4)  (2, 3, 4)  (2, 4, 4)
 (3, 1, 4)  (3, 2, 4)  (3, 3, 4)  (3, 4, 4)
 (4, 1, 4)  (4, 2, 4)  (4, 3, 4)  (4, 4, 4)

julia> Tuple.(cis) .|> ((x,y,z),)->(x/10, y/10, z/10)
4×4×4 Array{Tuple{Float64, Float64, Float64}, 3}:
[:, :, 1] =
 (0.1, 0.1, 0.1)  (0.1, 0.2, 0.1)  (0.1, 0.3, 0.1)  (0.1, 0.4, 0.1)
 (0.2, 0.1, 0.1)  (0.2, 0.2, 0.1)  (0.2, 0.3, 0.1)  (0.2, 0.4, 0.1)
 (0.3, 0.1, 0.1)  (0.3, 0.2, 0.1)  (0.3, 0.3, 0.1)  (0.3, 0.4, 0.1)
 (0.4, 0.1, 0.1)  (0.4, 0.2, 0.1)  (0.4, 0.3, 0.1)  (0.4, 0.4, 0.1)

[:, :, 2] =
 (0.1, 0.1, 0.2)  (0.1, 0.2, 0.2)  (0.1, 0.3, 0.2)  (0.1, 0.4, 0.2)
 (0.2, 0.1, 0.2)  (0.2, 0.2, 0.2)  (0.2, 0.3, 0.2)  (0.2, 0.4, 0.2)
 (0.3, 0.1, 0.2)  (0.3, 0.2, 0.2)  (0.3, 0.3, 0.2)  (0.3, 0.4, 0.2)
 (0.4, 0.1, 0.2)  (0.4, 0.2, 0.2)  (0.4, 0.3, 0.2)  (0.4, 0.4, 0.2)

[:, :, 3] =
 (0.1, 0.1, 0.3)  (0.1, 0.2, 0.3)  (0.1, 0.3, 0.3)  (0.1, 0.4, 0.3)
 (0.2, 0.1, 0.3)  (0.2, 0.2, 0.3)  (0.2, 0.3, 0.3)  (0.2, 0.4, 0.3)
 (0.3, 0.1, 0.3)  (0.3, 0.2, 0.3)  (0.3, 0.3, 0.3)  (0.3, 0.4, 0.3)
 (0.4, 0.1, 0.3)  (0.4, 0.2, 0.3)  (0.4, 0.3, 0.3)  (0.4, 0.4, 0.3)

[:, :, 4] =
 (0.1, 0.1, 0.4)  (0.1, 0.2, 0.4)  (0.1, 0.3, 0.4)  (0.1, 0.4, 0.4)
 (0.2, 0.1, 0.4)  (0.2, 0.2, 0.4)  (0.2, 0.3, 0.4)  (0.2, 0.4, 0.4)
 (0.3, 0.1, 0.4)  (0.3, 0.2, 0.4)  (0.3, 0.3, 0.4)  (0.3, 0.4, 0.4)
 (0.4, 0.1, 0.4)  (0.4, 0.2, 0.4)  (0.4, 0.3, 0.4)  (0.4, 0.4, 0.4)

julia> Tuple.(cis) .|>
           ((x,y,z),) -> (x/10, y/10, z/10) .|>
           (args...) -> sin(+(args...))
4×4×4 Array{Tuple{Float64, Float64, Float64}, 3}:
[:, :, 1] =
 (0.0998334, 0.0998334, 0.0998334)  …  (0.0998334, 0.389418, 0.0998334)
 (0.198669, 0.0998334, 0.0998334)      (0.198669, 0.389418, 0.0998334)
 (0.29552, 0.0998334, 0.0998334)       (0.29552, 0.389418, 0.0998334)
 (0.389418, 0.0998334, 0.0998334)      (0.389418, 0.389418, 0.0998334)

[:, :, 2] =
 (0.0998334, 0.0998334, 0.198669)  …  (0.0998334, 0.389418, 0.198669)
 (0.198669, 0.0998334, 0.198669)      (0.198669, 0.389418, 0.198669)
 (0.29552, 0.0998334, 0.198669)       (0.29552, 0.389418, 0.198669)
 (0.389418, 0.0998334, 0.198669)      (0.389418, 0.389418, 0.198669)

[:, :, 3] =
 (0.0998334, 0.0998334, 0.29552)  …  (0.0998334, 0.389418, 0.29552)
 (0.198669, 0.0998334, 0.29552)      (0.198669, 0.389418, 0.29552)
 (0.29552, 0.0998334, 0.29552)       (0.29552, 0.389418, 0.29552)
 (0.389418, 0.0998334, 0.29552)      (0.389418, 0.389418, 0.29552)

[:, :, 4] =
 (0.0998334, 0.0998334, 0.389418)  …  (0.0998334, 0.389418, 0.389418)
 (0.198669, 0.0998334, 0.389418)      (0.198669, 0.389418, 0.389418)
 (0.29552, 0.0998334, 0.389418)       (0.29552, 0.389418, 0.389418)
 (0.389418, 0.0998334, 0.389418)      (0.389418, 0.389418, 0.389418)
1 Like

Base.splat(func).(Iterators.product(v,v,v))

If your function takes a tuple as input, you don’t need the splat

funcs((a, b, c))= sin(a+b+c)

funcs.(Iterators.product(v,v,v))
2 Likes