function [ t, y, e ] = rk12_adapt ( yprime, tspan, y0, dt, tol )

%*****************************************************************************80
%
%% rk12_adapt uses Runge-Kutta schemes of order 1 and 2 for adaptive steps.
%
%  Discussion:
%
%    This function approximates the solution of a differential
%    equation of the form:
%      y' = yprime(t,y)
%      y(tspan(1)) = y0
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    09 April 2020
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    function handle yprime: defines the derivative function of the form
%      value = yprime ( t, y )
%
%    real tspan(2): contains the initial and final times.
%
%    real y0(m): contains the initial condition.
%
%    real dt: the suggested initial stepsize.
%
%    real tol: a tolerance; truncation error must be less that tol * dt.
%
%  Output:
%
%    real t(n+1,1): the times.
%
%    real y(n+1,m): the estimated solution values.
%
%    real e(n+1): the estimated truncation errors.
%
  m = length ( y0 );
  n = 0;
  t = zeros ( n + 1, 1 );
  y = zeros ( n + 1, m );
  e = zeros ( n + 1, 1 );

  i = 1;
  t(1,1) = tspan(1);
  y(1,:) = y0(:);
  e(1) = 0.0;
  
  while ( t(i,1) < tspan(2) )     

    while ( true )

      t(i+1,1) = t(i,1) + dt;

      if ( t(i+1,1) > tspan(2) )
        t(i+1,1) = tspan(2);
        dt = t(i+1,1) - t(i,1);
      end

      k1 = dt * yprime ( t(i,1), y(i,:) );
      y1 = y(i,:) + k1';
      k2 = dt * yprime ( t(i,1) + dt, y(i,:) + k1' );
      y2 = y(i,:) + 0.5 * k1' + 0.5 * k2';

      y(i+1,:) = y2;
      e(i+1) = norm ( y2 - y1 );

      if ( tol * dt < e(i+1) )
        dt = dt / 2.0;
      elseif ( e(i+1) < tol * dt / 16.0 )
        dt = dt * 2.0;
        break;
      else
        break;
      end
      
    end
    
    i = i + 1;
    
  end

  return
end

