Is there a way to "choose the indices" for broadcasting?

As always, examples are best. With a loop I can do:

for i in 1:3:12
  tmp[i] = a[i]*b[i]
end

Is there a way to make

tmp .= a.*b

only update specific chosen indices? And as a slight extension, what about having tmp be dense while the others aren’t?

idxs = 1:3:12
for i in idxs
  tmp[i] = a[idxs[i]]*b[idxs[i]]
end

You could use views, e.g. view(tmp, 1:3:12) .= view(a, 1:3:12) .* view(b, 1:3:12).

2 Likes

You could also do

I = 1:3:12
tmp[I] .= view(a, I) .* view(b, I)

This gets lowered to broadcast!(*, dotview(tmp, I), view(a, I), view(b, I)), where dotview is a view for AbstractArrays or getindex otherwise. I wonder whether it is worth to do the same for the rest of the arguments, in which case you could simply write tmp[I] .= a[I] .* b[I].

2 Likes

That last syntax is beautiful. What about a macro for that?

@broadcast_view tmp[I] .= a[I] .* b[I]
1 Like

I’ve been thinking about this as well, and I’ve submitted a PR so that you can just put @views in front of an assignment, a whole block of code, or even a whole function, and every slice is converted to a view: https://github.com/JuliaLang/julia/pull/20164

3 Likes