function x = parabolic_minimizer ( f, a, b, c, xtol )

%*****************************************************************************80
%
%% parabolic_minimizer estimates a minimizer using parabolic interpolation.
%
%  Discussion:
%
%    It is recommended that a < b < c, and that f(b) < f(a) and f(b) < f(c).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 October 2019
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    function handle f: the function for which a minimizer
%    is sought.
%
%    real a, b, c: three x values that sample the function near the
%    suspected minimizer, with a < b < c.
%
%    real xtol: a tolerance for the size of the interval 
%    dx = max(a,b,c)-min(a,b,c).  Once dx is smaller than xtol, the
%    iteration stops.
% 
%  Output:
%
%    real x: the estimated minimizer of the function.
%
  print_stuff = true;

  itmax = 100;

  if ( f(a) <= f(b) || f(c) <= f(b) )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'parabolic_minimizer - Warning!\n' );
    fprintf ( 1, '  f(b) < f(a) and f(b) < f(c) is recommended!\n' );
  end

  it = 0;

  while ( true )

    it = it + 1;

    if ( itmax < it )
      if ( print_stuff )
        fprintf ( 1, 'parabolic_minimizer: Reached iteration limit!\n' );
      end
    end

    abc_min = min ( [ a, b, c ] );
    abc_max = max ( [ a, b, c ] );
    dx = abc_max - abc_min;
    if ( dx < xtol )
      if ( print_stuff )
        fprintf ( 1, 'parabolic_minimizer: Success!\n' );
      end
      return
    end

    x = parabola_critical ( f, a, b, c );

    if ( print_stuff )
      fprintf ( 'it=%d  dx=%g  x=%16.10g  f(x)=%20.16g\n', it, dx, x, f(x) );
    end

    a = b;
    b = c;
    c = x;

  end

  return
end

