How does scipy.integrate.quad know when to stop?

元气小坏坏 提交于 2020-01-04 19:07:31

问题


I have a piece of code that I am using scipy.integrate.quad. The limits of integration are minus infinity to infinity. It runs OK, but I would like it faster.

The nature of the problem is that the function being integrated is the product of three functions: (1) one that is narrow (between zero and (2) one that is wide (between, say, 200,000 and 500,000), and (3) one that falls off as 1/abs(x).

I only need accuracy to .1%, if that.

I could do a lot of work and actually determine integration limits that are real numbers so no excess computation gets done; outside the regions of functions 1 and 2 they are both zero, so the 1/x doesn't even come into play there. But it would be a fair amount of error-prone code calculations.

  1. How does this function know how to optimize, and is it pretty good at it, with infinite bounds?

  2. Can I tune it through passing in guidance (like error tolerance)?

  3. Or, would it be worthwhile to try to give it limited integration bounds?


回答1:


quad uses different algorithms for finite and infinite intervals, but the general idea is the same: the integral is computed using two related methods (for example, 7-point Gauss rule and 15-point Kronrod rule), and the difference between those results provides an estimate for how accurate they are. If the accuracy is low, the interval is bisected and the process repeats for subintervals. A detailed explanation is beyond the scope of a Stack Overflow answer; numerical integration is complicated.

For large or infinite integration bounds, the accuracy and efficiency depend on the algorithm being able to locate the main features of the function. Passing the bounds as -np.inf, np.inf is risky. For example,

quad(lambda x: np.exp(-(x-20)**2), -np.inf, np.inf)

returns a wrong result (essentially zero instead of 1.77) because it does not notice the bump of the Gaussian function near 20.

On the other hand, arbitrarily imposing a finite interval is questionable in that you give up any control over error (no estimate on what was contained in the infinite tails that you cut off). I suggest the following:

  1. Split the integral into three: (-np.inf, A), (A, B), and (B, np.inf) where, say, A is -1e6 and B is 1e6.

  2. For the integral over (A, B), provide points parameter, which locates the features ("narrow parts") of the function. For example,

    quad(lambda x: np.exp(-(x-20)**2), -1e6, 1e6, points=[10, 30])
    

    returns 1.77 as it should.

  3. Adjust epsabs (absolute error) and epsrel (relative error) to within desired accuracy, if you find that the default accuracy is too demanding.



来源:https://stackoverflow.com/questions/49738870/how-does-scipy-integrate-quad-know-when-to-stop

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