Два существующих ответа объясняют, почему вы не можете так легко найти точное пересечение. Но что вам действительно нужно, так это ответ на вопрос что делать вместо этого, чтобы получить точные пересечения?
В вашем конкретном случае вы знаете аналитические функции, пересечение которых вы хотите выяснить. Вы можете использовать fzero
с функцией (необязательно анонимной), чтобы найти нулевое значение. функции, определяемой разницей двух ваших исходных функций:
y1fun = @(x) sin(x)+cos(1+x.^2)-1;
y2fun = @(x) ((1/2).*x)-1;
diff_fun = @(x) y1fun(x)-y2fun(x);
x0 = 1; % starting point for fzero's zero search
x_cross = fzero(diff_fun,x0);
Теперь это даст вам один нуль разностной функции, то есть одно пересечение ваших функций. Оказывается, найти каждый нуль функции — непростая задача. Обычно вам приходится вызывать fzero
несколько раз с разными начальными точками x0
. Если вы подозреваете, как выглядят ваши функции, это вовсе не безнадежно.
Так что же произойдет, если ваши функции станут более беспорядочными? В общем случае вы можете использовать функцию интерполяции, чтобы играть роль y1fun
и y2fun
в приведенном выше примере, например, используя interp1
:
% generate data
xdata = 0:0.001:5;
y1data = sin(xdata)+cos(1+xdata.^2)-1;
y2data = ((1/2).*xdata)-1;
y1fun = @(x) interp1(xdata,y1data,x);
y2fun = @(x) interp1(xdata,y2data,x);
x0 = 1; % starting point for fzero's zero search
x_cross = fzero(@(x)y1fun(x)-y2fun(x),x0);
что возвращает нас к исходной проблеме. Обратите внимание, что interp1
по умолчанию использует линейную интерполяцию, в зависимости от того, как выглядит ваша функция и как разбросаны ваши данные, вы можете выбрать другие параметры. Также обратите внимание на возможность экстраполяции (ее следует избегать).
Таким образом, в обоих случаях вы получаете одно пересечение для каждого вызова fzero
. Тщательно выбирая начальные точки, вы сможете найти все нули как можно точнее.
person
Andras Deak
schedule
18.06.2016