 # Zygote: Mutating arrays is not supported (small example)

A small educational example:

``````using Zygote
using ForwardDiff
``````

Let’s define a simple gaussian (sampled at integer coordinates)

``````x = -20:1.0:20
f2(xf) = 1000.0 .* exp.(-1.25 .* (x .- xf).^2)
``````

And a simple center of mass computation to estimate the location of the peak from the samples

``````function cm(xc, α)
y = f2(xc)

# The next two lines are the issue
y = y .- 15.0;
y[y.<0] .= 0.0;

y = y.^α #just a random example, could be some other function
i = argmax(y)
idx = i-2:1:i+2
return sum(y[idx] .* x[idx]) / sum(y[idx])
end
``````

And let’s say that I want to minimize the error that I make as function of alpha

``````function cost_cm(α)
r = cm.(-0.5:0.01:0.5, α) .- (-0.5:0.01:0.5)
return maximum(r)
end
``````

Forward diff is fine

``````d_cost_cm(x) = ForwardDiff.derivative(cost_cm, x)
d_cost_cm(1.0)
-0.02776240571095623
``````

Zygote is not happy

``````d_cost_cm_Zygote(x) = gradient(cost_cm, x)
d_cost_cm_Zygote(1.0)
Mutating arrays is not supported ...
``````

The issue are the lines:

``````	y = y .- 15.0;
y[y.<0] .= 0.0;
``````

Is there a way to replace them with something equivalent that would make Zygote happy?
(PS do we expect this issue to be solved by Diffractor.jl?)

Somehow related, if you use filter to create a new array instead of y[y.<0] .= 0.0 can you get the list of indexes to be used in sum(y_new_filtered_array .* x[idx]) / sum(y_new_filtered_array) ?

You could replace `y[y.<0] .= 0.0` by `y = clamp.(y, 0.0, Inf)`.
See here for workarounds when it is more difficult to write code without mutating arrays.

Thank you. For fun I also created a couple of alternatives that seem to work:

``````function cm(xc, α)
y0 = f2(xc)
y0 = y0 .- 15.0;

idx_m = argmax(y0)
idx = idx_m-2:1:idx_m+2

y = y0[idx];
y = clamp.(y, 0.0, Inf)
y = y.^α

return sum(y .* x[idx]) / sum(y)
end
``````

or

``````function cm(xc, α)
y0 = f2(xc)
y0 = y0 .- 15.0;

idx = findall(x -> x>=0.0,y0)
y = y0[idx];
y = y.^α

return sum(y .* x[idx]) / sum(y)
end
``````

I suspect I have to get a bit more familiar with what “mutating” an array means here.