实现在C / C的衍生物++(Implementing the derivative in C/C+

2019-07-23 00:34发布

如何被一个的衍生物f(x)通常计算编程,以确保最大的精确度?

我执行牛顿-拉夫逊方法,它需要一个函数的导数的服用。

Answer 1:

我同意@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)其中DBL_EPSILON是最小的双精度数e ,使得1 + e != 1的加工精度。 DBL_EPSILON大约是10^-15 ,所以你可以使用h = 10^-710^-8

有关详细信息,请参阅这些笔记上采摘的步长微分方程。



Answer 2:

Newton_Raphson假定可以有两个函数f(x)和其导函数f'(x)的。 如果你没有可以作为一个函数导数和必须从原来的函数估计导数,那么你应该用另一根查找算法。

维基百科求根给出了一些建议,将任何数值分析文本。



Answer 3:

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)是非常lagre然后第一个选项是更优选的:

请注意,在第一种情况下,h是比例至E,但在第二种情况下,h是比例至E ^ {1/3}。 对于双浮动操作Ck ^ {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)的。



Answer 4:

fprime(x) = (f(x+dx) - f(x-dx)) / (2*dx)

对于一些小DX。



Answer 5:

你知道F(X)是什么? 如果你只是有f作为一个黑盒子,你唯一可以做的事情就是数值逼近衍生物。 但精度通常并不好。

你可以做更好,如果你可以触摸,计算F中的代码。 尝试“自动差异化” 。 有一些不错的图书馆为可用。 随着一点点库魔法,你可以轻松地转换功能的东西,会自动计算出衍生物。 对于一个简单的C ++示例,请参见在此源代码德语讨论。



Answer 6:

你一定要考虑到约翰库克的建议采摘小时,但你通常不希望使用中心差分来近似导数。 最主要的原因是,它的成本额外的功能评价,如果你使用一个前锋差,即

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

然后,因为你需要计算它已经为牛顿法,你会得到F(X)的自由的价值。 这不是什么大不了的,当你有一个标量方程,但如果x是一个向量,则f'(x)是一个矩阵(雅可比),你会需要做额外ň函数求近似它使用中心差分的方法。



Answer 7:

除了约翰·库克回答上面不仅要考虑到浮点精度,而且函数f(x)的稳健性是很重要的。 例如,在金融,它是F(X)实际上是一种蒙特卡罗仿真和f(x)的具有一定的噪声的值的常见的情况。 使用一个非常小的步长可在这些情况下,严重地降低衍生物的精度。



Answer 8:

通常,信号噪声影响的衍生品质更是其他任何东西。 如果你在你的F(X)的噪音,Savtizky - 格雷是一个常常被用来计算好衍生物优秀的平滑算法。 简而言之,SG适合本地的多项式您的数据,当时该多项式可用于计算的衍生物。

保罗



文章来源: Implementing the derivative in C/C++