function x = blend_102 ( r, s, x00, x01, x10, x11 )

%*****************************************************************************80
%
%% BLEND_102 extends scalar point data into a square.
%
%  Diagram:
%
%    01------------11
%     |      .      |
%     |      .      |
%     |.....rs......|
%     |      .      |
%     |      .      |
%    00------------10
%
%  Formula:
%
%    Written in terms of R and S, the map has the form:
%
%      X(R,S) =
%               1     * ( + x00 )
%             + r     * ( - x00 + x10 )
%             + s     * ( - x00       + x01 )
%             + r * s * ( + x00 - x10 - x01 + x11 )
%
%    Written in terms of the coefficients, the map has the form:
%
%      X(R,S) = x00 * ( 1 - r - s + r * s )
%             + x01 * (         s - r * s )
%             + x10 * (     r     - r * s )
%             + x11 * (             r * s )
%
%             = x00 * ( 1 - r ) * ( 1 - s )
%             + x01 * ( 1 - r ) *       s
%             + x10 *       r   * ( 1 - s )
%             + x11 *       r           s
%
%    The nonlinear term ( r * s ) has an important role:
%
%      If ( x01 + x10 - x00 - x11 ) is zero, then the input data lies in
%      a plane, and the mapping is affine.  All the interpolated data
%      will lie on the plane defined by the four corner values.  In
%      particular, on any line through the square, data values at
%      intermediate points will lie between the values at the endpoints.
%
%      If ( x01 + x10 - x00 - x11 ) is not zero, then the input data does
%      not lie in a plane, and the interpolation map is nonlinear.  On
%      any line through the square, data values at intermediate points
%      may lie above or below the data values at the endpoints.  The
%      size of the coefficient of r * s will determine how severe this
%      effect is.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 October 2008
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    William Gordon,
%    Blending-Function Methods of Bivariate and Multivariate Interpolation
%    and Approximation,
%    SIAM Journal on Numerical Analysis,
%    Volume 8, Number 1, March 1971, pages 158-177.
%
%    William Gordon and Charles Hall,
%    Transfinite Element Methods: Blending-Function Interpolation over
%    Arbitrary Curved Element Domains,
%    Numerische Mathematik,
%    Volume 21, Number 1, 1973, pages 109-129.
%
%    William Gordon and Charles Hall,
%    Construction of Curvilinear Coordinate Systems and Application to
%    Mesh Generation,
%    International Journal of Numerical Methods in Engineering,
%    Volume 7, 1973, pages 461-477.
%
%    Joe Thompson, Bharat Soni, Nigel Weatherill,
%    Handbook of Grid Generation,
%    CRC Press, 1999.
%
%  Parameters:
%
%    Input, real R, S, the coordinates where an
%    interpolated value is desired.
%
%    Input, real X00, X01, X10, X11, the data values
%    at the corners.
%
%    Output, real X, the interpolated data value at (R,S).
%
  x =             + x00 ...
      + r *     ( - x00 + x10 ) ...
      + s *     ( - x00       + x01 ) ...
      + r * s * ( + x00 - x10 - x01 + x11 );

  return
end


function b = bernoulli_number ( n )

%*****************************************************************************80
%
%% BERNOULLI_NUMBER computes the value of the Bernoulli numbers B(0) through B(N).
%
%  Discussion:
%
%    The Bernoulli numbers are rational.
%
%    If we define the sum of the M-th powers of the first N integers as:
%
%      SIGMA(M,N) = sum ( 0 <= I <= N ) I**M
%
%    and let C(I,J) be the combinatorial coefficient:
%
%      C(I,J) = I! / ( ( I - J )! * J! )
%
%    then the Bernoulli numbers B(J) satisfy:
%
%      SIGMA(M,N) = 1/(M+1) * sum ( 0 <= J <= M ) C(M+1,J) B(J) * (N+1)**(M+1-J)
%
%  First values:
%
%   B0  1                   =         1.00000000000
%   B1 -1/2                 =        -0.50000000000
%   B2  1/6                 =         1.66666666666
%   B3  0                   =         0
%   B4 -1/30                =        -0.03333333333
%   B5  0                   =         0
%   B6  1/42                =         0.02380952380
%   B7  0                   =         0
%   B8 -1/30                =        -0.03333333333
%   B9  0                   =         0
%  B10  5/66                =         0.07575757575
%  B11  0                   =         0
%  B12 -691/2730            =        -0.25311355311
%  B13  0                   =         0
%  B14  7/6                 =         1.16666666666
%  B15  0                   =         0
%  B16 -3617/510            =        -7.09215686274
%  B17  0                   =         0
%  B18  43867/798           =        54.97117794486
%  B19  0                   =         0
%  B20 -174611/330          =      -529.12424242424
%  B21  0                   =         0
%  B22  854,513/138         =      6192.123
%  B23  0                   =         0
%  B24 -236364091/2730      =    -86580.257
%  B25  0                   =         0
%  B26  8553103/6           =   1425517.16666
%  B27  0                   =         0
%  B28 -23749461029/870     = -27298231.0678
%  B29  0                   =         0
%  B30  8615841276005/14322 = 601580873.901
%
%  Recursion:
%
%    With C(N+1,K) denoting the standard binomial coefficient,
%
%    B(0) = 1.0
%    B(N) = - ( sum ( 0 <= K < N ) C(N+1,K) * B(K) ) / C(N+1,N)
%
%  Warning:
%
%    This recursion, which is used in this routine, rapidly results
%    in significant errors.
%
%  Special Values:
%
%    Except for B(1), all Bernoulli numbers of odd index are 0.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 December 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the highest Bernoulli number to compute.
%
%    Output, real B(1:N+1), B(I+1) contains the I-th Bernoulli number.
%
  if ( n < 0 )
    b = [];
    return
  end

  b(1) = 1.0;

  if ( n < 1 )
    return
  end

  b(2) = -0.5;

  c = zeros ( n + 2, 1 );

  c(1) = 1;
  c(2) = 2;
  c(3) = 1;

  for i = 2 : n

    c = comb_row_next ( i + 1, c );

    if ( mod ( i, 2 ) == 1 )

      b(i+1) = 0.0;

    else

      b_sum = 0.0;
      for j = 0 : i - 1
        b_sum = b_sum + b(j+1) * c(j+1);
      end

      b(i+1) = -b_sum / c(i+1);

    end

  end

  return
end


function [s,t]=HFMChirp(T,fStart,fEnd,tSamp,phi)
%%LFMCHIRP Generate a complex hyperbolic frequency modulated (HFM) signal.
%          It can be an upchirp or a downchirp. HFM chirps have a role in
%          radar and sonar signal processing. They are more Doppler
%          insensitive than linear FM chirps.
%
%INPUTS: T The duration of the chirp (seconds).
%   fStart The frequency at the start of the chirp (Hertz). This must be
%          >0.
%     fEnd The frequency at the end of the chirp (Hertz). This must be >0.
%    tSamp If this is scalar, it is the sampling rate of the chirp and the
%          number of samples depends on T. Otherwise, this is a numSampX1
%          array of times at which samples are desired. Samples before
%          time 0 and after time T are set to zero. If this parameter is
%          omitted or an empty matrix is passed, the Nyquist sampling
%          rate is used.
%      phi The phase offset of the chirp. If this parameter is omitted or
%          an empty matrix is passed, then the default of pi/2 is used,
%          which makes the real part of the signal start at zero.
%
%OUTPUT: s The numSampX1 complex chirp signal.
%        t The sample times used. If tSamp was not a scalar, then this is
%          just tSamp.
%
%HFM chirps are described in [1] along with a range bias model for target
%tracking that is relevant when Doppler filtering is not performed.
%
%EXAMPLE 1:
%Here is an example of an upchirp:
% T=1e-3;
% fStart=1e3;
% fEnd=50e3;
% tSamp=1/(100*2*fEnd);%100 times the Nyquist frequency.
% [s,t]=HFMChirp(T,fStart,fEnd,tSamp);
% figure(1)
% clf
% plot(t,real(s),'linewidth',2)
% h1=xlabel('t');
% h2=ylabel('s');
% set(gca,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h1,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h2,'FontSize',14,'FontWeight','bold','FontName','Times')

%EXAMPLE 2:
%Here is an example of a downchirp:
% T=1e-3;
% fStart=50e3;
% fEnd=1e3;
% tSamp=1/(100*2*fStart);%100 times the Nyquist frequency.
% [s,t]=HFMChirp(T,fStart,fEnd,tSamp);
% figure(2)
% clf
% plot(t,real(s),'linewidth',2)
% h1=xlabel('t');
% h2=ylabel('s');
% set(gca,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h1,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h2,'FontSize',14,'FontWeight','bold','FontName','Times')
%
%REFERENCES:
%[1] X. Song, P. Willett, and S. Zhou, "Range bias modeling for hyperbolic-
%    frequency-modulated waveforms in target tracking," IEEE Journal of
%    Oceanic Engineering, vol. 37, no. 4, pp. 670-679, Oct. 2012.
%
%November 2016 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<4||isempty(tSamp))
   %Default to the Nyquist sampling rate.
   tSamp=1/(2*max(fStart,fEnd));
end

if(nargin<5||isempty(phi))
   phi=pi/2;%Phase offset so the signal starts at zero, by default.
end

%Equation 1
b=(fStart-fEnd)/(fStart*fEnd*T);

if(isscalar(tSamp))
    %If a scalar sampling rate is given.
    NPulse=fix(T/tSamp);
    t=(0:(NPulse-1))*tSamp;
else
    %If the samples themselves are given
    t=tSamp;
end

s=exp(1j*(phi+(2*pi/b)*log(1+b*fStart*t)));

sel=(t>T)&(t<0);
s(sel)=0;

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 [ n_data_new, n, c ] = bernoulli_number_values ( n_data )

%*****************************************************************************80
%
%% BERNOULLI_NUMBER_VALUES returns some values of the Bernoulli numbers.
%
%  Discussion:
%
%    The Bernoulli numbers are rational.
%
%    If we define the sum of the M-th powers of the first N integers as:
%
%      SIGMA(M,N) = sum ( 0 <= I <= N ) I**M
%
%    and let C(I,J) be the combinatorial coefficient:
%
%      C(I,J) = I! / ( ( I - J )! * J! )
%
%    then the Bernoulli numbers B(J) satisfy:
%
%      SIGMA(M,N) = 1/(M+1) * sum ( 0 <= J <= M ) C(M+1,J) B(J) * (N+1)**(M+1-J)
%
%  First values:
%
%   B0  1                   =         1.00000000000
%   B1 -1/2                 =        -0.50000000000
%   B2  1/6                 =         1.66666666666
%   B3  0                   =         0
%   B4 -1/30                =        -0.03333333333
%   B5  0                   =         0
%   B6  1/42                =         0.02380952380
%   B7  0                   =         0
%   B8 -1/30                =        -0.03333333333
%   B9  0                   =         0
%  B10  5/66                =         0.07575757575
%  B11  0                   =         0
%  B12 -691/2730            =        -0.25311355311
%  B13  0                   =         0
%  B14  7/6                 =         1.16666666666
%  B15  0                   =         0
%  B16 -3617/510            =        -7.09215686274
%  B17  0                   =         0
%  B18  43867/798           =        54.97117794486
%  B19  0                   =         0
%  B20 -174611/330          =      -529.12424242424
%  B21  0                   =         0
%  B22  854,513/138         =      6192.123
%  B23  0                   =         0
%  B24 -236364091/2730      =    -86580.257
%  B25  0                   =         0
%  B26  8553103/6           =   1425517.16666
%  B27  0                   =         0
%  B28 -23749461029/870     = -27298231.0678
%  B29  0                   =         0
%  B30  8615841276005/14322 = 601580873.901
%
%  Recursion:
%
%    With C(N+1,K) denoting the standard binomial coefficient,
%
%    B(0) = 1.0
%    B(N) = - ( sum ( 0 <= K < N ) C(N+1,K) * B(K) ) / C(N+1,N)
%
%  Special Values:
%
%    Except for B(1), all Bernoulli numbers of odd index are 0.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Milton Abramowitz and Irene Stegun,
%    Handbook of Mathematical Functions,
%    US Department of Commerce, 1964.
%
%  Parameters:
%
%    Input, integer N_DATA, indicates the index of the previous test data
%    returned, or is 0 if this is the first call.  For repeated calls,
%    set the input value of N_DATA to the output value of N_DATA_NEW
%    from the previous call.
%
%    Output, integer N_DATA_NEW, the index of the test data.
%
%    Output, integer N, the order of the Bernoulli number.
%
%    Output, real C, the value of the Bernoulli number.
%
  n_max = 10;
  c_vec = [ ...
    1.0000000000E+00, -0.5000000000E+00,  0.1666666667E+00, ...
    0.0000000000E+00, -0.0333333333E+00, -0.02380952381E+00, ...
   -0.0333333333E+00,  0.0757575757E+00, -529.1242424E+00, ...
    601580873.9E+00 ];
  n_vec = [ ...
     0,  1,  2,  3,  4, 6,  8, 10, 20, 30 ];

  n_data_new = n_data;

  if ( n_data_new < 0 )
    n_data_new = 0;
  end

  n_data_new = n_data_new + 1;

  if ( n_max < n_data_new )
    n_data_new = 0;
    n = 0;
    c = 0;
  else
    n = n_vec(n_data_new);
    c = c_vec(n_data_new);
  end

  return
end


function a = r83t_dif2 ( m, n )

%*****************************************************************************80
%
%% R83T_DIF2 returns the DIF2 matrix in R83T format.
%
%  Example:
%
%    N = 5
%
%    2 -1  .  .  .
%   -1  2 -1  .  .
%    . -1  2 -1  .
%    .  . -1  2 -1
%    .  .  . -1  2
%
%  Properties:
%
%    A is banded, with bandwidth 3.
%
%    A is tridiagonal.
%
%    Because A is tridiagonal, it has property A (bipartite).
%
%    A is a special case of the TRIS or tridiagonal scalar matrix.
%
%    A is integral, therefore det ( A ) is integral, and
%    det ( A ) * inverse ( A ) is integral.
%
%    A is Toeplitz: constant along diagonals.
%
%    A is symmetric: A' = A.
%
%    Because A is symmetric, it is normal.
%
%    Because A is normal, it is diagonalizable.
%
%    A is persymmetric: A(I,J) = A(N+1-J,N+1-I).
%
%    A is positive definite.
%
%    A is an M matrix.
%
%    A is weakly diagonally dominant, but not strictly diagonally dominant.
%
%    A has an LU factorization A = L * U, without pivoting.
%
%      The matrix L is lower bidiagonal with subdiagonal elements:
%
%        L(I+1,I) = -I/(I+1)
%
%      The matrix U is upper bidiagonal, with diagonal elements
%
%        U(I,I) = (I+1)/I
%
%      and superdiagonal elements which are all -1.
%
%    A has a Cholesky factorization A = L * L', with L lower bidiagonal.
%
%      L(I,I) =    sqrt ( (I+1) / I )
%      L(I,I-1) = -sqrt ( (I-1) / I )
%
%    The eigenvalues are
%
%      LAMBDA(I) = 2 + 2 * COS(I*PI/(N+1))
%                = 4 SIN^2(I*PI/(2*N+2))
%
%    The corresponding eigenvector X(I) has entries
%
%       X(I)(J) = sqrt(2/(N+1)) * sin ( I*J*PI/(N+1) ).
%
%    Simple linear systems:
%
%      x = (1,1,1,...,1,1),   A*x=(1,0,0,...,0,1)
%
%      x = (1,2,3,...,n-1,n), A*x=(0,0,0,...,0,n+1)
%
%    det ( A ) = N + 1.
%
%    The value of the determinant can be seen by induction,
%    and expanding the determinant across the first row:
%
%      det ( A(N) ) = 2 * det ( A(N-1) ) - (-1) * (-1) * det ( A(N-2) )
%                = 2 * N - (N-1)
%                = N + 1
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 July 2000
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Robert Gregory, David Karney,
%    A Collection of Matrices for Testing Computational Algorithms,
%    Wiley, 1969,
%    ISBN: 0882756494,
%    LC: QA263.68
%
%    Morris Newman, John Todd,
%    Example A8,
%    The evaluation of matrix inversion programs,
%    Journal of the Society for Industrial and Applied Mathematics,
%    Volume 6, Number 4, pages 466-476, 1958.
%
%    John Todd,
%    Basic Numerical Mathematics,
%    Volume 2: Numerical Algebra,
%    Birkhauser, 1980,
%    ISBN: 0817608117,
%    LC: QA297.T58.
%
%    Joan Westlake,
%    A Handbook of Numerical Matrix Inversion and Solution of
%    Linear Equations,
%    John Wiley, 1968,
%    ISBN13: 978-0471936756,
%    LC: QA263.W47.
%
%  Parameters:
%
%    Input, integer M, N, the order of the matrix.
%
%    Output, real A(M,3), the matrix.
%
  a = zeros(m,3);

  mn = min ( m, n );

  a(2:mn,1)   = -1.0;
  a(1:mn,2)   = +2.0;
  a(1:mn-1,3) = -1.0;

  if ( m < n )
    a(mn,3) = -1.0;
  elseif ( n < m )
    a(mn+1,1) = -1.0;
  end

  return
end


function value = circle_segment_contains_point ( r, c, omega1, omega2, xy )

%*****************************************************************************80
%
%% CIRCLE_SEGMENT_CONTAINS_POINT reports whether a point is in a circle segment.
%
%  Discussion:
%
%    Begin with a circle of radius R.  Choose two points P1 and P2 on the
%    circle, and draw the chord P1:P2.  This chord divides the circle
%    into two pieces, each of which is called a circle segment.
%    Consider one of the pieces.  The "angle" of this segment is the angle
%    P1:C:P2, where C is the center of the circle.  Let Q be the point on
%    the chord P1:P2 which is closest to C.  The "height" of the segment
%    is the distance from Q to the perimeter of the circle.
%
%    In this function, we allow the circle to have an arbitrary center C,
%    arbitrary radius R, and we describe the points P1 and P2 by specifying
%    their angles OMEGA1 and OMEGA2.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 May 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R, the radius of the circle.
%    0 < R.
%
%    Input, real C(2,1), the center of the circle.
%
%    Input, real OMEGA1, OMEGA2, the angles of the two points on the
%    circumference of the circle that define the circle segment.
%    OMEGA1 < OMEGA2 <= OMEGA1 + 2 * PI
%
%    Input, real XY(2,1), a point.
%
%    Output, integer VALUE, is TRUE if the point is inside the circle segment.
%
  if ( r <= 0.0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'CIRCLE_SEGMENT_CONTAINS_POINT - Fatal error!\n' );
    fprintf ( 1, '  R <= 0.0.\n' );
    error ( 'CIRCLE_SEGMENT_CONTAINS_POINT - Fatal error!' )
  end

  while ( omega2 < omega1 )
    omega2 = omega2 + 2.0 * pi;
  end
%
%  Destroy all row vectors.
%
  c = c(:);
  xy = xy(:);
%
%  Compute the vector V = XY - C:
%
  v(1:2,1) = xy(1:2,1) - c(1:2,1);
%
%  a: Point must be inside the circle, so ||V|| <= R.
%
  v_r = norm ( v );
  if ( r < v_r )
    value = 0;
    return
  end
%
%  b: Angle made by the vector V must be between OMEGA1 and OMEGA2.
%
  v_omega = atan2 ( v(2), v(1) );

  while ( omega1 <= v_omega + 2.0 * pi )
    v_omega = v_omega - 2.0 * pi;
  end

  while ( v_omega + 2.0 * pi <= omega1 )
    v_omega = v_omega + 2.0 * pi;
  end

  if ( omega2 < v_omega )
    value = 0;
    return
  end
%
%  c: Projection of V onto unit centerline must be at least R-H.
%
  omegah = 0.5 * ( omega1 + omega2 );
  v_project = v(1) * cos ( omegah ) + v(2) * sin ( omegah );

  theta = omega2 - omega1;
  h = circle_segment_height_from_angle ( r, theta );

  if ( v_project < r - h )
    value = 0;
    return
  end

  value = 1;

  return
end


function xn=linEqSolveFirstnRows(A,b,n)
%%LINEQSOLVEFIRSTNROWS This function solves the problem A*x=b for the first
%                      n rows of x. The matrix A CAN be singular as long as
%                      a unique solution exists for the first n rows of x.
%                      This function is useful for finding the position
%                      estimate in an information filter state even before
%                      estimates of all of the other target state
%                      components have become observable In such an
%                      instance A is the inverse covariance matrix, x is
%                      the target state and b is the information state.
%
%INPUTS: A The NXN matrix A in the equation A*x=b, where x is unknown. The
%          matrix can be singular, but the first n rows of x should be
%          observable.
%        b The NX1 column vector b in the equation A*x=b.
%        n The number of rows of x, starting from the first row and going
%          down, for which one wishes to solve in the equation A*b. n must
%          be less than or equal to the number of rows in A.
%
%OUTPUTS: xn The first n rows of the column vector of x solved from A*x=b.
%            If any of the components of xn are not finite, then the
%            problem was not completely observable. Because of how the
%            problem is solved, if the kth component is not finite, then
%            all subsequent components will not be finite, regardless of
%            whether they are observable.
%
%The linear equation is solved by performing a modified qr decomposition on
%the matrix A such that A=Q*R, where Q is an rotation matrix and R is a
%LOWER triangular matrix. A standard QR decomposition produces an upper
%triangular matrix. By flipping the rows and columns of a and then
%performing the inverse operations on Q and R, one can get a decomposition
%where R is a lower-triangular marix. One can then write R*x=Q'*b, since
%the transpose of a rotation matrix is its inverse. The first n rows of x
%can then be solved using forward substitution.
%
%The QR decomposition is in Matlab's built-in function qr. It is also
%discussed in Chapter 5.2 of [1].
%
%REFERENCES:
%[1] G. E. Golub and C. F. van Loan, Matrix Computations, 4rd ed.
%    Baltimore, MD: Johns Hopkins University Press, 2013.
%
%June 2014 David F.Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

%Perform a lower-triangular qr decomposition.
[Q,R]=qr(rot90(A,2));
Q=rot90(Q,2);
R=rot90(R,2);
%Now, Q*R=A and R is lower-triangular.

b=Q'*b;

%Perform forward substitution to solve for the first n components of x.
xn=zeros(n,1);
xn(1)=b(1)/R(1,1);
for curRow=2:n
    xn(curRow)=(b(curRow)-sum(xn(1:(curRow-1))'.*R(curRow,1:(curRow-1))))/R(curRow,curRow);
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 a = fibonacci2 ( n )

%*****************************************************************************80
%
%% FIBONACCI2 returns the FIBONACCI2 matrix.
%
%  Example:
%
%    N = 5
%
%    0 1 0 0 0
%    1 1 0 0 0
%    0 1 1 0 0
%    0 0 1 1 0
%    0 0 0 1 1
%
%  Properties:
%
%    A is generally not symmetric: A' /= A.
%
%    A is tridiagonal.
%
%    Because A is tridiagonal, it has property A (bipartite).
%
%    A is banded, with bandwidth 3.
%
%    A is integral: int ( A ) = A.
%
%    A is a zero/one matrix.
%
%    If N = 1 then
%      det ( A ) = 0
%    else
%      det ( A ) = (-1)^(N-1)
%
%    If 1 < N, then A is unimodular.
%
%    For 2 <= N, A has the eigenvalues:
%
%      PHI   (once),
%      1     (N-2) times,
%      1-PHI (once).
%
%    When applied to a Fibonacci1 matrix B, the Fibonacci2 matrix
%    A produces the "next" Fibonacci1 matrix C = A*B.
%
%    Let PHI be the golden ratio (1+sqrt(5))/2.
%
%    For 2 <= N, the eigenvalues and eigenvectors are:
%
%    LAMBDA(1)     = PHI,     vector = (1,PHI,PHI^2,...PHI^(N-1));
%    LAMBDA(2:N-1) = 1        vector = (0,0,0,...,0,1);
%    LAMBDA(N)     = 1 - PHI. vector = ((-PHI)^(N-1),(-PHI)^(N-2),...,1)
%
%    Note that there is only one eigenvector corresponding to 1.
%    Hence, for 3 < N, the matrix is defective.  This fact means,
%    for instance, that the convergence of the eigenvector in the power
%    method will be very slow.
%
%    The family of matrices is nested as a function of N.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    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 == 1 )

        if ( j == 2 )
          a(i,j) = 1.0;
        else
          a(i,j) = 0.0;
        end

      else

        if ( j == i-1 | j == i )
          a(i,j) = 1.0;
        else
          a(i,j) = 0.0;
        end

      end

    end
  end

  return
end


function cdf = cosine_cdf ( x, a, b )

%*****************************************************************************80
%
%% COSINE_CDF evaluates the Cosine CDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 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.
%
  if ( x <= a - pi * b )

    cdf = 0.0;

  elseif ( x <= a + pi * b )

    y = ( x - a ) / b;

    cdf = 0.5 + ( y + sin ( y ) ) / ( 2.0 * pi );

  elseif ( a + pi * b < x )

    cdf = 1.0;

  end

  return
end


function [ area, radin, radout ] = polygon_side_data_2d ( n, side )

%*****************************************************************************80
%
%% POLYGON_SIDE_DATA_2D determines polygonal data from its side length in 2D.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 May 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of sides of the polygon.
%    N must be at least 3.
%
%    Input, real SIDE, the length of one side of the polygon.
%
%    Output, real AREA, the area of the regular polygon.
%
%    Output, real RADIN, the inner radius of the polygon, that is,
%    the radius of the largest circle that can be inscribed within
%    the polygon.
%
%    Output, real RADOUT, the outer radius of the polygon, that is,
%    the radius of the smallest circle that can be described about
%    the polygon.
%
  if ( n < 3 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'POLYGON_SIDE_DATA_2D - Fatal error!\n' );
    fprintf ( 1, '  Input value of N must be at least 3.\n' );
    fprintf ( 1, '  but your input value was N = ', n );
    error ( 'POLYGON_SIDE_DATA_2D - Fatal error!' );
  end

  angle = pi / n;
  area = 0.5 * n * side * side / tan ( angle );
  radin = 0.5 * side / tan ( angle );
  radout = 0.5 * side / sin ( angle );

  return
end


function [J, grad] = cofiCostFunc(params, Y, R, num_users, num_movies, ...
                                  num_features, lambda)
%COFICOSTFUNC Collaborative filtering cost function
%   [J, grad] = COFICOSTFUNC(params, Y, R, num_users, num_movies, ...
%   num_features, lambda) returns the cost and gradient for the
%   collaborative filtering problem.
%

% Unfold the U and W matrices from params
X = reshape(params(1:num_movies*num_features), num_movies, num_features);
Theta = reshape(params(num_movies*num_features+1:end), ...
                num_users, num_features);

% You need to return the following values correctly
J = 0;
X_grad = zeros(size(X));
Theta_grad = zeros(size(Theta));

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost function and gradient for collaborative
%               filtering. Concretely, you should first implement the cost
%               function (without regularization) and make sure it is
%               matches our costs. After that, you should implement the
%               gradient and use the checkCostFunction routine to check
%               that the gradient is correct. Finally, you should implement
%               regularization.
%
% Notes: X - num_movies  x num_features matrix of movie features
%        Theta - num_users  x num_features matrix of user features
%        Y - num_movies x num_users matrix of user ratings of movies
%        R - num_movies x num_users matrix, where R(i, j) = 1 if the
%            i-th movie was rated by the j-th user
%
% You should set the following variables correctly:
%
%        X_grad - num_movies x num_features matrix, containing the
%                 partial derivatives w.r.t. to each element of X
%        Theta_grad - num_users x num_features matrix, containing the
%                     partial derivatives w.r.t. to each element of Theta
%

H_Theta = X * Theta';
Error = H_Theta - Y;
Error_logical = Error .* R;
J = 1/2 * sum(Error_logical(:).^2) + ...
    lambda/2*Theta(:)'*Theta(:) + ...
    lambda/2*X(:)'*X(:);

X_grad = Error_logical*Theta + lambda*X;
Theta_grad = Error_logical'*X + lambda*Theta;

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

grad = [X_grad(:); Theta_grad(:)];

end


function cx = cheby_u_polynomial ( n, x )

%*****************************************************************************80
%
%% CHEBY_U_POLYNOMIAL evaluates the Chebyshev polynomials of the second kind.
%
%  Differential equation:
%
%    (1-X*X) Y'' - 3 X Y' + N (N+2) Y = 0
%
%  First terms:
%
%    U(0)(X) =   1
%    U(1)(X) =   2 X
%    U(2)(X) =   4 X^2 -   1
%    U(3)(X) =   8 X^3 -   4 X
%    U(4)(X) =  16 X^4 -  12 X^2 +  1
%    U(5)(X) =  32 X^5 -  32 X^3 +  6 X
%    U(6)(X) =  64 X^6 -  80 X^4 + 24 X^2 - 1
%    U(7)(X) = 128 X^7 - 192 X^5 + 80 X^3 - 8X
%
%  Recursion:
%
%    U(0)(X) = 1,
%    U(1)(X) = 2 * X,
%    U(N)(X) = 2 * X * U(N-1)(X) - U(N-2)(X)
%
%  Norm:
%
%    Integral ( -1 <= X <= 1 ) ( 1 - X^2 ) * U(N)(X)^2 dX = PI/2
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 July 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the highest polynomial to compute.
%
%    Input, real X, the point at which the polynomials are to be computed.
%
%    Output, real CX(1:N+1), the values of the N+1 Chebyshev polynomials.
%
  cx = zeros ( n + 1, 1 );

  if ( n < 0 )
    cx = [];
    return
  end

  cx(1) = 1.0;

  if ( n < 1 )
    return
  end

  cx(2) = 2.0 * x;

  for i = 2 : n
    cx(i+1) = 2.0 * x * cx(i) - cx(i-1);
  end

  return
end


function fx = p38_fun ( n, x )

%*****************************************************************************80
%
%% P38_FUN evaluates the integrand for problem 38.
%
%  Discussion:
%
%    The problem has a parameter ALPHA that can be set by calling
%    P38_PARAM_SET.
%
%    The integrand oscillates more strongly as ALPHA is increased.
%
%    The suggested range for ALPHA is 0 to 10.
%
%  Interval:
%
%    0 <= x <= pi
%
%  Integrand:
%
%    cos ( 2^ALPHA * sin ( x ) )
%
%  Exact Integral:
%
%    pi * J0 ( 2^ALPHA )
%
%    where J0 ( x ) is the J Bessel function of order 0.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 November 2009
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Robert Piessens, Elise de Doncker-Kapenga,
%    Christian Ueberhuber, David Kahaner,
%    QUADPACK: A Subroutine Package for Automatic Integration,
%    Springer, 1983, page 83.
%
%  Parameters:
%
%    Input, integer N, the number of evaluation points.
%
%    Input, real X(N), the evaluation points.
%
%    Output, real FX(N), the integrand values.
%
  alpha = p38_param_get ( );

  fx = cos ( 2.0^alpha * sin ( x ) );

  return
end


function w = ncoh_compute_weights ( n )

%*****************************************************************************80
%
%% NCOH_COMPUTE_WEIGHTS computes weights for a Newton-Cotes "open half" quadrature rule.
%
%  Discussion:
%
%    The input value N is used to define N equal subintervals of [-1,+1].
%    The I-th abscissa is the center of the I-th subinterval.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 July 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order.
%
%    Output, real W(N), the weights.
%
  x = ncoh_compute_points ( n );

  w = nc_compute ( n, x_min, x_max, x );

  return
end


function [ n_data, x, fx ] = bessel_i1_spherical_values ( n_data )

%*****************************************************************************80
%
%% BESSEL_I1_SPHERICAL_VALUES returns some values of the Spherical Bessel function i1.
%
%  Discussion:
%
%    In Mathematica, the function can be evaluated by:
%
%      Sqrt[Pi/(2*x)] * BesselI[3/2,x]
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 January 2007
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Milton Abramowitz, Irene Stegun,
%    Handbook of Mathematical Functions,
%    National Bureau of Standards, 1964,
%    LC: QA47.A34,
%    ISBN: 0-486-61272-4.
%
%    Stephen Wolfram,
%    The Mathematica Book,
%    Fourth Edition,
%    Wolfram Media / Cambridge University Press, 1999.
%
%  Parameters:
%
%    Input/output, integer N_DATA.  The user sets N_DATA to 0 before the
%    first call.  On each call, the routine increments N_DATA by 1, and
%    returns the corresponding data; when there is no more data, the
%    output value of N_DATA will be 0 again.
%
%    Output, real X, the argument of the function.
%
%    Output, real FX, the value of the function.
%
  n_max = 21;

  fx_vec = [ ...
    0.03336667857363341E+00, ...
    0.06693371456802954E+00, ...
    0.1354788933285401E+00, ...
    0.2072931911031093E+00, ...
    0.2841280857128948E+00, ...
    0.3678794411714423E+00, ...
    0.4606425870674146E+00, ...
    0.5647736480096238E+00, ...
    0.6829590627779635E+00, ...
    0.8182955028627777E+00, ...
    0.9743827435800610E+00, ...
    1.155432469636406E+00, ...
    1.366396525527973E+00, ...
    1.613118767572064E+00, ...
    1.902515460838681E+00, ...
    2.242790117769266E+00, ...
    2.643689828630357E+00, ...
    3.116811526884873E+00, ...
    3.675968313148932E+00, ...
    4.337627987747642E+00, ...
    5.121438384183637E+00 ];

  x_vec = [ ...
     0.1E+00, ...
     0.2E+00, ...
     0.4E+00, ...
     0.6E+00, ...
     0.8E+00, ...
     1.0E+00, ...
     1.2E+00, ...
     1.4E+00, ...
     1.6E+00, ...
     1.8E+00, ...
     2.0E+00, ...
     2.2E+00, ...
     2.4E+00, ...
     2.6E+00, ...
     2.8E+00, ...
     3.0E+00, ...
     3.2E+00, ...
     3.4E+00, ...
     3.6E+00, ...
     3.8E+00, ...
     4.0E+00 ];

  if ( n_data < 0 )
    n_data = 0;
  end

  n_data = n_data + 1;

  if ( n_max < n_data )
    n_data = 0;
    x = 0.0;
    fx = 0.0;
  else
    x = x_vec(n_data);
    fx = fx_vec(n_data);
  end

  return
end


function [y,s]=gammalns(x)
% GAMMALNS Log of Gamma(x) for positive or negative real x [y,s]=(x)
%
%  Inputs: x      real matrix of input values
%
% Outputs: y      log(gamma(x)) or, if s is present, log(abs(gamma(x)))
%          s      sign(gamma(x))
%
% If s is not specified then y will b complex if gamma(x) is negative (i.e. if floor(x) is negative and odd).
% Uses gamma(x) = pi/gamma(1-z)/sin(pi*z) which is 5.5.3 from [1]
%
% [1]	F. W. J. Olver, D. W. Lozier, R. F. Boisvert, and C. W. Clark, editors.
%       NIST Handbook of Mathematical Functions. CUP, 2010. ISBN 978-0-521-14063-8.

%      Copyright (C) Mike Brookes 2017
%      Version: $Id: gammalns.m 9975 2017-07-02 09:57:41Z dmb $
%
%   VOICEBOX is a MATLAB toolbox for speech processing.
%   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   This program is free software; you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation; either version 2 of the License, or
%   (at your option) any later version.
%
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You can obtain a copy of the GNU General Public License from
%   http://www.gnu.org/copyleft/gpl.html or by writing to
%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
persistent l
m=x<=0;
y=zeros(size(x));
s=ones(size(x));
if ~all(m(:)) % non-negative x values
    y(~m)=gammaln(x(~m));
end
f=m & (x==fix(x)); % find and non-positive integers
if any(f(:))
    y(f)=Inf; % set output to infinity
    m=m & ~f; % do not consider these values furhter
end
if any(m(:)) % negative x values
    if isempty(l)
        l=log(pi);
    end
    t=sin(pi*x(m));
    if nargout>1
        p=t<0;
        s(m)=1-2*(p);
        y(m)=l-gammaln(1-x(m))-log(abs(t));
    else
        y(m)=l-gammaln(1-x(m))-log(t);
    end
end


function error_frobenius = r8mat_is_inverse_left ( m, n, a, b )

%*****************************************************************************80
%
%% R8MAT_IS_INVERSE_LEFT determines if one matrix is the left inverse of another.
%
%  Discussion:
%
%    This routine returns the Frobenius norm of B * A - I.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 July 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, N, the number of rows and columns
%    of the matrix.
%
%    Input, real A(M,N), the matrix.
%
%    Input, real B(N,M), the matrix to be checked as a left inverse of A.
%
%    Output, real ERROR_FROBENIUS, the Frobenius norm
%    of the difference matrix B * A - I, which would be exactly zero
%    if B was the exact left inverse of A and computer arithmetic were exact.
%
  c(1:n,1:n) = b(1:n,1:m) * a(1:m,1:n);

  for i = 1 : n
    c(i,i) = c(i,i) - 1.0;
  end

  error_frobenius = r8mat_norm_fro ( n, n, c );

  return
end


function [xi,w]=orthoPolyZerosFromRecur(n,a,b,c,mu0)
%%ORTHOPOLYZEROSFROMRECUR Consider a family of polynomials p_n(x) such that
%              p_n(x) is nth order and the polynomials are orthonormal with
%              respect to some weighting function w(x). This means that
%              integral_lowL^upL w(x)*p_n(x)*p_m(x) dx =1 if m=n and is
%              zero otherwise. All such polynomials can be written in
%              recursive form as
%              p_i(x)=(a(i)*x+b(i))*p_{(i-1)}(x)-c(i)*p_{i-2}(x)
%              starting with p_{-1}(x)=0 and p_0(x)=1. This function finds
%              the zeros of the nth polynomial given expressions for the
%              recursion of the polynomials. Parameters for common
%              orthogonal polynomials are given below. The zeros of such
%              orthonormal polynomials can be used as quadrature points for
%              1D integration from lowL to upL of all polynomials up to
%              order 2*n-1 times the weighting function w(x). The
%              associated quadrature weights for such integrals can also be
%              returned by this function if two outputs are requested.
%
%INPUTS: n The order of the polynomial whose zeros are desired.
%    a,b,c There are two formulations for the input. In the first one,
%          a,b, and c are vectors or function handles such that a(i), b(i),
%          and c(i) give the appropriate values for the recursive
%          formulation of the function values in
%          p_i(x)=(a(i)*x+b(i))*p_{(i-1)}(x)-c(i)*p_{i-2}(x)
%          where the values of i used in a and b go from 1 to n, and
%          indices used in  c(i) go from 2 to n. c(1) is not used.
%          Alternatively, if c is omitted or an empty matrix is passed,
%          then a and b are assumed to be coefficients in the three-term
%          expansion of the form
%          b(i)*p_i(x)=(x-a(i))*p_{(i-1)}(x)-b(i-1)*p_{i-2}(x)
%          and can be vectors or function handles. Indices of a run from 1
%          to n and b run from 1 to (n-1).
%      mu0 This parameter is only needed if the second output of this
%          function is desired. The quadrature weights must be scaled by
%          mu0=integral_lowL^upL w(x) dx. This is that mu0.
%
%OUTPUTS: xi The 1Xn set of zeros of the given set of orthonormal
%            polynomials.
%          w The set of n cubature weights associated with the orthonormal
%            polynomials. This requires the input mu0 be specified.
%
%When xi and w are used for quadrature integration, one can write
%integral_lowL^upL w(x)*f(x) dx=sum_{i=1}^n w(i)*f(xi(i))
%where the equality holds for all polynomials up to degree 2*n-1. This is
%the fundamental theorem of Gaussian quadrature. Thus, finding the zeros of
%polynomials that are orthonormal over a region of interest with respect to
%a particular weighting function can be useful.
%
%The algorithm is that of [1]. Because an eigenvalue decomposition is used,
%the results can be numerically unstable for large n.
%
%Examples of values for common polynomials, are given in [2]. Some are:
%1) Hermite polynomials. These are orthonormal with respect to exp(-x^2)
%   integrated over (-Inf,Inf). The recursion from [3] is
% mu0=sqrt(pi);
% a=@(i)2;
% b=@(i)0;
% c=@(i)2*(i-1);
%
%2) Legendre polynomials. These are orthonormal with respect to w(x)=1 for
%   integration over [-1,+1]. The recursion from [3] is
% mu0=2;
% a=@(i)(2*(i-1)+1)/i;
% b=@(i)0;
% c=@(i)(i-1)/i;
%However, the function GaussLegendrePoints1D should provide
%higher-precision zeros than this function.
%
%3) Laguerre polynomials. These are orthonormal with respect to
%   w(x)=exp(-x) for integration over [0,Inf). The recursion from [3] is
% mu0=1;
% a=@(i)-1/i;
% b=@(i)(2*(i-1)+1)/i;
% c=@(i)(i-1)/i;
%
%4) Associated Laguerre polynomials. These are orthonormal with respect to
%   w(x)=x^c1*exp(-x) for integration over [0,Inf). When considering
%   c1>-1, the recursion from [3] is
% mu0=gamma(1+c1);
% a=@(i)(-1/i);
% b=@(i)(2*i-1+c1)/i;
% c=@(i)(i-1+c1)/i;
%
%5) Gegenbauer polynomials. These are orthonormal with respect to
%   w(x)=(1-x^2)^(c1-1/2) for integration over [-1,1]. When considering
%   c1>-(1/2), the recursion from [3] is
% mu0=(sqrt(pi)*gamma((1/2)+c1))/gamma(1+c1);
% a=@(i)2*(i+c1-1)/i;
% b=@(i)0;
% c=@(i)(i+2*c1-2)/i;
%
%6) Modified Hermite polynomials that are orthogonal with respect to the
%   standard normal N(0,1) distribution integrated over (-Inf,Inf). These
%   are for w(x)=1/sqrt(2*pi)*exp(-x^2/2). The recursion [3] is
% mu0=1;
% a=@(i)1;
% b=@(i)0;
% c=@(i)i-1;
%
%REFERENCES:
%[1] G. H. Golub and J. H. Welsh, "Calculation of Gauss quadrature rules,"
%    Mathematics of Computation, vol. 23, pp. 221-230, 1969.
%[2] Weisstein, Eric W. "Orthogonal Polynomials." From MathWorld--A Wolfram
%    Web Resource. http://mathworld.wolfram.com/OrthogonalPolynomials.html
%[3] Abramowitz, M. and Stegun, I. A. (Eds.). "Orthogonal Polynomials."
%    Table 22.7 in Ch. 22 in Handbook of Mathematical Functions with
%    Formulas, Graphs, and Mathematical Tables, 9th printing. New York:
%    Dover, pp. 782, 1972.
%
%August 2015 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

J=zeros(n,n);
if(nargin<4||isempty(c))
    %If alpha and beta are directly given as a and b.
    for i=1:(n-1)
        J(i,i)=a(i);
        J(i,i+1)=b(i);
        J(i+1,i)=b(i);
    end
    J(n,n)=a(n);
else
    %The first row
    %Rows 1 through n-1
    for i=1:(n-1)
        bi=b(i);
        ai=a(i);
        aiNext=a(i+1);
        ciNext=c(i+1);

        %From Equation 2.2 in [1].
        alpha=-bi/ai;
        beta=sqrt(ciNext/(ai*aiNext));

        J(i,i)=alpha;
        J(i,i+1)=beta;
        J(i+1,i)=beta;
    end
    %The final row
    i=n;
    bi=b(i);
    ai=a(i);
    alpha=-bi/ai;
    J(i,i)=alpha;
end

[V,D]=eig(J);

xi=diag(D)';
w=abs(V(1,:)').^2*mu0;

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 fx = p55_fun ( n, x )

%*****************************************************************************80
%
%% P55_FUN evaluates the integrand for problem 55.
%
%  Interval:
%
%    a = 0 <= x <= 1 = b
%
%  Integrand:
%
%    exp ( - c^2 * ( x - x0 )^2 )
%
%  Exact Integral:
%
%    sqrt ( pi )
%    * ( erf ( c * ( b - x0 ) ) - erf ( c * ( a - x0 ) ) )
%    / ( 2 * c )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 November 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of evaluation points.
%
%    Input, real X(N), the evaluation points.
%
%    Output, real FX(N), the integrand values.
%
  c = p55_param ( 'get', 'c', [] );
  x0 = p55_param ( 'get', 'x0', [] );
  x0 = x0 * ones ( size ( x ) );

  fx(1:n) = exp ( - c * c * ( x(1:n) - x0 ).^2 );

  return
end


function p = circle_imp_points_3d ( r, pc, nc, n )

%*****************************************************************************80
%
%% CIRCLE_IMP_POINTS_3D returns points on an implicit circle in 3D.
%
%  Discussion:
%
%    Points P on an implicit circle in 3D satisfy the equations:
%
%      ( P(1) - PC(1) )^2
%    + ( P(2) - PC(2) )^2
%    + ( P(3) - PC(3) )^2 = R^2
%
%    and
%
%      ( P(1) - PC(1) ) * NC(1)
%    + ( P(2) - PC(2) ) * NC(2)
%    + ( P(3) - PC(3) ) * NC(3) = 0
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 December 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R, the radius of the circle.
%
%    Input, real PC(3,1), the center of the circle.
%
%    Input, real NC(3,1), a nonzero vector that is normal to
%    the plane of the circle.  It is customary, but not necessary,
%    that this vector have unit norm.
%
%    Input, integer N, the number of points desired.
%    N must be at least 1.
%
%    Output, real P(3,N), the coordinates of points
%    on the circle.
%

%
%  Get two unit vectors N1 and N2 which are orthogonal to each other,
%  and to NC.
%
  [ n1, n2 ] = plane_normal_basis_3d ( pc, nc );
%
%  Rotate R units away from PC in the plane of N1 and N2.
%
  for i = 1 : n

    theta = ( 2.0 * pi * ( i - 1 ) ) / n;

    p(1:3,i) = ( pc(1:3,1) ...
      + r * ( cos ( theta ) * n1(1:3,1) ...
            + sin ( theta ) * n2(1:3,1) ) );

  end

  return
end


clear;
clc
close all;

%% EXAMPLE 2.2(a) Conversion of Curvilinear Position to Cartesian ECEF Position

lat = deg2rad(45);
lon = deg2rad(30);
hgt = 1000;

[R_meridian, R_transverse, ~, ~, ~]= ch_earth(lat, lon, hgt);

xyz = ch_lla2ecef(lat, lon, hgt);
xyz

%% EXAMPLE 2.2(b) Conversion of Cartesian ECEF Position to Curvilinear Position
xyz = [3912960.837 2259148.993 4488055.516]';
[lat lon hgt] = ch_ecef2lla(xyz);
lat
lon
hgt


function[varargout]=cum2mom(varargin)
%CUM2MOM  Convert cumulants to moments.
%
%   [M0,M1,...MN]=CUM2MOM(K0,K1,...KN) converts the first N cumulants
%   K0,K1,...KN into the first N moments M0,M1,...MN.
%
%   The KN and MN are all scalars or arrays of the same size.
%
%   Note for a probability density function, M0=1 and K0=0.
%
%   MCELL=CUM2MOM(KCELL), where KCELL is a cell array whose (N+1)th
%   is the Nth cumulant, returns a similar cell array of moments.
%
%   CUM2MOM is inverted by MOM2CUM.
%
%   See also MOM2CUM, BELLPOLY.
%
%   Usage: [m0,m1,m2]=cum2mom(k0,k1,k2);
%          mcell=cum2mom(kcell);
%   __________________________________________________________________
%   This is part of JLAB --- type 'help jlab' for more information
%   (C) 2008 J.M. Lilly --- type 'help jlab_license' for details

%Tests for CUM2MOM are run by MOM2CUM.
if strcmpi(varargin{1}, '--t'),return,end

if nargin==1&&iscell(varargin{1})
    cum=varargin{1};
else
    cum=varargin;
end
mom=cell(size(cum));
mom{1}=exp(cum{1});

cum=cum(2:end);
mom(2:end)=bellpoly(cum);

for i=2:length(mom)
    mom{i}=mom{i}.*mom{1};
end

if nargin==1&&iscell(varargin{1})
    varargout{1}=mom;
else
    varargout=mom;
end


function proj = projPointOnEllipse(point, elli)
%PROJPOINTONELLIPSE Project a point orthogonally onto an ellipse.
%
%   PROJ = projPointOnEllipse(PT, ELLI)
%   Computes the (orthogonal) projection of point PT onto the ellipse given
%   by ELLI.
%
%
%   Example
%     % create an ellipse and a point
%     elli = [50 50 40 20 30];
%     pt = [60 10];
%     % display reference figures
%     figure; hold on; drawEllipse(elli, 'b');
%     axis equal; axis([0 100 0 100]);
%     drawPoint(pt, 'bo');
%     % compute projected point
%     proj = projPointOnEllipse(pt, elli);
%     drawEdge([pt proj], 'b');
%     drawPoint(proj, 'k*');
%
%   See also
%     ellipses2d, distancePointEllipse, projPointOnLine, ellipsePoint
%     drawEllipse
%

% ------
% Author: David Legland
% E-mail: david.legland@inrae.fr
% Created: 2022-07-17, using Matlab 9.12.0.1884302 (R2022a)
% Copyright 2022 INRAE - BIA Research Unit - BIBS Platform (Nantes)

% defaults
nMaxIters = 4;

% compute transform to centered axis-aligned ellipse
center = elli(1:2);
theta = deg2rad(elli(5));
transfo = createRotation(-theta) * createTranslation(-center);
pointT = transformPoint(point, transfo);

% retrieve ellipse semi axis lengths
a = elli(3);
b = elli(4);

% keep absolute values
px = abs(pointT(:,1));
py = abs(pointT(:,2));

% initial guess of solution
tx = 0.707;
ty = 0.707;

% iterate
for i = 1:nMaxIters
    x = a * tx;
    y = b * ty;

    ex = (a*a - b*b) * power(tx, 3) / a;
    ey = (b*b - a*a) * power(ty, 3) / b;

    rx = x - ex;
    ry = y - ey;

    qx = px - ex;
    qy = py - ey;

    r = hypot(ry, rx);
    q = hypot(qy, qx);

    tx = min(1, max(0, (qx .* r ./ q + ex) / a));
    ty = min(1, max(0, (qy .* r ./ q + ey) / b));
    t = hypot(ty, tx);
    tx = tx ./ t;
    ty = ty ./ t;

end

% computes coordinates of projection
projX = a * tx;
projY = b * ty;

% fix sign
projX(pointT(:,1) < 0) = -projX(pointT(:,1) < 0);
projY(pointT(:,2) < 0) = -projY(pointT(:,2) < 0);

% project pack to basis of original ellipse
proj = transformPoint([projX projY], inv(transfo));


function sigma_n = sigma ( n )

%*****************************************************************************80
%
%% SIGMA returns the value of SIGMA(N), the divisor sum.
%
%  Definition:
%
%    SIGMA(N) is the sum of the distinct divisors of N, including 1 and N.
%
%  First values:
%
%     N  SIGMA(N)
%
%     1    1
%     2    3
%     3    4
%     4    7
%     5    6
%     6   12
%     7    8
%     8   15
%     9   13
%    10   18
%    11   12
%    12   28
%    13   14
%    14   24
%    15   24
%    16   31
%    17   18
%    18   39
%    19   20
%    20   42
%
%  Formula:
%
%    SIGMA(U*V) = SIGMA(U) * SIGMA(V) if U and V are relatively prime.
%
%    SIGMA(P^K) = ( P^(K+1) - 1 ) / ( P - 1 ) if P is prime.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 July 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the value to be analyzed.
%
%    Output, integer SIGMA_N, the value of SIGMA(N).  If N is less than
%    or equal to 0, SIGMA_N will be returned as 0.  If there is not
%    enough room for factoring N, SIGMA_N is returned as -1.
%
  maxfactor = 20;

  if ( n <= 0 )
    sigma_n = 0;
    return
  end

  if ( n == 1 )
    sigma_n = 1;
    return
  end
%
%  Factor N.
%
  [ nfactor, factor, power, nleft ] = i4_factor ( n );

  if ( nleft ~= 1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'SIGMA - Fatal error!\n' );
    fprintf ( 1, '  Not enough factorization space.\n' );
    sigma_n = -1;
    error ( 'SIGMA - Fatal error!' );
  end

  sigma_n = 1;
  for i = 1 : nfactor
    sigma_n = ( sigma_n * ( factor(i)^( power(i) + 1 ) - 1 ) ) ...
      / ( factor(i) - 1 );
  end

  return
end


function [ x, err, iter, flag ] = sor(A, x, b, w, max_it, tol)
%
% [ x, err, iter, flag ] = sor(A, x, b, w, max_it, tol)
%
% SOR Successive Over-Relaxation Method
%   This function solves linear equation systems such as Ax=b using SOR
%   method (Successive Over-Relaxation).
%   When the relaxation scalar w=1, the method used is Gauss-Seidel.
%
% Input:
%   A - input matrix
%   x - inicial vector
%   b - vector b
%   w - relaxation scalar
%   max_it - maximum number of iterations
%   tol - tolerance
%
% Output:
%   x - solution vector
%   err - norm err estimate
%   iter - nu,ber of performed iterations
%   flag - 0 = a solution was found / 1 = no convergence for max_it
%
% Example:
%   [ x, err, iter, flag ] = sor( [.5 .125; .125 .25], zeros(2,1),
%       ones(2,1), .5, 1e4, 1e-4 )
%
% Author:	Tashi Ravach
% Version:	1.0
% Date:     08/06/2006
%

    if nargin == 3
        w = .5;
        max_it = 1e4;
        tol = 1e-4;
    elseif nargin == 4
        max_it = 1e4;
        tol = 1e-4;
    elseif nargin == 5
        tol = 1e-4;
    elseif nargin ~= 6
        error('sor: invalid input parameters');
    end

    flag = 0;
    iter = 0;

    norma2_b = norm(b);
    if (norma2_b == 0.0)
        norma2_b = 1.0;
    end

    r = b - A * x;
    err = norm(r) / norma2_b;
    if (err < tol)
        return
    end

    % separate A into several matrix for SOR/Gauss-Seidel
    [ M, N, b ] = matsep(A, b, w, 2);

    for iter = 1 : max_it
        x_1 = x;
        x = M \ (N * x + b); % adjust the aproximation
        %err = norm(x - x_1) / norm(x); % compute error
        err = norm(x_1 - x, 1); % compute error
        if (err <= tol) % check for convergence
            break
        end
    end
    b = b / w; % vector b

    if (err > tol) % no convergence
        flag = 1;
    end

end

function [ M, N, b ] = matsep(A, b, w, flag)
%
% [ M, N, b ] = matsep(A, b, w, flag)
%
% MATSEP Matrix Separation
%   Input matrix is splitted into several others in diferent ways depending
%   on the method to be used: Jacobi and SOR (Gauss-Seidel when w = 1)
%
% Input:
%   A - input matrix
%   x - inicial vector
%   b - vector b
%   flag - 1 = Jacobi / 2 = SOR
%
% Output:
%   M - matrix M
%   N - matrix N
%   b - vector b (modified for SOR)
%
% Author:	Tashi Ravach
% Version:	1.0
% Date:     08/06/2006
%

    if nargin ~= 4
        error('matsep: invalid input parameters');
    end

    [ m, n ] = size(A);
    if m ~= n
        error('matsep: input matrix A must have dimension nXn');
    end

    [ l, o ] = size(b);
    if l ~= n && o ~= 1
        error('matsep: input matrix b must have dimension nX1');
    end

    if (flag == 1) % separation for Jacobi
        M = diag(diag(A));
        N = diag(diag(A)) - A;
    elseif (flag == 2) % separation for SOR/Gauss-Seidel
        b = w * b;
        M =  w * tril(A, -1) + diag(diag(A));
        N = -w * triu(A,  1) + (1.0 - w) * diag(diag(A));
    end

end


function value = torus_square_volume_3d ( r1, r2 )

%*****************************************************************************80
%
%% TORUS_SQUARE_VOLUME_3D returns the volume of a square torus in 3D.
%
%  Integration region:
%
%    Points (X,Y,Z) such that:
%
%      R1 - R2 <= SQRT ( X**2 + Y**2 ) <= R1 + R2,
%      -R2 <= Z <= R2.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R1, R2, the two radii that define the torus.
%
%    Output, real TORUS_SQUARE_VOLUME_3D, the volume of the torus.
%
  value = 8.0E+00 * pi * r1 * r2 * r2;

  return
end


function mean = binomial_mean ( a, b )

%*****************************************************************************80
%
%% BINOMIAL_MEAN returns the mean of the Binomial PDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer A, the number of trials.
%    1 <= A.
%
%    Input, real B, the probability of success on one trial.
%    0.0 <= B <= 1.0.
%
%    Output, real MEAN, the expected value of the number of
%    successes in A trials.
%
  mean = a * b;

  return
end


function w = faddeeva(z,N)
% FADDEEVA   Faddeeva function
%   W = FADDEEVA(Z) is the Faddeeva function, aka the plasma dispersion
%   function, for each element of Z. The Faddeeva function is defined as:
%
%     w(z) = exp(-z^2) * erfc(-j*z)
%
%   where erfc(x) is the complex complementary error function.
%
%   W = FADDEEVA(Z,N) can be used to explicitly specify the number of terms
%   to truncate the expansion (see (13) in [1]). N = 16 is used as default.
%
%   Example:
%       x = linspace(-10,10,1001); [X,Y] = meshgrid(x,x);
%       W = faddeeva(complex(X,Y));
%       figure;
%       subplot(121); imagesc(x,x,real(W)); axis xy square; caxis([-1 1]);
%       title('re(faddeeva(z))'); xlabel('re(z)'); ylabel('im(z)');
%       subplot(122); imagesc(x,x,imag(W)); axis xy square; caxis([-1 1]);
%       title('im(faddeeva(z))'); xlabel('re(z)'); ylabel('im(z)');
%
%   Reference:
%   [1] J.A.C. Weideman, "Computation of the Complex Error Function," SIAM
%       J. Numerical Analysis, pp. 1497-1518, No. 5, Vol. 31, Oct., 1994
%       Available Online: http://www.jstor.org/stable/2158232

if nargin<2, N = []; end
if isempty(N), N = 16; end

w = zeros(size(z)); % initialize output

%%%%%
% for purely imaginary-valued inputs, use erf as is if z is real
idx = real(z)==0; %
w(idx) = exp(-z(idx).^2).*erfc(imag(z(idx)));

if all(idx), return; end
idx = ~idx;

%%%%%
% for complex-valued inputs

% make sure all points are in the upper half-plane (positive imag. values)
idx1 = idx & imag(z)<0;
z(idx1) = conj(z(idx1));

M = 2*N;
M2 = 2*M;
k = (-M+1:1:M-1)'; % M2 = no. of sampling points.
L = sqrt(N/sqrt(2)); % Optimal choice of L.

theta = k*pi/M;
t = L*tan(theta/2); % Variables theta and t.
f = exp(-t.^2).*(L^2+t.^2);
f = [0; f]; % Function to be transformed.
a = real(fft(fftshift(f)))/M2; % Coefficients of transform.
a = flipud(a(2:N+1)); % Reorder coefficients.

Z = (L+1i*z(idx))./(L-1i*z(idx));
p = polyval(a,Z); % Polynomial evaluation.
w(idx) = 2*p./(L-1i*z(idx)).^2 + (1/sqrt(pi))./(L-1i*z(idx)); % Evaluate w(z).

% convert the upper half-plane results to the lower half-plane if necesary
w(idx1) = conj(2*exp(-z(idx1).^2) - w(idx1));


%% SQUAREPOISSON Poisson equation in a square domain.
%
%   squarePoisson computes approximations of the Poisson equation in the
%   unit square on a sequence of meshes obtained by uniform refinement. It
%   plots the approximation error (in L2 norm or H1 norm) vs the number of
%   nodes.
%
% See also Poisson, crack, Lshape
%
% Copyright (C)  Long Chen. See COPYRIGHT.txt for details.

close all; clear all;
%% Parameters
maxIt = 4; N = zeros(maxIt,1);
erruIuh = zeros(maxIt,1);

%% Generate an initial mesh
[node,elem] = squaremesh([0 1 0 1], 0.25);
%bdFlag = setboundary(node,elem,'Dirichlet','~(x==0)','Neumann','x==0');
bdFlag = setboundary(node,elem,'Dirichlet','all','Neumann','y==1');
%bdFlag = setboundary(node,elem,'Dirichlet');
for k = 1:3
    [node,elem,bdFlag] = uniformrefine(node,elem,bdFlag);
%     [node,elem,bdFlag] = uniformbisect(node,elem,bdFlag);
end

%% Get the data of the pde
pde = sincosdata;
% pde = mixBCdata;
option.solver = 'mg';

%% Finite Element Method
for k = 1:maxIt
    % solve the equation
    [u,Du,eqn] = PoissonWG(node,elem,pde,bdFlag,option);
    N(k) = size(elem,1);
    % compute error
    uI = zeros(N(k)+size(eqn.edge,1),1);
    uI(1:N(k)) = pde.exactu((node(elem(:,1),:)+node(elem(:,2),:)+node(elem(:,3),:))/3);
    uI(N(k)+1:end) = pde.exactu((node(eqn.edge(:,1),:)+node(eqn.edge(:,2),:))/2);
    erruIuh(k) = sqrt((u-uI)'*eqn.A*(u-uI));
    % refine mesh
   [node,elem,bdFlag] = uniformrefine(node,elem,bdFlag);
%     [node,elem,bdFlag] = uniformbisect(node,elem,bdFlag);
end

%% Plot convergence rates
figure(2);
showrate(N,erruIuh);
%% Error table
% The optimal rate of convergence of the H1-norm (1st order) and L2-norm
% (2nd order) is observed. The 2nd order convergent rate between two
% discrete functions ||DuI-Duh|| is known as superconvergence.


% Excersize 1 - Calculate the equilibrium surface temperature of an icy
% body (e.g. a comet) at a given distance from the Sun.

% This sample program is a script that balances the equation of heat
% transfer on the surface of a ball made of ice, to find an equilibrium
% temperature. This script demonstrates how physical units can be used in
% calculations.

%% Set up the workspace with needed variables
si=setUnits;
% We begin by calling the |setUnits| function in order to get the interface
% structure that holds all predefined units.

LSun=3.8e26*si.joule/si.second;
% Total brightness of the Sun. This is the energy radiated by the Sun every
% second. (Tip: si.s is shorthand for si.second.)

dSun=2.5*1.496e11*si.meter;
% Distance from the Sun to the body whose temperature we must calculate. I
% have chosen a distance of 2.5 astronomical units (Earth-Sun distances)
% that puts our "comet" betwen Mars and Jupiter. (Tip: si.astronomical_unit
% is already defined, and si.AU is even easier. Also, si.m is shorthand for
% si.meter.)

KB=1.3806e-23*si.joule/si.K;
% Boltzmann's constant. (Tip: si.boltzmann is defined.)

stefan=5.67e-8*si.joule/si.m^2/si.s/si.K^4;
% The Stefan-Boltzmann constant. (Tip: Guess what, si.stefan_boltzmann.)

Hice=2.8345e6*si.joule/si.kg;
% Latent heat for sublimation of ice.

A=3.56e12*si.newton/si.m^2; B=6141.667*si.kelvin;
% These parameters are used in an empirical formula for the saturation
% vapor pressure. (Tip: si.N and si.K are shorter.)

avogad=6.022e23*si.mole^(-1);
% Avogadro's number. (Tip: Try si.avogadro.)

mH2O=18*si.g/si.mole;
% The molecular weight of water.

%% Now, Lion-hunt for the temperature of equilibrium
% When we write down the equation:
% radiant energy from the Sun = (radiant + sublimation)energy from the body
% we essentially get an implicit function of temperature vs. distance from
% the Sun. This function however cannot be inverted so we need to hunt for
% the temperature that will balance the equation.

tol=1e-3;
% We'll use this as the relative accuracy.

Tlo=1*si.K; Thi=400*si.K;
% The desired temperature is definitely bracketed by these values.

while (Thi-Tlo)/Thi>tol
    T=(Tlo+Thi)/2;
    fT=(stefan*T^4)+(Hice*sqrt(mH2O/(2*avogad*pi*KB*T))*A*exp(-(B/T)))-...
        (0.25*(LSun/(4*pi*dSun^2)));
    if double(fT)>0
        Thi=T;
    else
        Tlo=T;
    end
end

%% That's it. The desired temperature is
fprintf('The equilibrium temperature is\n')
T
% Try to introduce an easy-to-make-hard-to-detect error in one of the above
% statements, and run the script again. Instead of getting a wrong answer
% you will probably get an informative error message that will help you
% trace the "bug".


function C = xeucn( A, T, shape )
% n-dimensional euclidean distance between each window in A and template T.
%
% Similar to normxcorrn, except at each point (i,j) calculates the
% euclidean distance between the T and the window in A surrounding the
% point, storing the result in C(i,j).
%
% USAGE
%  C = xeucn( A, T, [shape] )
%
% INPUTS
%  A           - first d-dimensional matrix
%  T           - second d-dimensional matrix
%  shape       - ['full'] 'valid', or 'same' (see convn)
%
% OUTPUTS
%  C           - correlation matrix
%
% EXAMPLE
%  T=gaussSmooth(rand(20),2); A=repmat(T,[3 3]);
%  C1=normxcorrn(T,A);  C2=xcorrn(A,T);  C3=xeucn(A,T);
%  figure(1); im(C1);  figure(2); im(C2);  figure(3); im(-C3);
%
% See also XCORRN, CONVNFAST
%
% Piotr's Image&Video Toolbox      Version 2.0
% Copyright 2012 Piotr Dollar.  [pdollar-at-caltech.edu]
% Please email me if you find bugs, or have suggestions or questions!
% Licensed under the Simplified BSD License [see external/bsd.txt]

if( nargin<3 || isempty(shape)); shape='full'; end
nd = ndims(T);
if(nd~=ndims(A)); error('xeucn: T and A must have same ndims'); end;

% flip for conv purposes
if(nd==2); T=rot90(T,2); else for d=1:nd; T=flipdim(T,d); end; end

% The expression for euclidean distance can be rewritten as:
%   D(k,l) = sumj( (Akj - Tlj).^2 )
%          = sumj( Akj.^2 ) + sumj( Tlj.^2 ) - 2*sumj(Akj.*Tlj);
% T is constant.  Hence simply need square of A in each window, as
% well as each dot product between A and T.
Amag = localSum( A.*A, size(T), shape );     % sum of squares per window
Tmag = T.^2;  Tmag = sum( Tmag(:) );         % sum of squares of T
C = Amag + Tmag - 2 * convnFast(A,T,shape);  % distance squared
% C( Amag<.01 ) = Tmag;  % prevent numerical errors
C = real(sqrt(real(C)));


function h=spreadop(f,coef)
%SPREADOP  Spreading operator
%   Usage: h=spreadop(f,c);
%
%   `spreadop(f,c)` applies the operator with spreading function *c* to the
%   input *f*. *c* must be square.
%
%   `spreadop(f,c)` computes the following for *c* of size $L \times L$:
%
%   ..         L-1 L-1
%     h(l+1) = sum sum c(m+1,n+1)*exp(2*pi*i*l*m/L)*f(l-n+1)
%              n=0 m=0
%
%   .. math:: h\left(l+1\right)=\sum_{n=0}^{L-1}\sum_{m=0}^{L-1}c\left(m+1,n+1\right)e^{2{\pi}ilm/L}f\left(l-n+1\right)
%
%   where $l=0,\ldots,L-1$ and $l-n$ is computed modulo *L*.
%
%   The combined symbol of two spreading operators can be found by using
%   `tconv`. Consider two symbols *c1* and *c2* and define *f1* and *f2* by::
%
%     h  = tconv(c1,c2)
%     f1 = spreadop(spreadop(f,c2),c1);
%     f2 = spreadop(f,h);
%
%   then *f1* and *f2* are equal.
%
%   See also:  tconv, spreadfun, spreadinv, spreadadj
%
%   References: feko98

%   AUTHOR: Peter L. Søndergaard
%   TESTING: TEST_SPREAD
%   REFERENCE: REF_SPREADOP

complainif_argnonotinrange(nargin,2,2,mfilename);

if ndims(coef)>2 || size(coef,1)~=size(coef,2)
    error('Input symbol coef must be a square matrix.');
end;

L=size(coef,1);

% Change f to correct shape.
[f,Ls,W,wasrow,remembershape]=comp_sigreshape_pre(f,'DGT',0);

f=postpad(f,L);

h=zeros(L,W);

if issparse(coef) && nnz(coef)<L

    % The symbol is so sparse that the straighforward definition is
    % the fastest way to apply it.

    [mr,nr,cv]=find(coef);
    h=zeros(L,W);

    % We need mr and nr to be zero-indexed
    mr=mr-1;
    nr=nr-1;

    % This is the basic idea of the routine below
    %for ii=1:length(mr)
    %  for l=0:L-1
    %	h(l+1,:)=h(l+1,:)+cv(ii)*exp(-2*pi*i*l*mr(ii)/L)*f(mod(l-nr(ii),L)+1,:);
    %  end;
    %end;

    l=(-2*pi*i*(0:L-1)/L).';
    for ii=1:length(mr)
        bigmod=repmat(exp(l*mr(ii)),1,W);
        h=h+cv(ii)*(bigmod.*circshift(f,nr(ii)));
    end;

else

  % This version only touches coef one column at a time, and it suited
  % if coef is sparse.

  if issparse(coef)
    for n=0:L-1
      % The 'full' below is required for Matlab compatibility, as
      % Matlab refuses to do an ifft of a sparse matrix.
      cf=ifft(full(coef(:,n+1)))*L;
      modind=mod((0:L-1).'-n,L)+1;
      h=h+repmat(cf,1,W).*f(modind,:);
    end;
  else
    for n=0:L-1
      cf=ifft(coef(:,n+1))*L;
      modind=mod((0:L-1).'-n,L)+1;
      h=h+repmat(cf,1,W).*f(modind,:);
    end;
  end;

end;


function colin = points_colin_2d ( p1, p2, p3 )

%*****************************************************************************80
%
%% POINTS_COLIN_2D estimates the colinearity of 3 points in 2D.
%
%  Discussion:
%
%    The estimate of colinearity that is returned is the ratio
%    of the area of the triangle spanned by the points to the area
%    of the equilateral triangle with the same perimeter.
%
%    This estimate is 1 if the points are maximally noncolinear, 0 if the
%    points are exactly colinear, and otherwise is closer to 1 or 0 depending
%    on whether the points are far or close to colinearity.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 October 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real P1(2), P2(2), P3(2), the points.
%
%    Output, real COLIN, the colinearity estimate.
%
  dim_num = 2;

  t(1:dim_num,1:3) = [ p1(1:dim_num); p2(1:dim_num); p3(1:dim_num) ]';

  area_triangle = triangle_area_2d ( t );

  if ( area_triangle == 0.0 )

    colin = 0.0;

  else

    perim = sqrt ( sum ( ( p2(1:dim_num) - p1(1:dim_num) ).^2 ) ) ...
          + sqrt ( sum ( ( p3(1:dim_num) - p2(1:dim_num) ).^2 ) ) ...
          + sqrt ( sum ( ( p1(1:dim_num) - p3(1:dim_num) ).^2 ) );

    side = perim / 3.0;

    area2 = 0.25 * sqrt ( 3.0 ) * side * side;

    colin = abs ( area_triangle ) / area2;

  end

  return
end


function ps = normpdf2( xs, m, C )
% Normal prob. density function (pdf) with arbitrary covariance matrix.
%
% Evaluate the multi-variate density with mean vector m and covariance
% matrix C for the input vector xs.  Assumes that the N datapoints are d
% dimensional.  Then m is dx1 or 1xd, C is dxd, and xs is dxN or NxD where
% N is the number of samples to be evaluated.
%
% USAGE
%  ps = normpdf2( xs, m, C )
%
% INPUTS
%  xs  - points to evaluated (Nxd or dxN)
%  m   - mean vector (dx1 or 1xd)
%  C   - Covariance matrix (dxd)
%
% OUTPUTS
%  ps  - probability density at each x (Nx1)
%
% EXAMPLE
%  ps = normpdf2( randn(10,2), [0 0], eye(2) )
%
% See also NORMPDF
%
% Piotr's Computer Vision Matlab Toolbox      Version 2.30
% Copyright 2014 Piotr Dollar.  [pdollar-at-gmail.com]
% Licensed under the Simplified BSD License [see external/bsd.txt]

% get dimensions of data
d=length(m);
if( size(xs,1)~=d ); xs=xs'; end
N=size(xs,2);

if( d==1 ) % fast special case
  ps = 1/sqrt(2*pi*C) * exp(-(xs-m).*(xs-m)/(2*C))';

elseif( rcond(C)<eps ) % if matrix is badly conditioned
  warning('normpdf2: Covariance matrix close to singular.'); %#ok<WNTAG>
  ps = zeros(N,1);

else % get probabilities
  xs = (xs-m(:)*ones(1,N))';
  denom = (2*pi)^(d/2)*sqrt(abs(det(C)));
  mahal = sum( (xs/C).*xs, 2 );
  numer = exp(-0.5*mahal);
  ps = numer/denom;
end


function divdif_test21 ( )

%*****************************************************************************80
%
%% DIVDIF_TEST21tests DIF_BASIS_DERIV;
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 June 2013
%
%  Author:
%
%    John Burkardt
%
  nd = 3;
  xd = [ -2.0, 1.0, 5.0 ];

  fprintf ( 1, '\n' );
  fprintf ( 1, 'DIVDIF_TEST21\n' );
  fprintf ( 1, '  DIF_BASIS_DERIV computes difference tables for\n' );
  fprintf ( 1, '  the first derivative of each Lagrange basis.\n' );

  [ xdp, ddp ] = dif_basis_deriv ( nd, xd );
%
%  Because the difference tables were shifted to all 0 abscissas,
%  they contain the polynomial coefficients.
%
  r8mat_transpose_print ( nd - 1, nd, ddp, ...
    '  Lagrange basis derivative polynomial coefficients:' );

  c = dif_to_r8poly ( nd - 1, xdp, ddp(1:nd-1,1) );
  r8poly_print ( nd - 1, c, '  P1''=-(2x-6)/21' );

  c = dif_to_r8poly ( nd - 1, xdp, ddp(1:nd-1,2) );
  r8poly_print ( nd - 1, c, '  P2''=-(2x-3)/12' );

  c = dif_to_r8poly ( nd - 1, xdp, ddp(1:nd-1,3) );
  r8poly_print ( nd - 1, c, '  P3''=(2x+1)/28' );

  return
end


function idx = findClosestCentroids(X, centroids)
%FINDCLOSESTCENTROIDS computes the centroid memberships for every example
%   idx = FINDCLOSESTCENTROIDS (X, centroids) returns the closest centroids
%   in idx for a dataset X where each row is a single example. idx = m x 1
%   vector of centroid assignments (i.e. each entry in range [1..K])
%

% Set K
K = size(centroids, 1);

% You need to return the following variables correctly.
idx = zeros(size(X,1), 1);

% ====================== YOUR CODE HERE ======================
% Instructions: Go over every example, find its closest centroid, and store
%               the index inside idx at the appropriate location.
%               Concretely, idx(i) should contain the index of the centroid
%               closest to example i. Hence, it should be a value in the
%               range 1..K
%
% Note: You can use a for-loop over the examples to compute this.
%

% Doing some broadcasting (https://www.gnu.org/software/octave/doc/interpreter/Broadcasting.html)
%warning ("off", "Octave:broadcast");

% calculate all Euclidian distances betweek all X and all centroids (a^2 + b^2 = c^2)
%distances = sqrt(((X(:,1) - centroids(:,1)').^2) + ((X(:,2) - centroids(:,2)').^2));

% get the min value per row and corresponding index (which should be the centroid id)
%[minValues,idx]=min(distances,[],2);

% Restore broadcasting
%warning ("on", "Octave:broadcast");

for i = 1:length(idx)
    distance = zeros(K, 1);
    for j = 1:K
        % TODO(SaveTheRbtz@): Can be vectorized as diff * diff'
        distance(j) = sum(sum((X(i, :) - centroids(j, :)) .^ 2 ));
    endfor
    [value, idx(i)] = min(distance);
endfor

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

end


function [ x, w ] = ccc_nested_rule ( n )

%*****************************************************************************80
%
%% CCC_NESTED_RULE computes the nested Clenshaw Curtis Closed rule.
%
%  Discussion:
%
%    Nested version of Clenshaw Curtis Closed rule on [-1,+1].
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 February 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the rule.
%
%    Output, real X(N), W(N), the points and weights.
%

%
%  Get N equally spaced points that, in general, include [ 0, 1];
%
  if ( n == 1 )
    x = 0.5;
  elseif ( n == 2 )
    x = [ 0.5, 0.0 ];
  elseif ( n == 3 )
    x = [ 0.5, 0.0, 1.0 ];
  else
    x = vdc_sequence ( n - 2 );
    x(4:n) = x(2:n-2);
    x(2) = 0.0;
    x(3) = 1.0;
  end
%
%  Apply the Chebyshev transformation from [0,1] to [-1,+1].
%
  x = cos ( pi * x );
%
%  Get the weights.
%
  x_min = -1.0;
  x_max = +1.0;

  w = nc_compute ( n, x_min, x_max, x );

  return
end


function [ x, y, w ] = legendre_2d_set ( a, b, nx, ny )

%*****************************************************************************80
%
%% LEGENDRE_2D_SET: set a 2D Gauss-Legendre quadrature rule.
%
%  Discussion:
%
%    The integral:
%
%      integral ( a(2) <= y <= b(2) ) ( a(1) <= x <= b(1) ) f(x,y) dx dy
%
%    The quadrature rule:
%
%      sum ( 1 <= i <= n ) w(i) * f ( x(i),y(i) )
%
%    where n = nx * ny, the orders of the rule in the X and Y directions.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 May 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A(2), B(2), the lower and upper integration
%    limits.
%
%    Input, integer NX, NY, the orders in the X and Y directions.
%    NX and NY must be between 1 and 10.
%
%    Output, real X(N), Y(N), the abscissas.
%
%    Output, real W(N), the weights.
%

%
%  Get the rules for [-1,+1].
%
  [ xx, wx ] = legendre_set ( nx );
  [ yy, wy ] = legendre_set ( ny );
%
%  Adjust from [-1,+1] to [A,B].
%
  for i = 1 : nx
    xx(i) = ( ( 1.0 - xx(i) ) * a(1)   ...
            + ( 1.0 + xx(i) ) * b(1) ) ...
            /   2.0;
    wx(i) = wx(i) * ( b(1) - a(1) ) / 2.0;
  end

  for j = 1 : ny
    yy(j) = ( ( 1.0 - yy(j) ) * a(2)   ...
            + ( 1.0 + yy(j) ) * b(2) ) ...
            /   2.0;
    wy(j) = wy(j) * ( b(2) - a(2) ) / 2.0;
  end
%
%  Compute the product rule.
%
  n = nx * ny;
  x = zeros ( n, 1 );
  y = zeros ( n, 1 );
  w = zeros ( n, 1 );

  k = 0;
  for j = 1 : ny
    for i = 1 : nx
      k = k + 1;
      x(k) = xx(i);
      y(k) = yy(j);
      w(k) = wx(i) * wy(j);
    end
  end

  return
end


function W = compute_mesh_weight(vertex,face,type,options)

% compute_mesh_weight - compute a weight matrix
%
%   W = compute_mesh_weight(vertex,face,type,options);
%
%   W is sparse weight matrix and W(i,j)=0 is vertex i and vertex j are not
%   connected in the mesh.
%
%   type is either
%       'combinatorial': W(i,j)=1 is vertex i is conntected to vertex j.
%       'distance': W(i,j) = 1/d_ij^2 where d_ij is distance between vertex
%           i and j.
%       'conformal': W(i,j) = cot(alpha_ij)+cot(beta_ij) where alpha_ij and
%           beta_ij are the adjacent angle to edge (i,j)
%
%   If options.normalize=1, the the rows of W are normalize to sum to 1.
%
%   Copyright (c) 2007 Gabriel Peyre

options.null = 0;
[vertex,face] = check_face_vertex(vertex,face);

nface = size(face,1);
n = max(max(face));

if isfield(options, 'verb')
    verb = options.verb;
else
    verb = n>5000;
end

if nargin<3
    type = 'conformal';
end

switch lower(type)
    case 'combinatorial'
        W = triangulation2adjacency(face);
    case 'distance'
        W = my_euclidean_distance(triangulation2adjacency(face),vertex);
        W(W>0) = 1./W(W>0);
        W = (W+W')/2;
    case 'conformal'
        % conformal laplacian
        W = sparse(n,n);
        ring = compute_vertex_face_ring(face);
        for i = 1:n
            if verb
                progressbar(i,n);
            end
            for b = ring{i}
                % b is a face adjacent to a
                bf = face(:,b);
                % compute complementary vertices
                if bf(1)==i
                    v = bf(2:3);
                elseif bf(2)==i
                    v = bf([1 3]);
                elseif bf(3)==i
                    v = bf(1:2);
                else
                    error('Problem in face ring.');
                end
                j = v(1); k = v(2);
                vi = vertex(:,i);
                vj = vertex(:,j);
                vk = vertex(:,k);
                % angles
                alpha = myangle(vk-vi,vk-vj);
                beta = myangle(vj-vi,vj-vk);
                % add weight
                W(i,j) = W(i,j) + cot( alpha );
                W(i,k) = W(i,k) + cot( beta );
            end
        end
    otherwise
        error('Unknown type.')
end

if isfield(options, 'normalize') && options.normalize==1
    W = diag(sum(W,2).^(-1)) * W;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function beta = myangle(u,v);

du = sqrt( sum(u.^2) );
dv = sqrt( sum(v.^2) );
du = max(du,eps); dv = max(dv,eps);
beta = acos( sum(u.*v) / (du*dv) );

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function W = my_euclidean_distance(A,vertex)

if size(vertex,1)<size(vertex,2)
    vertex = vertex';
end

[i,j,s] = find(sparse(A));
d = sum( (vertex(i,:) - vertex(j,:)).^2, 2);
W = sparse(i,j,d);


function value = atan4 ( y, x )

%*****************************************************************************80
%
%% ATAN4 computes the inverse tangent of the ratio Y / X.
%
%  Discussion:
%
%    ATAN4 returns an angle whose tangent is ( Y / X ), a job which
%    the built in functions ATAN and ATAN2 already do.
%
%    However:
%
%    * ATAN4 always returns a positive angle, between 0 and 2 PI,
%      while ATAN and ATAN2 return angles in the interval [-PI/2,+PI/2]
%      and [-PI,+PI] respectively;
%
%    * ATAN4 accounts for the signs of X and Y, (as does ATAN2).  The ATAN
%     function by contrast always returns an angle in the first or fourth
%     quadrants.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 October 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real Y, X, two quantities which represent the tangent of
%    an angle.  If Y is not zero, then the tangent is (Y/X).
%
%    Output, real ATAN4, an angle between 0 and 2 * PI, whose tangent is
%    (Y/X), and which lies in the appropriate quadrant so that the signs
%    of its cosine and sine match those of X and Y.
%

%
%  Special cases:
%
  if ( x == 0.0E+00 )

    if ( 0.0E+00 < y )
      value = pi / 2.0E+00;
    elseif ( y < 0.0E+00 )
      value = 3.0E+00 * pi / 2.0E+00;
    elseif ( y == 0.0E+00 )
      value = 0.0E+00;
    end

  elseif ( y == 0.0E+00 )

    if ( 0.0E+00 < x )
      value = 0.0E+00;
    elseif ( x < 0.0E+00 )
      value = pi;
    end
%
%  We assume that ATAN2 is correct when both arguments are positive.
%
  else

    abs_y = abs ( y );
    abs_x = abs ( x );

    theta_0 = atan2 ( abs_y, abs_x );

    if ( 0.0E+00 < x & 0.0E+00 < y )
      value = theta_0;
    elseif ( x < 0.0E+00 & 0.0E+00 < y )
      value = pi - theta_0;
    elseif ( x < 0.0E+00 & y < 0.0E+00 )
      value = pi + theta_0;
    elseif ( 0.0E+00 < x & y < 0.0E+00 )
      value = 2.0E+00 * pi - theta_0;
    end

  end

  return
end


function [A, names] = mk_adj_mat(connections, names, topological)
% MK_ADJ_MAT Make a directed adjacency matrix from a list of connections between named nodes.
%
% A = mk_adj_mat(connections, name)
% This is best explaine by an example:
%   names = {'WetGrass', 'Sprinkler', 'Cloudy', 'Rain'};
%   connections = {'Cloudy', 'Sprinkler'; 'Cloudy', 'Rain'; 'Sprinkler', 'WetGrass'; 'Rain', 'WetGrass'};
% adds the arcs C -> S, C -> R, S -> W, R -> W. Node 1 is W, 2 is S, 3 is C, 4 is R.
%
% [A, names] = mk_adj_mat(connections, name, 1)
% The last argument of 1 indicates that we should topologically sort the nodes (parents before children).
% In the example, the numbering becomes: node 1 is C, 2 is R, 3 is S, 4 is W
% and the return value of names gets permuted to {'Cloudy', 'Rain', 'Sprinkler', 'WetGrass'}.
% Note that topological sorting the graph is only possible if it has no directed cycles.

if nargin < 3, topological = 0; end

n=length(names);
A=zeros(n);
[nr nc] = size(connections);
for r=1:nr
  from = strmatch(connections{r,1}, names, 'exact');
  assert(~isempty(from));
  to = strmatch(connections{r,2}, names, 'exact');
  assert(~isempty(to));
  %fprintf(1, 'from %s %d to %s %d\n', connections{r,1}, from, connections{r,2}, to);
  A(from,to) = 1;
end

if topological
  order = topological_sort(A);
  A = A(order, order);
  names = names(order);
end


function [g]=gsp_design_expwin(G, bmax, a)
%GSP_DESIGN_EXPWIN create an expwin window of lenth N with parameter a
%   Usage: g = gsp_design_expwin(G);
%          g = gsp_design_expwin(G, bmax);
%          g = gsp_design_expwin(G, bmax, a);
%
%   Input parameters:
%       G       : Graph structure
%       bmax    : Maximum relative band (default 0.2)
%       a       : Slope parameter (default 1).
%
%   Output parameters
%       g       : filter
%
%   This function design the following filter:
%
%   .. g(x) = s( (1-x) / bmax /lmax )
%
%   .. math:: g(x) = s\left(\frac{1-x}{\lambda_{\text{max}} b_{\text{max}} }\right)
%
%   where  $s(x)$ is the step function
%
%   ..          /   0                                      if x < -1
%   ..  s(x) = | exp(-a/x) / ( exp(-a/x) + exp(-a/(1-x)) ) if x in [-1, 1]
%   ..          \   1                                      if x > 1
%
%   .. math:: s(x)=\begin{cases} 0 & \mbox{if }x<-1 \\ \frac{e^{-\frac{a}{x}}}{e^{-\frac{a}{x}}+e^{-\frac{a}{1-x}}} & \mbox{if }x\in[-1,1]\\ 1 & \mbox{if }x>1 \end{cases}
%
%   It uses a clever exponential construction to obtain an infinitely
%   differentiable function that is band limited!
%
%   This function will compute the maximum eigenvalue of the laplacian. To
%   be more efficient, you can precompute it using::
%
%       G = gsp_estimate_lmax(G);
%
%   Example:::
%
%         Nf = 4;
%         G = gsp_sensor(100);
%         G = gsp_estimate_lmax(G);
%         g = gsp_design_expwin(G);
%         gsp_plot_filter(G,g);
%

% Author: Nathanael Perraudin
% Date  : 18 December 2014

if nargin<3
    a = 1;
end

if nargin<2
    bmax = 0.2;
end

if numel(bmax)>1
    g = cell(numel(bmax),1);
    for ii = 1:numel(bmax);
        g{ii} = gsp_design_expwin(G,bmax(ii),a);
    end
    return
end

if isstruct(G)
    if ~isfield(G,'lmax')
%         if param.verbose
            fprintf('GSP_DESIGN_EXPWIN has to compute lmax \n')
%         end
        G = gsp_estimate_lmax(G);
    end
   lmax = G.lmax;
else
   lmax = G;
end

g = @(x) gsp_smooth_downstep(x/bmax/lmax, a , 1);

end


function K = intmat(N, varargin)
%INTMAT   Spectral integration matrix.
%   K = INTMAT(N) returns the N x N integration matrix associated with the
%   Chebyshev spectral collocation method at second-kind Chebyshev points.
%
%   K = INTMAT(N, P) returns the N x N integration matrix of order P.
%
%   K = INTMAT(N, P, DOM) scales the integration matrix K to the domain
%   DOM. DOM should be a 1x2 vector.
%
%   K = INTMAT([M N]) returns the M x N first-order rectangular integration
%   matrix which maps from an N-point Chebyshev grid of the second kind to an
%   M-point Chebyshev grid of the same kind.
%
%   K = INTMAT([M N], P) returns an M x N rectangular integration matrix of
%   order P which maps from an N-point to an M-point Chebyshev grid, both of
%   second kind.
%
%   K = INTMAT([M N], P, DOM) returns the same K but scaled to the domain DOM.
%
% See also CUMSUMMAT, DIFFMAT, DIFFROW, INTROW.

% This code has been written for Aurentz and Trefethen,
% "Block operators and spectral discretizations", and is not
% yet fully compliant with standard Chebfun coding practices.

% Copyright 2015 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

% Parse inputs
[m, n, p, dom] = parseInputs(N, varargin{:});

% Build Lagrange basis
K = chebfun(eye(n),dom);

% Integrate p times
K = cumsum(K,p);

% Evaluate at grid of size m
K = feval(K,chebpts(m,dom));

end

function [m, n, p, dom] = parseInputs(N, varargin)
% Parse the inputs to INTMAT.

p = 1;
dom = [-1 1];

if ( isscalar(N) )
    n = N;
    m = n;
else
    m = N(1);
    n = N(2);
end

for j = 1:numel(varargin)
    v = varargin{j};
    if ( isnumeric(v) )
        if ( isscalar(v) )
            p = v;
        else
            dom = v;
        end
    else
        error('CHEBFUN:intmat:unknown', ...
            'Unknown input of type %s.', class(v));
    end
end

end


function [ Nreg ] = eigRegularizer( N, k )

% -----------------------------------------------------------------
% matrizer regularization by checking eigenvalues
% -----------------------------------------------------------------
%
% N:   input square matrix
% k:   required condition number

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

[V, D] = eig(N); 					 % eigenvectors and eigenvalues
e = diag(D);                         % eigenvalues (ascending order)

% k = 1e6;                           % condition number
% pos = find( e < (e(end)/k) );
% e(pos) = e(end)/k;                 % regularized eigenvalues
% Nreg = V*diag(e)*V';               % regularized matrix

pos = e < (max(e) / k);
e(pos) = max(e) / k;                 % regularized eigenvalues
Nreg = V * diag(e) * V';             % regularized matrix
%Nreg = real(V*diag(e)*V');          % regularized matrix

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

% figure; imagesc(N); colorbar
% figure; imagesc(Nreg); colorbar
% figure; imagesc(N-Nreg); colorbar


% P. Perona and W. T. Freeman, "A factorization approach to grouping",
% In H. Burkardt and B. Neumann, editors, Proc ECCV, pages 655-670, 1998.

% Yair Weiss, "Segmentation Using Eigenvectors: A Unifying View", UC
% Berkeley.

% Asad Ali
% GIK Institute of Engineering Sciences & Technology, Pakistan
% Email: asad_82@yahoo.com

% CONCEPT: Clustering algorithm based on thresholding of the first eigenvector of
% the affinity matrix
clear all;
close all;

THRESHOLD = 0.28; % change the threshold depending on the data.
% generate the data
data = GenerateData(1);
% break the block matrix structure
data = data(3:14,:);
figure,plot(data(:,1), data(:,2),'r+'),title('Original Data Points'); grid on;shg

affinity = CalculateAffinity(data);
figure,imshow(affinity,[]),title('Affinity Matrix')

[eigVectors,eigValues] = eig(affinity);

% first eigenvector is the one which has the highest eigenvalue
sz = size(eigVectors);
firstEig = eigVectors(:,sz(1,2));

% plot the eigen vector corresponding to the largest eigen value
[xx1,yy1,val1] = find(firstEig > THRESHOLD);
[xx2,yy2,val2] = find(firstEig <= THRESHOLD);
figure,
hold on;
plot(data(xx1,1),data(xx1,2),'g*')
plot(data(xx2,1),data(xx2,2),'b*')
hold off;
title('Clustering Results after thresholding the First Eigenvector');
grid on;shg


function volume = ball01_volume ( )

%*****************************************************************************80
%
%% BALL01_VOLUME returns the volume of the unit ball.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 January 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, real VOLUME, the volume of the unit ball.
%
  r = 1.0;
  volume = 4.0 * pi * r ^ 3 / 3.0;

  return
end


function [dStates, A, B, Positions] = Derive_EoM()

%This function derives the equations of motion for a tractor trailer truck.

%The outputs assume that the states and inputs are being listed in the
%order in which they are defined

%% Parameters

Lt = sym('Lt');
Lc = sym('Lc');

%% Inputs

v = sym('v');
psi = sym('psi');

%% States

x = sym('x');
y = sym('y');
th = sym('th');
phi = sym('phi');

%% State Derivatives

Dx = sym('Dx');
Dy = sym('Dy');
Dth = sym('Dth');
Dphi = sym('Dphi');

%% Equations of motion

%Unit Vectors
    i = [1;0];
    j = [0;1];

    An = cos(th)*i + sin(th)*j;
    At = -sin(th)*i + cos(th)*j;
    Bn = cos(phi)*An + sin(phi)*At;
    Bt = -sin(phi)*An + cos(phi)*At;
    Cn = cos(psi)*Bn + sin(psi)*Bt;
    Ct = -sin(psi)*Bn + cos(psi)*Bt;

%Derivatives of Unit Vectors
    dAn = Dth*At;
    dAt = -Dth*An;
    dBn = (Dphi + Dth)*Bt;
    dBt = -(Dphi + Dth)*Bn;

%Position Vectors
    Pa = x*i + y*j;
    Pb = Pa + Lt*At;
    Pc = Pb + Lc*Bt;
    Positions = [Pa,Pb,Pc];

%Derivatives of Position Vectors
    dPa = Dx*i + Dy*j;
    dPb = dPa + Lt*dAt;
    dPc = dPb + Lc*dBt;

%Trailer Back Wheel Constraint
    RHS_1 = 0;
    LHS_1 = Dot(dPa,An);

%Cab Back Wheel Constraint
    RHS_2 = 0;
    LHS_2 = Dot(dPb,Bn);

%Cab Front Wheel Constraints
    RHS_3 = dPc(1);
    LHS_3 = v*Ct(1);

    RHS_4 = dPc(2);
    LHS_4 = v*Ct(2);

%Solve for State Derivatives
    Solution = solve(...
        RHS_1-LHS_1, RHS_2-LHS_2, RHS_3-LHS_3, RHS_4-LHS_4,...
        Dx, Dy, Dth, Dphi);

%Express as Vector [Dx, Dy, Dth, Dphi]

    dStates = [...
        Solution.Dx;
        Solution.Dy;
        Solution.Dth;
        Solution.Dphi];

%% Jacobian Calculations

    J_x = diff(dStates,x);
    J_y = diff(dStates,y);
    J_th = diff(dStates,th);
    J_phi = diff(dStates,phi);
    J_v = diff(dStates,v);
    J_psi = diff(dStates,psi);

    A = [J_x, J_y, J_th, J_phi];
    B = [J_v, J_psi];

end


function [inv_map,bi_inv_map,logdet,invA] = invchol2(A)
% INVCHOL2
% Does a Cholesky decomposition on A and returns logdet, inverse and
% two function handles that respectively map X to A\X and A\X/A.
%

if nargin==0
    test_this();
    return;
end

if isreal(A)

    R = chol(A); %R'*R = A
    inv_map = @(X) R\(R'\X);

    % inv(A)*X*inv(A)
    bi_inv_map = @(X) (inv_map(X)/R)/(R');

    if nargout>2
        logdet = 2*sum(log(diag(R)));
        if nargout>3
            invA = inv_map(eye(size(A)));
        end
    end
else
    inv_map = @(X) A\X;

    % inv(A)*X*inv(A)
    bi_inv_map = @(X) (A\X)/A;

    if nargout>2
        logdet = log(det(A));
        if nargout>3
            invA = inv_map(eye(size(A)));
        end
    end
end

function test_this()
dim = 3;
r = randn(dim,2*dim);
A = r*r';
[inv_map,bi_inv_map,logdet,iA] = invchol2(A);
[logdet,log(det(A))]
X = randn(dim,3);
Y1 = A\X,
Y2 = inv_map(X)

Z1 = (A\X)/A
Z2 = bi_inv_map(X)

iA,
inv(A)


% TERNCOORDS calculate rectangular coordinates of fractions on a ternary plot
%   [X, Y] = TERNCOORDS(FA, FB) returns the rectangular X and Y coordinates
%   for the point with a fraction defined by FA and FB.  It is assumed that
%   FA and FB are sensible fractions.
%
%   [X, Y] = TERNCOORDS(FA, FB, FC) returns the same.  FC is assumed to be
%   the remainder when subtracting FA and FB from 1.

% Author: Carl Sandrock 20050211

% Modifications

% Modifiers

function [x, y] = terncoords(fA, fB, fC)
if nargin < 3
    fC = 1 - (fA + fB);
end

y = fB*sin(deg2rad(60));
x = fA + y*cot(deg2rad(60));


function [t] = LineSearchGoldenSection(func,LB,UB,EPSILON)
%
% Golden Section search for an approximate minimum of unimodal
%         function f(t) using only function evaluations
%
% length of location interval is reduced by 0.318 each iteration
%

narginchk(3,4);
if nargin == 3
    EPSILON = max(abs(UB) + abs(LB),2)*0.5e-4;
end
GR = (sqrt(5)-1)/2; % 0.618

l = UB - (UB-LB)*GR;
r = LB + (UB-LB)*GR;
fl = func(l);
fr = func(r);
while UB - LB >= EPSILON
    if fl < fr
        UB = r;
        r = l;
        fr = fl;
        l = UB - (UB-LB)*GR;
        fl = func(l);
    else
        LB = l;
        l = r;
        fl = fr;
        r = LB + (UB-LB)*GR;
        fr = func(r);
    end
end

t = (UB+LB)/2;

end

github-repos/MATLAB/yuanhao-cui-Must-Reading-on-ISAC/Must-Reading-on-ISAC-34cd6615c52ebca121428a979e756c608b195040/Codes/Fan2018TSP/Codes for DFRC Waveform Design/Waveform Design With Given Radar Beampatterns/LineSearchGoldenSection.m


function value = lrline ( xu, yu, xv1, yv1, xv2, yv2, dv )

%*****************************************************************************80
%
%% LRLINE determines if a point is left of, right or, or on a directed line.
%
%  Discussion:
%
%    The directed line is parallel to, and at a signed distance DV from
%    a directed base line from (XV1,YV1) to (XV2,YV2).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 February 2005
%
%  Author:
%
%    Original FORTRAN77 version by Barry Joe,
%    MATLAB version by John Burkardt
%
%  Reference:
%
%    Barry Joe,
%    GEOMPACK - a software package for the generation of meshes
%    using geometric algorithms,
%    Advances in Engineering Software,
%    Volume 13, pages 325-331, 1991.
%
%  Parameters:
%
%    Input, real XU, YU, the coordinates of the point whose
%    position relative to the directed line is to be determined.
%
%    Input, real XV1, YV1, XV2, YV2, the coordinates of two points
%    that determine the directed base line.
%
%    Input, real DV, the signed distance of the directed line
%    from the directed base line through the points (XV1,YV1) and (XV2,YV2).
%    DV is positive for a line to the left of the base line.
%
%    Output, integer VALUE, the result:
%    +1, the point is to the right of the directed line;
%     0, the point is on the directed line;
%    -1, the point is to the left of the directed line.
%
  tol = 100.0 * eps;

  dx = xv2 - xv1;
  dy = yv2 - yv1;
  dxu = xu - xv1;
  dyu = yu - yv1;

  tolabs = tol * max ( abs ( dx ), ...
                 max ( abs ( dy ), ...
                 max ( abs ( dxu ), ...
                 max ( abs ( dyu ), abs ( dv ) ) ) ) );

  t = dy * dxu - dx * dyu + dv * sqrt ( dx * dx + dy * dy );

  if ( tolabs < t )
    value = 1;
  elseif ( -tolabs <= t )
    value = 0;
  else
    value = -1;
  end

  return
end


function variance = uniform_discrete_variance ( a, b )

%*****************************************************************************80
%
%% UNIFORM_DISCRETE_VARIANCE returns the variance of the Uniform discrete PDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer A, B, the parameters of the PDF.
%    A <= B.
%
%    Output, real VARIANCE, the variance of the PDF.
%
  variance = ( ( b + 1 - a )^2 - 1 ) / 12.0;

  return
end


function integral = circle01_monomial_integral ( e )

%*****************************************************************************80
%
%% CIRCLE01_MONOMIAL_INTEGRAL: integrals on circumference of unit circle in 2D.
%
%  Discussion:
%
%    The integration region is
%
%      X^2 + Y^2 = 1.
%
%    The monomial is F(X,Y) = X^E(1) * Y^E(2).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 January 2014
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Philip Davis, Philip Rabinowitz,
%    Methods of Numerical Integration,
%    Second Edition,
%    Academic Press, 1984, page 263.
%
%  Parameters:
%
%    Input, integer E(2), the exponents of X and Y in the
%    monomial.  Each exponent must be nonnegative.
%
%    Output, real INTEGRAL, the integral.
%
  if ( any ( e(1:2) < 0 ) )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'CIRCLE01_MONOMIAL_INTEGRAL - Fatal error!\n' );
    fprintf ( 1, '  All exponents must be nonnegative.\n' );
    error ( 'CIRCLE01_MONOMIAL_INTEGRAL - Fatal error!' );
  end

  if ( any ( mod ( e(1:2), 2 ) == 1 ) )

    integral = 0.0;

  else

    integral = 2.0;

    for i = 1 : 2
      integral = integral * gamma ( 0.5 * ( e(i) + 1 ) );
    end

    integral = integral / gamma ( 0.5 * sum ( e(1:2) + 1 ) );

  end

  return
end