function r = normal_dataset ( m, n, seed, mu, a )

%*****************************************************************************80
%
%% NORMAL_DATASET generates a multivariate normal dataset and writes it to a file.
%
%  Usage:
%
%    x = normal_dataset ( m, n, seed, mu, a )
%
%    where
%
%    * M the spatial dimension;
%    * N the number of points to generate;
%    * SEED the seed, a positive integer;
%    * MU is the mean vector of dimension M;
%    * A is the MxM positive definite symmetric variance-covariance matrix;
%    * R is the M by N array created.
%
%    The command creates an M by N multivariate normal dataset and writes
%    it to the file "normal_M_N.txt".
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 December 2009
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'NORMAL_DATASET\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Generate a multivariate normal random dataset.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  The program requests input values from the user:\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  * M, the spatial dimension,\n' );
  fprintf ( 1, '  * N, the number of points to generate,\n' );
  fprintf ( 1, '  * SEED, a seed for the random number generator.\n' );
  fprintf ( 1, '  * MU, the mean vector of length M.\n' );
  fprintf ( 1, '  * A, the MxM positive definite symmetric variance-covariance matrix.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  The program generates the data and writes it to the file\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '    normal_M_N.txt\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  where "M" and "N" are the numeric values.\n' );
%
%  Get the spatial dimension.
%
  if ( nargin < 1 )
    fprintf ( 1, '\n' );
    m = input ( '  Enter the spatial dimension M: ' );
  else
    m = str2num ( m );
  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Spatial dimension M = %d\n', m );
%
%  Get the number of points.
%
  if ( nargin < 2 )
    fprintf ( 1, '\n' );
    n = input ( '  Enter the number of points N: ' );
  else
    n = str2num ( n );
  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Number of points N = %d\n', n );
%
%  Get the seed.
%
  if ( nargin < 3 )
    fprintf ( 1, '\n' );
    seed = input ( '  Enter the seed: ' );
  else
    seed = str2num ( seed );
  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  The seed = %d\n', seed );
%
%  Get the mean vector.
%
  if ( nargin < 4 )
    fprintf ( 1, '\n' );
    mu(1:m) = input ( '  Enter the mean vector MU' );
  else
    mu(1:m) = str2num ( mu(1:m) );
  end

  r8vec_print ( m, mu, '  The mean vector MU:' )
%
%  Get the variance-covariance matrix A.
%
  if ( nargin < 5 )
    fprintf ( 1, '\n' );
    a(1:m,1:m) = input ( '  Enter the variance-covariance matrix A' );
  else
    a(1:m,1:m) = str2num ( a(1:m,1:m) );
  end

  r8mat_print ( m, m, a, '  The variance-covariance matrix A:' )
%
%  Compute the data.
%
  r = multinormal_sample ( m, n, a, mu, seed );
%
%  Write it to a file.
%
  output_filename = ...
    strcat ( 'normal_', num2str ( m ), '_', num2str ( n ), '.txt' );

  r8mat_write ( output_filename, m, n, r );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  The data was written to the file "%s".\n', ...
    output_filename );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'NORMAL_DATASET:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );

  fprintf ( 1, '\n' );
  timestamp ( );

  return
end
function [ x, seed ] = multinormal_sample ( m, n, a, mu, seed )

%*****************************************************************************80
%
%% MULTINORMAL_SAMPLE samples a multivariate normal distribution.
%
%  Discussion:
%
%    The multivariate normal distribution for the M dimensional vector X
%    has the form:
%
%      pdf(X) = (2*pi*det(A))**(-M/2) * exp(-0.5*(X-MU)'*inverse(A)*(X-MU))
%
%    where MU is the mean vector, and A is a positive definite symmetric
%    matrix called the variance-covariance matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 December 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the dimension of the space.
%
%    Input, integer N, the number of points.
%
%    Input, real A(M,M), the variance-covariance
%    matrix.  A must be positive definite symmetric.
%
%    Input, real MU(M), the mean vector.
%
%    Input, integer SEED, the random number seed.
%
%    Output, real X(M), the points.
%
%    Output, integer SEED, the random number seed.
%

%
%  Compute the upper triangular Cholesky factor R of the variance-covariance
%  matrix.
%
  [ r, info ] = r8po_fa ( m, a );

  if ( info ~= 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'MULTINORMAL_SAMPLE - Fatal error!\n' );
    fprintf ( 1, ...
      '  The variance-covariance matrix is not positive definite symmetric.\n' );
    error ( 'MULTINORMAL_SAMPLE - Fatal error!' );
  end
%
%  Get an MxN vector of samples of the 1D normal distribution with mean 0
%  and variance 1.
%
  [ x(1:m*n), seed ] = r8vec_normal_01 ( m*n, seed );
%
%  Reshape the vector to an MxN matrix.
%
  x = reshape ( x, m, n );
%
%  Compute MU + R' * X.
%
  for j = 1 : n
    x(1:m,j) = mu(1:m)' + r(1:m,1:m)' * x(1:m,j);
  end

  return
end
function r8mat_print ( m, n, a, title )

%*****************************************************************************80
%
%% R8MAT_PRINT prints an R8MAT.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the number of rows in A.
%
%    Input, integer N, the number of columns in A.
%
%    Input, real A(M,N), the matrix.
%
%    Input, string TITLE, a title to be printed.
%
  r8mat_print_some ( m, n, a, 1, 1, m, n, title );

  return
end
function r8mat_print_some ( m, n, a, ilo, jlo, ihi, jhi, title )

%*****************************************************************************80
%
%% R8MAT_PRINT_SOME prints out a portion of an R8MAT.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 September 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, N, the number of rows and columns of the matrix.
%
%    Input, real A(M,N), an M by N matrix to be printed.
%
%    Input, integer ILO, JLO, the first row and column to print.
%
%    Input, integer IHI, JHI, the last row and column to print.
%
%    Input, string TITLE, a title.
%
  incx = 5;

  fprintf ( 1, '\n' );
  fprintf ( 1, '%s\n', title );

  for j2lo = max ( jlo, 1 ): incx : min ( jhi, n )

    j2hi = j2lo + incx - 1;
    j2hi = min ( j2hi, n );
    j2hi = min ( j2hi, jhi );

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Col: ' );

    for j = j2lo : j2hi
      fprintf ( 1, '%7d       ', j );
    end

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Row\n' );

    i2lo = max ( ilo, 1 );
    i2hi = min ( ihi, m );

    for i = i2lo : i2hi

      fprintf ( 1, '%7d  ', i );

      for j = j2lo : j2hi
        fprintf ( 1, '%12g  ', a(i,j) );
      end

      fprintf ( 1, '\n' );

    end

  end

  return
end
function r8mat_write ( output_filename, m, n, table )

%*****************************************************************************80
%
%% R8MAT_WRITE writes an R8MAT file.
%
%  Discussion:
%
%    An R8MAT is an array of R8's.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 August 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string OUTPUT_FILENAME, the output filename.
%
%    Input, integer M, the spatial dimension.
%
%    Input, integer N, the number of points.
%
%    Input, real TABLE(M,N), the points.
%

%
%  Open the file.
%
  output_unit = fopen ( output_filename, 'wt' );

  if ( output_unit < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'R8MAT_WRITE - Error!\n' );
    fprintf ( 1, '  Could not open the output file.\n' );
    error ( 'R8MAT_WRITE - Error!' );
  end
%
%  Write the data.
%
%  For smaller data files, and less precision, try:
%
%     fprintf ( output_unit, '  %14.6f', table(i,j) );
%
  for j = 1 : n
    for i = 1 : m
      fprintf ( output_unit, '  %24.16f', table(i,j) );
    end
    fprintf ( output_unit, '\n' );
  end
%
%  Close the file.
%
  fclose ( output_unit );

  return
end
function [ r, info ] = r8po_fa ( n, a )

%*****************************************************************************80
%
%% R8PO_FA factors a R8PO matrix.
%
%  Discussion:
%
%    The R8PO storage format is appropriate for a symmetric positive definite
%    matrix and its inverse.  (The Cholesky factor of a R8PO matrix is an
%    upper triangular matrix, so it will be in R8GE storage format.)
%
%    Only the diagonal and upper triangle of the square array are used.
%    This same storage scheme is used when the matrix is factored by
%    R8PO_FA, or inverted by R8PO_INVERSE.  For clarity, the lower triangle
%    is set to zero.
%
%    The positive definite symmetric matrix A has a Cholesky factorization
%    of the form:
%
%      A = R' * R
%
%    where R is an upper triangular matrix with positive elements on
%    its diagonal.  This routine overwrites the matrix A with its
%    factor R.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 February 2004
%
%  Author:
%
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Dongarra, Bunch, Moler, Stewart,
%    LINPACK User's Guide,
%    SIAM, 1979.
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%
%    Input, real A(N,N), the matrix in R8PO storage.
%
%    Output, real R(N,N), the Cholesky factor R in R8GE storage.
%
%    Output, integer INFO, error flag.
%    0, normal return.
%    K, error condition.  The principal minor of order K is not
%    positive definite, and the factorization was not completed.
%
  r(1:n,1:n) = a(1:n,1:n);

  for j = 1 : n

    for k = 1 : j - 1
      t = 0.0;
      for i = 1 : k-1
        t = t + r(i,k) * r(i,j);
      end
      r(k,j) = ( r(k,j) - t ) / r(k,k);
    end

    t = 0.0;
    for i = 1 : j - 1
      t = t + r(i,j)^2;
    end

    s = r(j,j) - t;

    if ( s <= 0.0 )
      info = j;
      return;
    end

    r(j,j) = sqrt ( s );

  end

  info = 0;
%
%  Since the Cholesky factor is stored in R8GE format, be sure to
%  zero out the lower triangle.
%
  for i = 1 : n
    for j = 1 : i-1
      r(i,j) = 0.0;
    end
  end

  return
end
function [ x, seed ] = r8vec_normal_01 ( n, seed )

%*****************************************************************************80
%
%% R8VEC_NORMAL_01 returns a unit pseudonormal R8VEC.
%
%  Discussion:
%
%    The standard normal probability distribution function (PDF) has
%    mean 0 and standard deviation 1.
%
%    This routine can generate a vector of values on one call.  It
%    has the feature that it should provide the same results
%    in the same order no matter how we break up the task.
%
%    Before calling this routine, the user may call RANDOM_SEED
%    in order to set the seed of the random number generator.
%
%    The Box-Muller method is used, which is efficient, but
%    generates an even number of values each time.  On any call
%    to this routine, an even number of new values are generated.
%    Depending on the situation, one value may be left over.
%    In that case, it is saved for the next call.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 July 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of values desired.  If N is negative,
%    then the code will flush its internal memory; in particular,
%    if there is a saved value to be used on the next call, it is
%    instead discarded.  This is useful if the user has reset the
%    random number seed, for instance.
%
%    Input, integer SEED, a seed for the random number generator.
%
%    Output, real X(N), a sample of the standard normal PDF.
%
%    Output, integer SEED, an updated seed for the random number generator.
%
%  Local parameters:
%
%    Local, integer MADE, records the number of values that have
%    been computed.  On input with negative N, this value overwrites
%    the return value of N, so the user can get an accounting of
%    how much work has been done.
%
%    Local, real R(N+1), is used to store some uniform random values.
%    Its dimension is N+1, but really it is only needed to be the
%    smallest even number greater than or equal to N.
%
%    Local, integer SAVED, is 0 or 1 depending on whether there is a
%    single saved value left over from the previous call.
%
%    Local, integer X_LO_INDEX, X_HI_INDEX, records the range of entries of
%    X that we need to compute.  This starts off as 1:N, but is adjusted
%    if we have a saved value that can be immediately stored in X(1),
%    and so on.
%
%    Local, real Y, the value saved from the previous call, if
%    SAVED is 1.
%
  persistent made;
  persistent saved;
  persistent y;
%
%  I'd like to allow the user to reset the internal data.
%  But this won't work properly if we have a saved value Y.
%  I'm making a crock option that allows the user to signal
%  explicitly that any internal memory should be flushed,
%  by passing in a negative value for N.
%
  if ( n < 0 )
    made = 0;
    saved = 0;
    y = 0.0;
    x = [];
    return
  elseif ( n == 0 )
    x = [];
    return
  end
%
%  Record the range of X we need to fill in.
%
  x_lo_index = 1;
  x_hi_index = n;
%
%  Use up the old value, if we have it.
%
  if ( saved == 1 )
    x(1) = y;
    saved = 0;
    x_lo_index = 2;
  end
%
%  Maybe we don't need any more values.
%
  if ( x_hi_index - x_lo_index + 1 == 0 )
%
%  If we need just one new value, do that here to avoid null arrays.
%
  elseif ( x_hi_index - x_lo_index + 1 == 1 )

    [ r, seed ] = r8vec_uniform_01 ( 2, seed );

    x(x_hi_index) = ...
      sqrt ( -2.0 * log ( r(1) ) ) * cos ( 2.0 * pi * r(2) );
    y =      sqrt ( -2.0 * log ( r(1) ) ) * sin ( 2.0 * pi * r(2) );

    saved = 1;

    made = made + 2;
%
%  If we require an even number of values, that's easy.
%
  elseif ( mod ( x_hi_index - x_lo_index + 1, 2 ) == 0 )

    m = floor ( ( x_hi_index - x_lo_index + 1 ) / 2 );

    [ r, seed ] = r8vec_uniform_01 ( 2*m, seed );

    x(x_lo_index:2:x_hi_index-1) = ...
      sqrt ( -2.0 * log ( r(1:2:2*m-1) ) ) ...
      .* cos ( 2.0 * pi * r(2:2:2*m) );

    x(x_lo_index+1:2:x_hi_index) = ...
      sqrt ( -2.0 * log ( r(1:2:2*m-1) ) ) ...
      .* sin ( 2.0 * pi * r(2:2:2*m) );

    made = made + x_hi_index - x_lo_index + 1;
%
%  If we require an odd number of values, we generate an even number,
%  and handle the last pair specially, storing one in X(N), and
%  saving the other for later.
%
  else

    x_hi_index = x_hi_index - 1;

    m = floor ( ( x_hi_index - x_lo_index + 1 ) / 2 ) + 1;

    [ r, seed ] = r8vec_uniform_01 ( 2*m, seed );

    x(x_lo_index:2:x_hi_index-1) = ...
      sqrt ( -2.0 * log ( r(1:2:2*m-3) ) ) ...
      .* cos ( 2.0 * pi * r(2:2:2*m-2) );

    x(x_lo_index+1:2:x_hi_index) = ...
      sqrt ( -2.0 * log ( r(1:2:2*m-3) ) ) ...
      .* sin ( 2.0 * pi * r(2:2:2*m-2) );

    x(n) = sqrt ( -2.0 * log ( r(2*m-1) ) ) ...
      * cos ( 2.0 * pi * r(2*m) );

    y = sqrt ( -2.0 * log ( r(2*m-1) ) ) ...
      * sin ( 2.0 * pi * r(2*m) );

    saved = 1;

    made = made + x_hi_index - x_lo_index + 2;

  end

  return
end
function r8vec_print ( n, a, title )

%*****************************************************************************80
%
%% R8VEC_PRINT prints a real vector.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 January 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the dimension of the vector.
%
%    Input, real A(N), the vector to be printed.
%
%    Input, string TITLE, a title.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '%s\n', title );
  fprintf ( 1, '\n' );
  for i = 1 : n
    fprintf ( 1, '%6d  %12f\n', i, a(i) );
  end

  return
end
function [ r, seed ] = r8vec_uniform_01 ( n, seed )

%*****************************************************************************80
%
%% R8VEC_UNIFORM_01 returns a unit pseudorandom R8VEC.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 September 2006
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Paul Bratley, Bennett Fox, Linus Schrage,
%    A Guide to Simulation,
%    Second Edition,
%    Springer, 1987,
%    ISBN: 0387964673,
%    LC: QA76.9.C65.B73.
%
%    Bennett Fox,
%    Algorithm 647:
%    Implementation and Relative Efficiency of Quasirandom
%    Sequence Generators,
%    ACM Transactions on Mathematical Software,
%    Volume 12, Number 4, December 1986, pages 362-376.
%
%    Pierre L'Ecuyer,
%    Random Number Generation,
%    in Handbook of Simulation,
%    edited by Jerry Banks,
%    Wiley, 1998,
%    ISBN: 0471134031,
%    LC: T57.62.H37.
%
%    Peter Lewis, Allen Goodman, James Miller,
%    A Pseudo-Random Number Generator for the System/360,
%    IBM Systems Journal,
%    Volume 8, Number 2, 1969, pages 136-143.
%
%  Parameters:
%
%    Input, integer N, the number of entries in the vector.
%
%    Input, integer SEED, a seed for the random number generator.
%
%    Output, real R(N), the vector of pseudorandom values.
%
%    Output, integer SEED, an updated seed for the random number generator.
%
  i4_huge = 2147483647;

  if ( seed == 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'R8VEC_UNIFORM_01 - Fatal error!\n' );
    fprintf ( 1, '  Input SEED = 0!\n' );
    error ( 'R8VEC_UNIFORM_01 - Fatal error!' );
  end

  r = zeros ( n, 1 );

  for i = 1 : n

    k = floor ( seed / 127773 );

    seed = 16807 * ( seed - k * 127773 ) - k * 2836;

    if ( seed < 0 )
      seed = seed + i4_huge;
    end

    r(i) = seed * 4.656612875E-10;

  end

  return
end
function timestamp ( )

%*****************************************************************************80
%
%% TIMESTAMP prints the current YMDHMS date as a timestamp.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
  t = now;
  c = datevec ( t );
  s = datestr ( c, 0 );
  fprintf ( 1, '%s\n', s );

  return
end


% IM = mkSine(SIZE, PERIOD, DIRECTION, AMPLITUDE, PHASE, ORIGIN)
%      or
% IM = mkSine(SIZE, FREQ, AMPLITUDE, PHASE, ORIGIN)
%
% Compute a matrix of dimension SIZE (a [Y X] 2-vector, or a scalar)
% containing samples of a 2D sinusoid, with given PERIOD (in pixels),
% DIRECTION (radians, CW from X-axis, default = 0), AMPLITUDE (default
% = 1), and PHASE (radians, relative to ORIGIN, default = 0).  ORIGIN
% defaults to the center of the image.
%
% In the second form, FREQ is a 2-vector of frequencies (radians/pixel).

% Eero Simoncelli, 6/96.

function [res] = mkSine(sz, per_freq, dir_amp, amp_phase, phase_orig, orig)

%------------------------------------------------------------
%% OPTIONAL ARGS:

if (prod(size(per_freq)) == 2)
  frequency = norm(per_freq);
  direction = atan2(per_freq(1),per_freq(2));
  if (exist('dir_amp') == 1)
    amplitude = dir_amp;
  else
    amplitude = 1;
  end
  if (exist('amp_phase') == 1)
    phase = amp_phase;
  else
    phase = 0;
  end
  if (exist('phase_orig') == 1)
    origin = phase_orig;
  end
  if (exist('orig') == 1)
    error('Too many arguments for (second form) of mkSine');
  end
else
  frequency = 2*pi/per_freq;
  if (exist('dir_amp') == 1)
    direction = dir_amp;
  else
    direction = 0;
  end
  if (exist('amp_phase') == 1)
    amplitude = amp_phase;
  else
    amplitude = 1;
  end
  if (exist('phase_orig') == 1)
    phase = phase_orig;
  else
    phase = 0;
  end
  if (exist('orig') == 1)
    origin = orig;
  end
end

%------------------------------------------------------------

if (exist('origin') == 1)
  res = amplitude*sin(mkRamp(sz, direction, frequency, phase, origin));
else
 res = amplitude*sin(mkRamp(sz, direction, frequency, phase));
end


% IM = mkAngle(SIZE, PHASE, ORIGIN)
%
% Compute a matrix of dimension SIZE (a [Y X] 2-vector, or a scalar)
% containing samples of the polar angle (in radians, CW from the
% X-axis, ranging from -pi to pi), relative to angle PHASE (default =
% 0), about ORIGIN pixel (default = (size+1)/2).

% Eero Simoncelli, 6/96.

function [res] = mkAngle(sz, phase, origin)

sz = sz(:);
if (size(sz,1) == 1)
  sz = [sz,sz];
end

% -----------------------------------------------------------------
% OPTIONAL args:

if (exist('origin') ~= 1)
  origin = (sz+1)/2;
end

% -----------------------------------------------------------------

[xramp,yramp] = meshgrid( [1:sz(2)]-origin(2), [1:sz(1)]-origin(1) );

res = atan2(yramp,xramp);

if (exist('phase') == 1)
  res = mod(res+(pi-phase),2*pi)-pi;
end


function center = polylineCentroid(varargin)
%POLYLINECENTROID Computes the centroid of a curve defined by a series of points.
%
%   PT = polylineCentroid(POINTS);
%   Computes center of mass of a polyline defined by POINTS. POINTS is a
%   N-by-D array of double, representing a set of N points in a
%   D-dimensional space.
%
%   PT = polylineCentroid(PTX, PTY);
%   PT = polylineCentroid(PTX, PTY, PTZ);
%   Specifies points as separate column vectors
%
%   PT = polylineCentroid(..., TYPE);
%   Specifies if the last point is connected to the first one. TYPE can be
%   either 'closed' or 'open'.
%
%   Example
%   poly = [0 0;10 0;10 10;20 10];
%   polylineCentroid(poly)
%   ans =
%       [10 5]
%
%   See also
%     polygons2d, centroid, polygonCentroid, polylineLength
%

% ------
% Author: David Legland
% E-mail: david.legland@inrae.fr
% Created: 2006-05-22
% Copyright 2006-2022 INRA - TPV URPOI - BIA IMASTE

%% process input arguments

% check whether the curve is closed
closed = false;
var = varargin{end};
if ischar(var)
    if strcmpi(var, 'closed')
        closed = true;
    end
    % remove last argument
    varargin(end) = [];
end

% extract point coordinates
if length(varargin)==1
    points = varargin{1};
elseif length(varargin)==2
    points = [varargin{1} varargin{2}];
end

%% Main computation

% compute centers and lengths composing the curve
if closed
    centers = (points + points([2:end 1],:))/2;
    lengths = sqrt(sum(diff(points([1:end 1],:)).^2, 2));
else
    centers = (points(1:end-1,:) + points(2:end,:))/2;
    lengths = sqrt(sum(diff(points).^2, 2));
end

% centroid of edge centers weighted by edge length
%weigths = repmat(lengths/sum(lengths), [1 size(points, 2)]);
center = sum(centers .* repmat(lengths, [1 size(points, 2)]), 1) / sum(lengths);


function cdf = sech_cdf ( x, a, b )

%*****************************************************************************80
%
%% SECH_CDF evaluates the Hyperbolic Secant CDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the argument of the PDF.
%
%    Input, real A, B, the parameter of the PDF.
%    0.0 < B.
%
%    Output, real CDF, the value of the CDF.
%
  y = ( x - a ) / b;

  cdf = 2.0 * atan ( exp ( y ) ) / pi;

  return
end


function [xn, xmean, xstd] = normdata(x,xmean,xstd)
%NORMDATA  Normalize input to zero mean and unit variance
%
%  Description
%    [XN, XMEAN, XSTD] = NORMDATA(X) normalizes X to zero mean and
%    unit variance. Returns normalized XN, mean of X XMEAN and
%    standard deviance of X XSTD.
%
%    XN = NORMDATA(X,XMEAN,XSTD) normalizes X using precomputed
%    XMEAN and XSTD.
%
%  See also DENORMDATA
%

% Copyright (c) 2010 Aki Vehtari

% This software is distributed under the GNU General Public
% License (version 3 or later); please refer to the file
% License.txt, included with the software, for details.

  if nargin<=1
    xmean=nanmean(x);
    xstd=nanstd(x);
  end
  xn=bsxfun(@rdivide,bsxfun(@minus,x,xmean),xstd);


function [FisoInd]=faceIsotropyIndex(F,V)
%% function for computing  triangular faces isotropy index.
% This is an index of the  "regularity" of the triangle. Equilateral triangle (perfectly regular)
%
% INPUTS:
% * F: nFaces-by-3 array representing the list of vertices for triangular faces
% * V: nVertices-by-3 array representing the 3d positions of the vertices of F in the reference positions
%
% OUTPUTS:
% * FisoInd: isotropy index for each face. value of 1 means perfectly
% equilateral. value of 0 means vertices are aligned (on a line)
%
%From the paper: Surface-Marker Cluster Design Criteria for 3-D Bone Movement Reconstruction (1997)
% Aurelio Cappozzo, Angelo Cappello, Ugo Della Croce, and Francesco Pensalfini
%%

FisoInd=zeros(size(F,1),1);
for iface=1:size(F,1)

    x1=V(F(iface,1),:)';
    x2=V(F(iface,2),:)';
    x3=V(F(iface,3),:)';

    if any(any(isnan([x1 x2 x3]))) % if any nan, iso index=nan
        FisoInd(iface)=NaN;
    else
        xa=(x1+x2+x3)/3;
        X=[x1-xa,x2-xa,x3-xa]; %cluster position model
        K=X*X'/3;
        Keig=real(eig(K)); %eigenvalues of X
        FisoInd(iface)=2*Keig(2)/(Keig(2)+Keig(3)); % isotropy index
    end
end

end

%%
% MultiDIC: a MATLAB Toolbox for Multi-View 3D Digital Image Correlation
%
% License: <https://github.com/MultiDIC/MultiDIC/blob/master/LICENSE.txt>
%
% Copyright (C) 2018  Dana Solav
%
% If you use the toolbox/function for your research, please cite our paper:
% <https://engrxiv.org/fv47e>


% Find the Least Root Mean Square distance
% between two sets of N points in D dimensions
% and the rigid transformation (i.e. translation and rotation)
% to employ in order to bring one set that close to the other,
% Using the Kabsch (1976) algorithm.
% Note that the points are paired, i.e. we know which point in one set
% should be compared to a given point in the other set.
%
% References:
% 1) Kabsch W. A solution for the best rotation to relate two sets of vectors. Acta Cryst A 1976;32:9223.
% 2) Kabsch W. A discussion of the solution for the best rotation to relate two sets of vectors. Acta Cryst A 1978;34:8278.
% 3) http://cnx.org/content/m11608/latest/
% 4) http://en.wikipedia.org/wiki/Kabsch_algorithm
%
% We slightly generalize, allowing weights given to the points.
% Those weights are determined a priori and do not depend on the distances.
%
% We work in the convention that points are column vectors;
% some use the convention where they are row vectors instead.
%
% Input  variables:
%  P : a D*N matrix where P(a,i) is the a-th coordinate of the i-th point
%      in the 1st representation
%  Q : a D*N matrix where Q(a,i) is the a-th coordinate of the i-th point
%      in the 2nd representation
%  m : (Optional) a row vector of length N giving the weights, i.e. m(i) is
%      the weight to be assigned to the deviation of the i-th point.
%      If not supplied, we take by default the unweighted (or equal weighted)
%      m(i) = 1/N.
%      The weights do not have to be normalized;
%      we divide by the sum to ensure sum_{i=1}^N m(i) = 1.
%      The weights must be non-negative with at least one positive entry.
% Output variables:
%  U : a proper orthogonal D*D matrix, representing the rotation
%  r : a D-dimensional column vector, representing the translation
%  lrms: the Least Root Mean Square
%
% Details:
% If p_i, q_i are the i-th point (as a D-dimensional column vector)
% in the two representations, i.e. p_i = P(:,i) etc., and for
% p_i' = U p_i + r      (' does not stand for transpose!)
% we have p_i' ~ q_i, that is,
% lrms = sqrt(sum_{i=1}^N m(i) (p_i' - q_i)^2)
% is the minimal rms when going over the possible U and r.
% (assuming the weights are already normalized).
%
function[U, r, lrms] = Kabsch(P, Q, m)
	sz1 = size(P) ;
	sz2 = size(Q) ;
	if (length(sz1) ~= 2 || length(sz2) ~= 2)
		error 'P and Q must be matrices' ;
	end
	if (any(sz1 ~= sz2))
		error 'P and Q must be of same size' ;
	end
	D = sz1(1) ;         % dimension of space
	N = sz1(2) ;         % number of points
	if (nargin >= 3)
		if (~isvector(m) || any(size(m) ~= [1 N]))
			error 'm must be a row vector of length N' ;
		end
		if (any(m < 0))
			error 'm must have non-negative entries' ;
		end
		msum = sum(m) ;
		if (msum == 0)
			error 'm must contain some positive entry' ;
		end
		m = m / msum ;     % normalize so that weights sum to 1
	else                 % m not supplied - use default
		m = ones(1,N)/N ;
	end

	p0 = P*m' ;          % the centroid of P
	q0 = Q*m' ;          % the centroid of Q
	v1 = ones(1,N) ;     % row vector of N ones
	P = P - p0*v1 ;      % translating P to center the origin
	Q = Q - q0*v1 ;      % translating Q to center the origin

	% C is a covariance matrix of the coordinates
	% C = P*diag(m)*Q'
	% but this is inefficient, involving an N*N matrix, while typically D << N.
	% so we use another way to compute Pdm = P*diag(m),
	% which is equivalent to, but more efficient than,
	% Pdm = zeros(D,N) ;
	% for i=1:N
	% 	Pdm(:,i) = m(i)*P(:,i) ;
	% end
	Pdm = bsxfun(@times,m,P) ;
	C = Pdm*Q' ;
%	C = P*Q' / N ;       % (for the non-weighted case)
	[V,S,W] = svd(C) ;   % singular value decomposition
	I = eye(D) ;
	if (det(V*W') < 0)   % more numerically stable than using (det(C) < 0)
		I(D,D) = -1 ;
	end
	U = W*I*V' ;

	r = q0 - U*p0 ;

	Diff = U*P - Q ;     % P, Q already centered
%	lrms = sqrt(sum(sum(Diff.*Diff))/N) ; % (for the non-weighted case)
	% to compute the lrms, we employ an efficient method, equivalent to:
	% lrms = 0 ;
	% for i=1:N
	% 	lrms = lrms + m(i)*Diff(:,i)'*Diff(:,i) ;
	% end
	% lrms = sqrt(lrms) ;
	lrms = sqrt(sum(sum(bsxfun(@times,m,Diff).*Diff))) ;
end


function [J, grad] = costFunction(theta, X, y)
%COSTFUNCTION Compute cost and gradient for logistic regression
%   J = COSTFUNCTION(theta, X, y) computes the cost of using theta as the
%   parameter for logistic regression and the gradient of the cost
%   w.r.t. to the parameters.

% Initialize some useful values
m = length(y); % number of training examples

% You need to return the following variables correctly
J = 0;
grad = zeros(size(theta));

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost of a particular choice of theta.
%               You should set J to the cost.
%               Compute the partial derivatives and set grad to the partial
%               derivatives of the cost w.r.t. each parameter in theta
%
% Note: grad should have the same dimensions as theta
%
h_theta = sigmoid(X*theta);
J = (1 / m) * ((-y' * log(h_theta)) - (1 - y)' * log(1 - h_theta));

grad = (1 / m) * (h_theta - y)' * X;

% =============================================================

end


% gerschdisc.m
%
% This function plots the Gershgorin Discs for the matrix A passed as an argument.
% It will also plot the centers of such discs, and the actual eigenvalues
% of the matrix.

function gershdisc(A)

error(nargchk(nargin,1,1));
if size(A,1) ~= size(A,2)
    error('Matrix should be square');
    return;
end

% For each row, we say:
for i=1:size(A,1)
    % The circle has center in (h,k) where h is the real part of A(i,i) and
    % k is the imaginary part of A(i,i)   :
    h=real(A(i,i)); k=imag(A(i,i));

    % Now we try to compute the radius of the circle, which is nothing more
    % than the sum of norm of the elements in the row where i != j
    r=0;
    for j=1:size(A,1)
       if i ~= j
           r=r+(norm(A(i,j)));
       end
    end

    % We try to make a vector of points for the circle:
    N=256;
    t=(0:N)*2*pi/N;

    % Now we're able to map each of the elements of this vector into a
    % circle:
    plot( r*cos(t)+h, r*sin(t)+k ,'-');

    % We also plot the center of the circle for better undesrtanding:
    hold on;
    plot( h, k,'+');
end

% For the circles to be better graphed, we would like to have equal axis:
axis equal;

% Now we plot the actual eigenvalues of the matrix:
ev=eig(A);
for i=1:size(ev)
    rev=plot(real(ev(i)),imag(ev(i)),'ro');
end
hold off;
legend(rev,'Actual Eigenvalues');

end


function chi2 = chi_squared(y,fit,P,eb)

% returns *reduced* chi^2 value for use in data modelling
% "y" is a vector of data, "fit" is a vector of model values (size(fit)=size(y)), P is the number of
% parameters fit in the model, and eb is a vector of error bars (1-to-1 correspondnce with y)
% Ref: John R. Taylor, "An Introduction to Error Analysis", (2nd ed., 1997)
% 11/11/01 Mike Scarpulla.  Please direct questions or comments to scarps@uclink.berkeley.edu
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if nargin<3
    error('Wrong number of arguments passed to "chi_squared"')
end

% if error bars are not availible, evaluate chi^2 by normalizing deviation^2 by magnitude of data.
% This assumes that the STDEV of a value scales as SQRT(value).  USE WITH THIS CAVEAT IN MIND
if nargin==3
    N = max(size(y));
    terms = ((y-fit).^2)./abs(y);
    chi2 = 1/(N-P)*sum(terms);
end

%if error bars are availible, normalize the deviation to the expectred error
if nargin==4
    N = max(size(y));
    terms = ((y-fit)./eb).^2;
    chi2 = 1/(N-P)*sum(terms);
end


function y = r8vec_sqctf ( n, x )

%*****************************************************************************80
%
%% R8VEC_SQCTF computes a "slow" quarter cosine transform forward of an R8VEC.
%
%  Discussion:
%
%    This routine is provided for illustration and testing.  It is inefficient
%    relative to optimized routines that use fast Fourier techniques.
%
%    For 0 <= I <= N-1,
%
%      Y(I) = (1/N) Sum ( 0 <= J <= N-1 ) X(J) * cos ( PI * I * (J+1/2) / N )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 February 2010
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    William Briggs, Van Emden Henson,
%    The Discrete Fourier Transform,
%    SIAM, 1995,
%    QA403.5 B75
%
%  Parameters:
%
%    Input, integer N, the number of data values.
%
%    Input, real X(N), the data sequence.
%
%    Output, real Y(N), the transformed data.
%
  y(1:n) = 0.0;

  for i = 1 : n
    for j = 1 : n
      theta = 0.5 * pi * ( i - 1 ) * ( 2 * j - 1 ) / n;
      y(i) = y(i) + x(j) * cos ( theta  );
    end
  end

  y(1:n) = y(1:n) / n;

  return
end


function [ x, seed ] = log_series_sample ( a, seed )

%*****************************************************************************80
%
%% LOG_SERIES_SAMPLE samples the Logarithmic Series PDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 March 1999
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Luc Devroye,
%    Non-Uniform Random Variate Generation,
%    Springer-Verlag, New York, 1986, page 547.
%
%  Parameters:
%
%    Input, real A, the parameter of the PDF.
%    0.0 < A < 1.0.
%
%    Input, integer SEED, a seed for the random number generator.
%
%    Output, integer X, a sample of the PDF.
%
%    Output, integer SEED, an updated seed for the random number generator.
%
  [ u, seed ] = r8_uniform_01 ( seed );
  [ v, seed ] = r8_uniform_01 ( seed );

  x = floor ( 1.0 + log ( v ) / ( log ( 1.0 - ( 1.0 - a )^u ) ) );

  return
end


%DECOMPOSEHOMOGRAPHYMAT  Decompose a homography matrix to rotation(s), translation(s) and plane normal(s)
%
%     [motions, nsols] = cv.decomposeHomographyMat(H, K)
%
% ## Input
% * __H__ The input homography matrix between two images, 3x3.
% * __K__ The input intrinsic camera calibration matrix, 3x3.
%
% ## Output
% * __motions__ Decomposed `H`. A scalar struct with the following fields:
%   * __R__ Array of rotation matrices. Cell array of 3x3 rotations.
%   * __t__ Array of translation matrices. Cell array of 3x1 translations.
%   * __n__ Array of plane normal matrices. Cell array of 3x1 normals.
% * __nsols__ number of solutions.
%
% This function extracts relative camera motion between two views observing a
% planar object from the homography `H` induced by the plane. The intrinsic
% camera matrix `K` must also be provided. The function may return up to four
% mathematical solution sets. At least two of the solutions may further be
% invalidated if point correspondences are available by applying positive
% depth constraint (all points must be in front of the camera). The
% decomposition method is described in detail in [Malis]:
%
%     H = s * K * (R{i} + t{i} * n{i}') * inv(K),  for i=1:nsols
%
% `s` is a scaling factor approximated as:
%
%     s = median(svd(inv(K) * H * K))
%
% ## References
% [Malis]:
% > Ezio Malis, Manuel Vargas, and others. "Deeper understanding of the
% > homography decomposition for vision-based control". 2007.
%
% See also: cv.findHomography, cv.decomposeEssentialMat
%


function [U S] = performPCA(X)

% This function calculates the covariance matrix (Sigma) and then performs
% svd on it to get the eigen vectors and eigen values

[m n] = size(X); % m - no of egs; n - no of features

Sigma = (1/m)*(X')*(X); % Covariance matrix

[U S V] = svd(Sigma); % Perform Singular Value Decomposition


function [x,y] = intline(x1,x2,y1,y2)
%INTLINE Integer-coordinate line drawing algorithm.
%   [X,Y] = INTLINE(X1,X2,Y1,Y2) computes an approximation to the line
%   segment joining (X1,Y1) and (X2,Y2) with integer coordinates. X1,
%   X2, Y1, and Y2 should be integers. INTLINE is reversible; that is,
%   INTLINE(X1,X2,Y1,Y2) produces the same results as
%   FLIPUD(INTLINE(X2,X1,Y2,Y1)).

%   Copyright 1993-2019 The MathWorks, Inc.
%   License: https://github.com/mathworks/matlab-color-tools/blob/master/license.txt

dx = abs(x2 - x1);
dy = abs(y2 - y1);

% Check for degenerate case.
if ((dx == 0) && (dy == 0))
   x = x1;
   y = y1;
  return;
end

flip = 0;
if (dx >= dy)
   if (x1 > x2)
      % Always "draw" from left to right.
      t = x1; x1 = x2; x2 = t;
      t = y1; y1 = y2; y2 = t;
      flip = 1;
   end
   m = (y2 - y1)/(x2 - x1);
   x = (x1:x2).';
   y = round(y1 + m*(x - x1));
else
   if (y1 > y2)
      % Always "draw" from bottom to top.
      t = x1; x1 = x2; x2 = t;
      t = y1; y1 = y2; y2 = t;
      flip = 1;
   end
   m = (x2 - x1)/(y2 - y1);
   y = (y1:y2).';
   x = round(x1 + m*(y - y1));
end

if (flip)
   x = flipud(x);
   y = flipud(y);
end


function p = prime_ge ( n )

%*****************************************************************************80
%
%% PRIME_GE returns the smallest prime greater than or equal to N.
%
%  Discussion:
%
%    The MATLAB version of this program is made much simpler
%    because of the availability of the IS_PRIME logical function.
%
%  Example:
%
%    N     PRIME_GE
%
%    -10    2
%      1    2
%      2    2
%      3    3
%      4    5
%      5    5
%      6    7
%      7    7
%      8   11
%      9   11
%     10   11
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 March 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number to be bounded.
%
%    Output, integer P, the smallest prime number that is greater
%    than or equal to N.
%
  p = max ( ceil ( n ), 2 );

  while ( ~ isprime ( p ) )
      p = p + 1;
  end

  return
end


function intVal=monomialIntCrossPolytope(alpha)
%%MONOMIALINTCROSSPOLYTOPE Evaluate the integral of
%          prod_{i=1}^N x(i)^alpha(i) over the space defined by
%          sum(abs(x))=1. That is, this function gives the value of the
%          desired monomial integral taken over an N-dimensional cross
%          polytope. The region is designated as G_n in [1]. In two
%          dimensions, this shape is a square, in three an octohedron, in
%          N, a cross polytope (or N-dimensional hyperoctahedron).
%
%INPUTS: alpha An NX1 or 1XN vector of the integer exponents of the
%              monomial term. All elements must be >=0.
%
%OUTPUTS: intVal The value of the specified integral.
%
%The formula is taken from Chapter 7.7 of [1]. These types of explicit
%moment formulae are useful for testing cubature integration points.
%
%EXAMPLE:
%Here we verify that the moment value produced here equals that obtained
%using cubature points of an appropriate order.
% [xi,w]=fifthOrderCrossPolyCubPoints(3);
% alpha=[0;2;2];
% theMoment=findMomentFromSamp(alpha,xi,w)
% intVal=monomialIntCrossPolytope(alpha)
%One will find that theMoment and intVal are both near 0.0063.
%
%REFERENCES:
%[1] A.H. Stroud, Approximate Calculation of Multiple Integrals. Cliffs,
%    NJ: Prentice-Hall, Inc., 1971.
%
%February 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(all(mod(alpha,2)==0))
    n=length(alpha);

    intVal=exp(n*log(2)+sum(gammaln(alpha+1))-gammaln(n+sum(alpha)+1));
else
    intVal=0;
end
end

%LICENSE:
%
%The source code is in the public domain and not licensed or under
%copyright. The information and software may be used freely by the public.
%As required by 17 U.S.C. 403, third parties producing copyrighted works
%consisting predominantly of the material produced by U.S. government
%agencies must provide notice with such work(s) identifying the U.S.
%Government material incorporated and stating that such material is not
%subject to copyright protection.
%
%Derived works shall not identify themselves in a manner that implies an
%endorsement by or an affiliation with the Naval Research Laboratory.
%
%RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE
%SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY THE NAVAL
%RESEARCH LABORATORY FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE ACTIONS
%OF RECIPIENT IN THE USE OF THE SOFTWARE.


function mask = maskEllipse( mRows, nCols, varargin )
% Creates a binary image of an ellipse.
%
% Creates a binary image of size (mRows x nCols), with all pixels set to 0
% outside the ellipse and 1 inside.  The ellipse is given by 5 parameters,
% a semimajor axis of ra, a semminor axis of radius rb, angle phi (in
% radians), and center (cRow,cCol). An alternative method of specifying the
% ellipse parameters is in terms of a 2D Gaussian. For more info on how a
% Gaussian relates to an ellipse see gauss2ellipse.
%
% USAGE
%  mask = maskEllipse( mRows, nCols, cRow, cCol, ra, rb, phi )
%  mask = maskEllipse( mRows, nCols, mu, C, [rad] )
%
% INPUTS [version 1]
%  mRows   - number of rows in mask
%  nCols   - number of columns in mask
%  cRow    - the row location of the center of the ellipse
%  cCol    - the column location of the center of the ellipse
%  ra      - semi-major axis length (in pixels) of the ellipse
%  rb      - semi-minor axis length (in pixels) of the ellipse
%  phi     - rotation angle (in radians) of semimajor axis to x-axis
%
% INPUTS [version 2]
%  mRows   - number of rows in mask
%  nCols   - number of columns in mask
%  mu      - 1x2 vector representing the center of the ellipse
%  C       - 2x2 cov matrix
%  rad     - [2] Number of std to create the ellipse to
%
% OUTPUTS
%  mask    - created image mask
%
% EXAMPLE
%  mask = maskEllipse(  200, 200, 40, 100,  20, 15, pi/4 );
%  figure(1); im(mask); [mu,C] = imMlGauss( mask, 0, 2 );
%
% See also PLOTELLIPSE, GAUSS2ELLIPSE, MASKCIRCLE, MASKGAUSSIANS, IMMLGAUSS
%
% Piotr's Computer Vision Matlab Toolbox      Version 2.40
% Copyright 2014 Piotr Dollar.  [pdollar-at-gmail.com]
% Licensed under the Simplified BSD License [see external/bsd.txt]

if( nargin==7 )
  [cRow, cCol, ra, rb, phi] = deal( varargin{:} );
elseif( nargin==4 )
  [mu, C] = deal( varargin{:} );
  [cRow, cCol, ra, rb, phi] = gauss2ellipse( mu, C );
elseif( nargin==5 )
  [mu, C, rad] = deal( varargin{:} );
  [cRow, cCol, ra, rb, phi] = gauss2ellipse( mu, C, rad );
else
  error( ['Incorrect number of input arguments: ' int2str(nargin)] );
end;

% compute the leftmost and rightmost points of the ellipse
raCos=ra*cos(pi-phi); rbCos=rb*cos(pi-phi);
raSin=ra*sin(pi-phi); rbSin=rb*sin(pi-phi);
d = sqrt(raCos*raCos + rbSin*rbSin);
cRad = abs(raCos*raCos/d + rbSin*rbSin/d);
c0 = max( ceil(cCol-cRad), 1 );
c1 = min( floor(cCol+cRad), nCols );
B = rbSin / raCos; B2=B*B;

% compute and add the top/bottom points for each c
mask = zeros( mRows, nCols );
for c=c0:c1
  A=(c-cCol)/raCos; C=sqrt(max(0,B2-A*A+1));
  r0 = cRow - raSin*(A-B*C)/(B2+1) + rbCos*(A*B+C)/(B2+1);
  r1 = cRow - raSin*(A+B*C)/(B2+1) + rbCos*(A*B-C)/(B2+1);
  if(r0>r1), tmp=r0; r0=r1; r1=tmp; end
  r0 = max( ceil(r0-.0001), 1 );
  r1 = min( floor(r1+.0001), mRows );
  mask( r0:r1, c ) = 1;
end


function [out] = meanangle(in,dim,sens);

% MEANANGLE will calculate the mean of a set of angles (in degrees) based
% on polar considerations.
%
% Usage: [out] = meanangle(in,dim)
%
% in is a vector or matrix of angles (in degrees)
% out is the mean of these angles along the dimension dim
%
% If dim is not specified, the first non-singleton dimension is used.
%
% A sensitivity factor is used to determine oppositeness, and is how close
% the mean of the complex representations of the angles can be to zero
% before being called zero.  For nearly all cases, this parameter is fine
% at its default (1e-12), but it can be readjusted as a third parameter if
% necessary:
%
% [out] = meanangle(in,dim,sensitivity)
%
% Written by J.A. Dunne, 10-20-05
%

if nargin<3
    sens = 1e-12;
end

if nargin<2
    ind = min(find(size(in)>1));
    if isempty(ind)
        %This is a scalar
        out = in;
        return
    end
    dim = ind;
end

in = in * pi/180;

in = exp(i*in);
mid = mean(in,dim);
out = atan2(imag(mid),real(mid))*180/pi;
out(abs(mid)<sens) = nan;


function f=lorenz_ext(t,X)
%
%  Lorenz equation
%
%               dx/dt = SIGMA*(y - x)
%               dy/dt = R*x - y -x*z
%               dz/dt= x*y - BETA*z
%
%        In demo run SIGMA = 10, R = 28, BETA = 8/3
%        Initial conditions: x(0) = 0, y(0) = 1, z(0) = 0;
%        Reference values for t=10 000 :
%              L_1 = 0.9022, L_2 = 0.0003, LE3 = -14.5691
%
%        See:
%    K. Ramasubramanian, M.S. Sriram, "A comparative study of computation
%    of Lyapunov spectra with different algorithms", Physica D 139 (2000) 72-86.
%
% --------------------------------------------------------------------
% Copyright (C) 2004, Govorukhin V.N.

% Values of parameters
SIGMA = 10;
R = 28;
BETA = 8/3;

x=X(1); y=X(2); z=X(3);

Y= [X(4), X(7), X(10);
    X(5), X(8), X(11);
    X(6), X(9), X(12)];

f=zeros(9,1);

%Lorenz equation
f(1)=SIGMA*(y-x);
f(2)=-x*z+R*x-y;
f(3)=x*y-BETA*z;

%Linearized system

 Jac=[-SIGMA, SIGMA,     0;
         R-z,    -1,    -x;
           y,     x, -BETA];

%Variational equation
f(4:12)=Jac*Y;

%Output data must be a column vector


function val=secDerivVal(z,n)
%%SECDERIVVAL Return the value of the nth derivative of sec(x) with respect
%             to x evaluated at x=z.
%
%INPUTS: z A matrix of real or complex values at which the nth derivative
%          of the secant function is desired.
%        n The number of derivatives to take. n>=0.
%
%OUTPUTS: val The value of the nth derivative of the secant function taken
%             at all of the points in z. val has the same dimensions as z.
%
%This function implements the algorithm of [1].
%
%REFERENCES:
%[1] M. E. Hoffman, "Derivative polynomials for tangent and secant," The
%    American Mathematical Monthly, vol. 102, no. 1, pp. 23-30, Jan. 1995.
%
%October 2016 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

numEls=numel(z);

val=zeros(size(z));
for curEl=1:numEls
    x=z(curEl);
    u=tan(x);

    P=zeros(n+1,1);
    Q=zeros(n+1,1);
    P(1)=u;
    Q(1)=1;

    for k=1:n
        %The loop implements Equation 5.
        sumValP=0;
        sumValQ=0;
        for i=0:(k-1)
            binomVal=binomial(k-1,i);
            sumValP=sumValP+binomVal*P(i+1)*P(k-1-i+1);
            sumValQ=sumValQ+binomVal*P(i+1)*Q(k-1-i+1);
        end
        if(k==1)
            sumValP=sumValP+1;
        end
        P(k+1)=sumValP;
        Q(k+1)=sumValQ;
    end
    val(curEl)=Q(end)*sec(x);
end

end

%LICENSE:
%
%The source code is in the public domain and not licensed or under
%copyright. The information and software may be used freely by the public.
%As required by 17 U.S.C. 403, third parties producing copyrighted works
%consisting predominantly of the material produced by U.S. government
%agencies must provide notice with such work(s) identifying the U.S.
%Government material incorporated and stating that such material is not
%subject to copyright protection.
%
%Derived works shall not identify themselves in a manner that implies an
%endorsement by or an affiliation with the Naval Research Laboratory.
%
%RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE
%SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY THE NAVAL
%RESEARCH LABORATORY FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE ACTIONS
%OF RECIPIENT IN THE USE OF THE SOFTWARE.


function pdf = geometric_pdf ( x, a )

%*****************************************************************************80
%
%% GEOMETRIC_PDF evaluates the Geometric PDF.
%
%  Discussion:
%
%    PDF(X)(A) = A * ( 1 - A )**(X-1)
%
%    PDF(X)(A) is the probability that exactly X Bernoulli trials, each
%    with probability of success A, will be required to achieve
%    a single success.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer X, the number of trials.
%    0 < X
%
%    Input, real A, the probability of success on one trial.
%    0.0 <= A <= 1.0.
%
%    Output, real PDF, the value of the PDF.
%

%
%  Special cases.
%
  if ( x < 1 )

    pdf = 0.0;

  elseif ( a == 0.0 )

    pdf = 0.0;

  elseif ( a == 1.0 )

    if ( x == 1 )
      pdf = 1.0;
    else
      pdf = 0.0;
    end

  else

    pdf = a * ( 1.0 - a )^( x - 1 );

  end

  return
end


function glopts = loc2glob_3d ( cospitch, cosroll, cosyaw, sinpitch, sinroll, ...
  sinyaw, globas, locpts )

%*****************************************************************************80
%
%% LOC2GLOB_3D converts from a local to global coordinate system in 3D.
%
%  Discussion:
%
%    A global coordinate system is given.
%
%    A local coordinate system has been translated to the point with
%    global coordinates GLOBAS, and rotated through a yaw, a pitch, and
%    a roll.
%
%    A point has local coordinates LOCPTS, and it is desired to know
%    the point's global coordinates GLOPTS.
%
%    The transformation may be written as
%
%      GLOB = GLOBAS + N_YAW * N_PITCH * N_ROLL * LOC
%
%    where
%
%               (  cos(Yaw)   -sin(Yaw)        0      )
%    N_YAW    = (  sin(Yaw)    cos(Yaw)        0      )
%               (      0           0           1      )
%
%               (  cos(Pitch)      0       sin(Pitch) )
%    N_PITCH =  (      0           1           0      )
%               ( -sin(Pitch)      0       cos(Pitch) )
%
%               (      1           0           0      )
%    N_ROLL =   (      0       cos(Roll)  -sin(Roll)  )
%               (      0       sin(Roll)   cos(Roll)  )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real COSPITCH, COSROLL, COSYAW, the cosines of the
%    pitch, roll and yaw angles.
%
%    Input, real SINPITCH, SINROLL, SINYAW, the sines of the pitch,
%    roll and yaw angles.
%
%    Input, real GLOBAS(3,1), the global coordinates of the base
%    vector.
%
%    Input, real LOCPTS(3,1), the local coordinates of the point.
%
%    Output, real GLOPTS(3,1), the global coordinates of the point.
%
  glopts(1,1) = globas(1,1) + (  cosyaw * cospitch ) * locpts(1,1) ...
    + (  cosyaw * sinpitch * sinroll - sinyaw * cosroll ) * locpts(2,1) ...
    + (  cosyaw * sinpitch * cosroll + sinyaw * sinroll ) * locpts(3,1);

  glopts(2,1) = globas(2,1) + (  sinyaw * cospitch ) * locpts(1,1) ...
    + (  sinyaw * sinpitch * sinroll + cosyaw * cosroll ) * locpts(2,1) ...
    + (  sinyaw * sinpitch * cosroll - cosyaw * sinroll ) * locpts(3,1);

  glopts(3,1) = globas(3,1) + ( -sinpitch ) * locpts(1,1) ...
    + (  cospitch * sinroll ) * locpts(2,1) ...
    + (  cospitch * cosroll ) * locpts(3,1);

  return
end


function [p alpha] = circ_vmpdf(alpha, thetahat, kappa)

% [p alpha] = circ_vmpdf(alpha, w, p)
%   Computes the circular von Mises pdf with preferred direction thetahat
%   and concentration kappa at each of the angles in alpha
%
%   The vmpdf is given by f(phi) =
%   (1/(2pi*I0(kappa))*exp(kappa*cos(phi-thetahat)
%
%   Input:
%     alpha     angles to evaluate pdf at, if empty alphas are chosen to
%               100 uniformly spaced points around the circle
%     [thetahat preferred direction, default is 0]
%     [kappa    concentration parameter, default is 1]
%
%   Output:
%     p         von Mises pdf evaluated at alpha
%     alpha     angles at which pdf was evaluated
%
%
%   References:
%     Statistical analysis of circular data, Fisher
%
% Circular Statistics Toolbox for Matlab

% By Philipp Berens and Marc J. Velasco, 2009
% velasco@ccs.fau.edu

% if no angles are supplied, 100 evenly spaced points around the circle are
% chosen
if nargin < 1 || isempty(alpha)
    alpha = linspace(0, 2*pi, 101)';
    alpha = alpha(1:end-1);
end
if nargin < 3
    kappa = 1;
end
if nargin < 2
    thetahat = 0;
end

alpha = alpha(:);

% evaluate pdf
C = 1/(2*pi*besseli(0,kappa));
p = C * exp(kappa*cos(alpha-thetahat));


function p = he_polynomial_value ( m, n, x )

%*****************************************************************************80
%
%% HE_POLYNOMIAL_VALUE evaluates He(i,x).
%
%  Discussion:
%
%    He(i,x) represents the probabilist's Hermite polynomial.
%
%  Differential equation:
%
%    ( exp ( - 0.5 * x^2 ) * He(n,x)' )' + n * exp ( - 0.5 * x^2 ) * He(n,x) = 0
%
%  First terms:
%
%   1
%   X
%   X^2  -  1
%   X^3  -  3 X
%   X^4  -  6 X^2 +   3
%   X^5  - 10 X^3 +  15 X
%   X^6  - 15 X^4 +  45 X^2 -   15
%   X^7  - 21 X^5 + 105 X^3 -  105 X
%   X^8  - 28 X^6 + 210 X^4 -  420 X^2 +  105
%   X^9  - 36 X^7 + 378 X^5 - 1260 X^3 +  945 X
%   X^10 - 45 X^8 + 630 X^6 - 3150 X^4 + 4725 X^2 - 945
%
%  Recursion:
%
%    He(0,X) = 1,
%    He(1,X) = X,
%    He(N,X) = X * He(N-1,X) - (N-1) * He(N-2,X)
%
%  Orthogonality:
%
%    Integral ( -oo < X < +oo ) exp ( - 0.5 * X^2 ) * He(M,X) He(N,X) dX
%    = sqrt ( 2 * pi ) * N! * delta ( N, M )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 February 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Milton Abramowitz, Irene Stegun,
%    Handbook of Mathematical Functions,
%    National Bureau of Standards, 1964,
%    ISBN: 0-486-61272-4,
%    LC: QA47.A34.
%
%    Frank Olver, Daniel Lozier, Ronald Boisvert, Charles Clark,
%    NIST Handbook of Mathematical Functions,
%    Cambridge University Press, 2010,
%    ISBN: 978-0521192255,
%    LC: QA331.N57.
%
%  Parameters:
%
%    Input, integer M, the number of evaluation points.
%
%    Input, integer N, the highest order polynomial to compute.
%    Note that polynomials 0 through N will be computed.
%
%    Input, real X(M,1), the evaluation points.
%
%    Output, real P(M,N+1), the values of the probabilist's Hermite polynomials
%    of index 0 through N.
%
  p = zeros ( m, n + 1 );

  p(1:m,1) = 1.0;

  if ( n == 0 )
    return
  end

  p(1:m,2) = x(1:m,1);

  for j = 2 : n
    p(1:m,j+1) = x(1:m,1) .* p(1:m,j) - ( j - 1 ) * p(1:m,j-1);
  end

  return
end


function value = angle_rad_2d ( p1, p2, p3 )

%*****************************************************************************80
%
%% ANGLE_RAD_2D returns the angle swept out between two rays in 2D.
%
%  Discussion:
%
%    Except for the zero angle case, it should be true that
%
%      ANGLE_RAD_2D(P1,P2,P3) + ANGLE_RAD_2D(P3,P2,P1) = 2 * PI
%
%        P1
%        /
%       /
%      /
%     /
%    P2--------->P3
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 April 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real P1(2), P2(2), P3(2), define the rays
%    P1 - P2 and P3 - P2 which in turn define the angle.
%
%    Output, real VALUE, the angle swept out by the rays, measured
%    in radians.  0 <= VALUE < 2*PI.  If either ray has zero length,
%    then VALUE is set to 0.
%
  p(1) = ( p3(1) - p2(1) ) * ( p1(1) - p2(1) ) ...
       + ( p3(2) - p2(2) ) * ( p1(2) - p2(2) );

  p(2) = ( p3(1) - p2(1) ) * ( p1(2) - p2(2) ) ...
       - ( p3(2) - p2(2) ) * ( p1(1) - p2(1) );

  if ( p(1) == 0.0 & p(2) == 0.0 )
    value = 0.0;
    return
  end

  value = atan2 ( p(2), p(1) );

  if ( value < 0.0 )
    value = value + 2.0 * pi;
  end

  return
end


function pdf = semicircular_pdf ( x, a, b )

%*****************************************************************************80
%
%% SEMICIRCULAR_PDF evaluates the Semicircular PDF.
%
%  Formula:
%
%    PDF(X)(A,B) = ( 2 / ( B * PI ) ) * SQRT ( 1 - ( ( X - A ) / B )**2 )
%    for A - B <= X <= A + B
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the argument of the PDF.
%
%    Input, real A, B, the parameters of the PDF.
%    0.0 < B.
%
%    Output, real PDF, the value of the PDF.
%
  if ( x < a - b )

    pdf = 0.0;

  elseif ( x <= a + b )

    y = ( x - a ) / b;

    pdf = 2.0 / ( b * pi ) * sqrt ( 1.0 - y * y );

  elseif ( a + b < x )

    pdf = 0.0;

  end

  return
end


% book : Signals and Systems Laboratory with MATLAB
% authors : Alex Palamides & Anastasia Veloni
%
%
% Partial fraction expansion of a rational function
%
%

%        s^2+3s+1
% X(s)=----------------
%       s^3+5s^2+2s-8

A=[1 5 2 -8];
rt=roots(A)
syms s
X=(s^2+3*s+1)/(s^3+5*s^2+2*s-8);

c1=limit((s-rt(1))*X,s,rt(1))
c2=limit( (s-rt(2))*X,s,rt(2))
c3=limit( (s-rt(3))*X,s,rt(3))

X1=simplify( (s-rt(1))*X );
X2=simplify( (s-rt(2))*X );
X3=simplify( (s-rt(3))*X );
c1=subs(X1,s,rt(1))
c2=subs(X2,s,rt(2))
c3=subs(X3,s,rt(3))

%alternative conversion
num=[ 1 3 1];
den=[ 1 5 2 -8];
[R,P,K]=residue(num,den)
syms s
X=R(1)/(s-P(1))+R(2)/(s-P(2))+R(3)/(s-P(3))
pretty(X)

%
%        s^2+3s+1
% X(s)=------------
%       s^3-3s+2

A=[1 0 -3 2];
rt=roots(A)
syms s
X=(s^2+3*s+1)/(s^3-3*s+2);

c1=limit((s-rt(1))*X,s,rt(1))

r=2;
i=1;
f= ((s-1)^r )*X;
d=diff(f,s,r-i);
fact=1/factorial(r-i);
c2=limit(fact*d,s,1)

i=2;
d=diff(f,s,r-i);
fact=1/factorial(r-i);
c3=limit(fact*d,s,1)

%alternative conversion
num=[ 1 3 1];
den=[1 0 -3 2];
[R,P,K]=residue(num,den)

%
%        s^2-12s+11
% X(s)=------------
%        s^2+4s+3

num=[1 -12 11];
den=[ 1 4 3];
[k,g]=deconv(num,den)
rt=roots(den)

syms s
GA=(-16*s+8)/(s^2+4*s+3);
c1=limit((s-rt(1))*GA,s,rt(1))
c2=limit((s-rt(2))*GA,s,rt(2))

%alternative conversion
num=[ 1 -12 11];
den=[ 1 4 3];
[R,P,K]=residue(num,den)


function [ G ] = gsp_erdos_renyi( N,p,param )
%GSP_ERDOS_RENYI Create a random Erdos Renyi graph
%   Usage:  G = gsp_erdos_renyi( N,p,param );
%           G = gsp_erdos_renyi( N,p );
%
%   Input parameters:
%         N     : Number of nodes
%         p     : Probability of connection of a node with another
%         param : Structure of optional parameter
%   Output parameters:
%         G     : Graph structure.
%
%   'gsp_erdos_renyi( N,p,param )' initializes create a graph structure
%   containing the weighted adjacency matrix (G.W), the number of vertices
%   (G.N) for an Erdos Renyi graph. All edge weights are equal to 1.
%
%   The Erdos Renyi graph is constructed by connecting nodes randomly. Each
%   edge is included in the graph with probability p independent from every
%   other edge.
%
%   *param* a Matlab structure containing the following fields:
%
%     * *param.connected* : flag to force the graph to be connected. By
%       default, it is 0.
%
%     * *param.maxit* : is the maximum number of try to connect the graph.
%       By default, it is 10.
%
%     * *param.verbose* : 0 no log, 1 print main steps, 2 print all steps.
%       By default, it is 1.
%
%   Example::
%
%        G = gsp_erdos_renyi(100,0.05)

% Author : Nathanael Perraudin

% Optional input arguments
if nargin<3, param=struct; end

if ~isfield(param, 'connected'), param.connected=0; end
if ~isfield(param, 'maxit'), param.maxit=10; end
if ~isfield(param, 'verbose'), param.verbose=1 ; end

% Check if the user didn't put silly parameter
if param.connected
    if N*p<3
        if param.verbose
            fprintf(['The model has very low chance to create a '...
                ,'connected graph. Increase N, p or disable '...
                ,'param.connected \n']);
        end
    end
end

if p>1
   error('The probability p cannot be above 1');
end

if p<0
    error('The probability p cannot be negative');
end

% Create the graph structure
G=struct;
G.graph_type='erdos_renyi';
G.connected=param.connected;

% Create the graph
if param.connected
    bool=0;
    iter=1;
    if param.verbose>1
        fprintf('Entering the iteration process\n')
    end
    while ~bool

        G.W = sprandsym(N, p)>0;
        G.W(1:N+1:end) = 0;

        bool=gsp_check_connectivity(G.W);
        if iter==param.maxit
            warning('The graph is not strongly connected.');
            break;
        elseif ~bool
            if param.verbose>1
                fprintf('Iteration %i failed. Trying again \n',iter)
            end
            iter=iter+1;
        end
    end
    if param.verbose>1
        if bool
            fprintf('A connected graph has been created in %i iteration\n',iter);
        else
            fprintf('The iterative process has failed.\n');
        end
    end
else
   G.W = sprandsym(N,p)>0;
   G.W(1:N+1:end) = 0;
end

% try to create point to be associated with the points of the graph

% [x, y] = draw_dot(G.W);
%
%
% G.coords=[x',y'];
% G.limits=[-1e-4,1.01*max(x),-1e-4,1.01*max(y)];

G.type = 'erdos_renyi';

G = gsp_graph_default_parameters(G);

end


function p = gam_cdf(x,a,b)
%GAM_CDF Cumulative of Gamma probability density function (cdf).
%
%   P = GAM_CDF(X,A,B) Returns the gamma cdf with
%   shape A and inverse scale B, at the values in X.
%
%   The size of X is the common size of the input arguments. A
%   scalar input functions as a constant matrix of the same size as
%   the other inputs.
%
%   The parameterization is as in Gelman et al. (2004). Bayesian Data
%   Analysis (second edition)

% Copyright (c) 1998-2004 Aki Vehtari

% This software is distributed under the GNU General Public
% License (version 3 or later); please refer to the file
% License.txt, included with the software, for details.

if nargin < 3,
  error('Requires three input arguments.');
end

p=gammainc(b*x,a);


function a = rectangle_adj ( row_num, col_num, n )

%*****************************************************************************80
%
%% RECTANGLE_ADJ returns the RECTANGLE_ADJ matrix.
%
%  Discussion:
%
%    This is the adjacency matrix for a set of points arranged in
%    a ROW_NUM by COL_NUM grid.
%
%  Diagram:
%
%     1---5---9
%     |   |   |
%     2---6--10
%     |   |   |
%     3---7--11
%     |   |   |
%     4---8--12
%
%  Example:
%
%    ROW_NUM = 4
%    COL_NUM = 3
%
%    0  1  0  0    1  0  0  0    0  0  0  0
%    1  0  1  0    0  1  0  0    0  0  0  0
%    0  1  0  1    0  0  1  0    0  0  0  0
%    0  0  1  0    1  0  0  1    0  0  0  0
%
%    1  0  0  0    0  1  0  0    1  0  0  0
%    0  1  0  0    1  0  1  0    0  1  0  0
%    0  0  1  0    0  1  0  1    0  0  1  0
%    0  0  0  1    0  0  1  0    0  0  0  1
%
%    0  0  0  0    1  0  0  0    0  1  0  0
%    0  0  0  0    0  1  0  0    1  0  1  0
%    0  0  0  0    0  0  1  0    0  1  0  1
%    0  0  0  0    0  0  0  1    0  0  1  0
%
%  Properties:
%
%    A is integral, therefore det ( A ) is integral, and
%    det ( A ) * inverse ( A ) is integral.
%
%    A is a zero/one matrix.
%
%    A is block tridiagonal.
%
%    A is an adjacency matrix.
%
%    A is related to the "LIGHTS_OUT" matrix.
%
%    A is symmetric: A' = A.
%
%    Because A is symmetric, it is normal.
%
%    Because A is normal, it is diagonalizable.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 July 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer ROW_NUM, COL_NUM, the number of rows and
%    columns in the rectangle.
%
%    Input, integer N, the order of A.
%
%    Output, real A(N,N), the matrix.
%
  a = zeros ( n, n );

  for j_block = 1 : col_num

    j = ( j_block - 1 ) * row_num + 1;

    for i_block = 1 : col_num

      i = ( i_block - 1 ) * row_num + 1;

      if ( j_block == i_block )
        a(i:i+row_num-1,j:j+row_num-1) = line_adj ( row_num );
      elseif ( abs ( j_block - i_block ) == 1 )
        a(i:i+row_num-1,j:j+row_num-1) = identity ( row_num, row_num );
      else
        a(i:i+row_num-1,j:j+row_num-1) = zero ( row_num, row_num );
      end

    end
  end

  return
end


function a = tri_upper_inverse ( alpha, n )

%*****************************************************************************80
%
%% TRI_UPPER_INVERSE returns the inverse of the TRI_UPPER matrix.
%
%  Formula:
%
%    if ( I = J )
%      A(I,J) = 1
%    elseif ( I = J - 1 )
%      A(I,J) = -ALPHA
%    elseif ( I < J )
%      A(I,J) = - ALPHA * ( 1-ALPHA)^(J-I-1)
%    else
%      A(I,J) = 0
%
%  Example:
%
%    ALPHA = 3, N = 5
%
%    1 -3  6 -12  24
%    0  1 -3   6 -12
%    0  0  1  -3   6
%    0  0  0   1  -3
%    0  0  0   0   1
%
%  Properties:
%
%    A is generally not symmetric: A' /= A.
%
%    A is nonsingular.
%
%    A is upper triangular.
%
%    A is Toeplitz: constant along diagonals.
%
%    A is persymmetric: A(I,J) = A(N+1-J,N+1-I).
%
%    det ( A ) = 1.
%
%    A is unimodular.
%
%    LAMBDA(1:N) = 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real ALPHA, value used on the superdiagonals.
%
%    Input, integer N, the order of A.
%
%    Output, real A(N,N), the matrix.
%
  a = zeros ( n, n );

  for i = 1 : n
    for j = 1 : n

      if ( i == j )
        a(i,j) = 1.0;
      elseif ( i == j - 1 )
        a(i,j) = - alpha;
      elseif ( i < j )
        a(i,j) = - alpha * ( 1.0 - alpha )^(j-i-1);
      else
        a(i,j) = 0.0;
      end

    end
  end

  return
end


function [ u, nullty, ifault ] = cholesky ( a, n, nn )

%*****************************************************************************80
%
%% CHOLESKY computes the Cholesky factorization of a PDS matrix.
%
%  Discussion:
%
%    For a positive definite symmetric matrix A, the Cholesky factor U
%    is an upper triangular matrix such that A = U' * U.
%
%    This routine was originally named "CHOL", but that conflicts with
%    the name of a built in MATLAB routine.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 February 2008
%
%  Author:
%
%    Original FORTRAN77 version by Michael Healy.
%    Modifications by AJ Miller.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Michael Healy,
%    Algorithm AS 6:
%    Triangular decomposition of a symmetric matrix,
%    Applied Statistics,
%    Volume 17, Number 2, 1968, pages 195-197.
%
%  Parameters:
%
%    Input, real A((N*(N+1))/2), a positive definite matrix
%    stored by rows in lower triangular form as a one dimensional array,
%    in the sequence
%    A(1,1),
%    A(2,1), A(2,2),
%    A(3,1), A(3,2), A(3,3), and so on.
%
%    Input, integer N, the order of A.
%
%    Input, integer NN, the dimension of the array used to store A,
%    which should be at least (N*(N+1))/2.
%
%    Output, real U((N*(N+1))/2), an upper triangular matrix,
%    stored by columns, which is the Cholesky factor of A.
%
%    Output, integer NULLTY, the rank deficiency of A.  If NULLTY is zero,
%    the matrix is judged to have full rank.
%
%    Output, integer IFAULT, an error indicator.
%    0, no error was detected;
%    1, if N < 1;
%    2, if A is not positive semi-definite.
%    3, if NN < (N*(N+1))/2.
%
%  Local Parameters:
%
%    Local, real ETA, should be set equal to the smallest positive
%    value such that 1.0 + ETA is calculated as being greater than 1.0 in the
%    accuracy being used.
%

%
%  Initialize output.
%
  u = [];
  nullty = 0;
  ifault = 0;

  eta = 1.0E-09;

  if ( n <= 0 )
    ifault = 1;
    return
  end

  if ( nn < floor ( ( n * ( n + 1 ) ) / 2 ) )
    ifault = 3;
    return
  end

  u(1:nn) = 0.0;
  j = 1;
  k = 0;
  ii = 0;
%
%  Factorize column by column, ICOL = column number.
%
  for icol = 1 : n

    ii = ii + icol;
    x = eta * eta * a(ii);
    l = 0;
    kk = 0;
%
%  IROW = row number within column ICOL.
%
    for irow = 1 : icol

      kk = kk + irow;
      k = k + 1;
      w = a(k);
      m = j;

      for i = 1 : irow - 1
        l = l + 1;
        w = w - u(l) * u(m);
        m = m + 1;
      end

      l = l + 1;

      if ( irow == icol )
        break
      end

      if ( u(l) ~= 0.0 )

        u(k) = w / u(l);

      else

        u(k) = 0.0;

        if ( abs ( x * a(k) ) < w * w )
          ifault = 2;
          return
        end

      end

    end
%
%  End of row, estimate relative accuracy of diagonal element.
%
    if ( abs ( w ) <= abs ( eta * a(k) ) )

      u(k) = 0.0;
      nullty = nullty + 1;

    else

      if ( w < 0.0 )
        ifault = 2;
        return
      end

      u(k) = sqrt ( w );

    end

    j = j + icol;

  end

  return
end


% Gauss-Seidel 迭代法（分量形式）求解方程组
clear;
% 输入值
A = [10, -1, -2; -1, 10, -2; -1, -1, 5];
b = [7.2; 8.3; 4.2];
tol = 1e-5;
N = 100;
x = [0; 0; 0];
x_backup = [0; 0; 0];
y = [0; 0; 0];
%
A_ = A;
for i = 1 : length(A)
    A_(i,i) = 0;
end

for i = 0 : N
    for j = 1 : length(A)
        y(j,1) = (b(j) - A_(j,:) * x) / A(j,j);
        x_backup(j) = x(j);   % 备份“老值”
        x(j) = y(j);     % “新值” 替换 “老值”
    end
    if (max(abs(x_backup - y)) < tol)
        fprintf('迭代次数: %d\n', i);
        fprintf('方程组的根: %10.8f\n', y);
        break;
    end
end
if i == N
    fprintf('迭代方法失败\n');
end


function [ fmin, a, b ] = p00_fmin ( a, b, problem, tol )

%*****************************************************************************80
%
%% P00_FMIN seeks a minimizer of a scalar function of a scalar variable.
%
%  Discussion:
%
%    FMIN seeks an approximation to the point where F attains a minimum on
%    the interval (A,B).
%
%    The method used is a combination of golden section search and
%    successive parabolic interpolation.  Convergence is never much
%    slower than that for a Fibonacci search.  If F has a continuous
%    second derivative which is positive at the minimum (which is not
%    at A or B), then convergence is superlinear, and usually of the
%    order of about 1.324....
%
%    The function F is never evaluated at two points closer together
%    than EPS * ABS ( FMIN ) + (TOL/3), where EPS is approximately the
%    square root of the relative machine precision.  If F is a unimodal
%    function and the computed values of F are always unimodal when
%    separated by at least EPS * ABS ( XSTAR ) + (TOL/3), then FMIN
%    approximates the abcissa of the global minimum of F on the
%    interval [A, B] with an error less than 3 * EPS * ABS ( FMIN ) + TOL.
%    If F is not unimodal, then FMIN may approximate a local, but
%    perhaps non-global, minimum to the same accuracy.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 February 2009
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Richard Brent,
%    Algorithms for Minimization without Derivatives,
%    Prentice Hall, 1973.
%
%    David Kahaner, Cleve Moler, Steven Nash,
%    Numerical Methods and Software,
%    Prentice Hall, 1988.
%
%  Parameters
%
%    Input, real A, B, the left and right endpoints of the initial interval.
%
%    Input, integer PROBLEM, the index of a problem.
%
%    Input, real TOL, the desired length of the interval of
%    uncertainty of the final result.  TOL must not be negative.
%
%    Output, real FMIN, the abcissa approximating the
%    minimizer of f.
%
%    Output, real A, B, the lower and upper bounds for the minimizer.
%
  c = 0.5 * ( 3.0 - sqrt ( 5.0 ) );
%
%  C is the squared inverse of the golden ratio.
%
%  EPSILON is the square root of the relative machine precision.
%
  epsilon = sqrt ( eps );
%
%  Initialization.
%
  v = a + c * ( b - a );
  w = v;
  x = v;
  e = 0.0;
  fx = p00_f ( problem, x );
  fv = fx;
  fw = fx;
%
%  The main loop starts here.
%
  while ( 1 )

    midpoint = 0.5 * ( a + b );
    tol1 = epsilon * abs ( x ) + tol / 3.0;
    tol2 = 2.0 * tol1;
%
%  Check the stopping criterion.
%
    if ( abs ( x - midpoint ) <= ( tol2 - 0.5 * ( b - a ) ) )
      break
    end
%
%  Is golden-section necessary?
%
    if ( abs ( e ) <= tol1 )
      if ( midpoint <= x )
        e = a - x;
      else
        e = b - x;
      end

      d = c * e;
%
%  Consider fitting a parabola.
%
    else

      r = ( x - w ) * ( fx - fv );
      q = ( x - v ) * ( fx - fw );
      p = ( x - v ) * q - ( x - w ) * r;
      q = 2.0 * ( q - r );
      if ( 0.0 < q )
        p = -p;
      end
      q = abs ( q );
      r = e;
      e = d;
%
%  Choose a golden-section step if the parabola is not advised.
%
      if ( ...
        ( abs ( 0.5 * q * r ) <= abs ( p ) ) | ...
        ( p <= q * ( a - x ) ) | ...
        ( q * ( b - x ) <= p ) )

        if ( midpoint <= x )
          e = a - x;
        else
          e = b - x;
        end

        d = c * e;
%
%  Choose a parabolic interpolation step.
%
      else

        d = p / q;
        u = x + d;

        if ( ( u - a ) < tol2 )
          d = abs ( tol1 ) * r8_sign ( midpoint - x );
        end

        if ( ( b - u ) < tol2 )
          d = abs ( tol1 ) * r8_sign ( midpoint - x );
        end

     end

   end
%
%  F must not be evaluated too close to X.
%
    if ( tol1 <= abs ( d ) )
      u = x + d;
    end

    if ( abs ( d ) < tol1 )
      u = x + abs ( tol1 ) * r8_sign ( d );
    end

    fu = p00_f ( problem, u );
%
%  Update the data.
%
    if ( fu <= fx )

      if ( x <= u )
        a = x;
      else
        b = x;
      end

      v = w;
      fv = fw;
      w = x;
      fw = fx;
      x = u;
      fx = fu;
      continue

    end

    if ( u < x )
      a = u;
    else
      b = u;
    end

    if ( fu <= fw | w == x )
      v = w;
      fv = fw;
      w = u;
      fw = fu;
    elseif ( fu <= fv | v == x | v == w )
      v = u;
      fv = fu;
    end

  end

  fmin = x;

  return
end


function circVar=findCircVar(x,w)
%%FINDCIRCVAR Given a set of samples of a circular distribution, determine
%             the circular variance. As in Chapter 2.3.1 of [1], this is
%             just 1 minus the resultant length of the first trigonometric
%             moment.
%INPUTS: x The 1XN or NX1 vector of possibly weighted samples.
%        w The NX1 weights associated with the samples. If this parameter
%          is omitted or an empty matrix is passed, then the samples are
%          uniformly weighted.
%
%OUTPUTS: circVar The circular variance of the measurements.
%
%The mean resultant length is found using findTrigMomentFromSamp and is
%then subtracted from 1.
%
%REFERENCES
%[1] K. V. Mardia and P. E. Jupp, Directional Statistics. Chichester: John
%    Wiley and Sons, 2000.
%
%April 2018 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<2)
    w=[];
end

[~,~,RS]=findTrigMomentFromSamp(1,x,w);
circVar=1-RS;

end

%LICENSE:
%
%The source code is in the public domain and not licensed or under
%copyright. The information and software may be used freely by the public.
%As required by 17 U.S.C. 403, third parties producing copyrighted works
%consisting predominantly of the material produced by U.S. government
%agencies must provide notice with such work(s) identifying the U.S.
%Government material incorporated and stating that such material is not
%subject to copyright protection.
%
%Derived works shall not identify themselves in a manner that implies an
%endorsement by or an affiliation with the Naval Research Laboratory.
%
%RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE
%SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY THE NAVAL
%RESEARCH LABORATORY FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE ACTIONS
%OF RECIPIENT IN THE USE OF THE SOFTWARE.


function FR = factorialratio(A,B)
% FACTORIALRATIO - ratio of factorial numbers
%
%   FR = FACTORIALRATIO (A,B) calculates the ratio between products of
%   factorials specified by A and B.  A and B are lists of positive
%   integers, with N and M elements, respectively. The number of values in
%   each list may differ. The factorial ratio is based on the following formula:
%
%              (A1! * A2! * ... * AN!)
%      FR  =  -------------------------
%              (B1! * B2! * ... * BM!)
%
%    However, an approach is taken that increases the accuracy when A or B
%    contain larger values, as mentioned in the help of FACTORIAL.
%
%    Examples:
%
%      f1 = factorialratio([10 8 6],[9 6 5]) ;
%      f2 = 10 * 8 * 7 * 6 ; % by hand
%      f3 = (factorial(10) * factorial(8) * factorial(6)) ./ ...
%            (factorial(9) * factorial(6) * factorial(5)) ;
%      disp('f1, f2, f3 = ') ; disp([f1 f2 f3])
%
%
%      % Also for larger values FACTORIALRATIO works correctly
%      f1 = factorialratio(150,143) ;
%      f2 = prod(144:150) ; % by hand
%      % where FACTORIAL lacks precision
%      f3 = factorial(150) ./ factorial(143) ;
%      disp('f1, f2, f3 = ') ; disp([f1 f2 f3])
%      disp('   Differences with f2 = ') ; disp([f1-f2 f2-f2 f3-f2])
%
%      % and even for extreme numbers things turn out well
%      f1 = factorialratio(30000,29998) ;
%      f2 = (30000 * 29999) ; % by hand
%      % whereas calls to FACTORIAL fail miserably ...
%      f3 = factorial(30000) ./ factorial(29998) ;
%      disp('f1, f2, f3 = ') ; disp([f1 f2 f3])
%
%    Note that, for instance, factorialratio(200,1) also fails, of course.
%    For such occasions other engines have to be used.
%
%    See also PROD, FACTORIAL, GAMMALN

% for Matlab R13 and up
% version 2.0 (oct 2012)
% (c) Jos van der Geest
% email: jos@jasen.nl

% History
% 1.0 (feb 2009) - created for (later) use in a statistical test
% 1.1 (feb 2009) - fixed minor bug in error checking
% 2.0 (oct 2012) - fixed bug "maxE > 1" which should be "maxE > 0". Thanks
%                  to 'Charles' for pointing this out.

% check the input arguments
error(nargchk(2,2,nargin)) ;
if isempty(A) || isempty(B) || ...
    ~isnumeric(A) || ~isnumeric(B) || ...
    any(A(:)<0) || any(fix(A(:)) ~= A(:)) || ...
    any(B(:)<0) || any(fix(B(:)) ~= B(:))
    error('Inputs should be numerical arrays with positive integers.')
end

% Example for terminology used in comments:
%   FR = factorialratio([6 4],[3 2 1])      call
%      = (6! * 4!) / (3! * 2!)              numerators / denominators  (ignoring ones)
%      = 6*5*4*3*2*4*3*2 / 3*2*2            expanded factorial (showing all factors > 1)
%         [6 5 4 3 2] .^ [1 1 1 2 2]
%      = ----------------------------       as powers (factors and exponents)
%         [6 5 4 3 2] .^ [0 0 0 1 2]
%
%      = [6 5 4 3 2] .^ [1 1 1 1 0]         rewritten

% only values larger than 2 have an effect as both 1! and 0! equal 1
% we can subtract 1 if we do not forget to add 1 later
A = A(A>1) - 1 ;
B = B(B>1) - 1 ;

% what is the largest element?
maxE = max([A(:) ; B(:) ; 0]) ;

if maxE > 0 && ~isequal(A,B),
    % Create a 2 by m array holding the elements of A and B:
    % - the first column refers to the numerators of the ratio (A)
    % - the second column refers to the denominators of the ratio (B)
    R = sparse(A,1,1,maxE,2) + sparse(B,2,1,maxE,2) ;

    % By flipping, cumsumming (over columns) and flipping again ...
    R = flipud(cumsum(flipud(R))) ;
    % ... we get numbers that indicate how many times a factor is present in
    % the expanded ratio. R(X,1) indicates the number of times (X+1) is present in
    % the numerator in the expanded ratio, and R(X,2) the number of times
    % (X+1) is present in the denominator. The difference will give us the
    % exponent for taking the power of the value (X+1).
    R = (R(:,1) - R(:,2)).' ;    % exponents
    X = 2:(maxE+1) ;             % base numbers (we now do need to add the 1)

    % We only used the nonzero entries, since X^0 = 1, and this may affect
    % the time used for ...
    q = find(R) ;
    % ... getting the total product
    FR = prod(X(q).^R(q)) ; %
else
    % All elements were less than 2, or A equals B
    FR = 1 ;
end


function e = line_cvt_energy ( n, a, b, x )

%*****************************************************************************80
%
%% LINE_CVT_ENERGY computes the CVT energy for a given set of generators.
%
%  Discussion:
%
%    Given a set of generators G over the line [A,B], then the energy
%    is defined as
%      E = integral ( a <= x <= b ) ( x - g(x) )^2 dx
%    where g(x) is the nearest generator to the point x.
%
%    For the 1D case, this integral can be evaluated exactly as the
%    sum of integrals over each subinterval:
%
%      E(i) = integral ( xl <= x <= xr ) ( x - x(i) )^2 dx
%           = ( ( x(i) - xl )^3 + ( xr - x(i) )^3 ) / 3
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 July 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of generators.
%
%    Input, real A, B, the left and right endpoints.
%
%    Input, real X(N), the generator locations.
%
%    Output, real E, the energy of the generator distribution.
%
  e = 0.0;

  for j = 1 : n

    if ( j == 1 )
      xl = a;
    else
      xl = ( x(j-1) + x(j) ) / 2.0;
    end

    if ( j == n )
      xr = b;
    else
      xr = ( x(j) + x(j+1) ) / 2.0;
    end

    e = e + ( ( x(j) - xl )^3 + ( xr - x(j) )^3  ) / 3.0;

  end

  return
end


function [ x, seed ] = normal_01_sample ( seed )

%*****************************************************************************80
%
%% NORMAL_01_SAMPLE samples the standard normal probability distribution.
%
%  Discussion:
%
%    The standard normal probability distribution function (PDF) has
%    mean 0 and standard deviation 1.
%
%    The Box-Muller method is used.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 August 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer SEED, a seed for the random number generator.
%
%    Output, X, a sample of the standard normal PDF.
%
%    Output, integer SEED, an updated seed for the random number generator.
%
  [ r1, seed ] = r8_uniform_01 ( seed );
  [ r2, seed ] = r8_uniform_01 ( seed );
  x = sqrt ( -2.0 * log ( r1 ) ) * cos ( 2.0 * pi * r2 );

  return
end


function value = ball_unit_volume_3d ( )

%*****************************************************************************80
%
%% BALL_UNIT_VOLUME_3D computes the volume of a unit ball in 3D.
%
%  Integration region:
%
%    Points (X,Y,Z) such that
%
%      X**2 + Y**2 + Z**2 <= 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, real BALL_UNIT_VOLUME_3D, the volume of the ball.
%
  value = ( 4.0E+00 / 3.0E+00 ) * pi;

  return
end


function lambda = lambda_measure ( dim_num, n, z )

%*****************************************************************************80
%
%% LAMBDA_MEASURE determines the pointset quality measure LAMBDA.
%
%  Discussion:
%
%    The LAMBDA measure of point distribution quality for a set Z of
%    N points in an DIM_NUM-dimensional region is defined as follows:
%
%    Let
%
%      GAMMA(I) = minimum ( 1 <= J <= N, I /= J ) distance ( Z(I), Z(J) )
%
%    and let
%
%      GAMMA_AVE = sum ( 1 <= I <= N ) GAMMA(I) / N
%
%    then
%
%      LAMBDA = sqrt ( sum ( 1 <= I <= N ) ( GAMMA(I) - GAMMA_AVE )**2 / N )
%        / GAMMA_AVE
%
%    An ideally regular mesh would have GAMMA(I) = GAMMA_AVE for all I,
%    so that LAMBDA would be 0.  Under this measure, the mesh with the
%    smaller value of LAMBDA is to be preferred.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 November 2004
%
%  Author:
%
%    Max Gunzburger
%    John Burkardt
%
%  Reference:
%
%    Max Gunzburger and John Burkardt,
%    Uniformity Measures for Point Samples in Hypercubes.
%
%  Parameters:
%
%    Input, integer DIM_NUM, the spatial dimension.
%
%    Input, integer N, the number of points.
%
%    Input, real Z(DIM_NUM,N), the points.
%
%    Output, real LAMBDA, the LAMBDA quality measure.
%
%  Local parameters:
%
%    Local, real GAMMA_MAX, the maximum, over all points,
%    of the minimum distance to a distinct point.
%
%    Local, real GAMMA_MIN, the minimum, over all points,
%    of the minimum distance to a distinct point.
%

%
%  Take care of ridiculous cases.
%
  if ( n <= 1 )
    lambda = 0.0;
    return
  end
%
%  Compute the minimum spacing between distinct points of the set.
%
  gamma = pointset_spacing ( dim_num, n, z );
%
%  Average the minimum spacing.
%
  gamma_ave = sum ( gamma(1:n) ) / n;
%
%  Compute a weighted variance.
%
  if ( gamma_ave <= 0.0 )
    lambda = r8_huge ( );
  else
    lambda = sqrt ( sum ( ( gamma(1:n) - gamma_ave ).^2 ) / n ) / gamma_ave;
  end

  return
end


function Adj = polygon(N, d, rad)
% Adj = polygon(N, d, rad)
% Plots the regular polygon {N/d} with vertices on a circle of radius
% 'rad'. The output 'Adj' is the adjacency matrix of the corresponding
% graph.
%
% Description:
% ------------
% Let d < N be a positive integer and define p = N/d.
% Let y_{1} be a point on the unit circle. Let R be clockwise
% rotation by the angle t = 2*pi/p. The generalized regular
% polygon {p} is given by the points y_{i+1} = R * y_{i}, and edges
% between points i and i+1.
%
% Example:
% --------
% polygon(9, 4, 1);
%
%
% Nima Moshtagh (nima@seas.upenn.edu)
% University of Pennsylvania
%
% Sept. 2007
%

% check the values of 'd' and 'N'. They must be integers.
if (d - round(d)) ~= 0 || (N - round(N)) ~= 0
    display('error: Input parameters N and d must be integers!');
    return;
elseif d > N,
        display('error: d must be less than or equal to N.');
        return
else
    p = N/d;
    t = 2*pi/p;
end

% generate the vertices.
%theta = [pi/N : 2*pi/N : 2*pi];
theta = [0 : 2*pi/N : 2*pi]
Pos = rad * exp(i*theta);

X = real(Pos);
Y = imag(Pos);

% plot the vertices on a circle
plot(X,Y,'o');
axis([-2*rad 2*rad -2*rad 2*rad]);

A = zeros(N);
for j = 1:N,
    % compute the position of the neighboring vertix
    node = exp(i*t) *Pos(j);
    xx = real(node);
    yy = imag(node);

    % find the index of the neighboring vertix
    indx = mod(j+d,N);
    if indx == 0,
        indx = N;
    end
    A(j,indx) = 1;
    % connect the vertices
    line([X(j) xx], [Y(j) yy]);
end
axis equal
% the Adjacency matrix
Adj = A + A';


function fx = p10_fun ( n, x )

%*****************************************************************************80
%
%% P10_FUN evaluates the integrand for problem 10.
%
%  Interval:
%
%    0 <= x <= 1
%
%  Integrand:
%
%    1 / ( 1 + x )
%
%  Antiderivative:
%
%    ln ( 1 + x )
%
%  Exact Integral:
%
%    ln ( 2 )
%
%  Approximate Integral (25 digits):
%
%    0.6931471805599453094172321...
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 November 2009
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    David Kahaner,
%    Comparison of Numerical Quadrature Formulas,
%    in Mathematical Software, edited by John R Rice,
%    Academic Press, 1971.
%
%  Parameters:
%
%    Input, integer N, the number of evaluation points.
%
%    Input, real X(N), the evaluation points.
%
%    Output, real FX(N), the integrand values.
%
  fx = 1.0 ./ ( 1.0 + x );

  return
end


function root = newton(f,g,xo,epsilon)
% Program : newton.m
%
% Purpose : find the root of a given single variable function within the
%           given interval
%
% Author :  Aamir Alaud Din
% Date :    20.09.2013
%
% Inputs :  At least three input arguments are required viz., function,
%           derivative of the function, and initial guess
%
% Syntax :  root = newton(f,g,xo)
%           where f is an inline function and is continuous in the given
%           interval
%           e.g., f = inline('sin(x)','x');
%           g is the first derivative of f in the form of inline function
%           and is continuous in the given interval
%           e.g., g = inline('cos(x)','x');
%           xo is the initial guess which lies in the given interval
%
% Example:  root = newton(f,g,5)
%           The fourth input argument is the stopping criteria
%           If the function value deceeds epsilon, the loop terminates
%           giving the root. Default is 1e-6.
%
% Syntax :  root = newton(f,g,xo,epsilon)
%           where f, g, xo, and epsilon are explained above.
%
% Example:  root = bisection(f,g,-2,1e-9)

if (nargin < 3)
    error('Less input arguments provided.');

elseif (nargin == 3)
    epsilon = 1e-6;
    Iter = 0;
    fprintf('Iteration\t\t   xo\t\t   x1\t\t\tf(x)\t\t\tg(x)\n');
    fprintf('=========\t\t ======\t\t ======\t\t===========\t\t===========\t\t\n');
    while (abs(f(xo)) >= epsilon)
        Iter = Iter + 1;
        if (g(xo) == 0)
            fprintf('g(xo) is zero on iteration number %d',Iter);
            fprintf('\n');
            disp('We can''t compute the root');
            return;
        end
        x1 = xo - (f(xo)/g(xo));
        fprintf('%3d',Iter);
        fprintf('%20.4f',xo);
        fprintf('%12.4f',x1);
        fprintf('%16.4f',f(xo));
        fprintf('%16.4f',g(xo));
        fprintf('\n');
        xo = x1;
    end
    root = xo;
elseif (nargin == 4)
    Iter = 0;
    fprintf('Iteration\t\t   xo\t\t   x1\t\t\tf(x)\t\t\tg(x)\n');
    fprintf('=========\t\t ======\t\t ======\t\t===========\t\t===========\t\t\n');
    while (abs(f(xo)) >= epsilon)
        Iter = Iter + 1;
        if (g(xo) == 0)
            fprintf('g(xo) is zero on iteration number %d',Iter);
            fprintf('\n');
            disp('We can''t compute the root');
            return;
        end
        x1 = xo - (f(xo)/g(xo));
        fprintf('%3d',Iter);
        fprintf('%20.4f',xo);
        fprintf('%12.4f',x1);
        fprintf('%16.4f',f(xo));
        fprintf('%16.4f',g(xo));
        fprintf('\n');
        xo = x1;
    end
    root = xo;
end


%% Ex. 11 Another example for the usage of index for a matrix

A = [3 5; 2 4];
norm1 = 0;
for m = 1:2
for n = 1:2
 norm1 = norm1+A(m,n)^2;
end
end
norm1 = sqrt(norm1)

%Output:
%    norm1 = 7.348
% Remark: This program calculates the Euclidean norm of the A matrix


function C=discSinCosTrans(x,type)
%%DISCSINCOSTRANS Compute the 1D discrete sine or cosine transformation of
%              a given array. All 16 standard types of sine and cosine
%              transforms are available plus a unitary version of the type
%              II even cosine transform.
%
%INPUTS: x  An (N+1)X1 or 1X(N+1) real or complex vector whose discrete
%           sine or cosine transform is desired.
%     type  A string specifying the type of discrete sine or cosine
%           transform desired. If omitted or an empty matrix is passed, the
%           default is 'CIIe'. Possible values are:
%           'CIe' Perform a type I even discrete cosine transform. The
%                 item in element k of the result is
%                 x(0)+(-1)^k*X(N-1)+2*sum_{j=1}^{N-2}x(j)*cos(pi*j*k/(N-1))
%                 where all indexation is form 0.
%           'CIIe' Perform a type II even discrete cosine transform. The
%                 item in element k of the result is the sum from n=0 to
%                 N-1 of
%                 2*x(n)*cos(pi*k*(n+1/2)/N), where all indexation is from
%                 0.
%         'CIIeU' This is the same as type CIIe, except for scaling. The
%                 scaling is
%                 CU(1)=CII(1)/(2*sqrt(N));
%                 CU(2:end)=CII(2:end)*0.5*sqrt(2/N); where CIIe is the
%                 type 2 transform and CU is the unitary transform.
%         'CIIIe' Perform a type III even discrete cosine transform.
%          'CIVe' Perform a type IV even discrete cosine transform.
%           'CIo' Perform a type I odd discrete cosine transform.
%          'CIIo' Perform a type II odd discrete cosine transform.
%         'CIIIo' Perform a type III odd discrete cosine transform.
%          'CIVo' Perform a type IV odd discrete cosine transform.
%           'SIe' Perform a type I even discrete sine transform.
%          'SIIe' Perform a type II even discrete sine transform.
%         'SIIIe' Perform a type III even discrete sine transform.
%          'SIVe' Perform a type IV even discrete sine transform.
%         'SIIIe' Perform a type III even discrete sine transform.
%          'SIVe' Perform a type IV even discrete sine transform.
%           'SIo' Perform a type I odd discrete sine transform.
%          'SIIo' Perform a type II odd discrete sine transform.
%         'SIIIo' Perform a type III odd discrete sine transform.
%          'SIVo' Perform a type IV odd discrete sine transform.
%
%OUTPUTS: C The (N+1)X1 or 1X(N+1) real discrete cosine or sine
%           transformation of x.
%
%The algorithms are implemented using the generalized discrete Fourier
%transform (GDFT) based upon the relations of the sequences and the GDFT
%that are given in [1]. The definition of the unitary version of the type
%II transformation is taken from [2].
%
%The inverse of this function is invDiscSinCosTrans.
%
%REFERENCES:
%[1] S. Martucci, "Symmetric convolution and the discrete sine and cosine
%    transforms," IEEE Transactions on Signal Processing, vol. 42, no. 5,
%    pp. 1038-1051, May 1994.
%[2] J. Makhoul, "A fast cosine transform in one and two dimensions," IEEE
%    Transactions on Acoustics, Speech, and Signal Processing, vol. ASSP-
%    28, no. 1, pp. 27-34, Feb. 1980.
%
%December 2016 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<2)
    type='CIIe';
end

N=length(x);
if(size(x,1)==N)
    colVec=true;
else
    colVec=false;
end

x=x(:);
switch(type)
    case 'CIIeU'
        %Perform the CIIe transform
        C=genDFT([x;flip(x)],0,1/2);
        C=C(1:N);

        %Modify the weighting.
        C(1)=C(1)/(2*sqrt(N));
        C(2:end)=C(2:end)*0.5*sqrt(2/N);
    case 'CIe'
        C=fft([x;x((N-1):-1:2)]);
        C=C(1:N);
    case 'CIIe'
        C=genDFT([x;flip(x)],0,1/2);
        C=C(1:N);
    case 'CIIIe'
        C=genDFT([x;0;-flip(x(2:end))],1/2,0);
        C=C(1:N);
    case 'CIVe'
        C=genDFT([x;-flip(x)],1/2,1/2);
        C=C(1:N);
    case 'CIo'
        C=fft([x;flip(x(2:end))]);
        C=C(1:N);
    case 'CIIo'
        C=genDFT([x;flip(x(1:(end-1)))],0,1/2);
        C=C(1:N);
    case 'CIIIo'
        C=genDFT([x;-flip(x(2:end))],1/2,0);
        C=C(1:N);
    case 'CIVo'
        C=genDFT([x;0;-flip(x)],1/2,1/2);
        C=C(1:N);
    case 'SIe'
        C=1j*fft([0;x;0;-flip(x)]);
        C=C(2:(N+1));
    case 'SIIe'
        C=1j*genDFT([x;-flip(x)],0,1/2);
        C=C(2:(N+1));
    case 'SIIIe'
        C=1j*genDFT([0;x(1:end);flip(x(1:(end-1)))],1/2,0);
        C=C(1:N);
    case 'SIVe'
        C=1j*genDFT([x;flip(x)],1/2,1/2);
        C=C(1:N);
    case 'SIo'
        C=1j*fft([0;x;-flip(x)]);
        C=C(2:(N+1));
    case 'SIIo'
        C=1j*genDFT([x;0;-flip(x)],0,1/2);
        C=C(2:(N+1));
    case 'SIIIo'
        C=1j*genDFT([0;x;flip(x)],1/2,0);
        C=C(1:N);
    case 'SIVo'
        C=1j*genDFT([x;flip(x(1:(end-1)))],1/2,1/2);
        C=C(1:N);
    otherwise
        error('Discrete cosine transform type not suported.')
end

%Get rid of finite precision errors. We know that if the purely input is
%real or imaginary, then the output must be the same.
if(isreal(x))
	C=real(C);
elseif(isImag(x))
    C=1j*imag(C);
end

if(~colVec)
    C=C.';
end
end

%LICENSE:
%
%The source code is in the public domain and not licensed or under
%copyright. The information and software may be used freely by the public.
%As required by 17 U.S.C. 403, third parties producing copyrighted works
%consisting predominantly of the material produced by U.S. government
%agencies must provide notice with such work(s) identifying the U.S.
%Government material incorporated and stating that such material is not
%subject to copyright protection.
%
%Derived works shall not identify themselves in a manner that implies an
%endorsement by or an affiliation with the Naval Research Laboratory.
%
%RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE
%SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY THE NAVAL
%RESEARCH LABORATORY FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE ACTIONS
%OF RECIPIENT IN THE USE OF THE SOFTWARE.