问题描述
我正在使用scipy.interpolate.interp1d进行信号的三次样条插值。虽然我相信内插信号应该通过所有原始数据点,但在插入某些因素时却并非如此。
例如如果有N个样本,样本之间有N-1个空格,并且插值因子为f,我们可以在样本之间插入x个点N * f ==(N-1)* x +N。如果x不是整数,内插信号无法通过原始数据点。正如预期的那样,下面使用scipy进行编码,N = 4,插值因子f为3或4。
我的问题是A)这是正确的还是我做错了什么? B)上面的公式中x是一个整数是否足以检查原始数据样本是否会出现在内插信号中(或者可能存在边缘情况)。
非常感谢
import scipy.interpolate
import numpy as np
# produce random data and interp
x = np.linspace(0,2,4)
np.random.seed(123)
y = np.random.random(4)
interp_f = scipy.interpolate.interp1d(x,y,kind='cubic')
# upsample factor 4
x_f4 = np.linspace(0,16)
y_f4 = interp_f(x_f4)
# upsample factor 3
x_f3 = np.linspace(0,12)
y_f3 = interp_f(x_f3)
print("Sample 2 in raw data: {0:.10f},Sample 6 in interp f4: {1:.10f},Sample 4 in interp f3: {2:.10f}".format(y[1],y_f4[5],y_f3[4]))
# Sample 2 in raw data: 0.2861393350,Sample 6 in interp f4: 0.2861393350,Sample 5 in interp f3: 0.2657521625
解决方法
首先,确实如您所写,三次插值通过其原始点。您可以通过以下方式进行验证:
all(y == interp_f(x)) # gives True
您的上采样公式似乎有些混乱。如果我们看一个例子,很容易看到:
- 假设我们有间隔
[0,w]
,其中w = 2
。 - 具有
n = 5
个样本会给出(n-1)
个宽度为d = w/(n-1) = .5
的间隔。 - 要以
f=4
的系数进行上采样,我们将新间隔宽度设为d_4 = d / f = 0.125
。 - 因此
d_4 = w / (n_4 - 1)
也需要保持不变,其中n_4
是上采样信号的数量样本。 - 利用
1 / d_4 = f * (n-1) / w
等于(n_4 - 1) / w
会导致n_4 = f * (n-1) + 1 = 17
只要f
是一个正整数,原始样本将包含在上采样信号中(由于d_4 = d / f
)。我们可以通过以下方式验证公式:
n,f = 5,4
n_4 = f * (n-1) + 1
x = np.linspace(0,2,n)
x_4 = np.linspace(0,n_4)
if all(x_4[::f] == x): # Every fourth sample is equal to the original
print("Up-sampling works.")