function ford_gradient2 ( )

%*****************************************************************************80
%
%% ford_gradient2 uses gradient descent on the Ford data.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 October 2019
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'ford_gradient2:\n' );
  fprintf ( 1, '  MATLAB version.\n' );
  fprintf ( 1, '  Gradient descent for Ford data.\n' );

  bm0 = [ 0.5, 0.0 ];
  r = 0.01;
  dxtol = 0.001;
  dftol = 0.001;
  itmax = 1000; 
  [ bm, it ] = gradient_descent2 ( @(x)ford_f(x), @(x)ford_df(x), bm0, ...
    r, dxtol, dftol, itmax );

  b = bm(1);
  m = bm(2);
%
%  Report the results.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Estimating model parameters:\n' );
  fprintf ( 1, '  x = normalized mileage\n' );
  fprintf ( 1, '  y = normalized price\n' );
  fprintf ( 1, '  Seek relationship y = b + m * x\n' );
  fprintf ( 1, '  b = %g\n', b );
  fprintf ( 1, '  m = %g\n', m );
%
%  Plot the data.
%
  [ x, y ] = ford_data ( );

  clf ( );
  hold ( 'on' );
  plot ( x, y, '.', 'MarkerSize', 35 );
  x2 = [ 0.0, 1.0 ];
  y2 = b + m * x2;
  plot ( x2, y2, 'linewidth', 3 );
  grid ( 'on' );
  xlabel ( 'Normalized mileage' );
  ylabel ( 'Normalized price' );
  title ( 'Ford Escort Price as Function of Mileage', 'Fontsize', 16 );
  hold ( 'off' );
  filename = 'ford_gradient2.png';
  print ( '-dpng', filename );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Graphics saved as "%s"\n', filename );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'ford_gradient2:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );

  return
end
function value = ford_f ( bm )

%*****************************************************************************80
%
%% ford_f evaluates the norm of the residual function.
%
%  Discussion:
%
%    For each data item (x,y,), we estimate y = b + m * x.
%
%    Our residual error is 
%      value = sum ( y - b - m * x )^2
%
  b = bm(1);
  m = bm(2);

  [ x, y ] = ford_data ( );

  value = sum ( ( y - b - m * x ).^2 );

  return
end
function value = ford_df ( bm )

%*****************************************************************************80
%
%% ford_df evaluates the gradient of the function to be minimized.
%
%  Discussion:
%
%    For each data item (x,y,), we estimate y = b + m * x.
%
%    Our residual error is 
%      value = sum ( y - b - m * x )^2
%
%    Our partial derivatives are:
%      d/db = sum - 2.0 * ( y - b - m * x )
%      d/dm = sum - 2.0 * ( y - b - m * x ) * x
%
  b = bm(1);
  m = bm(2);

  [ x, y ] = ford_data ( );

  dfdb = - 2.0 * sum ( ( y - b - m * x ) );
  dfdm = - 2.0 * sum ( ( y - b - m * x ) .* x );

  value = [ dfdb, dfdm ];

  return
end
function [ x, y ] = ford_data ( )

%*****************************************************************************80
%
%% ford_data returns a normalized copy of the Ford data.
%
  data = load ( 'ford_data.txt' );

  x = data(:,2);
  y = data(:,3);

  x = ( x - min ( x ) ) / ( max ( x ) - min ( x ) );
  y = ( y - min ( y ) ) / ( max ( y ) - min ( y ) );

  return
end




