Алгоритм модифицированного метода Эйлера.




ШАГ 1.

Задать отрезок [a;b]; задать число шагов ; задать начальное условие

ШАГ 2.

Высчитать шаг

ШАГ 3.

Если , то переходим к шагу 4, иначе к шагу 5.

ШАГ 4.

; ; ;

ШАГ 5.

Stop.

 

Алгоритм Рунге-Кутты.

ШАГ 1.

Задать отрезок [a;b]; задать число шагов ; задать начальное условие

ШАГ 2.

Высчитать шаг

ШАГ 3.

Если , то переходим к шагу 4, иначе к шагу 5.

ШАГ 4.

;

;

;

;

;

ШАГ 5.

Stop.

 

ЛИСТИНГ ПРОГРАММЫ

1. Основной код:

clear,clc

 

flag_solve=0;

flag_table=0;

qq=0;

 

% Диалоговое окно для выбора метода:

[Selection,ok] = listdlg('ListString', {'Метод Эйлера'; 'Модифицированный метод Эйлера';...

'Метод Рунге-Кутты'; 'Все методы'},'SelectionMode','single','Name',...

'Решение ДУ первого порядка', 'ListSize', [200 100],'PromptString', 'Выберите метод','fus', 5);

 

if (ok==0)

error('Никакой из методов не выбран!');

end

 

def={''};

optn=struct('Resize','on','WindowStyle','normal','Interpreter','none');

 

% Диалоговое окно для ввода ДУ первого порядка:

try

func=inputdlg('Введите ДУ первого порядка:','Окно ввода',1,def, optn);

func=func{1};

func=strrep(func,' ',''); % убираем пробелы, если есть

f=inline(func,'x','y');

test_flag_1=feval(f,0,0); % проверка на правильно введённой информацию

catch

error('Неправильные входные данные[ДУ]!');

end

 

if (strcmp(func,'')==true)

error('Введена пустая строка!');

end

 

% Диалоговое окно для ввода отрезка:

try

text_1='Введите левый конец отрезка [a,...:';

text_2='Введите правый конец отрезка...,b]:';

p_int=inputdlg({text_1, text_2},'Окно ввода',1,[def, def], optn);

a=str2num(p_int{1});

b=str2num(p_int{2});

test_flag_2=feval(f,a,b); % проверка на правильно введённую информацию

catch

error('Неправильные входные данные[отрезок]!');

end

 

if ((isempty(a)==1) || (isempty(b)==1))

error('Неправильные входные данные[отрезок]!');

end

 

if (a>=b)

error('Отрезок, в котором a>=b: ошибка, так как [a,b]!');

end

 

% Диалоговое окно для ввода начального условия:

try

p_beg=inputdlg('Введите начальное условие y(a):','Окно ввода',1,def, optn);

ya=str2num(p_beg{1});

test_flag_3=feval(f,0,ya);

catch

error('Неправильные входные данные![нач. усл.]');

end

 

if (isempty(ya)==1)

error('Неправильные входные данные![нач. усл.]');

end

 

% Диалоговое окно для ввода количества шагов:

try

p_step=inputdlg('Введите количество шагов:','Окно ввода',1,def, optn);

step=str2num(p_step{1});

test_flag_4=feval(f,0,step);

catch

error('Неправильные входные данные![кол-во шагов]');

end

 

if (isempty(step)==1)

error('Неправильные входные данные![кол-во шагов]');

end

step=round(step);

 

if (step<=0)

error('Количество шагов должно быть >0!');

end

 

% Диалоговое окно для ввода частного решения ДУ, если оно есть:

try

solve_func=inputdlg('Введите частное решение ДУ первого порядка (необязательно):','Окно ввода',1,def, optn);

solve_func=solve_func{1};

solve_func=strrep(solve_func,' ',''); % убираем пробелы, если есть

so_f=inline(solve_func,'x');

test_flag_s=feval(so_f,0);

catch

error('Неправильные входные данные[ч.р.ДУ]');

end

 

if (strcmp(solve_func,'')==false)

flag_solve=1;

end

 

% Точное решение (нахождение значений функции):

if (flag_solve==1)

F=zeros(1,step+1);

T=zeros(1,step+1);

h_1=(b-a)/step;

T=a:h_1:b;

F(1)=feval(so_f,a);

qq=a+h_1;

for i=1:step

F(i+1)=feval(so_f,qq);

qq=qq+h_1;

end

Ans_s=[T' F'];

end

 

% Графики и таблицы:

if ((Selection==1)&&(ok==1))

hold on;

if (flag_solve==1)

plot(Ans_s(:,1),Ans_s(:,2),'m.-');

fprintf('Точные значения (y=f(x)):\n');

fprintf(' i xi yi\n');

for i=1:step+1

fprintf('%3d %8.5f %8.5f\n', i-1, T(i), F(i));

end

fprintf('\n');

end

Ans_1=Euler(f,a,b,ya,step);

plot(Ans_1(:,1),Ans_1(:,2),'k.-');

grid on;

xlabel('Координата по Ox');

ylabel('Координата по Oy');

if (flag_solve==1)

legend('Точное решение','Метод Эйлера');

else

legend('Метод Эйлера');

end

hold off;

elseif ((Selection==2)&&(ok==1))

hold on;

if (flag_solve==1)

plot(Ans_s(:,1),Ans_s(:,2),'m.-');

fprintf('Точные значения (y=f(x)):\n');

fprintf(' i xi yi\n');

for i=1:step+1

fprintf('%3d %8.5f %8.5f\n', i-1, T(i), F(i));

end

fprintf('\n');

end

Ans_2=Modified_Euler(f,a,b,ya,step);

plot(Ans_2(:,1),Ans_2(:,2),'r.-');

grid on;

xlabel('Координата по Ox');

ylabel('Координата по Oy');

if (flag_solve==1)

legend('Точное решение','Модифицированный метод Эйлера');

else

legend('Модифицированный метод Эйлера');

end

hold off;

elseif ((Selection==3)&&(ok==1))

hold on;

if (flag_solve==1)

plot(Ans_s(:,1),Ans_s(:,2),'m.-');

fprintf('Точные значения (y=f(x)):\n');

fprintf(' i xi yi\n');

for i=1:step+1

fprintf('%3d %8.5f %8.5f\n', i-1, T(i), F(i));

end

fprintf('\n');

end

Ans_3=Runge_Kutta_4(f,a,b,ya,step);

plot(Ans_3(:,1),Ans_3(:,2),'g.-');

grid on;

xlabel('Координата по Ox');

ylabel('Координата по Oy');

if (flag_solve==1)

legend('Точное решение','Метод Рунге-Кутты');

else

legend('Метод Рунге-Кутты');

end

hold off;

elseif ((Selection==4)&&(ok==1))

hold on;

if (flag_solve==1)

flag_table=1;

plot(Ans_s(:,1),Ans_s(:,2),'m.-');

fprintf('Точные значения (y=f(x)):\n');

fprintf(' i xi yi\n');

for i=1:step+1

fprintf('%3d %8.5f %8.5f\n', i-1, T(i), F(i));

end

fprintf('\n');

end

Ans_1=Euler(f,a,b,ya,step);

plot(Ans_1(:,1),Ans_1(:,2),'k.-');

grid on;

xlabel('Координата по Ox');

ylabel('Координата по Oy');

 

Ans_2=Modified_Euler(f,a,b,ya,step);

plot(Ans_2(:,1),Ans_2(:,2),'r.-');

 

Ans_3=Runge_Kutta_4(f,a,b,ya,step);

plot(Ans_3(:,1),Ans_3(:,2),'g.-');

if (flag_solve==1)

legend('Точное решение','Метод Эйлера','Модифицированный метод Эйлера','Метод Рунге-Кутты');

else

legend('Метод Эйлера','Модифицированный метод Эйлера','Метод Рунге-Кутты');

end

hold off;

end

 

% Вывод общей табицы (при условии, что дана y=f(x) и выбраны все методы):

if ((flag_solve==1) && (Selection==4))

fprintf('\n Сравнение методов (погрешности):\n');

k_1=' i |Точные значения yi*| Метод_Эйлера |';

k_2=' Мод._метод Эйлера | Метод_Рунге-Кутты |\n';

k_3=' - |-------------------| yi | |yi*-yi| |';

k_4=' yi | |yi*-yi| | yi | |yi*-yi| |\n';

fprintf(strcat(k_1,k_2));

fprintf(strcat(k_3,k_4));

s='|';

for i=1:step+1

ab_1=abs(Ans_s(i,2)-Ans_1(i,2));

ab_2=abs(Ans_s(i,2)-Ans_2(i,2));

ab_3=abs(Ans_s(i,2)-Ans_3(i,2));

fprintf('%4d %s %17.6f %s %13.6f %s %13.6f %s %13.6f %s %13.6f %s %13.6f %s %13.6f %s\n',...

i-1,s, Ans_s(i,2),s, Ans_1(i,2),s,ab_1,s, Ans_2(i,2),s, ab_2,s,...

Ans_3(i,2),s, ab_3,s);

end

end

 

2. Реализация метода Эйлера:

function Ans=Euler(f,a,b,ya,count_step)

h=(b-a)/count_step; % шаг

M=count_step+1;

T=zeros(1,M); % вектор-строка значений xi

Y=zeros(1,M); % вектор-строка значений f(xi)

T=a:h:b;

Y(1)=ya; % начальное условие y(a)

fprintf('Метод Эйлера:\n');

fprintf(' i xi yi f(xi;yi) h*f(xi;yi)\n');

 

for j=1:count_step

f_x=feval(f,T(j),Y(j));

Y(j+1)=Y(j)+h*f_x; % y[i+1]=y[i]+h*f(x[i],y[i])

fprintf('%3d %8.5f %8.5f %8.5f %8.5f\n', j-1, T(j), Y(j), f_x, h*f_x);

end

str='--------';

fprintf('%3d %8.5f %8.5f %9s %9s\n', j, T(M), Y(M), str, str);

fprintf('\n');

Ans=[T' Y'];

end

 

3. Реализация модифицированного метода Эйлера:

function Ans=Modified_Euler(f,a,b,ya,count_step)

h=(b-a)/count_step; % шаг

M=count_step+1;

T=zeros(1,M); % вектор-строка значений xi

Y=zeros(1,M); % вектор-строка значений f(xi)

T=a:h:b;

Y(1)=ya; % начальное условие y(a)

fprintf('Модифицированный метод Эйлера:\n');

fprintf(' i xi yi g=f(xi;yi) xi+h/2 yi+h/2*g h*f(xi+h/2;yi+h/2*g) \n');

 

for j=1:count_step

h_1=h/2;

f_x=feval(f,T(j),Y(j));

f_xx=feval(f,T(j)+h_1,Y(j)+h_1*f_x);

Y(j+1)=Y(j)+h*f_xx;

fprintf('%3d %9.5f %9.5f %9.5f %9.5f %9.5f %9.5f \n', j-1, T(j), Y(j), f_x,...

T(j)+h_1, Y(j)+h_1*f_x, h*f_xx);

% y[i+1]=y[i]+h*f(x[i]+h/2,y[i]+h/2*f(x[i],y[i]))

end

 

str='--------';

fprintf('%3d %9.5f %9.5f %9s %9s %9s %9s\n', j, T(M), Y(M), str, str, str, str);

fprintf('\n');

Ans=[T' Y'];

end

4. Реализация метода Рунге-Кутты:

function Ans=Runge_Kutta_4(f,a,b,ya,count_step)

h=(b-a)/count_step; % шаг

M=count_step+1;

T=zeros(1,M); % вектор-строка значений xi

Y=zeros(1,M); % вектор-строка значений f(xi)

T=a:h:b;

Y(1)=ya; % начальное условие y(a)

fprintf('Метод Рунге-Кутты:\n');

fprintf(' i xi yi k1 k2 k3 k4 h/6*(k1+2*k2+2*k3+k4)\n');

 

for j=1:count_step

h_1=h/2;

k1=feval(f,T(j),Y(j));

k2=feval(f,T(j)+h_1,Y(j)+k1*h_1);

k3=feval(f,T(j)+h_1,Y(j)+k2*h_1);

k4=feval(f,T(j)+h,Y(j)+h*k3);

Y(j+1)=Y(j)+h/6*(k1+2*k2+2*k3+k4);

fprintf('%3d %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f\n', j-1, T(j), Y(j),...

k1, k2, k3, k4, h/6*(k1+2*k2+2*k3+k4));

end

str='--------';

fprintf('%3d %8.5f %8.5f %8s %8s %8s %8s %8s\n', j, T(M), Y(M),...

str, str, str, str, str);

fprintf('\n');

Ans=[T' Y'];

end

Функции Euler, Modified_Euler, Runge_Kutta_4 принимают следующие параметры:

f – функция, вводимая, как строка;

a – левая крайняя точка;

b – правая крайняя точка;

ya – начальное условие y(a);

count_step – число шагов.

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-08-26 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: