⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtl_ode_sim_eulerconv.m

📁 Eulers Method Ordinary Differential Equations
💻 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 + -