如何以f(x)
编程方式计算典型的导数以确保最大精度?
我正在实现Newton-Raphson方法,它需要对函数进行导数。
如何以f(x)
编程方式计算典型的导数以确保最大精度?
我正在实现Newton-Raphson方法,它需要对函数进行导数。
我同意@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_EPSILON
e
1 + e != 1
DBL_EPSILON
10^-15
h = 10^-7
10^-8
有关更多详细信息,请参阅有关为微分方程选择步长的这些说明。
Newton_Raphson 假设您可以有两个函数 f(x) 及其导数 f'(x)。如果您没有可用的导数作为函数并且必须从原始函数估计导数,那么您应该使用另一种求根算法。
维基百科根发现提供了一些建议,就像任何数值分析文本一样。
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),请更正此值。
fprime(x) = (f(x+dx) - f(x-dx)) / (2*dx)
对于一些小dx。
您肯定要考虑约翰库克关于选择 h 的建议,但您通常不希望使用居中差异来近似导数。主要原因是它需要额外的函数评估,如果你使用前向差异,即
f'(x) = (f(x+h) - f(x))/h
然后您将免费获得 f(x) 的值,因为您需要已经为牛顿法计算它。当你有一个标量方程时,这没什么大不了的,但如果 x 是一个向量,那么 f'(x) 是一个矩阵(雅可比行列式),你需要做 n 个额外的函数评估来近似它使用中心差分法。
除了上面的 John D. Cooks 回答之外,重要的是不仅要考虑浮点精度,还要考虑函数 f(x) 的鲁棒性。例如,在金融领域,常见的情况是 f(x) 实际上是蒙特卡罗模拟,并且 f(x) 的值有一些噪音。在这些情况下,使用非常小的步长会严重降低导数的准确性。
通常,信号噪声对导数质量的影响大于其他任何因素。如果 f(x) 中确实存在噪声,Savtizky-Golay 是一种出色的平滑算法,通常用于计算良好的导数。简而言之,SG 将多项式局部拟合到您的数据,然后该多项式可用于计算导数。
保罗