我正在尝试使用阶数为n
的高斯求积来计算双积分(在具有(0,0),(0,1),(1,0)的节点的三角形上)。但是,运行
import scipy.integrate as integrate
f = lambda x,y: x+y
inside = lambda x: integrate.fixed_quad(f, 0, 1-x, args=(x,), n=5)[0]
outside = integrate.fixed_quad(inside, 0, 1, n=5)
给出
追踪(最近一次通话): 文件"",第1行,in File" /Users/username/anaconda/lib/python3.5/site-packages/scipy/integrate/quadrature.py" ;,第82行,在fixed_quad中 return(b-a)/2.0 * np.sum(w * func(y,* args),axis = 0),None 文件"",第1行,in 文件" /Users/username/anaconda/lib/python3.5/site-packages/scipy/integrate/quadrature.py",第78行,在fixed_quad中 如果np.isinf(a)或np.isinf(b):
ValueError:具有多个元素的数组的真值是不明确的。使用a.any()或a.all()
这是问题Can scipy.integrate.fixed_quad compute integral with functional boundaries?的第二部分。
答案 0 :(得分:1)
在某些情况下,您的问题的答案是肯定的。
出于演示目的,我首先选择与您不同的界限(11
而不是1 - x
)。
通常,可以使用dblquad
来解决这些类型的积分:
area_dblquad = integrate.dblquad(lambda x, y: x + y, 0, 1, lambda x: 0, lambda x: 11)[0]
这里返回66
。这不是你在评论中提到的选项。
现在可以逐步进行此集成,它适用于quad
以及fixed_quad
:
def integrand(x, y):
return x + y
def fint_quad(x):
return integrate.quad(integrand, 0, 11, args=(x, ))[0]
def fint_fixed_quad(x):
return integrate.fixed_quad(integrand, 0, 11, args=(x, ), n=5)[0]
res_quad = integrate.quad(lambda x: fint_quad(x), 0, 1)
res_fixed_quad = integrate.fixed_quad(lambda x: fint_fixed_quad(x), 0, 1, n=5)
他们也按预期返回66
。这表明它可以使用scipy.integrate.fixed_quad
来计算双积分。
但是,如果现在将上限更改回您的上限(从11
到1 - x
),它仍可用于quad
,但会因fixed_quad
而崩溃:
area_dblquad = integrate.dblquad(lambda x, y: x + y, 0, 1, lambda x: 0, lambda x: 1 - x)[0]
res_quad = integrate.quad(lambda x: fint_quad(x), 0, 1)
返回0.333333...
,fixed_quad
的通话会导致您收到错误。通过查看源代码可以理解错误:
x, w = _cached_roots_legendre(n)
x = np.real(x)
if np.isinf(a) or np.isinf(b):
raise ValueError("Gaussian quadrature is only available for "
"finite limits.")
y = (b-a)*(x+1)/2.0 + a
return (b-a)/2.0 * np.sum(w*func(y, *args), axis=-1), None
当一个人打印a
和b
时,会得到:
a: 0
b: 1
a: 0
b: [ 0.95308992 0.76923466 0.5 0.23076534 0.04691008]
因此,对于使用1-x
的调用,b
实际上是一个带有n
元素的numpy数组,并且无法将数组与无穷大进行比较,这就是它崩溃的原因。无论是预期的行为还是错误,我无法回答;可能值得在github上打开一个问题。
答案 1 :(得分:0)
fixed_quad
要求f
接受矢量输入。结果应该是输入的映射值(即类似map(f, xs)
的值)。考虑到这一点,只需确保您的inside
函数返回映射的值,就可以使用了。
import scipy.integrate as integrate
f = lambda y,x: x+y
inside = lambda xs, n: np.array([integrate.fixed_quad(f, 0, 1-x, args=(x,), n=n)[0]
for x in np.array(xs)])
order = 5
outside = integrate.fixed_quad(inside, 0, 1, n=order, args=(order,))
此外,请注意被积数的参数顺序。从代码arg=(x,)
来看,您似乎希望沿着y维完成内部积分。被积数的第一个参数是其被积分的维度。因此应该改为lambda y,x
(请注意,这也是dblquad
期望的被积数的形状)。