使用DifferentialEquations:您未更新

时间:2018-09-29 23:05:12

标签: julia differentialequations.jl

我相信此代码中存在错误。为了简洁起见,我只编写定义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已正确更新。为什么会这样呢?

1 个答案:

答案 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),尽管如果状态变量是(非静态)数组,这样做会降低性能。