Julia 使用微分方程:u未更新

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

我相信这段代码中有一个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=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),修复确实有效