Нахождение точек пересечения между ОДУ 3-го порядка и линией? - PullRequest
1 голос
/ 08 февраля 2011

Как найти точки пересечения между решением ОДУ 3-го порядка и линией y = x?

Код моего ODE

sol=dsolve('D3y-4*D2y+Dy+2*y=0,y(0)=-4,Dy(0)=-6,D2y(0)=-4')
x=0:2
y=subs(sol,'t',x)
plot(x,y)

1 Ответ

2 голосов
/ 08 февраля 2011

Чтобы найти числовые значения пересечений:

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

sol = dsolve('D3y-4*D2y+Dy+2*y=0,y(0)=-4,Dy(0)=-6,D2y(0)=-4');
my_func = @(x) subs(sol,'t',x) - x; % Your solution - x is equal to zero at the %intersections

затем, если выхотите найти значения графически:

plot(-5:.01:5,my_func(-5:.01:5))

или численно, с помощью процедуры оптимизации:

x = fzero(my_func,0); % I find x = -.6847

, которая будет искать ноль функции рядом с 0. Она не найдет всенулями, поэтому вам нужно будет запустить функцию fzero рядом со значениями, где вы ожидаете, что пересечения будут.

Надеюсь, это поможет,

Эндрю

Редактирование: a как кметод деления пополам.

Как только мы получим нашу анонимную одномерную функцию "my_func", если вы не хотите использовать метод оптимизации для решения уравнения, но случайно знаете диапазон [range_ {min} range_ {max}], в котором my_func = 0, тогда следующий алгоритм найдет для вас ноль функции при условии, что вы работаете с непрерывной функцией:

range_min = 0; % say our range is [0 2]
range_max = 2;

error_tolerance = .0001; % will find the answer to within .0001

while (range_max - range_min < error_tolerance)
range_temp = (range_max + range_min)/2;
if ((my_func(range_temp) <0 & my_func(range_max)>0) | (my_func(range_temp) >0 & my_func(range_max)<0))
range_min = range_temp;

else if ((my_func(range_min)<0 & my_func(range_temp)>0) | (my_func(range_min)>0 & my_func(range_temp)<0))
    range_max = range_temp;

else if (my_func(range_temp == 0)
range_min = range_temp;
range_max = range_temp;

    end

end

t_intersection = (range_min + range_max)/2;

Итак, некоторые пояснения: еслифункция непрерывна, и ваша есть, тогда, если она пересекает y = t в точке t_intersection, то в нашей модифицированной функции my_func (t) = sol (t) -t будет иметь ноль в точке t_intersection.Поскольку my_func является непрерывным, то мы можем найти ноль функции при условии, что мы знаем два значения функции, одно из которых больше нуля, а другое меньше нуля.

Итак, мы начнем с этих известных точек иопределить диапазон [range_min range_max], где либо my_func (range_min) <0 и my_func (range_max)> 0, либо наоборот.Затем мы разрезаем этот диапазон пополам, создав среднюю точку range_temp = mean (range_min и _max).Теперь мы создадим новый диапазон [range_temp range_max] или [range_min range_temp], чтобы сохранить изменение знака my_func в диапазоне.Мы повторяем этот процесс до тех пор, пока не достигнем удовлетворительной точности.

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

  • Если вам нужно больше о методе деления пополам: http://en.wikipedia.org/wiki/Bisection_method
  • Если вам нужно больше о методах поиска нуля, я бы посмотрел в университетской библиотеке книгу о числовом анализе.
  • Если вам нужно больше об анонимных функциях в Matlab ("= @ (т) "вещь, которую я использовал), затем проверьте здесь: http://www.mathworks.com/help/techdoc/matlab_prog/f4-70115.html

Я думаю, что это охватывает, удачи.

- Андрей

...