I believe there is a bug in this code. For the sake of brevity though I will just write the function which defines the ODE
function clones(du,u,p,t)
(Nmut,f) = p
# average fitness
phi = sum(f.*u)
# constructing mutation kernel
eps = 0.01
Q = Qmatrix(Nmut,eps)
# defining differential equations
Nclones=2^Nmut;
du = zeros(Nclones)
ufQ = transpose(transpose(u.*f)*Q)
du = ufQ .- phi*u
end
If the whole code is needed I can provide it, but it is messy and I'm not sure how to create a minimal example. I tried this when Nmut = 2 so I can compare to a hard-coded version. The output of du at the first time steps are identical. But this version does not seem to ever update u it stays at the u0 prescribed.
Does anyone have an idea why this might be the case? I can also provide the full script, but wanted to avoid that if someone could just see why u would not update.
EDIT:
maxdim=4;
for i in 1:maxdim
du[i] = 0.0;
for j in 1:maxdim
du[i] += u[j].*w[j].*Q[j,i]
end
du[i] -= u[i].*phi
end
The du is updated correctly if we use this version. Why would that be the case?
You are using the in-place form. With this, you have to update the values of
du
. In your script you are usingThat is replacing the name
du
with a new array, but not mutating the values in the originaldu
array. A quick fix would be to use the mutating equals:Notice that this is
.=
.To understand what this means in a more example based format, think about this. We have an array:
Now we point a new variable to that same array
When we change a value of
a
we see that reflected ina2
since they point to the same memory:But now if we replace
a
we notice nothing happens toa2
since they no longer refer to the same arrayPackages like DifferentialEquations.jl utilize mutating forms so that way users can get rid of array allocations by repeatedly changing the values in cached arrays. As a consequence these means that you should be updating the values of
du
and not replacing its pointer.If you feel more comfortable not using mutation, you can use the function syntax
f(u,p,t)
, although there will be a performance hit for doing so if the state variables are (non-static) arrays.