function [T, Y] = ode45octave(FUN, tspan, Y0, tol, varargin)1%ode45octave2% [T, Y] = ode45octave(FUN, tspan, Y0)3%4% Integra un sistema de ecuaciones diferenciales ordinarias usando el5% m�todo de Runge-Kutta en la variante Dormand-Price.6%7% [T, Y] = ode45octave(FUN, tspan, Y0, tol, par_1, par_2, ...)8% FUN funci�n con las derivadas9% tspan intervalo de integraci�n [tinicial, tfinal]10% Y0 magnitud inicial de las variables11% tol margen de error (por defecto 1e-10)12% par_i par�metros para FUN13% T puntos de integraci�n14% Y soluci�n del sistema de ecuaciones en cada punto15%16% Esta funci�n fue creada originalmente por Marc Compere17% http://users.powernet.co.uk/kienzle/octave/matcompat/scripts/ode_v1.11/ode45.m18% y modificada para simplificarla y garantizar la compatibilidad con19% Matlab. FUN debe usar la sintaxis de odefile en Matlab, de modo20% que dYdt = fun(t, Y, [], par_1, par_2, ...)2122if nargin < 4, tol = []; end23if isempty(tol), tol = 1e-10; end2425pow = 1/6; % see p.91 in the Ascher & Petzold reference for more infomation.2627% Use the Dormand-Prince 4(5) coefficients:28a_(1,1)=0;29a_(2,1)=1/5;30a_(3,1)=3/40; a_(3,2)=9/40;31a_(4,1)=44/45; a_(4,2)=-56/15; a_(4,3)=32/9;32a_(5,1)=19372/6561; a_(5,2)=-25360/2187; a_(5,3)=64448/6561; a_(5,4)=-212/729;33a_(6,1)=9017/3168; a_(6,2)=-355/33; a_(6,3)=46732/5247; a_(6,4)=49/176; a_(6,5)=-5103/18656;34a_(7,1)=35/384; a_(7,2)=0; a_(7,3)=500/1113; a_(7,4)=125/192; a_(7,5)=-2187/6784; a_(7,6)=11/84;35% 4th order b-coefficients36b4_(1,1)=5179/57600; b4_(2,1)=0; b4_(3,1)=7571/16695; b4_(4,1)=393/640; b4_(5,1)=-92097/339200; b4_(6,1)=187/2100; b4_(7,1)=1/40;37% 5th order b-coefficients38b5_(1,1)=35/384; b5_(2,1)=0; b5_(3,1)=500/1113; b5_(4,1)=125/192; b5_(5,1)=-2187/6784; b5_(6,1)=11/84; b5_(7,1)=0;3940for i=1:741c_(i)=sum(a_(i,:));42end4344% Initialization45t0 = tspan(1);46tfinal = tspan(2);47t = t0;48hmax = (tfinal - t) / 2.5;49hmin = (tfinal - t) / 1e9;50h = (tfinal - t)/100; % initial guess at a step size51x = Y0(:); % this always creates a column vector, x52T = t; % first output time53Y = x'; % first output solution54k_ = zeros(size(x,1), 7); % k_ needs to be initialized as an Nx7 matrix where N=number of rows in x55% (just for speed so octave doesn't need to allocate more memory at each stage value)5657% Compute the first stage prior to the main loop. This is part of the Dormand-Prince pair caveat.58% Normally, during the main loop the last stage for x(k) is the first stage for computing x(k+1).59% So, the very first integration step requires 7 function evaluations, then each subsequent step60% 6 function evaluations because the first stage is simply assigned from the last step's last stage.61% note: you can see this by the last element in c_ is 1.0, thus t+c_(7)*h = t+h, ergo, the next step.6263k_(:,1) = feval(FUN, t, x, [], varargin{1:nargin-4}); % first stage6465% The main loop using Dormand-Prince 4(5) pair66while (t < tfinal) * (h >= hmin),67if t + h > tfinal, h = tfinal - t; end6869% Compute the slopes by computing the k(:,j+1)'th column based on the previous k(:,1:j) columns70% notes: k_ needs to end up as an Nxs, a_ is 7x6, which is s by (s-1),71% s is the number of intermediate RK stages on [t (t+h)] (Dormand-Prince has s=7 stages)72for j = 1:673k_(:,j+1) = feval(FUN, t+c_(j+1)*h, x+h*k_(:,1:j)*a_(j+1,1:j)', [], varargin{1:nargin-4});74end7576% compute the 4th order estimate77x4 = x + h * (k_*b4_); % k_ is Nxs (or Nx7) and b4_ is a 7x17879% compute the 5th order estimate80x5 = x + h * (k_*b5_); % k_ is Nxs (or Nx7) and b5_ is a 7x18182% estimate the local truncation error83gamma1 = x5 - x4;8485% Estimate the error and the acceptable error86delta = norm(gamma1, 'inf'); % actual error87tau = tol * max(norm(x, 'inf'), 1.0); % allowable error8889% Update the solution only if the error is acceptable90if (delta <= tau)91t = t + h;92x = x5; % <-- using the higher order estimate is called 'local extrapolation'93T = [T; t];94Y = [Y; x'];95end9697% Update the step size98if (delta == 0.0), delta = 1e-16; end99h = min(hmax, 0.8*h*(tau/delta)^pow);100101% Assign the last stage for x(k) as the first stage for computing x(k+1).102% This is part of the Dormand-Prince pair caveat.103% k_(:,7) has already been computed, so use it instead of recomputing it104% again as k_(:,1) during the next step.105k_(:,1) = k_(:,7);106107end108109if (t < tfinal), disp('Step size grew too small.'); end110111if nargout == 0112plot(T, Y, 'o-');113T = [];114end115116117118