振荡函数的集成不会在python中收敛

时间:2017-07-18 12:45:20

标签: python scipy

我想使用scipy.integrate.quad来评估函数的积分。以下是被积函数的样子: Integrand of oscillatory function 我们可以注意到,该被积函数的大部分贡献将来自.1到4或5。对于x = 10或更大,虽然函数是振荡的(很难在图片上看出来),但它非常小并且不断变小。

以下是从0到某些上限的整合结果。积分的上限在x轴上。 Integration of integrand up to some upper bound 在这里,虽然结果似乎在前100个x中是稳定的,但不久之后,即使我期待一条直线......

我对python很新,我不知道什么是最好的行动方案。我现在最好的猜测是将一些小于100的值作为积分的上限,并丢弃其他值,因为它只是来自integrate.quad的一个不好的收敛。

修改 为了绘制第二个图,我使用了scipy.integrate.quad函数。但是,如果我只是采用我生成的点来绘制被积函数(第一个数字)并在scipy.integrate.simps中使用它并改变我整合的最大x,我得到一致的结果。

1 个答案:

答案 0 :(得分:5)

当被积函数具有远小于积分范围的重要特征时,它可能会被忽略"通过自适应quad例程。相反,simps如果使用足够精细的网格,则不会错过它们,但可能需要更长时间才能进行评估。我将介绍两种解决方法,第二种方法更实用。

指向参数

您可以使用points的{​​{1}}参数来确保不会发生这种情况。这是一个例子,我在区间[-1000,5000]上集成了高斯函数quad。该函数位于0附近;几乎所有这些都在区间[-5,5]中,所以我包括exp(-x**2)以确保不会忽略这个范围。 (这些点必须在整合范围内,因此出现points=[-5, 5])。

if

红色曲线是没有import numpy as np from scipy.integrate import quad import matplotlib.pyplot as plt f = lambda x: np.exp(-x**2) numpoints = 1000 t = np.linspace(-1000, 5000, numpoints) y = np.zeros((numpoints,)) for i in range(numpoints): y[i] = quad(f, -1000, t[i])[0] # integration without points plt.plot(t, y, 'r') for i in range(numpoints): # using points if upper bound is above 5 y[i] = quad(f, -1000, t[i], points=[-5,5])[0] if t[i] > 5 else quad(f, -1000, t[i])[0] plt.plot(t, y, 'b') plt.show() 的输出,蓝色曲线是points。后者的行为应该如此:从0上升到pi / 2并保持在那里。

results

重复使用以前的计算

在多个点计算反衍生物的更有效的方法是使用先前计算的值,向其添加未积分的区间的贡献。

points

这与上面的蓝色曲线具有相同的输出。