【发布时间】:2015-06-11 11:38:20
【问题描述】:
我正在用牛顿法求解一维非线性方程。我试图弄清楚为什么牛顿方法的一种实现精确地收敛在浮点精度内,而另一种则没有。
以下算法不收敛:
而以下确实收敛:
您可以假设函数 f 和 f' 是平滑且表现良好的。我能想到的最好的解释是,这在某种程度上与所谓的迭代改进有关(Golub 和 Van Loan,1989 年)。任何进一步的见解将不胜感激!
这是一个简单的 Python 示例来说明问题
# Python
def f(x):
return x*x-2.
def fp(x):
return 2.*x
xprev = 0.
# converges
x = 1. # guess
while x != xprev:
xprev = x
x = (x*fp(x)-f(x))/fp(x)
print(x)
# does not converge
x = 1. # guess
while x != xprev:
xprev = x
dx = -f(x)/fp(x)
x = x + dx
print(x)
注意:我知道浮点数的工作原理(请不要将您最喜欢的链接发布到告诉我永远不要比较两个浮点数的网站)。另外,我不是在寻找问题的解决方案,而是想解释为什么其中一种算法收敛而另一种不收敛。
更新:
正如@uhoh 指出的那样,在很多情况下第二种方法不会收敛。但是,我仍然不知道为什么第二种方法在我的现实世界场景中比第一种更容易收敛。所有的测试用例都有非常简单的函数f,而现实世界的f 有几百行代码(这就是我不想发布的原因)。所以也许f 的复杂性很重要。如果您对此有任何其他见解,请告诉我!
【问题讨论】:
-
你什么时候在第一个算法中分配
Xprev?如果是在评估dx之前,那么在代数上两者是相同的。也许非常小的f'(x)会溢出? -
错字。现已更正。
-
f'(x)通常为 ~1,x为 ~0.1。所以我认为不会在任何地方发生溢出。 -
从代数上讲,您的两个公式是相同的,因此要么实现中存在错误,要么您永远不会完全获得相同的浮点数。通常,您通过将两个浮点数的差异与一个非常小数进行比较来比较它们。
-
是的,通常我会将它与一个非常小的数字进行比较,这很好。但是,我仍然对为什么第二种算法完全收敛感到困惑(对于许多具有不同初始
x和f的不同运行,即它不是一组特定数字取消的巧合)。
标签: python math floating-point newtons-method