MATLAB - 线性插值
MATLAB - 一维数据插值
Section titled “MATLAB - 一维数据插值”插值是估计已知数据点之间未知值的过程。当您有一组数据点 (x, v) 并想在新的查询点 xq 处找到值 vq 时,使用一维(1-D)插值。MATLAB 的主要函数是 interp1。
interp1 函数
Section titled “interp1 函数”% 基本语法vq = interp1(x, v, xq)
% 指定插值方法vq = interp1(x, v, xq, method)
% 指定方法和外推行为vq = interp1(x, v, xq, method, extrapolation)
% 使用默认采样点 [1, 2, 3, ...]vq = interp1(v, xq, ...)x:采样点位置的向量(自变量)。必须是单调的。v:对应样本值(因变量)的向量或矩阵。如果v是矩阵,则对每列独立执行插值。xq:您想要估计值的查询点向量或矩阵。vq:输出,包含与xq对应的插值结果。
选择合适的插值方法
Section titled “选择合适的插值方法”method 选项会显著改变结果。以下是最常见的选择:
| Method | Description & Best Use Case |
|---|---|
'linear' (Default) | 使用直线连接点。快速简单。最适用于密集或近似线性数据。 |
'spline' | 三次样条插值。生成一条非常平滑的曲线,穿过所有数据点。适用于平滑、连续的信号。 |
'pchip' | 保形分段三次插值。防止过冲并保持单调性。非常适用于不应在点之间振荡的数据。 |
'makima' | 改进的 Akima 三次 Hermite 插值。类似于 'pchip',但通常在不产生过冲的情况下更准确地捕捉数据形状。是 'spline' 和 'pchip' 的推荐现代替代方案。 |
'nearest' | “最近邻”插值。输出是最近采样点的值。适用于离散或分类数据。 |
示例 1:比较插值方法
Section titled “示例 1:比较插值方法”%% --- 定义原始数据和查询数据 ---x = 0:10; % 原始采样点v = sin(x); % 原始值xq = 0:0.25:10; % 查询点(更高分辨率)
%% --- 执行插值 ---vq_linear = interp1(x, v, xq, 'linear');vq_spline = interp1(x, v, xq, 'spline');vq_makima = interp1(x, v, xq, 'makima');
%% --- 绘图比较 ---figure;hold on; % 允许在同一坐标轴上绘制多个图
% 绘制原始粗略数据plot(x, v, 'o', 'MarkerSize', 10, 'DisplayName', '原始样本');
% 绘制插值结果plot(xq, vq_linear, ':', 'LineWidth', 1.5, 'DisplayName', '线性');plot(xq, vq_spline, '--', 'LineWidth', 1.5, 'DisplayName', '样条');plot(xq, vq_makima, '-', 'LineWidth', 2, 'DisplayName', 'Makima');
hold off;
% --- 专业绘图的最后润色 ---title('插值方法比较');xlabel('X');ylabel('sin(X)');legend('show', 'Location', 'southwest');grid on;将生成一个图。它将显示原始 sin(x) 值,表示为大的蓝色圆圈。三条线将追踪这些点之间的路径:一条绿色虚线显示线性插值的直线连接;一条红色虚线显示样条插值的平滑、有时会过冲的曲线;一条粗蓝色实线显示来自 ‘makima’ 方法的平滑但无过冲的曲线。
外推:数据范围之外
Section titled “外推:数据范围之外”如果 xq 中的查询点超出 x 的范围会发生什么?默认情况下,interp1 返回 NaN(非数值)。您可以使用 extrapolation 参数改变此行为。
示例 2:外推
Section titled “示例 2:外推”x = 1:5;v = [12, 16, 10, 18, 15];xq = 0:0.5:6; % 查询点包含 [1, 5] 范围之外的值
% 执行线性插值并允许外推vq_extrap = interp1(x, v, xq, 'linear', 'extrap');
% 执行插值并对范围外的点返回 0vq_no_extrap = interp1(x, v, xq, 'linear', 0);
figure;hold on;plot(x, v, 'bo-', 'LineWidth', 2, 'MarkerSize', 8, 'DisplayName', 'Original Data');plot(xq, vq_extrap, 'rx--', 'LineWidth', 1.5, 'DisplayName', 'With Extrapolation (''extrap'')');plot(xq, vq_no_extrap, 'g*:', 'LineWidth', 1.5, 'DisplayName', 'With Extrapolation (value 0)');hold off;
title('处理范围外查询点');xlabel('x');ylabel('值');legend('show');grid on;该图将显示原始数据为实心蓝色圆圈。一条红色虚线将在原始数据范围的两端延伸,延续线性趋势。一条带有星号的绿色虚线将跟随数据范围内的插值,但在范围外的所有点处降至零。
实用技巧:处理多个数据集
Section titled “实用技巧:处理多个数据集”interp1 针对向量和矩阵操作进行了高度优化。如果您有多个在相同 x 点采样的数据集,可以将它们放置在 v 的列中,并通过一次调用全部进行插值。这比使用循环快得多。
x = (0:4)'; % 在此示例中必须是列向量
% 三列中的三个数据集v = [x.^2, x.^3, exp(x)];
xq = 0:0.1:4;
% 一次性插值所有三列vq = interp1(x, v, xq, 'pchip');
% 绘图figure;plot(x, v, 'o', 'MarkerSize', 8);hold on;plot(xq, vq, '--', 'LineWidth', 1.5);hold off;title('插值多个数据集');legend('原始数据集 1', '原始数据集 2', '原始数据集 3', 'Location', 'northwest');