MATLAB - 线性插值



线性插值是一种用于估计两个已知数据点之间值的方法。在这种方法中,在两点之间画一条直线,然后根据端点的已知值计算沿线任何中间点的值。线性插值常用于各种应用,例如信号处理、计算机图形学和数据分析,以根据一组已知数据点估计未知值。

语法

vq = interp1(x,v,xq)
vq = interp1(x,v,xq,method)
vq = interp1(x,v,xq,method,extrapolation)
vq = interp1(v,xq)

以下是语法的解释:

vq = interp1(x,v,xq) - 通过估计 v 中现有数据点之间的点来计算新的值 vq。已知点由 x 和 v 指定,其中 x 是采样点,v 是相应的值。该函数计算由 xq 指定的位置的值。如果 v 包含在相同点采样的多组数据,则 v 的每一列都代表一组不同的样本值。

vq = interp1(x,v,xq,method) - 允许您为插值选择特定方法。method 参数指定函数应如何估计已知点之间的值。可用方法包括 'linear'、'nearest'、'next'、'previous'、'pchip'、'cubic'、'v5cubic'、'makima' 或 'spline'。默认方法是 'linear',它在点之间创建一条直线。

vq = interp1(x,v,xq,method,extrapolation) - 允许您指定如何处理位于已知数据点 x 范围之外的点。如果将 extrapolation 设置为 'extrap',则该函数将使用指定的插值方法来估计范围之外的点的值。或者,您可以指定单个值,interp1() 将为 x 范围之外的所有点返回该值。

vq = interp1(v,xq) - 假设一组默认的采样点坐标来计算插值值。默认坐标是从 1 到 n 的数字序列,其中 n 取决于 v 的形状:

  • 如果 v 是向量,则默认坐标是从 1 到 v 的长度。
  • 如果 v 是数组,则默认坐标是从 1 到 v 的行数。

MATLAB 中线性插值的示例

以下是一些 MATLAB 中线性插值的常见示例:

示例 1:使用 vq = interp1(x,v,xq)

我们的代码如下:

x = [1, 2, 3, 4, 5];
v = [10, 20, 15, 25, 30];
xq = 1.5:0.5:4.5;

% Perform linear interpolation
vq = interp1(x, v, xq);

% Plot the original data points
figure;
plot(x, v, 'bo-', 'LineWidth', 1.5, 'MarkerSize', 8);
hold on;

% Plot the interpolated values
plot(xq, vq, 'rx-', 'LineWidth', 1.5, 'MarkerSize', 8);

% Add labels and legend
xlabel('x');
ylabel('Value');
title('Linear Interpolation Example');
legend('Original Data', 'Interpolated Values', 'Location', 'best');
grid on;
hold off;

在这个例子中:

  • 我们将 x 定义为采样点 [1, 2, 3, 4, 5],并将 v 定义为相应的值 [10, 20, 15, 25, 30]。
  • xq 定义为插值的查询点,范围从 1.5 到 4.5,步长为 0.5。
  • interp1() 函数用于根据已知点 (x, v) 插值 xq 查询点的值。
  • 计算并显示插值值 vq。vq 的每个元素都对应于 xq 中相应查询点的插值值。
  • 该代码将原始数据点绘制为由线连接的蓝色圆圈 ('bo-'),并将插值值绘制为由线连接的红色十字 ('rx-')。

代码执行后,输出如下:

linear interpolation

示例 2:使用 vq = interp1(x,v,xq,method),其中 method 为 cubic

我们的代码是:

x = [1, 2, 3, 4, 5];
v = [10, 20, 15, 25, 30];

xq = 1.5:0.5:4.5;

% Perform interpolation with different methods

method = 'cubic';
vq = interp1(x, v, xq, method);

% Plot the interpolated values

plot(x, v, 'bo-', 'LineWidth', 1.5, 'MarkerSize', 8);
hold on;
plot(xq, vq, 'rx-', 'LineWidth', 1.5, 'MarkerSize', 8);
xlabel('x');
ylabel('Value');
title(['Interpolation Method: ', method]);
legend('Original Data', 'Interpolated Values', 'Location', 'best');
grid on;
hold off;

在上面的示例中,我们有:

  • 我们将 x 定义为采样点 [1, 2, 3, 4, 5],并将 v 定义为相应的值 [10, 20, 15, 25, 30]。
  • 我们定义了用于插值的查询点 xq,范围从 1.5 到 4.5,步长为 0.5。
  • 我们使用了 cubic 方法,可用的方法选项包括 'nearest'、'next'、'previous'、'linear'、'pchip'、'cubic'、'spline'。
  • 我们使用 interp1() 计算插值值 vq,最后绘制 cubic 方法的原始数据点和插值值。原始数据点为蓝色圆圈,插值值为红色十字,标题指示所使用的插值方法。

执行后,我们得到的输出是:

interpolation methods

示例 3:使用 vq = interp1(x,v,xq,method,extrapolation) 进行外推

我们的代码如下:

x = [1, 2, 3, 4, 5];
v = [10, 20, 15, 25, 30];

xq = [0, 1.5, 2.5, 3.5, 4.5, 6];

% Perform linear interpolation with 'extrap' extrapolation
vq_extrap = interp1(x, v, xq, 'linear', 'extrap');

% Perform linear interpolation without extrapolation
vq_no_extrap = interp1(x, v, xq, 'linear', 0);

figure;
plot(x, v, 'bo-', 'LineWidth', 1.5, 'MarkerSize', 8);
hold on;

plot(xq, vq_extrap, 'rx--', 'LineWidth', 1.5, 'MarkerSize', 8);
plot(xq, vq_no_extrap, 'gx:', 'LineWidth', 1.5, 'MarkerSize', 8);

xlabel('x');
ylabel('Value');
title('Linear Interpolation with Extrapolation Example');
legend('Original Data', 'Interpolated Values (extrap)', 'Interpolated Values (no extrap)', 'Location', 'best');
grid on;
hold off;

在上面的示例中,我们有:

  • 我们将 x 定义为采样点 [1, 2, 3, 4, 5],并将 v 定义为相应的值 [10, 20, 15, 25, 30]。
  • 我们定义了用于插值的查询点 xq,包括一些超出 x 范围的点(例如,0 和 6)。
  • 我们使用 interp1() 计算具有 'extrap' 外推法的插值值 vq_extrap 和没有外推法的 vq_no_extrap。
  • 我们绘制原始数据点为蓝色圆圈,vq_extrap 为具有虚线的红色十字,vq_no_extrap 为具有点线的绿色十字。

代码执行后,我们得到的输出如下:

linear interpolation extrapolation

示例 4:使用 vq = interp1(v,xq) 的默认采样点

我们的代码如下:

v = [10, 20, 15, 25, 30];

xq = 1.5:0.5:5.5;

% Perform linear interpolation assuming default sample point coordinates
vq = interp1(v, xq);

% Plot the original values and the interpolated values
figure;
plot(1:length(v), v, 'bo-', 'LineWidth', 1.5, 'MarkerSize', 8);
hold on;
plot(xq, vq, 'rx-', 'LineWidth', 1.5, 'MarkerSize', 8);
xlabel('Sample Point Index');
ylabel('Value');
title('Linear Interpolation Example with Default Sample Points');
legend('Original Values', 'Interpolated Values', 'Location', 'best');
grid on;
hold off;

在上面的例子中:

  • 我们将 v 定义为用于插值的值 [10, 20, 15, 25, 30]。
  • 我们定义了用于插值的查询点 xq,范围从 1.5 到 5.5,步长为 0.5。
  • 我们使用 interp1() 计算假设默认采样点坐标的插值值 vq。
  • 我们绘制原始值为由线连接的蓝色圆圈,插值值为由线连接的红色十字。x 轴表示采样点的索引。

执行后,输出为:

linear interpolation default

示例 5:无点的线性插值

我们的代码如下:

v = [3, 4.5, 7, 6, 3, 1.5, 0, 1.5, 3];
xq = 1.5:0.5:8.5;
vq = interp1(1:numel(v), v, xq);
figure
plot((1:9),v,'o',xq,vq,'*');
legend('v','vq');

在上面的代码中,我们有:

  • v = [3, 4.5, 7, 6, 3, 1.5, 0, 1.5, 3]; - 定义一个向量 v,其中包含用于插值的原始值。
  • xq = 1.5:0.5:8.5; - 定义用于插值的查询点 xq。这些点的范围是从 1.5 到 8.5,步长为 0.5。
  • vq = interp1(1:numel(v), v, xq); - 使用 interp1 函数执行线性插值。该函数在 xq 中指定的查询点处对 v 中的值进行插值。由于没有明确指定采样点,因此该函数使用从 1 到 v 中元素数量的默认采样点坐标。
  • plot((1:9),v,'o',xq,vq,'*'); - 绘制原始值 v 为蓝色圆圈,插值值 vq 为红色星号。x 轴表示采样点的索引。

执行后,我们得到的输出如下:

linear interpolation points

示例 6:使用复数

我们的代码如下:

v = [1+2i, 3+4i, 5+6i, 7+8i, 9+10i];

xq = 1.5:0.5:5.5;

% Perform linear interpolation
vq = interp1(1:numel(v), v, xq, 'linear');

% Plot the original and interpolated complex values
figure;
plot(1:numel(v), real(v), 'bo-', 1:numel(v), imag(v), 'go-', ...
   xq, real(vq), 'rx--', xq, imag(vq), 'yx--', 'LineWidth', 1.5, 'MarkerSize', 8);
xlabel('Sample Point Index');
ylabel('Value');
title('Linear Interpolation of Complex Values');
legend('Real(v)', 'Imag(v)', 'Real(vq)', 'Imag(vq)', 'Location', 'best');
grid on;

在上面的例子中:

  • 我们定义一个包含复数值的向量 v。
  • 我们定义用于插值的查询点 xq。
  • 我们使用 interp1 对查询点 xq 处的复数值 v 执行线性插值。
  • 我们绘制原始 (v) 和插值 (vq) 复数值的实部和虚部。x 轴表示采样点的索引。

执行后,我们得到的输出如下:

sample point index

示例 7:使用日期和时间

我们的代码如下:

dates = datetime({'2022-01-01', '2022-01-03', '2022-01-06', '2022-01-10'}, 'InputFormat', 'yyyy-MM-dd');
values = [10, 15, 25, 20];

query_dates = datetime({'2022-01-02', '2022-01-04', '2022-01-05', '2022-01-07', '2022-01-08', '2022-01-09'}, 'InputFormat', 'yyyy-MM-dd');

% Perform linear interpolation
interp_values = interp1(dates, values, query_dates, 'linear');

% Plot the original and interpolated values
figure;
plot(dates, values, 'o-', query_dates, interp_values, 'x--', 'LineWidth', 1.5, 'MarkerSize', 8);
xlabel('Date');
ylabel('Value');
title('Linear Interpolation of Values over Dates');
legend('Original Values', 'Interpolated Values', 'Location', 'best');
grid on;

在上面的示例中:

  • 我们定义一个向量 dates,其中包含表示日期的 datetime 值,以及一个包含数值的相应向量 values。
  • 我们定义一个向量 query_dates,其中包含我们想要插值值的 datetime 值。
  • 我们使用 interp1 对原始值在日期上进行线性插值,以估计 query_dates 的值。
  • 我们绘制原始值和日期上的插值值。x 轴表示日期,y 轴表示值。

执行后,我们得到的输出如下:

interpolated values

示例 8:多组数据

我们的代码如下:

x = (-3:3)';
v1 = x.^3;
v2 = 2*x.^3 + 2;
v3 = 3*x.^3 + 4;

v = [v1 v2 v3];

xq = -3:0.1:3;

vq = interp1(x, v, xq, 'pchip');

% Plot the original and interpolated values for all three sets of data
figure;
plot(x, v, 'o-', xq, vq, '--', 'LineWidth', 1.5, 'MarkerSize', 8);
xlabel('x');
ylabel('Value');
title('Linear Interpolation of Multiple Sets of Data');
legend('Set 1 - Original Values', 'Set 2 - Original Values', 'Set 3 - Original Values', 'Interpolated Values', 'Location', 'best');
grid on;

在上面的示例中:

  • 我们定义一个向量 x,表示原始采样点。
  • 我们使用 x 的不同函数计算三组原始值 (v1、v2、v3)。
  • 我们将原始值组合到一个矩阵 v 中。
  • 我们定义一个向量 xq,其中包含用于插值的查询点。
  • 我们使用 interp1 函数和 'pchip' 方法对样本点的原始值进行插值,以估算查询点的值。
  • 我们绘制了所有三组数据的原始值和插值值。x 轴表示 x,y 轴表示值。

执行后,我们得到的输出如下:

multiple sets
广告