我正在尝试将一个函数集成到一个点列表上,并将整个数组传递给一个集成函数,以便对该事物进行矢量化。对于初学者来说,调用scipy.integrate.quad太慢了,因为我有类似10 000 000点积分的东西。使用scipy.integrate.romberg可以更快,几乎是瞬间完成技巧,而四边形很慢,因为你必须循环它或向量化它。
我的功能非常复杂,但为了演示目的,假设我想将x ^ 2从a集成到b,但x是一个用于评估x的标量数组。例如
导入numpy为np
from scipy.integrate import quad, romberg
def integrand(x, y):
return x**2 + y**2
quad(integrand, 0, 10, args=(10) # this fails since y is not a scalar
romberg(integrand, 0, 10) # y works here, giving the integral over
# the entire range
但这只适用于固定界限。有没有办法做类似
的事情z = np.arange(20,30)
romberg(integrand, 0, z) # Fails since the function doesn't seem to
# support variable bounds
我唯一看到的方法就是在numpy中重新实现算法本身,然后使用它,这样我就可以有变量边界。任何支持这样的功能?还有romb,你必须直接提供integrand的值和dx间隔,但这对我复杂的函数来说太不精确了(marcum Q函数,找不到任何实现,这可能是另一种点缀它的方法)。
答案 0 :(得分:0)
尝试评估特殊函数时,最好的方法是编写一个函数,该函数使用函数的属性在所有参数体系中快速准确地评估它。单一方法不太可能为所有参数范围提供准确(或甚至稳定)的结果。在这种情况下,对积分的直接评估在很多情况下几乎肯定会崩溃。
话虽如此,通过将积分转换为微分方程并求解,可以解决在多个范围内评估积分的一般问题。粗略地说,步骤将是
scipy.integrate.odeint()
求解此微分方程。该范围应包含所有感兴趣的限制。取样的精确程度取决于功能以及需要评估的准确程度。i = scipy.interpolate.InterpolatedUnivariateSpline(t,I)
。b
和a
中给出一组上限和下限,然后我们可以将它们全部评估为res=i(b)-i(a)
。这种方法是否适用于您的情况需要您仔细研究它的参数范围。另请注意,Marcum Q函数涉及半无限积分。原则上这不是问题,只需将积分转换为有限范围内的积分。例如,考虑变换x-> 1 / x。无法保证这种方法在数值上对您的问题稳定。