Python数值微分和h的最小值

时间:2019-03-16 18:33:37

标签: python numerical-methods

我使用以下代码计算一阶导数:

enter code here

例如,对于def f(x): f = np.exp(x) return f def dfdx(x): Df = (f(x+h)-f(x-h)) / (2*h) return Df ,它可以正常工作。但是,当我将x == 10设置为h或以下时,10E-14开始 以获得与期望值Df确实相距甚远的值,并且期望值与f(10)之间的相对误差变得很大。

那是为什么?这是怎么回事?

4 个答案:

答案 0 :(得分:3)

f(x)的评估最多具有|f(x)|*mu的舍入误差,其中mu是浮点类型的机器常数。因此,中心差公式的总误差约为

2*|f(x)|*mu/(2*h)  +  |f'''(x)|/6 * h^2

在当前情况下,指数函数等于其所有导数,因此误差与

成比例
mu/h + h^2/6

的最小值为h = (3*mu)^(1/3),对于带有mu=1e-16的双精度格式,最小值为h=1e-5

如果在分母中使用评估点之间的实际差值2*h代替(x+h)-(x-h),则会提高精度。在下面到精确导数的距离的对数图中可以看到这一点。

enter image description here

答案 1 :(得分:2)

您可能会遇到一些数值不稳定的情况,例如对于x = 10和h =〜1E-13,无论加还是减去h,np.exp的参数都非常接近10,因此的近似误差很小np.exp通过除以2 * h的小数来显着缩放。

答案 2 :(得分:2)

除了@LutzL的答案之外,我还将在5.7章的出色著作Numerical Recipes 3rd Edition: The Art of Scientific Computing中添加一些有关数值导数的信息,尤其是关于给定h的最佳x

  • 始终选择h,以使hx相差一个可精确表示的数字。除非1/3等于x的东西,否则应避免使用诸如14.3333333之类的有趣东西。
  • 舍入误差约为epsilon * |f(x) * h|,其中epsilon为浮点精度,Python表示浮点数具有双精度,因此为1e-16。对于更复杂的功能(可能会进一步导致精度错误),它可能会有所不同,尽管情况并非如此。
  • 选择最佳的h:如果您的sqrt(epsilon) * x接近零(除非您在书中会找到更多信息),否则不作任何详细介绍就简单的正向情况而言x ,这是您的情况。在这种情况下,您可能希望使用更高的x值,已经提供了补充答案。在您的示例中,f(x+h) - f(x-h)等于epsilon ** 1/3 * x,大约是5e-6x的情况下,对于较小的值(例如,你的。不过,与@LutzL发布的实际结果相当接近(如果可以这样说的话,请记住浮点运算...)。
  • 除了使用symmetric以外,您还可以使用其他派生公式。您可能需要使用forwardbackward评估(如果函数的评估成本很高,并且您已经预先计算了f(x)。如果函数的评估成本很低,则可能需要评估多次使用高阶方法来减小精度误差(请参见问题注释中的five-point stencil on wikipedia)。

答案 3 :(得分:0)

Python tutorial解释了精度受限的原因。总之,小数最终以二进制表示,精度约为17个有效数字。因此,在10E-14之后它变得模糊是正确的。