function [tout, yout] = bdode45(ypfun, t0, tfinal, y0, tol, trace) %BDODE45 is a slight modification of the routine ODE45 supplied with MATLAB, %which uses 4th and 5th order Runge-Kutta formulas to integrate a system of %ordinary differential equations. The only difference is that BDODE45 will %solve backwards (tfinal < t0) while ODE45 will not. Usage and variables are %exactly the same as for ODE45. Type "help ode45" for more information. % (M. Day 1/6/95) % 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; hmin=tol; hmax = (tfinal - t)/16; dir=sign(hmax); 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 (dir*t < dir*tfinal) & (dir*(t + h) > dir*t) if dir*(t + h) > dir*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 = hmax*min(1.0, 0.8*(h/hmax)*(tau/delta)^pow); end if dir*h