function [x, rate] = newton( f, df, x, tol, maxIter, verbose = false )
  % ----------------------------------------------------------------------
  % Jonathan Senning <jonathan.senning@gordon.edu>
  % Gordon College
  %
  % Usage: x = newton(@f, @df, x, tol, maxIter[, verbose])
  %        or
  %        [x,rate] = newton(@f, @df, x, tol, maxIter[, verbose])
  %
  % This function performs a Newton-Raphson iteration to solve f(x) = 0.
  %
  % This function requires that functions computing f(x) and f'(x) both
  % be already defined.
  % ----------------------------------------------------------------------

  if ( nargin ~= 5 && nargin ~= 6 )
    fprintf( '\aUsage: ' );
    fprintf( '[x,rate] = newton(@f, @df, x, tol, maxIter[, verbose])\n' );
    return
  end

  % These extra points are needed to start off the error calculation which
  % compares estimates of solutions just computed with previous estimates.

  x1 = x + 8.0 * tol;
  x0 = x + 4.0 * tol;

  k = 0;

  if verbose
    fprintf( '     k  Estimate of root  Est. diff.\n' );
    fprintf( '    -- ------------------ ----------\n' );
  end

  while ( k <= maxIter && abs( x - x0 ) >= tol )
    x2 = x1;
    x1 = x0;
    x0 = x;
    x = x - f( x ) / df( x );
    if verbose
      fprintf( '    %2d %18.11e %10.4e\n', k, x, abs( x - x0 ) );
    end
    k = k + 1;
  end

  if ( k > maxIter )
    fprintf( 'Error: exceeded %d iterations\n', maxIter );
  end

  rate = log( abs((x - x0) / (x0 - x1)) ) / log( abs((x0 - x1) / (x1 - x2)) );

end
