classdef ChiSquareD
%%CHISQUARED Functions to handle the central or non-central chi-squared
%            distributions. These distributions arise when summing the
%            squares of independent normal random variables. The result is
%            central if the mean of the normal random variables was zero.
%Implemented methods are: mean, var, PDF, CDF, invCDF (only for the central
%                         chi squared distribution), rand, (only for the
%                         central chi squared distribution) entropy
%
%DEPENDENCIES: GammaD.m
%
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

methods(Static)

function val=mean(nu,lambda)
%%MEAN Obtain the mean of chi squared probability distribution.
%
%INPUTS: nu The number of degrees of freedom of the chi-squared
%           distribution. Note that nu>0.
%    lambda The non-centrality parameter of the distribution. In the
%           central chi-squared distribution, this is zero.
%
%OUTPUTS: val The mean of the chi squared distribution under consideration.
%
%The noncentral chi-squared distribution is descirbed in [1].
%
%REFERENCES:
%[1] Weisstein, Eric W. "Noncentral Chi-Squared Distribution." From
%    MathWorld--A Wolfram Web Resource.
%    http://mathworld.wolfram.com/NoncentralChi-SquaredDistribution.html
%
%October 2013 David F. Crouse, Naval Research Laboratory, Washington D.C.

    if(nargin<2||isempty(lambda))
        lambda=0;
    end

    val=nu+lambda;
end

function val=var(nu,lambda)
%%VAR Obtain the variance of chi squared probability distribution for the
%     given number of degrees of freedom.
%
%INPUTS: nu The number of degrees of freedom of the chi-square
%           distribution. Note that nu>0.
%    lambda The non-centrality parameter of the distribution. In the
%           central chi-squared distribution, this is zero.
%
%OUTPUTS: val The variance of the chi squared distribution under
%             consideration.
%
%The noncentral chi-squared distribution is descirbed in [1].
%
%REFERENCES:
%[1] Weisstein, Eric W. "Noncentral Chi-Squared Distribution." From
%    MathWorld--A Wolfram Web Resource.
%    http://mathworld.wolfram.com/NoncentralChi-SquaredDistribution.html
%
%October 2013 David F. Crouse, Naval Research Laboratory, Washington D.C.

    if(nargin<2||isempty(lambda))
        lambda=0;
    end

    val=2*nu+4*lambda;
end

function val=PDF(x,nu,lambda)
%%PDF Evaluate the chi squared probability distribution function (PDF) at
%     the desired points.
%
%INPUTS: x The point(s) at which the chi-squared PDF is to be evaluated.
%          Note that x>=0 for nonzero probabilities.
%       nu The number of degrees of freedom of the chi-square distribution.
%          Note that nu>0.
%   lambda The non-centrality parameter of the distribution. In the central
%          chi-squared distribution, this is zero.
%
%OUTPUTS: val The value(s) of the chi squared PDF evaluated at x.
%
%The noncentral chi-squared distribution is descirbed in [1].
%
%When lambda is very small but nonzero, the PDF function could run into
%problems due to the logarithm of lambda. The logarithms were used instead
%of a simpler form to lessen the numerical instability. If an invalid value
%for the noncentral distribution is obtained, it is assumed that it is due
%to using an extremely small nonzero value of lambda, and the result is
%approximated using lambda=0.
%
%REFERENCES:
%[1] Weisstein, Eric W. "Noncentral Chi-Squared Distribution." From
%    MathWorld--A Wolfram Web Resource.
%    http://mathworld.wolfram.com/NoncentralChi-SquaredDistribution.html
%
%September 2013 David F. Crouse, Naval Research Laboratory, Washington D.C.

    if(nargin<3||isempty(lambda))
        lambda=0;
    end

    if(lambda==0)
        val=(1/(2^(nu/2)*gamma(nu/2))).*x.^((nu-2)/2).*exp(-x/2);
    else
        val=0.5*exp(-(x+lambda)/2+(nu/4-0.5)*(log(x)-log(lambda))).*besseli(nu/2-1,sqrt(lambda*x));

        if(~isfinite(val))
            val=(1/(2^(nu/2)*gamma(nu/2))).*x.^((nu-2)/2).*exp(-x/2);
        end
    end

    val(x<0)=0;
end

function prob=CDF(x,nu,lambda)
%%CDF Evaluate the cumulative distribution function (CDF) of the central or
%     noncentral chi-squared distribution at desired points.
%
%INPUTS: x The point(s) at which the chi-squared CDF is to be evaluated.
%          Note that x>0 for nonzero values.
%       nu The number of degrees of freedom of the chi-square distribution.
%          Note that nu>0. When lambda is not zero, the CDF function is
%          numerically stabler when nu is an integer.
%   lambda The non-centrality parameter of the distribution. In the central
%          chi-squared distribution, this is zero.
%
%OUTPUTS: prob The value(s) of the CDF of the chi-squared distribution with
%              nu degrees of freedom and noncentrality parameter lambda
%              evaluated at x.
%
%The CDF of the central chi squared function with nu degrees of freedom
%evaluated at x is just a special case of the incomplete gamma function, as
%described at [1]. The incomplete gamma function is built into Matlab
%without the use of any toolboxes. When the noncentrality parameter is
%nonzero, the CDF is evaluated in terms of the equivalent noncentral gamma
%distribution. The noncentral gamma algorithm is documented further in
%GammaD.m.
%
%REFERENCES:
%[1] Weisstein, Eric W. "Noncentral Chi-Squared Distribution." From
%    MathWorld--A Wolfram Web Resource.
%    http://mathworld.wolfram.com/NoncentralChi-SquaredDistribution.html
%
%September 2013 David F. Crouse, Naval Research Laboratory, Washington D.C.
%Updated to use the noncentral gamma distribution's function
%December 2014 David A. Karnick, Naval Research Laboratory, Washington D.C.

    if(nargin<3||isempty(lambda))
        lambda=0;
    end

    if(lambda==0)
        prob=gammainc(x/2,nu/2);
    else
        prob=GammaD.CDF(x,nu/2,2,lambda);
    end
    prob(x<=0)=0;
end

function val=invCDF(prob,nu)
%%INVCDF Evaluate the inverse of the cumulative distribution function (CDF)
%        of the central chi squared distribution. This is only implemented
%        for the central chi-squared distribution.
%
%INPUTS: prob The probability or probabilities (0<=prob<=1) at which the
%             argument of the CDF is desired.
%          nu The number of degrees of freedom of the chi-squared
%             distribution. Note that nu>0.
%
%OUTPUTS: val The argument(s) of the CDF that would give the probability or
%             probabilities in prob.
%
%The CDF of the chi squared function with nu degrees of freedom evaluated
%at x is just a special case of the incomplete gamma function, as described
%on Mathworld at [1]. The inverse incomplete gamma function is built into
%Matlab without the use of any toolboxes and thus is called here.
%
%REFERENCES:
%[1] Weisstein, Eric W. "Noncentral Chi-Squared Distribution." From
%    MathWorld--A Wolfram Web Resource.
%    http://mathworld.wolfram.com/NoncentralChi-SquaredDistribution.html
%
%September 2013 David F. Crouse, Naval Research Laboratory, Washington D.C.

    val=2*gammaincinv(prob,nu/2);
end

function vals=rand(N,nu,lambda)
%%RAND Generate chi-squared distributed random variables with the given
%      parameters.
%
%INPUTS: N If N is a scalar, then rand returns an NXN matrix of random
%          variables. If N=[M,N1] is a two-element row vector, then rand
%          returns an MXN1 matrix of random variables.
%       nu The number of degrees of freedom of the chi-squared
%          distribution. Note that nu>0. If lambda is not zero, nu >=1.
%   lambda The non-centrality parameter of the distribution. In the central
%          chi-squared distribution, this is zero. If this parameter is
%          omitted or an empty matrix is passed, then 0 is used.
%
%OUTPUTS: vals A matrix whose dimensions are determined by N of the
%              generated chi-squared random variables.
%
%The algorithm for the central chi squared distribution is an
%implementation of the inverse transform algorithm of Chapter 5.1 of [1].
%When the noncentral distribution is used, the random variables are
%generated by summing the squares of normally distributed random variables.
%
%A non-central chi squared distribution is the sum of a chi-squared
%distribution with nu-1 degrees of freedom plus the squared of a normal
%distribution with mean sqrt(lambda) and standard deviation 1. This is how
%the noncentral distribution is generated and why it is required that
%nu>=1.
%
%REFERENCES:
%[1] S. M. Ross, Simulation, Ed. 4, Amsterdam: Elsevier, 2006.
%
%September 2013 David F. Crouse, Naval Research Laboratory, Washington D.C.

    if(nargin<3||isempty(lambda))
        lambda=0;
    end

    if(isscalar(N))
        dims=[N, N];
    else
        dims=N;
    end

    if(lambda==0)
        U=rand(dims);
        vals=ChiSquareD.invCDF(U,nu);
    else
        U=rand(dims);
        vals=ChiSquareD.invCDF(U,nu-1)+(sqrt(lambda)+randn(N)).^2;
    end
end

function entropyVal=entropy(nu)
%%ENTROPY Obtain the differential entropy of the central chi squared
%         distribution given in nats. The differential entropy of a
%         continuous distribution is entropy=-int_x p(x)*log(p(x)) dx where
%         the integral is over all values of x. Units of nats mean that the
%         natural logarithm is used in the definition. Unlike the Shannon
%         entropy for discrete variables, the differential entropy of
%         continuous variables can be both positive and negative.
%
%INPUTS: nu The number of degrees of freedom of the chi-squared
%           distribution. Note that nu>0
%
%OUTPUTS: entropyVal The value of the differential entropy in nats.
%
%Differential entropy is defined in Chapter 8 of [1].
%
%REFERENCES:
%[1] T. M. Cover and J. A. Thomas, Elements of Information Theory, 2nd ed.
%    Hoboken, NJ: Wiley-Interscience, 2006.
%
%April 2018 David F. Crouse, Naval Research Laboratory, Washington D.C.

    entropyVal=nu/2+log(2)+gammaln(nu/2)+(1-nu/2)*psi(nu/2);
end
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 varargout = createRhombododecahedron()
%CREATERHOMBODODECAHEDRON Create a 3D mesh representing a rhombododecahedron.
%
%   [V, E, F] = createRhombododecahedron
%   V is a 14-by-3 array with vertex coordinate,
%   E is a 12-by-2 array containing indices of neighbour vertices,
%   F is a 8-by-3 array containing vertices array of each face.
%
%   [V, F] = createRhombododecahedron;
%   Returns only the vertices and the face vertex indices.
%
%   MESH = createRhombododecahedron;
%   Returns the data as a mesh structure, with fields 'vertices', 'edges'
%   and 'faces'.
%
%   Example
%   [v, e, f] = createRhombododecahedron;
%   drawMesh(v, f);
%
%
%   See also
%   meshes3d, drawMesh

%   ---------
%   author : David Legland
%   e-mail: david.legland@inra.fr
%   INRA - TPV URPOI - BIA IMASTE
%   created the 10/02/2005.
%

%   HISTORY
%   04/01/2007: remove unused variables

nodes = [0 0 2;...
    1 -1 1;1 1 1;-1 1 1;-1 -1 1;...
    2 0 0;0 2 0;-2 0 0;0 -2 0;...
    1 -1 -1;1 1 -1;-1 1 -1;-1 -1 -1;...
    0 0 -2];

edges = [...
    1 2;1 3;1 4;1 5;...
    2 6;2 9;3 6;3 7;4 7;4 8;5 8;5 9;...
    6 10;6 11;7 11;7 12;8 12;8 13;9 10;9 13; ...
    10 14;11 14;12 14;13 14];

faces = [...
    1 2 6 3;...
    1 3 7 4;...
    1 4 8 5;...
    1 5 9 2;...
    2 9 10 6;...
    3 6 11 7;...
    4 7 12 8;...
    5 8 13 9;...
    6 10 14 11;...
    7 11 14 12;...
    8 12 14 13;...
    9 13 14 10];

% format output
varargout = formatMeshOutput(nargout, nodes, edges, faces);


function a = ris ( n )

%*****************************************************************************80
%
%% RIS returns the RIS matrix.
%
%  Discussion:
%
%    This is sometimes called the "dingdong" matrix, invented by F N Ris.
%
%  Formula:
%
%    A(I,J) = 1 / ( 3 + 2 * N - 2 * I - 2 * J )
%
%  Example:
%
%    N = 5
%
%    1/9  1/7  1/5  1/3   1
%    1/7  1/5  1/3   1   -1
%    1/5  1/3   1   -1  -1/3
%    1/3   1   -1  -1/3 -1/5
%     1   -1  -1/3 -1/5 -1/7
%
%  Properties:
%
%    A is a Cauchy matrix.
%
%    A is a Hankel matrix: constant along anti-diagonals.
%
%    A is symmetric: A' = A.
%
%    Because A is symmetric, it is normal.
%
%    Because A is normal, it is diagonalizable.
%
%    The eigenvalues of A cluster around PI/2 and -PI/2.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    John Nash,
%    Compact Numerical Methods for Computers: Linear Algebra and
%    Function Minimisation,
%    John Wiley, 1979, page 210.
%
%  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
      a(i,j) = 1.0 / ( 3 + 2 * n - 2 * i - 2 * j );
    end
  end

  return
end


function [ c_est, r_est, c_err, r_err ] = sphere_random_centralize ( ...
  m, n, c, r )

%*****************************************************************************80
%
%% SPHERE_RANDOM_CENTRALIZE estimates the center of a sphere.
%
%  Discussion:
%
%    We generate N points on the M dimensional sphere of center C and radius R.
%    We seek to estimate the values of C and R.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 April 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the spatial dimension.
%
%    Input, integer N, the number of random points to generate.
%
%    Input, real C(M,1), the center.
%
%    Input, real R, the radius.
%
%    Output, real C_EST(M,1), R_EST, the estimated center and radius.
%
%    Output, real C_ERR, R_ERR, the errors in the estimates.
%
  c = c(:);
  x = sphere_surface_sample ( m, n, c, r );

  c_est = sum ( x, 2 ) / n;
  c_err = norm ( c - c_est );

  r_mat = x - repmat ( c_est, 1, n );
  r_mat = r_mat.^2;
  r_mat = sum ( r_mat, 1 );
  r_mat = sqrt ( r_mat );
  r_est = sum ( r_mat ) / n;
  r_err = abs ( r - r_est );

  return
end


% Create Noise Signal and embed sine wave in it at a random location
npts=5000; % # points in signal
srate=1000; % sample rate (Hz)
dur=npts/srate; % signal duration in sec
amp_n=3.5; % noise amplitude
amp_t=1.0; % sine wave amplitude
freq=100; % sine wave frequency
sinepts=400; % # points in sine wave

t=[0:npts-1]/srate; % signal time base
sine_t=[0:sinepts-1]/srate; % sine wave time base
noise=(rand(1,npts)-.5)*amp_n; %noise signal
sinewave=amp_t*(sin(2*pi*freq*sine_t)); % sine wave
% random location of sinewave
sinepos=floor(rand(1,1)*(npts-sinepts))+1;
signal = noise; % make signal equal to noise
endsine = sinepos + sinepts-1; %calc index end of sine wave
% add sinewave to signal starting at index sinepos
signal(sinepos:endsine) = signal(sinepos:endsine) + sinewave;

% Plot signal
subplot(5,1,1)
plot(t,signal);
hold on
%plot red dot on location of sine wave start
plot(sinepos/srate,0,'.r');
hold off
title('Original Signal');

% Step 1: Filter signal
hbandwidth=5; %half bandwidth
nyquist=srate/2;
ntaps=200;
hpf=(freq-hbandwidth)/nyquist;
lpf=(freq+hbandwidth)/nyquist;
[b,a]=fir1(ntaps, [hpf lpf]); %calc filter coefficients
signal_f=filter(b,a,signal); %filter signal
subplot(5,1,2)
plot(t,signal_f); %plot filtered signal
hold on
%plot red dot on location of sine wave
plot(sinepos/srate,0,'.r');
hold off
title('Step 1. Filter Signal');

signal_r=abs(signal_f); %abs value of filtered signal
subplot(5,1,3)
plot(t,signal_r); %plot filtered signal
hold on
%plot red dot on location of sine wave
plot(sinepos/srate,0,'.r');
hold off
title('Step 2. Rectify Signal');

% Step 3: Low-pass filter rectified signal
lpf=10/nyquist; % low-pass filter corner frequency
npoles=6;
[b,a]=butter(npoles, lpf); % Butterworth filter coeff
signal_env=filter(b,a,signal_r); %Filter signal
subplot(5,1,4)
plot(t,signal_env); %plot filtered signal
hold on
%plot red dot on location of sine wave
plot(sinepos/srate,0,'.r');
hold off
title('Step 3. Envelope Signal');

% Step 4: Threshold signal
threshold=amp_t/2;
gated=(signal_env>threshold);
subplot(5,1,5)
plot(t,signal_env); %plot filtered signal
hold on
%plot red dot on location of sine wave
plot(sinepos/srate,0,'.r');
plot(t, gated, 'r'); % plot threshold signal
hold off
title('Step 4. Threshold Signal');
xlabel('Time (s)');

d_gated=diff(gated);
plot(d_gated);

find(d_gated==1)

find(d_gated == -1)

abs(find(d_gated==1) - find(d_gated == -1))


function E = r8mat_expm2 ( A )

%*****************************************************************************80
%
%% R8MAT_EXPM2 uses the Taylor series for the matrix exponential.
%
%  Discussion:
%
%    Formally,
%
%      exp ( A ) = I + A + 1/2 A^2 + 1/3! A^3 + ...
%
%    This function sums the series until a tolerance is satisfied.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 March 2011
%
%  Author:
%
%    Cleve Moler, Charles Van Loan
%
%  Reference:
%
%    Cleve Moler, Charles VanLoan,
%    Nineteen Dubious Ways to Compute the Exponential of a Matrix,
%    Twenty-Five Years Later,
%    SIAM Review,
%    Volume 45, Number 1, March 2003, pages 3-49.
%
%  Parameters:
%
%    Input, real A(N,N), the matrix.
%
%    Output, real E(N,N), the estimate for exp(A).
%
  E = zeros ( size ( A ) );
  F = eye ( size ( A ) );
  k = 1;

  while ( 0 < norm ( E + F - E, 1 ) )
    E = E + F;
    F = A * F / k;
    k = k + 1;
  end

  return
end


function b = r8vec_sht ( n, a  )

%*****************************************************************************80
%
%% R8VEC_SHT computes a "slow" Hartley transform of an R8VEC.
%
%  Discussion:
%
%    The discrete Hartley transform B of a set of data A is
%
%      B(I) = 1/sqrt(N) * Sum ( 0 <= J <= N-1 ) A(J) * CAS(2*PI*I*J/N)
%
%    Here, the data and coefficients are indexed from 0 to N-1.
%
%    With the above normalization factor of 1/sqrt(N), the Hartley
%    transform is its own inverse.
%
%    This routine is provided for illustration and testing.  It is inefficient
%    relative to optimized routines.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 February 2010
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Ralph Hartley,
%    A More Symmetrical Fourier Analysis Applied to Transmission Problems,
%    Proceedings of the Institute of Radio Engineers,
%    Volume 30, pages 144-150, 1942.
%
%  Parameters:
%
%    Input, integer ( kind = 4 ) N, the number of data values.
%
%    Input, real A(N), the data to be transformed.
%
%    Output, real B(N), the transformed data.
%
  b(1:n) = 0.0;

  for i = 1 : n
    for j = 1 : n
      theta = 2.0 * pi * mod ( ( i - 1 ) * ( j - 1 ), n ) / n;
      b(i) = b(i) + a(j) * ( cos ( theta ) + sin ( theta ) );
    end
  end

  b(1:n) = b(1:n) / sqrt ( n );

  return
end


function F = ml_Fmeasure(cluster_labels, class_labels)
%ML_FMEASURE Compute the Fmeasure for clustering with external validity
%
%
%   http://www.uni-weimar.de/medien/webis/teaching/lecturenotes/machine-learning/unit-en-cluster-analysis-evaluation.pdf
%   slide number 23-26
%
%   Macro average F-measure
%
%   Fm is an N x M matrix (N number of classes, M number of clusters) where
%   Fm(i,j) is the F-measure of the jth cluster computed with respect to
%   the ith class
%
%
%   input -----------------------------------------------------------------
%
%       - cluster_labels : N x 1 vector of cluster labels given by the clustering algorithm
%       (N is the size of data)
%
%       - class_labels : N x 1 vector of class labels (ground truth)
%
%   output ----------------------------------------------------------------
%
%       - F = macro averaged F-measure

nbOfClusters = length(unique(cluster_labels));
nbOfClasses  = length(unique(class_labels));
sizeClasses  = zeros(nbOfClasses,1);

Fm = zeros(nbOfClasses,nbOfClusters);

unique_cluster_labels = unique(cluster_labels);
unique_class_labels   = unique(class_labels);

% for i = 1:nbOfClasses
%     for j = 1:nbOfClusters
%         N=0;
%         for k = 1:length(cluster_labels)
%             if(cluster_labels(k) == j && class_labels(k) == i)
%                 N = N+1;
%             end
%         end
%         Precision = N/length(find(cluster_labels==j));
%         Recall = N/length(find(class_labels==i));
%         Fm(i,j) = 2*Precision*Recall/(Precision+Recall);
%     end
% end

for i = 1:nbOfClasses
    for j = 1:nbOfClusters
        N=0;
        for k = 1:length(cluster_labels)
            if(cluster_labels(k) == unique_cluster_labels(j) && class_labels(k) == unique_class_labels(i))
                N = N+1;
            end
        end
        Precision = N/length(find(cluster_labels==unique_cluster_labels(j)));
        Recall = N/length(find(class_labels==unique_class_labels(i)));
        Fm(i,j) = 2*Precision*Recall/(Precision+Recall);
    end
end

for m = 1:nbOfClasses
    sizeClasses(m,:) = length(find(class_labels==unique_class_labels(m)));
end

F = sum(max(Fm,[],2).*sizeClasses)/sum(sizeClasses);

end


function [ X ] = uniformCircle(c,R,N)
%  X  = uniformCircle(c,R,N)
% inputs : c = [c1,c2] center of the circle, R radius, N number of points
% output : X of size Nx2, points uniformly distributed on the cricle
theta = 2*pi*rand(N,1);
X = [c(1)+R*cos(theta) c(2)+R*sin(theta)];

end


function c = opoly(x,y,n)
%
%   opolyfit     OPOLYFIT(x,y,n) finds the n coefficients of a polynomial
%		 formed from the data in row vector x that fits the data
%		 in row vector y in a least-squares sense. Orthogonal
%		 polynomials are used to improve accuracy. See also polyfit.
%
%		 c = opolyfit(x,y,n)
%		 c  ---	coefficient vector, size n
%
%		 References:
%		 G. E. Forsythe, "Generation and use of orthogonal poly-
%		 nomials for data fitting on a digital computer",
%		 J. SIAM, 5(1957), 74-88.
%
%		 P. F. Hultquist, "Numerical Methods for Engineers and
%		 Computer Scientists", Benjamin-Cummings, 1988.
%
%		 Copyright 1992. Gordon	J. Frazer, Signal Processing Research
%		 Laboratory, and Roy J. Hughes, Laboratory for Instrumental and
%		 Developmental Chemistry, QUT, Brisbane, AUSTRALIA, 1992.
%		 Email:	g.frazer@qut.edu.au or	r.hughes@qut.edu.au
n=n+1; % To make it similar to MATLAB polyfit.m

if n<1
 error('polynomial order too small, must be greater than or equal to one');
end
if n+1>length(x)
 error('polynomial order too large for number of data points');
end
% normalise y to improve numerical stability
yscale=0.5/max(abs(y));
yy=yscale*y;
% initialise opoloyfit
gamma_0=length(x);
alpha_0=mean(x);
PC=zeros(n);
PC(1,1)=1;
a=zeros(1,n);
a(1)=mean(yy);
% calculate the	first iteration	manually
PC(2,1:2)=conv([1,-alpha_0],PC(1,1));
gamma_k=sum(polyval(PC(2,1:2),x).*polyval(PC(2,1:2),x));
beta_k=gamma_k/gamma_0;
alpha_k=sum(x.*(polyval(PC(2,1:2),x).*polyval(PC(2,1:2),x)))/gamma_k;
a(2)=sum(yy.*polyval(PC(2,1:2),x))/gamma_k;
% calculate for	the remaining polynomial orders
for k=2:n-1
 PC(k+1,1:k+1)=conv([1,-alpha_k],PC(k,1:k))-beta_k*[0,0,PC(k-1,1:k-1)];
 gamma_km1=gamma_k;
 gamma_k=sum(polyval(PC(k+1,1:k+1),x).*polyval(PC(k+1,1:k+1),x));
 beta_k=gamma_k/gamma_km1;
 alpha_k=sum(x.*(polyval(PC(k+1,1:k+1),x).*polyval(PC(k+1,1:k+1),x)))/gamma_k;
 a(k+1)=sum(yy.*polyval(PC(k+1,1:k+1),x))/gamma_k;
end
% combine the a's to simplify the polynomial
for i=1:n
 PC(i,:)=a(i)*PC(i,:);
end
for i=1:n
 cc(i)=sum(diag(PC,i-n));
end
% unnormalise c	by the y scale factor
c=(1/yscale)*cc;


% book : Signals and Systems Laboratory with MATLAB
% authors : Alex Palamides & Anastasia Veloni

% circular convolution

% mod(-m,N)
N=4;
for m=0:3
p(m+1)=mod(-m,N);
end
p

% circular time-reversed sequence
h=[1,1,0.5,2];
for m=0:3
hs(1+m)=h(1+p(m+1));
end
hs'
stem(0:N-1,hs);
axis([-.4 3.4 -.2 2.2])
legend('h_s(m)=h[((-m))_N]')

% circular convolution
clear y;
figure
N=4;
x=[1,0,2.5,1.5];
m=0:N-1;
stem(m,x);
axis([-.4 3.4 -.2 2.9])
legend('x[m]')
n=0;
hsn=circshift(hs',n);
stem(m,hsn);
axis([-.4 3.4 -.2 2.2]);
legend('h[((n-m))_N],n=0')
y(n+1)=sum( x.*hsn')
% or  alternatively
% y(n+1)=x*hsn;

figure
m=0:N-1;
stem(m,x);
axis([-.4 3.4 -.2 2.9])
legend('x[m]')

figure
n=1;
hsn=circshift(hs',n);
stem(m,hsn);
axis([-.4 3.4 -.2 2.2]);
legend(' h[((n-m))_N], n=1')
y(n+1)=sum(x.*hsn')

figure
n=2;
hsn=circshift(hs',n);
stem(m,hsn);
axis([-.4 3.4 -.2 2.2]);
legend(' h[((n-m))_N], n=2')
y(n+1)=sum(x.*hsn')

figure
n=3;
hsn=circshift(hs',n);
stem(m,hsn);
axis([-.4 3.4 -.2 2.2]);
legend('h[((n-m))_N], n=3')
y(n+1)=x*hsn

figure
stem(m,y)
axis([-.4 3.4 -.2 7.2]);
title('circular convolution')
legend(' y[n] ')


function a = c4mat_test ( n )

%*****************************************************************************80
%
%% C4MAT_TEST sets up a test matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 April 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of A.
%
%    Output, complex A(N,N), the Fourier matrix.
%
  complex_i = complex ( 0.0, 1.0 );

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

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

      a(i,j) = exp ( complex_i * angle ) / sqrt ( n );

    end
  end

  return
end


function varargout = rosenbrock(x)
%ROSENBROCK Rosenbrock's 'banana' function in 2D

if nargin == 0
    varargout{1} = [-2,-1];                 % LB
    varargout{2} = [2,3];                   % UB
    varargout{3} = [0,3000];                % Zlim
    varargout{4} = [-26.5,60];              % view
    varargout{5} = [1,1];                   % xmin
    varargout{6} = 'Rosenbrock function';   % name
    varargout{7} = [-0.5,2.5];              % default x0
    return;
end

if size(x,2) == 1; x = x'; end

varargout{1} = 100*(x(:,2)-x(:,1).^2).^2+(1-x(:,1)).^2;
if nargout > 1
    varargout{2} = [-400*(x(:,2)-x(:,1).^2).*x(:,1)-2*(1-x(:,1)), 200*(x(:,2)-x(:,1).^2)];
end

end


% Implementation of a simple version of the Dijkstra shortest path algorithm
% Returns the distances from a single vertex to all others, doesn't save the path
%
% INPUTS: adjacency matrix, adj (nxn), start node s (index between 1 and n)
% OUTPUTS: shortest path length from the start node to all other nodes, 1xn
%
% Note: Works for a weighted/directed graph.
% GB: last updated, September 28, 2012

function d = simpleDijkstra(adj,s)

n=length(adj);
d = inf*ones(1,n); % distance s-all nodes
d(s) = 0;    % s-s distance
T = 1:n;    % node set with shortest paths not found yet

while not(isempty(T))
    [dmin,ind] = min(d(T));
    for j=1:length(T)
        if adj(T(ind),T(j))>0 && d(T(j))>d(T(ind))+adj(T(ind),T(j))
            d(T(j))=d(T(ind))+adj(T(ind),T(j));
        end
    end
    T = setdiff(T,T(ind));
end


function [dist, pos] = distancePointEdge(point, edge)
%DISTANCEPOINTEDGE Minimum distance between a point and an edge.
%
%   DIST = distancePointEdge(POINT, EDGE);
%   Return the euclidean distance between edge EDGE and point POINT.
%   EDGE has the form: [x1 y1 x2 y2], and POINT is [x y].
%
%   If EDGE is N-by-4 array, result is 1-by-4 array computed for each edge.
%   If POINT is a N-by-2 array, the result is a N-by-1 array.
%   If both POINT and EDGE are array, the result is computed for each
%   point-edge couple, and stored into a NP-by-NE array.
%
%   [DIST POS] = distancePointEdge(POINT, EDGE);
%   Also returns the position of closest point on the edge. POS is
%   comprised between 0 (first point) and 1 (last point).
%
%   Eaxmple
%     % Distance between a point and an edge
%     distancePointEdge([3 4], [0 0 10 0])
%     ans =
%         4
%
%     % Distance between several points and one edge
%     points = [10 15; 15 10; 30 10];
%     edge   = [10 10 20 10];
%     distancePointEdge(points, edge)
%     ans =
%         5
%         0
%        10
%
%     % Distance between a point a several edges
%     point = [14 33];
%     edges  = [10 30 20 30; 20 30 20 40;20 40 10 40;10 40 10 30];
%     distancePointEdge(point, edges)
%     ans =
%         3    6    7    4
%
%
%   See also
%   edges2d, points2d, distancePoints, distancePointLine
%

% ------
% Author: David Legland
% E-mail: david.legland@nantes.inra.fr
% Created: 2004-04-07
% Copyright 2004-2022 INRA - BIA-BIBS

% direction vector of each edge (row vectors)
vx = (edge(:, 3) - edge(:,1))';
vy = (edge(:, 4) - edge(:,2))';

% squared length of edges, with a check of validity
delta = vx .* vx + vy .* vy;
invalidEdges = delta < eps;
delta(invalidEdges) = 1;

% difference of coordinates between point and edge first vertex
% (NP-by-NE arrays)
dx  = bsxfun(@minus, point(:, 1), edge(:, 1)');
dy  = bsxfun(@minus, point(:, 2), edge(:, 2)');

% compute position of points projected on the supporting line, by using
% normalised dot product (NP-by-NE array)
pos = bsxfun(@rdivide, bsxfun(@times, dx, vx) + bsxfun(@times, dy, vy), delta);

% ensure degenerated edges are correclty processed (consider the first
% vertex is the closest)
pos(:, invalidEdges) = 0;

% change position to ensure projected point is located on the edge
pos(pos < 0) = 0;
pos(pos > 1) = 1;

% compute distance between point and its projection on the edge
dist = hypot(bsxfun(@times, pos, vx) - dx, bsxfun(@times, pos, vy) - dy);


function b = isPointInTriangle(point, p1, p2, p3)
%ISPOINTINTRIANGLE Test if a point is located inside a triangle
%
%   B = isPointInTriangle(POINT, V1, V2, V3)
%   POINT is a 1-by-2 row vector containing coordinates of the test point,
%   V1, V2 and V3 are 1-by-2 row vectors containing coordinates of triangle
%   vertices. The function returns 1 is the point is inside or on the
%   boundary of the triangle, and 0 otherwise.
%
%   B = isPointInTriangle(POINT, VERTICES)
%   Specifiy the coordinates of vertices as a 3-by-2 array.
%
%   If POINT contains more than one row, the result B has as many rows as
%   the input POINT.
%
%
%   Example
%     % vertices of the triangle
%     p1 = [0 0];
%     p2 = [10 0];
%     p3 = [5 10];
%     tri = [p1;p2;p3];
%     % check if points are inside
%     isPointInTriangle([0 0], tri)
%     ans =
%         1
%     isPointInTriangle([5 5], tri)
%     ans =
%         1
%     isPointInTriangle([10 5], tri)
%     ans =
%         0
%     % check for an array of points
%     isPointInTriangle([0 0;1 0;0 1], tri)
%     ans =
%         1
%         1
%         0
%
%   See also
%   polygons2d, isPointInPolygon, isCounterClockwise
%
%
% ------
% Author: David Legland
% e-mail: david.legland@grignon.inra.fr
% Created: 2011-05-16,    using Matlab 7.9.0.529 (R2009b)
% Copyright 2011 INRA - Cepia Software Platform.

% if triangle vertices are given as a single array, extract vertices
if nargin == 2
    p2 = p1(2, :);
    p3 = p1(3, :);
    p1 = p1(1, :);
end

% check triangle orientation
isDirect = isCounterClockwise(p1, p2, p3);

% check location of point with respect to each side
if isDirect
    b12 = isCounterClockwise(p1, p2, point) >= 0;
    b23 = isCounterClockwise(p2, p3, point) >= 0;
    b31 = isCounterClockwise(p3, p1, point) >= 0;
else
    b12 = isCounterClockwise(p1, p2, point) <= 0;
    b23 = isCounterClockwise(p2, p3, point) <= 0;
    b31 = isCounterClockwise(p3, p1, point) <= 0;
end

% combines the 3 results
b = b12 & b23 & b31;


function Z = projectData(X, U, K)
%PROJECTDATA Computes the reduced data representation when projecting only
%on to the top k eigenvectors
%   Z = projectData(X, U, K) computes the projection of
%   the normalized inputs X into the reduced dimensional space spanned by
%   the first K columns of U. It returns the projected examples in Z.
%

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

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the projection of the data using only the top K
%               eigenvectors in U (first K columns).
%               For the i-th example X(i,:), the projection on to the k-th
%               eigenvector is given as follows:
%                    x = X(i, :)';
%                    projection_k = x' * U(:, k);
%

Ureduce = U(:, 1:K);

for i=1:size(X, 1)
    z = Ureduce' * X(i, :)';
    Z(i, :) = z;
end;

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

end


function x = twos2dec(t)

% TWOS2DEC Convert binary string two's complement to decimal integer.
%
% Usage: X = TWOS2DEC(T)
%
% Converts the two's complement representation as a string given by T to
% decimal integers X. T can be a character array or cell string. Input
% multiple numbers into T along the rows, and the output will be as a
% column vector. Similarly to BIN2DEC, leading spaces in T are sign
% extended (so treated as either 0 or 1 depending on the first non space
% character), and embedded and trailing spaces are removed.
%
% Example:
%     >> twos2dec(['010 111'; ' 010111'; '101011 '; ' 10   1'])
%
%     ans =
%
%         23
%         23
%        -21
%         -3
%
% Inputs:
%   -T: string two's complement numbers to convert to decimal integers.
%
% Outputs:
%   -X: decimal representation of T.
%
% See also: DEC2TWOS, FIX2DEC, DEC2FIX, BIN2DEC, HEX2DEC, BASE2DEC.

error(nargchk(1, 1, nargin));
if iscellstr(t)
    t = char(t);
end

% Convert to numbers.
x = bin2dec(t);

% Get the number of bits as the number of 0's and 1's in each row.
nbits = sum(t == '0' | t == '1', 2);

% Case for negative numbers.
xneg = log2(x) >= nbits - 1;
% xneg = bitshift(x, -(nbits - 1)) == 1;
if any(xneg)
    x(xneg) = -( bitcmp(x(xneg), nbits(xneg)) + 1 );
end


function y = logMvGamma(x, d)
% Compute logarithm multivariate Gamma function
% which is used in the probability density function of the Wishart and inverse Wishart distributions.
% Gamma_d(x) = pi^(d(d-1)/4) \prod_(j=1)^d Gamma(x+(1-j)/2)
% log(Gamma_d(x)) = d(d-1)/4 log(pi) + \sum_(j=1)^d log(Gamma(x+(1-j)/2))
% Input:
%   x: m x n data matrix
%   d: dimension
% Output:
%   y: m x n logarithm multivariate Gamma
% Written by Michael Chen (sth4nth@gmail.com).
y = d*(d-1)/4*log(pi)+sum(gammaln(x(:)+(1-(1:d))/2),2);
y = reshape(y,size(x));


function value = i4vec_norm_l0 ( n, a )

%*****************************************************************************80
%
%% I4VEC_NORM_L0 returns the l0 "norm" of an I4VEC.
%
%  Discussion:
%
%    An I4VEC is a vector of I4's.
%
%    The l0 "norm" simply counts the number of nonzero entries in the vector.
%    It is not a true norm, but has some similarities to one.  It is useful
%    in the study of compressive sensing.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 June 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of entries in the vector.
%
%    Input, integer A(N), the vector.
%
%    Output, integer I4VEC_NORM_L0, the value of the norm.
%
  value = sum ( a(1:n) ~= 0 );

  return
end


function [U, S] = pca(X)
%PCA Run principal component analysis on the dataset X
%   [U, S, X] = pca(X) computes eigenvectors of the covariance matrix of X
%   Returns the eigenvectors U, the eigenvalues (on diagonal) in S
%

% Useful values
[m, n] = size(X);

% You need to return the following variables correctly.
U = zeros(n);
S = zeros(n);

% ====================== YOUR CODE HERE ======================
% Instructions: You should first compute the covariance matrix. Then, you
%               should use the "svd" function to compute the eigenvectors
%               and eigenvalues of the covariance matrix.
%
% Note: When computing the covariance matrix, remember to divide by m (the
%       number of examples).
%

Sigma = X'*X/m;

[U,S] = svd(Sigma);

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

end


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

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

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

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost of a particular choice of theta.
%               You should set J to the cost.
%               Compute the partial derivatives and set grad to the partial
%               derivatives of the cost w.r.t. each parameter in theta
%
% Hint: The computation of the cost function and gradients can be
%       efficiently vectorized. For example, consider the computation
%
%           sigmoid(X * theta)
%
%       Each row of the resulting matrix will contain the value of the
%       prediction for that example. You can make use of this to vectorize
%       the cost function and gradient computations.
%
% Hint: When computing the gradient of the regularized cost function,
%       there're many possible vectorized solutions, but one solution
%       looks like:
%           grad = (unregularized gradient for logistic regression)
%           temp = theta;
%           temp(1) = 0;   % because we don't add anything for j = 0
%           grad = grad + YOUR_CODE_HERE (using the temp variable)
%

sigmo = sigmoid(X * theta);

Jreg = lambda / (2 * m) * (theta' * theta - theta(1) .^2);

J = 1 / m * (-y' * log(sigmo) - (1 - y)' * log(1 - sigmo)) + Jreg;

temp = theta;
temp(1) = 0;
gradreg = lambda / m * temp;

grad = 1 / m * X' * (sigmo - y) + gradreg;

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

grad = grad(:);

end


function l = l1pp ( n, h )

%*****************************************************************************80
%
%% L1PP stores the 1D PP Laplacian as a full matrix.
%
%  Discussion:
%
%    The N grid points are assumed to be evenly spaced by H.
%
%    For N = 5, the discrete Laplacian with periodic boundary conditions
%    has the matrix form L:
%
%       2 -1  0  0 -1
%      -1  2 -1  0  0
%       0 -1  2 -1  0
%       0  0 -1  2 -1
%      -1  0  0 -1  2
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 October 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of points.
%    N must be at least 3.
%
%    Input, real H, the spacing between points.
%
%    Output, real L(N,N), the Laplacian matrix.
%
  if ( n < 3 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'L1PP - Fatal error!\n' );
    fprintf ( 1, '  N < 3.\n' );
    error ( 'L1PP - Fatal error!' );
  end

  l = zeros ( n, n );

  i = 1;
  l(1,1) =  2.0 / h / h;
  l(1,2) = -1.0 / h / h;
  l(1,n) = -1.0 / h / h;

  for i = 2 : n - 1
    l(i,i-1) = -1.0 / h / h;
    l(i,i) =    2.0 / h / h;
    l(i,i+1) = -1.0 / h / h;
  end

  i = n;
  l(n,1) =   -1.0 / h / h;
  l(n,n-1) = -1.0 / h / h;
  l(n,n) =    2.0 / h / h;

  return
end


function [ thetaVec,sVec ] = getEllipseLengthVector( a,b, theta0,theta1 )
%% About:
% This function is used to return the length of the ellipse as a function
% of the angle theta.

%% Inputs:
% theta0, theta1: start/end angle of the arc of the ellipse (from the parametric equation of the ellipse)
% a,b: the big and the small radious of the ellipse.

% Mohammad SAFEEA 10-Nov-2017

thetaSpan = [theta0 theta1];
s0 = 0;
opts = odeset('RelTol',1e-2,'AbsTol',1e-4);
[thetaVec,sVec] = ode45(@(theta,s) ((a*a*sin(theta)*sin(theta)+b*b*cos(theta)*cos(theta))^0.5), thetaSpan, s0,opts);

end


function pde = sincosdata3
%% SINCOSDATA3 trigonometric data for Poisson equation in 3-D
%
%     u = cos(pi*x)*cos(pi*y)*cos(pi*z);
%     f = - Delta u = 3*pi^2*cos(pi*x)*cos(pi*y)*cos(pi*z);
%     Du = (-pi*sin(pi*x)*cos(pi*y)*cos(pi*z),
%           -pi*cos(pi*x)*sin(pi*y)*cos(pi*z),
%           -pi*cos(pi*x)*cos(pi*y)*sin(pi*z));
%
% Copyright (C) Long Chen. See COPYRIGHT.txt for details.

pde = struct('f',@f,'exactu',@exactu,'g_D',@g_D,'Du',@Du,'g_N',@g_N, 'phi', @phi);

    % load data (right hand side function)
    function s = f(p)
    x = p(:,1); y = p(:,2); z = p(:,3);
    s = 3*pi^2*cos(pi*x).*cos(pi*y).*cos(pi*z);
    end
    % exact solution
    function s = exactu(p)
    x = p(:,1); y = p(:,2); z = p(:,3);
    s = cos(pi*x).*cos(pi*y).*cos(pi*z); % for neumann boundary condition, int_u =0
    end
    % Dirichlet boundary condition
    function s = g_D(p)
    s = exactu(p);
    end
    % Neumann boundary condtion
    function f = g_N(p)
    f = zeros(size(p,1),1);
    x = p(:,1); y = p(:,2); z = p(:,3);
    uprime = [-pi*sin(pi*x).*cos(pi*y).*cos(pi*z) ...
              -pi*cos(pi*x).*sin(pi*y).*cos(pi*z) ...
              -pi*cos(pi*x).*cos(pi*y).*sin(pi*z)];
    downbd = (abs(z)<eps); % n = (0,0,-1)
    f(downbd) = -uprime(downbd,3);
    upbd = (abs(z-1)<eps);% n = (0,0,1)
    f(upbd) = uprime(upbd,3);
    leftbd = (abs(x)<eps); % n = (-1,0,0)
    f(leftbd) = -uprime(leftbd,1);
    rightbd = (abs(x-1)<eps); % n = (1,0,0)
    f(rightbd) = uprime(rightbd,1);
    backbd = (abs(y-1)<eps); % n =(0,1,0)
    f(backbd) = uprime(backbd,2);
    frontbd = (abs(y)<eps); % n = (0,-1,0)
    f(frontbd) = -uprime(frontbd,2);
    end
    % Derivative of the exact solution
    function s = Du(p)
    x = p(:,1); y = p(:,2); z = p(:,3);
    s(:,1) = -pi*sin(pi*x).*cos(pi*y).*cos(pi*z);
    s(:,2) = -pi*cos(pi*x).*sin(pi*y).*cos(pi*z);
    s(:,3) = -pi*cos(pi*x).*cos(pi*y).*sin(pi*z);
    end
    function s = phi(p) % level set function
        x = p(:,1); y = p(:,2); z =p(:,3);
        s = x.^2 + y.^2 +z.^2 - 0.75^2;
    end
end


function varargout = easom(X)
% Easom function
%
%   EASOM([x1, x2]) returns the value of the Easom function at the
%   specified points. [x1] and [x2] may be vectors. The search
%   domain is
%
%               -100 < x_i < 100
%
%   The global minimum is
%
%               f(x1, x2) = f(pi, pi) = -1.

% Author: Rody P.S. Oldenhuis
% Delft University of Technology
% E-mail: oldenhuis@dds.nl
% Last edited 20/Jul/2009

    % if no input is given, return dimensions, bounds and minimum
    if (nargin == 0)
        varargout{1} = 2;  % # dims
        varargout{2} = [-100, -100]; % LB
        varargout{3} = [+100, +100]; % UB
        varargout{4} = [pi,pi]; % solution
        varargout{5} = -1; % function value at solution (too complicated)

    % otherwise, output function value
    else

        % keep values in the serach interval
        X(X < -100) = inf;     X(X > 100) = inf;

        % split input vector X into x1, x2
        if size(X, 1) == 2
            x1 = X(1, :);        x2 = X(2, :);
        else
            x1 = X(:, 1);        x2 = X(:, 2);
        end

        % output function value
        varargout{1} = -cos(x1).*cos(x2).*exp(-((x1-pi).^2 + (x2-pi).^2));

    end

end


function varargout = styblinskitang(X)
% Styblinski-Tang function
%
%   STYBLINSKYTANG([x1, x2, ..., xn]) returns the value of the
%   Styblinski-Tang at the specified points. All [xi] may be vectors.
%   The search domain is
%
%               -5 < x_i < 5
%
%   The global minimum is
%
%               f(x1, x2, ..., xn) =
%               f(-2.903534, -2.903534, ..., -2.903534) = -39.16599 * n

% Author: Rody P.S. Oldenhuis
% Delft University of Technology
% E-mail: oldenhuis@dds.nl
% Last edited 20/Jul/2009

    % if no input is given, return dimensions, bounds and minimum
    if (nargin == 0)
        varargout{1} = inf;  % # dims
        varargout{2} = -5; % LB
        varargout{3} = +5; % LB
        varargout{4} = -2.903534018185960e+000; % solution
        varargout{5} = -3.916616570377142e+001; % *(#dims) .. function value at solution

    % otherwise, output function value
    else

        % keep all values in the search domain
        X(X < -5) = inf;  X(X > 5) = inf;

        % NOTE: orientation can not be determined automatically
        % defaults to columnsums...
        varargout{1} = sum(X.^4 - 16*X.^2 + 5*X, 1)/2;

    end

end


function y = gvar(x,n)
%GVAR Variance of a grouped sample.
%  In some scientific works, once the data have been gathered from a
%  population of interest, it is often difficult to get a sense of what
%  the data indicate when they are presented in an unorganized fashion.
%  Assembling the raw data into a meaningful form, such as a frequency
%  distribution, makes the data easier to understand and interpret. It is
%  in the context of frequency distributions that the importance of
%  conveying in a succinct way numerical information contained in the data
%  is encountered.
%  So, grouped data is data that has been organized into groups known as
%  classes.  The raw dataset can be organized by constructing a table
%  showing the frequency distribution of the variable (whose values are
%  given in the raw dataset). Such a frequency table is often referred to
%  as grouped data.
%  Here, we developed a m-code to calculate the variance of a grouped data.
%  One can input the returns or modified vectors n and xout containing the
%  frequency counts and the bin locations of the hist m-function, in a
%  column form matrix.
%  Normalizes Y by (N-1), where N is the sample size.  This is an unbiased
%  estimator of the variance of the population from which X is drawn.
%  Y = VAR(X,1) normalizes by N and produces the second moment of the
%  sample about its mean. VAR(X,0) is the same as VAR(X).
%
%  Variance calculation uses the formula,
%
%
%              V =  Sum(F*(MC - M)^2)/D
%
%  where:
%  F  = class frequency
%  MC = mark class
%  M = grouped mean
%  D = N - 1 or N, whether normalizes by n-1 or by n
%  N = sample size [=sum(F)]
%
%  Syntax: function y = gvar(x)
%
%  Inputs:
%       x - data matrix (Size of matrix must be n-by-2; absolut frequency=
%           column 1, class mark=column 2)
%       n - [normalized by n-1] = 0 (default), [normalized by n] = 1
%  Outputs:
%       y  - variance of the values in x
%
%  Example: Suppose we have the next frequency table:
%
%                     ----------------
%                       MC         F
%                     ----------------
%                        5         6
%                       15        16
%                       25        24
%                       35        25
%                       45        17
%                     ----------------
%
%  Taken from:
%  http://mlsc.lboro.ac.uk/resources/statistics/var_stand_deviat_group.pdf
%
%  Where we are interested to get the variance value normalized by n.
%
%  Data input:
%  x=[5 6;15 16;25 24;35 25;45 17];
%
%  Calling on Matlab the function:
%          y = gvar(x,1)
%
%  Answer is:
%
%  y = 138.7268
%
%  Created by A. Trujillo-Ortiz and R. Hernandez-Walls
%             Facultad de Ciencias Marinas
%             Universidad Autonoma de Baja California
%             Apdo. Postal 453
%             Ensenada, Baja California
%             Mexico.
%             atrujo@uabc.edu.mx
%
%  Copyright (C)  September 18, 2012.
%
%  To cite this file, this would be an appropriate format:
%  Trujillo-Ortiz, A. and R. Hernandez-Walls. (2012).
%     gvar:Varience of a grouped sample. [WWW document].
%     URL http://www.mathworks.com/matlabcentral/fileexchange/
%     38281-gvar
%
%  Reference:
%  Jayaraman, K. (1999), A Statistical Manual for Foresty Research. Foresty
%             Research Support Programme for Asia and the Pacific. FAO-
%             Corporate Document Repository. Forestry Statistics and Data
%             Collection.
%             URL http://www.fao.org/DOCREP/003/X6831E/X6831E00.HTM
%             PDF ftp://ftp.fao.org/docrep/fao/003/X6831E/X6831E00.pdf
%

if  nargin < 2,
    n = 0; %default
end

c = size(x,2);

if c ~= 2
    error('stats:gvar:BadData','X must have two colums.');
end

mc = x(:,1); %class mark
f = x(:,2); %absolut frequency
s = sum(f.*mc);
m = s/sum(f);
ss = sum(f.*(mc - m).^2);

if n == 0; %default
    d = sum(f) - 1;
else n = 1;
    d = sum(f);
end

y = ss/d;

return,


function volume = sphere_imp_zone_volume_3d ( r, h1, h2 )

%*****************************************************************************80
%
%% SPHERE_IMP_ZONE_VOLUME_3D computes the volume of a spherical zone in 3D.
%
%  Discussion:
%
%    An implicit sphere in 3D satisfies the equation:
%
%      sum ( ( P(1:DIM_NUM) - CENTER(1:DIM_NUM) )**2 ) = R**2
%
%    Draw any radius of the sphere and note the point P where the radius
%    intersects the sphere.  Now choose two points on the radius line, a
%    distance H1 and H2 from the point P.  Consider all the points on or within
%    the sphere whose projection onto the radius lies between these two points.
%    These points constitute the spherical zone, which can also be considered
%    the difference of two spherical caps.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R, the radius of the sphere.
%
%    Input, real H1, H2, the distances that define the
%    thickness of the zone.  H1 and H2 must be between 0 and 2 * R.
%
%    Output, real VOLUME, the volume of the spherical zone
%
  h11 = min ( h1, h2 );
  h11 = max ( h11, 0.0 );

  if ( 2.0 * r <= h11 )
    volume = 0.0;
    return
  end

  h22 = max ( h1, h2 );
  h22 = min ( h22, 2.0 * r );

  if ( h22 <= 0.0 )
    volume = 0.0;
    return
  end

  volume = ( 1.0 / 3.0 ) * pi * ( ...
      h22 * h22 * ( 3.0 * r - h22 ) ...
    - h11 * h11 * ( 3.0 * r - h11 ) );

  return
end


function [airfoildata] = PerformRegression(data)
% Relate the coefficients of the drag polar to Re as parabolic functions.
% Drag polar is Cd = a0 + a1*alpha + a2*alpha^2
% The contents of airfoildata are the coefficients resulting from the
% polynomial regression with respect to Reynolds number:
%'NACA 4 or 5 digit' | 3 coefficients for a0 |
% 3 coefficients for a1 | 3 coefficients for a2 |
% 3 coefficients for alpha_stall
% so that:
% a0 = b1 + b2*log10(Re) + b3*log10(Re)^2
% a1 = c1 + c2*log10(Re) + c3*log10(Re)^2
% a2 = d1 + d2*log10(Re) + d3*log10(Re)^2
% and:
% alphastall = k1 + k2*log10(Re) + k3*log10(Re)^2

for i = 1:length(data)
    if length(data(i).Re) >= 2
        airfoildata{1}{i} = data(i).airfoil;
        airfoildata{2}{i} = [ones(size(data(i).Re)) log10(data(i).Re) log10(data(i).Re).^2]\[data(i).a0];
        airfoildata{3}{i} = [ones(size(data(i).Re)) log10(data(i).Re) log10(data(i).Re).^2]\[data(i).a1];
        airfoildata{4}{i} = [ones(size(data(i).Re)) log10(data(i).Re) log10(data(i).Re).^2]\[data(i).a2];
        airfoildata{5}{i} = [ones(size(data(i).Re)) log10(data(i).Re) log10(data(i).Re).^2]\[data(i).alphastall];
    end
end


function [ w, xy ] = triangle_unit_o07 ( )

%*****************************************************************************80
%
%% TRIANGLE_UNIT_O07 returns a 7 point quadrature rule for the unit triangle.
%
%  Discussion:
%
%    This rule is precise for monomials through degree 5.
%
%    The integration region is:
%
%      0 <= X
%      0 <= Y
%      X + Y <= 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 April 2009
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Carlos Felippa,
%    A compendium of FEM integration formulas for symbolic work,
%    Engineering Computation,
%    Volume 21, Number 8, 2004, pages 867-890.
%
%  Parameters:
%
%    Output, real W(7), the weights.
%
%    Output, real XY(2,7), the abscissas.
%
  w(1:7,1) = [ ...
    0.12593918054482715260, ...
    0.12593918054482715260, ...
    0.12593918054482715260, ...
    0.13239415278850618074, ...
    0.13239415278850618074, ...
    0.13239415278850618074, ...
    0.22500000000000000000 ];

  xy(1:2,1:7) = [ ...
    0.79742698535308732240,  0.10128650732345633880; ...
    0.10128650732345633880,  0.79742698535308732240; ...
    0.10128650732345633880,  0.10128650732345633880; ...
    0.059715871789769820459,  0.47014206410511508977; ...
    0.47014206410511508977,  0.059715871789769820459; ...
    0.47014206410511508977,  0.47014206410511508977; ...
    0.33333333333333333333,  0.33333333333333333333 ]';

  return
end


function a = pascal2 ( n )

%*****************************************************************************80
%
%% PASCAL2 returns the PASCAL2 matrix.
%
%  Formula:
%
%    If ( I = 1 or J = 1 )
%      A(I,J) = 1
%    else
%      A(I,J) = A(I-1,J) + A(I,J-1)
%
%  Example:
%
%    N = 5
%
%    1 1  1  1  1
%    1 2  3  4  5
%    1 3  6 10 15
%    1 4 10 20 35
%    1 5 15 35 70
%
%  Properties:
%
%    A is a "chunk" of the Pascal binomial combinatorial triangle.
%
%    A is positive definite.
%
%    A is symmetric: A' = A.
%
%    Because A is symmetric, it is normal.
%
%    Because A is normal, it is diagonalizable.
%
%    A is integral, therefore det ( A ) is integral, and
%    det ( A ) * inverse ( A ) is integral.
%
%    A is nonsingular.
%
%    det ( A ) = 1.
%
%    A is unimodular.
%
%    Eigenvalues of A occur in reciprocal pairs.
%
%    The condition number of A is approximately 16^N / ( N*PI ).
%
%    The elements of the inverse of A are integers.
%
%    A(I,J) = (I+J-2)! / ( (I-1)! * (J-1)! )
%
%    The Cholesky factor of A is a lower triangular matrix R,
%    such that A = R * R'.  The matrix R is a Pascal
%    matrix of the type generated by subroutine PASCAL.  In other
%    words, PASCAL2 = PASCAL * PASCAL'.
%
%    If the (N,N) entry of A is decreased by 1, the matrix is singular.
%
%    Gregory and Karney consider a generalization of this matrix as
%    their test matrix 3.7, in which every element is multiplied by a
%    nonzero constant K.  They point out that if K is the reciprocal of
%    an integer, then the inverse matrix has all integer entries.
%
%    The family of matrices is nested as a function of N.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Robert Brawer, Magnus Pirovino,
%    The linear algebra of the Pascal matrix,
%    Linear Algebra and Applications,
%    Volume 174, 1992, pages 13-23.
%
%    Robert Gregory, David Karney,
%    Example 3.7,
%    A Collection of Matrices for Testing Computational Algorithms,
%    Wiley, 1969, page 32,
%    LC: QA263.G68.
%
%    Nicholas Higham,
%    Accuracy and Stability of Numerical Algorithms,
%    Society for Industrial and Applied Mathematics,
%    Philadelphia, PA, USA, 1996; section 26.4.
%
%    Sam Karlin,
%    Total Positivity, Volume 1,
%    Stanford University Press, 1968.
%
%    Morris Newman, John Todd,
%    The evaluation of matrix inversion programs,
%    Journal of the Society for Industrial and Applied Mathematics,
%    Volume 6, Number 4, pages 466-476, 1958.
%
%    Heinz Rutishauser,
%    On test matrices,
%    Programmation en Mathematiques Numeriques,
%    Centre National de la Recherche Scientifique,
%    1966, pages 349-365.
%
%    John Todd,
%    Basic Numerical Mathematics, Vol. 2: Numerical Algebra,
%    Academic Press, 1977, page 172.
%
%    HW Turnbull,
%    The Theory of Determinants, Matrices, and Invariants,
%    Blackie, 1929.
%
%  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 )
        a(i,j) = 1.0;
      elseif ( j == 1 )
        a(i,j) = 1.0;
      else
        a(i,j) = a(i,j-1) + a(i-1,j);
      end

    end
  end

  return
end


function [phi,dphi]=pt2TetrahedronCoords3D(x,v)
%%PT2TETRAHEDRONCOORDS3D Convert a 3D point to barycentric coordinates in
%      a tetrahedron using the relative areas of subtetrahedra, as
%      discussed at the beginning of [1]. A signed tetrahedral volume area
%      is used so that points outside of the tetrahedron can also be
%      represented (albeit with some negative weights).
%
%INPUTS: x The 3XnumPts set of points to convert into tetrahedral
%          coordinates.
%        v The 3X4 set of vertices of the tetrahedron.
%
%OUTPUTS: phi A 4XnumPts set of the coordinates in the triangle.
%        dphi A 4X3XnumPts set of derivatives of the elements of phi
%             (rows) taken with respect to the elements of x (columns) for
%             each input measurement (3rd dimension).
%
%In [1], the coordinates are defined as the ratio of the volume of a number
%of sub-tetrahedra (with x as a vertex) and the tetrahedron given in v.
%Here, things differ a little bit in that signed tetrahedral volumes are
%used with a very specific ordering. This allows this function to work
%with points inside the tetrahedron (with all positive weights) as well as
%with points outside the tetrahdron (with some negative weights).
%
%EXAMPLE 1:
%In this example, the coordinates of three points are found and the points
%are recreated from the phi values. The residual error of the reverse
%conversion is seen to be on the order of finite precision errors.
% x=sqrt(3)/3;
% h=sqrt(6)/3;
% d=sqrt(3)/6;
% v=[x,  -d,  -d, 0;
%    0, 1/2,-1/2, 0;
%    0,   0,   0, h];
% xPts=[[0;0;0.5],[x;0;0],[1;1;1]];
% phi=pt2TetrahedronCoords3D(xPts,v);
% xBack=barycentricCoords2Pt(phi,v);
% ResidualErr=max(max(abs(xBack-xPts)))
%
%EXAMPLE 2:
%In this example, we verify that the derivative is consistent with
%numerical differentiation. The absolute error is consistent with what one
%might expect due to finite precision limitations.
% v=randn(3,4);
% x=randn(3,1);
% [~,dphi]=pt2TetrahedronCoords3D(x,v);
% f=@(y)pt2TetrahedronCoords3D(y,v);
% dPhiNumDiff=numDiff(x,f,4);
% RelErr=max(max(abs((dphi-dPhiNumDiff)./dPhiNumDiff)))
%
%REFERENCES:
%[1] M. S. Floater, "Generalized barycentric coordinates and applications,"
%    Acta Numerica, vol. 24, pp. 161-214, 1 May 2015.
%
%December 2021 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

a=v(:,1);
b=v(:,2);
c=v(:,3);
d=v(:,4);

numX=size(x,2);
phi=zeros(4,numX);
dphi=zeros(4,3,numX);
for curX=1:numX
    [Va,dVa]=tetrahedronVolume([b,x(:,curX),d,c],false,2);
    [Vb,dVb]=tetrahedronVolume([a,x(:,curX),c,d],false,2);
    [Vc,dVc]=tetrahedronVolume([a,x(:,curX),d,b],false,2);
    [Vd,dVd]=tetrahedronVolume([a,x(:,curX),b,c],false,2);

    %Nominally, V=tetrahedronVolume(v,false); should equal Va+Vb+Vc+Vd.
    %However, to ensure that phi is normalized to more significant digits,
    %we compute V directly from the sum rather than computing it once
    %outside this loop and reusing it.
    V=Va+Vb+Vc+Vd;

    phi(:,curX)=[Va;Vb;Vc;Vd]/V;

    dphi(:,:,curX)=[dVa;
                    dVb;
                    dVc;
                    dVd]/V;
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 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 [ 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