问题描述
我有一个函数,我需要估计它在许多不同区间的定积分,其中一些区间的端点彼此非常接近,
\int_a^{b_k} f(x) dx
我可以为每个时间间隔重新调用 integrate.quad
,但这似乎效率很低,因为 integrate.quad
会为每次调用多次评估函数。有什么方法可以重用 quad
已经评估过的点,以便更快地对 quad
进行后续调用?
(如果没有 integrate.quad
,也许是另一个 scipy 函数或使用不同的公共 python 库?)
或者我应该缓存我之前的积分值,然后调用 quad
来计算新点和之前计算的最近点之间的差异?
另请注意,所选择的端点并非都是事先知道的,它们是自适应选择的。
解决方法
对于具有不同端点的区间,您可以使用通用自适应积分方法的希望不大。这样做的原因是,一般情况下,如果您稍微更改限制,积分值就会发生很大变化。您必须以某种方式提供您的函数在边界处不是“疯狂”的信息,给出估计等,而我不知道这样的方法。
您可以做的是通过变量替换将积分转换为相同的区间,比如 [0,1]
。您最终的任务是在 [0,1]
上集成许多(参数化的)函数。
\int_0^1 f_a(x)
然后您可以尝试对函数调用进行向量化,即针对一个点或一组点同时评估所有函数。
quadpy(我的一个项目)支持矢量化正交,可以显着加快集成速度。多个不同指数的 x ** a
示例:
import numpy as np
import quadpy
a = np.arange(1,7)
def f(x):
return np.power.outer(x,a).T
val,err = quadpy.quad(f,0.0,1.0)
print(val)
print(err)
[0.5 0.33333333 0.25 0.2 0.16666667 0.14285714]
[1.87519478e-20 2.58599737e-20 4.45666434e-20 5.19063171e-20
5.45158477e-20 4.09060649e-20]
请注意,在 f
中,计算是矢量化的,而不是迭代 a
。这大大加快了计算速度。