double MyClass::dx = ?????;
double MyClass::f(double x)
{
return 3.0*x*x*x - 2.0*x*x + x - 5.0;
}
double MyClass::fp(double x) // derivative of f(x), that is f'(x)
{
return (f(x + dx) - f(x)) / dx;
}
使用有限差分方法进行推导时,选择最佳dx
值至关重要。数学上,dx
必须尽可能小。但是,我不确定选择最小的正双精度数是否是正确的选择(即; 2.2250738585072014 x 10 -308 )。
是否有最佳数值区间或精确值来选择dx
以使计算错误尽可能小?
(我正在使用64位编译器。我将在Intel i5处理器上运行我的程序。)
答案 0 :(得分:3)
选择最小的可能值几乎肯定是错误的:如果dx
是最小的数字,那么由于四舍五入,f(x + dx)
等于f(x)
所以你有一个权衡:选择dx
太小,你会失去舍入错误的精确度。选择它太大,由于 x 更改导致的衍生变化,结果将不准确。
要判断数字错误,请以数学方式考虑(f(x + dx) - f(x))/f(x)
1 。分子表示您想要计算的差异,但分母表示您正在处理的数字的大小。如果该分数大约为2 - k ,那么您可以在结果中获得大约 k 位的精度。
如果您了解自己的功能,则可以计算出选择dx
过大会导致的错误。然后,您可以使用balence事物,因此由此引起的错误与舍入产生的错误大致相同。但是如果你知道这个函数,那么通过提供一个直接计算导数的函数可能会更好,就像在你的例子中使用多边形f
一样。
pogorskiy Wikipedia section pointed out建议使用sqrt(ε) x 或大约1.5e-8 * x
的值。如果没有关于功能的更详细的知识,这样的经验法则将提供合理的默认值。另请注意,相同的部分建议不要除dx
,而是(x + dx) - x
,因为这会将计算x + dx
时产生的舍入错误考虑在内。但我想整篇文章都充满了你可能会使用的建议。
1 这个公式确实应该除以f(x)
,而不是dx
,即使过去的编辑也有不同的看法。我试图比较除法后剩余的有效位数,而不是切线的斜率。
答案 1 :(得分:-1)
为什么不使用权力规则来推导衍生品,你会得到一个确切的答案:
f(x) = 3x^3 - 2x^2 + x - 5
f'(x) = 9x^2 - 4x + 1
因此:
f(x) = 3.0 * x * x * x - 2.0 * x * x + x - 5.0
fp(x) = 9.0 * x * x - 4.0 * x + 1.0