24

如何以f(x)编程方式计算典型的导数以确保最大精度?

我正在实现Newton-Raphson方法,它需要对函数进行导数。

4

8 回答 8

64

我同意@erikkallen 的观点,这(f(x + h) - f(x - h)) / 2 * h是数值逼近导数的常用方法。然而,获得正确的步长 h 有点微妙。

( 中的近似误差f(x + h) - f(x - h)) / 2 * h随着h变小而减小,这表示您应该h尽可能小。但是随着h变小,浮点减法的误差会增加,因为分子需要减去几乎相等的数字。如果h太小,您可以松动减法的精度很高。因此在实践中,您必须选择一个不太小的值,h以最大限度地减少近似误差和数值误差的组合。

根据经验,您可以尝试机器精度中 最小的双精度数h = SQRT(DBL_EPSILON)在哪里。是关于所以你可以使用or 。DBL_EPSILONe1 + e != 1DBL_EPSILON10^-15h = 10^-710^-8

有关更多详细信息,请参阅有关为微分方程选择步长的这些说明。

于 2009-10-13T12:41:11.430 回答
11

Newton_Raphson 假设您可以有两个函数 f(x) 及其导数 f'(x)。如果您没有可用的导数作为函数并且必须从原始函数估计导数,那么您应该使用另一种求根算法。

维基百科根发现提供了一些建议,就像任何数值分析文本一样。

于 2009-10-13T12:01:50.070 回答
9

替代文字

替代文字

1)第一种情况:

替代文字

替代文字— 相对舍入误差,双精度约为 2^{-16},浮点约为 2^{-7}。

我们可以计算总误差:

替代文字

假设您正在使用双浮动操作。因此, h的最佳值为2sqrt(DBL_EPSILON/ f''(x) )。你不知道f''(x)。但是你必须估计这个值。例如,如果f''(x)约为 1,则h的最优值为2^{-7},但如果f''(x)约为 10^6,则h的最优值为2^{- 10}!

2)第二种情况:

替代文字

请注意,第二个近似误差趋于 0 比第一个快。但是如果 f'''(x) 非常滞后,那么第一个选项更可取:

替代文字

请注意,在第一种情况下,h 与 e 成正比,但在第二种情况下,h 与 e^{1/3} 成正比。对于双浮点运算,e^{1/3} 是 2^{-5} 或 2^{-6}。(我想 f'''(x) 大约是 1)。


哪种方式更好?如果你不知道 f''(x) 和 f'''(x) 或者你无法估计这些值,那是未知的。相信第二种选择更可取。但是,如果您知道 f'''(x) 非常大,请使用第一个。

h的最佳值是多少?假设 f''(x) 和 f'''(x) 大约为 1。还假设我们使用双浮点运算。那么在第一种情况下,h 约为 2^{-8},在第一种情况下,h 约为 2^{-5}。如果您知道 f''(x) 或 f'''(x),请更正此值。

于 2009-10-13T14:55:50.893 回答
6
fprime(x) = (f(x+dx) - f(x-dx)) / (2*dx)

对于一些小dx。

于 2009-10-13T11:48:38.757 回答
5

你对 f(x) 了解多少?如果您只有 f 作为黑盒,那么您唯一能做的就是对导数进行数值近似。但准确度通常不是那么好。

如果您可以触摸计算 f 的代码,您可以做得更好试试“自动微分”。有一些不错的库可用。借助一些库魔法,您可以轻松地将函数转换为自动计算导数的函数。有关简单的 C++ 示例,请参阅此德语讨论中的源代码。

于 2009-10-13T12:48:40.570 回答
5

您肯定要考虑约翰库克关于选择 h 的建议,但您通常不希望使用居中差异来近似导数。主要原因是它需要额外的函数评估,如果你使用前向差异,即

f'(x) = (f(x+h) - f(x))/h

然后您将免费获得 f(x) 的值,因为您需要已经为牛顿法计算它。当你有一个标量方程时,这没什么大不了的,但如果 x 是一个向量,那么 f'(x) 是一个矩阵(雅可比行列式),你需要做 n 个额外的函数评估来近似它使用中心差分法。

于 2009-10-14T01:10:15.940 回答
3

除了上面的 John D. Cooks 回答之外,重要的是不仅要考虑浮点精度,还要考虑函数 f(x) 的鲁棒性。例如,在金融领域,常见的情况是 f(x) 实际上是蒙特卡罗模拟,并且 f(x) 的值有一些噪音。在这些情况下,使用非常小的步长会严重降低导数的准确性。

于 2009-10-13T13:27:31.547 回答
1

通常,信号噪声对导数质量的影响大于其他任何因素。如果 f(x) 中确实存在噪声,Savtizky-Golay 是一种出色的平滑算法,通常用于计算良好的导数。简而言之,SG 将多项式局部拟合到您的数据,然后该多项式可用于计算导数。

保罗

于 2009-11-06T16:41:37.980 回答