scipy - 如何整合线性插值函数?

时间:2017-06-28 20:01:54

标签: python numpy scipy

我有一个函数,它是一个相对较大的数据集的插值。我使用线性插值interp1d,因此有许多非平滑尖点,如this。 scipy的quad函数会因尖锐点而发出警告。我想知道如何在没有警告的情况下进行整合?

谢谢!

感谢所有答案。在这里,我总结了解决方案,以防其他一些人遇到同样的问题:

  1. 就像@Stelios所做的那样,使用points来避免警告并获得更准确的结果。
  2. 在实践中,积分数通常大于limit=50的默认限制(quad),因此我选择quad(f_interp, a, b, limit=2*p.shape[0], points=p)来避免所有这些警告。
  3. 如果ab与数据集x的起点或终点不同,则可以p选择点p = x[where(x>=a and x<=b)]

2 个答案:

答案 0 :(得分:2)

quad接受一个名为points的可选参数。根据文件:

  

点:(浮点数序列,整数),可选

     

有界积分区间中的一系列断点   可能发生局部困难(例如,奇点,   不连续性)。序列不必排序。

在您的情况下,“困难”points正好是数据点的x坐标。这是一个例子:

import numpy as np 
from scipy.integrate import quad
np.random.seed(123)

# generate random data set 
x = np.arange(0,10)  
y = np.random.rand(10)

# construct a linear interpolation function of the data set 
f_interp = lambda xx: np.interp(xx, x, y)

以下是数据点和f_interp的图表: enter image description here

现在将quad称为

quad(f_interp,0,9)

返回一系列警告以及

  

(4.89770017785734, 1.3762838395159349e-05)

如果您提供points参数,即

quad(f_interp,0,9, points = x)

它没有发出警告,结果是

  

(4.8977001778573435, 5.437539505167948e-14)

与前一次调用相比,这也意味着结果的准确性要高得多。

答案 1 :(得分:2)

而不是interp1d,您可以使用scipy.interpolate.InterpolatedUnivariateSpline。该插补器具有计算定积分的方法integral(a, b)

以下是一个例子:

import numpy as np
from scipy.interpolate import InterpolatedUnivariateSpline
import matplotlib.pyplot as plt


# Create some test data.
x = np.linspace(0, np.pi, 21)
np.random.seed(12345)
y = np.sin(1.5*x) + np.random.laplace(scale=0.35, size=len(x))**3

# Create the interpolator.  Use k=1 for linear interpolation.
finterp = InterpolatedUnivariateSpline(x, y, k=1)

# Create a finer mesh of points on which to compute the integral.
xx = np.linspace(x[0], x[-1], 5*len(x))

# Use the interpolator to compute the integral from 0 to t for each
# t in xx.
qq = [finterp.integral(0, t) for t in xx]

# Plot stuff
p = plt.plot(x, y, '.', label='data')
plt.plot(x, y, '-', color=p[0].get_color(), label='linear interpolation')
plt.plot(xx, qq, label='integral of linear interpolation')
plt.grid()
plt.legend(framealpha=1, shadow=True)
plt.show()

情节:

plot