Professor Diomar Cesar Lobao

Universidade Federal Fluminense-Volta Redonda, RJ, Brasil

Diomar Cesar


Dept. Ciências Exatas - Exact Science Dept.

Search

rk4ada.m

function [t,y] = rk4ada(func, a, b, y0, h1,errmax);
% solution of 1st order ODE using RK 4th order with adaptive step size
%
%      dy/dt = func(t,y)
%
% USAGE:  [t,y] = rk4ada(func,a,b,y0,h1,eps)
%
% input  func    = name of external function to evaluate the RHS
%                  of the ODE
%        a, b    = limits of integration
%        y0      = initial condition
%        h1      = initial stepsize
%        errmax  = desired absolute accuracy
%
% output [t, y]  = solution vectors

t = [a];
y = [y0];
i = 1;

while t(i) < b

   % first solution using h = h1
   h = h1;
   k1 = feval(func, t(i)    , y(i)       );
   k2 = feval(func, t(i)+h/2, y(i)+k1*h/2);
   k3 = feval(func, t(i)+h/2, y(i)+k2*h/2);
   k4 = feval(func, t(i)+h  , y(i)+k3*h  );
   y1 = y(i) + (k1 + 2*k2 + 2*k3 + k4)*h/6;

   % second solution using h = h1 / 2
   h = h1 / 2;
   k1 = feval(func, t(i)    , y(i)       );
   k2 = feval(func, t(i)+h/2, y(i)+k1*h/2);
   k3 = feval(func, t(i)+h/2, y(i)+k2*h/2);
   k4 = feval(func, t(i)+h  , y(i)+k3*h  );
   tm = t(i) + h;
   ym = y(i) + (k1 + 2*k2 + 2*k3 + k4)*h/6;

   k1 = feval(func, tm    , ym       );
   k2 = feval(func, tm+h/2, ym+k1*h/2);
   k3 = feval(func, tm+h/2, ym+k2*h/2);
   k4 = feval(func, tm+h  , ym+k3*h  );
   y2 = ym + (k1 + 2*k2 + 2*k3 + k4)*h/6;

   % estimate error, modify solution, change next step size
   delta = y2 - y1;

   i = i+1;
   t(i) = t(i-1) + h1;
   y(i) = y2 + delta/15;

   if abs(delta) < errmax   % error below tolerance
      alpha = .2;
   else                  % error too big
      alpha = .25;
   end

   h1 = h1*(errmax/abs(delta))^alpha

end
Skip to content