function area = sphere01_area ( )

%*****************************************************************************80
%
%% SPHERE01_AREA returns the area of the unit sphere.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 January 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, real AREA, the area of the unit sphere.
%
  r = 1.0;
  area = 4.0 * pi * r * r;

  return
end


function p = polynomial_value ( m, o, c, e, n, x )

%*****************************************************************************80
%
%% POLYNOMIAL_VALUE evaluates a polynomial.
%
%  Discussion:
%
%    The polynomial is evaluated term by term, and no attempt is made to
%    use an approach such as Horner's method to speed up the process.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 December 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the spatial dimension.
%
%    Input, integer O, the "order" of the polynomial.
%
%    Input, real C(O), the coefficients of the polynomial.
%
%    Input, integer E(O), the indices of the exponents of the polynomial.
%
%    Input, integer N, the number of evaluation points.
%
%    Input, real X(M,N), the coordinates of the evaluation points.
%
%    Output, real P(N), the value of the polynomial at X.
%
  p = zeros ( n, 1 );

  for j = 1 : o
    f = mono_unrank_grlex ( m, e(j) );
    v = mono_value ( m, n, f, x );
    p(1:n) = p(1:n) + c(j) * v(1:n);
  end

  return
end


% RANDN Normally distributed pseudorandom numbers.
%    R = RANDN(N) returns an N-by-N matrix containing pseudorandom values drawn
%    from the standard normal distribution.  RANDN(M,N) or RANDN([M,N]) returns
%    an M-by-N matrix. RANDN(M,N,P,...) or RANDN([M,N,P,...]) returns an
%    M-by-N-by-P-by-... array. RANDN returns a scalar.  RANDN(SIZE(A)) returns
%    an array the same size as A.
%
%    Note: The size inputs M, N, P, ... should be nonnegative integers.
%    Negative integers are treated as 0.
%
%    R = RANDN(..., CLASSNAME) returns an array of normal values of the
%    specified class. CLASSNAME can be 'double' or 'single'.
%
%    R = RANDN(..., 'like', Y) returns an array of normal values of the
%    same class as Y.
%
%    The sequence of numbers produced by RANDN is determined by the settings of
%    the uniform random number generator that underlies RAND, RANDN, and RANDI.
%    RANDN uses one or more uniform random values to create each normal random
%    value.  Control that shared random number generator using RNG.
%
%    Examples:
%
%       Example 1: Generate values from a normal distribution with mean 1
%        and standard deviation 2.
%          r = 1 + 2.*randn(100,1);
%
%       Example 2: Generate values from a bivariate normal distribution with
%       specified mean vector and covariance matrix.
%          mu = [1 2];
%          Sigma = [1 .5; .5 2]; R = chol(Sigma);
%          z = repmat(mu,100,1) + randn(100,2)*R;
%
%       Example 3: Reset the random number generator used by RAND, RANDI, and
%       RANDN to its default startup settings, so that RANDN produces the same
%       random numbers as if you restarted MATLAB.
%          rng('default');
%          randn(1,5)
%
%       Example 4: Save the settings for the random number generator used by
%       RAND, RANDI, and RANDN, generate 5 values from RANDN, restore the
%       settings, and repeat those values.
%          s = rng
%          z1 = randn(1,5)
%          rng(s);
%          z2 = randn(1,5) % z2 contains exactly the same values as z1
%
%       Example 5: Reinitialize the random number generator used by RAND,
%       RANDI, and RANDN with a seed based on the current time.  RANDN will
%       return different values each time you do this.  NOTE: It is usually
%       not necessary to do this more than once per MATLAB session.
%          rng('shuffle');
%          randn(1,5)
%
%    See Replace Discouraged Syntaxes of rand and randn to use RNG to replace
%    RANDN with the 'seed' or 'state' inputs.
%
%    See also RAND, RANDI, RNG, RANDSTREAM, RANDSTREAM/RANDN
%
%    Reference page in Doc Center
%       doc randn
%
%    Other functions named randn
%
%       codistributed/randn        distributed/randn    RandStream/randn
%       codistributor1d/randn      gpuArray/randn       ts/randn
%       codistributor2dbc/randn
%


function alpha = sphericalAngle(p1, p2, p3)
%SPHERICALANGLE Compute angle between points on the sphere.
%
%   ALPHA = sphericalAngle(P1, P2, P3)
%   Computes angle (P1, P2, P3), i.e. the angle, measured at point P2,
%   between the direction (P2, P1) and the direction (P2, P3).
%   The result is given in radians, between 0 and 2*PI.
%
%   Points are given either as [x y z] (there will be normalized to lie on
%   the unit sphere), or as [phi theta], with phi being the longitude in [0
%   2*PI] and theta being the elevation on horizontal [-pi/2 pi/2].
%
%
%   NOTE:
%   this is an 'oriented' version of the angle computation, that is, the
%   result of sphericalAngle(P1, P2, P3) equals
%   2*pi-sphericalAngle(P3,P2,P1). To have the more classical relation
%   (with results given betwen 0 and PI), it suffices to take the minimum
%   of angle and 2*pi-angle.
%
%   Examples
%     % Use inputs as cartesian coordinates
%     p1 = [0 1 0];
%     p2 = [1 0 0];
%     p3 = [0 0 1];
%     alpha = sphericalAngle(p1, p2, p3)
%     alpha =
%         1.5708
%
%     % Use inputs as spherical coordinates
%     sph1 = [.1 0];
%     sph2 = [0 0];
%     sph3 = [0 .1];
%     alphas = sphericalAngle(sph1, sph2, sph3)
%     alphas =
%         1.5708
%
%
%   See also:
%   geom3d, angles3d, spheres, sph2cart

%   ---------
%   author : David Legland
%   INRA - TPV URPOI - BIA IMASTE
%   created the 21/02/2005.
%

%   HISTORY
%   23-05-2006 fix bug for points with angle from center > pi/2
%   05-06-2013 fix bug for points given as spherical coordinates, better
%       support for multiple inputs

% test if points are given as matlab spherical coordinates
if size(p1, 2) == 2
    [x, y, z] = sph2cart(p1(:,1), p1(:,2), ones(size(p1,1), 1));
    p1 = [x y z];
    [x, y, z] = sph2cart(p2(:,1), p2(:,2), ones(size(p2,1), 1));
    p2 = [x y z];
    [x, y, z] = sph2cart(p3(:,1), p3(:,2), ones(size(p3,1), 1));
    p3 = [x y z];
end

% normalize points
p1  = normalizeVector3d(p1);
p2  = normalizeVector3d(p2);
p3  = normalizeVector3d(p3);

% create the plane tangent to the unit sphere and containing central point
plane = createPlane(p2, p2);

% project the two other points on the plane
pp1 = planePosition(projPointOnPlane(p1, plane), plane);
pp3 = planePosition(projPointOnPlane(p3, plane), plane);

% compute angle on the tangent plane
pp2 = zeros(max(size(pp1, 1), size(pp3,1)), 2);
alpha = angle3Points(pp1, pp2, pp3);


function value = r8vec_norm_l0 ( n, a )

%*****************************************************************************80
%
%% R8VEC_NORM_L0 returns the l0 "norm" of an R8VEC.
%
%  Discussion:
%
%    An R8VEC is a vector of R8'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:
%
%    02 January 2015
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of entries in the vector.
%
%    Input, real A(N), the vector.
%
%    Output, real R8VEC_NORM_L0, the value of the norm.
%
  value = sum ( a(1:n) ~= 0.0 );

  return
end


function matrixOut = smooth2a(matrixIn,Nr,Nc)
% Smooths 2D array data.  Ignores NaN's.
%
%function matrixOut = smooth2a(matrixIn,Nr,Nc)
%
% This function smooths the data in matrixIn using a mean filter over a
% rectangle of size (2*Nr+1)-by-(2*Nc+1).  Basically, you end up replacing
% element "i" by the mean of the rectange centered on "i".  Any NaN
% elements are ignored in the averaging.  If element "i" is a NaN, then it
% will be preserved as NaN in the output.  At the edges of the matrix,
% where you cannot build a full rectangle, as much of the rectangle that
% fits on your matrix is used (similar to the default on Matlab's builtin
% function "smooth").
%
% "matrixIn": original matrix
% "Nr": number of points used to smooth rows
% "Nc": number of points to smooth columns.  If not specified, Nc = Nr.
%
% "matrixOut": smoothed version of original matrix
%
%
% 	Written by Greg Reeves, March 2009.
% 	Division of Biology
% 	Caltech
%
% 	Inspired by "smooth2", written by Kelly Hilands, October 2004
% 	Applied Research Laboratory
% 	Penn State University
%
% 	Developed from code written by Olof Liungman, 1997
% 	Dept. of Oceanography, Earth Sciences Centre
% 	Gďż˝teborg University, Sweden
% 	E-mail: olof.liungman@oce.gu.se

%
% Initial error statements and definitions
%
if nargin < 2, error('Not enough input arguments!'), end

N(1) = Nr;
if nargin < 3, N(2) = N(1); else N(2) = Nc; end

if length(N(1)) ~= 1, error('Nr must be a scalar!'), end
if length(N(2)) ~= 1, error('Nc must be a scalar!'), end

%
% Building matrices that will compute running sums.  The left-matrix, eL,
% smooths along the rows.  The right-matrix, eR, smooths along the
% columns.  You end up replacing element "i" by the mean of a (2*Nr+1)-by-
% (2*Nc+1) rectangle centered on element "i".
%
[row,col] = size(matrixIn);
eL = spdiags(ones(row,2*N(1)+1),(-N(1):N(1)),row,row);
eR = spdiags(ones(col,2*N(2)+1),(-N(2):N(2)),col,col);

%
% Setting all "NaN" elements of "matrixIn" to zero so that these will not
% affect the summation.  (If this isn't done, any sum that includes a NaN
% will also become NaN.)
%
A = isnan(matrixIn);
matrixIn(A) = 0;

%
% For each element, we have to count how many non-NaN elements went into
% the sums.  This is so we can divide by that number to get a mean.  We use
% the same matrices to do this (ie, "eL" and "eR").
%
nrmlize = eL*(~A)*eR;
nrmlize(A) = NaN;

%
% Actually taking the mean.
%
matrixOut = eL*matrixIn*eR;
matrixOut = matrixOut./nrmlize;


function y = Evaluate_FT(x,shift,boxlen,center,w)
% Evaluate_FT -- 1d unequispaced Fourier transform followed by windowing
% Usage:
%   y = Evaluate_FT(x,shift,boxlen,center,w)
% Inputs:
%   x	      vector of length n
%   shift     vector of shifts
%   boxlen    half length of interval around each shift
%   center    boolean variable: 0/1 = unbiased/biased FT
%   w         tapering window of size 2*boxlen
% Outputs:
%   y         vector of length: (# shifts) * (2*boxlen)
% Description:
%  Evaluates the FT at the frequency points
%                   omega(j,k) = shift(j) + k, -boxlen <= k <boxlen
%  If center = 0,
%
%  y = sum_{-n/2 <= t < n/2} exp(-i 2pi omega t/n) x(t), -n/2 <= t < n/2
%
%  If center = 1,
%
%  y = sum_{0 <= t < n} exp(-i 2pi omega t/n) x(t), 0 <= t < n
%
%  For each shift parameter (shift(j)), the outcome y_j is then
%  tapered with the window w
%
%  Evaluate_FT uses two different methods for computing the
%  unesquispaced Fourier transform. If the number of shifts is less
%  than 8, it uses an exact method, otherwise it uses the
%  accelerated USFFT.
%  See Also
%    Adj_Evaluate_FT, USFFT, USFT_simple
%
% By Emmanuel candes, 2003-2004

  if nargin < 5,
    w = ones(1,2*boxlen);
  end

  if nargin < 4,
    center = 0;
  end

  n = length(x);
  boxcnt = length(shift);

  if (boxcnt <= 16)
	  y = USFT_simple(x,shift,boxlen,center,w); % nonequispaced FT
  else
    % Make frequency grid
    k = (-boxlen):(boxlen -1);
    omega = meshgrid(shift,k) + meshgrid(k,shift).';
    omega = 2*pi*(omega(:))./n;

    y = USFFT(x,omega,16,6,center)./sqrt(n); % Take USFFT
    y = repmat(w(:),boxcnt,1) .* y; % Tapering
  end


function prob = ml_gaussPDF(Data, Mu, Sigma)
%ML_GAUSSPDF
% This function computes the Probability Density Function (PDF) of a
% multivariate Gaussian represented by means and covariance matrix.
%
% Author:	Sylvain Calinon, 2009
%			http://programming-by-demonstration.org
%
% Inputs -----------------------------------------------------------------
%   o Data:  D x N array representing N datapoints of D dimensions.
%   o Mu:    D x 1 array representing the centers of the K GMM components.
%   o Sigma: D x D x 1 array representing the covariance matrices of the
%            K GMM components.
% Outputs ----------------------------------------------------------------
%   o prob:  1 x N array representing the probabilities for the
%            N datapoints.

[nbVar,nbData] = size(Data);

%      (D x N) - repmat((D x 1),1,N)
%      (D x N) - (D x N)
Data = (Data - repmat(Mu,1,nbData))';

% Data = (N x D)

% (N x 1)
prob = sum((Data*inv(Sigma)).*Data, 2);
prob = exp(-0.5*prob) / sqrt((2*pi)^nbVar * (abs(det(Sigma))+realmin));


function [termMats,alreadyHomogenized]=homogenizeMultiDimPolys(termMats,makeProjTransform)
%%HOMOGENIZEMULTIDIMPOLYS Given a system of multivariate polynomials,
%              produce a homogenized system. The degree of a monomial term
%              c*x1^a1*x2^a2*...xn^an for a1...an>=0 is the sum of all
%              a1...an. Most multivariate polynomials will contain terms of
%              different powers. This function adds an extra variable so
%              that all of the terms have the same power. That is for each
%              polynomial f(x1,x2,...,xn), the homogenized polynomial is
%              x0^d*f(x1/x0,x2/x0,...,xn/x0), where d is the highest degree
%              of any monomial term in the polynomial.
%
%INPUTS: termMats Either a single term matrix of a cell array containing
%           multiple term matrices. Each term matrix is An (n+1)XnumTerms
%           matrix such that termMat(:,i)=[c,a1,a2,...,an] is a monomial
%           term where c is the value of of the monomial coefficient and
%           the monomial is x1^(a1-1)*x2^(a2-1)*x3^(a3-1)...xn^(an-1). The
%           number of variables and the maximum degree need not be the same
%           for each term matrix. Differing numbers of variables implies
%           that the missing coefficients all have zero exponents.
% makeProjTransform An optional  boolean variable indicating whether the
%           final output system should be a projective transformation of
%           the input system. In such an instance, a cell array must be
%           returned as termMats is expanded by one equation, which is a
%           linear function consisting of random complex numbers times each
%           of the variables. As noted in Section 8 of [1], for a system of
%           n simultaneous polynomial equations in n unknowns, the
%           homogenized system/ projective transform system has a number of
%           solutions exactly equal to the B�zout bound and has no
%           solutions at infinity. If omitted or an empty matrix is passed,
%           the default is false.
%
%OUTPUTS: termMats The homogenized equations. If a sinle term matrix is
%            passed, then this is a matrix. otherwise, this is a cell array
%            of term matrices like the input. All of the term matrices now
%            contain the same number of variables (with zeros for unused
%            variables) with one more variable than the equation with the
%            most variables on the input. This new variable is the
%            homogenizing variable.
%  alreadyHomogenized A boolean value indicating that the input system was
%            already homogenized. In such an instance, all exponents of
%            the added homogenization variable in the retunred system are
%            zero.
%
%Homogenization of multivariate polynomial systems is often used in
%multivariate polynomial solving algorithms to better handle "solutions at
%infinite", which are generally not solutions that one cares about. For
%example, an application of homogenizing multivariate polynomials is in
%Section 8 of [1].
%
%EXAMPLE:
%Consider four equations in four unknowns.
% termMats=cell(4,1);
% termMats{1}=string2Terms('x1*x3-2*x2*x3-6*x1-x2-4*x4+12');
% termMats{2}=string2Terms('x1*x3-3*x2*x3-7*x1+12');
% termMats{3}=string2Terms('x1*x4^3-2*x1*x2-6*x4-x2+12');
% termMats{4}=string2Terms('x1^2+x2^2+x3^2+x4^2-6');
% [termMats1,alreadyHomogenized]=homogenizeMultiDimPolys(termMats)
% %The new system will correspond to
% %'x1*x3-2*x2*x3-6*x1*x5-x2*x5-4*x4*x5+12*x5^2'
% %'x2*x3-3*x3*x4-7*x1*x5+12*x5^2'
% %'x1*x4^3-2*x1*x2*x5^2-6*x4*x5^3-1*x2*x5^3+12*x5^4'
% %'x1^2+x2^2+x3^2+x4^2-6*x5^2'
% %The projective transformed solution is
% [termMats2,alreadyHomogenized]=homogenizeMultiDimPolys(termMats,true)
% %It is the same as the above solution except an extra equation consisting
% %of
% % 'c1*x1+c2*x2+c3*x3+c4*x4+c5*x5'
% %has been added, where c1...c5 are random complex numbers (with both
% %components between 0 and 1).
%
%REFERENCES:
%[1] L. T. Watson, S. C. Billups, and A. P. Morgan, "Algorithm 652 HOMPACK:
%    A suit of codes for globally convergent homotopy algorithms," ACM
%    Transactions on Mathematical Software, vol. 13, no. 3, pp. 281-310,
%    Sep. 1987.
%
%March 2016 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<2||isempty(makeProjTransform))
   makeProjTransform=false;
end

isCell=true;
%If only a single matrix is passed.
if(~isa(termMats,'cell'))
    isCell=false;
    termMats={termMats};%Put it in a cell array.
end

numPoly=length(termMats);

%Determine the maximum number of variables.
n=0;
for curPoly=1:numPoly
   n=max([n,size(termMats{curPoly},1)-1]);
end

alreadyHomogenized=false;
for curPoly=1:numPoly
    termMat=termMats{curPoly};

    %The degrees of the terms.
    dTerms=sum(termMat(2:end,:),1);

    %The total degree of the polynomial.
    d=max(dTerms);

    numTerms=size(termMat,2);

    nCur=size(termMats,1)-1;

    %Augment to make have the same number of variables as the equation with
    %the most variables, plus one extra for the homogenization.
    termMat=[termMat;zeros(n-nCur,numTerms)];

    for i=1:numTerms
        %The degree of the term.
        deg=dTerms(i);

        %The homogenization makes all terms of degree d
        diff=d-deg;
        termMat(end,i)=diff;
        alreadyHomogenized=alreadyHomogenized||(d-deg~=0);
    end

    termMats{curPoly}=termMat;
end
alreadyHomogenized=~alreadyHomogenized;

%If only a single equation was passed as a matrix, not a cell array, then
%return a matrix.
if(isCell==false&&makeProjTransform==false)
    termMats=termMats{1};
    return;
end

if(makeProjTransform)
    termMat=zeros(n+2,n+1);

    termMat(1,:)=rand(1,n+1)+1j*rand(1,n+1);
    termMat(2:end,:)=eye(n+1,n+1);

    termMats{end+1}=termMat;
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 [en,U,lam] = kentropy(X, A1, A2, A3, A4)
% Quadratic Renyi Entropy for a kernel based estimator
%
% Given the eigenvectors and the eigenvalues of the kernel matrix, the entropy is computed by
%
% >> H = kentropy(X, U, lam)
%
% The eigenvalue decomposition can also be computed (or
% approximated) implicitly:
%
% >> H = kentropy(X, kernel, sig2)
%
%
% Full syntax
%
% >> H = kentropy(X, kernel, kernel_par)
% >> H = kentropy(X, kernel, kernel_par, type)
% >> H = kentropy(X, kernel, kernel_par, type, nb)
%
%       Outputs
%         H          : Quadratic Renyi entropy of the kernel matrix
%       Inputs
%         X          : N x d matrix with the training data
%         kernel     : Kernel type (e.g. 'RBF_kernel')
%         kernel_par : Kernel parameter (bandwidth in the case of the 'RBF_kernel')
%         type(*)    : 'eig'(*), 'eigs', 'eign'
%         nb(*)      : Number of eigenvalues/eigenvectors used in the eigenvalue decomposition approximation
%
%
% >> H = kentropy(X, U, lam)
%
%       Outputs
%         H   : Quadratic Renyi entropy of the kernel matrix
%       Inputs
%         X   : N x d matrix with the training data
%         U   : N x nb matrix with principal eigenvectors
%         lam : nb x 1 vector with eigenvalues of principal components
%
% See also:
%   kernel_matrix, RBF_kernel, demo_fixedsize

% Copyright (c) 2011,  KULeuven-ESAT-SCD, License & help @ http://www.esat.kuleuven.be/sista/lssvmlab

n= size(X,1);

if isstr(A1), % kernel_matrix

  kernel = A1;
  kernel_par = A2;
  eval('etype = A3;','etype =''eig'';');
  if ~(strcmp(etype, 'eig') |strcmp(etype, 'eigs') |strcmp(etype,'eign')),
    error('type has to be ''eig'', ''eigs'' or ''eign''...');
  end
  eval('nb = A4;',' ');

  if strcmp(etype,'eign'),
    eval('[U,lam] = eign(X,kernel,kernel_par,nb);','[U,lam] = eign(X,kernel,kernel_par);');
  else
    omega = kernel_matrix(X, kernel, kernel_par);
    eval('[U,lam] = feval(etype,omega,nb);','[U,lam] = feval(etype,omega);');
    if size(lam,1)==size(lam,2), lam = diag(lam); end
    %onen = ones(n,1)./n; en = -log(onen'*omega*onen);
  end

else
  U = A1;
  lam = A2;
end
en = -log((sum(U,1)/n).^2 * lam);


function s = ellipsoidSurfaceArea(elli)
%ELLIPSOIDSURFACEAREA  Approximated surface area of an ellipsoid.
%
%   S = ellipsoidSurfaceArea(ELLI)
%   Computes an approximation of the surface area of an ellipsoid.
%   ELLI is a 1-by-9 row vector given by [XC YC ZC A B C THETA PHI PSI],
%   where (XC YC ZC) is the center, (A B C) is the length of each semi axis
%   and (THETA PHI PSI) representes the orientation.
%   If ELLI is a 1-by-3 row vector, it is assumed to contain only the
%   lengths of semi-axes.
%
%   This functions computes an approximation of the surface area, given by:
%   S = 4 * pi * ( (a^p * b^p + a^p * c^p + b^p * c^p) / 3) ^ (1/p)
%   with p = 1.6075. The resulting error should be less than 1.061%.
%
%   Example
%   ellipsoidSurfaceArea
%
%   See also
%   geom3d, ellipsePerimeter, oblateSurfaceArea, prolateSurfaceArea
%
%   References
%   * http://en.wikipedia.org/wiki/Ellipsoid
%   * http://mathworld.wolfram.com/Ellipsoid.html
%

% ------
% Author: David Legland
% E-mail: david.legland@grignon.inra.fr
% Created: 2012-02-24, using Matlab 7.9.0.529 (R2009b)
% Copyright 2012-2022 INRA - Cepia Software Platform

%% Parse input argument

if size(elli, 2) == 9
    a = elli(:, 4);
    b = elli(:, 5);
    c = elli(:, 6);

elseif size(elli, 2) == 3
    a = elli(:, 1);
    b = elli(:, 2);
    c = elli(:, 3);
end

p = 1.6075;
s = 4 * pi * ( (a.^p .* b.^p + a.^p .* c.^p + b.^p .* c.^p) / 3) .^ (1 / p);


% Euclidean projection on the nonnegative orthant
% Section 8.1.1, Boyd & Vandenberghe "Convex Optimization"
% Joelle Skaf - 10/07/05
%
% The projection of x0 on the proper cone K = R+^n is given by
%           minimize || x - x0 ||^2
%               s.t.    x >= 0
% It is also given by: P_K(x0)_k = max{x0_k,0}

% Input data
randn('seed',0);
n  = 10;
x0 = randn(n,1);

fprintf(1,'Computing the analytical solution...');

% Analytical solution
pk_x0 = max(x0,0);

fprintf(1,'Done! \n');

% Solution via CVX
fprintf(1,'Computing the solution via a QP...');

cvx_begin quiet
    variable x(n)
    minimize ( norm(x - x0) )
    x >= 0; %#ok
cvx_end

fprintf(1,'Done! \n');

% Verification
disp('-----------------------------------------------------------------');
disp('Verifying that the analytical solution and the solution obtained via QP are equal: ');
disp([pk_x0 x])
disp('They should be equal!');


function quad = fibonacci_lattice_q2 ( k, f )

%*****************************************************************************80
%
%% FIBONACCI_LATTICE_Q2 applies a Fibonacci lattice integration rule in 2D.
%
%  Discussion:
%
%    This is a modification of the algorithm in FIBONACCI_LATTICE_Q.
%    It uses a nonlinear transformation on the integrand, which makes
%    the lattice rule more suitable for nonperiodic integrands.
%
%    The transformation replaces the integration variable X by
%
%      PHI(X) = 3*X^3 *( 10 - 15 * X + 6 * X^2 )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 November 2008
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Ian Sloan, Stephen Joe,
%    Lattice Methods for Multiple Integration,
%    Oxford, 1994,
%    ISBN: 0198534728,
%    LC: QA311.S56
%
%  Parameters:
%
%    Input, integer K, the index of the Fibonacci number to be used.
%    K must be at least 3.
%
%    Input, external real F, the name of the user-supplied routine
%    which evaluates the function, of the form:
%    function f ( dim_num, x )
%    integer dim_num
%    real f
%    real x(dim_num)
%    f = ...
%
%    Output, real QUAD, the estimated integral.
%
  dim_num = 2;

  quad = 0.0;

  m = fibonacci ( k );

  z(1) = 1;
  z(2) = fibonacci ( k - 1 );

  for j = 0 : m - 1
    x(1:dim_num) = mod ( j * z(1:dim_num) / m, 1.0 );
    dphi = 1.0;
    for i = 1 : dim_num
      y(i) = ( 10.0 - 15.0 * x(i) + 6.0 * x(i)^2 ) * x(i)^3;
      dphi = dphi * 30.0 * ( 1.0 - x(i) )^2 * x(i)^2;
    end
    quad = quad + f ( dim_num, y ) * dphi;
  end

  quad = quad / m;

  return
end


classdef Quadrature_Quadrilateral < Quadrature

    methods (Access = public)
        function computeQuadrature(obj,order)
            computeQuadrature@Quadrature(obj,order);
            switch order
                case 'CONSTANT'
                    obj.ngaus = 1;
                    obj.posgp(:,1) = [0,0];
                    obj.weigp = 4;

                case 'LINEAR'
                    obj.ngaus = 4;
                    % Compute WEIGP and POSGP
                    a =  0.577350269189626;
                    obj.posgp(:,1) = [-a,-a];
                    obj.posgp(:,2) = [+a,-a];
                    obj.posgp(:,3) = [-a,+a];
                    obj.posgp(:,4) = [+a,+a];

                    obj.weigp =  [1,1,1,1];%1*ones(1,obj.ngaus);

                case 'QUADRATIC' %SERENDIPITY, QUADRILATERAL QUADRATIC NOT IMPLEMENTED
                    % Copied from down below
                    obj.ngaus = 9;
                    % Compute WEIGP and POSGP
                    a =  0.77459667;
                    obj.posgp(:,1) = [ 0,+a];
                    obj.posgp(:,2) = [ 0, 0];
                    obj.posgp(:,3) = [+a,+a];
                    obj.posgp(:,4) = [-a,-a];
                    obj.posgp(:,5) = [-a, 0];
                    obj.posgp(:,6) = [+a, 0];
                    obj.posgp(:,7) = [+a,-a];
                    obj.posgp(:,8) = [-a,+a];
                    obj.posgp(:,9) = [ 0,-a];

                    obj.weigp =(4/9)*ones(1,obj.ngaus);

                case 'QUADRATICMSS' %SERENDIPITY, QUADRILATERAL QUADRATIC NOT IMPLEMENTED
                    obj.ngaus = 9;
                    % Compute WEIGP and POSGP
                    a =  0.77459667;
                    obj.posgp(:,1) = [ 0,+a];
                    obj.posgp(:,2) = [ 0, 0];
                    obj.posgp(:,3) = [+a,+a];
                    obj.posgp(:,4) = [-a,-a];
                    obj.posgp(:,5) = [-a, 0];
                    obj.posgp(:,6) = [+a, 0];
                    obj.posgp(:,7) = [+a,-a];
                    obj.posgp(:,8) = [-a,+a];
                    obj.posgp(:,9) = [ 0,-a];

                    obj.weigp =(4/9)*ones(1,obj.ngaus);

                case 'QUADRATICMASS'
                    posgl(1) =-0.774596669241483;
                    posgl(2) = 0.0;
                    posgl(3) = 0.774596669241483;
                    weigl(1) = 0.555555555555556;
                    weigl(2) = 0.888888888888889;
                    weigl(3) = 0.555555555555556;
                    obj.ngaus = 9;
                    igaus = 0;
                    nlocs = 3;
                    for ilocs = 1:nlocs
                        for jlocs = 1:nlocs
                            igaus = igaus+1;
                            obj.weigp(  igaus) = weigl(ilocs)*weigl(jlocs);
                            obj.posgp(1,igaus) = posgl(ilocs);
                            obj.posgp(2,igaus) = posgl(jlocs);
                        end
                    end

                otherwise
                    error('Invalid interpolation order for element Quadrilateral.');
            end
        end
    end
end


function [VIn,MIn] = partition_distance(Cx,Cy)
%PARTITION_DISTANCE     Distance between community partitions
%
%   This function quantifies the distance between pairs of community
%   partitions with information theoretic measures.
%
%   VIn       = partition_distance(Cx,Cy)
%   [VIn MIn] = partition_distance(Cx,Cy)
%
%   Inputs:         Cx,         Community affiliation vector X
%                   Cy,         Community affiliation vector Y
%
%   Outputs:        VIn,        Normalized variation of information
%                   MIn,        Normalized mutual information
%
%   (Definitions:
%       VIn = [H(X) + H(Y) - 2MI(X,Y)]/log(n)
%       MIn = 2MI(X,Y)/[H(X)+H(Y)]
%    where H is entropy, MI is mutual information and n is number of nodes)
%
%   Reference: Meila M (2007) J Multivar Anal 98, 873-895.
%
%   2011, Mika Rubinov, UNSW

%   Modification History:
%   Mar 2011: Original

%#ok<*ASGLU>

n = numel(Cx);                                  %n

[dum,dum,Cx]  = unique(Cx);
[dum,dum,Cy]  = unique(Cy);
[dum,dum,Cxy] = unique([Cx(:) Cy(:)],'rows');

Px  = hist(Cx,1:max(Cx))/n;                     %P(x)
Py  = hist(Cy,1:max(Cy))/n;                     %P(y)
Pxy = hist(Cxy,1:max(Cxy))/n;                   %P(x,y)

Hx  = -sum(Px.*log(Px));                        %H(x)
Hy  = -sum(Py.*log(Py));                        %H(y)
Hxy = -sum(Pxy.*log(Pxy));                      %H(x,y)

VIn = (2*Hxy-Hx-Hy)/log(n);                     %VIn
MIn = 2*(Hx+Hy-Hxy)/(Hx+Hy);                    %MIn


function result = fit_ML_log_normal( x,hAx )
% fit_ML_normal - Maximum Likelihood fit of the log-normal distribution of i.i.d. samples!.
%                  Given the samples of a log-normal distribution, the PDF parameter is found
%
%    fits data to the probability of the form:
%        p(x) = sqrt(1/(2*pi))/(s*x)*exp(- (log(x-m)^2)/(2*s^2))
%    with parameters: m,s
%
% format:   result = fit_ML_log_normal( x,hAx )
%
% input:    x   - vector, samples with log-normal distribution to be parameterized
%           hAx - handle of an axis, on which the fitted distribution is plotted
%                 if h is given empty, a figure is created.
%
% output:   result  - structure with the fields
%                      m,s          - fitted parameters
%                      CRB_m,CRB_s  - Cram?r-Rao Bound for the estimator value
%                      RMS          - RMS error of the estimation
%                      type         - 'ML'
%

%
% Algorithm
% ===========
%
% We use the ML algorithm to estimate the PDF from the samples.
% The log-normal destribution is given by:
%
%    p(x;m,s) = sqrt(1/(2*pi))/(s*x)*exp(- (log(x-m)^2)/(2*s^2))
%
%    where x are the samples which distribute by the function p(x;m,s)
%            and are assumed to be i.i.d !!!
%
% The ML estimator is given by:
%
%    a         = parameters vector = [m,s]
%    f(Xn,a)   = sqrt(1/(2*pi))/(s*Xn)*exp(- (log(Xn-m)^2)/(2*s^2))
%    L(a)      = f(X,a) = product_by_n( f(Xn,a) )
%              = (2*pi*s^2)^(-N/2) * PI{1/Xn} * exp(-sum((log(Xn)-m)^2)/(2*s^2))
%    log(L(a)) = -N/2*log(2*pi) - N*log(s) - sum(log(Xn)) - sum((log(Xn)-m)^2)/(2*s^2)
%
%    The maximum likelihood point is found by the derivative of log(L(a)) with respect to "a":
%
%    diff(log(L(a)),s^2) = N/(2*s^4) * ( sum( (log(Xn)-m)^2 )/N - s^2 )
%                        = J(s^2) * (s^2_estimation - s^2)
%    diff(log(L(a)),m)   = 2*N/(s^2) * ( sum(log(Xn))/N - m )
%                        = J(m) * (m_estimator - m)
%
%    Therefore, the (efficient) estimators are given by:
%
%               m   = sum( log( Xn ) )/N
%               s^2 = sum(( log(Xn)-m)^2)/N
%
%    The Cram?r-Rao Bounds for these estimator are:
%
%               VAR( m )   = 1/J(m)   = (s^2) / N
%               VAR( s^2 ) = 1/J(s^2) = (2*s^4) / N
%
%    NOTE: the ML estimator does not detect a deviation from the model.
%          therefore, check the RMS value !
%

if (nargin<1)
    error( 'fit_ML_log_normal - insufficient input arguments' );
end

% Estimation
% =============
lnx     = log(x(:));                 % should be column vectors !
N       = length(x);
m       = sum( lnx )/N;
s2      = (lnx-m)'*(lnx-m)/N;
CRB_m   = s2 / N;
CRB_s2  = (2*s2^2) / N;
[n,x_c] = hist( x,100 );
n       = n / sum(n*abs(x_c(2)-x_c(1)));
y       = sqrt(1/(2*pi))./(sqrt(s2)*x_c).*exp(- ((log(x_c)-m).^2)/(2*s2));
RMS     = sqrt( (y-n)*((y-n)')/ (x_c(2)-x_c(1))^2 / (length(x_c)-1) );

% finish summarizing results
% ============================
result = struct( 'm',m,'s2',s2,'CRB_m',CRB_m,'CRB_s2',CRB_s2,'RMS',RMS,'type','ML' );

% plot distribution if asked for
% ===============================
if (nargin>1)
    xspan = linspace(min(x),max(x),100);
    if ishandle( hAx )
        plot_log_normal( xspan,result,hAx,1 );
    else
        figure;
        plot_log_normal( xspan,result,gca,1 );
    end
end


function [X,E0,R0]=totalLeastSquares(A,B,d,t)
%%TOTALLEASTSQUARES Solve the total least squares problem. That is, given
%          an mXn matrix A and an mXk matrix or vector B, find the an nXk
%          matrix or vector X such that (A+E0)*X=(B+R0), where the error
%          terms E0 and R0 are chosen to minimize the Frobenius norm of
%          D*[E0,R0]*T where D=diag(d) and T=diag(t) are nonsingular
%          diagonal matrices. This problem is essentially just solving
%          A*X=B for X where both A and B can be noisy, whereas the normal
%          least squares problem solves for the case where only B is noisy.
%
%INPUTS: A A real mXn matrix.
%        B A real nXk matrix.
%        d Optional  mX1 vector of real diagonal elements for the matrix D,
%          which affects how the errors are weighted. If omitted, a vector
%          of ones is used (D is just an identity matrix).
%        t Optional (n+k)X1 vector of real diagonal elements for the matrix
%          T, which affects show errors are weighted. If omitted, a vector
%          of ones is used (T is just an identity matrix).
%
%OUTPUTS: X The nXk real solution of the total least squares problem.
%     E0,R0 The error matrices associated with the solution to the problem.
%           They are such that (A+E0)*X=(B+R0) and the Frobenius norm of
%           D*[E0,R0]*T, which is computed via norm(D*[E0,R0]*T,'fro'), is
%           minimized.
%
%The algorithm for solving the total least squares problem is taken from
%Chapter 6.3.1 of [1].
%
%REFERENCES:
%[1] G. H. Golub and C. F. Van Loan, Matrix Computations, 4th ed.
%    Baltimore: Johns Hopkins University Press, 2013.
%
%April 2015 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

m=size(A,1);
n=size(A,2);
k=size(B,2);

if(nargin<4)
    t=ones(n+k,1);
end

if(nargin<3)
    d=ones(m,1);
end

D=diag(d);
T=diag(t);

[U,Sigma,V]=svd(D*[A,B]*T);

V12=V(1:n,(n+1:end));
V22=V((n+1):end,(n+1):end);

T1=diag(t(1:n));
T2=diag(t((n+1):end));

X=-T1*V12/V22/T2;

if(nargout>1)
    U2=U(:,(n+1):end);
    Sigma2=Sigma((n+1):end,(n+1):end);

    ERMat=-D\(U2*Sigma2*[V12',V22'])/T;

    E0=ERMat(:,1:n);
    R0=ERMat(:,(n+1):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 [Xsol, Ssol] = generalized_eigenvalue_computation(A, B, p)
% Returns orthonormal basis of the dominant invariant p-subspace of B^-1 A.
%
% function [Xsol, Ssol] = generalized_eigenvalue_computation(A, B, p)
%
% Input: A is a real, symmetric matrix of size nxn,
%        B is a symmetric positive definite matrix, same size as A, and
%        an integer p < n.
% Output: Xsol: a real, orthonormal matrix X of size nxp such that
%         trace(X'*A*X) is maximized, subject to X'*B*X being identity.
%         That is, the columns of X form an orthonormal basis of a dominant
%         subspace of dimension p of B^(-1)*A. These are thus eigenvectors
%         associated with the largest eigenvalues of B^(-1)*A  (in no
%         particular order). Sign is important: 2 is deemed a larger
%         eigenvalue than -5.
%         Ssol: the eigenvalues associated with the eigenvectors Xsol.
%
% We intend to solve the homogeneous system A*X = B*X*S,
% where S is a diagonal matrix of dominant eigenvalues of B^-1 A.
%
%
% The optimization is performed on the generalized Grassmann manifold,
% since only the space spanned by the columns of X matters.
%
% The optimization problem that we are solving here is
% maximize trace(X'*A*X) subject to X'*B*X = eye(p).
% Consequently, the solutions remain invariant to transformation
% X --> XO, where O is a p-by-p orthogonal matrix. The search space, in
% essence, is set of equivalence classes
% [X] = {XO : X'*B*X = I and O is orthogonal matrix}. This space is called
% the generalized Grassmann manifold.
%
% See also dominant_invariant_subspace nonlinear_eigenspace

% This file is part of Manopt and is copyrighted. See the license file.
%
% Main author: Bamdev Mishra, June 30, 2015.
% Contributors:
% Change log:

    % Generate some random data to test the function
    if ~exist('A', 'var') || isempty(A)
        n = 128;
        A = randn(n);
        A = (A+A')/2;
    end
    if ~exist('B', 'var') || isempty(B)
        n = size(A, 1);
        e = ones(n, 1);
        B = spdiags([-e 2*e -e], -1:1, n, n); % Symmetric positive definite
    end

    if ~exist('p', 'var') || isempty(p)
        p = 3;
    end

    % Make sure the input matrix is square and symmetric
    n = size(A, 1);
	assert(isreal(A), 'A must be real.')
    assert(size(A, 2) == n, 'A must be square.');
    assert(norm(A-A', 'fro') < n*eps, 'A must be symmetric.');
	assert(p <= n, 'p must be smaller than n.');

    % Define the cost and its derivatives on the generalized
    % Grassmann manifold, i.e., the column space of all X such that
    % X'*B*X is identity.
    gGr = grassmanngeneralizedfactory(n, p, B);

    problem.M = gGr;
    problem.cost  = @(X)    -trace(X'*A*X);
    problem.egrad = @(X)    -2*(A*X); % Only Euclidean gradient needed.
    problem.ehess = @(X, H) -2*(A*H); % Only Euclidean Hessian needed.

    % Execute some checks on the derivatives for early debugging.
    % These things can be commented out of course.
    % checkgradient(problem);
    % pause;
    % checkhessian(problem);
    % pause;

    % Issue a call to a solver. A random initial guess will be chosen and
    % default options are selected except for the ones we specify here.
    options.Delta_bar = 8*sqrt(p);
    [Xsol, costXsol, info] = trustregions(problem, [], options); %#ok<NASGU,ASGLU>

    % To extract the eigenvalues, solve the small p-by-p symmetric
    % eigenvalue problem.
    Ssol = eig(Xsol'*(A*Xsol));

end


function cdf = beta_cdf ( x, a, b )

%*****************************************************************************80
%
%% BETA_CDF evaluates the Beta CDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the argument of the CDF.
%
%    Input, real A, B, the parameters of the PDF.
%    0.0D+00 < A,
%    0.0D+00 < B.
%
%    Output, real CDF, the value of the CDF.
%
  if ( x <= 0.0 )
    cdf = 0.0;
  elseif ( x <= 1.0 )
    cdf = beta_inc ( a, b, x );
  else
    cdf = 1.0;
  end

  return
end


function value = triangle_orientation_2d ( t )

%*****************************************************************************80
%
%% TRIANGLE_ORIENTATION_2D determines the orientation of a triangle in 2D.
%
%  Discussion:
%
%    Three distinct non-colinear points in the plane define a circle.
%    If the points are visited in the order P1, P2, and then
%    P3, this motion defines a clockwise or counterclockwise
%    rotation along the circle.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 July 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real T(2,3), the triangle vertices.
%
%    Output, integer VALUE, reports if the three points lie
%    clockwise on the circle that passes through them.  The possible
%    return values are:
%    0, the points are distinct, noncolinear, and lie counterclockwise
%    on their circle.
%    1, the points are distinct, noncolinear, and lie clockwise
%    on their circle.
%    2, the points are distinct and colinear.
%    3, at least two of the points are identical.
%
  dim_num = 2;

  if ( all ( t(1:dim_num,1) == t(1:dim_num,2) ) | ...
       all ( t(1:dim_num,2) == t(1:dim_num,3) ) | ...
       all ( t(1:dim_num,3) == t(1:dim_num,1) ) )
    value = 3;
    return
  end

  det = ( t(1,1) - t(1,3) ) * ( t(2,2) - t(2,3) ) ...
      - ( t(1,2) - t(1,3) ) * ( t(2,1) - t(2,3) );

  if ( det == 0.0 )
    value = 2;
  elseif ( det < 0.0 )
    value = 1;
  elseif ( 0.0 < det )
    value = 0;
  end

  return
end


function anss = rombquad(f,a,b,m)
%ROMBQUAD(f,a,b,m) evaluates the integral of f from a to b.
% f is an inline function or function handle.
% a is the lower limit of integration.
% b is the upper limit of integration.
% m - is the exponent in the relative error.  For example m = 10 implies an
% estimated relative error of 1e-10.
%
% Example:
%
%           f = @(x) x.^2; % Vectoized function handle.
%           rombquad(f,0,2); % The integral from 0 to 2.
%
% See also quad, quadl, quadv and gaussquad (on the FEX)
%
% Author:  Matt Fig
% Contact:  popkenai@yahoo.com

if nargin<3
   error ('Not enough arguments. See help.')
elseif nargin<4 || floor(m)~=m || m <1
    m = 10;
end

if isinf(a) || isinf(b)
   error('Infinite limits not allowed.')
end

h = 2.^((1:m)-1)*(b-a)/2^(m-1);             % These are the intervals used.
k1 = 2.^((m-2):-1:-1)*2+1;                  % Index into the intervals.
f1 = feval(f,a:h(1):b);                     % Function evaluations.
R = zeros(1,m);                             % Pre-allocation.
% Define the starting vector:
for ii = 1:m
	R(ii) = 0.5*h(ii)*(f1(1)+2*...
            sum(f1(k1(end-ii+1):k1(end-ii+1)-1:end-1)) + f1(end));
end
% Interpolations:
for jj = 2:m
    jpower = (4^(jj-1)-1);
    for kk = 1:(m-jj+1)
        R(kk) = R(kk)+(R(kk)-R(kk+1))/jpower;
    end
end
anss = R(1);


% vgg_wedge  Wedge product of N-1 N-vectors (generalization of cross product).
%
% Y = vgg_wedge(X)  Wedge product of columns/rows of X.
%   Y ... double (1,N).
%   X ... double (N,N-1).
% It is Y = X(:,1) \wedge X(:,2) \wedge ... \wedge X(:,N-1). For N=3,
% wedge product is the same as cross (vector) product. E.g., for N=4,
% wedge product of three 4-vectors is in fact computation of a plane in
% 3-D projective space from 3 points in the plane.
% The sign is chosen so that for any square matrix X it is: det(X) == wedge(X(:,1:end-1))*X(:,end)
% Works also dually for
%   Y ... double (N,1).
%   X ... double (N-1,N).
%
% Y = vgg_wedge(X_1,X_2,...,X_{N-1})  Wedge product for each (N-1)-tuple of corresponding columns of X_n.
%   X_n ... double (N,K)
%   Y ... double (K,N)
% Equivalent to
%   for k = 1:K, Y(k,:) = wedge([X_1(:,k) ... X_{N-1}(:,k)]); end
% E.g.: wedge(X1,X2) is the same as cross(X1,X2)' but faster.
% Dual form is not available.

function Y = vgg_wedge(varargin)

if nargin == 1

  X = varargin{1};

  [N,Nm1] = size(X);
  if Nm1>N
    Y = vgg_wedge(X')';
    return
  end

  switch N
   case 3 % make it faster for special case N==3
    Y = [X(2,1).*X(3,2)-X(3,1).*X(2,2),...
         X(3,1).*X(1,2)-X(1,1).*X(3,2),...
         X(1,1).*X(2,2)-X(2,1).*X(1,2)];
   otherwise
    for n = 1:N
      Y(n) = (-1)^(n+N)*det(X([1:n-1 n+1:N],:));
    end
  end

else

  N = nargin + 1;
  switch N
   case 3 % make it faster for special case N==3
    X1 = varargin{1};
    X2 = varargin{2};
    Y = [(X1(2,:).*X2(3,:)-X1(3,:).*X2(2,:))',...
         (X1(3,:).*X2(1,:)-X1(1,:).*X2(3,:))',...
         (X1(1,:).*X2(2,:)-X1(2,:).*X2(1,:))'];
   otherwise
    for k = 1:size(varargin{1},2)
      for n = 1:N-1
	X(:,n) = varargin{n}(:,k);
      end
      Y(k,:) = vgg_wedge(X);
    end
  end

end

return


function pdf = beta_pdf(x, a, b)
% PURPOSE: pdf of the beta(a,b) distribution
%--------------------------------------------------------------
% USAGE: pdf = beta_pdf(x,a,b)
% where:   x = vector of components
%          a = beta distribution parameter, a = scalar
%          b = beta distribution parameter  b = scalar
% NOTE: mean[(beta(a,b)] = a/(a+b), variance = ab/((a+b)*(a+b)*(a+b+1))
%--------------------------------------------------------------
% RETURNS: pdf at each element of x of the beta(a,b) distribution
%--------------------------------------------------------------
% SEE ALSO: beta_d, beta_pdf, beta_inv, beta_rnd
%--------------------------------------------------------------

%       Anders Holtsberg, 18-11-93
%       Copyright (c) Anders Holtsberg
% documentation modified by LeSage to
% match the format of the econometrics toolbox

if (nargin ~=3)
    error('Wrong # of arguments to beta_pdf');
end

if any(any((a<=0)|(b<=0)))
   error('Parameter a or b is nonpositive');
end

I = find((x<0)|(x>1));

pdf = x.^(a-1) .* (1-x).^(b-1) ./ beta(a,b);
pdf(I) = 0*I;


function theta = deg2rad(omega)

% DEG2RAD Transform degrees to radians.
% FORMAT
% DESC onverts degrees to radians.
% ARG omega : angle in degrees.
% ARG theta : angle in radians.
%
% COPYRIGHT : Neil D. Lawrence, 2005

% NDLUTIL

theta = omega/180*pi;


function y = acoshplus1(x)
%ACOSHPLUS1 Inverse hyperbolic cosine of argument plus one.
%
%   ACOSHPLUS1(X) is ACOSH(X+1) calculated in a way that is numerically better
%   when X is close to one.
%
%   This illustrates the difference
%
%      x = 2e-15*(0:0.01:1);
%      plot(x, acosh(x+1), 'b-', x, acoshplus1(x), 'r-');
%
%   See also COSHMINUS1.

%   Author:      Peter J. Acklam
%   Time-stamp:  2003-10-13 14:54:17 +0200
%   E-mail:      pjacklam@online.no
%   URL:         http://home.online.no/~pjacklam

   % check number of input arguments
   error(nargchk(1, 1, nargin));

   y = 2 * asinh(sqrt(x / 2));


function geometry_test060 ( )

%*****************************************************************************80
%
%% TEST060 tests PLANE_IMP_TRIANGLE_INT_3D.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 April 2009
%
%  Author:
%
%    John Burkardt
%
  dim_num = 3;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST060\n' );
  fprintf ( 1, '  PLANE_IMP_TRIANGLE_INT_3D finds the\n' );
  fprintf ( 1, '    intersection points of an implicit plane\n' );
  fprintf ( 1, '    and a triangle.\n' );

  a = 1.0;
  b = -2.0;
  c = -3.0;
  d = 6.0;

  fprintf ( 1, '\n' );
  fprintf ( 1, '  The implicit plane: A*X + B*Y + C*Z + D = 0.\n' );
  fprintf ( 1, '  A,B,C,D = %f  %f  %f  %f\n', a, b, c, d );

  for i = 1 : 4

    if ( i == 1 )
      t(1:dim_num,1:3) = [ ...
         3.0,  0.0, -7.0; ...
        13.0, -4.0, -1.0; ...
         5.0,  1.0, -2.0 ]';
    elseif ( i == 2 )
      t(1:dim_num,1:3) = [ ...
         3.0,  0.0, -7.0; ...
        13.0, -4.0, -1.0; ...
         9.0,  3.0,  8.0 ]';
    elseif ( i == 3 )
      t(1:dim_num,1:3) = [ ...
        -6.0,  0.0,  0.0; ...
         0.0,  3.0,  0.0; ...
         0.0,  0.0,  2.0 ]';
    elseif ( i == 4 )
      t(1:dim_num,1:3) = [ ...
        -4.0,  1.0,  0.0; ...
         0.0,  6.0, -2.0; ...
         0.0,  0.0,  1.0 ]';
    end

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Case %d\n', i );

    r8mat_transpose_print ( dim_num, 3, t, '  Triangle vertices:' );

    [ num_int, pint ] = plane_imp_triangle_int_3d ( a, b, c, d, t );

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Number of intersection points is %d\n', num_int );

    r8mat_transpose_print ( dim_num, num_int, pint, '  Intersection points:' );

  end

  return
end


function D = diffmat(n, p)
%DIFFMAT  Trigonometric differentiation matrix.
%   D = DIFFMAT(N) is the matrix that maps function values at N equally-spaced
%   points in [0 2*pi) to values of the derivative of the Fourier interpolant
%   at those points.
%
%   D = DIFFMAT(N, K) is the same, but for the Kth derivative.
%
% See also DIFF.

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

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% References for the rectangular differentiation matrices:
%
% J.A.C. Weideman and S.C. Reddy, A MATLAB differentiation matrix suite, ACM
% Transcations on Mathematical Software, Vol. 26, No. 4, Page 465--519, 2000.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% grid spacing:
h = 2*pi/n;

% sign of entries in a column:
sgn = (-1).^(1:n-1).';

% indices:
n1 = floor((n-1)/2);
n2 = ceil((n-1)/2);

% grid points on [-1 0):
v = (1:n2)'*h/2;

% For different p:
if ( p == 0 )           % Zeroth-derivative
    D = eye(n);
else
    switch p
        case 1          % 1st-derivative

            % Forming the first column by 'flipping trick':
            if ( rem(n, 2) )           % n is odd
                tmp = csc(v);
                col = [0; (pi/2)*sgn.*[tmp; flipud(tmp(1:n1))]];
            else                      % n is even
                tmp = cot(v);
                col = [0; (pi/2)*sgn.*[tmp; -flipud(tmp(1:n1))]];
            end

            % Form the first row:
            row = -col;

        case 2         % 2nd-derivative

            % Form the first column by 'flipping trick':
            if ( rem(n, 2) )           % n is odd
                tmp = csc(v).*cot(v);
                col = pi^2*[-pi^2/(3*h^2)+1/12; ...
                    -0.5*sgn.*[tmp; -flipud(tmp(1:n1))]];
            else                      % n is even
                tmp = csc(v).^2;
                col = pi^2*[-pi^2/(3*h^2)-1/6; ...
                    -0.5*sgn.*[tmp; flipud(tmp(1:n1))]];
            end

            % Form the first row:
            row = col;

        otherwise      % pth-derivative for p >= 3

            % Form the first column using FFT:
            n3 = (-n/2)*rem(p+1,2)*ones(rem(n+1,2));
            waveNumber = 1i*[(0:n1) n3 (-n1:-1)];
            col = pi^p*real(ifft(waveNumber.^p.*fft(eye(1,n))));

            % Form the first row:
            if ( rem(p,2) )      % p is odd
                col = [0 col(2:n)]';
                row = -col;
            else                 % p is even
                row = col;
            end
    end

    % Form the differentiation matrix which is toeplitz:
    D = toeplitz(col, row);

end

end


function distance = cylinder_point_dist_3d ( p1, p2, r, p )

%*****************************************************************************80
%
%% CYLINDER_POINT_DIST_3D determines the distance from a cylinder to a point in 3D.
%
%  Discussion:
%
%    We are computing the distance to the SURFACE of the cylinder.
%
%    The surface of a (right) (finite) cylinder in 3D is defined by an axis,
%    which is the line segment from point P1 to P2, and a radius R.  The points
%    on the surface of the cylinder are:
%    * points at a distance R from the line through P1 and P2, and whose nearest
%      point on the line through P1 and P2 is strictly between P1 and P2,
%    PLUS
%    * points at a distance less than or equal to R from the line through P1
%      and P2, whose nearest point on the line through P1 and P2 is either
%      P1 or P2.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 August 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real P1(3), P2(3), the first and last points
%    on the axis line of the cylinder.
%
%    Input, real R, the radius of the cylinder.
%
%    Input, real P(3), the point.
%
%    Output, real DISTANCE, the distance from the point
%    to the cylinder.
%
  dim_num = 3;

  axis(1:dim_num) = p2(1:dim_num) - p1(1:dim_num);

  axis_length = r8vec_norm ( dim_num, axis );

  if ( axis_length == 0.0 )
    distance = - r8_huge ( );
    return
  end

  axis(1:dim_num) = axis(1:dim_num) / axis_length;

  p_dot_axis = ( p(1:dim_num) - p1(1:dim_num) ) * axis(1:dim_num)';
%
%  Case 1: Below bottom cap.
%
  if ( p_dot_axis <= 0.0 )

    distance = disk_point_dist_3d ( p1, r, axis, p );
%
%  Case 2: between cylinder planes.
%
  elseif ( p_dot_axis <= axis_length )

    p_length = r8vec_norm ( dim_num, p(1:dim_num) - p1(1:dim_num) );
    off_axis_component = sqrt ( p_length.^2 - p_dot_axis.^2 );

    distance = abs ( off_axis_component - r );

    if ( off_axis_component < r )
      distance = min ( distance, axis_length - p_dot_axis );
      distance = min ( distance, p_dot_axis );
    end
%
%  Case 3: Above the top cap.
%
  elseif ( axis_length < p_dot_axis )

    distance = disk_point_dist_3d ( p2, r, axis, p );

  end

  return
end


% Numerical solution for wave propagation

% Copyright 2001 P. Wesseling
% This program and its subprograms may be freely used, modified and distributed
% under the GNU General Public License: http://www.gnu.org/copyleft/gpl.html

% Theory in Section 9.3 of:

% 	P. Wesseling: Principles of Computational Fluid Dynamics
% 	Springer, Heidelberg, 2000 ISBN 3-5453-0. XII, 642 pp.
% See http://ta.twi.tudelft.nl/nw/users/wesseling/cfdbook.html

% Equation (9.34) is solved with the kappa scheme
% dy/dt + c dy/dx = 0
% Known exact solution f(x-ct)
% Boundary conditions using upwind schemes or extrapolation
% Uniform vertex-centred grid
% This program generates Figs. 9.6 and 9.7 in the book

% Functions called: exact_solution

		% ...............Input.........................................
kappa = 0;	% Parameter of kappa-scheme
c = 1;		% Velocity
sigma = 0.7;	% CFL number
J = 31;		% Number of grid cells
bc = 2;		% Governs choice of numerical boundary conditions; see page 350
		% Enter 1 for boundary conditions using upwind schemes
		%    or 2 for extrapolation using  equation (9.36)
T = 0.4;	% Final time
		% ..............End of input...................................

h = 1.0/(J-1);		% Size of grid cells
dt = sigma*h/c;		% Time step
n = floor(T/dt);	% Number of time steps

% 	Definition of grid numbering

%     x=0    			  x=1
% grid |------|------|------|------|
%      1      2      3             J

x = [0:J-1]'*h;		% Location of grid nodes

sig2 = sigma^2; sig4 = sigma/4;

ynew = zeros(J,1); yright = zeros(n+1,1);
t = 0;	yright(1) = exact_solution(t,1,c);  yold = exact_solution(t,x,c);
for i = 1:n,  t = t + dt;
  a = 2*yold(1) - yold(2);	% Extrapolated inflow value
  ynew(1) = exact_solution(t,0,c);
  if bc == 1
    ynew(2) =  yold(2) - sigma*(yold(2) - yold(1));
  else
    ynew(2) =  yold(2) +sig4*(-1+kappa + (1-3*kappa)*sigma +2*kappa*sig2)*a +...
    sig4*(5-3*kappa+(9*kappa-1)*sigma-6*kappa*sig2)*yold(1)...
    +sig4*(-3+3*kappa -(1+9*kappa)*sigma+6*kappa*sig2)*yold(2)+...
    sig4*(-1-kappa+(1+3*kappa)*sigma-2*kappa*sig2)*yold(3);
  end
  for j = 3:J-1
    ynew(j) = yold(j) +sig4*(-1+kappa + (1-3*kappa)*sigma +2*kappa*sig2)*...
    yold(j-2)+sig4*(5-3*kappa+(9*kappa-1)*sigma-6*kappa*sig2)*yold(j-1)...
    +sig4*(-3+3*kappa -(1+9*kappa)*sigma+6*kappa*sig2)*yold(j)+...
    sig4*(-1-kappa+(1+3*kappa)*sigma-2*kappa*sig2)*yold(j+1);
  end
  if bc == 1		% Fully upwind scheme at outflow
    ynew(J) = (1-1.5*sigma+0.5*sig2)*yold(J) + sigma*(2-sigma)*yold(J-1)...
    +sigma*0.5*(sigma-1)*yold(J-2);
  else			% Extrapolation at outflow
      ynew(J) = yold(J) +sig4*(-1+kappa + (1-3*kappa)*sigma +2*kappa*sig2)*...
    yold(J-2)+sig4*(5-3*kappa+(9*kappa-1)*sigma-6*kappa*sig2)*yold(J-1)...
    +sig4*(-3+3*kappa -(1+9*kappa)*sigma+6*kappa*sig2)*yold(J)+...
      sig4*(-1-kappa+(1+3*kappa)*sigma-2*kappa*sig2)*(2*yold(J) - yold(J-1));
  end
  yright(i+1) = ynew(J);  yold = ynew;
end

yexact =  exact_solution(t,x,c);	error = ynew - yexact;
norm1 = norm(error,1)/J			% Compute error norms
norm2 = norm(error,2)/sqrt(J)
norminf = norm(error,inf)

figure(1), clf, hold on
xx = 0:0.005:1;	plot (xx,exact_solution(t,xx,c),'-'); plot (x,ynew,'o');
s1 = ['kappa=',num2str(kappa),' bc =', num2str(bc),' sigma=',...
	num2str(sigma),' cells=',num2str(J-1),' t=',num2str(t)];
title(s1,'fontsize',18);


% Spectral factorization using Kolmogorov 1939 approach
% (code follows pp. 232-233, Signal Analysis, by A. Papoulis)
%
% Computes the minimum-phase impulse response which satisfies
% given auto-correlation.
%
% Input:
%   r: top-half of the auto-correlation coefficients
%      starts from 0th element to end of the auto-corelation
%      should be passed in as a column vector
% Output
%   h: impulse response that gives the desired auto-correlation

function h = spectral_fact(r)

% length of the impulse response sequence
nr = length(r);
n  = (nr+1)/2;

% over-sampling factor
mult_factor = 30;        % should have mult_factor*(n) >> n
m = mult_factor*n;

% computation method:
% H(exp(jTw)) = alpha(w) + j*phi(w)
% where alpha(w) = 1/2*ln(R(w)) and phi(w) = Hilbert_trans(alpha(w))

% compute 1/2*ln(R(w))
w = 2*pi*[0:m-1]/m;
R = exp( -j*kron(w',[-(n-1):n-1]) )*r;
R = abs(real(R)); % remove numerical noise from the imaginary part
figure; plot(20*log10(R));
alpha = 1/2*log(R);

% find the Hilbert transform
alphatmp = fft(alpha);
alphatmp(floor(m/2)+1:m) = -alphatmp(floor(m/2)+1:m);
alphatmp(1) = 0;
alphatmp(floor(m/2)+1) = 0;
phi = real(ifft(j*alphatmp));

% now retrieve the original sampling
index  = find(rem([0:m-1],mult_factor)==0);
alpha1 = alpha(index);
phi1   = phi(index);

% compute the impulse response (inverse Fourier transform)
h = ifft(exp(alpha1+j*phi1),n);


% Finding a point that satisfies many linear inequalities
% Section 11.4.1, Boyd & Vandenberghe "Convex Optimization"
% Written for CVX by Almir Mutapcic - 02/18/06
%
% We consider a set of linear inequalities A*x <= b which are
% infeasible. Here A is a matrix in R^(m-by-n) and b belongs
% to R^m. We apply a heuristic to find a point x that violates
% only a small number of inequalities.
%
% We use the sum of infeasibilities heuristic:
%
%   minimize   sum( max( Ax - b ) )
%
% which is equivalent to the following LP (book pg. 580):
%
%   minimize   sum( s )
%       s.t.   Ax <= b + s
%              s >= 0
%
% with variables x in R^n and s in R^m.

% problem dimensions (m inequalities in n-dimensional space)
m = 150;
n = 10;

% fix random number generator so we can repeat the experiment
seed = 0;
randn('state',seed);

% construct infeasible inequalities
A = randn(m,n);
b = randn(m,1);

fprintf(1, ['Starting with an infeasible set of %d inequalities ' ...
            'in %d variables.\n'],m,n);

% sum of infeasibilities heuristic
cvx_begin
   variable x(n)
   minimize( sum( max( A*x - b, 0 ) ) )
cvx_end

% full LP version of the sum of infeasibilities heuristic
% cvx_begin
%   variables x(n) s(m)
%   minimize( sum( s ) )
%   subject to
%     A*x <= b + s;
%     s >= 0;
% cvx_end

% number of satisfied inequalities
nv = length( find( A*x > b ) );
fprintf(1,'\nFound an x that violates %d out of %d inequalities.\n',nv,m);


function g = sigmoid(z)
%SIGMOID Compute sigmoid functoon
%   J = SIGMOID(z) computes the sigmoid of z.

g = 1 ./ (1 + exp(-z));

end


function H=chi2test(x, alpha)
%   CHI2TEST: Single sample Pearson Chi Square goodness-of-fit hypothesis test.
%   H=CHI2TEST(X,ALPHA) performs the particular case of Pearson Chi Square
%   test to determine whether the null hypothesis of composite normality PDF is
%   a reasonable assumption regarding the population distribution of a random sample X
%   with the desired significance level ALPHA.
%
%   H indicates the result of the hypothesis test according to the MATLAB rules
%   of conditional statements:
%   H=1 => Do not reject the null hypothesis at significance level ALPHA.
%   H=0 => Reject the null hypothesis at significance level ALPHA.
%
%   The Chi Square hypotheses and test statistic in this particular case are:
%
%   Null Hypothesis:        X is normal with unknown mean and variance.
%   Alternative Hypothesis: X is not normal.
%
%   The random sample X is shifted by its estimated mean and normalized by its
%   estimated standard deviation. The tested bins XP of the assumed normal distribution
%   are chosen [-inf, -1.6:0.4:1.6, inf] to avoid unsufficient statistics.
%
%   Let E(x) be the expected frequency X falls within XP according to the normal
%   distribution and O(x) be the observed frequency. The Pearson statistic,
%   X2=SUM((E(x)-O(x))^2/E(x)) distributes Chi Square with length(XP)-3 degrees
%   of freedom.
%
%   The decision to reject the null hypothesis is taken when the P value (probability that Chi2
%   random value with length(XP)-3 degrees of freedomd is greater than X2) is less than
%   significance level ALPHA.
%
%   X must be a row vector representing a random sample. ALPHA must be a scalar.
%   The function doesn't check the formats of X and ALPHA, as well as a number of the
%   input and output parameters.
%
%   The asymptotic limit of the Chi Square test presented is reached when LENGTH(X)>90.
%
% Acknowledge: Dr. S. Loyka
%
% Author: G. Levin, May, 2003.
%
% References:
%   W. T. Eadie, D. Drijard, F. E. James, M Roos and B. Sadoulet, "Statistical Methods
%   in Experimental Physics", North-Holland, Sec. Reprint, 1982.

%Normalize x
N=length(x);
x=(x-mean(x))/std(x); %standardization

xp=[-inf, -1.6:.4:1.6, inf]; %tested bins
E=0.5*N*diff(erfc(-xp/sqrt(2))); %expected frequency
S=histc(x, xp);
O=S(1:end-1); %%observed frequency
%plot(xp(2:end),E,'k-',xp(2:end),O,'k.');
x2=sum((E-O).^2./E); %statistics

pval=1-gammainc(x2/2,(length(O)-3)/2); %p value

H=(pval>=alpha);


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

% DTFT properties

% time difference

syms w
n=0:4;
x=[1,1,1,1,0];
x1=[0,1,1,1,1];
L=x-x1;
Left=sum(L.*exp(-j*w*n));
subplot(211);
ezplot(abs(Left));
title('| DTFT of x[n]-x[n-1] |')
w1=-2*pi:.1:2*pi;
Left=subs(Left,w,w1);
subplot(212);
plot(w1,angle(Left));
title('Phase of DTFT of x[n]-x[n-1]')
xlim([-2*pi  2*pi])

figure
X= sum(x.*exp(-j*w*n));
Right=(1-exp(-j*w))*X;
subplot(211);
ezplot(abs(Right));
title('| (1-exp(jw))*X(w) |')
subplot(212);
Right=subs(Right,w,w1);
plot(w1,angle(Right));
title('\angle (1-exp(jw))*X(w)')
xlim([-2*pi 2*pi])


function polinomio=trigpol(N)

%  TRIGPOL generate trigonometric polynomial.
%
%          TRIGPOL(N) generates the following polynomial in e^jw:
%
%          P(e^jw)=sum(k=0,...,N-1){ (N-1+k) ( e^(-jw) - 2 + e^jw )
%                                       k
%
%          The output of the function is a vector of size 2*N-1 holding
%          the coefficients corresponding to the different powers of e^jw.
%
%          See also: NUMCOMB, DAUB, SPLINE

%--------------------------------------------------------
% Copyright (C) 1994, 1995, 1996, by Universidad de Vigo
%
%
% Uvi_Wave 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, or (at your option) any
% later version.
%
% Uvi_Wave 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 should have received a copy of the GNU General Public License
% along with Uvi_Wave; see the file COPYING.  If not, write to the Free
% Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
%
%       Author: Nuria Gonzalez Prelcic
%       e-mail: Uvi_Wave@tsc.uvigo.es
%--------------------------------------------------------

%The polynomial is constructed from a sum.
%coefs holds the coefficients of each term in the sum.

coefs=zeros(N,2*N-1);
coefs(1,N)=1;

for i=1:N-1
	fila=[1 -2 1];
	for j=2:i
		fila=conv(fila,[1 -2 1]);
	end;
	fila=numcomb(N-1+i,i)*(-0.25)^i*fila;
	fila=[ zeros(1,(N-i-1))  fila zeros(1,(N-i-1))];
	coefs(i+1,:)=fila;
end

for i=0:(2*(N-1))
	polinomio(i+1)=0;
	for j=1:N
		polinomio(i+1)=polinomio(i+1)+coefs(j,i+1);
	end
end;


function r = spm_invIcdf(F,n,p)
% Inverse Cumulative Distribution Function (CDF) of Binomial distribution
% FORMAT r = spm_invIcdf(F,n,p)
%
% F - CDF (lower tail p-value)
% n - Binomial n
% p - Binomial p [Defaults to 0.5]
% r - ordinate
%__________________________________________________________________________
%
% spm_invIcdf returns the inverse Cumulative Distribution Function for
% the Binomial family of distributions.
%
% Definition:
%--------------------------------------------------------------------------
% The Bin(n,p) distribution is the distribution of the number of
% successes from n identical independent Bernoulli trials each with
% success probability p. If random variable R is the number of
% successes from such a set of Bernoulli trials, then the CDF F(r) is
% the probability of r or less sucesses.
%
% The Binomial distribution is discrete, defined for p in [0,1] and r
% in {0,1,...,n}, so F(r) is a discrete function. This inverse CDF
% function returns the smallest Whole r such that the F(r) equals or
% exceeds the given CDF probability F. I.e. F(r) is treated as a step
% function.
%
% Algorithm:
%--------------------------------------------------------------------------
% r is found by direct summation of the Binomial PDFs until F is exceeded.
%
% References:
%--------------------------------------------------------------------------
% Evans M, Hastings N, Peacock B (1993)
%       "Statistical Distributions"
%        2nd Ed. Wiley, New York
%
% Abramowitz M, Stegun IA, (1964)
%       "Handbook of Mathematical Functions"
%        US Government Printing Office
%
% Press WH, Teukolsky SA, Vetterling AT, Flannery BP (1992)
%       "Numerical Recipes in C"
%        Cambridge
%
%__________________________________________________________________________
% Copyright (C) 1999-2011 Wellcome Trust Centre for Neuroimaging

% Andrew Holmes
% $Id: spm_invIcdf.m 4182 2011-02-01 12:29:09Z guillaume $

%-Format arguments, note & check sizes
%--------------------------------------------------------------------------
if nargin<3, p=0.5; end
if nargin<2, error('Insufficient arguments'), end
ad = [ndims(F);ndims(n);ndims(p)];
rd = max(ad);
as = [[size(F),ones(1,rd-ad(1))];...
      [size(n),ones(1,rd-ad(2))];...
      [size(p),ones(1,rd-ad(3))]];
rs = max(as);
xa = prod(as,2)>1;
if sum(xa)>1 && any(any(diff(as(xa,:)),1))
    error('non-scalar args must match in size');
end

%-Computation
%--------------------------------------------------------------------------
%-Initialise result to zeros
r = zeros(rs);

%-Only defined for whole n, p&F in [0,1]. Return NaN if undefined.
md = ( F>=0  &  F<=1  &  n==floor(n)  &  n>=0  &  p>=0  &  p<=1 );
if any(~md(:))
    r(~md) = NaN;
    warning('Returning NaN for out of range arguments');
end

%-Non-zero only where defined, & F>0
Q  = find( md  &  F>0 );
if isempty(Q), return, end
if xa(1), QF=Q; else QF=1; end
if xa(2), Qn=Q; else Qn=1; end
if xa(3), Qp=Q; else Qp=1; end

%-Compute by directly summing Bin PDF's for successive r & comparing with F
tr  = 0;
Ftr = spm_Ipdf(tr,n(Qn),p(Qp));
while any(F(QF)>Ftr) && any(n(Qn)>tr)
    tr      = tr+1;
    i       = find(Ftr<F(QF));
    r(Q(i)) = r(Q(i)) + 1;
    Ftr     = Ftr + spm_Ipdf(tr,n(Qn),p(Qp));
end


function [RSS, XYproj] = Residuals_ellipse(XY,ParG)
%
%   Projecting a given set of points onto an ellipse
%   and computing the distances from the points to the ellipse
%
%   This is a modified version of an iterative algorithm published by D. Eberly
%     Internet publication: "Distance from a point to an ellipse in 2D" (2004)
%                           Geometric Tools, LLC, www.geometrictools.com
%     Book publication: "3D Game Engine Design", 2nd edition.
%                       Morgan Kaufmann Publishers, San Francisco, CA, 2007.
%                              (see Section 14.13.1)
%
%   Input:  XY(n,2) is the array of coordinates of n points x(i)=XY(i,1), y(i)=XY(i,2)
%           ParG is a vector 5x1 of the ellipse parameters
%           ParG =  [Center(1:2), Axes(1:2), Angle]'
%                Center - the coordinates of the ellipse's center
%                Axes   - the axes (major, minor)
%                Angle  - the angle of tilt of the ellipse
%
%   Output:  RSS is the Residual Sum of Squares (the sum of squares of the distances)
%            XYproj is the array of coordinates of projections
%
%   The algorithm is proven to converge and reaches an accuracy of 7-8 significant digit
%   It takes 4-5 iterations per point, on average.

Center = ParG(1:2);   Axes = ParG(3:4);  Angle = ParG(5);

n = size(XY,1);
XYproj = zeros(n,2);
tolerance = 1e-9;

%  First handling the circle case

if abs((Axes(1)-Axes(2))/Axes(1))<tolerance
    phiall = angle(XY(:,1)-Center(1) + sqrt(-1)*(XY(:,2)-Center(2)));
    XYproj = [Axes(1)*cos(phiall)+Center(1) Axes(2)*sin(phiall)+Center(2)];
    RSS = norm(XY-XYproj,'fro')^2;
    return;
end

%  Now dealing with proper ellipses

a = Axes(1); b = Axes(2);
aa = a^2;  bb = b^2;

tol_a = tolerance*a;
tol_b = tolerance*b;
tol_aa = tolerance*aa;

%  Matrix Q for rotating the points and the ellipse to the canonical system

s = sin(Angle); c = cos(Angle);
Q = [c -s; s c];

%  data points in canonical coordinates

XY0  = [XY(:,1)-Center(1) XY(:,2)-Center(2)]*Q;
XYA = abs(XY0);
Tini = max(a*(XYA(:,1)-a),b*(XYA(:,2)-b));

%  main loop over the data points

for i=1:n
    u = XYA(i,1);  v = XYA(i,2);
    ua = u*a;      vb = v*b;

    if (u == 0)
        z1 = 1;
    else
        z1 = sign(XY0(i,1));
    end

    if (v == 0)
        z2 = 1;
    else
        z2 = sign(XY0(i,2));
    end

    %       does the point lie on the minor axis?

    if u<tol_a
        if XY0(i,2)<0
            XYproj(i,:) = [0 -b];
        else
            XYproj(i,:) = [0 b];
        end
        continue;
    end

    %       does the point lie on the major axis?

    if v<tol_b
        if u<a-bb/a
            xproj = aa*u/(aa-bb);
            XYproj(i,:) = [z1*xproj z2*b*sqrt(1-(xproj/a)^2)];
        else
            XYproj(i,:) = [z1*a 0];
        end
        continue;
    end

    %      generic case: start the iterative procedure

    T = Tini(i);
    for iter=1:100
        Taa = T + aa;
        Tbb = T + bb;
        PP1 = (ua/Taa)^2;
        PP2 = (vb/Tbb)^2;
        F  = PP1 + PP2 - 1;
        if F<0; break; end;
        Fder = 2*(PP1/Taa + PP2/Tbb);
        Ratio = F/Fder;
        if (Ratio<tol_aa); break; end;
        T = T + Ratio;
    end

    %       compute the projection of the point onto the ellipse

    xproj = XY0(i,1)*aa/Taa;
    XYproj(i,:) = [xproj sign(XY0(i,2))*b*sqrt(1-(xproj/a)^2)];

end % end the main loop

%    rotate back to the original system
XYproj = XYproj*Q';
XYproj = [XYproj(:,1)+Center(1) XYproj(:,2)+Center(2)];
RSS = norm(XY-XYproj,'fro')^2;
end   % Residuals_ellipse


function val=PearsonsGammaInc(u,p)
%%PEARSONSGAMMAINC Evaluate Pearson's incomplete gamma function. This is
%          equal to (1/gamma(p+1))*integral_0^(u*sqrt(p+1)) exp(-t)*t^p dt.
%
%INPUTS: u The positive u value (or matrix for multiple values to be
%          computed in parallel) in the upper bound of the integral. u>=0.
%          It is allowable to pass a scalar for this and a matrix for p.
%        p The exponent of the t term in the integral, or a matrix for
%          multiple values to be done in parallel. p>-1. It is allowable to
%          pass a scalar for this and a matrix for u.
%
%OUTPUTS: val The value or values of Person's gamma function at the desired
%             points.
%
%Pearson's incomplete gamma function is defined in terms of an integral in
%Section 6.5.6 of [1]. In Equation 1.7 of [2], Pearson's incomplete gamma
%function is expressed in terms of Tricomi's incomplete gamma function and
%Equation 1.3 expressed tricomi's gamma function in terms of the type of
%agmma function used in gammainc. Thus, this function uses the
%transformations and the gammainc function to express the result.
%
%REFERENCE
%[1] Abramowitz, M. and Stegun, I. A. (Eds.). "Gamma function and related
%    functions." in Ch. 6 in Handbook of Mathematical Functions with
%    Formulas, Graphs, and Mathematical Tables, 9th printing. New York:
%    Dover, 1972.
%[2] W. Gautschi, "A computational procedure for incomplete gamma
%    functions," ACM Transactions on Mathematical Software, vol. 5, no. 4,
%    pp. 466-481, Dec. 1979.
%
%March 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(isscalar(u)&&~isscalar(p))
    u=u*ones(size(p));
elseif(~isscalar(u)&&isscalar(p))
    p=p*ones(size(u));
end

val=gammainc(sqrt(1+p).*u,1+p);

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 fd1d_advection_lax ( )

%*****************************************************************************80
%
%% FD1D_ADVECTION_LAX solves the advection equation using the LAX method.
%
%  Discussion:
%
%    The Lax method is stable for the advection problem, if the time step
%    satisifies the Courant-Friedrichs-Levy (CFL) condition:
%
%      dt <= dx / c
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 January 2013
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'FD1D_ADVECTION_LAX:\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Solve the constant-velocity advection equation in 1D,\n' );
  fprintf ( 1, '    du/dt = - c du/dx\n' );
  fprintf ( 1, '  over the interval:\n' );
  fprintf ( 1, '    0.0 <= x <= 1.0\n' );
  fprintf ( 1, '  with periodic boundary conditions, and\n' );
  fprintf ( 1, '  with a given initial condition\n' );
  fprintf ( 1, '    u(0,x) = (10x-4)^2 (6-10x)^2 for 0.4 <= x <= 0.6\n' );
  fprintf ( 1, '           = 0 elsewhere.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  We modify the FTCS approach using the Lax method:\n' );
  fprintf ( 1, '    du/dt = (u(t+dt,x)-0.5*u(t,x-dx)-0.5*u(t,x+dx))/dt\n' );
  fprintf ( 1, '    du/dx = (u(t,x+dx)-u(t,x-dx))/2/dx\n' );

  nx = 101;
  dx = 1.0 / ( nx - 1 );
  x = linspace ( 0.0, 1.0, nx );
  nt = 1000;
  dt = 1.0 / nt;
  c = 1.0;

  u = zeros ( 1, nx );
  i = find ( 0.4 <= x & x <= 0.6 );
  u(i) = ( 10.0 * x(i) - 4.0 ).^2 .* ( 6.0 - 10.0 * x(i) ).^2;

  iplot = 1;
  uplot(iplot,:) = u(:)';
  tplot(iplot) = 0.0;
  plotstep = ceil ( nt / 50 );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Number of nodes NX = %d\n', nx );
  fprintf ( 1, '  Number of time steps NT = %d\n', nt );
  fprintf ( 1, '  Constant velocity C = %g\n', c );
  fprintf ( 1, '  CFL condition: dt (%g) <= dx / c (%g)\n', dt, dx / c );

  im1 = [ nx, 1:nx-2, nx-1 ];
  i   = [ 1,  2:nx-1, nx   ];
  ip1 = [ 2,  3:nx,   1    ];

  for j = 1 : nt

    unew(i) = 0.5 * ( u(im1) + u(ip1) ) - c * dt / dx / 2.0 * ( u(ip1) - u(im1) );
    u(i) = unew(i);

    if ( rem ( j, plotstep ) < 1 )
      iplot = iplot + 1;
      uplot(iplot,:) = u(:)';
      tplot(iplot) = j * dt;
    end

  end
%
%  Plot.
%
  mesh ( x, tplot, uplot );
  xlabel ( '<--X-->' );
  ylabel ( '<--T-->');
  title ( 'U(X,T)');

  filename = 'fd1d_advection_lax.png';
  print ( '-dpng', filename );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Saving plot as "%s".\n', filename );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'FD1D_ADVECTION_LAX\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  return
end
function timestamp ( )

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

  return
end


function dist = lines_exp_dist_3d_2 ( p1, p2, q1, q2 )

%*****************************************************************************80
%
%% LINES_EXP_DIST_3D_2 computes the distance between two explicit lines in 3D.
%
%  Discussion:
%
%    The explicit form of a line in 3D is:
%
%      the line through the points P1 and P2.
%
%    This routine uses a method that is essentially independent of dimension.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 August 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real P1(3,1), P2(3,1), two points on the first line.
%
%    Input, real Q1(3,1), Q2(3,1), two points on the second line.
%
%    Output, real DIST, the distance between the lines.
%
  dim_num = 3;
%
%  Let U = (P2-P1) and V = (Q2-Q1) be the direction vectors on
%  the two lines.
%
  u(1:dim_num,1) = p2(1:dim_num,1) - p1(1:dim_num,1);
  v(1:dim_num,1) = q2(1:dim_num,1) - q1(1:dim_num,1);
%
%  Let SN be the unknown coordinate of the nearest point PN on line 1,
%  so that PN = P(SN) = P1 + SN * (P2-P1).
%
%  Let TN be the unknown coordinate of the nearest point QN on line 2,
%  so that QN = Q(TN) = Q1 + TN * (Q2-Q1).
%
%  Let W0 = (P1-Q1).
%
  w0(1:dim_num,1) = p1(1:dim_num,1) - q1(1:dim_num,1);
%
%  The vector direction WC = P(SN) - Q(TC) is unique (among directions)
%  perpendicular to both U and V, so
%
%    U dot WC = 0
%    V dot WC = 0
%
%  or, equivalently:
%
%    U dot ( P1 + SN * (P2 - P1) - Q1 - TN * (Q2 - Q1) ) = 0
%    V dot ( P1 + SN * (P2 - P1) - Q1 - TN * (Q2 - Q1) ) = 0
%
%  or, equivalently:
%
%    (u dot u ) * sn - (u dot v ) tc = -u * w0
%    (v dot u ) * sn - (v dot v ) tc = -v * w0
%
%  or, equivalently:
%
%   ( a  -b ) * ( sn ) = ( -d )
%   ( b  -c )   ( tc )   ( -e )
%
  a = u' * u;
  b = u' * v;
  c = v' * v;
  d = u' * w0;
  e = v' * w0;
%
%  Check the determinant.
%
  det = - a * c + b * b;

  if ( det == 0.0 )
    sn = 0.0;
    if ( abs ( b ) < abs ( c ) )
      tn = e / c;
    else
      tn = d / b;
    end
  else
    sn = ( c * d - b * e ) / det;
    tn = ( b * d - a * e ) / det;
  end

  pn(1:dim_num,1) = p1(1:dim_num,1) + sn * ( p2(1:dim_num,1) - p1(1:dim_num,1) );
  qn(1:dim_num,1) = q1(1:dim_num,1) + tn * ( q2(1:dim_num,1) - q1(1:dim_num,1) );

  dist = sqrt ( sum ( ( pn(1:dim_num,1) - qn(1:dim_num,1) ).^2 ) );

  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
%

J = sum(sum(((X * Theta') .* R .- Y) .^ 2)) / 2;
X_grad = ((X * Theta') .* R .- Y) * Theta;
Theta_grad = ((X * Theta') .* R .- Y)' * X;

offset = (lambda / 2) * (sum(sum(Theta .^ 2)) + sum(sum(X .^ 2)));
J = J + offset;
X_grad = X_grad + lambda * X;
Theta_grad = Theta_grad + lambda * Theta;
% =============================================================

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

end