在有限差分方法中使用的最佳epsilon / dx值是多少?

时间:2012-11-17 11:28:09

标签: c++ double-precision derivative epsilon

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处理器上运行我的程序。)

2 个答案:

答案 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