Julia 使用微分方程:u未更新
我相信这段代码中有一个bug。为了简洁起见,我将只编写定义ODE的函数Julia 使用微分方程:u未更新,julia,differentialequations.jl,Julia,Differentialequations.jl,我相信这段代码中有一个bug。为了简洁起见,我将只编写定义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
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输出相同。但是这个版本似乎从来没有更新过u,它保持在规定的u0
有人知道为什么会这样吗?我也可以提供完整的脚本,但如果有人能看到你为什么不更新,我想避免这种情况
编辑:
如果使用此版本,du将正确更新。为什么会出现这种情况?您使用的是就地表单。这样,您就必须更新
du
的值。在您使用的脚本中
du = ufQ .- phi*u
这就是用新数组替换名称du
,但不改变原始du
数组中的值。一个快速解决方法是使用变异等式:
du .= ufQ .- phi*u
请注意,这是=
要以更基于示例的格式理解这意味着什么,请考虑以下内容。我们有一个阵列:
a = [1,2,3,4]
现在,我们将一个新变量指向同一数组
a2 = a
a = [1,2,3,4]
println(a2) # [5,2,3,4]
当我们更改a
的值时,我们会看到反映在a2
中的值,因为它们指向相同的内存:
a[1] = 5
println(a2) # [5,2,3,4]
但是现在如果我们替换a
我们注意到a2
没有任何变化,因为它们不再引用相同的数组
a2 = a
a = [1,2,3,4]
println(a2) # [5,2,3,4]
像Differentialsequations.jl这样的包利用了变异形式,这样用户就可以通过反复更改缓存数组中的值来摆脱数组分配。因此,这意味着您应该更新du
的值,而不是替换其指针
如果您觉得不使用变异更合适,您可以使用函数语法
f(u,p,t)
,尽管如果状态变量是(非静态)数组,那么这样做会影响性能。这非常有用,谢谢!我已经做了编辑,其中包括硬编码版本。你能解释一下为什么这个新设置中的du没有相同的问题吗?我尝试了du.=但每次它仍然返回相同的向量du。请记下。显然,如果我删除线du=0(Nclones),修复确实有效