Write a function with NumPy to calculate integral with a specific tolerance

六月ゝ 毕业季﹏ 提交于 2019-12-24 03:31:21

问题


I want to write a custom function to integrate an expression (python or lambda function) numerically with a specific tolerance. I know with scipy.integrate.quad one can simply change the epsabs but I want to write the function myself using numpy.

From this blogpost I know the function:

def integrate(f, a, b, N):
    x = np.linspace(a+(b-a)/(2*N), b-(b-a)/(2*N), N)
    fx = f(x)
    area = np.sum(fx)*(b-a)/N
    return area

gives me the numerical integration with N segments. How can I write another function or extend this to take a tol input and increase N until the difference between the two subsequent calculations is smaller than the given tolerance?


回答1:


Using the function you have, one can start with a reasonable N, for example 5, and keep doubling the number until the required precision is reached.

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        

A simple test:

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

prints

2.3504023872876028
2.3504023872876028

There is no guarantee that the error is indeed less than tol (but then again, scipy.quad does not guarantee that either). In practice, the error will be much smaller than tol, because of the trick I used, called Richardson extrapolation: the return value (4*new_integral - old_integral)/3 is in general much more accurate than either new or old approximations themselves. (Explanation: since integrate uses the midpoint rule, each doubling of N reduces the error by the factor of about 4. So, taking the combination 4*new_integral - old_integral nearly cancels out the residual error in both of those results.)

(Remark: in the while loop it's unadvisable to start with N=1; it probably will not be enough, and there's higher risk of stopping too early because of some numerical coincidence, e.g., the function being zero in a bunch of places.)



来源:https://stackoverflow.com/questions/50033275/write-a-function-with-numpy-to-calculate-integral-with-a-specific-tolerance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!