如何在Julia中快速求解多项式方程?

如何在Julia中快速求解多项式方程?,julia,differential-equations,polynomial-math,Julia,Differential Equations,Polynomial Math,我在研究生物系统的进化模拟。我必须解多项式方程,找到根(u*X^3-N*p*r*X^2-N*p*X^2+K^2*u*X-N*K^2*p),其中u和K是常数,N是常数数组,p,r是演化参数。基本上,对于每一代人口中的每个个体,我需要进行以下计算(长度(N)>>长度(p)): 我知道我可以通过使用不同的核来求解不同个体的方程来并行代码,甚至在每个个体内,我可以并行求解每个X[j,I]。我想知道处理这种情况的最佳实践/快速方法是什么?有可能以更快的方式解一个方程吗 这个答案比较了根、GSL和多项式根解

我在研究生物系统的进化模拟。我必须解多项式方程,找到根(u*X^3-N*p*r*X^2-N*p*X^2+K^2*u*X-N*K^2*p),其中u和K是常数,N是常数数组,p,r是演化参数。基本上,对于每一代人口中的每个个体,我需要进行以下计算(长度(N)>>长度(p)):


我知道我可以通过使用不同的核来求解不同个体的方程来并行代码,甚至在每个个体内,我可以并行求解每个X[j,I]。我想知道处理这种情况的最佳实践/快速方法是什么?有可能以更快的方式解一个方程吗

这个答案比较了
GSL
多项式根
解决问题版本的软件包。机器上的计时可能不同,最好在本地运行。但本质上,
GSL
是最快的,大约比
根快1000倍,其中
多项式根介于两者之间(但更接近
GSL
)。有关更多信息,请参见注释

守则:

# using Julia 0.5.1-pre+4
# Pkg.add("Roots")
# Pkg.add("GSL")
# Pkg.add("PolynomialRoots")

using GSL
using Roots
using PolynomialRoots

function test1(p,r,N,u,K)
  X = Matrix{Float64}(length(N),length(p))
  for i = 1:length(p)
    for j = 1:length(N)
      X[j,i] = mean(fzeros(S -> u*S^3 - p[i]*N[j]*r[i]*S^2 - p[i]*N[j]*S^2 + K^2*u*S - p[i]*K^2*N[j], 0, Inf) )
    end
  end
  return X
end

function test2(p,r,N,u,K)
  X = Matrix{Float64}(length(N),length(p))
  uinv = inv(u)
  for i = 1:length(p)
    for j = 1:length(N)
      X[j,i] = mean(poly_solve_cubic(-uinv*(p[i]*N[j]*r[i]+p[i]*N[j]),K^2,-uinv*p[i]*K^2*N[j]) )
    end
  end
  return X
end

function test3(p,r,N,u,K)
  X = Matrix{Float64}(length(N),length(p))
  for i = 1:length(p)
    for j = 1:length(N)
      X[j,i] = mean(filter(x->abs(imag(x))<1.0e-10,
        PolynomialRoots.solve_cubic_eq(Complex{Float64}[- p[i]*K^2*N[j], K^2*u, - p[i]*N[j]*r[i] - p[i]*N[j],u])))
    end
  end
  return X
end

K = 1.0
u = 1.0
N = rand(1000)+1.0
p = rand(10)+1.0
r = rand(10)+1.0

res1 = test1(p,r,N,u,K);
res2 = test2(p,r,N,u,K);
res3 = test3(p,r,N,u,K);

using Base.Test
@test_approx_eq res1 res2
@test_approx_eq res1 res3

@time test1(p,r,N,u,K); # Roots
@time test2(p,r,N,u,K); # GSL
@time test3(p,r,N,u,K); # PolynomialRoots

nothing

如果你比较一下这些方法,你会很高兴听到关于实际问题时间安排的报告。谢谢。

我怀疑这个问题的答案不是朱莉娅的;熟悉该领域的人可能会向您指出特定的算法及其实现。如果您想要所有根(包括复数根),则可以通过这种方式使用
fzeros
fzeros(f,a,b)
(非常慢。(该算法非常简单,并且依赖于二分法,它比其他算法使用更多的迭代次数。)改用
多项式根
包甚至可以提供更快的解决方案。这与微分方程有什么关系?我需要解的方程实际上是一个微分方程,但我需要的是平衡点dX/dt=0,所以基本上是找到多项式方程的根n、 @jverzani谢谢。我想知道获得实根的最快方法是什么?似乎
roots
给出了所有实根和复根。毫不奇怪roots这么慢,其他两种方法都是针对立方体的,roots实现是针对任何标量函数的,但我很惊讶GSL比Polynom快得多i根,因为这两个都是针对问题量身定制的。一定是由于在多项式根中进行了复杂的运算。K=50.0 u=1e-4 N=collect(linspace(10.^1.5,10.^5,100))p=[5e-9;5e-9]r=[5;[5.]5.]根:0.536053秒(4.84 M分配:297.875 MB,17.26%gc时间)GSL:0.000087秒(1.61 K分配:83.422 KB)多项式根不起作用。无论如何,GSL比根快6000x+。
# using Julia 0.5.1-pre+4
# Pkg.add("Roots")
# Pkg.add("GSL")
# Pkg.add("PolynomialRoots")

using GSL
using Roots
using PolynomialRoots

function test1(p,r,N,u,K)
  X = Matrix{Float64}(length(N),length(p))
  for i = 1:length(p)
    for j = 1:length(N)
      X[j,i] = mean(fzeros(S -> u*S^3 - p[i]*N[j]*r[i]*S^2 - p[i]*N[j]*S^2 + K^2*u*S - p[i]*K^2*N[j], 0, Inf) )
    end
  end
  return X
end

function test2(p,r,N,u,K)
  X = Matrix{Float64}(length(N),length(p))
  uinv = inv(u)
  for i = 1:length(p)
    for j = 1:length(N)
      X[j,i] = mean(poly_solve_cubic(-uinv*(p[i]*N[j]*r[i]+p[i]*N[j]),K^2,-uinv*p[i]*K^2*N[j]) )
    end
  end
  return X
end

function test3(p,r,N,u,K)
  X = Matrix{Float64}(length(N),length(p))
  for i = 1:length(p)
    for j = 1:length(N)
      X[j,i] = mean(filter(x->abs(imag(x))<1.0e-10,
        PolynomialRoots.solve_cubic_eq(Complex{Float64}[- p[i]*K^2*N[j], K^2*u, - p[i]*N[j]*r[i] - p[i]*N[j],u])))
    end
  end
  return X
end

K = 1.0
u = 1.0
N = rand(1000)+1.0
p = rand(10)+1.0
r = rand(10)+1.0

res1 = test1(p,r,N,u,K);
res2 = test2(p,r,N,u,K);
res3 = test3(p,r,N,u,K);

using Base.Test
@test_approx_eq res1 res2
@test_approx_eq res1 res3

@time test1(p,r,N,u,K); # Roots
@time test2(p,r,N,u,K); # GSL
@time test3(p,r,N,u,K); # PolynomialRoots

nothing
 20.664363 seconds (225.67 M allocations: 13.650 GB, 18.81% gc time) # Roots
  0.010303 seconds (80.01 k allocations: 4.044 MB, 75.30% gc time) # GSL
  0.215453 seconds (394.90 k allocations: 9.917 MB) # PolynomialRoots