scipy.integrate.quad如何知道何时停止?

时间:2018-04-09 17:53:34

标签: python scipy numerical-integration

我有一段代码,我正在使用scipy.integrate.quad。积分的极限是无穷大到无穷大。它运行正常,但我希望它更快。

问题的本质是所集成的功能是三个功能的产物:(1)一个狭窄的功能(在零和(2)之间宽(在200,000和500,000之间),以及(3)一个下降为1 / abs(x)。

我只需要精确到.1%,如果那样的话。

我可以做很多工作,实际上确定了实数的积分限制,因此不会进行多余的计算;在函数1和2的区域之外它们都是零,因此1 / x甚至不会在那里发挥作用。但这将是一个容易出错的代码计算量。

  1. 这个函数如何知道如何优化,并且它具有无限的界限?

  2. 我可以通过传递指导(如容错)来调整它吗?

  3. 或者,尝试给它有限的集成界限是否值得?

1 个答案:

答案 0 :(得分:2)

quad对有限和无限区间使用不同的算法,但总体思路是相同的:使用两种相关方法(例如,7点高斯规则和15点Kronrod规则)计算积分,这些结果之间的差异可以估算出它们的准确程度。如果精度较低,则间隔被平分,并且子过程重复该过程。详细说明超出了Stack Overflow答案的范围;数值积分很复杂。

对于大型或无限积分边界,精度和效率取决于能够定位函数主要特征的算法。将边界作为-np.inf, np.inf传递是有风险的。例如,

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

返回错误的结果(基本上为零而不是1.77),因为它没有注意到高斯函数在20附近的碰撞。

另一方面,任意施加有限区间是值得怀疑的,因为你放弃了对错误的任何控制(没有估计你切断的无限尾部中包含的内容)。我建议如下:

  1. 将积分拆分为三个:(-np.inf, A)(A, B)(B, np.inf),其中,例如,A是-1e6,B是1e6。

  2. 对于(A, B)以上的积分,请提供points参数,该参数用于定位函数的要素(“窄部分”)。例如,

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

    应该返回1.77。

  3. 如果您发现默认准确度过高,请将epsabs(绝对误差)和epsrel(相对误差)调整到所需的精度范围内。