ШАГ 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 – число шагов.