在 python 中实施 Laugerre 的方法

Implementing Laugerre's method in python

我正在编写一个 python 数学模块,我已经尝试创建一个基本实现 拉盖尔方法,不使用外部库,如 numpy 或 scipy.

拉盖尔法是一种求多项式根(即:与 x 轴的交点)的算法,在 维基百科:https://en.wikipedia.org/wiki/Laguerre%27s_method

这是我想出的:

def laguerre_method(f_0: Callable, f_1: Callable, f_2: Callable, x0: float, n: float, epsilon: float = 0.00001):
    xk = x0
    while abs(f_0(xk)) > epsilon:
        G = f_1(xk) / f_0(xk)
        H = G ** 2 - f_2(xk) / f_0(xk)
        root = cmath.sqrt((n - 1) * (n * H - G ** 2))
        d = max(abs(G + root), abs(G - root))
        a = n / d
        xk -= a
    return xk

f_0是原函数,f_1是它的导数,f_2是二阶导数。
x0 是我们开始的猜测。
Epsilon 表示点的 y 值应接近 0 的程度,才能被视为根。

n表示多项式的次方,即x^3 + 3x + 5的次方为3。

出于某种原因,当初始值 ( x0 ) 为正时,即使是小的负数,该方法也能按预期工作,但如果负值较大,则失败,显示数学域错误或 OverflowError: (34, 'Result too large') 或 ZeroDivisionError: 浮点除以零

例如,让我们用 lambdas 定义一个函数、它的导数和它的二阶导数:

 f_0 = lambda n: 2 * n ** 3 - 5 * n ** 2 - 23 * n - 10
 f_1 = lambda n: 6 * n ** 2 - 10 * n - 23
 f_2 = lambda n: 12 * n - 10

代码适用于这些输入:

print(laguerre_method(f_0, f_1, f_2, 6, 3))
print(laguerre_method(f_0, f_1, f_2, -1, 3))

并分别输出大约5.0和-2.0,也就是对应的根

然而,输入失败,例如:

print(laguerre_method(f_0, f_1, f_2, -7, 3))

算法在维基百科中有详细介绍。

请记住,这不是最终的实现,我知道我可能犯了一个愚蠢的错误,所以请期待我的愚蠢。

这一行:

d = max(abs(G + root), abs(G - root))

应该是:

d = max([G + root, G - root], key=abs)