我相信此代码中存在错误。为了简洁起见,我只编写定义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
如果需要完整的代码,我可以提供它,但是它很凌乱,我不确定如何创建一个最小的示例。我在Nmut = 2时尝试过此操作,因此可以与硬编码版本进行比较。第一步的du输出是相同的。但是此版本似乎从未更新过,而是保持在规定的u0上。
有人知道为什么会这样吗?我还可以提供完整的脚本,但是想避免有人看到您为什么不更新的情况。
编辑:
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
如果使用此版本,则du已正确更新。为什么会这样呢?
答案 0 :(得分:1)
您正在使用就地表单。这样,您必须更新du
的值。在您的脚本中,您正在使用
du = ufQ .- phi*u
这将用新数组替换名称du
,但不会更改原始du
数组中的值。一种快速的解决方法是使用变异等式:
du .= ufQ .- phi*u
请注意,这是.=
。
要了解基于示例的格式的含义,请考虑一下。我们有一个数组:
a = [1,2,3,4]
现在我们将新变量指向相同的数组
a2 = a
当我们更改值a
时,我们会看到a2
反映了这一点,因为它们指向相同的内存:
a[1] = 5
println(a2) # [5,2,3,4]
但是现在,如果我们替换a
,我们会发现a2
不会发生任何变化,因为它们不再引用同一数组
a = [1,2,3,4]
println(a2) # [5,2,3,4]
像DifferentialEquations.jl这样的软件包利用了变异形式,因此用户可以通过重复更改缓存数组中的值来摆脱数组分配。因此,这意味着您应该更新du
的值,而不要替换其指针。
如果您不使用突变会更舒适,则可以使用函数语法f(u,p,t)
,尽管如果状态变量是(非静态)数组,这样做会降低性能。