Найти пересечения общего вектора с нулями MATLAB - PullRequest
1 голос
/ 07 апреля 2020

Рассмотрим общий вектор, который представляет некоторую нелинейную функцию

, например:

x = [1 2 3 4 5 6 7 8 9 10];
f = [-1 6 8 7 5 2 0.1 -2 -3];

Есть ли в matlab метод, который может найти решения f(x)=0? с некоторой заданной точностью

Ответы [ 3 ]

1 голос
/ 07 апреля 2020

Может быть, вы можете попробовать interp1 в arrayfun, как показано ниже (была применена линейная интерполяция)

x0 = arrayfun(@(k) interp1(f(k:k+1),x(k:k+1),0),find(sign(f(1:end-1).*f(2:end))<0));

, так что

x0 =

   1.1429   7.0476   9.5000

ДАННЫЕ

x = [1 2 3 4 5 6 7 8 9 10];
f = [-1 6 8 7 5 2 0.1 -2 -3 3];
1 голос
/ 07 апреля 2020

Если подумать, когда у вас случайное распределение f, поиск нулей можно выполнить только с помощью линейной интерполяции между точками данных:

Для вашего примера я бы определил функцию myFunc as:

function y = myFunc(val)
x = [1 2 3 4 5 6 7 8 9 10];
f = [-1 6 8 7 5 2 0.1 -2 -3 3];
P = griddedInterpolant (x, f, 'linear', 'linear'); 
y = P(val);
end

и применить алгоритм поиска root через что-то вроде fzero:

val = 0; 
x = [1 2 3 4 5 6 7 8 9 10];
x = [-inf x inf]; % Look outside boundary too
fun = @myFunc;
sol = zeros(1, numel(x)-1);
cnt = 0;
for i = 1:length(x)-1 % fzero stops at the 1st zero hence the loop over each interval
    bound = [x(i) x(i+1)];
    try 
        z = fzero(fun, bound);
        cnt = cnt+1;
        sol(cnt) = z;
    catch
        % No answer within the boundary
    end
end
sol(cnt+1:end) = [];
0 голосов
/ 07 апреля 2020

Я сделал функцию, которая делает это, но чувствую, что это что-то вполне "регулярное", что matlab должен был встроить ответы ... так что если кто-то что-нибудь запишет, я приму это как ответ.

function sol = find_zeros(x,f)    
    f_vec = round(f*10^2)/10^2;
    ind=find(diff(sign(f_vec))~=0);
    K = length(ind);
    if (K>0)
        sol = zeros(1,K);
        for k=1:K
            if (f_vec(ind(k))<f_vec(ind(k)+1))                
                df = f_vec(ind(k)):0.01:f_vec(ind(k)+1);
            else
                df = flip(f_vec(ind(k)+1):0.01:f_vec(ind(k)));
            end
            dx = linspace(x(ind(k)),x(ind(k)+1),length(df));
            j = find(df==0);
            sol(k) = dx(j);
        end
    else
        sol=[];
    end
    sol=unique(sol);
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...