# Scalar indexing using broadcast notation?

**URL:** <https://discourse.julialang.org/t/scalar-indexing-using-broadcast-notation/107471>\
**Category:** Signal and Image Processing\
**Created:** [December 12, 2023, 12:03am UTC](https://discourse.julialang.org/t/scalar-indexing-using-broadcast-notation/107471 "2023-12-12T00:03:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![nihil](https://avatars.discourse-cdn.com/v4/letter/n/8c91f0/32.png) [@nihil](https://discourse.julialang.org/u/nihil)\
**Post date:** [December 12, 2023, 12:03am UTC](https://discourse.julialang.org/t/scalar-indexing-using-broadcast-notation/107471/1 "2023-12-12T00:03:35Z")

</div>

I want to convert this to broadcast . notation

```
        indices = shuffle([(i, j) for i in 1:height for j in 1:width])
    
        for (i, j) in indices  
            img[i, j] = sum(img .- (function.((img .- img[i, j]))))
        end

```

Is this possible? I want to use the CuArrays functionality, and I am getting a warning from the package that I am using scalar indexing.

Perhaps it’s an unusual operation since it uses a global operation per pixel. Any suggestions would be golden.

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [December 12, 2023, 1:42am UTC](https://discourse.julialang.org/t/scalar-indexing-using-broadcast-notation/107471/2 "2023-12-12T01:42:28Z")

</div>

Each iteration of the `for` loop mutates `img` for the next iteration. There is a lot of intra-loop dependency here. Is this desired? Usually, a new image is used for the destination in such operations.  
Additionally, providing code is nice… providing **running** code is **much** nicer.

---

<div class="post-metadata">

**Author:** ![nihil](https://avatars.discourse-cdn.com/v4/letter/n/8c91f0/32.png) [@nihil](https://discourse.julialang.org/u/nihil)\
**Post date:** [December 12, 2023, 1:50am UTC](https://discourse.julialang.org/t/scalar-indexing-using-broadcast-notation/107471/3 "2023-12-12T01:50:35Z")

</div>

Hi Dan,

Thanks for replying! Yes you are right, it mutates and that’s okay, it executes randomly over the image and it’s okay for this to happen concurrently.

---

<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:** [December 12, 2023, 2:09am UTC](https://discourse.julialang.org/t/scalar-indexing-using-broadcast-notation/107471/4 "2023-12-12T02:09:39Z")

</div>

Agree about the data race. One broadcasted implementation is:

```julia
tmp = reshape(img, 1, 1, size(img)...)
sum!(img, tmp .- func.(tmp .- img))

```

from here:

```julia
julia> using TensorCast # my package

julia> @pretty @reduce img[i, j] = sum(k, l) img[k, l] - func(img[k, l] - img[i, j])
begin
    @boundscheck ndims(img) == 2 || throw(ArgumentError("expected a 2-tensor img[i, j]"))
    local starling = transmute(img, Val((nothing, nothing, 1, 2)))
    sum!(img, @ __dot__ (starling - func(starling - img)))
end

```

Note that this allocates an intermediate array of size `(size(img)..., size(img)...)`. With CUDA it should be possible to avoid this via lazy broadcasting but not so easy to write out.

Another way is this, which does not use broadcasting:

```julia
using Tullio, KernelAbstractions, CUDA
@tullio img[i, j] = img[k, l] - func(img[k, l] - img[i, j]) # implicit sum over k,l

```

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [December 12, 2023, 2:39am UTC](https://discourse.julialang.org/t/scalar-indexing-using-broadcast-notation/107471/5 "2023-12-12T02:39:52Z")

</div>

To retain the random ordering of updates:

```julia
p = randperm(length(img))
permute!(vec(img), p)
# .... Tullio code on `img` comes here
invpermute!(vec(img), p)

```

will do the trick, since all the operation depend on either pixel or all image (no neighbourhood effects).
