function [ slope, b ] = svd_lls ( h, w, h_name, w_name, prefix )

%*****************************************************************************80
%
%% svd_lls() finds a linear least squares relation between data vectors.
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    11 February 2019
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    real H(N), W(N), two vectors of data.
%
%    string H_NAME, W_NAME, names for the two sets of data.
%
%    string PREFIX, the prefix to be used for the three plot files.
%
%  Output:
%
%    real SLOPE, B, the slope and intercept of the least squares relations.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'SVD_LLS\n' );
  fprintf ( 1, '  Find best linear relation between two .\n' );
%
%  Data statistics.
%
  hmin = min ( h );
  have = mean ( h );
  hmax = max ( h );

  wmin = min ( w );
  wave = mean ( w );
  wmax = max ( w );

  fprintf ( 1, '\n' );
  fprintf ( 1, '           Min  Ave   Max\n' );
  fprintf ( 1, '  %s: %g  %g  %g\n', h_name, min ( h ), mean ( h ), max ( h ) );
  fprintf ( 1, '  %s: %g  %g  %g\n', w_name, min ( w ), mean ( w ), max ( w ) );
%
%  Data for centered variables.
%
  h2 = h - have;
  w2 = w - wave;
  h2min = min ( h2 );
  h2max = max ( h2 );
  w2min = min ( w2 );
  w2max = max ( w2 );
%
%  Create data matrix, get SVD, and determine the slope.
%
  A = [ h2, w2 ]';
  [ U, S, V ] = svd ( A );
  slope = U(2,1) / U(1,1);
  b = wave - slope * have;
%
%  Report numerics.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Linear relationship:\n' );
  fprintf ( 1, '    %s-average = %g * ( %s - average )\n', w_name, slope, h_name );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Affine relationship:\n' );
  fprintf ( 1, '    %s = %g * %s + %g\n', w_name, slope, h_name, b );
%
%  #1: Plot the data.
%
  figure ( 1 )
  clf
  hold on
  plot ( [ 0; h], [0;w], 'bo', 'linewidth', 1 );
  plot ( [0, hmax], [0,0], 'k-', 'linewidth', 3 );
  plot ( [0, 0],    [0,wmax], 'k-', 'linewidth', 3 );
  label = sprintf ( '<-- %s -->', h_name );
  xlabel ( label )
  label = sprintf ( '<-- %s -->', w_name );
  ylabel ( label )
  label = sprintf ( 'Data for %s versus %s\n', h_name, w_name );
  title ( label, 'Fontsize', 12 );
  grid ( 'on' );
  hold off
  filename = sprintf ( '%s_plot01.png', prefix );
  print ( '-dpng', filename );
  fprintf ( 1, '  Graphics saved as "%s\n', filename );
%
%  #2: Plot the linear relationship.
%
  figure ( 2 )
  clf
  hold on
  plot ( h2, w2, 'bo', 'linewidth', 1 );
  plot ( [h2min, h2max], [slope*h2min, slope*h2max], 'r-', 'linewidth', 3 );
  plot ( [h2min,h2max], [0,0], 'k-', 'linewidth', 3 );
  plot ( [0,0], [w2min,w2max], 'k-', 'linewidth', 3 );
  grid ( 'on' )
  label = sprintf ( '<-- %s - %g -->', h_name, have );
  xlabel ( label )
  label = sprintf ( '<-- %s - %g -->', w_name, wave );
  ylabel ( label )
  label = sprintf ( 'Linear Least Squares: (%s - average) = slope * (%s - average)', w_name, h_name );
  title ( label, 'Fontsize', 12 );
  hold off
  filename = sprintf ( '%s_plot02.png', prefix );
  print ( '-dpng', filename );
  fprintf ( 1, '  Graphics saved as "%s\n', filename );
%
%  #3: Plot the affine relationship.
%
  figure ( 3 )
  clf
  hold on
  plot ( [0;h], [0;w], 'bo', 'linewidth', 1 );
  plot ( [hmin, hmax], [ slope*hmin+b, slope*hmax+b], 'r-', 'linewidth', 3 );
  plot ( [0, hmax], [0,0], 'k-', 'linewidth', 3 );
  plot ( [0, 0],    [0,wmax], 'k-', 'linewidth', 3 );
  grid ( 'on' )
  label = sprintf ( '<-- %s -->', h_name );
  xlabel ( label )
  label = sprintf ( '<-- %s -->', w_name );
  ylabel ( label )
  label = sprintf ( 'Affine Least Squares: %s = slope * %s + b', w_name, h_name );
  title ( label, 'Fontsize', 12 );
  hold off
  filename = sprintf ( '%s_plot03.png', prefix );
  print ( '-dpng', filename );
  fprintf ( 1, '  Graphics saved as "%s\n', filename );

  return
end
 
