📄 mtl_ode_sim_eulerconv.m
字号:
function mtl_gen_ode_sim_eulerconv
% This file was developed for the Holistic Numerical Methods Institute
% by Nathaniel Collier (http://numericalmethods.eng.usf.edu). Contributions
% also came from Timothy Fawcett and Dr. Autar Kaw.
%
% Nothing needs to be changed in the code. Simply run the function (type
% the name in the command window or right click it in the Current Directory
% window and choose run. There a window will appear in which you may alter
% 4 quantities.
%
% dy/dx in form of f(x,y)
% x0, x location of known intial condition
% y0, corresponding value of y at x0
% xf, x location at where you wish to see the solution to the ODE
% n, the number of steps to take
%
% These inputs will have defaults, simply change them as needed. Once you
% click away from the text boxes, the screen will automatically update.
% This file will show you Euler's approximation of the solution of the ODE
% as well as true and relative true error and approximate and relative
% approximate error versus the number of steps taken.
%
% Note that here exact value is a matlab determined exact value.
% The function ode45 is used. There may be some cases where an exact
% solution is not available. This does not mean, however, that the solution
% cannot be approximated or that Euler's is not valid. It simply means that
% there will be no exact value for comparison.
clc; close all;
function varargout=eulerODE(f,x0,y0,xf,n)
h=(xf-x0)/n;
xa=x0;
ya=y0;
for i = 2:n+1
xa=xa+h;
ya=ya+f(xa-h,ya)*h;
end
varargout=ya;
end %end Euler fcn
function actual_and_approximate(src,evt)
%Read variables from UI
fcnstr=get(fcnbox,'String');
x0=str2num(get(x0box,'String'));
y0=str2num(get(y0box,'String'));
xf=str2num(get(xfbox,'String'));
n=str2num(get(steps,'String'));
istep=get(combo,'Value');
if x0 < xf
f=inline(fcnstr);
xspan = [x0 xf];
% Exact Solution
[x,y]=ode45(f,xspan,y0);
[yfi dummy]=size(y);
yf=y(yfi);
% Approximations
% solution at nmax
h=(xf-x0)/n;
xa=x0;
ya(1)=y0;
for i = 2:n+1
xa(i)=xa(i-1)+h;
ya(i)=ya(i-1)+f(xa(i-1),ya(i-1))*h;
end
% yf as a function of n
count=floor(log(n)/log(2))+1;
for i = 1:count
yff(i)=yf;
ii(i)=2^(i-1);
hf=(xf-x0)/ii(i);
xaf=x0;
yaf=y0;
for j = 1:ii(i)
yaf=yaf+f(xaf,yaf)*hf;
xaf=xaf+hf;
end
yfa(i)=yaf;
Et(i)=yfa(i)-yf;
et(i)=abs(Et(i)/yf)*100;
if i==1
Ea(i)=0;
ea(i)=0;
sff(i)=0;
else
Ea(i)=yfa(i)-yfa(i-1);
ea(i)=abs(Ea(i)/yfa(i-1))*100;
if ea(i)<5
sff(i)=floor(2 - log(ea(i)/0.5)/log(10));
else
sff(i)=0;
end
end
end
switch istep
case 1
hold off
axis([x0 xf min([min(ya) min(y)]) max([max(ya) max(y)])])
plot(x,y,'-','LineWidth',2,...
'Color',[0 0 1]);
hold off
case 2
axis([x0 xf min([min(ya) min(y)]) max([max(ya) max(y)])])
plot(x,y,'-','LineWidth',2,...
'Color',[0 0 1]);
hold on
plot(xa,ya,'-','LineWidth',2,...
'Color',[0 1 0]);
hold off
case 3
hold off
plot(ii,yfa,'-','LineWidth',2,...
'Color',[1 0 0]);
hold off
case 4
hold off
plot(ii,Et,'-','LineWidth',2,...
'Color',[0 0 1]);
hold off
case 5
hold off
plot(ii,et,'-','LineWidth',2,...
'Color',[0 0 1]);
hold off
case 6
hold off
plot(ii,Ea,'-','LineWidth',2,...
'Color',[0 1 0]);
hold off
case 7
hold off
plot(ii,ea,'-','LineWidth',2,...
'Color',[0 1 0]);
hold off
case 8
hold off
plot(ii,sff,'-','LineWidth',2,...
'Color',[1 0.5 0.5]);
hold off
end
set(tablebox1(1),'String',ii);
set(tablebox1(2),'String',yff);
set(tablebox1(3),'String',yfa);
set(tablebox1(4),'String',Et);
set(tablebox1(5),'String',et);
set(tablebox1(6),'String',Ea);
set(tablebox1(7),'String',ea);
set(tablebox1(8),'String',sff);
else
warndlg('For Matlab''s solver to work correctly, you must have x0 < xf. Please change these values and try again.');
end %end if
end % End actual_and_approximate
function fontCallback(src,evt)
fs=6+2*(get(combof,'Value')-1);
set(titlebox,'FontSize',fs+4);
set(fcnlabel,'FontSize',fs);
set(fcnbox,'FontSize',fs);
set(y0label,'FontSize',fs);
set(x0box,'FontSize',fs);
set(y0box,'FontSize',fs);
set(xflabel,'FontSize',fs);
set(introbox,'FontSize',fs);
set(xfbox,'FontSize',fs);
end % End fontCallback
function helpme(src,evt)
web http://numericalmethods.eng.usf.edu/mtlhelp/08ode/mtl_gen_ode_hlp_eulerconv.doc -browser;
end % End fontCallback
function gotoweb(src,evt)
web http://numericalmethods.eng.usf.edu/topics/euler_method.htm -browser;
end % End fontCallback
%GUI----------------------------------------------------------------
% Window
ssize=get(0,'ScreenSize');
gsize=[1/8*ssize(3) 1/8*ssize(4) 3/4*ssize(3) 3/4*ssize(4)];
gui=figure('Resize','off',...
'Position',gsize,...
'Name','Convergence of Euler''s Method of Solving Ordinary Differential Equations',...
'NumberTitle','off',...
'menubar','none');
% !!!Set font sizes
switch ssize(3)
case 800
fs = 6;
sel = 1;
warndlg('At this resolution (800 x 600) you may have trouble viewing all data in this window.');
case 1024
fs = 8;
sel = 2;
case 1152
fs = 8;
sel = 2;
case 1280
fs = 8;
sel = 2;
case 1600
fs = 10;
sel = 3;
otherwise
fs = 8;
sel = 3;
end
panelColor = get(gui,'Color');
% Title box
title_pos=[1/16*gsize(3) 29/32*gsize(4) 7/8*gsize(3) 2/32*gsize(4)];
title = 'Euler''s Method of Solving Ordinary Differential Equations';
titlebox=uicontrol(gui,'BackgroundColor',panelColor,...
'Style','text',...
'FontWeight','bold',...
'String',title,...
'FontSize',fs+4,...
'Position',title_pos);
% Label for Function Input
fcnlabel_pos=[1/16*gsize(3) 3/32*gsize(4) 7/8/3*gsize(3) 1/32*gsize(4)];
fcnlabel=uicontrol(gui,'BackgroundColor',[1 1 1],...
'Style','text',...
'String','Enter dy/dx as f(x,y)',...
'FontSize',fs,...
'Position',fcnlabel_pos);
% Function Input Box
fcnbox_pos=fcnlabel_pos+[fcnlabel_pos(3) 0 -7/8/6*gsize(3) 0];
fcnbox=uicontrol(gui,'BackgroundColor',[1 1 1],...
'Style','edit',...
'String','y*x-1.2*y',...
'FontSize',fs,...
'Position',fcnbox_pos,...
'Callback',@actual_and_approximate);
% Label for x0 and y0 Input
y0label_pos=[1/16*gsize(3) 2/32*gsize(4) 7/8/3*gsize(3) 1/32*gsize(4)];
y0label=uicontrol(gui,'BackgroundColor',[1 1 1],...
'Style','text',...
'String','Initial condition x0 and y0 repsectively',...
'FontSize',fs,...
'Position',y0label_pos);
% x0 Input box
x0box_pos=y0label_pos+[y0label_pos(3) 0 -7/8/6*gsize(3)-fcnbox_pos(3)/2 0];
x0box=uicontrol(gui,'BackgroundColor',[1 1 1],...
'Style','edit',...
'String','0.0',...
'FontSize',fs,...
'Position',x0box_pos,...
'Callback',@actual_and_approximate);
% y0 Input Box
y0box_pos=x0box_pos+[x0box_pos(3) 0 0 0];
y0box=uicontrol(gui,'BackgroundColor',[1 1 1],...
'Style','edit',...
'String','1.0',...
'FontSize',fs,...
'Position',y0box_pos,...
'Callback',@actual_and_approximate);
% Label for xf
xflabel_pos=[1/16*gsize(3) 1/32*gsize(4) 7/8/3*gsize(3) 1/32*gsize(4)];
xflabel=uicontrol(gui,'BackgroundColor',[1 1 1],...
'Style','text',...
'String','Enter x at which solution is desired, xf',...
'FontSize',fs,...
'Position',xflabel_pos);
% xf Input box
xfbox_pos=xflabel_pos+[xflabel_pos(3) 0 -7/8/6*gsize(3) 0];
xfbox=uicontrol(gui,'BackgroundColor',[1 1 1],...
'Style','edit',...
'String','2.0',...
'FontSize',fs,...
'Position',xfbox_pos,...
'Callback',@actual_and_approximate);
% Intro Frame and Text Box
intro_frame_pos=[2/32*gsize(3) 40/64*gsize(4) 14/16*gsize(3) 19/64*gsize(4)];
intro_frame = uicontrol(gui,'BackgroundColor',[1 1 1],...
'Position',intro_frame_pos);
introbox = uicontrol(gui,'BackgroundColor',[1 1 1],...
'Position',intro_frame_pos+[20 20 -40 -40],...
'Style','text',...
'FontSize',fs,...
'HorizontalAlignment', 'left',...
'Visible','off',...
'String','');
% Combo box for display
combo_pos = fcnlabel_pos + [fcnlabel_pos(3)+fcnbox_pos(3)+2*x0box_pos(3) 0 0 0];
combo_sel = {'Introduction and Exact Solution',...
'Exact and Approximate Solution',...
'Approximate Value vs. Number of Steps',...
'True Error vs. Number of Steps',...
'Absolute Relative True Error(%) vs. Number of Steps',...
'Approximate Error vs. Number of Steps',...
'Absolute Relative Approximate Error(%) vs. Number of Steps',...
'Least Number of Significant Digits Correct vs. Number of Steps'};
combo = uicontrol(gui,'BackgroundColor',[1 1 1],...
'Style','popupmenu',...
'position',combo_pos,...
'String',combo_sel,...
'Callback',@actual_and_approximate);
% !!! Combo box for fonts sizes
combof_pos = combo_pos - [0 combo_pos(4) 0 0];
combof_sel = {'FontSize 6',...
'FontSize 8',...
'FontSize 10',...
'FontSize 12',...
'FontSize 14'};
combof = uicontrol(gui,'BackgroundColor',[1 1 1],...
'Style','popupmenu',...
'position',combof_pos,...
'String',combof_sel,...
'Value',sel,...
'Callback',@fontCallback);
% Help Button
help_pos=combof_pos+[0 -combof_pos(4) -0.5*combof_pos(3) 0];
helpbutton = uicontrol(gui,'BackgroundColor',[1 1 1],...
'Position',help_pos,...
'String','Help!',...
'Callback',@helpme);
% Web Button
web_pos=help_pos+[help_pos(3) 0 0 0];
webbutton = uicontrol(gui,'BackgroundColor',[1 1 1],...
'Position',web_pos,...
'String','More Resources',...
'Callback',@gotoweb);
% Steps label
rwidth=(combo_pos(1)-y0box_pos(1)-y0box_pos(3))*0.8;
offset=rwidth/0.8-rwidth;
lsteps_pos=[y0box_pos(1)+offset/2+y0box_pos(3) y0box_pos(2) rwidth 2*fcnlabel_pos(4)];
lsteps=uicontrol(gui,'BackgroundColor',[1 1 1],...
'Style','text',...
'String','Maximum number of steps',...
'FontSize',fs,...
'Position',lsteps_pos,...
'Callback',@actual_and_approximate);
% Steps input box
steps_pos=[lsteps_pos(1) lsteps_pos(2)-lsteps_pos(4)/2 lsteps_pos(3) lsteps_pos(4)/2];
steps=uicontrol(gui,'BackgroundColor',[1 1 1],...
'Style','edit',...
'String','128',...
'FontSize',fs,...
'Position',steps_pos,...
'Callback',@actual_and_approximate);
for i = 1:8
tablebox(i) = uicontrol(gui,'BackgroundColor',[1 1 1],...
'Position',[2/32*gsize(3)+20+(i-1)*(14/16*gsize(3)-40)/8 40/64*gsize(4)+20+(19/64*gsize(4)-40-2/3*lsteps_pos(4)) (14/16*gsize(3)-40)/8 2/3*lsteps_pos(4)],...
'Style','text',...
'FontSize',fs,...
'HorizontalAlignment','center',...
'String','');%19/64*gsize(4)-40
tablebox1(i) = uicontrol(gui,'BackgroundColor',[1 1 1],...
'Position',[2/32*gsize(3)+20+(i-1)*(14/16*gsize(3)-40)/8 40/64*gsize(4)+20 (14/16*gsize(3)-40)/8 19/64*gsize(4)-40-2/3*lsteps_pos(4)],...
'Style','text',...
'FontSize',fs,...
'HorizontalAlignment','center',...
'String','');%19/64*gsize(4)-40
end
set(tablebox(1),'String','n');
set(tablebox(2),'String','Exact Value');
set(tablebox(3),'String','Approx Value');
set(tablebox(4),'String','True Error');
set(tablebox(5),'String','Rel True Error');
set(tablebox(6),'String','Approx Error');
set(tablebox(7),'String','Rel Approx Error');
set(tablebox(8),'String','# of Correct Sig. Digits');
plot_pos=[1/16 5/32 7/8 28/64];
plot1=axes('position',plot_pos,...
'FontSize',fs);
actual_and_approximate %This runs the callback function immediately after loading all GUI items
end % end eulermethod
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -