Broadcasting iterator?

Say I have

x = [1 2]
y = [10, 20, 30]
f(a,b) = a+b+0.5

I want an iterator that goes through the elements of f.(x,y) (11.5, 21.5, 31.5, …) without allocating the output array. Bonus points for an iterator that can also give the indices of x, y, and their nonexistent broadcasted output per iteration: (1,1,1), (1,2,2), (1,3,3), … That last bit might be a bit trickier for arrays that don’t allow linear indexing.

(f(a,b) for (a,b) in Iterators.product(x,y))?

It might help to start with

x = [1 2]
y = [10, 20, 30]
f(a,b) = a+b+0.5
f.(x',y')
# 2×3 Array{Float64,2}:
#  11.5  21.5  31.5
#  12.5  22.5  32.5

I’m not exactly sure what product means but it doesn’t seem to mean broadcast. Say I have z=[1, 2, 3] and do f.(y, z).

I read enough of github issue #19198 to learn that b = Broadcast.broadcasted(f, x, y) gives an iterable over the elements of f.(x,y). @time suggests it doesn’t allocate the output array; Broadcast.materialize(b) does.

1 Like

Couple more comments on the “bonus” part of the post after reading through broadcast.jl:

  • eachindex(b::Broadcasted) will give an iterable of b's indices.
  • An index of b can also be used to “index” into the input arrays x and y to get the values used for that iteration: Broadcast._getindex(b.args, b_index). This was the application I had in mind.
  • If you really need the indices of x and y per iteration: Broadcast.newindex(x, b_index)
1 Like

Well, you just need LazyArrays.jl