使用您拥有的函数,可以从一个合理的N开始,例如5,并将数字加倍,直到达到所需的精度。
def integrate_tol(f, a, b, tol):
N = 5
old_integral = integrate(f, a, b, N)
while True:
N *= 2
new_integral = integrate(f, a, b, N)
if np.abs(old_integral - new_integral) < tol:
return (4*new_integral - old_integral)/3
old_integral = new_integral
一个简单的测试:
f = lambda x: np.exp(x)
print(integrate_tol(f, -1, 1, 1e-9))
print(np.exp(1)-np.exp(-1)) # exact value for comparison
打印
2.3504023872876028
2.3504023872876028
不能保证误差确实小于tol
(但是,scipy.quad
也无法保证)。实际上,由于我使用了称为Richardson外推的技巧,因此误差将远小于tol:返回值(4*new_integral - old_integral)/3
通常比新旧逼近本身更准确。 (解释:由于integrate
使用中点规则,N加倍会将误差减少约4倍。因此,取组合4*new_integral - old_integral
几乎会消除这些结果中的残余误差。)
(备注:在while循环中,从N = 1开始不可取;它可能不够用,并且由于某些数值巧合,例如函数在一堆地方为零,停止太早的风险更高。)
erf
在这里毫无意义。 - user6655984