求解Julia中n阶多项式根的通用函数

时间:2014-03-23 08:43:20

标签: julia

全部,

我刚开始玩朱莉娅语并且很享受它。在第3个教程结束时,有一个有趣的问题:对二次公式进行泛化,使其解决任何n-order polynomial equation的根。

这让我感到震惊,因为(a)一个有趣的编程问题和(b)一个有趣的Julia问题。谁有人解决了这个?作为参考,这里是带有几个玩具示例的Julia代码。同样,这个想法是为任何n阶多项式制作这个通用的。

干杯,

亚伦

function derivative(f)
    return function(x)
        # pick a small value for h
        h = x == 0 ? sqrt(eps(Float64)) : sqrt(eps(Float64)) * x

        # floating point arithmetic gymnastics
        xph = x + h
        dx = xph - x

        # evaluate f at x + h
        f1 = f(xph)

        # evaluate f at x
        f0 = f(x)

        # divide the difference by h
        return (f1 - f0) / dx
    end
end


function quadratic(f)

    f1 = derivative(f)

    c = f(0.0)

    b = f1(0.0)

    a = f(1.0) - b - c

    return (-b + sqrt(b^2 - 4a*c + 0im))/2a, (-b - sqrt(b^2 - 4a*c + 0im))/2a
end

quadratic((x) -> x^2 - x - 2)
quadratic((x) -> x^2 + 2)

2 个答案:

答案 0 :(得分:3)

PolynomialRoots.jl提供函数roots()以查找任何顺序的多项式的所有(实数和复数)根。唯一的强制参数是具有多项式系数的数组,按升序排列。

例如,为了找到

的根
6x^5 + 5x^4 + 3x^2 + 2x + 1

加载包(using PolynomialRoots)后,您可以使用

julia> roots([1, 2, 3, 4, 5, 6])
5-element Array{Complex{Float64},1}:
           0.294195-0.668367im
 -0.670332+2.77556e-17im
           0.294195+0.668367im
          -0.375695-0.570175im
          -0.375695+0.570175im

该软件包是本文所述的根查找算法的Julia实现:http://arxiv.org/abs/1203.1034

PolynomialRoots.jl也支持任意精度计算。这对于求解无法以双精度求解的方程非常有用。例如

julia> r = roots([94906268.375, -189812534, 94906265.625]);

julia> (r[1], r[2])
(1.0000000144879793 - 0.0im,1.0000000144879788 + 0.0im)

给出了多项式的错误结果,而是以任意精度传递输入数组,强制任意精度计算,提供正确的答案(参见https://en.wikipedia.org/wiki/Loss_of_significance):

julia> r = roots([BigFloat(94906268.375), BigFloat(-189812534), BigFloat(94906265.625)]);

julia> (Float64(r[1]), Float64(r[2]))
(1.0000000289759583,1.0)

答案 1 :(得分:0)

对于五度及以上的一般多项式,没有代数公式(实际上不能是see here)。所以从理论上讲,你可以继续使用相同的方法来解决立方体和四次方的问题,但即使这样做也会给很多艰苦的工作提供非常笨重的四分法根。您还可以使用SymPy之类的CAS来查找这些公式。