【问题标题】:Scipy using PyCall in JuliaScipy 在 Julia 中使用 PyCall
【发布时间】:2017-04-14 09:12:43
【问题描述】:

我有一个中等规模的非线性方程组,我想在 Julia 中使用 scipy.optimize 来求解。问题是我在将方程传递给求解器之前将它们存储在向量中,而 PyCall 不接受这一点。例如,这些方法都有效:

using PyCall
@pyimport scipy.optimize as so

function F(x)
 f1=1- x[1] - x[2]
 f2=8 - x[1] - 3*x[2]
 return f1, f2
end

x0 = [1,1]
x = so.fsolve(F, x0)

function G(x)
 f=[1 - x[1] - x[2],
    8 - x[1] - 3*x[2]]
 return f
end

x0 = [1,1]
x = so.fsolve(G, x0)

但事实并非如此:

function H(x)
 f[1]=1 - x[1] - x[2]
 f[2]=8 - x[1] - 3*x[2]
 return f
end

x0 = [1,1]
x = so.fsolve(H, x0)

这个也不行:

function P(x)
 f[1]= 1 - x[1] - x[2]
 f[2]= 8 - x[1] - 3*x[2]
 return f[1], f[2]
end

x0 = [1,1]
x = so.fsolve(P, x0)

由于问题的性质,我认为不使用循环是不可行的。有没有办法以 fsolve 可以接受的方式返回向量?

【问题讨论】:

    标签: python scipy julia


    【解决方案1】:

    后两种方法永远不会创建f,这是问题所在。你必须先创建数组。

    function H(x)
     f = similar(x)
     f[1]=1 - x[1] - x[2]
     f[2]=8 - x[1] - 3*x[2]
     return f
    end
    

    会自动匹配x的大小和类型,也可以使用构造函数:

    function H(x)
     f = Vector{Float64}(2)
     f[1]=1 - x[1] - x[2]
     f[2]=8 - x[1] - 3*x[2]
     return f
    end
    

    无论你想做什么,你都需要制作数组。 P 有同样的问题。

    另外,您应该查看 NLSolve.jl。它允许预先分配的表格:

    function H(x,f)
     f[1]=1 - x[1] - x[2]
     f[2]=8 - x[1] - 3*x[2]
     return nothing
    end
    

    应该分配更少并且做得更好。 Roots.jl 是另一个不错的 Julia 选项。

    【讨论】:

    • 非常感谢!我确实尝试了 NLSolve,但我不确定为什么必须在 H(x,f) 中包含 f 向量。现在很清楚了。我在使用 NLSolve 时遇到的问题是,即使我给出了从 Matlab 获得的解作为初始猜测,它也没有收敛。
    • 我会就此提出另一个问题。我怀疑你的代码有错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-25
    • 2017-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多