通过原始数据点所需的三次样条插值因子(scipy,python)
Cubic spline interpolation factors required to pass through original datapoints (scipy, python)
我正在使用 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, 2, 16)
y_f4 = interp_f(x_f4)
# upsample factor 3
x_f3 = np.linspace(0, 2, 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
您的 up-sampling 公式似乎有点混乱。很容易看出,如果我们看一个例子:
- 假设我们有区间
[0, w]
,其中 w = 2
.
- 有
n = 5
个样本给出 (n-1)
个宽度 d = w/(n-1) = .5
的间隔。
- 到up-sample乘以
f=4
,我们除了新的间隔宽度为d_4 = d / f = 0.125
。
- 因此
d_4 = w / (n_4 - 1)
也需要成立,其中 n_4
是 up-sampled 信号的样本数。
- 利用
1 / d_4 = f * (n-1) / w
应该等于 (n_4 - 1) / w
结果 n_4 = f * (n-1) + 1 = 17
只要f
为正整数,原始样本就会包含在up-sampled信号中(由于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, 2, n_4)
if all(x_4[::f] == x): # Every fourth sample is equal to the original
print("Up-sampling works.")
我正在使用 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, 2, 16)
y_f4 = interp_f(x_f4)
# upsample factor 3
x_f3 = np.linspace(0, 2, 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
您的 up-sampling 公式似乎有点混乱。很容易看出,如果我们看一个例子:
- 假设我们有区间
[0, w]
,其中w = 2
. - 有
n = 5
个样本给出(n-1)
个宽度d = w/(n-1) = .5
的间隔。 - 到up-sample乘以
f=4
,我们除了新的间隔宽度为d_4 = d / f = 0.125
。 - 因此
d_4 = w / (n_4 - 1)
也需要成立,其中n_4
是 up-sampled 信号的样本数。 - 利用
1 / d_4 = f * (n-1) / w
应该等于(n_4 - 1) / w
结果n_4 = f * (n-1) + 1 = 17
只要f
为正整数,原始样本就会包含在up-sampled信号中(由于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, 2, n_4)
if all(x_4[::f] == x): # Every fourth sample is equal to the original
print("Up-sampling works.")