function [ t, y ] = adapt2 ( dydt, tspan, y0, dt, tol )

%*****************************************************************************80
%
%% adapt2 increases or decreases the stepsize based on an error estimate.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 October 2020
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    function handle dydt: defines the derivative function of the form
%      value = dydt ( t, y )
%
%    real tspan(2): contains the initial and final times.
%
%    real y0(m): contains the initial condition.
%
%    real dt: the size of the first step.
%
%    real tol: an error tolerance.
%
%  Output:
%
%    real t(n+1): the times.
%
%    real y(n+,m): the estimated solution values.
%
  t0 = tspan(1);
  tstop = tspan(2);
  dt_min = 1.0E-6;

  i = 1;
  t(i) = t0;
  y(i) = y0;

  while ( t(i) < tstop )

    y1 = y(i) + dt * dydt ( t(i), y(i) );
 
    th = t(i) + dt / 2.0;
    yh = y(i) + dt / 2.0 * dydt ( t(i), y(i) );
    y2 = yh   + dt / 2.0 * dydt ( th, yh );

    t(i+1) = t(i) + dt;
    y(i+1) = 2.0 * y2 - y1;
    i = i + 1;

    e = y2 - y1;
%
%  Decrease or increase stepsize if error is large or small.
%
    if ( 1.5 * tol * dt / ( tstop - t0 ) < norm ( e ) )
      dt = dt / 2.0;
    elseif ( norm ( e ) < 0.5 * tol * dt / ( tstop - t0 ) )
      dt = dt * 2.0;
    end
%
%  Don't let dt get too small!
%
    dt = max ( dt, dt_min );
%
%  If we are going past the endpoint, adjust dt.
%
    dt = min ( dt, tstop + eps - t(i) );

  end

  return
end

