function [xk,objfunvals,xkk] = solveLASSOProblem(A,b,alpha,varargin)
%%SOLVELASSOPROBLEM This function solves the Least Absolute Shrinkage and
%               Selection Operator (LASSO) problem. This optimization
%               problem is
%               minimize (1/2)*norm(A*x-b,2)^2+alpha*norm(x,1)
%               Thus, the LASSO problem is the same as the ridge regression
%               problem except the second term uses an l_1 norm instead of
%               an l_2 norm. This type of optimization plays a notable role
%               in compressive sensing algorithms. The optimization problem
%               is solved using the Fast-Iterative Shrinkage and
%               Thresholding Algorithm (FISTA) for sparse vectors.
%
%INPUTS:      A An mXn matrix. This can be complex.
%             b An mX1 vector. This can be complex.
%         alpha A real scalar value.
%      varargin Arguments that are specified as fieldname, value pairs.
%               Possible pairs are:
%               FIELD NAME         VALUE TYPE     DESCRIPTION
%               -----------------  -------------- -----------------------
%               'maxiter'          numeric scalar The maximum number of
%                                                 iterations (default 2000)
%               'tol'              numeric scalar Tolerence for termination
%                                                 (default 1e-6).
%               'tau'              numeric scalar Descent parameter used to
%                                                 to control the rate of
%                                                 minimization (default:
%                                                 svds(A,1).^2).
%               'backtracking'     bool           Performs backtracking if
%                                                 turned on.
%               'verbose'          bool           Enables verbose mode.
%               'stoppingcriteria' char           'cauchy' or 'gradient'.
%               'init'             vector         n x 1 vector for warm
%                                                 start.
%
%OUTPUTS: xk The nX1 vector solution to the optimization problem.
% objfunvals If verbose mode is activated, then this will hold the value of
%            the objective function at every iteration. in a numIterX1
%            vector. Otherwise, this is an empty matrix.
%        xkk An nXnumIter matrix holding the value of the estimate at each
%            step.
%
%The algorithm implemented is that of [1]. The algorithm typically needs a
%very large number of iterations to converge. However, the number of
%iterations is not particularly dependent on the scale of the problem,
%making the solver good for large problems.
%
%EXAMPLE:
%A trivial example is
% A=[10,  4,   -3, 6;
%     0,  -18, 24, -10;
%     5,  7,   3,  12];
% xTrue=[0;2;0;12];
% alpha=2;
% b=A*xTrue;
% xk=solveLASSOProblem(A,b,alpha)
%The xk found should have the required sparsity, but the l1 penalty term
%means that the xk found will not equal xTrue; Rather, it will be
%xk=[0;2.006;0;11.9922]. Increasing alpha forces the sparsity up. For
%example, using alpha=3200 changes the result to xk=[0;2.6581;0;0] and
%using alpha=4000 changes xk to all zeros. Making alpha close to 0 reduces
%the result to approach pinv(A)*b.
%
%REFERENCES:
%[1] A. Beck and M. Teboulle, "A fast iterative shrinkage-thresholding
%    algorithm for linear inverse problems," SIAM Journal on Imaging
%    Sciences, vol. 2, no. 1, pp. 183-202, 2009.
%
%February 2016 Hatim F. Alqadah, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

    %% PROCESS INPUTS HERE
    if(nargin < 3)
        alpha = [];
    end
    if(nargin < 2)
        error('invalid number of arguments');
    end

    % check argument type and sizes
    assert(ismatrix(A),'A should be a matrix');
    assert(isvector(b),'b should be a vector');
    [m,n] = size(A);
    assert(size(b,1) == m,'invalid vector length on right hand side');

    % if matrix or data is complex we need to seperate out
    % the real and imaginary components
    is_complex = ~(isreal(A) && isreal(b));
    if(is_complex)
        % reformulate into a purely real problem
        A = [real(A) -imag(A);imag(A) real(A)];
        b = [real(b);imag(b)];
    end

    % set default options and process user defined ones
    opts.maxiter = 2000;
    opts.tol = 1e-6;
    opts.stopcrit = 'cauchy';
    opts.backtracking = false;
    opts.verbose = false;
    opts.restart = false;
    opts.return_as_dense = true;
    opts.init = [];
    opts.tau = [];

    [opts] = addCelListToStruct(opts,varargin);
    clear varargin

    if(~isempty(opts.init))
        assert(length(opts.x0) == n,'given warm start has incorrect length');
        xk = x0;
        if(is_complex)
            xk = [real(xk);imag(xk)];
        end
    else
        if(is_complex)
            xk = sparse(2*n,1);
        else
            xk = sparse(n,1);
        end
    end

    %% PREPROCESSING

    % set initial quantities
    xp = xk;
    nn = 0;
    tk = 1;
    tp = 1;
    At = A';
    Atb = At*b;
    has_converged = false;
    keep_history = nargout > 2;
    objfunvals = [];
    xkk = [];

    if(isempty(alpha))
        alpha = .5*norm(Atb,'inf');
    end

    if(isempty(opts.tau))
        %Use iterative method to find the Lipschitz constant
        opts.tau = svds(A,1).^2;
    end

    %Setup reporting functions if quiet mode is disabled
    if(opts.verbose)
        fprintf('\n*******************************************\n');
        fprintf('* FISTA: SPARSE VECTOR RECONSTRUCTION \n');
        if(is_complex)
        	fprintf('* CMPLX     : %s\n','true');
        else
            fprintf('* CMPLX     : %s\n','false');
        end
        fprintf('* MAXITER   : %d\n',opts.maxiter);
        fprintf('* TOL       : %e\n',opts.tol);
        if(opts.restart)
            fprintf('* RESTART   : %s\n','true');
        else
            fprintf('* RESTART   : %s\n','false');
        end
        fprintf('* STOPCRIT  : %s\n',opts.stopcrit);
        fprintf('*******************************************\n');
        msgstr = ['Current Precision: ',num2str(inf)];
        h = waitbar(0,msgstr);
        precision = zeros(opts.maxiter,1);
        objfun = @(x) ObjFunc(x,A,b,alpha);
        objfunvals = zeros(opts.maxiter,1);
    end
    if(keep_history)
        xkk = zeros(length(xk),opts.maxiter);
    end

    %% MAINLOOP

    while(nn < opts.maxiter)
        if opts.verbose
            objfunvals(nn+1) = objfun(xk); %#ok<*AGROW>
        end
        if(keep_history)
            xkk(:,nn+1) = xk;
        end

        yk = xk + ((tp-1)/tk)*(xk - xp);
        grd = At*(A*yk) - Atb;
        xp = xk;
        if(opts.backtracking)
            % solve the local regularization problem with an appropriate
            % step size
            [xk,opts.tau] = LineSearch(A,b,grd,alpha,yk,opts.tau);
        else
            xk = sparse(shrink(yk - (1/opts.tau)*grd,alpha/opts.tau));
        end

        % check stopping criterion
        switch(lower(opts.stopcrit))
            case 'cauchy'
                prec = norm(xk(:) - yk(:))/max(norm(xk),1);
            case 'subgradient'
                % we need to estimate the subgradient at current pt
                % optimality occurs at zero
                prec = ComputeOptimalityResidue(A,At,xk,Atb,alpha);
        end
        if(prec < opts.tol)
            has_converged = true;
            break;
        end

        % keep going
        nn = nn + 1;
        tp = tk;
        tk = 0.5*(1+sqrt(1+4*tk*tk));

        % check if a restart is necessary
        if(opts.restart && ((yk - xk)'*(xk - xp) > 0))
            % forget all previous iterations
            % and reset momentum back to zero
            tp = 1;
            tk = 1;
        end
        if(opts.verbose)
            precision(nn) = prec;
            waitbar(nn/opts.maxiter,h,['Current precision: ',num2str(prec)]);
        end
    end
    if(~has_converged)
        warning('MATLAB:no_convergence','method failed to converge within given time steps');
    end

    %% Post-processing
    if(opts.verbose)
        waitbar(1,h);
        objfunvals = objfunvals(1:nn);
        precision = precision(1:nn);
        iter = 0:nn-1;
        figure;
        semilogy(iter,objfunvals,'--r','linewidth',1.2);
        grid on;
        title(['Objective Function for \alpha = ',num2str(alpha)]);
        xlabel('ITERATION');
        ylabel('FOBJ VAL');

        figure;
        semilogy(iter,precision,'--g','linewidth',1.2);
        grid on;
        title(['Precision for \alpha = ',num2str(alpha)]);
        xlabel('ITERATION');
        ylabel('PREC LVL');
        close(h);
    end
    if(opts.return_as_dense)
        xk = full(xk);
        if keep_history
            xkk = full(xkk(:,1:nn));
        end
    end
    if(is_complex)
        xk = complex(xk(1:n),xk(n+1:end));
        if(keep_history)
            xkk = complex(xkk(1:n,:),xkk(n+1:end,:));
        end
    end

end
%% UTILITY
% defines the standard shrinkage operator.
function z = shrink(x,mu)
    z = sign(x).*max(abs(x)-mu,0);
end

% Experimental stopping criteria particlarly for proximal gradient methods.
% It is not clear if this can help issues do non-strict convexivity of the
% data fidelity term
function prec = ComputeOptimalityResidue(A,At,xk,Atb,alpha)
    % first compute the gradient at the current point
    gradF = At*(A*xk) - Atb;

    % compute the unique portion of the sub-gradient
    subGrad = alpha*sign(xk);

    % now for the points that are zero minimize the
    % optimality residue
    inds = find(subGrad == 0);

    % compute solution to the constrained
    % sub optimization problem
    g = gradF(inds);
    y = zeros(size(g));

    for i=1:50
        yp = y;
        lambda = abs(y+g)/alpha;
        y = (y - .5*(y+g))./(1 - .5*lambda);
        if(norm(y-yp)/max([norm(y),1]) < 1e-5)
            break;
        end
    end
    subGrad(inds) = y;

    % evaluate the maximum sub-gradient component
    prec = norm(gradF + subGrad,'inf');
end

% returns the objective function value of the unconstrained l2-l1 problem
function val = ObjFunc(x,A,b,alpha)
   val = .5*norm(A*x - b).^2 + alpha*norm(x,1);
end

% A straight-forward line search method for first order methods
function [xk,fxk,L] = LineSearch(A,b,grd,alpha,yk,L)
    beta = 1.2;
    stopBacktrack = false;
    fyk = .5*norm(A*yk - b).^2 + alpha*norm(yk,1);
    while(~stopBacktrack)
        % predict the next value
        xk = sparse(shrink(yk - (1/L)*grd,alpha/L));
        fxk = .5*norm(A*xk - b).^2 + alpha*norm(xk,1);

        % find the Lipschitz constant that ensures the Taylor
        % expansion is valid
        q =  fyk + (xk-yk)'*grd + 0.5*L*norm(xk-yk).^2 + alpha*norm(xk,1);
        if(fxk <= q)
            stopBacktrack = true;
        else
            % increase the Lipschitz constant estimate
            L = L*beta;
        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 [f, df, ddf] = rosenbrock(x);

% rosenbrock.m This function returns the function value, partial derivatives
% and Hessian of the (general dimension) rosenbrock function, given by:
%
%       f(x) = sum_{i=1:D-1} 100*(x(i+1) - x(i)^2)^2 + (1-x(i))^2
%
% where D is the dimension of x. The true minimum is 0 at x = (1 1 ... 1).
%
% Carl Edward Rasmussen, 2001-07-21.

D = length(x);
f = sum(100*(x(2:D)-x(1:D-1).^2).^2 + (1-x(1:D-1)).^2);

if nargout > 1
  df = zeros(D, 1);
  df(1:D-1) = - 400*x(1:D-1).*(x(2:D)-x(1:D-1).^2) - 2*(1-x(1:D-1));
  df(2:D) = df(2:D) + 200*(x(2:D)-x(1:D-1).^2);
end

if nargout > 2
  ddf = zeros(D,D);
  ddf(1:D-1,1:D-1) = diag(-400*x(2:D) + 1200*x(1:D-1).^2 + 2);
  ddf(2:D,2:D) = ddf(2:D,2:D) + 200*eye(D-1);
  ddf = ddf - diag(400*x(1:D-1),1) - diag(400*x(1:D-1),-1);
end


function table = hn_exponential_product ( p, b )

%*****************************************************************************80
%
%% HN_EXPONENTIAL_PRODUCT: exponential products exp(b*x)*Hn(i,x)*Hn(j,x).
%
%  Discussion:
%
%    Hn(i,x) is the normalized physicist's Hermite polynomial of degree I.
%
%    For polynomial chaos applications, it is of interest to know the
%    value of the integrals of products of exp(B*X) with every possible pair
%    of basis functions.  That is, we'd like to form
%
%      Tij = Integral ( -oo < X < +oo ) exp(B*X) * Hn(I,X) * Hn(J,X) exp(-X*X) dx
%
%    We will estimate these integrals using Gauss-Hermite quadrature.
%    Because of the exponential factor exp(B*X), the quadrature will not
%    be exact.
%
%    However, when B = 0, the quadrature is exact, and moreoever, the
%    table will be the identity matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 February 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer P, the maximum degree of the polyonomial factors.
%    0 <= P.
%
%    Input, real B, the coefficient of X in the exponential factor.
%
%    Output, real TABLE(P+1,P+1), the table of integrals.  TABLE(I,J)
%    represents the weighted integral of exp(B*X) * Hn(I+1,X) * Hn(J+1,X).
%
  table(1:p+1,1:p+1) = 0.0;

  order = floor ( ( 3 * p + 4 ) / 2 );

  [ x_table, w_table ] = h_quadrature_rule ( order );
  r8vec2_print ( order, x_table, w_table, '  Quadrature rule:' );

  for k = 1 : order

    x = x_table(k);
    h_table = hn_polynomial_value ( 1, p, x );
%
%  The following formula is an outer product in H_TABLE.
%
    table(1:p+1,1:p+1) = table(1:p+1,1:p+1) ...
      + w_table(k) * exp ( b * x ) * h_table(1:p+1)' * h_table(1:p+1);

  end

  return
end


function er3OC_sym
%EG3OC_sym    Example 3 of optimal control tutorial.
%    This example is from D.S.Naidu, "Optimal contorl systems"
%    page 77-80, Example 2.14
%    Symbolic toolbox is used to get the analytical solution

sol = dsolve('Dx1 = x2, Dx2 = -p2, Dp1 = 0, Dp2 = -p1',...
           'x1(0) = 1, x2(0) = 2, x1(tf) = 3, p2(tf) = 0');
eq1 = subs(sol.x1) - 'x1tf';
eq2 = subs(sol.x2) - 'x2tf';
eq3 = subs(sol.p1) - 'p1tf';
eq4 = subs(sol.p2) - 'p2tf';
eq5 = sym('p1tf*x2tf - 0.5*p2tf^2');
%%
sol_2 = solve(eq1, eq2, eq3, eq4, eq5);
tf = sol_2.tf;
x1tf = sol_2.x1tf;
x2tf = sol_2.x2tf;

x1 = subs(sol.x1);
x2 = subs(sol.x2);
p1 = subs(sol.p1);
p2 = subs(sol.p2);

%%
sol_book = {@(t)((4/54).*t.^3-(2/3)*t.^2+2.*t+1),...
            @(t)((4/18).*t.^2-(4/3).*t+2)};
u = @(t)((4/9).*t-(4/3));
t = double(tf);
time = linspace(0,t,20);
s_book = [sol_book{1}(time);sol_book{2}(time)];
ut = u(time);

figure(1);
ezplot(x1,[0 t]); hold on;
ezplot(x2,[0 t]);
plot(time, s_book,'*');
plot(time, ut, 'k:');
axis([0 t -1.5 3]);
text(1.3,2.5,'x_1(t)');
text(1.3,1,'x_2(t)');
text(1.3,-.5,'u(t)');
xlabel('time');
ylabel('states');
title('Analytical solution');
hold off;
% print -djpeg90 -r300 eg3a.jpg

%% ------------------------------------------------------------------------
% % The same procedure applied on example problem 1 with tf unknown.
% % no explicit solution could be found
% sol = dsolve('Dx1 = x2, Dx2 = -x2 - p2, Dp1 = 0, Dp2 = p1 - p2',...
%            'x1(0) = 1, x2(0) = 2, x1(tf) = 5, x2(tf) = 2');
% eq1 = subs(sol.x1) - 'x1tf';
% eq2 = subs(sol.x2) - 'x2tf';
% eq3 = subs(sol.p1) - 'p1tf';
% eq4 = subs(sol.p2) - 'p2tf';
% eq5 = sym('p1tf*x2tf-p2tf*x2tf-0.5*p2tf^2');
%
% sol_2 = solve(eq1, eq2, eq3, eq4, eq5);
% tf = sol_2.tf;
% x1tf = sol_2.x1tf;
% x2tf = sol_2.x2tf;
% clear t;
% x1 = subs(sol.x1);
% x2 = subs(sol.x2);
% p1 = subs(sol.p1);
% p2 = subs(sol.p2);


function [intT,T]=ChebyshevPolyInt(tau,n,tauStart,tauEnd)
%%CHEBYSHEVPOLYDERIV Compute the indefinite integral (with zero additive
%                    constant) of Chebyshev polynomials of the first kind
%                    from order 0 to order n evaluated at the points given
%                    in tau.
%
%INPUTS: tau An NX1 or 1XN vector of values from tauStart to tauEnd, or
%            from -1 to 1 if tauStart and tauEnd are omitted, where one
%            wishes to evaluate the indefinite integrals (antiderivatives)
%            of the Chebyshev polynomials.
%          n The non-negative integer maximum order of the Chebyshev
%            polynomials evaluated.
% tauStart,tauEnd The possible range of the inputs. If omitted, a range of
%            -1 to 1 is assumed --the normal range for Chebyshev
%            polynomials. The option for mapping to a wider range is useful
%            when using Chebyshev polynomials for interpolation. Note that
%            such polynomials are generally not useful for interpolating
%            far outside of the valid range.
%
%OUTPUTS: dT An (n+1)XN matrix of the antiderivatives of the Chebyshev
%            polynomials from order 0 to n evaluated at each of the values
%            of tau. T(i,j) is the antiderivative of the (i-1)th order
%            Chebyshev polynomial evaluated at tau(j), taking into account
%            that the function has been mapped to the range
%            (tauStart,tauEnd), if necessary.
%          T Since the Chebyshev functions have to be computed to find the
%            indefinite integrals, an (n+2)XN matrix of the Chebyshev
%            functions can also be returned, if desired
%
%The recursion for finding the indefinite integral values can be obtained
%by examining how the function ChebyshevPolyIntCoeffs modifies the
%coefficients of a weighted series of Chebyshev polynomials when only a
%single 1 is present for each given order.
%
%September 2014 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

N=length(tau);
tau=tau(:)';%Make tau into a column vector.
%Map the tau values to the -1 to 1 range, if necessary.
if(nargin>2)
    tau=(tau-0.5*(tauStart+tauEnd))/(0.5*(tauEnd-tauStart));
end

%Get the Chebyshev polynomial function values.
T=ChebyshevPoly(tau,n+1);
intT=zeros(n+1,N);

%Deal with the n=0 case.
curN=0;
intT(curN+1,:)=T(curN+1+1,:);

if(n>0)
    %Deal with the n=1 case.
    curN=1;
    intT(curN+1,:)=0.5*(T(curN+1+1,:)/(curN+1)+0.5);
end

%Perform recusion for the rest of the values.
for curN=2:n
    intT(curN+1,:)=0.5*(T(curN+1+1,:)/(curN+1)-T(curN-1+1,:)/(curN-1));
end

%The constant to handle a mapping from -1->1 to some other range of
%parameters.
if(nargin>2)
    intT=intT*((tauEnd-tauStart)/2);
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 theta = lineAngle(varargin)
%LINEANGLE Computes angle between two straight lines.
%
%   A = lineAngle(LINE);
%   Returns the angle between horizontal, right-axis and the given line.
%   Angle is fiven in radians, between 0 and 2*pi, in counter-clockwise
%   direction.
%
%   A = lineAngle(LINE1, LINE2);
%   Returns the directed angle between the two lines. Angle is given in
%   radians between 0 and 2*pi, in counter-clockwise direction.
%
%   See also
%   lines2d, angles2d, createLine, normalizeAngle
%
%   ---------
%   author : David Legland
%   INRA - TPV URPOI - BIA IMASTE
%   created the 31/10/2003.
%

%   HISTORY
%   2004-02-19 added support for multiple lines.
%   2011-01-20 use bsxfun

nargs = length(varargin);
if nargs == 1
    % angle of one line with horizontal
    line = varargin{1};
    theta = mod(atan2(line(:,4), line(:,3)) + 2*pi, 2*pi);

elseif nargs==2
    % angle between two lines
    theta1 = lineAngle(varargin{1});
    theta2 = lineAngle(varargin{2});
    theta = mod(bsxfun(@minus, theta2, theta1)+2*pi, 2*pi);
end


function intVal=monomialIntCubicalShell(alpha,K1,K2)
%%MONOMIALINTCUBALSHELL Evaluate the integral of prod_{i=1}^N x(i)^alpha(i)
%              taken over the region K1<=x(i)<=K2 with 0<K1<K2<Inf. That
%              is, this function gives the value of the desired monomial
%              integral over an N-dimensional hypercubic shell. The region
%              is designated as C_N^{shell} in [1].
%
%INPUTS: alpha An NX1 or 1XN vector of the integer exponents of the
%              monomial term. All elements must be >=0.
%       K1, K2 Two positive, finite, real values such that 0<K1<K2.
%
%OUTPUTS: intVal The value of the specified integral.
%
%The formula is taken from Chapter 7.3 of [1]. These types of explicit
%moment formulae are useful for testing cubature integration points.
%
%EXAMPLE:
%Here we verify that the moment value produced here equals that obtained
%using cubature points of an appropriate order.
% K1=0.5;
% K2=1.25;
% [xi,w]=thirdOrderNDimShellCubPoints(3,K1,K2);
% alpha=[0;2;0];
% theMoment=findMomentFromSamp(alpha,xi,w)
% intVal=monomialIntCubicalShell(alpha,K1,K2)
%One will find that both theMoment and intVal are about 8.0547.
%
%REFERENCES:
%[1] A.H. Stroud, Approximate Calculation of Multiple Integrals. Cliffs,
%    NJ: Prentice-Hall, Inc., 1971.
%
%February 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

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

    intVal=(2^n/prod(alpha+1))*(K2^(n+alphaSum)-K1^(n+alphaSum));
else
    intVal=0;
end

end

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


function P = agm_pi(d)
% AGM_PI  Arithmetic-geometric mean for pi.
% Brent-Salamin algorithm.
% agm_pi(d) produces d decimal digits.
% See Cleve's Corner, "Computing Pi",
% http://www.mathworks.com/company/ ...
%    newsletters/news_notes/2011/

% Copyright 2011 MathWorks, Inc.

digits(d)
a = vpa(1,d);
b = 1/sqrt(vpa(2,d));
s = 1/vpa(4,d);
p = 1;
n = ceil(log2(d));
for k = 1:n
   c = (a+b)/2;
   b = sqrt(a*b);
   s = s - p*(c-a)^2;
   p = 2*p;
   a = c;
end
P = a^2/s;


function boolVal=isProbablePrime(n,numRuns)
%%ISPROBABLEPRIME Determine whether a positive integer is prime, with an
%                 algorithm that has a small probablity of falsely
%                 declaring a non-prime to be a prime, but which is faster
%                 than dbrute force division.
%
%INPUTS: n A real positive integer. This value must be <=sqrt(flintmax).
%          The algorithm gets slower for smaller numbers.
%  numRuns An optional parameter specifying how many times the algorithm is
%          rerun when it initially detects a probable prime. The default if
%          omitted or an empty matrix is passed is 25. The more runs, the
%          more conficence one can have in the solution. In Chapter 4.5.4
%          of [1], it is noted that the algorithm might have a pase
%          positive up to 1/4 of the time, so the likelihood of having 25
%          of them is about (1/4)^25=8.8818e-16 is very slow.
%
%OUTPUTS: boolVal This is true if n is a probable prime and false if n is
%                 definitely not a prime.
%
%This function implements Algorithm P in Section 4.5.4 of [1].
%
%EXAMPLE:
%Here, we test a known Mersenne prime and a nearby number that is not
%prime.
% boolVal0=isProbablePrime(2^19-1)
% boolVal1=isProbablePrime(2^19-3)
%One should get boolVal0=true and boolVal1=false.
%
%REFERENCES:
%[1] D. E. Knuth, The Art of Computer Programming. Vol. 2: Seminumerical
%    Algorithms, 3rd Edition, Boston: Addison-Wesley, 2011.
%
%October 2018 David Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(n<0||~isreal(n)||n~=fix(n))
    error('n must be a real non-negative integer.')
end

if(n>sqrt(flintmax))
   error('The algorithm will not work with n>sqrt(flintmax).')
end

if(nargin<2||isempty(numRuns))
    numRuns=25;
end

%If divisible by 2.
if(mod(n,2)==0)
   boolVal=false;
   return
end

%We now want to find an odd q such that n-1=2^k*q
q=n-1;
k=0;
pow2Val=1;
while(mod(q,2)==0)
    pow2Val=pow2Val*2;
    q=q/2;
    k=k+1;
end

for curRun=1:numRuns
    %Step P1
    x=randi(n-2)+1;%1<x<n
    %Step P2
    %This calculation method helps avoid overflow.
    j=0;
    %This does y=mod(x^q,n), but in a manner that avoids numerical
    %overflows unless x is very big.
    y=powModuloC(x,q,n);

    while(1)
        %Step P3
        if(y==n-1||y==1&&j==0)
            boolVal=true;
            break;
        end

        %Step P4
        if(y==1&&j>0)
            boolVal=false;
            return
        end

        j=j+1;
        if(j<k)
            y=mod(y^2,n);
        else
            boolVal=false;
            return;
        end
    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 iprime = primer ( n )

%*****************************************************************************80
%
%% PRIMER computes the prime numbers up to a given limit.
%
%  Discussion:
%
%    PRIMER returns the results of its computations in the vector
%    IPRIME.  IPRIME(I) is -1 if the number I is not prime, and
%    1 if I is prime.
%
%    The algorithm is a simple-minded sieve of Eristothenes, with
%    no attempt at efficiency.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 April 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the dimension of IPRIME, and the maximum
%    value that will be considered.
%
%    Output, integer IPRIME(N), records the results for each integer.
%    IPRIME(I) = -1 if I is not prime, and IPRIME(I) = 1 if I is
%    prime.  By convention, IPRIME(1) will be set to -1.
%

%
%  IPRIME(I) = 0 means we don't know if I is prime.
%
  iprime(1:n) = 0;
%
%  By convention, 1 is not prime.
%
  iprime(1) = -1;
  next = 1;
%
%  Examine the integers in order.
%
  for next = 2 : n

    if ( iprime(next) == 0 )
      iprime(next) = 1;
      for i = 2 * next : next : n
        iprime(i) = -1;
      end
    end

  end

  return
end


%  Script file: lsqfit.m
%
%  Purpose:
%    To perform a least-squares fit of an input data set
%    to a straight line, and print out the resulting slope
%    and intercept values.  The input data for this fit
%    comes from a user-specified input data file.
%
%  Record of revisions:
%      Date       Programmer          Description of change
%      ====       ==========          =====================
%    03/24/07    S. J. Chapman        Original code
%
% Define variables:
%   count     -- number of values read
%   filename  -- Input file name
%   fid       -- File id
%   msg       -- Open error message
%   n         -- Number of input data pairs (x,y)
%   slope     -- Slope of the line
%   sum_x     -- Sum of all input X values
%   sum_x2    -- Sum of all input X values squared
%   sum_xy    -- Sum of all input X*Y values
%   sum_y     -- Sum of all input Y values
%   x         -- An input X value
%   x_bar     -- Average X value
%   y         -- An input Y value
%   y_bar     -- Average Y value
%   y_int     -- Y-axis intercept of the line

% Initialize sums
n = 0; sum_x = 0; sum_y = 0; sum_x2 = 0; sum_xy = 0;

% Prompt user and get the name of the input file.
disp('This program performs a least-squares fit of an');
disp('input data set to a straight line. Enter the name');
disp('of the file containing the input (x,y) pairs:  ' );
filename = input(' ','s');

% Open the input file
[fid,msg] = fopen(filename,'rt');

% Check to see if the open failed.
if fid < 0

   % There was an error--tell user.
   disp(msg);

else

   % File opened successfully. Read the (x,y) pairs from
   % the input file.  Get first (x,y) pair before the
   % loop starts.
   [in,count] = fscanf(fid,'%g %g',2);

   while ~feof(fid)
      x = in(1);
      y = in(2);
      n      = n + 1;                  %
      sum_x  = sum_x + x;              % Calculate
      sum_y  = sum_y + y;              %   statistics
      sum_x2 = sum_x2 + x.^2;          %
      sum_xy = sum_xy + x * y;         %

      % Get next (x,y) pair
      [in,count] = fscanf(fid,'%f',[1 2]);

   end

   % Close the file
   fclose(fid);

   % Now calculate the slope and intercept.
   x_bar = sum_x / n;
   y_bar = sum_y / n;
   slope = (sum_xy - sum_x*y_bar) / (sum_x2 - sum_x*x_bar);
   y_int = y_bar - slope * x_bar;

   % Tell user.
   fprintf('Regression coefficients for the least-squares line:\n');
   fprintf('   Slope (m)     = %12.3f\n',slope);
   fprintf('   Intercept (b) = %12.3f\n',y_int);
   fprintf('   No of points  = %12d\n',n);

end


function [s,iter]=IAAFT(x,c,maxiter)
%Syntax: [s,iter]=IAAFT(x,c,maxiter)
%___________________________________
%
% Makes c Iterative Amplitude Adjusted Fourier Transformed (AAFT) surrogates
% of a time series x.
%
% s is the IAAFT surrogate time series.
% iter is the number of iterations needed of the i-th surrogate series.
% x is the original time series.
% c is the number of surrogates.
% maxiter is the maximum number of iterations allowed.
%
%
% References:
%
% Schreiber T, Schmitz A (1996): Improved surrogate data for nonlinearity
% tests. Physical Review Letters 77: 635-638
%
% I am grateful to Dr D. Kugiumtzis for providing me a version of his Matlab
% function concerning this algorithm.
%
%
% Alexandros Leontitsis
% Department of Education
% University of Ioannina
% 45110 - Dourouti
% Ioannina
% Greece
%
% University e-mail: me00743@cc.uoi.gr
% Lifetime e-mail: leoaleq@yahoo.com
% Homepage: http://www.geocities.com/CapeCanaveral/Lab/1421
%
% 20 November 2001.

if nargin<1 | isempty(x)==1
   error('You should provide a time series.');
else
   % x must be a vector
   if min(size(x))>1
      error('Invalid time series.');
   end
   x=x(:);
end

if nargin<2 | isempty(c)==1
   c=1;
else
   % c must be scalar
   if sum(size(c))>2
      error('c must be scalar.');
   end
   % c must be greater or equal than 1
   if c<1
      error('c must be greater or equal than 1.');
   end
end

if nargin<3 | isempty(maxiter)==1
   maxiter=1000;
else
   % maxiter must be scalar
   if sum(size(maxiter))>2
      error('maxiter must be scalar.');
   end
   % maxiter must be greater or equal than 1
   if maxiter<1
      error('maxiter must be greater or equal than 1.');
   end
end

% The magnitudes of x
amp=abs(fft(x));

% Shuffle x
s=shuffle(x,c);

% Sort x
[x,r]=sort(x);

for j=1:c

    % Calculate the phases of the shuffled series
    phase=angle(fft(s(:,j)));

    % Initialize the loop
    k=1;
    indold=r;
    converge = 0;
    while k<=maxiter & converge == 0
        % Make phase-randomized surrogates ...
        s(:,j)=amp.*exp(phase.*i);
        s(:,j)=real(ifft(s(:,j)));
        % ... and give them the distribution of x
        [s(:,j),T]=sort(s(:,j));
        [s(:,j),indnew]=sort(T);
        s(:,j)=x(indnew);
        % Check the convergence
        if indnew==indold
            converge=1;
        else
            indold=indnew;
            k=k+1;
        end
        % Loop again if needed, calculating the phases once more
        phase=angle(fft(s(:,j)));
    end

    % Get the iterations of each surrogate series
    iter(j)=k;

end


function lebesgue_test04 ( )

%*****************************************************************************80
%
%% LEBESGUE_TEST04 looks at Chebyshev4 points.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 January 2015
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'LEBESGUE_TEST04:\n' );
  fprintf ( 1, '  Analyze Chebyshev4 points.\n' );

  n_max = 11;
  l = zeros ( n_max, 1 );
  xfun = linspace ( -1.0, +1.0, 501 );
  xfun = xfun';

  for n = 1 : n_max
    x = chebyshev4 ( n );
    l(n) = lebesgue_constant ( n, x, xfun );
  end

  r8vec_print ( n_max, l, '  Chebyshev4 Lebesgue constants for N = 1 to 11:' )
%
%  Examine one case more closely.
%
  n = 11;
  x = chebyshev4 ( n );
  r8vec_print ( n, x, '  Chebyshev4 points for N = 11' );

  label = 'Chebyshev4 points for N = 11';
  filename = 'chebyshev4.png';
  lebesgue_plot ( n, x, xfun, label, filename );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Plot file saved as "s"\n', filename );

  return
end


function cU = chebTcoeffs2chebUcoeffs(cT)
%CHEBTCOEFFS2CHEBUCOEFFS   Convert Chebyshev-T coeffs. to Chebyshev-U coeffs.
%   CU = CHEBTCOEFFS2CHEBUCOEFFS(CT) takes a column vector of coefficients of a
%   polynomial represented as an expansion in the Chebyshev polynomials of the
%   first kind T_k(x) (ordered starting with the coefficient of T_0(x)) and
%   returns the column vector of coefficients of the same polynomial expanded
%   in Chebyshev polynomials of the second kind U_k(x) (ordered starting with
%   the coefficient of U_0(x)).
%
%   If CT is a matrix, the conversion is performed column-wise.

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

if ( isempty(cT) )
    cU = [];
    return;
end

% We compute 2nd-kind coefficients from the 1st-kind coefficients
% using the recurrence T_n(x) = (1/2)*(U_n(x) - U_{n-2}(x)).  The
% coefficient of U_n requires the coefficients of T_n and T_{n + 2}, so we
% pad with two zero-coefficients initially.
nCols = size(cT, 2);
cU = [cT ; zeros(2,nCols)];

% Run the recurrence.
cU(1,:) = 2*cT(1,:);
cU = 0.5*[cU(1:end-2,:) - cU(3:end,:) ; cU(end-1:end,:)];
cU = cU(1:end-2,:);

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 = ((1.0/m) .* (X' * X));
[U, S, V] = svd(Sigma);

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

end


function [J, grad] = costFunctionReg(theta, X, y, lambda)
%COSTFUNCTIONREG Compute cost and gradient for logistic regression with regularization
%   J = COSTFUNCTIONREG(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

J = ((-1/m)*((y'*log(sigmoid(X*theta))) + ((1-y)'*log(1 - sigmoid(X*theta))))) + ((lambda/(2*m))*((theta' * theta)-(theta(1)^2)));

grad = ((1/m)*(X' * (sigmoid(X*theta) - y)))+((lambda/m)*(theta));

grad(1) = grad(1) - ((lambda/m)*(theta(1)));

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

end


function a = c8vec_unity ( n )

%*****************************************************************************80
%
%% C8VEC_UNITY returns the N roots of unity.
%
%  Discussion:
%
%    A(1:N) = exp ( 2 * PI * (0:N-1) / N )
%
%    A(1:N)^N = ( (1,0), (1,0), ..., (1,0) ).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    13 September 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of elements of A.
%
%    Output, complex A(N,1), the N roots of unity.
%
  x = 0 : 2 : 2 * n - 2;
  theta = pi * ( x' ) / n;
  a(1:n,1) = cos ( theta ) + i * sin ( theta );

  return
end


function area = sphere_unit_area_nd ( dim_num )

%*****************************************************************************80
%
%% SPHERE_UNIT_AREA_ND computes the surface area of a unit sphere in ND.
%
%  Discussion:
%
%    The unit sphere in ND satisfies:
%
%      sum ( 1 <= I <= DIM_NUM ) X(I) * X(I) = 1
%
%    Results for the first few values of N are:
%
%    DIM_NUM   Area
%
%     2    2        * PI
%     3    4        * PI
%     4  ( 2 /   1) * PI**2
%     5  ( 8 /   3) * PI**2
%     6  ( 1 /   1) * PI**3
%     7  (16 /  15) * PI**3
%     8  ( 1 /   3) * PI**4
%     9  (32 / 105) * PI**4
%    10  ( 1 /  12) * PI**5
%
%    For the unit sphere, Area(DIM_NUM) = DIM_NUM * Volume(DIM_NUM)
%
%    Sphere_Unit_Area ( DIM_NUM ) = 2 * PI**(DIM_NUM/2) / Gamma ( DIM_NUM / 2 )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer DIM_NUM, the dimension of the space.
%
%    Output, real SPHERE_UNIT_AREA_ND, the area of the sphere.
%
  if ( mod ( dim_num, 2 ) == 0 )
    m = floor ( dim_num / 2 );
    area = 2.0 * pi^m;
    for i = 1 : m-1
      area = area / i;
    end
  else
    m = floor ( ( dim_num - 1 ) / 2 );
    area = pi^m * 2.0^dim_num;
    for i = m+1 : 2*m
      area = area / i;
    end
  end

  return
end


% ECEF2LLA - convert earth-centered earth-fixed (ECEF)
%            cartesian coordinates to latitude, longitude,
%            and altitude
%
% USAGE:
% [lat,lon,alt] = ecef2lla(x,y,z)
%
% lat = geodetic latitude (radians)
% lon = longitude (radians)
% alt = height above WGS84 ellipsoid (m)
% x = ECEF X-coordinate (m)
% y = ECEF Y-coordinate (m)
% z = ECEF Z-coordinate (m)
%
% Notes: (1) This function assumes the WGS84 model.
%        (2) Latitude is customary geodetic (not geocentric).
%        (3) Inputs may be scalars, vectors, or matrices of the same
%            size and shape. Outputs will have that same size and shape.
%        (4) Tested but no warranty; use at your own risk.
%        (5) Michael Kleder, April 2006

function [lat,lon,alt] = ecef2lla(x,y,z)

% WGS84 ellipsoid constants:
a = 6378137;
e = 8.1819190842622e-2;

% calculations:
b   = sqrt(a^2*(1-e^2));
ep  = sqrt((a^2-b^2)/b^2);
p   = sqrt(x.^2+y.^2);
th  = atan2(a*z,b*p);
lon = atan2(y,x);
lat = atan2((z+ep^2.*b.*sin(th).^3),(p-e^2.*a.*cos(th).^3));
N   = a./sqrt(1-e^2.*sin(lat).^2);
alt = p./cos(lat)-N;

% return lon in range [0,2*pi)
lon = mod(lon,2*pi);

% correct for numerical instability in altitude near exact poles:
% (after this correction, error is about 2 millimeters, which is about
% the same as the numerical precision of the overall function)

k=abs(x)<1 & abs(y)<1;
alt(k) = abs(z(k))-b;

return


function area = hypersphere_01_area ( dim_num )

%*****************************************************************************80
%
%% HYPERSPHERE_01_AREA computes the surface area of a unit sphere in ND.
%
%  Discussion:
%
%    The unit sphere in ND satisfies:
%
%      sum ( 1 <= I <= DIM_NUM ) X(I) * X(I) = 1
%
%    Results for the first few values of N are:
%
%    DIM_NUM   Area
%
%     2    2        * PI
%     3    4        * PI
%     4  ( 2 /   1) * PI^2
%     5  ( 8 /   3) * PI^2
%     6  ( 1 /   1) * PI^3
%     7  (16 /  15) * PI^3
%     8  ( 1 /   3) * PI^4
%     9  (32 / 105) * PI^4
%    10  ( 1 /  12) * PI^5
%
%    For the unit sphere, Area(DIM_NUM) = DIM_NUM * Volume(DIM_NUM)
%
%    Sphere_Unit_Area ( DIM_NUM ) = 2 * PI^(DIM_NUM/2) / Gamma ( DIM_NUM / 2 )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer DIM_NUM, the dimension of the space.
%
%    Output, real SPHERE_UNIT_AREA_ND, the area of the sphere.
%
  if ( mod ( dim_num, 2 ) == 0 )
    m = floor ( dim_num / 2 );
    area = 2.0 * pi^m;
    for i = 1 : m-1
      area = area / i;
    end
  else
    m = floor ( ( dim_num - 1 ) / 2 );
    area = pi^m * 2.0^dim_num;
    for i = m+1 : 2*m
      area = area / i;
    end
  end

  return
end


function [maxSum,startIdx,endIdx]=maxSubsequenceSum(a)
%%MAXSUBSEQUENCESUM  Given a vector of numbers that might be positive or
%                    find the maximum value that can be obtained by summing
%                    a subsequence of the set a.
%
%INPUTS: a  A 1XN or NX1 vector of real numbers.
%
%OUTPUTS: maxSum The maximum value of sums possible by summing consecutive
%                values in a. If a only contains negative values, then this
%                will be zero as the minimum value is obtained by summing
%                nothing in a.
%startIdx,endIdx The beginning and ending indices of the maximum
%                subsequence of a. If a is all negative, these will both be
%                zero.
%
%The solution to the maximum subsequence sum is described in Chapter 2.4
%of [1]. Multiple approaches to the problem are described in [2]. The
%algorithm has O(N) complexity as noted in its presentation in [3].
%
%The algorithm has been slightly modified to handle arrays that contain all
%negative or zero elements.
%
%REFERENCES:
%[1] M.A.Weiss, Data Structures and Algorithm Analysis in C++, 2nd ed.
%    Reading, MA: Addison-Wesley, 1999.
%[2] J. Bentley, "Algorithm design techniques," Communications of the ACM,
%    vol. 27, no. 9, pp. 865-871, Sep. 1984.
%[3] D. Gries, "A note on the standard strategy for developing loop
%    invariants and loops," Department of Computer Science, Cornell
%    University, Ithaca, NY, Tech. Rep. TR 82-531, Oct. 1982.
%
%July 2015 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

numElA=length(a);

maxSum=0;
thisSum=0;
thisStartIdx=1;

startIdx=0;
endIdx=0;

maxVal=-Inf;
maxIdx=0;

for j=1:numElA
    %Finding the maximum value is needed so that something can be returned if
    %an array of only zero or negative numbers is passed.
    if(a(j)>maxVal)
        maxVal=a(j);
        maxIdx=j;
    end

    thisSum=thisSum+a(j);

    if(thisSum>maxSum)
        maxSum=thisSum;
        startIdx=thisStartIdx;
        endIdx=j;
    elseif(thisSum<0)
        thisSum=0;
        thisStartIdx=j+1;
    end
end

if(maxVal<=0)
    %If all of the entries are negative or zero, then return the index of
    %the maximum element.
    maxSum=maxVal;
    startIdx=maxIdx;
    endIdx=maxIdx;
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 g = sigmoid(z)
%SIGMOID Compute sigmoid functoon
%   J = SIGMOID(z) computes the sigmoid of z.

% You need to return the following variables correctly
g = zeros(size(z));

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the sigmoid of each value of z (z can be a matrix,
%               vector or scalar)

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

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

end


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

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

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

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost of a particular choice of theta.
%               You should set J to the cost.
%               Compute the partial derivatives and set grad to the partial
%               derivatives of the cost w.r.t. each parameter in theta
%
% Note: grad should have the same dimensions as theta
%

sigmo = sigmoid(X * theta);

J = 1 / m * (-y' * log(sigmo) - (1 - y') * log(1 - sigmo));
grad = 1 / m * ((sigmo - y)' * X)';

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

end


function cdf = pareto_cdf ( x, a, b )

%*****************************************************************************80
%
%% PARETO_CDF evaluates the Pareto CDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the argument of the CDF.
%
%    Input, real A, B, the parameters of the PDF.
%    0.0 < A,
%    0.0 < B.
%
%    Output, real CDF, the value of the CDF.
%
  if ( x < a )
    cdf = 0.0;
  else
    cdf = 1.0 - ( a / x )^b;
  end

  return
end


function [p,S] = polyfit(x,y,n)
    %POLYFIT Polynomial curve fitting.
    %	POLYFIT(x,y,n) finds the coefficients of a polynomial p(x) of
    %	degree n that fits the data, p(x(i)) ~= y(i), in a least-squares sense.
    %
    %	[p,S] = POLYFIT(x,y,n) returns the polynomial coefficients p and a
    %	matrix S for use with POLYVAL to produce error estimates on predictions.
    %	If the errors in the data, y, are independent normal with constant
    %	variance, POLYVAL will produce error bounds which contain at least 50%
    %	of the predictions.
    %
    %	See also POLY, POLYVAL, ROOTS.

    %	J.N. Little 4-21-85, 8-23-86; CBM, 12-27-91 BAJ, 5-7-93.
    %	Copyright (c) 1984-94 by The MathWorks, Inc.

    % The regression problem is formulated in matrix format as:
    %
    %    y = V*p    or
    %
    %          3  2
    %    y = [x  x  x  1] [p3
    %                      p2
    %                      p1
    %                      p0]
    %
    % where the vector p contains the coefficients to be found.  For a
    % 7th order polynomial, matrix V would be:
    %
    % V = [x.^7 x.^6 x.^5 x.^4 x.^3 x.^2 x ones(size(x))];

    %report_this_filefun(mfilename('fullpath'));

    if any(size(x) ~= size(y))
        error('X and Y vectors must be the same size.')
    end

    x = x(:);
    y = y(:);

    % Construct Vandermonde matrix.
    V(:,n+1) = ones(length(x),1);
    for j = n:-1:1
        V(:,j) = x.*V(:,j+1);
    end

    % Solve least squares problem.
    [Q,R] = eval('qr(V,0)','qr(V)');

    % The current PC version does not have the two-argument form of qr
    [rows, cols] = size(R);
    if rows ~= cols
        R = R(1:cols,:);
        Q = Q(:,1:cols);
    end

    p = R\(Q'*y);    % Same as p = V\y;
    r = y - V*p;
    p = p';          % Polynomial coefficients are row vectors by convention.

    % S is a structure containing three elements: the Cholesky factor of the
    % Vandermonde matrix, the degrees of freedom and the norm of the residuals.

    df = length(y) - (n+1);
    S = [R; [df zeros(1,n)]; [norm(r) zeros(1,n)]];


function a = r8sd_dif2 ( m, n, ndiag, offset )

%*****************************************************************************80
%
%% R8SD_DIF2 returns the DIF2 matrix in R8SD 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 number of rows and columns.
%
%    Input, integer NDIAG, the number of diagonals that are stored.
%    NDIAG must be at least 2.
%
%    Input, integer OFFSET(NDIAG), the offsets for the diagonal
%    storage.  It is simply assumed that OFFSET(1) = 0 and OFFSET(2) = 1.
%
%    Output, real A(N,NDIAG), the matrix.
%
  a = zeros(n,ndiag);

  a(1:n,  1) =  2.0;
  a(1:n-1,2) = -1.0;

  return
end


function [f] = binomial(n,d)
%BINOMIAL  calculate the binomial coefficient
%          n and d may be complex and any equal size
%
%        n!
% f = --------
%     d!(n-d)!
%
%usage: b = binomial(n,d)
%
%tested on version 5.3.1
%
%see also: Gamma, Prod
%see also: mhelp binomial
%
%not correct for negative integer arguments!

%Paul Godfrey
%pgodfrey@conexant.com
%8-12-00

nsize=size(n); n=n(:);
dsize=size(d); d=d(:);

if min(nsize==dsize)==0
   error('Input argument size mismatch!')
end

if (0<n & 0<=d & round(n)==n & round(d)==d & n>=d & max(size(n))==1 & max(size(d))==1)
   f = prod((d+1):n)/prod(1:(n-d));
else
   z=gamma([n d n-d]+1);
   f=z(:,1)./(z(:,2).*z(:,3));
end

f=reshape(f,nsize);

return

%a demo of this routine is
dx=1/16;
dy=dx;
x=-4:dx:4;
y=-4:dy:4;
[X,Y]=meshgrid(x,y);
f=binomial(X,Y);
p=find(abs(f)>4);
%f(p)=sign(real(f(p)))*4;
f(p)=NaN;
mesh(x,y,real(f))
view([23 54]);
rotate3d


function [C,dt] = VBA_getNtuples(k,n,verbose)
% gets all n-draws (with replacement) from a k-urn.
% [C] = VBA_getNtuples(k,n,verbose)
% This function construct all the n-tuples that can be obtained (with
% replacement) from an urn containing k marbles.
% A couple of examples is worth a long description:
%
% VBA_getNtuples(2,3)
%
% ans =
%
%      1     1     1     1     2     2     2     2
%      1     1     2     2     1     1     2     2
%      1     2     1     2     1     2     1     2
%
% VBA_getNtuples(3,2)
%
% ans =
%
%      1     1     1     2     2     2     3     3     3
%      1     2     3     1     2     3     1     2     3
%
% IN:
%   - k: the cardinality of the set, whose permutations are replicated over
%   n dimensions
%   - n: the dimension of the tuple, whose entries are elements of the set
%   {1,2,...,k}.
% OUT:
%   - C: a nXn^p matrix, whose columns are the n-draws
% Thanks to Antonin "magic" Ancelle!

try; verbose;catch;verbose=0;end
tic;
np = k^n;
if verbose
    fprintf(1,['Getting the ',num2str(np),' ',num2str(n),'-draws from ',num2str(k),'-urn...'])
end
C = zeros(n,np); % pre-allocate k-permutations
for ind = 1:n
    for j = 1:k^(ind-1)
        nbch = np/(k^(ind-1));
        C(ind,(1+(j-1)*nbch):j*nbch) = ceil((1:nbch)/(nbch/k));
    end
end
dt = toc;
if verbose
    fprintf(1,[' OK. (took ',num2str(dt),' seconds)'] )
    fprintf(1,'\n')
end

return


function area = polygon_area_2d ( n, v )

%*****************************************************************************80
%
%% POLYGON_AREA_2D computes the area of a polygon in 2D.
%
%  Discussion:
%
%    AREA = 1/2 * abs ( sum ( 1 <= I <= N ) X(I) * ( Y(I+1) - Y(I-1) ) )
%    where Y(0) should be replaced by Y(N), and Y(N+1) by Y(1).
%
%    If the vertices are given in counterclockwise order, the area
%    will be positive.  If the vertices are given in clockwise order,
%    the area will be negative.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 January 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of vertices of the polygon.
%
%    Input, real V(2,N), the vertices.
%
%    Output, real AREA, the area of the polygon.
%
  area = 0.0;

  for i = 1 : n

    im1 = i4_wrap ( i-1, 1, n );
    ip1 = i4_wrap ( i+1, 1, n );

    area = area + v(1,i) * ( v(2,ip1) - v(2,im1) );

  end

  area = 0.5 * area;

  return
end


function [ xmin, ymin ] = minquad ( x1, y1, x2, y2, x3, y3 )

%*****************************************************************************80
%
%% MINQUAD finds a local minimum of F(X) = A * X * X + B * X + C.
%
%  Discussion:
%
%    MINQUAD is primarily intended as a utility routine.
%    The square of the distance function between a point
%    and a line segment has the form of F(X).  Hence, we can seek
%    the line on the second segment which minimizes the square of
%    the distance to the other line segment.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 March 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X1, Y1, X2, Y2, X3, Y3, three sets of data
%    of the form ( X, F(X) ).  The three X values must be distinct.
%
%    Output, real XMIN, YMIN.  XMIN is a point within the interval
%    spanned by X1, X2 and X3, at which F takes its local minimum value YMIN.
%

%
%  Refuse to deal with coincident data.
%
  if ( x1 == x2 | x2 == x3 | x3 == x1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'MINQUAD - Fatal error!\n' );
    fprintf ( 1, '  X values are equal.\n' );
    error ( 'MINQUAD - Fatal error!' );
  end
%
%  Find the interval endpoints.
%
  xleft = min ( x1, min ( x2, x3 ) );
  xrite = max ( x1, max ( x2, x3 ) );
%
%  Find the minimizer and its function value, over the three input points.
%
  if ( y1 <= y2 & y1 <= y3 )
    xmin = x1;
    ymin = y1;
  elseif ( y2 <= y1 & y2 <= y3 )
    xmin = x2;
    ymin = y2;
  else
    xmin = x3;
    ymin = y3;
  end
%
%  Find the minimizer and its function value over the real line.
%
  [ x, y, ierror ] = parabola_ex ( x1, y1, x2, y2, x3, y3 );
%
%  If F is linear, then take the already computed min.
%
  if ( ierror == 2 )
%
%  If F has a maximum, then take the already computed min.
%
  elseif ( ymin < y )
%
%  If the minimizer is to the left, take the already computed min.
%
  elseif ( x < xleft )
%
%  If the minimizer is to the right, take the already computed min.
%
  elseif ( xrite < x )

  else

    xmin = x;
    ymin = y;

  end

  return
end


%% Homework 11
% We wish to solve the following PDE using the approximate factorization
% method:
%
% $\frac{\partial \phi }{\partial t}+U(x,y)\frac{\partial \phi }{\partial
% x}+V(x,y)\frac{\partial \phi }{\partial y}=\alpha \left (
% \frac{\partial^2 \alpha }{\partial x^2}-\frac{\partial^2 \phi }{\partial
% y^2} \right)$
%
% This is 2D convection-diffusion equation

close all
clear all

%% Grid

ly = [-1,1];                lx =[0,10];
dy = 0.2;                   dx = 0.5;
y  = ly(1):dy:ly(2);        x  = lx(1):dx:lx(2); % Physical grid
q  = length(y);             p  = length(x);
phi = zeros(q,p); % Numerical grid

t_end = 1;      dt = 0.1;   n = (t_end-0)/dt;

%% Boundary Conditions

phi(:,1) = 1;
phi(1,:) = 1;

%% Constants & coheficients
% assume: $\alpha = const$.

alpha = 1;

% 1. assume: $u(x,y)=x*y% and $v(x,y)=x/(y+0.1)$,
% 2. assume: $u(x,y)=1$ and $v(x,y)=1$.

u = zeros(q,p);
for j = 1:q
    for i = 1:p
        u(j,i) = x(i)*y(j);
        % u(j,i) = 1
    end
end

v = zeros(q,p);
for j = 1:q
    for i = 1:p
        v(j,i) = (1/(y(j)+0.1))*x(i);
        % v(j,i) = 1
    end
end

%% Formulate Base matrices
% Dy
% Constants
a = dt/2*(alpha/dy^2 - v/(2*dy));
b = (1 - dt/dy^2);
c = dt/2*(alpha/dy^2 + v/(2*dy));

Qy = zeros(q-2,q-2,p);
for i = 2:p-1
    e = zeros(q-2,3);
    e(:,3) =  a(1:q-2,i);
    e(:,2) =  b*ones(q-2,1); % But the last No. in de Diag must be modif.:
    e(q-2,2) =  a(q-1,i)-b(q-1,i);
    e(:,1) =  c(3:q,i);
    Qy(:,:,i) = spdiags(e,-1:1,q-2,q-2);
end

% Dx
% Constants
% f = dt/2*(alpha/dx^2 - u/(2*dx));
% g = (1 - dt/dx^2);
% h = dt/2*(alpha/dx^2 - u/(2*dx));
%
% e1 = a(1,3:p-1);
% e2 = b*ones(1,p-2);
% e3 = c(1,2:p-2);
% Qx = spdiags([e3 e2 e1],[-1 0 1],p-2,p-2);

%% Compute $f$ for time n step

%% Boundary Conditions


function [ res, jac ] = opt05_rj ( x, flag, a )

%*****************************************************************************80
%
%% OPT05_RJ evaluates RES and JAC for test case #5.
%
%  Discussion:
%
%    This example is known as the Rosenbrock "banana" function.
%
%    This example is discussed in Dennis and Schnabel, page 157.
%    (There is a misprint in Dennis and Schabel.  When they print the
%    rescaled function, they include an incorrect sign on the second term.)
%
%    This example tests the scaling matrices.
%
%    Suggested starting points are
%
%      X(init) = ( -1.2/A, A)
%      or
%      X(init) = ( 6.39/A, -0.221*A )
%
%    The optimizing value is
%
%      X* = (1/A, A)
%
%    for which
%
%      RES(X*) = (0,0).
%
%    A typical value of A is 1.  For values of A that are greater or lesser
%    than 1, the optimization can take significantly longer.
%
%  Modified:
%
%    02 January 2008
%
%  Author:
%
%    Jeff Borggaard,
%    Gene Cliff,
%    Virginia Tech.
%
%  Reference:
%
%    John Dennis, Robert Schnabel,
%    Numerical Methods for Unconstrained Optimization
%    and Nonlinear Equations,
%    SIAM, 1996,
%    ISBN13: 978-0-898713-64-0,
%    LC: QA402.5.D44.
%
%  Parameters:
%
%    Input, real X(2), the evaluation point.
%
%    Input, string FLAG, indicates what must be computed.
%    'f' means only the value of RES is needed,
%    'g' means only the value of JAC is needed,
%    'all' means RES and JAC are needed.
%    It is acceptable to behave as though FLAG was 'all'
%    on every call.
%
%    Input, real A, the scale factor.  A typical value is 1.
%    A should not be 0.
%
%    Output, real RES(2,1), the residual column vector.
%
%    Output, real J(2,2), the Jacobian matrix.
%
  n = length ( x );

  if ( n ~= 2 )
    fprintf ( '\n' );
    fprintf ( 'OPT05_RJ - Fatal error!\n' );
    fprintf ( '  The input vector X should have length 2.\n'),
    fprintf ( '  Instead, it has length = %d.\n', n );
    keyboard
  end

  if ( a == 0 )
    fprintf ( '\n' );
    fprintf ( 'OPT05_RJ - Fatal error!\n' );
    fprintf ( '  The scale factor A should be nonzero.\n'),
    keyboard
  end

  res(1,1) = 10 * ( ( a * x(1) )^2 - x(2) / a );
  res(2,1) = 1 - a * x(1);

  jac(1,1) = 20 * a * a * x(1);
  jac(1,2) = - 10 / a;

  jac(2,1) = - a;
  jac(2,2) = 0.0;


function   r = assortativity(CIJ,flag)
%ASSORTATIVITY      Assortativity coefficient
%
%   r = assortativity(CIJ,flag);
%
%   The assortativity coefficient is a correlation coefficient between the
%   degrees of all nodes on two opposite ends of a link. A positive
%   assortativity coefficient indicates that nodes tend to link to other
%   nodes with the same or similar degree.
%
%   Inputs:     CIJ,        binary directed/undirected connection matrix
%               flag,       1 = directed graph; 0 = non-directed graph
%
%   Outputs:    r,          assortativity
%
%   Notes: The function accepts weighted networks, but all connection
%   weights are ignored. The main diagonal should be empty.
%
%   Reference:  Newman (2002) Phys Rev Lett 89:208701.
%
%
%   Olaf Sporns, Indiana University, 2007/2008
%   Vassilis Tsiaras, University of Crete, 2009

if (flag==0)
    [deg] = degrees_und(CIJ);
    [i,j] = find(triu(CIJ,1)>0);
    K = length(i);
    for k=1:K
        degi(k) = deg(i(k));
        degj(k) = deg(j(k));
    end;
end;
if (flag==1)
    [id,od,deg] = degrees_dir(CIJ);
    [i,j] = find(CIJ>0);
    K = length(i);
    for k=1:K
        degi(k) = deg(i(k));
        degj(k) = deg(j(k));
    end;
end;

% compute assortativity
r = (sum(degi.*degj)/K - (sum(0.5*(degi+degj))/K)^2)/(sum(0.5*(degi.^2+degj.^2))/K - (sum(0.5*(degi+degj))/K)^2);


% Sparse covariance estimation for Gaussian variables
% Joëlle Skaf - 04/24/08
% (a figure is generated)
%
% Suppose y \in\reals^n is a Gaussian random variable with zero mean and
% covariance matrix R = \Expect(yy^T), with sparse inverse S = R^{-1}
% (S_ij = 0 means that y_i and y_j are conditionally independent).
% We want to estimate the covariance matrix R based on N independent
% samples y1,...,yN drawn from the distribution, and using prior knowledge
% that S is sparse
% A good heuristic for estimating R is to solve the problem
%           maximize    logdet(S) - tr(SY) - lambda*sum(sum(abs(S)))
%           subject to  S >= 0
% where Y is the sample covariance of y1,...,yN, and lambda is a sparsity
% parameter to be chosen or tuned.
% A figure showing the sparsity (number of nonzeros) of S versus lambda
% is generated.

% Input data
rand('state',0); %#ok
randn('state',0); %#ok
n = 10;
N = 100;
Strue = sprandsym(n,0.5,0.01,1);
Strue(abs(Strue(:))<=1e-4) = 0;
nnz_true = nnz(Strue);
R = inv(full(Strue));
y_sample = sqrtm(R)*randn(n,N);
Y = cov(y_sample');
Nlambda = 20;
lambda = logspace(-2, 3, Nlambda);
nnz_i = zeros(1,Nlambda);

for i=1:Nlambda
    disp(['i = ' num2str(i) ', lambda(i) = ' num2str(lambda(i))]);
    % Maximum likelihood estimate of R^{-1}
    cvx_begin sdp quiet
        variable S(n,n) symmetric
        maximize log_det(S) - trace(S*Y) - lambda(i)*sum(sum(abs(S)))
        S >= 0; %#ok
    cvx_end
    nnz_i(i) = sum(abs(S(:))>1e-4);
end

figure;
semilogx(lambda, nnz_i);
hold on;
semilogx(lambda, nnz_true*ones(1,Nlambda),'r');
xlabel('\lambda');
legend('nonzeros in S', 'nonzeros in R^{-1}');


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

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

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

flip = 0;
if dx >= dy
    if x1 > x2
        % swap coordinates to draw from left to right.
        t = x1; x1 = x2; x2 = t;
        t = y1; y1 = y2; y2 = t;
        flip = 1;
    end

    % compute line slope, and y from x
    m = (y2 - y1) / (x2 - x1);
    x = (x1:x2).';
    y = round(y1 + m * (x - x1));

else
    if y1 > y2
        % swap coordinates to draw from bottom to top.
        t = x1; x1 = x2; x2 = t;
        t = y1; y1 = y2; y2 = t;
        flip = 1;
    end

    % compute line slope, and x from y
    m = (x2 - x1) / (y2 - y1);
    y = (y1:y2).';
    x = round(x1 + m * (y - y1));
end

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


function s = collatz ( seed )

%*****************************************************************************80
%
%% COLLATZ computes the Collatz sequence for a given starting point.
%
%  Discussion:
%
%    The Collatz sequence is defined recursively as follows:
%
%      Let T be the current entry of the sequence, and U the next:
%
%      If T = 1, the sequence terminates (or U = 1, your choice);
%      Else if T is even, U = T / 2;
%      Else (if T is odd, and greater than 1) U = 3 * T + 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 February 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer SEED, the starting point for the sequence.
%    SEED must be positive.
%
%    Output, integer S[*], the Collatz sequence, starting with SEED.
%    Once the sequence reaches the value 1, no more entries are computed.
%
  if ( seed <= 0 )
    s = [];
    return
  end

  n = 1;
  t = seed;
  s(n) = t;

  while ( t ~= 1 )

    if ( 2 * round ( t / 2 ) == t )
      t = t / 2;
    else
      t = 3 * t + 1;
    end

    n = n + 1;
    s(n) = t;

  end

  return
end


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);
%

U_reduced = U(:, 1:K);
Z = X * U_reduced;

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

end


function value = r8_exponential_sample ( lambda )

%*****************************************************************************80
%
%% R8_EXPONENTIAL_SAMPLE samples the exponential PDF.
%
%  Discussion:
%
%    Note that the parameter LAMBDA is a multiplier.  In some formulations,
%    it is used as a divisor instead.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 June 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real LAMBDA, the parameter of the PDF.
%
%    Output, real VALUE, a sample of the PDF.
%
  r = r8_uniform_01_sample ( );

  value = - log ( r ) * lambda;

  return
end


function [xi,w]=thirdOrder2DCubPoints()
%%THIRDORDER2DCUBPOINTS Generate third-order cubature points
%               for integration over a 2-dimensional cube with bounds of
%               (-1,-1), (-1,1), (1,1), and (1,-1).
%
%INPUTS: None
%
%OUTPUTS: xi This is a 2XnumCubPoints set of points for the standard
%            square.
%          w A 1XnumCubPoints set of cubature weights. This sums to the
%            volume of the standard square (4).
%
%This function implements the points given in [1] (4 points).
%
%EXAMPLE:
%We compare a 2nd-order moment computed using these cubature points
%to one computed using monomialIntCube (a 3rd order moment would have just
%been 0). The results are the same within typical finite precision limits.
% [xi,w]=thirdOrder2DCubPoints();
% alpha=[2;0];
% theMoment=findMomentFromSamp(alpha,xi,w);
% intVal=monomialIntCube(alpha);
% RelErr=(theMoment-intVal)/intVal
%
%REFERENCES:
%[1] F. D. Witherden and P. E. Vincent, "On the identification of symmetric
%    quadrature rules for finite element methods," Computer and Mathematics
%    with Applications, vol. 69, no. 10, pp. 1232-1241, May 2015.
%
%October 2022 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

M=[0.57735026918962576450914878050195745565,   0.57735026918962576450914878050195745565, 1;
   0.57735026918962576450914878050195745565,  -0.57735026918962576450914878050195745565, 1;
  -0.57735026918962576450914878050195745565,   0.57735026918962576450914878050195745565, 1;
  -0.57735026918962576450914878050195745565,  -0.57735026918962576450914878050195745565, 1];
w=M(:,3);
xi=M(:,1:2)';

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.


%ANGDIFF Difference of two angles
%
% ANGDIFF(TH1, TH2) is the difference between angles TH1 and TH2, ie. TH1-TH2
% on the circle.  The result is in the interval [-pi pi).  Either or both
% arguments can be a vector:
% - If TH1 is a vector, and TH2 a scalar then return a vector where TH2 is modulo
%   subtracted from the corresponding elements of TH1.
% - If TH1 is a scalar, and TH2 a vector then return a vector where the
%   corresponding elements of TH2 are modulo subtracted from TH1.
% - If TH1 and TH2 are vectors then return a vector whose elements are the modulo
%   difference of the corresponding elements of TH1 and TH2, which must be the
%   same length.
%
% ANGDIFF(TH) as above but TH=[TH1 TH2].
%
% ANGDIFF(TH) is the equivalent angle to the scalar TH in the interval [-pi pi).
%
% Notes::
% - The MathWorks Robotics Systems Toolbox defines a function with the same name
%   which computes TH2-TH1 rather than TH1-TH2.
% - If TH1 and TH2 are both vectors they should have the same
%   orientation, which the output will assume.
%

% Copyright (C) 1993-2019 Peter I. Corke
%
% This file is part of The Spatial Math Toolbox for MATLAB (SMTB).
%
% Permission is hereby granted, free of charge, to any person obtaining a copy
% of this software and associated documentation files (the "Software"), to deal
% in the Software without restriction, including without limitation the rights
% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
% of the Software, and to permit persons to whom the Software is furnished to do
% so, subject to the following conditions:
%
% The above copyright notice and this permission notice shall be included in all
% copies or substantial portions of the Software.
%
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
% FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
% COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
% IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
% CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
%
% https://github.com/petercorke/spatial-math

function d = angdiff(th1, th2)

    switch nargin
        case 1
            if length(th1) == 2
                d = th1(1) - th1(2);
            else
                d = th1;
            end
        case 2
            if length(th1) > 1 && length(th2) > 1
                % if both arguments are vectors, they must be the same
                assert(all(size(th1) == size(th2)), 'SMTB:angdiff:badarg', 'vectors must be same shape');
            end
            % th1 or th2 could be scalar
            d = th1 - th2;
    end

    % wrap the result into the interval [-pi pi)
    d = mod(d+pi, 2*pi) - pi;
end

% Simplistic version of the code, easy to see what it does, but slow...
%
% for very negative angles keep adding 2pi
%     while true
%         k = find(d < -pi);
%         if isempty(k)
%             break;
%         end
%         d(k) = d(k) + 2*pi;
%     end
%
%     % for very positive angles keep subtracting 2pi
%     while true
%         k = find(d > pi);
%         if isempty(k)
%             break;
%         end
%         d(k) = d(k) - 2*pi;
%     end


function [new_mu, new_Sigma, new_Sigma2] = collapse_mog(mu, Sigma, coefs)
% COLLAPSE_MOG Collapse a mixture of Gaussians to a single Gaussian by moment matching
% [new_mu, new_Sigma] = collapse_mog(mu, Sigma, coefs)
%
% coefs(i) - weight of i'th mixture component
% mu(:,i), Sigma(:,:,i) - params of i'th mixture component

% S = sum_c w_c (S_c + m_c m_c' + m m' - 2 m_c m')
%   = sum_c w_c (S_c + m_c m_c') + m m' - 2 (sum_c m_c) m'
%   = sum_c w_c (S_c + m_c m_c') - m m'

new_mu = sum(mu * diag(coefs), 2); % weighted sum of columns

n = length(new_mu);
new_Sigma = zeros(n,n);
new_Sigma2 = zeros(n,n);
for j=1:length(coefs)
  m = mu(:,j) - new_mu;
  new_Sigma = new_Sigma + coefs(j) * (Sigma(:,:,j) + m*m');
  new_Sigma2 = new_Sigma2 + coefs(j) * (Sigma(:,:,j) + mu(:,j)*mu(:,j)');
end
%assert(approxeq(new_Sigma, new_Sigma2 - new_mu*new_mu'))


function rad = deg2rad(deg)
%DEG2RAD Convert angle from degrees to radians
%
%   Usage:
%   R = deg2rad(D)
%   convert an angle in degrees to an angle in radians.
%
%   Example
%   deg2rad(180)    % gives pi
%   ans =
%       3.1416
%   deg2rad(60)     % gives pi/3
%   ans =
%       1.0472
%
%   See Also
%   angles2d, rad2deg
%
%   ---------
%   author : David Legland
%   INRA - TPV URPOI - BIA IMASTE
%   created the 09/12/2004.
%

rad = deg*pi/180;


function a = schur_block ( n, x, y )

%*****************************************************************************80
%
%% SCHUR_BLOCK returns the SCHUR_BLOCK matrix.
%
%  Formula:
%
%    if ( i == j )
%      a(i,j) = x( (i+1)/2 )
%    else ( mod ( i, 2 ) == 1 & j == i + 1 )
%      a(i,j) = y( (i+1)/2 )
%    else ( mod ( i, 2 ) == 0 & j == i - 1 )
%      a(i,j) = -y( (i+1)/2 )
%    else
%      a(i,j) = 0.0
%
%  Example:
%
%    N = 5, X = ( 1, 2, 3 ), Y = ( 4, 5 )
%
%    1  4    0    0    0
%   -4  1    0    0    0
%    0  0    2    5    0
%    0  0   -5    2    0
%    0  0    0    0    3
%
%  Properties:
%
%    A is generally not symmetric: A' /= A.
%
%    A is block diagonal, with the blocks being 2 by 2 or 1 by 1 in size.
%
%    A is in real Schur form.
%
%    The eigenvalues of A are X(I) +/- sqrt ( - 1 ) * Y(I)
%
%    A is tridiagonal.
%
%    A is banded, with bandwidth 3.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Francoise Chatelin,
%    Section 4.2.7,
%    Eigenvalues of Matrices,
%    John Wiley, 1993.
%
%    Francoise Chatelin, Valerie Fraysse,
%    Qualitative computing: Elements of a theory for finite precision
%    computation, Lecture notes,
%    CERFACS, Toulouse, France and THOMSON-CSF, Orsay, France, June 1993.
%
%  Parameters:
%
%    Input, integer N, the order of A.
%
%    Input, real X( (N+1)/2 ), specifies the diagonal elements
%    of A.
%
%    Input, real Y( N/2 ), specifies the off-diagonal elements
%    of the Schur blocks.
%
%    Output, real A(N,N), the matrix.
%
  a = zeros ( n, n );

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

      if ( i == j )
        a(i,j) = x( floor ( (i+1)/2 ) );
      elseif ( mod ( i, 2 ) == 1 & j == i + 1 )
        a(i,j) = y( floor ( (i+1)/2 ) );
      elseif ( mod ( i, 2 ) == 0 & j == i - 1 )
        a(i,j) = - y( floor ( (i+1)/2 ) );
      else
        a(i,j) = 0.0;
      end

    end
  end

  return
end


function result = polygon_xy_2d ( n, x, y )

%*****************************************************************************80
%
%% POLYGON_XY_2D integrates the function X*Y over a polygon in 2D.
%
%  Integration region:
%
%    The polygon bounded by the points (X(1:N), Y(1:N)).
%
%  Formula:
%
%    INTEGRAL = (1/24) * SUM ( 1 <= I <= N )
%      ( Y(I)   * ( 3 * X(I)**2 + 2 * X(I) * X(I-1) +     X(I-1)**2 )
%      + Y(I-1) * (     X(I)**2 + 2 * X(I) * X(I-1) + 3 * X(I-1)**2 ) )
%      * ( Y(I) - Y(I-1) )
%
%    where X(0) and Y(0) should be replaced by X(N) and Y(N).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    S F Bockman,
%    Generalizing the Formula for Areas of Polygons to Moments,
%    American Mathematical Society Monthly,
%    1989, pages 131-132.
%
%  Parameters:
%
%    Input, integer N, the number of vertices of the polygon.
%    N should be at least 3 for a nonzero result.
%
%    Input, real X(N), Y(N), the coordinates of the vertices
%    of the polygon.  These vertices should be given in
%    counter-clockwise order.
%
%    Output, real RESULT, the value of the integral.
%
  result = 0.0E+00;

  if ( n < 3 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'POLYGON_XY_2D - Warning!\n' );
    fprintf ( 1, '  The number of vertices must be at least 3.\n' );
    fprintf ( 1, '  The input value of N = %d\n', n );
    error ( 'POLYGON_XY_2D - Fatal error!' );
  end

  for i = 1 : n

    if ( i == 1 )
      im1 = n;
    else
      im1 = i - 1;
    end

    result = result + ( ...
      y(i) * ( 3.0E+00 * x(i)^2 + 2.0E+00 * x(i) * x(im1) + x(im1)^2 ) ...
      + y(im1) * ( x(i)^2 + 2.0E+00 * x(i) * x(im1) + 3.0E+00 * x(im1)^2 ) ...
      ) * ( y(i) - y(im1) );

  end

  result = result / 24.0E+00;

  return
end


function variance = log_series_variance ( a )

%*****************************************************************************80
%
%% LOG_SERIES_VARIANCE returns the variance of the Logarithmic Series PDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 February 1999
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, the parameter of the PDF.
%    0.0 < A < 1.0.
%
%    Output, real VARIANCE, the variance of the PDF.
%
  alpha = - 1.0 / log ( 1.0 - a );

  variance = a * alpha * ( 1.0 - alpha * a ) / ( 1.0 - a )^2;

  return
end


function [f] = psi(z)
%Psi     Psi (or Digamma) function valid in the entire complex plane.
%
%                 d
%        Psi(z) = --log(Gamma(z))
%                 dz
%
%usage: [f] = psi(z)
%
%tested under versions 6.0 and 5.3.1
%
%        Z may be complex and of any size.
%
%        This program uses the analytical derivative of the
%        Log of an excellent Lanczos series approximation
%        for the Gamma function.
%
%References: C. Lanczos, SIAM JNA  1, 1964. pp. 86-96
%            Y. Luke, "The Special ... approximations", 1969 pp. 29-31
%            Y. Luke, "Algorithms ... functions", 1977
%            J. Spouge,  SIAM JNA 31, 1994. pp. 931
%            W. Press,  "Numerical Recipes"
%            S. Chang, "Computation of special functions", 1996
%
%
%see also:   GAMMA GAMMALN GAMMAINC PSIN
%see also:   mhelp psi
%see also:   mhelp GAMMA

%Paul Godfrey
%pgodfrey@conexant.com
%July 13, 2001
%see gamma for calculation details...

siz = size(z);
z=z(:);
zz=z;

f = 0.*z; % reserve space in advance

%reflection point
p=find(real(z)<0.5);
if ~isempty(p)
   z(p)=1-z(p);
end

%Lanczos approximation for the complex plane

g=607/128; % best results when 4<=g<=5

c = [  0.99999999999999709182;
      57.156235665862923517;
     -59.597960355475491248;
      14.136097974741747174;
      -0.49191381609762019978;
        .33994649984811888699e-4;
        .46523628927048575665e-4;
       -.98374475304879564677e-4;
        .15808870322491248884e-3;
       -.21026444172410488319e-3;
        .21743961811521264320e-3;
       -.16431810653676389022e-3;
        .84418223983852743293e-4;
       -.26190838401581408670e-4;
        .36899182659531622704e-5];

n=0;
d=0;
for k=size(c,1):-1:2
    dz=1./(z+k-2);
    dd=c(k).*dz;
    d=d+dd;
    n=n-dd.*dz;
end
d=d+c(1);
gg=z+g-0.5;
%log is accurate to about 13 digits...

f = log(gg) + (n./d - g./gg) ;

if ~isempty(p)
   f(p) = f(p)-pi*cot(pi*zz(p));
end

p=find(round(zz)==zz & real(zz)<=0 & imag(zz)==0);
if ~isempty(p)
   f(p) = Inf;
end

f=reshape(f,siz);

return

%A demo of this routine is:
clc
clear all
close all
x=-4:1/16:4.5;
y=-4:1/16:4;
[X,Y]=meshgrid(x,y);
z=X+i*Y;
f=psi(z);
p=find(abs(f)>10);
f(p)=10;

mesh(x,y,abs(f),phase(f));
view([45 10]);
rotate3d;

figure(2);
ezplot psi;
grid on;

One=psi(2)-psi(1)
EulerGamma=-psi(1)

return


function J = computeCostMulti(X, y, theta)
%COMPUTECOSTMULTI Compute cost for linear regression with multiple variables
%   J = COMPUTECOSTMULTI(X, y, theta) computes the cost of using theta as the
%   parameter for linear regression to fit the data points in X and y

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

% You need to return the following variables correctly
J = 0;

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost of a particular choice of theta
%               You should set J to the cost.

predictions =  X*theta;
sqerrors = (predictions - y).^2;
J = 1/(2*m)* sum(sqerrors);

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

end


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

% DTFT of a discrete time signal x[n]

%x[n]=0.8^n , 0<=n<=20
syms w
n= 0:20;
x=0.8.^n;
X=sum(x.*exp(-j*w*n));
ezplot(abs(X),[-pi pi])
title(' Magnitude of DTFT')
ylim([0 5.4])

figure
w1=-pi:.01:pi;
XX=subs(X,w,w1)
plot(w1,angle(XX));
xlim([-pi pi])
title('Phase of DTFT')

figure
ezplot(abs(X),[-5*pi 5*pi]);
title('Magnitude of DTFT in 5 periods')
ylim([0 5.8])

figure
w1=-5*pi:.01:5*pi;
XX=subs(X,w,w1);
plot(w1,angle(XX));
xlim([-5*pi 5*pi])
title(' Phase of DTFT in 5 periods')

%x[n]=0.8^n u[n]
figure
syms n w
x=0.6^n
X=symsum(x*exp(-j*w*n),n,0,inf)
w1=-pi:.01:pi;
X_=subs(X,w,w1);
plot(w1,abs(X_));
legend('|X(\omega)|')
xlim([-pi pi])

figure
plot(w1,angle(X_));
xlim([-pi pi])
legend('\angle X(\omega)')


function cartPoints=ellips2Cart(points,a,f)
%%ELLIPS2CART Convert ellipsoidal coordinates to ECEF Cartesian
%             coordinates.
%
%INPUTS: points One or more points given in geodetic latitude and
%               longitude, in radians, and height, in meters that are to be
%               converted to Cartesian coordinates. To convert N points,
%               points is a 3XN matrix with each column having the format
%               [latitude;longitude; height].
%             a The semi-major axis of the reference ellipsoid. If this
%               argument is omitted or an empty matrix is passed, the value
%               in Constants.WGS84SemiMajorAxis is used.
%             f The flattening factor of the reference ellipsoid. If this
%               argument is omitted or an empty matrix is passed, the value
%               in Constants.WGS84Flattening is used.
%
%OUTPUTS: cartPoints For N points, cartPoints is a 3XN matrix of the
%               converted points with each column having the format
%               [x;y;z].
%
%The conversions are mentioned in [1].
%
%REFERENCES:
%[1] D. F. Crouse, "Simulating aerial targets in 3D accounting for the
%    Earth's curvature," Journal of Advances in Information Fusion, vol.
%    10, no. 1, Jun. 2015.
%
%September 2013 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<3||isempty(f))
    f=Constants.WGS84Flattening;
end

if(nargin<2||isempty(a))
    a=Constants.WGS84SemiMajorAxis;
end

%The geodetic latitudes
phi=points(1,:);
%The longitudes
lambda=points(2,:);

if(size(points,1)==3)
    %The altitudes
    h=points(3,:);
else
    h=0;
end

sinP=sin(phi);
cosP=cos(phi);
sinL=sin(lambda);
cosL=cos(lambda);

%The square of the first numerical eccentricity
e2=2*f-f^2;
%The normal radii of curvature.
Ne=a./sqrt(1-e2*sinP.^2);

x=(Ne+h).*cosP.*cosL;
y=(Ne+h).*cosP.*sinL;
z=(Ne*(1-e2)+h).*sinP;

cartPoints=[x;y;z];
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 fibonacci_spiral ( n )

%*****************************************************************************80
%
%% FIBONACCI_SPIRAL draws points on a Fibonacci spiral.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 April 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of points to plot.
%    Default is 101.
%
  if ( nargin < 1 )
    n = 101;
  end
%
%  PHI is the golden ratio, the limit of the ratio of
%  successive Fibonacci numbers:
%
%    PHI = limit ( N->oo ) F(N+1)/F(N)
%
  phi = ( 1.0 + sqrt ( 5.0 ) ) / 2.0;
%
%  Allocate storage for the data.
%
  x = zeros ( n, 1 );
  y = zeros ( n, 1 );
%
%  Set the angle and radius of the first point.
%
  a = 0.0;
  r = 0.0;
%
%  Set the increments.
%
  da = 2.0 * pi * ( phi - 1.0 ) / phi;
  dr = 1.0;
%
%  Create a spiral in which the radius R and angle A both
%  increase by a constant increment,
%
  for i = 1 : n
    x(i) = r * cos ( a );
    y(i) = r * sin ( a );
    a = mod ( a + da, 2 * pi );
    r = r + dr;
  end
%
%  Display the data in a scatter plot.
%
  scatter ( x, y, 'b.' )
  axis equal
  title ( sprintf ( 'Fibonacci spiral, N = %d', n ) )

  return
end


function l = l1dn ( n, h )

%*****************************************************************************80
%
%% L1DN stores the 1D DN 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 left Dirichlet and right
%    Neumann condition on [0,6] has the matrix form L:
%
%       2 -1  0  0  0
%      -1  2 -1  0  0
%       0 -1  2 -1  0
%       0  0 -1  2 -1
%       0  0  0 -1  1
%
%  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, 'L1DN - Fatal error!\n' );
    fprintf ( 1, '  N < 3.\n' );
    error ( 'L1DN - Fatal error!' );
  end

  l = zeros ( n, n );

  i = 1;
  l(1,1) =  2.0 / h / h;
  l(1,2) = -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,n-1) = -1.0 / h / h;
  l(n,n) =    1.0 / h / h;

  return
end


function [ xval, yval ] = bc_val ( n, t, xcon, ycon )

%*****************************************************************************80
%
%% BC_VAL evaluates a parameterized Bezier curve.
%
%  Discussion:
%
%    BC_VAL(T) is the value of a vector function of the form
%
%      BC_VAL(T) = ( X(T), Y(T) )
%
%    where
%
%      X(T) = Sum ( 0 <= I <= N ) XCON(I) * BERN(I,N)(T)
%      Y(T) = Sum ( 0 <= I <= N ) YCON(I) * BERN(I,N)(T)
%
%    BERN(I,N)(T) is the I-th Bernstein polynomial of order N
%    defined on the interval [0,1],
%
%    XCON(0:N) and YCON(0:N) are the coordinates of N+1 "control points".
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 February 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Kahaner, Moler, and Nash,
%    Numerical Methods and Software,
%    Prentice Hall, 1989.
%
%  Parameters:
%
%    Input, integer N, the order of the Bezier curve, which
%    must be at least 0.
%
%    Input, real T, the point at which the Bezier curve should
%    be evaluated.  The best results are obtained within the interval
%    [0,1] but T may be anywhere.
%
%    Input, real XCON(0:N), YCON(0:N), the X and Y coordinates
%    of the control points.  The Bezier curve will pass through
%    the points ( XCON(0), YCON(0) ) and ( XCON(N), YCON(N) ), but
%    generally NOT through the other control points.
%
%    Output, real XVAL, YVAL, the X and Y coordinates of the point
%    on the Bezier curve corresponding to the given T value.
%
  bval = bp01 ( n, t );

  xval = xcon(1:n+1) * bval(1:n+1)';
  yval = ycon(1:n+1) * bval(1:n+1)';

  return
end


function [w,rho] = mh(A)
% Computes the Metropolis-Hastings heuristic edge weights
%
% [W,RHO] = MH(A) gives a vector of the Metropolis-Hastings edge weights
% for a graphb described by the incidence matrix A (NxM). N is the number
% of nodes, and M is the number of edges. Each column of A has exactly one
% +1 and one -1. RHO is computed from the weights W as follows:
%    RHO = max(abs(eig( eye(n,n) - (1/n)*ones(n,n) - A*W*A' ))).
%
% The M.-H. weight on an edge is one over the maximum of the degrees of the
% adjacent nodes.
%
% For more details, see the references:
% "Fast linear iterations for distributed averaging" by L. Xiao and S. Boyd
% "Fastest mixing Markov chain on a graph" by S. Boyd, P. Diaconis, and L. Xiao
% "Convex Optimization of Graph Laplacian Eigenvalues" by S. Boyd
%
% Almir Mutapcic 08/29/06

% degrees of the nodes
n = size(A,1);
Lunw = A*A';          % unweighted Laplacian matrix
degs = diag(Lunw);

% Metropolis-Hastings weights
mh_degs = abs(A)'*diag(degs);
w = 1./max(mh_degs,[],2);

% compute the norm
if nargout > 1,
    rho = norm( eye(n) - A*diag(w)*A' - (1/n)*ones(n) );
end


function u=randDirVec(numDim,N)
%%RANDDIRVEC Generate a uniformly distributed random direction vector
%            (unit vector) in an arbitrary number of dimensions.
%
%INPUTS: numDim The number of dimensions of the random unit vector. This
%               is >=1.
%             N The number of random direction vectors to generate. If
%               this parameter is omitted, then N=1 is used.
%
%OUTPUTS: u A numDimXN matrix of N numDim-dimensional unit vectors that
%           are uniformly distributed on the unit-sphere (or hypersphere).
%
%One cannot simply generate a uniformly-distributed direction vector by
%setting each dimensions to a Uniform(-1,1) random variable and then
%normalizing the result. Rather, following the algorithm in Chapter 3.4.1,
%E6 of [1], the elements of the vector must be generated as normal 0-1
%random variables and then the vector normalized.
%
%REFERENCES:
%[1] D. Knuth, The Art of Computer Programming: Seminumerical Algorithms,
%    3rd ed. Reading, MA: Addison-Wesley, 1998, vol. 2.
%
%September 2014 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<2)
    N=1;
end

u=zeros(numDim,N);

for curN=1:N
    %Knuth, Chapter 3.4.1, E6 (Random point on an n-dimensional sphere with
    %radius one.
    u(:,curN)=randn(numDim,1);
    u(:,curN)=u(:,curN)/norm(u(:,curN));

    %Deal with the instance that norm(u)=0, which will occur with an extremely
    %small probability due to the limited precision of the random number
    %generation.
    if(~isfinite(u(:,curN)))
       u(:,curN)=zeros(numDim,1);
       u(1,curN)=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 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);
%

subsetU = U(:, 1:K);
Z = X * subsetU;

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

end