Написание функции линейной интерполяции в MATLAB - PullRequest
0 голосов
/ 01 февраля 2019

Я пытаюсь написать скрипт линейной интерполяции в Matlab.Как мне исправить, что векторы имеют разную длину?

Я пытался обернуть голову вокруг этой проблемы, но, похоже, не понимаю.Должен ли оператор if быть включен где-либо в цикл for?

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

Теперь он возвращает ошибку о том, что разные стороны имели разное количество элементов.Есть ли способ исправить это, чтобы он работал как функция interp1, уже установленная в MATLAB?

1 Ответ

0 голосов
/ 01 февраля 2019

Есть несколько проблем с вашим кодом:

  1. Чтобы определить vel, вам необходим поэлементный оператор мощности, как указано в сообщении об ошибке, которое вы должны были увидеть:

    vel = 1500*z.^0.1; % Use .^ rather than ^
    
  2. Существует вероятность того, что lower или upper будут пустыми, если в тестируемом диапазоне нет точек.Вам необходимо пропустить эти случаи с помощью теста, подобного следующему:

    ~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

С нестрогими неравенствами, как показано выше <= и >=:

valid result

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...