function projectile_gradient2 ( )

%*****************************************************************************80
%
%% projectile_gradient2 uses gradient descent on the projectile function.
%
%  Discussion:
%
%    Gradient descent for a function of 2 variables.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 October 2019
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'projectile_gradient2:\n' );
  fprintf ( 1, '  Seek minimizer of sum-of-squares error for projectile data.\n' );
%
%  Choose a initial guess.
% 
  c0 = [ 1000.0, 2.0, -5.0 ];
%
%  Choose a small learning rate.
%
  r = 0.03;
%
%  Choose a small tolerance for the stepsize.
%
  dxtol = 0.00001;
%
%  Choose a small tolerance for the derivative.
%
  dftol = 0.001;
%
%  Maximum number of iterations
%
  itmax = 20000;

  [ c, it ] = gradient_descent2 ( @(c)projectile(c), @(c)projectile_df(c), c0, r, dxtol, dftol, itmax );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  %d gradient descent steps were taken.\n', it );
  fprintf ( 1, '  Initial c = (%g,%g,%g)\n', c0 );
  fprintf ( 1, '  f(c) = %g\n', projectile ( c0 ) )
  fprintf ( 1, '  f''(x,y) = (%g,%g,%g)\n', projectile_df ( c0 ) )
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Final   c = (%g,%g,%g)\n', c )
  fprintf ( 1, '  f(c) = %g\n', projectile ( c ) )
  fprintf ( 1, '  f''(x,y) = (%g,%g,%g)\n', projectile_df ( c ) )
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'projectile_gradient2:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  return
end
function e = projectile ( c )
  [ t, h ] = projectile_data ( );
  e = sum ( ( h - c(1) - c(2) * t - c(3) * t.^2 ).^2 );
  return
end
function dedc = projectile_df ( c )
  [ t, h ] = projectile_data ( );
  dedc1 = sum ( - 2.0 * ( h - c(1) - c(2) * t - c(3) * t.^2 ) );
  dedc2 = sum ( - 2.0 * ( h - c(1) - c(2) * t - c(3) * t.^2 ) .* t );
  dedc3 = sum ( - 4.0 * ( h - c(1) - c(2) * t - c(3) * t.^2 ) .* t.^2 );
  dedc = [ dedc1, dedc2, dedc3 ];
  return
end
function [ t, h ] = projectile_data ( )
  data = load ( 'projectile_data.txt' );
  t = data(:,1);
  h = data(:,2);
  return
end


