在MATLAB中编写线性插值函数

时间:2019-02-01 09:11:56

标签: arrays matlab linear-interpolation

我正在尝试在matlab中编写线性插值脚本。如何确定向量长度不同?

我已经设法解决了这个问题,但似乎无法理解。是否应该在for循环中的任何位置包含if语句?

z = linspace(0,1000,21)
vel = 1500*z^0.1;

% I want to interpolate vel between the 201 elements of depths. 
depths = [0:5:1000];
numel_depths = numel(depths);

for ii = 1:numel_depths   %Going through all indices of depths

    lower = find(z > depths(ii),1); % Finding x0 and x1.
    higher = find(z < depths(ii),1,'last'); 

    V2(ii) = vel(lower) + ((vel(higher) - vel(lower))/(z(higher)-  
        z(lower)))*(depths(ii)-z(lower)); % linear interpolation step
end

现在,它返回一个错误,指出不同的面具有不同数量的元素。有没有一种方法可以解决此问题,使其能够像已经在MATLAB中安装的interp1函数一样工作?

1 个答案:

答案 0 :(得分:5)

您的代码有几个问题:

  1. 您需要按元素的幂运算符来定义vel,如必须看到的错误消息所指示:

    vel = 1500*z.^0.1; % Use .^ rather than ^
    
  2. 如果没有点在您要测试的范围内,lowerupper可能为空。您需要使用类似的测试来跳过这些情况:

    ~isempty( lower ) && ~isempty( higher )
    
  3. 您尚未使用有效的行继续。在MATLAB中,您不能只断开一行,而必须在虚线的末尾添加省略号(...)。

  4. 您正在使用严格的不等式><,这意味着您错过了应包含在插值中的边界点(下面的示例)。

  5. 您应该在for循环之前预先分配数组,所以

    v2 = NaN(size(depths)); % Define output V2 to be same size as input depths
    
  6. lower是MATLAB的内置函数,用于使字符串小写,避免将其用作变量名。

修复以上所有问题的方法如下:

z = linspace(0,1000,21);
vel = 1500*z.^0.1;      % Element-wise power operator
depths = 0:5:1000;
V2 = NaN(size(depths)); % Pre-allocate output array

for ii = 1:numel(depths);   
    % Finding x0 and x1, inclusive of boundaries (>= or <=).
    % Using 'x0' and 'x1' as var names to avoid shadowing the 'lower' function
    x0 = find(z >= depths(ii),1); 
    x1 = find(z <= depths(ii),1,'last'); 

    % Check if any points fell in this region
    if ~isempty( x0 ) && ~isempty( x1 )
        % Interpolation step, note the line continuation "..."
        V2(ii) = vel(x0) + ((vel(x1) - vel(x0))/(z(x1) - ...  
            z(x0)))*(depths(ii)-z(x0)); 
    end
end    

我们可以针对内置插值函数interp1

进行验证
  1. 与原有严格不等式<>

plot with errors

  1. 具有如<=>=所示的非严格不等式:

valid result