在 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)
我正在编写一个 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)