home *** CD-ROM | disk | FTP | other *** search
- function [tout, yout] = ode45(ypfun, t0, tfinal, y0, tol, trace)
- %ODE45 Solve differential equations, higher order method.
- % ODE45 integrates a system of ordinary differential equations using
- % 4th and 5th order Runge-Kutta formulas.
- % [T,Y] = ODE45('yprime', T0, Tfinal, Y0) integrates the system of
- % ordinary differential equations described by the M-file YPRIME.M,
- % over the interval T0 to Tfinal, with initial conditions Y0.
- % [T, Y] = ODE45(F, T0, Tfinal, Y0, TOL, 1) uses tolerance TOL
- % and displays status while the integration proceeds.
- %
- % INPUT:
- % F - String containing name of user-supplied problem description.
- % Call: yprime = fun(t,y) where F = 'fun'.
- % t - Time (scalar).
- % y - Solution column-vector.
- % yprime - Returned derivative column-vector; yprime(i) = dy(i)/dt.
- % t0 - Initial value of t.
- % tfinal- Final value of t.
- % y0 - Initial value column-vector.
- % tol - The desired accuracy. (Default: tol = 1.e-6).
- % trace - If nonzero, each step is printed. (Default: trace = 0).
- %
- % OUTPUT:
- % T - Returned integration time points (column-vector).
- % Y - Returned solution, one solution column-vector per tout-value.
- %
- % The result can be displayed by: plot(tout, yout).
- %
- % See also ODE23, ODEDEMO.
-
- % C.B. Moler, 3-25-87, 8-26-91, 9-08-92.
- % Copyright (c) 1984-93 by The MathWorks, Inc.
-
- % The Fehlberg coefficients:
- alpha = [1/4 3/8 12/13 1 1/2]';
- beta = [ [ 1 0 0 0 0 0]/4
- [ 3 9 0 0 0 0]/32
- [ 1932 -7200 7296 0 0 0]/2197
- [ 8341 -32832 29440 -845 0 0]/4104
- [-6080 41040 -28352 9295 -5643 0]/20520 ]';
- gamma = [ [902880 0 3953664 3855735 -1371249 277020]/7618050
- [ -2090 0 22528 21970 -15048 -27360]/752400 ]';
- pow = 1/5;
- if nargin < 5, tol = 1.e-6; end
- if nargin < 6, trace = 0; end
-
- % Initialization
- t = t0;
- hmax = (tfinal - t)/16;
- h = hmax/8;
- y = y0(:);
- f = zeros(length(y),6);
- chunk = 128;
- tout = zeros(chunk,1);
- yout = zeros(chunk,length(y));
- k = 1;
- tout(k) = t;
- yout(k,:) = y.';
-
- if trace
- clc, t, h, y
- end
-
- % The main loop
-
- while (t < tfinal) & (t + h > t)
- if t + h > tfinal, h = tfinal - t; end
-
- % Compute the slopes
- temp = feval(ypfun,t,y);
- f(:,1) = temp(:);
- for j = 1:5
- temp = feval(ypfun, t+alpha(j)*h, y+h*f*beta(:,j));
- f(:,j+1) = temp(:);
- end
-
- % Estimate the error and the acceptable error
- delta = norm(h*f*gamma(:,2),'inf');
- tau = tol*max(norm(y,'inf'),1.0);
-
- % Update the solution only if the error is acceptable
- if delta <= tau
- t = t + h;
- y = y + h*f*gamma(:,1);
- k = k+1;
- if k > length(tout)
- tout = [tout; zeros(chunk,1)];
- yout = [yout; zeros(chunk,length(y))];
- end
- tout(k) = t;
- yout(k,:) = y.';
- end
- if trace
- home, t, h, y
- end
-
- % Update the step size
- if delta ~= 0.0
- h = min(hmax, 0.8*h*(tau/delta)^pow);
- end
- end
-
- if (t < tfinal)
- disp('Singularity likely.')
- t
- end
-
- tout = tout(1:k);
- yout = yout(1:k,:);
-