Content #
# 不好的实现示例
def numerical_diff(f, x):
h = 10e-50
return (f(x+h) - f(x)) / h
这段代码有两处需要改进的地方。
- 舍入误差
h使用了10e-50(有50个连续的0的“0.00 … 1”)这个微小值。但是,这样产生了舍入误差(rounding error)。所谓舍入误差,是指因省略小数的精细部分的数值(比如,小数点第8位以后的数值)而造成最终的计算结果上的误差。比如,在Python中,舍入误差可如下表示:
>>> np.float32(1e-50)
0.0
如上所示,如果用float32类型(32位的浮点数)来表示1e-50,就会变成0.0,无法正确表示出来。也就是说,使用过小的值会造成计算机出现计算上的问题。这是第一个需要改进的地方,即将微小值h改为10-4。使用10-4就可以得到正确的结果。
- 中心差分
数值微分含有误差。为了减小这个误差,我们可以计算函数f在(x+h)和(x-h)之间的差分。因为这种计算方法以x为中心,计算它左右两边的差分,所以也称为中心差分(而(x+h)和x之间的差分称为前向差分)。
基于上述两个要改进的点来实现数值微分:
def numerical_diff(f, x):
h = 1e-4 # 0.0001
return (f(x+h) - f(x-h)) / (2*h)