我正在使用quad
中的scipy.integrate v0.19.1
函数在积分区间的每一端将函数与平方根(如奇点)集成,例如
In [1]: quad(lambda x: 1/sqrt(1-x**2), -1, 1)
(我使用sqrt
中的numpy v1.12.0
函数),它立即产生正确的结果pi:
Out[1]: (3.141592653589591, 6.200897573194197e-10)
根据quad
函数的文档,关键字points
应该用于指示被积函数的奇点或不连续点的位置,但如果我指出点[1, -1]
,那么以上积分是单数我得到警告并nan
结果:
In [2]: quad(lambda x: 1/sqrt(1-x**2), -1, 1, points=[-1, 1])
RuntimeWarning: divide by zero encountered in double_scalars
IntegrationWarning: Extremely bad integrand behavior occurs at some
points of the integration interval.
Out[2]: (nan, nan)
有人可以澄清一下,如果指定了被积函数的奇点,为什么quad
会产生这些问题,如果没有指出这些点,那么运行正常?
修改 我想我找到了解决这个问题的正确方法。对于其他人遇到类似问题的情况,我很快就想分享我的发现:
我想要将f(x)*g(x)
形式的函数与平滑函数f(x)
和g(x) = (x-a)**alpha * (b-x)**beta
集成,其中a
和b
是整合限制和g(x)
在alpha, beta < 0
时具有这些限制的奇点,那么您应该使用f(x)
作为加权函数集成g(x)
。对于quad
例程,可以使用weight
和wvar
参数。通过这些论证,您还可以处理不同种类的奇点和有问题的振荡行为。通过设置g(x)
并使用weight='alg'
指定wvar=(alpha, beta)
中的指数,可以使用上面定义的加权函数g(x)
。
由于1/sqrt(1-x**2) = (x+1)**(-1/2) * (1-x)**(-1/2)
我现在可以按如下方式处理积分:
In [1]: quad(lambda x: 1, -1, 1, weight='alg', wvar=(-1/2, -1/2))
Out[1]: (3.1415926535897927, 9.860180640534107e-14)
能够以非常高的准确度产生正确的答案pi
,无论我是否使用参数points=(-1, 1)
(据我现在理解,只应该使用,如果选择合适的加权函数不能处理奇点/不连续性。
答案 0 :(得分:1)
参数points
适用于在积分区间内出现的奇点/不连续性。它不适用于间隔的端点。因此,在您的示例中,没有points
的版本是正确的方法。 (我无法确定在points
中包含端点时出现的问题,而不会深入了解SciPy包含的FORTRAN代码。)
与以下示例比较,其中在积分区间内出现奇点:
>>> quad(lambda x: 1/sqrt(abs(1-x**2)), -2, 2)
(inf, inf)
>>> quad(lambda x: 1/sqrt(abs(1-x**2)), -2, 2, points = [-1, 1])
(5.775508447436837, 7.264979728915932e-10)
这里包含points
是合适的,并产生正确的结果,而没有points
输出是没有价值的。