-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPopulationODEExample.m
More file actions
146 lines (130 loc) · 5.11 KB
/
PopulationODEExample.m
File metadata and controls
146 lines (130 loc) · 5.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
%% Population Ordinary Differential Equation Example
% The population of a habitat or area can be modeled by a differential
% equation (ODE). Here is a relatively simple model
%
% \begin{align*}
% t & = \text{time} \\
% y & = \text{population} \\
% \alpha & = \text{growth rate} \\
% \beta & = \text{limiting population} \\
% \gamma(t) & = \text{rate of immigration of emigration} \\
% \frac{\textrm{d}y}{\textrm{d}t} & = \alpha y (1 - y/\beta) + \gamma(t),
% \qquad 0 \le t \\
% y(0) &= y_0
% \end{align*}
%
% This ODE cannot be solved in general by analytic means. In this script
% we show how to numerically compute the solution for certain values of the
% parameters.
%% Population model
% First we set up the population ODE model.
InitializeWorkspaceDisplay %initialize the workspace and the display parameters
tic
alpha = 1.5; %low population growth rate
beta = 1000; %limiting population
gamma = @(t) 100.*real((t>=0)&(t<=1)); %immigration rate
f = @(t,y) alpha*y.*(1 - y/beta) + gamma(t); %right-hand-side of the ODE
y0 = 10; %initial condition
tint = [0,4]; %time interval
%% Euler's method
% The simplest method for solving ODEs is Euler's method. This method has
% been coded as follows
%
% <include>Euler.m</include>
%
% We will compute the Euler's method approximation to the population ODE
% for different time steps.
hvec = [0.5 0.1 0.05 0.01]; %vector of time steps
nh = numel(hvec); %number of different time steps
hand1 = zeros(nh,1); %initialize graphics handle
hand2 = hand1;
legtext=cell(nh,1); %initialize legend text
MATLABColors = [0, 0.447, 0.741; ... %these are
0.85, 0.325, 0.098; ... %MATLAB plotting
0.494, 0.184, 0.556; ... %colors that
0.466, 0.674, 0.188]; %we want to use
tplot=(tint(1):0.002:tint(2)); %times to plot at
for i=1:nh;
[tEuler,yEuler] = Euler(f,tint,y0,hvec(i)); %compute by Euler's method
yplot = spline(tEuler,yEuler,tplot); %values of y to plot
hand1(i) = plot(tEuler,yEuler,'.'); %plot y at times in Euler method
set(hand1(i),'color',MATLABColors(mod(i-1,4)+1,:))
hold on
hand2(i) = plot(tplot,yplot,'-'); %plot finer mesh of y values
set(hand2(i),'color',MATLABColors(mod(i-1,4)+1,:))
legtext{i} = ['\(h=' num2str(hvec(i)) '\)'];
end
axis([tint 0 1.1*max(yplot)])
xlabel('\(t\)')
ylabel('\(y(t)\)')
legend(hand1,legtext,'location','southeast')
print -depsc 'popEuler.eps'
%%
% Notice that as the stepsize gets smaller, the approximate answer
% converges (to the correct answer).
%% Modified Euler's method
% The modified Euler method is more accurate than Euler's method because it
% adds a correction to the original approximation at each time step. It has
% been coded as follows
%
% <include>modifiedEuler.m</include>
%
% We will compute the modified Euler's method approximation to the
% population ODE.
figure
for i=1:nh;
[tmEuler,ymEuler]=modifiedEuler(f,tint,y0,hvec(i)); %compute by modified Euler's method
yplot=spline(tmEuler,ymEuler,tplot); %values of y to plot
hand1(i) = plot(tmEuler,ymEuler,'.'); %plot y at times in the modified Euler method
set(hand1(i),'color',MATLABColors(mod(i-1,4)+1,:))
hold on
hand2(i) = plot(tplot,yplot,'-'); %plot finer mesh of y values
set(hand2(i),'color',MATLABColors(mod(i-1,4)+1,:))
legtext{i} = ['\(h=' num2str(hvec(i)) '\)'];
end
axis([tint 0 1.1*max(yplot)])
xlabel('\(t\)')
ylabel('\(y(t)\)')
legend(hand1,legtext,'location','southeast')
print -depsc 'popmodEuler.eps'
%%
% Again, as the stepsize gets smaller, the approximate answer converges (to
% the correct answer), but the convergence is faster.
%% |ode45|
% The modified Euler method is the simplest example of a Runge-Kutta
% method. MATLAB's |ode45| is a higher order Runge Kutta method, that
% automatically adjusts the step-size to meet the desired error tolerance.
% Notice that the number of time steps required for high accuracy is fewer
% than the Euler and modified Euler methods. According to the
% documentation, the default relative error tolerance is \(0.001\), and the
% default absolute error tolerance is \(0.000001\).
sol=ode45(f,tint,y0); %get solution as a structure variable
yplot=deval(sol,tplot); %evaluate solution of ODE at many points
figure
plot(tplot,yplot,'-',sol.x,sol.y,'.'); %plot solution
axis([tint 0 1200])
xlabel('\(t\)')
ylabel('\(y(t)\)')
print -depsc 'popode45.eps'
%% |ode113|
% The modified Euler method is also the simplest example of a
% predictor-corrector method. MATLAB's |ode113| is a higher (and even
% variable) order predictor-corrector method, that automatically adjusts
% the step-size to meet the desired error tolerance. Notice that the
% number of time steps required for high accuracy is fewer than the Euler
% and modified Euler methods. In this example, it requires more steps than
% the |ode45|.
sol=ode113(f,tint,y0); %get solution as a structure variable
yplot=deval(sol,tplot); %evaluate solution of ODE at many points
figure
plot(tplot,yplot,'-',sol.x,sol.y,'.'); %plot solution
axis([tint 0 1200])
xlabel('$t$')
ylabel('$y(t)$')
print -depsc 'popode113.eps'
toc
%%
% The additional steps needed after \(t = 1\) may be due to the
% discontinuity in the function \(\gamma\) at \(t = 1\).
%
% _Author: Fred J. Hickernell_