Как найти пересечение функций в матлаб

You’ll have to find the point of intersection (px, py) manually:

idx = find(y1 - y2 < eps, 1); %// Index of coordinate in array
px = x(idx);
py = y1(idx);

Remember that we’re comparing two numbers in floating point representation, so instead of y1 == y2 we must set a tolerance. I’ve chosen it as eps, but it’s up to you to decide.

To draw a circle around this point, you can compute its points and then plot them, but a better approach would be to plot one point with a blown-up circle marker (credit to Jonas for this suggestion):

plot(px, py, 'ro', 'MarkerSize', 18)

This way the dimensions of the circle are not affected by the axes and the aspect ratio of the plot.

Example

x = 0:0.01:30;
y1 = x .^ 2 + 2;
y2 = x .^ 3;

%// Find point of intersection
idx = find(y1 - y2 < eps, 1);
px = x(idx);
py = y1(idx);

figure
plot(x, y1, x, y2, px, py, 'ro', 'MarkerSize', 18)
axis([0 10 0 10])

This should produce the following plot:
result

0 / 0 / 0

Регистрация: 08.02.2016

Сообщений: 32

1

Найти точки пересечения произвольных графиков

16.05.2019, 10:21. Показов 18241. Ответов 12


Студворк — интернет-сервис помощи студентам

Задача такая, найти точки пересечения двух произвольно заданных графиков(планируется задавать в guide, выполнить их построение, а потом посчитать площадь между ними) . Ход х 0.01, есть мысли прогнать циклом если yi>yj а потом yi+1<yj+1 то взять приближенную точку пересечения, ещё где-то прочитал, что можно указателем тыкнуть на точку пересечения и матлаб автоматически определит ее координаты. Если есть какие-то мысли пишите, подумаем вместе.



0



1256 / 894 / 437

Регистрация: 21.10.2012

Сообщений: 2,551

16.05.2019, 13:35

2



2



0 / 0 / 0

Регистрация: 08.02.2016

Сообщений: 32

16.05.2019, 22:36

 [ТС]

3

Огромное спасибо, помогло. Но всё же не совсем, программа в первой ссылке не подходит ко всем графикам, например, если я сделаю перебор х-ов от -100 до 100 выдаёт ошибки при вводе функции, не существующей на отрицательных х. А во второй честно не понял, как взять остальные корни, ну и вывести отрицательные корни.

Миниатюры

Найти точки пересечения произвольных графиков
 



0



1256 / 894 / 437

Регистрация: 21.10.2012

Сообщений: 2,551

17.05.2019, 12:02

4

шишка23, без кода сложно что-то вам подсказать



0



Krasme

6637 / 4739 / 1977

Регистрация: 02.02.2014

Сообщений: 12,700

17.05.2019, 12:14

5

какие-то заморочки с переборами…
а так нельзя решать?

Matlab M
1
2
3
4
5
6
7
8
9
10
clc; clear; clf
syms x
f1=x;
f2=x^0.5;
X=solve(f1-f2)
% графики
x=X(1):0.01:X(2)+0.1;
f1=@(x)x;
f2=@(x)x.^0.5;
plot(x,f1(x),x,f2(x),X,f1(X),'or')



1



шишка23

0 / 0 / 0

Регистрация: 08.02.2016

Сообщений: 32

17.05.2019, 22:02

 [ТС]

6

спасибо! Сделал разбиением на кусочки и сравнением последующих У, а оказывается есть такая функция solve… Кстати, немного доработал, сделав цикл до x=X(1):0.01:X(length(X)), теперь точно универсальная!

Добавлено через 38 минут
а можно поинтересоваться в лексике @ и inline.
вот пример работающей программы:

Matlab M
1
2
3
4
5
6
7
8
9
syms x
y1 = eval(get(handles.edit1,'String'));
y2 = eval(get(handles.edit2,'String'));
X=solve(y1-y2);
% графики
x=X(1):0.01:X(length(X));
y1 = inline(get(handles.edit1,'String'));
y2 = inline(get(handles.edit2,'String'));
plot(x,y1(x),x,y2(x),X,y1(X),'ok','linew',2)

А например: y1 =@(x)(get(handles.edit1,’String’)); не работает

 Комментарий модератора 
Правила форума, пункт 4.9. Используйте тэги форматирования текста и редактор формул для удобства восприятия ваших сообщений другими пользователями.



0



0 / 0 / 0

Регистрация: 08.02.2016

Сообщений: 32

18.05.2019, 14:19

 [ТС]

7

при вводе функций f1=x-5; f2=x.^2; выводит решение с мнимой единицей… не подскажете как бороться с этим? может есть что-то на подобии x=double(vpa(x,5))?



0



Krasme

6637 / 4739 / 1977

Регистрация: 02.02.2014

Сообщений: 12,700

18.05.2019, 14:26

8

если решение — мнимые числа, значит, графики не пересекаются…

Добавлено через 58 секунд
для самостоятельного анализа достаточно черкнуть маленький скриптик

Matlab M
1
2
3
4
x=-10:0.1:10;
f1=@(x)x-5;
f2=@(x)x.^2;
plot(x,f1(x),x,f2(x))



0



0 / 0 / 0

Регистрация: 08.02.2016

Сообщений: 32

18.05.2019, 14:59

 [ТС]

9

А избавиться от них никак? Лучше бы матлаб ошибку выдавал и не рисовал эти точки

Миниатюры

Найти точки пересечения произвольных графиков
 



0



Krasme

6637 / 4739 / 1977

Регистрация: 02.02.2014

Сообщений: 12,700

18.05.2019, 15:22

10

от них не избавишься, коли решение такое..
делайте обход по условию,

Matlab M
1
2
  если решение действительное, то рисуем график, 
  иначе график не рисуем



0



0 / 0 / 0

Регистрация: 08.02.2016

Сообщений: 32

18.05.2019, 18:29

 [ТС]

11

Цитата
Сообщение от Krasme
Посмотреть сообщение

какие-то заморочки с переборами…
а так нельзя решать?

к сожалению не находит две точки пересечения функций y1=x.^2; y2=cos(x); , хотя они есть

Миниатюры

Найти точки пересечения произвольных графиков
 



0



шишка23

0 / 0 / 0

Регистрация: 08.02.2016

Сообщений: 32

31.05.2019, 00:27

 [ТС]

12

Если кому интересно, в итоге сделал так, работает с sqrt(x), sin(x), корни с мнимой единицей не выводит, взял диапазон от -1000 до 1000, грубой выборкой с шагом 0.01 нахожу точки пересечения, но есть вероятность, что как раз на этом промежутке функции два раза пересекутся и программы ничего не выведет, сам в матлабе начал работать недавно, так что не судите строго.

Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
X=[];
x=-1000:0.01:1000;
y1 = eval(get(handles.edit1,'String'));
y2 = eval(get(handles.edit2,'String'));
k=1;
for i=1:length(x)-1
    if or(and(y1(i)>y2(i),y1(i+1)<y2(i+1)), and (y1(i)<y2(i),y1(i+1)>y2(i+1)))
        x=x(i):0.000001:x(i+1);
y1 = eval(get(handles.edit1,'String'));
y2 = eval(get(handles.edit2,'String'));
        for i=1:length(x)-1
            if or(and(y1(i)>y2(i),y1(i+1)<y2(i+1)),and(y1(i)<y2(i),y1(i+1)>y2(i+1)))
            X(k)=x(i);
            k=k+1;
            else if y1(i)==y2(i)
                    X(k)=x(i);
                    k=k+1;
                end
            end
        end
x=-1000:0.01:1000;
y1 = eval(get(handles.edit1,'String'));
y2 = eval(get(handles.edit2,'String'));
    else if y1(i)==y2(i)
            X(k)=x(i);
            k=k+1;
        end
    end
end
if k==1
    msgbox('точек пересечения нет или площадь очень мала')
    return
else if k==2
        msgbox('точка пересечения одна или площадь очень мала') 
        return
     end
end



0



nuHrBuH

483 / 427 / 205

Регистрация: 04.03.2011

Сообщений: 1,259

31.05.2019, 15:57

13

Функция eval() более энергозатратна

Matlab M
1
2
3
4
5
6
7
8
9
10
% y1 = eval(get(handles.edit1,'String'));
% y2 = eval(get(handles.edit2,'String'));
s1 = get(handles.edit1,'String');
s2 = get(handles.edit2,'String');
s1 = vectorize(s1);                     % если нету точек перед ^,*,/
s2 = vectorize(s2);
f1 = str2func(['@(x)',s1]);
f2 = str2func(['@(x)',s2]);
y1 = f1(x);
y2 = f2(x);

Подобная тема: тема



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

31.05.2019, 15:57

13

1. Используйте plot () для рисования базовой графики.

x1 = linspace (1,1,10);% X1-X2 (от 1 до 1) дает 10 точек
 y1 = linspace (1,2,10);% от Y1 до Y2 (от 1 до 2) дает 10 точек
plot(x1,y1);
hold on
 x2 = linspace (1,2,10);% генерируют 10 точек от 1 до 2, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2
 y2 = linspace (2,1,10);% генерирует 10 точек от 2 до 1, 1.9, 1.8, 1.7, 1.6, 1.5, 1.4, 1.3, 1.2, 1.2, 1.1.
 plot (x2, y2);% соединить координаты каждой точки в линию
hold on
x3=linspace(2,2,10);
y3=linspace(1,2,10);
plot(x3,y3);
grid on;
xlim([0.5,2.5]); ylim([0.5,2.5])
plot([1 1 2 2],[1 2 1 2],'o');


2. Пересечение прямой и прямой:

% Сначала нарисуйте две картинки в одном окне
x=[1,113,334,361,440,964,964,1];
 y = [1,107,324,323,400,400,471,471];% подготовки данных
 plot (x, y, '.-')% Используйте пунктирные линии для соединения точек (x, y) в линию
                             % Рисунок с графиком - это линейный график, который соединяет две соседние точки прямой линией.
 удерживать% Сохранить свойства текущего графика и оси, чтобы последующие команды рисования можно было добавлять к существующему графику
 x1 = [0 1000];% подготовки данных
y1=x1-25;
 plot (x1, y1, 'r')% Нарисуйте график функции y1 красной линией

 % Определите точку пересечения ниже и отметьте точку пересечения
y2=471;
 x2 = y2 + 25;% определяет точку пересечения (x2, y2)
[x3,y3]=solve('y=324+(323-324)/(361-334)','y=x-25');
 x3 = double (x3); y3 = double (y3);% подтвердить точку пересечения (x3, y3)
 plot ([x2, x3], [y2, y3], 'mo')% Отметьте пересечение красным и фиолетовым кружком
 легенда ('данные графика', 'y = x-25', 'точка пересечения', 2)% добавить легенду


3. Нарисуйте следующие две кривые на одном рисунке и отметьте их точки пересечения:
x1^2 — 2x1x2 — x1 + x2^2 — 2=0
x1^2 — 2x1x2 + x2^2 + 5*x2 — 2=0

clear all;clc;
syms x1 x2
 [s1, s2] = решить ('x1 ^ 2-2 * x1 * x2-x1 + x2 ^ 2-2 = 0', 'x1 ^ 2-2 * x1 * x2 + x2 ^ 2 + 5 * x2-2 = 0 ');% Искать решение уравнений
s1=double(s1);
s2=double(s2);
f1=x1^2-2*x1*x2-x1+x2^2-2;
f2=x1^2-2*x1*x2+x2^2+5*x2-2;
 h1 = ezplot (f1);% нарисовать кривую f1
 set (h1, 'Color', 'r')% устанавливает красный цвет кривой f1, где h1 - маркер кривой
 удерживать;% Сохранить текущие свойства графика и оси, чтобы последующие команды рисования можно было добавить к существующему графику
 h2 = ezplot (f2);% нарисовать кривую f2
 set (h2, 'Color', 'k')% устанавливает черный цвет кривой f2, где h2 - маркер кривой
grid on
 plot (s1, s2, 'r.', 'MarkerSize', 20)% отметьте пересечение красной точкой, размер отмеченной точки равен 20


4. Найдите гиперболическое уравнение x на рисунке ниже.2/42-y2/3Пересечение 2 = 1 и уравнения прямой y = 1/2 * x + 1:

close all; clear all; clc
 syms x y% определяют переменные x, y
 s = решить (x ^ 2/4 ^ 2-y ^ 2/3 ^ 2 == 1, y == 1/2 * x + 1, x, y);% найти пересечение гиперболической и прямой линий
X=double(s.x);
Y=double(s.y);
h1=ezplot(x^2/4^2-y^2/3^2==1,[-10,10]);
 set (h1, 'color', 'r', 'LineWidth', 2)% установить цвет линии на красный
axis equal;
hold on;
h2=ezplot(y==1/2*x+1,[-10,10]);
set(h2,'color','k','LineWidth',2)
 легенда ('x ^ 2/4 ^ 2-y ^ 2/3 ^ 2 = 1', 'y = 1/2 * x + 1', 2)% Добавьте легенду в верхнем левом углу
 plot (X, Y, 'r.', 'MarkerSize', 20)% отметьте пересечение красной сплошной точкой
 text (X (1), Y (1), '(7.4788, 4.7394)', 'FontSize', 12)% отметить пересечение на пересечении
text(X(2),Y(2),'(-4.2788, -1.1394)','fontsize',12)
 plot (0, [- 15: 0.01: 15], 'k');% проведите ось y
 plot ([- 15: 0.01: 15], 0, 'k');% проведите ось x


5. Параболическое уравнение y ^ 2 = 4x и уравнение прямой y = 2Пересечение x-1.

close all; clear all; clc
syms x y
s=solve(y^2==4*x,y==2*x-1,x,y);
X=double(s.x);
Y=double(s.y);
h1=ezplot(y^2==4*x);
set(h1,'color',[0,0,0],'LineWidth',2)
axis equal;
hold on;
h2=ezplot(y==2*x-1);
set(h2,'color',[0,0,1],'LineWidth',2)
legend('y^2=4*x','y=2*x-1',2)
plot(X,Y,'r.','MarkerSize',20)
text(X(1),Y(1),'(1.8660,2.7321)','FontSize',12)
text(X(2),Y(2),'(0.1340,-0.7321)','fontsize',12)
plot(0,[-10:0.01:10],'k');
plot([-10:0.01:10],0,'k')


6. Эллиптическое уравнение x2/52+y2/42 = 1 и гиперболическое уравнение x2/42-y2/3Пересечение 2 = 1.

close all; clear all; clc
syms x y
s=solve(x^2/5^2+y^2/4^2==1,x^2/4^2-y^2/3^2==1,x,y);
X=double(s.x);
Y=double(s.y);
h1=ezplot(x^2/5^2+y^2/4^2==1);
set(h1,'color',[0,0,0],'LineWidth',2)
axis equal; hold on;
h2=ezplot(x^2/4^2-y^2/3^2==1);
set(h2,'color',[0,0,0],'LineWidth',2)
plot(X,Y,'r.','MarkerSize',20)
text(X(1),Y(1),'(4.5596, 1.6415)','FontSize',11)
text(X(2),Y(2),'(-4.5596, 1.6415)','fontsize',11)
text(X(3),Y(3),'(4.5596, -1.6415)','FontSize',11)
text(X(4),Y(4),'(-4.5596, -1.6415)','fontsize',11)
plot(0,[-10:0.01:10],'k');plot([-10:0.01:10],0,'k')


7. Найдите пересечение двух гипербол.

close all; clear all; clc
syms x y
s=solve(x^2-y^2/15==1,(x-8)^2/4-y^2/12==1);
X=double(s.x);
Y=double(s.y);
h1=ezplot(x^2-y^2/15==1,[-100,100,-100,100]);
set(h1,'color','b','LineWidth',2)
axis equal; hold on;
h2=ezplot((x-8)^2/4-y^2/12==1,[-100,100,-100,100]);
set(h2,'color','k','LineWidth',2)
plot(X,Y,'g.','MarkerSize',20)
text(X(1),Y(1),'(2.5,(3*35^(1/2))/2)','FontSize',11)
text(X(2),Y(2),'(2.5, -(3*35^(1/2))/2)','fontsize',11)
text(X(3),Y(3),'(6.5, (15*11^(1/2))/2)','FontSize',11)
text(X(4),Y(4),'(-6.5, (15*11^(1/2))/2)','fontsize',11)


9. Проблема гиперболического позиционирования:

close all; clear all; clc
syms x y
f1 = sqrt(x^2+(y-0.35/1.414)^2)-sqrt((x-0.15/1.414)^2+(y-0.20/1.414)^2)-(2.5000e-04)*340;
f2 = sqrt((x-0.05/1.414)^2+(y-0.15/1.414)^2)-sqrt((x-0.30/1.414)^2+(y-0.05/1.414)^2)-(1.25000e-04)*340;
s = solve(f1,f2);
X = double(s.x);
Y = double(s.y);
h1=ezplot('abs(sqrt(x^2+(y-0.35/1.414)^2)-sqrt((x-0.15/1.414)^2+(y-0.20/1.414)^2))-(2.5000e-04)*340',[-0.8,0.8,-0.8,4])
set(h1,'color','b','LineWidth',2)
hold on;
h2=ezplot('abs(sqrt((x-0.05/1.414)^2+(y-0.15/1.414)^2)-sqrt((x-0.30/1.414)^2+(y-0.05/1.414)^2))-(1.25000e-04)*340',[-0.8,0.8,-0.8,4])
set(h2,'color','r','LineWidth',2)
legend('f1','f2',2)
plot(X,Y,'g.','MarkerSize',20)
text(X(1),Y(1),'A','FontSize',11)
text(X(2),Y(2),'B','fontsize',11)
text(X(3),Y(3),'C','FontSize',11)
text(X(4),Y(4),'D','fontsize',11)

Я делаю это:

>> plot(x,y1,x,y2);
>> x=0:0.001:5;
>> y1=sin(x)+cos(1+x.^2)-1;
>> y2 = ((1/2).*x)-1;
>> find (y1==y2)

И получаю это:

ans =

   Empty matrix: 1-by-0

Как ответ, и это просто сводит меня с ума! Я не знаю, почему Matlab и Scilab не дают мне ответа о пересечениях. Я пытался уменьшить интервалы, например x = 0:0.0001:5; но это ничего не изменило. Как я могу заставить его вернуть мне значения пересечения?

Спасибо.

3 ответа

Лучший ответ

Вы должны помнить, что Matlab используется для поиска численных решений проблем. Вы предоставляете дискретный набор входных точек x=0:0.001:5; и просите его вычислить дискретные выходные точки y1[x] и y2[x]. Это означает, что y1 и y2 не являются непрерывными и не обязательно пересекаются, как их непрерывные аналоги. У меня нет Matlab, поэтому я не запускал ваш код, но ваши дискретные функции, скорее всего, не пересекаются. То есть не существует пары точек a = y1[x_i] и b = y2[x_i], где a = b. Вместо этого вы, скорее всего, захотите найти точки, в которых y2-y1 находится по одну сторону от нуля на конкретном входе и по другую сторону от нуля для следующего входа. Это означало бы, что непрерывные составные части функции пересеклись бы где-то посередине.

Случай, когда функции встречаются, но не пересекаются, немного сложнее, но идея та же.

РЕДАКТИРОВАТЬ:

Такого рода вещи проще всего представить изображениями, поэтому я создал одно, чтобы проиллюстрировать, что я имею в виду.

Plot of y1 and y2

Здесь я использовал гораздо меньше точек, чем вы пытаетесь использовать, но идея та же. Вы можете видеть, что непрерывные версии y1 и y2 пересекаются в нескольких местах, но вы просите Matlab найти точку в y1, которая равна точке в y2 для одинаковых значений x. На этом изображении вы можете видеть, что многие из них близки, но ваш компьютер хранит числа с плавающей запятой с очень высокой точностью, поэтому шансы на их равенство очень малы.

Когда вы увеличиваете количество точек выборки, изображение начинает больше походить на его «непрерывную копию».

Image with increased sample points


1

user2027202827
8 Июл 2016 в 00:02

Возможно, два вектора нигде не имеют абсолютно равных значений. Вы можете попытаться найти наименьшую разницу:

abs(y1-y2)<tolerance

Где допуск = 0,001 — небольшое число


0

Airidas Korolkovas
18 Июн 2016 в 21:49

Два существующих ответа объясняют, почему вы не можете так легко найти точное пересечение. Но что вам действительно нужно, так это ответ на вопрос что делать вместо этого , чтобы получить точные пересечения?

В вашем конкретном случае вы знаете аналитические функции, пересечение которых вы хотите вычислить. Вы можете использовать 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. Тщательно выбирая начальные точки, вы сможете найти все нули как можно точнее.


1

Andras Deak
19 Июн 2016 в 00:04

С уважением, Пользователь. Если я могу спросить, ваша цель — получить точную точку, которая пересекает эти две функции или ближайшую точку к точке пересечения? (последний с использованием аппроксимации)

Вот идея:

1) Если ваша дискретизация: x=0:0.05:2; do содержат точку пересечения, вы можете использовать функцию intersect в Matlab.

Например

intersect([1,2,3],[4,3,1])

вернет вектор с двумя элементами 1 и 3, пересечение этих двух векторов.

Найти точку пересечения — найти точку x такую, что y1 (x) = y2 (x). Поэтому применим

yin = intersect(y1,y2);

После этого, поскольку ваш x отсортирован, вы должны проверить значение в yin которое имеет тот же индекс как в y1 и y2.

Значение, удовлетворяющее этому условию, является точкой пересечения по оси y.

2) Если ваш x не содержит точку пересечения по оси x, используйте численные методы. Найти корни y2-y1. (или точки, где g (x) = y2 (x) -y1 (x) = 0, так как это то же самое, что и y1 (x) = y2 (x))

Вы можете попробовать их первыми. Надеюсь, это будет полезно. Благодарю.

Понравилась статья? Поделить с друзьями:

Не пропустите также:

  • Формула как найти количество теплоты при нагревании
  • Как найти выразительные средства речи
  • Как можно найти мишки
  • Как составить резюме в свободной форме образец бесплатно
  • Как найти все карты в гта онлайн

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии