function val=intCotPow(u,n)
%%INTCOTPOWER Evaluate the integral of cot(u)^n du.  A definite integral
%             can be evaluated, or an indefinite integral (with a
%             particular additive constant).
%
%INPUTS: u A 2XN (for definite integral) or a 1XN (for indefinite
%          integrals) set of N points. For definite integrals, u(1,:) are
%          the real lower bounds and u(2,:) are the real upper bounds. For
%          indefinite integrals, the integral is evaluated at the points in
%          u. The values in u should be real.
%        n The positive integer exponent of the cotangent term.
%
%OUTPUTS: val The 1XN set of values of the integral of cot(u)^n.
%
%This function simply implements the recursion that arises from integration
%by parts from basic calculus, as are given in the tables in the back of
%[1].
%
%REFERENCES:
%[1] J. Stewart, Calculus, 7th ed. Belmont, CA: Brooks/Cole, 2012.
%
%October 2016 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

numDim=size(u,1);

if(isempty(u))
   val=[];
   return;
end

if(numDim==1)%An indefinite integral
    val=indefIntCotPow(u,n);
else%A definite integral
    val=indefIntCotPow(u(2,:),n)-indefIntCotPow(u(1,:),n);
end

end

function val=indefIntCotPow(u,n)

if(n==0)
    val=u;
    return;
elseif(n==1)
    val=log(abs(sin(u)));
    return;
end

%If here, n>=1
cotVal=cot(u);

val=0;
if(mod(n,2)==0)%If n is even
    endVal=2;
else
    endVal=3;
end

coeffProd=1;
for k=n:-2:endVal
    val=val-coeffProd*(1/(k-1))*cotVal.^(k-1);
    coeffProd=-coeffProd;
end

if(endVal==2)
    %The final integral is over cot^0
    val=val+coeffProd*u;
else
    %The final integral is over cot^1
    val=val+coeffProd*log(abs(sin(u)));
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.


%% Homework 10
% We Wish to solve the following partial differential equation:
%
% $\frac{\partial T}{\partial t}+u \frac{\partial T}{\partial x}=\alpha \frac{\partial^2 T}{\partial x^2}$
%
%% Part 2: Convection and Diffusion (Assume $\alpha=0.001$)
% Now using the same initial boundary conditions in Part 1, Solve the
% convection-diffusion equation. Repeat part(a): i and ii with the
% addition of the second-order central difference for the diffusion term.
%
% Following the condition: $cfl < 1$
%  where $cfl = u \frac{\Delta t}{\Delta x}$
%
% And now define $\alpha*\frac{\Delta t}{(\Delta x)^2}$ in the range [0,1]

clc
clear all
close all

% Initial Parameters
cfl    = 0.7;
u      = 0.08;
dx     = 1/50; % at least 51 grid points
dt     = cfl*dx/u;
alpha  = 0.001;
beta   = alpha*dt/dx^2;
t_end  = 8;

% Grid
x = 0:dx:1;
t = 0:dt:t_end;
X = length(x);
N = length(t);
T = zeros(N,X);

% Initial Condition
T(1,1:12)  = 1.-(10.*x(1:12)-1).^2;
T(1,12:51) = 0;

% Plot options
xmin=1; xmax=51; ymin=-0.2; ymax=1.7;

%% Barckward Euler time advancement
% a) Using Explicit Euler time advancement and second-order central
% difference for the spatial derivate.

% Numerical Scheme:
T(:,1) = 0; T(:,X) = 0;
for n = 1:N-1
    for j = 2:X-1
    T(n+1,j) = T(n,j) - 1/2*cfl*(T(n,j+1) - T(n,j-1))...
        + beta*(T(n,j+1) - 2*T(n,j) + T(n,j-1));
    end
end

% Plot Figures:
figure
Axis([xmin xmax ymin ymax])
Title(['Backward Euler Scheme',', CFL = ',num2str(cfl),', Beta = ',num2str(beta)])
hold on
plot(T(1,:),'ro')
plot(T(floor(N/2),:),'b+')
plot(T(N,:),'gs')
legend('@ t = 0','@ t = 4','@ t = 8')
hold off

%% Leapfrog time advancement
% b) Using Leapfrog time advancement and second-order central
% difference for the spatial derivate and a central difference for the
% diffusion term.
%
% This is a multistep method that is we need to use the first two lines on
% the forward euler to start our new scheme.

T2 = zeros(N,X);
T2(1,:) = T(1,:);
T2(2,:) = T(2,:);
T2(1,1) = 0; T2(1,X) = 0;

% Numerical Scheme:
T2(:,1) = 0; T2(:,X) = 0;
for n = 2:N-1
    for j = 2:X-1
    T2(n+1,j) = T2(n-1,j) - cfl*(T2(n,j+1) - T2(n,j-1))...
        + 2*beta*(T2(n,j+1) - 2*T2(n,j) + T2(n,j-1));
    end
end

% Plot Figures:
figure
%Axis([xmin xmax ymin ymax])
Title(['Leapfrog Scheme',', CFL = ',num2str(cfl),', Beta = ',num2str(beta)])
hold on
plot(T2(1,:),'-.ro')
plot(T2(floor(N/2),:),'-.b+')
plot(T2(N,:),'-.gs')
legend('@ t = 0','@ t = 4','@ t = 8')
hold off

%% Leapfrog time advancement with the diffusion term lagged in time.
% c) Using Leapfrog time advancement and second-order central
% difference for the spatial derivate and a central difference for the
% diffusion term. But this time the diffusion term would be evaluated at
% step "n-1" rather than "n".
%
% This is a multistep method that is we need to use the first two lines on
% the forward euler to start our new scheme.

T3 = zeros(N,X);
T3(1,:) = T(1,:);
T3(2,:) = T(2,:);
T3(1,1) = 0; T3(1,X) = 0;

% Numerical Scheme:
T3(:,1) = 0; T3(:,X) = 0;
for n = 2:N-1
    for j = 2:X-1
    T3(n+1,j) = T3(n-1,j) - cfl*(T3(n,j+1) - T3(n,j-1))...
        + 2*beta*(T3(n-1,j+1) - 2*T3(n-1,j) + T3(n-1,j-1));
    end
end

% Plot Figures:
figure
Axis([xmin xmax ymin ymax])
Title(['Leapfrog with diff-term lagged Scheme',', CFL = ',num2str(cfl),', Beta = ',num2str(beta)])
hold on
plot(T3(1,:),'ro')
plot(T3(floor(N/2),:),'b+')
plot(T3(N,:),'gs')
legend('@ t = 0','@ t = 4','@ t = 8')
hold off

%% Discusion
% How the presence of the diffusion term affected the physical behavior of
% the solution and stability properties of the numerical solution?


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

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

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

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

H_theta = sigmoid(X * theta);

J = -1/m * sum(y .* log(H_theta) + (1 - y) .* log(1 - H_theta));

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

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

end


function level=isodata(I)
%   ISODATA Compute global image threshold using iterative isodata method.
%   LEVEL = ISODATA(I) computes a global threshold (LEVEL) that can be
%   used to convert an intensity image to a binary image with IM2BW. LEVEL
%   is a normalized intensity value that lies in the range [0, 1].
%   This iterative technique for choosing a threshold was developed by Ridler and Calvard .
%   The histogram is initially segmented into two parts using a starting threshold value such as 0 = 2B-1,
%   half the maximum dynamic range.
%   The sample mean (mf,0) of the gray values associated with the foreground pixels and the sample mean (mb,0)
%   of the gray values associated with the background pixels are computed. A new threshold value 1 is now computed
%   as the average of these two sample means. The process is repeated, based upon the new threshold,
%   until the threshold value does not change any more.

%
%   Class Support
%   -------------
%   The input image I can be of class uint8, uint16, or double and it
%   must be nonsparse.  LEVEL is a double scalar.
%
%   Example
%   -------
%       I = imread('blood1.tif');
%       level = graythresh(I);
%       BW = im2bw(I,level);
%       imshow(BW)
%
%   See also IM2BW.
%
% Reference :T.W. Ridler, S. Calvard, Picture thresholding using an iterative selection method,
%            IEEE Trans. System, Man and Cybernetics, SMC-8 (1978) 630-632.

% Convert all N-D arrays into a single column.  Convert to uint8 for
% fastest histogram computation.
I = im2uint8(I(:));

% STEP 1: Compute mean intensity of image from histogram, set T=mean(I)
[counts,N]=imhist(I);
i=1;
mu=cumsum(counts);
T(i)=(sum(N.*counts))/mu(end);
T(i)=round(T(i));

% STEP 2: compute Mean above T (MAT) and Mean below T (MBT) using T from
% step 1
mu2=cumsum(counts(1:T(i)));
MBT=sum(N(1:T(i)).*counts(1:T(i)))/mu2(end);

mu3=cumsum(counts(T(i):end));
MAT=sum(N(T(i):end).*counts(T(i):end))/mu3(end);
i=i+1;
% new T = (MAT+MBT)/2
T(i)=round((MAT+MBT)/2);

% STEP 3 to n: repeat step 2 if T(i)~=T(i-1)
while abs(T(i)-T(i-1))>=1
    mu2=cumsum(counts(1:T(i)));
    MBT=sum(N(1:T(i)).*counts(1:T(i)))/mu2(end);

    mu3=cumsum(counts(T(i):end));
    MAT=sum(N(T(i):end).*counts(T(i):end))/mu3(end);

    i=i+1;
    T(i)=round((MAT+MBT)/2);
    Threshold=T(i);
end

 % Normalize the threshold to the range [i, 1].
level = (Threshold - 1) / (N(end) - 1);


function [W, S, latent] = PCA(X, pcaDims)
%% [W, S, latent] = PCA(X, pcaDims)
%
% Function for learning a Principle Component Analysis (PCA) subspace.
%
% Inputs:
%   X: training data, with rows corresponding to samples and columns features.
%   pcaDims: optional parameter specifying the output PCA subspace
%       dimensions.
%
% Outputs:
%   W: the learned PCA subspace projection matrix.
%   S: projected coefficients of X by W.
%   latent: latent values of the covariant matrix
%
% Version: 1.0
% Date: 2014-07-22
%
% Author: Shengcai Liao
% Institute: National Laboratory of Pattern Recognition,
%   Institute of Automation, Chinese Academy of Sciences
% Email: scliao@nlpr.ia.ac.cn

[n, d] = size(X);

if nargin == 1
    pcaDims = min(d,n) - 1;
end

if pcaDims <= 0 || pcaDims >= min(d,n)
    error('Incorrect pcaDims.');
end

fprintf('Start to train PCA...');
t0 = tic;

mu = mean(X);
X = bsxfun(@minus, X, mu);

if n >= d
    C = X' * X; %[d,d]
else
    C = X * X'; %[n,n]
end

[W, D] = eig(C);
latent = diag(D);
[latent, index] = sort(latent, 'descend');
W = W(:, index);

W = W(:, 1:pcaDims);
latent = latent(1:pcaDims);

if n < d
    W = X' * W * diag(1 ./ sqrt(latent));
end

if nargout >= 2 && ~isempty(S)
    S = X * W;
end

fprintf('%.3g seconds.\n', toc(t0));


function [xi,w]=thirdOrderExpCubPoints(numDim,algorithm)
%%THIRDORDEREXPCUBPOINTS Generate third-order cubature points for
%               integration over real space involving the weighting
%               function w(x)=exp(-sqrt(sum(x.*x))).
%
%INPUTS: numDim An integer specifying the dimensionality of the points to
%               be generated.
%     algorithm A value indicating which algorithm should be used. Possible
%               values are:
%               0 (The default if omitted or an empty matrix is passed)
%                 Formula E_n^r 3-1 in [1], pg. 329, 2*numDim points.
%               1 Formula E_n^r 3-2 in [1], pg. 329, 2^numDim points.
%
%OUTPUTS: xi A numDim X numCubaturePoints matrix containing the cubature
%            points. (Each "point" is a vector)
%          w A numCubaturePoints X 1 vector of the weights associated with
%            the cubature points.
%
%REFERENCES:
%[1] A.H. Stroud, Approximate Calculation of Multiple Integrals. Cliffs,
%    NJ: Prentice-Hall, Inc., 1971.
%
%October 2015 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release

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

switch(algorithm)
    case 0%E_n^r 3-1 in [1], pg. 329, 2*numDim points.
        V=2*pi^(numDim/2)*exp(gammaln(numDim)-gammaln(numDim/2));
        r=sqrt(numDim*(numDim+1));

        w=V/(2*numDim)*ones(2*numDim,1);
        xi=fullSymPerms([r;zeros(numDim-1,1)]);
    case 1%E_n^r 3-2 in [1], pg. 329, 2^numDim points.
        V=2*pi^(numDim/2)*exp(gammaln(numDim)-gammaln(numDim/2));
        r=sqrt(numDim+1);

        xi=PMCombos(r*ones(numDim,1));
        w=2^(-numDim)*V*ones(2^numDim,1);
    otherwise
        error('Unknown algorithm specified');
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.


%% Laplace Operator
%
% In this demo, we show how to use the OpenCV function |cv.Laplacian| to
% implement a discrete analog of the _Laplacian operator_.
%
% Sources:
%
% * <https://docs.opencv.org/3.2.0/d5/db5/tutorial_laplace_operator.html>
% * <https://github.com/opencv/opencv/blob/3.2.0/samples/cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp>
%

%% Theory
%
% In a previous demo, we learned how to use the _Sobel Operator_. It was based
% on the fact that in the edge area, the pixel intensity shows a "jump" or a
% high variation of intensity. Getting the first derivative of the intensity,
% we observed that an edge is characterized by a maximum, as it can be seen in
% the figure:
%
% <<https://docs.opencv.org/3.2.0/Laplace_Operator_Tutorial_Theory_Previous.jpg>>
%
% And what happens if we take the second derivative?
%
% <<https://docs.opencv.org/3.2.0/Laplace_Operator_Tutorial_Theory_ddIntensity.jpg>>
%
% You can observe that the second derivative is zero! So, we can also use this
% criterion to attempt to detect edges in an image. However, note that zeros
% will not only appear in edges (they can actually appear in other meaningless
% locations); this can be solved by applying filtering where needed.
%
%% Laplacian Operator
%
% From the explanation above, we deduce that the second derivative can be used
% to _detect edges_. Since images are "2D", we would need to take the
% derivative in both dimensions. Here, the Laplacian operator comes handy.
%
% The _Laplacian operator_ is defined by:
%
% $$Laplace(f) = \frac{\partial^{2} f}{\partial x^{2}} +
%                \frac{\partial^{2} f}{\partial y^{2}}$$
%
% The Laplacian operator is implemented in OpenCV by the function
% |cv.Laplacian|. In fact, since the Laplacian uses the gradient of images, it
% calls internally the _Sobel_ operator to perform its computation.
%

%% Code
%
% The program:
%
% * Loads an image
% * Remove noise by applying a Gaussian blur and then convert the original
%   image to grayscale
% * Applies a Laplacian operator to the grayscale image and stores the output
%   image
% * Display the result in a window
%

%%
% load source image
src = cv.imread(fullfile(mexopencv.root(),'test','butterfly.jpg'), 'Color',true);

%%
% apply a Gaussian blur to reduce the noise
src = cv.GaussianBlur(src, 'KSize',[3 3]);

%%
% convert filtered image to grayscale
gray = cv.cvtColor(src, 'RGB2GRAY');

%%
% apply the Laplacian operator to the grayscale image
% (input is 8-bit, we set the output image depth to 16-bit to avoid overflow)
dst = cv.Laplacian(gray, 'KSize',3, 'DDepth','int16');

%%
% take absolute value and convert results back to 8-bit
dstabs = cv.convertScaleAbs(dst);

%%
% show result
imshow(dstabs)
title('Laplace Demo')


function [x,f,exitCode]=convexQuadProg(G,a,C,b,numEqConst,epsVal,maxIter)
%%CONVEXQUADPROG Perform quadratic programming on a convex problem with
%                equality and inequality constraints. Specifically, this
%                algorithm solves the optimization problem:
%                minimize_x a'*x+(1/2)*x'*G*x
%                such that C(:,1:numEqConst)'*x=b(1:numEqConst)
%                     and C(:,(numEqConst+1):end)'*x>=b((numEqConst+1):end)
%                A dual active set algorithm for strictly convex problems
%                is used. Strict convexity means that G is positive
%                definite. The algorithm is robust to poorly conditioned
%                matrices. Thus, to handle the semidefinite case,
%                eigenvalue thresholding is applied prior to running the
%                algorithm.
%
%INPUTS: G An nXn real, positive (semi)definite symmetric matrix (n>0).
%        a An nX1 real vector.
%        C An nXm real matrix (m>=0). The first numEqConst constraints (the
%          equality constraints) must be linearly independent or the
%          algorithm will identify the problem as infeasible.
%        b An mX1 vector.
% numEqConst The number of constraints in C that are equality constraints
%          (numEqConst<=m). If this parameter is omitted or an empty matrix
%          is passed, the default numEqConst=0 is used.
%   epsVal A small value that is used to determine whether there is no step
%          in the primal space such that a constraint becomes feasible,
%          meaning that a step must be taken in the dual space and a
%          constraint dropped. This value should be >0 due to finite
%          precision errors. If this parameter is omitted or an empty
%          matrix is passed, the default value of eps() is used.
%  maxIter The maximum number of iterations to allow. The default value if
%          this parameter is omitted or an empty matrix is passed is 200.
%
%OUTPUTS: x The nX1 solution to the optimization problem or an empty matrix
%           if the problem is infeasible.
%         f The value of the objective function at x, or an empty ,matrix
%           if the problem is infeasible.
%  exitCode A value indicating how the algorithm terminated. Possible
%           values are:
%           0 The algorithm found the optimal value x.
%           1 The maximum number of iterations elapsed.
%          -1 The optimization problem is infeasible.
%
%The algorithm of [1] is implemented. However, the algorithmic description
%in [1] omits a few minor details regarding deleting elements from uPlus
%and updating s removing a constraint. The changes are commented in the
%code. Also, the algorithm of [1] is only described for inequality
%constraints. The change to allow equality constraints is performed by
%forcing the first numEqConst columns of C to be chosen to be added to the
%active set and then making sure that they are never removed from the
%active set. If an attempt is made to remove them from the active set, then
%the corresponding dual variables are set to zero rather than removed.
%
%Another change from the algorithm of [1] deals with the qr formulation of
%certain terms. Though the qr formulation of the H and NStar matrices is
%used, the single column deletions and insertions are not performed. Though
%slower than the algorithm in the paper, one does not need to worry about
%cumulative finite precision errors due to many incremental updates.
%
%Also, algorithm [1] did not include an epsVal term to try to deal with
%finite precision effects limiting the ability to determine whether no
%primal step can activate a certain constraint.
%
%EXAMPLE 1:
%This is the example worked out step-by-step in [1]:
% G=[4, -2;-2, 4];
% b=[0;0;2];
% a=[6;0];
% C=[1,0,1;
%    0,1,1];
% [x,f,exitCode]=convexQuadProg(G,a,C,b)
%The optimal solution can be seen to be x=[0.5;1.5] and f=6.5;
%
%EXAMPLE 2:
%In [1], the algorithm was tested on many random problems. Below is an
%implementation of the method described in the paper for n=81 dimensions
%and m=3*n=243 constraints. The first qStar=m/3=81 constraints end up being
%enforced.
% n=81;
% m=3*n;
% qStar=m/3;
%
% G=rand(n,n);
% G=G+G';
% %G is not symmetric and all elements are in the range of -1 to 1
% SCur=sum(G(1,2:end));
% G(1,1)=1+SCur+rand(1);
% for curRow=2:n
%    SPrev=SCur;
%    SCur=sum(G(curRow,[1:(curRow-1),(curRow+1):end]));
%    G(curRow,curRow)=G(curRow-1,curRow-1)+SCur+SPrev+rand();
% end
%
% xStar=-0.5+rand(n,1);
% C=-1+2*rand(n,m);
% C=bsxfun(@times,C,1./sqrt(sum(C.*C,1)));
% s=zeros(m,1);
% s((qStar+1):end)=rand(m-qStar,1);
% b=-(s-C'*xStar);%Sign changed from description in paper to be feasible.
% u=30*rand(m,1);
% u((qStar+1):end)=0;
% a=C*u-G*xStar;
% [x,f,exitCode]=convexQuadProg(G,a,C,b)
%
%EXAMPLE 3:
%This is an example of a problem having both inequality and equality
%constraints:
% G=[4, -2;-2, 4];
% b=[2;1.6];
% a=[6;0];
% C=[1,0;
%    1,1];
% numEqConst=1;%One equality constraint.
% [x,f,exitCode]=convexQuadProg(G,a,C,b,numEqConst)
%The optimal solution is x=[0.4;1.6] and f=6.56.
%
%REFERENCES:
%[1] D.Goldfarb and A. Idnani, "A numerically stable dual method for
%    solving strictly convex quadratic programs," Mathematical Programming,
%    vol. 27, no. 1, pp. 1-33, Sep. 1983.
%
%January 2016 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<5||isempty(numEqConst))
   numEqConst=0;
end

if(numEqConst>size(C,1))
   error('numEqConst is larger than the number of constraints in C')
end

if(nargin<6||isempty(epsVal))
    epsVal=eps();
end

if(nargin<7||isempty(maxIter))
    maxIter=200;
end

%This portion is to compensate for the possibility that G is positive
%semidefinite.
[V,D]=eig(G);
d=diag(D);
dNew=max(d,2*max(size(G))*eps(max(d)));
if(~all(dNew==d))
    %Only change G if some eigenvalues were too small.
    D=diag(dNew);
    G=V*D/V;
    G=(G+G')/2;%Ensure symmetry.
end

%If there are no constraints, the return the unconstrained solution.
if(isempty(b))
    x=-G\a;
    f=(1/2)*a'*x;
    exitCode=0;
    return
end

%Step 0: Find the unconstrained minimum and initialize parameters.
H=inv(G);
x=-G\a;
f=(1/2)*a'*x;
%Values are added to and deleted from A. Though this is inefficient, it is
%questionable whether any particular data structure could make it notably
%more efficient than what Matlab does without reprogramming this function
%in C.
A=[];
q=0;
u=[];
NStar=[];
L=chol(G,'lower');

skipStep1=false;
for curIter=1:maxIter
    %Step 1: Choose a violated constant, if any. We shall choose the most
    %violated constant.
    if(skipStep1==false)
        s=C'*x-b;
        %Force the equality constraints to be added first.
        if(curIter<=numEqConst)
            p=curIter;
        else
            [~,p]=min(s);

            if(any(p==A)||s(p)>=0)
                %If no constraints are violated, the current solution is
                %feasible and optimal.
                exitCode=0;
                return;
            end
        end

        uPlus=[u;0];%Dual variables with one for constraint p added.
        nPlus=C(:,p);
    end

    %Step 2: Check for feasibility and determine a new S-pair
    %Step 2a) Determine the step direction.
    z=H*nPlus;

    %r is empty when no constraints have been added.
    if(q==0)
        r=[];
    else
        r=NStar*nPlus;
    end

    %Step 2b) Determine the step length
    %Step 2bi) Find t1, the maximum step without violating dual
    %          feasibility.
    t1=Inf;
    l=[];
    for i=1:q
        %The added requirement that uPlus(i)>0 arises due to the equality
        %constraints. Otherwise, all of the dual variables enforced would
        %be greater than zero due to the nature of the dual problem.
        if(r(i)>0&&uPlus(i)>0)
            t1Cur=uPlus(i)/r(i);
            if(t1Cur<t1)
                t1=t1Cur;
                l=i;
            end
        end
    end

    %Step 2bii: Find the minimum step in the primal space such that the
    %pth constraint becomes feasible.
    zProd=z'*nPlus;

    %This comparison is not described in [1], but appears to be necessary
    %due to finite precision errors in some instances.
    if(zProd<epsVal)
        t2=Inf;
    else
        t2=-s(p)/zProd;
    end
    t=min(t1,t2);

    %Step 2c: Determine a new S-pair and take the step.
    %Step 2ci: If no step exists in the primal or dual spaces.
    if(~isfinite(t)||(t==0&&~all(uPlus==0)))
        %The problem is infeasible. The t=0 condition comes from adding
        %equality constraints to inequality constraints.
        x=[];
        f=[];
        exitCode=-1;
        return;
    end

    if(~isfinite(t2))
        %Step 2cii: If a step exists only in the dual space.
        uPlus=uPlus+t*[-r;1];
        if(l>numEqConst)%Do not delete equality constraints
            %Delete constraint A(l).
            A(l)=[];
            %Delete the dual variables associated with the constraint.
            %This deletion is not mentioned in the steps given in the paper,
            %but is necessary.
            uPlus(l)=[];
            q=q-1;

            %x did not change, so s(p) does not need to be recomputed.

            [NStar,H]=updateNStarH(q,A,C,L);
        else
            uPlus(l)=0;
        end
        skipStep1=true;
    else
        %Step 2ciii: Take a step in primal and dual space.
        x=x+t*z;
        f=f+t*z'*nPlus*((1/2)*t+uPlus(q+1));
        uPlus=uPlus+t*[-r;1];

        if(t==t2)%If a full step is taken, add constraint p
            u=uPlus;
            q=q+1;
            A(q)=p;

            [NStar,H]=updateNStarH(q,A,C,L);
            skipStep1=false;
        else%If a partial step is taken, then drop constraint k=A(l)
            if(l>numEqConst)%Do not delete equality constraints
                A(l)=[];
                %Delete the dual variables associated with the constraint.
                %This deletion is not mentioned in the steps given in the
                %paper, but is necessary.
                uPlus(l)=[];
                q=q-1;

                [NStar,H]=updateNStarH(q,A,C,L);
            else
                uPlus(l)=0;
            end
            %s must be recomputed for a partial step. This is not mentioned
            %in the paper.
            s=C'*x-b;
            skipStep1=true;
        end
    end
end

%Maximum number of iterations exceeded.
exitCode=1;
end

function [NStar,H]=updateNStarH(q,A,C,L)
%UPDATENSTARH This function is based on the discussion in Section 4 of [1].
%             It uses a qr decomposition, but does not use any of the qr
%             updating methods.
    N=C(:,A);

    opts.LT=true;
    opts.UT=false;
    %Solve B=L\N;
    B=linsolve(L,N,opts);
    [Q,R]=qr(B);
    R=R(1:q,1:q);

    opts.LT=false;
    opts.UT=true;
    %Solve J=(L')\Q;
    J=linsolve(L',Q,opts);
    J1=J(:,1:q);
    J2=J(:,(q+1):end);

    H=J2*J2';
    NStar=R\(J1');
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 [M,R] = ballatsq(N)
% BALLATSQ - Balanced Latin Square
%    M = BALLATSQ(N) creates a balanced latin square of size N containing
%    the numbers 1 to N. N should be an even positive integer.
%
%    [M, R] = BALLATSQ(N) also returns a randomized balanced latin square in R.
%
%    A latin square of size M is a MxM matrix filled with the M different
%    numbers in such a way that each number occurs exactly once in each row
%    and exactly once in each column. A balanced latin square has the further
%    restriction that each sequence of two values in a row does not occur
%    more than once in the whole matrix. They have applications in the
%    design of experiments.
%    More information: http://en.wikipedia.org/wiki/Latin_square
%
%    Example:
%      M = ballatsq(6) % ->
%      %      1     2     6     3     5     4
%      %      2     3     1     4     6     5
%      %      3     4     2     5     1     6
%      %      4     5     3     6     2     1
%      %      5     6     4     1     3     2
%      %      6     1     5     2     4     3
%
%     Note that "sort(ballatsq(N),1-2)" will return 1:N in each column-row.
%
%    See also MAGIC, GALLERY, CIRCSHIFT
%             LATSQ, CIRCULANT (FEX)

% for Matlab R13 and up
% version 2.2 (mar 2009)
% (c) Jos van der Geest
% email: jos@jasen.nl

% History
% 1.0 (feb 2006) created
% 2.0 (apr 2006) previous algorithm was faulty. Thanks to Jen M. (UK)
% 2.1 (sep 2006) can now also return a randomize balanced latin square
% 2.2 (mar 2009) added internal comments, changed variable names, improved
%     randomization

if nargin ~= 1 || ~isnumeric(N) || numel(N)~=1 || N<2 || rem(N,2) || fix(N)~=N,
    error('Single argument should be a positive even integer') ;
end

V = 1:N ;        % values in each column
CSI = [V ; -V] ; % circular shift index
M = zeros(N) ;   % pre-allocation

% the first colum just contains the numbers 1 to N
M(:,1) = V(:) ;
for i=2:N,
    % every column contains the numbers 1 to N shifted circularly according
    % to CSI
    M(:,i) =  rem(V(:)+CSI(i-1)+(N-1),N) + 1 ;
end

if nargout==2,
    % randomize the values 1:N
    rN = randperm(N) ;
    R = rN(M) ;
end


function f = polyVal2D(p,x,y,n,m)
%POLYVAL2D Evaluate a 2-D polynomial using Horner's method.
%   F = POLYVAL2D(P,X,Y) evaluates the 2-D polynomial P at the points
%   specified by X and Y, which must have the same dimensions. The output F
%   will have the same dimensions as X and  Y. N and M specify the order of X
%   and Y respectively. Polynomial coefficients are in the following order.
%
%   F(X,Y) = P_1 * X^N * Y^M + P_2 * X^{N-1} * Y^M + ... + P_{N+1} * Y^M + ...
%            P_{N+2} * X^N * Y^{M-1} + P_{N+3} * X^{N-1} * Y^{M-1} + ... + P_{2*(N+1)} * Y^{M-1} + ...
%            ...
%            P_{M*(N+1)+1} * X^N + P_{M*(N+1)+2} * X^{N-1} + ... + P_{(N+1)*(M+1)}
%
%
% See also: POLYFITN by John D'Errico on MathWorks MATLAB Central FEX
% http://www.mathworks.com/matlabcentral/fileexchange/34765-polyfitn
%
% Mark Mikofski, http://poquitopicante.blogspot.com
% Version 1-0, 2013-03-13

%% LaTex
%
% $$f\left(x,y\right)=p_1 x^n y^m+p_2 x^{\left(n-1\right)} y^m+\ldots+p_{n+1} y^m+\ldots$$
%
% $$p_{n+2}x^ny^{\left(m-1\right)}+p_{n+3}x^{\left(n-1\right)}y^{\left(m-1\right)}+\ldots+p_{2\left(n+1\right)}y^{\left(m-1\right)}+\ldots$$
%
% $$\ldots$$
%
% $$p_{m\left(n+1\right)+1}*x^n+p_{m\left(n+1\right)+2}*x^{\left(n-1\right)}+\ldots+p_{\left(n+1\right)\left(m+1\right)}$$

%% check input args
validateattributes(p,{'numeric'},{'2d','nonempty','real','finite'}, ...
    'polyVal2D','p',1)
validateattributes(x,{'numeric'},{'nonempty','real','finite'}, ...
    'polyVal2D','x',2)
validateattributes(y,{'numeric'},{'nonempty','real','finite'}, ...
    'polyVal2D','y',3)
assert(all(size(x)==size(y)),'polyVal2D:sizeMismatch', ...
    'X and Y must be the same size.')
% use size of p to set n & m
pdims = size(p);
if nargin<4 && all(pdims>1)
    n = pdims(1)-1;
    m = pdims(2)-1;
end
validateattributes(n,{'numeric'},{'scalar','integer','positive','<',10}, ...
    'polyVal2D','n',4)
validateattributes(m,{'numeric'},{'scalar','integer','positive','<',10}, ...
    'polyVal2D','m',5)
if all(pdims>1)
    assert(pdims(1)==n+1,'polyVal2D:xOrderMismatch', ...
        'The number of x coefficients doesn''t match the order n.')
    assert(pdims(2)==m+1,'polyVal2D:yOrderMismatch', ...
        'The number of y coefficients doesn''t match the order m.')
end
%% evaluate polynomial P
f = p(1);
for ni = 1:n
    f = f.*x+p(1+ni);
end
for mi = 1:m
    mj = (n+1)*mi+1;
    g = p(mj);
    for ni = 1:n
        g = g.*x+p(mj+ni);
    end
    f = f.*y+g;
end


function [VG,A,PPG]= colorgrad(f,T)
%COLORGRAD Computes the vector gradient of an RGB image.
%   [VG,VA,PPG] = COLORGRAD(F,T) computes the vector gradient, VG, and
%   corresponding angle array, VA, (in radians) of RGB image F. It also
%   computes PPG, the per-plane composite gradient obtained by summing
%   the 2-D gradients of the individual color planes. Input T is a
%   threshold in the range [0,1]. If it is included in the input,
%   outputs VG and PPG are logical matrices such that VG(x,y) = 0 for
%   values <= T and VG(x,y) = 1 otherwise. Similar comments apply to
%   PPG. If T is not included in the input argument, then both output
%   gradients are scaled to the double range [0,1].
%
%  All equations on which this function is based are from Chapter 7 of
%  DIPUM3E.
%
%   Copyright 2002-2020 Gatesmark
%
%   This function, and other functions in the DIPUM Toolbox, are based
%   on the theoretical and practical foundations established in the
%   book Digital Image Processing Using MATLAB, 3rd ed., Gatesmark
%   Press, 2020.
%
%   Book website: http://www.imageprocessingplace.com
%   License: https://github.com/dipum/dipum-toolbox/blob/master/LICENSE.txt

if size(f,3) ~= 3
   error('Input image must be of size M-by-N-by-3');
end

if nargin == 2 && (T < 0 || T > 1)
   error('T must be in the range [0 1]')
end

% Compute the x and y derivatives of the three component images using
% Sobel operators.
sh = fspecial('sobel');
sv = sh';
Rx = imfilter(double(f(:,:,1)),sh,'replicate');
Ry = imfilter(double(f(:,:,1)),sv,'replicate');
Gx = imfilter(double(f(:,:,2)),sh,'replicate');
Gy = imfilter(double(f(:,:,2)),sv,'replicate');
Bx = imfilter(double(f(:,:,3)),sh,'replicate');
By = imfilter(double(f(:,:,3)),sv,'replicate');

% Compute the parameters of the vector gradient.
gxx = Rx.^2 + Gx.^2 + Bx.^2;
gyy = Ry.^2 + Gy.^2 + By.^2;
gxy = Rx.*Ry + Gx.*Gy + Bx.*By;
A = 0.5*(atan(2*gxy./(gxx - gyy + eps)));
G1 = 0.5*((gxx + gyy) + (gxx - gyy).*cos(2*A) + 2*gxy.*sin(2*A));

% Now repeat for angle + pi/2. Then select the maximum at each point.
A = A + pi/2;
G2 = 0.5*((gxx + gyy) + (gxx - gyy).*cos(2*A) + 2*gxy.*sin(2*A));
G1 = G1.^0.5;
G2 = G2.^0.5;

% Form VG by picking the maximum at each (x,y) and then scale
% to the range [0,1] using function mat2gray.
VG = mat2gray(max(G1,G2));

% Select the corresponding angles. Where G2 is greater than G1, pick
% values from array A + pi/2. Else, use values from A, which correspond
% to G1. The angles are in radians.
A(G2 > G1) = A(G2 > G1) + pi/2;

% Compute the per-plane gradients.
RG = hypot(Rx,Ry);
GG = hypot(Gx,Gy);
BG = hypot(Bx,By);
% Form the composite by adding the individual results and scale to
% [0,1].
PPG = mat2gray(RG + GG + BG);

% If T was provided, threshold the result.
if nargin == 2
   VG = VG > T;
   PPG = PPG > T;
end


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

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

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

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

htheta = sigmoid(X * theta);
J = 1 / m * sum(-y .* log(htheta) - (1 - y) .* log(1 - htheta)) + lambda / (2 * m) * sum(theta(2:end) .^ 2);
temp = theta;
temp(1) = 0;
grad = 1 / m * (X' * (htheta - y) + lambda * temp);

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

end


function area = annulus_sector_area_2d ( r1, r2, theta1, theta2 )

%*****************************************************************************80
%
%% ANNULUS_SECTOR_AREA_2D computes the area of an annular sector in 2D.
%
%  Discussion:
%
%    An annular sector with center (XC,YC), inner radius R1 and
%    outer radius R2, and angles THETA1, THETA2, is the set of points
%    (X,Y) so that
%
%      R1**2 <= (X-XC)**2 + (Y-YC)**2 <= R2**2
%
%    and
%
%      THETA1 <= THETA ( X - XC, Y - YC ) <= THETA2
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 August 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R1, R2, the inner and outer radii.
%
%    Input, real THETA1, THETA2, the angles.
%
%    Output, real AREA, the area.
%
  area = 0.5 * ( theta2 - theta1 ) * ( r2 + r1 ) * ( r2 - r1 );

  return
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
%

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

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

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

end


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

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

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

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

H = sigmoid(X*theta);
T = y.*log(H) + (1 - y).*log(1 - H);
J = -1/m*sum(T) + lambda/(2*m)*sum(theta(2:end).^2);

ta = [0; theta(2:end)];
grad = X'*(H - y)/m + lambda/m*ta;

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

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 y = norm_lpdf(x,mu,sigma)
%NORM_LPDF Normal log-probability density function (lpdf).
%
%   Y = NORM_LPDF(X,MU,SIGMA) Returns the log of the normal pdf with
%   mean, MU, and standard deviation, SIGMA, at the values in X.
%
%   The size of Y is the common size of the input arguments. A scalar input
%   functions as a constant matrix of the same size as the other inputs.
%
%   Default values for MU and SIGMA are 0 and 1 respectively.

% Copyright (c) 1998-2004 Aki Vehtari

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

if nargin < 3,
  sigma = 1;
end

if nargin < 2;
  mu = 0;
end

if nargin < 1,
  error('Requires at least one input argument.');
end

y = -0.5 * ((x-mu)./sigma).^2 -log(sigma) -log(2*pi)/2;


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

H_theta = sigmoid(X * theta);

J = -1/m * sum(y .* log(H_theta) + (1 - y) .* log(1 - H_theta)) + ...
    lambda/(2 * m) * norm(theta([2:end]))^2;

% extra term for gradient
G = lambda/m .* theta;
G(1) = 0;

grad = 1/m .* X' * (H_theta - y) + G;

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

end


function Angles = QUADangles(vertices)

% Purpose: To find the angles of Quadrilateral when vertices are known
% Synopsis: Angles = FindAngles(vertices)
%
% Variable description:
% INPUT: vertices - coordinates of Quadrilateral in order 4X2 . The vertices
%                   are given input in anticlock wise direction.
%
% OUTPUT: Angles - Row vector of angles of Quadrilateral in degrees of order 4X1
%
% Example: vertices = [4  4;4  6;5 6; 5  4]
%          angles = FindAngles(vertices);
%          angles = [90 90 90 90]
%
% Algorithm: Calculates the angles using dot product
%            theta = arccos((a.b)/(|a||b|)
%
% Release : 1.0
% Release Date: 03/07/2012
%--------------------------------------------------------------------------
% Author : Siva Srinivas Kolukula
%          Senior Research Fellow
%          Structural Mechanics Laboratory
%          Indira Gandhi Center for Atomic Research
%          India
% E-mail : allwayzitzme@gmail.com
%          http://sites.google.com/site/kolukulasivasrinivas/
%--------------------------------------------------------------------------

Angles = zeros(1,4) ;
order = [ 1 2 4; 2 1 3; 3 4 2;4 3 1] ;
for i = 1:4
    % Form the vectors along the vertices
    data1 = [vertices(i,:); vertices(order(i,2),:)];
    data2 = [vertices(i,:); vertices(order(i,3),:)];
    % Use dor ptodict to find the angle between vector1 and vector2
    Angles(i) = acos((diff(data1)*diff(data2)')/.....
        (sqrt(sum(diff(data1,[],1).^2,2))*sqrt(sum(diff(data2,[],1).^2,2)))) ;
end
% Convert the angles in radians to degrees
Angles = Angles*180./pi ;        %


% File: lognormpdf.m
%
% Copyright (C) Daphne Koller, Stanford Univerity, 2012

function [log_prob] = lognormpdf(x,mu,sigma)

% LOGNORMPDF Natural logarithm of the normal probability density function (pdf)
% Y = lognormpdf(X,MU,SIGMA) returns the log of the pdf of the normal
% distribution parameterized by mean MU and standard deviation SIGMA evaluated
% at each value in the vector X. Thus, the size of the return
% vector Y is the size of X.
%
% MU and X should have the same dimensions.

log_prob = -log(sigma*sqrt(2*pi))-(x-mu).^2 ./ (2*sigma.^2);


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.

J = (1/(2*m))*sum(power((X*theta - y),2));

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

end

github-repos/MATLAB/Borye-machine-learning-coursera-1/machine-learning-coursera-1-033fdc2e6da393eeb1179a09aafe92362021effb/Week 2 Assignments/Linear Regression with Multiple Variables/mlclass-ex1/computeCostMulti.m


function value = i4_factorial2 ( n )

%*****************************************************************************80
%
%% I4_FACTORIAL2 computes the factorial N!!
%
%  Formula:
%
%    FACTORIAL2( N ) = Product ( N * (N-2) * (N-4) * ... * 2 )  (N even)
%                    = Product ( N * (N-2) * (N-4) * ... * 1 )  (N odd)
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the argument of the double factorial function.
%    If N is less than 1, VALUE is returned as 1.
%
%    Output, integer VALUE, the value of N!!.
%
  value = 1;

  if ( n < 1 )
    return
  end

  while ( 1 < n )
    value = value * n;
    n = n - 2;
  end

  return
end


function [ x, seed ] = sphere_unit_sample2_nd ( dim_num, seed )

%*****************************************************************************80
%
%% SPHERE_UNIT_SAMPLE2_ND picks a random point on the unit sphere in ND.
%
%  Discussion:
%
%    The unit sphere in ND satisfies:
%
%      sum ( 1 <= I <= DIM_NUM ) X(I) * X(I) = 1
%
%    DIM_NUM independent normally distributed random numbers are generated,
%    and then scaled to have unit norm.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer DIM_NUM, the dimension of the space.
%
%    Input, integer SEED, a seed for the random number generator.
%
%    Output, real X(DIM_NUM), the random point.
%
%    Output, integer SEED, a seed for the random number generator.
%
  [ x, seed ] = r8vec_normal_01 ( dim_num, seed );

  norm = sqrt ( sum ( x(1:dim_num).^2 ) );

  x(1:dim_num) = x(1:dim_num) / norm;

  return
end


function y=lagrange(x,pointx,pointy)
%
%LAGRANGE   approx a point-defined function using the Lagrange polynomial interpolation
%
%      LAGRANGE(X,POINTX,POINTY) approx the function definited by the points:
%      P1=(POINTX(1),POINTY(1)), P2=(POINTX(2),POINTY(2)), ..., PN(POINTX(N),POINTY(N))
%      and calculate it in each elements of X
%
%      If POINTX and POINTY have different number of elements the function will return the NaN value
%
%      function wrote by: Calzino
%      7-oct-2001
%
n=size(pointx,2);
L=ones(n,size(x,2));
if (size(pointx,2)~=size(pointy,2))
   fprintf(1,'\nERROR!\nPOINTX and POINTY must have the same number of elements\n');
   y=NaN;
else
   for i=1:n
      for j=1:n
         if (i~=j)
            L(i,:)=L(i,:).*(x-pointx(j))/(pointx(i)-pointx(j));
         end
      end
   end
   y=0;
   for i=1:n
      y=y+pointy(i)*L(i,:);
   end
end


function [y, slope] = groundHeight(x)
%
% This function returns the height (y) and slope (Dy) of the ground as a
% function of the horizontal position. An interesting ground profile is
% generated by summing three sine waves. This also makes the derivative
% (slope) easy to compute.
%

%Parameters for each of the three sine ewaves:
    Amp1 = 0.3;
    Freq1 = 1;
    Phase1 = 1.58;

    Amp2 = 0.1;
    Freq2 = 6;
    Phase2 = 1.9;

    Amp3 = 0.2;
    Freq3 = 3.7;
    Phase3 = 1.58;

%Compute the ground height
y = Amp1*sin(Freq1*x+Phase1)+...
    Amp2*sin(Freq2*x+Phase2)+...
    Amp3*sin(Freq3*x+Phase3);

%Compute the ground slope
slope = Amp1*Freq1*cos(Freq1*x+Phase1)+...
        Amp2*Freq2*cos(Freq2*x+Phase2)+...
        Amp3*Freq3*cos(Freq3*x+Phase3);

end


function [retPath,retDist,cycleNodes]=BellmanFordAlg(adjMat,sourceIdx,destIdx)
%%BELLMANFORDALG Use the Bellman-Ford algorithm to find the shortest path
%                from a given source node through a graph represented using
%                an adjacency matrix. Negative edge costs are allowed and
%                if a negative cycle reachable from the source exists in
%                the graph, then that cycle will be returned (and no
%                minimum distance path will exist).
%
%INPUTS: adjMat  An adjacency matrix full of costs for the graph.
%                adjMat(i,j) is the cost of going from vertex i to vertex
%                j. If there is no connection between the vertices in the
%                graph, then set that element to infinity. Cycles
%                accessible from the source involving negative edge weights
%                are detected by the algorithm and mean that no solution
%                exists.
%     sourceIdx  The index of the node (vertex) from which the shortest
%                paths to other vertices is desired.
%        destIdx The index of the destination path. If this parameter is
%                provided, then the path of nodes from the source to the
%                destination is returned along with the path length.
%                Otherwise, information allowing one to reconstruct the
%                whole path is returned if this parameter is omtted.
%
%OUTPUTS: retPath If destIdx is given, this is the minimum cost sequence of
%                 nodes to get from sourceIdx to destIdx, including the end
%                 nodes; if there is no path to the node, an empty matrix
%                 is returned. Otherwise, this is prevNodes, such that one
%                 can recreate all shortest paths. Starting at index idx,
%                 the next node on the path in the reverse direction from
%                 destimation to source is retPath(idx). By looping, one
%                 can recreate the whole path. If there is no path to a
%                 node, then retPath(idx)=0. If a negative cycle exists
%                 in the path, then an empty matrix is returned.
%         retDist If destIdx is given, this is the shortest distance from
%                 the source to the destination. If destIdx is not given,
%                 then this is an array where each index holds the shortest
%                 distance from the source to that node. If a negative
%                 cycle exists in the graph, then an empty matrix is
%                 returned.
%      cycleNodes If no negative cost cycles exist in the graph, then this
%                 is an empty matrix. If any negative cycles exist, then
%                 this will be the nodes in order of the first negative
%                 cycle found. The last node in cycleNodes is connected
%                 back to the first node, finishing the loop. A cycle is a
%                 loop in the graph; a negative cost cycle is one where the
%                 sum of the costs in the cycle is negative.
%
%The algorithm implemented is that of Chapter 24.1 of [1], where the
%extraction of a negative cost cycle accessible from the source is added
%when a negative cost cycle is detected.
%
%Ad an example, consider the adjacency matric with two negative cost
%cycles:
% adjMat=[Inf,    -20,    Inf;
%         Inf,    Inf,    10,
%         5,      -15,    Inf];
% [retPath,retDist,cycleNodes]=BellmanFordAlg(adjMat,1,3);
%Looking for a path from 1 to 3, the algorithm would encounter the cycle.
%Thus, the return values would be [] and [] for retPath and retDist and
%cycleNodes=[3;2], because that is the first cycle found.
%
%REFERENCES:
%[1] T. H. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein,
%    Introduction to Algorithms, 2nd ed. Cambridge, MA: The MIT Press,
%    2001.
%
%June 2015 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

%The number of vertices.
numNodes=length(adjMat);

%The shortest distance yet found from the source to each of the nodes.
dist=inf(numNodes,1);
%The distance from the source to itself is zero. This is the first node to
%be visited.
dist(sourceIdx)=0;
%The previous node in the optimal path from the given node to the source.
prevNodes=zeros(numNodes,1);

for i=1:(numNodes-1)
    for curNode=1:numNodes
        %We have to go over all edges from the current node. If
        %adjMat(curNode,destNode) is infinite, then no edge exists to destNode.
        for destNode=1:numNodes
            w=adjMat(curNode,destNode);%The edge weight
            if(~isfinite(w))
                continue;
            end

            %Perform the relaxation step.
            if(dist(curNode)+w<=dist(destNode))
                dist(destNode)=dist(curNode)+w;
                prevNodes(destNode)=curNode;
            end
        end
    end
end

%Now, we check for a negative weight cycle (reachable from the source). If
%a negative weight cycle is found, then return it. We have to look at all
%edges in the graph.
cycleStart=[];
for curNode=1:numNodes
    for destNode=1:numNodes
        w=adjMat(curNode,destNode);%The edge weight
        if(~isfinite(w))
            continue;
        end

        if(dist(curNode)+w<dist(destNode))
            cycleStart=destNode;
            prevNodes(destNode)=curNode;
            break;
        end
    end
end

%If a negative weight cycle is present, then trace back along it to get the
%cycle to return. However, a problem is that from the starting node, we
%might get lost in a cycle that does not return to the starting node. Thus,
%we have to keep track of when we visited each edge and declare a cycle
%once we revisit any edge, not necessarily the starting edge.

if(~isempty(cycleStart))
    %Allocate the maximum space possible for the cycle.
    cycleNodes=zeros(numNodes,1);
    nodeVisited=zeros(numNodes,1);

    curIdx=1;
    cycleNodes(curIdx)=cycleStart;
    nodeVisited(cycleStart)=curIdx;
    while(1)
        nextNode=prevNodes(cycleNodes(curIdx));
        %if we have seen this node before
        if(nodeVisited(nextNode)~=0)
            break;
        end
        cycleNodes(curIdx+1)=prevNodes(cycleNodes(curIdx));
        nodeVisited(nextNode)=curIdx+1;

        curIdx=curIdx+1;
    end

    %Shrink the list of cycle nodes down to the size of the number of
    %actual nodes in the cycle and reverse the order so that the nodes are
    %in the correct order.
    cycleNodes=flipud(cycleNodes(nodeVisited(nextNode):curIdx));

    %It cannot solve for the optimal path, because of the negative cycle.
    retPath=[];
    retDist=[];
    return;
else
    cycleNodes=[];
end

%If a destination index is given, the recreate the path, if there are no
%cycles.
if(nargin>2)
    %If there is no path to the desired node.
    if(~isfinite(dist(destIdx)))
        retPath=[];
        retDist=Inf;
        return;
    end

    path=zeros(numNodes,1);
    path(1)=destIdx;
    pathStep=1;
    while(path(pathStep)~=sourceIdx)
        path(pathStep+1)=prevNodes(path(pathStep));
        pathStep=pathStep+1;
    end
    retPath=flipud(path(1:pathStep));
    retDist=dist(destIdx);
else
    retPath=prevNodes;
    retDist=dist;
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 value = v_hofstadter ( n )

%*****************************************************************************80
%
%% V_HOFSTADTER computes the Hofstadter V sequence.
%
%  Discussion:
%
%    V(N) = 0                          if N = 0
%         = 1                          if 1 <= N <= 4
%         = V(N-V(N-1)) + V(N-V(N-4)), otherwise.
%
%    V(N) is defined for all nonnegative integers.
%
%  Table:
%
%     N  V(N)
%    --  ----
%
%     0     0
%     1     1
%     2     1
%     3     1
%     4     1
%     5     2
%     6     3
%     7     4
%     8     5
%     9     5
%    10     6
%    11     6
%    12     7
%    13     8
%    14     8
%    15     9
%    16     9
%    17    10
%    18    11
%    19    11
%    20    11
%    21    12
%    22    12
%    23    13
%    24    14
%    25    14
%    26    15
%    27    15
%    28    16
%    29    17
%    30    17
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 July 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the argument of the function.
%
%    Output, integer VALUE, the value of the function.
%
  if ( n <= 0 )
    value = 0;
  elseif ( n <= 4 )
    value = 1;
  else
    value = v_hofstadter ( n - v_hofstadter(n-1) ) ...
          + v_hofstadter ( n - v_hofstadter(n-4) );
  end

  return
end


function ellipsLat=reducedLat2EllipsLat(reducedLat,f)
%%REDUCEDLAT2ELLIPSLAT Convert reduced (parameteric) latitude into an
%                      ellipsoidal (geodetic) latitude. A parameteric
%                      latitude is an angle of elevation drawn from the
%                      center of a sphere whose radius is equal to the
%                      semi-major axis of the ellipsoid. The parametric
%                      latitude is the angle of the point on the sphere
%                      where a vertical line drawn from the major axis of
%                      the ellipse through the point on the ellipse
%                      intersects the sphere. This is a way of mapping an
%                      ellipsoid onto a sphere.
%
%INPUTS: reducedLat A vector or matrix of reduced latitudes in radians.
%                   These typically range from -pi/2 to pi/2.
%                 f The flattening factor of the reference ellipsoid. If
%                   this argument is omitted, the value in
%                   Constants.WGS84Flattening is used.
%
%OUTPUTS: reducedLat The ellipsoidal (geodetic) latitude ranging from
%                   -pi/2 to pi/2, for each reduced latitude.
%
%%The definition of the reduced (parameteric) latitude from Chapter 3 (pg.
%18) of [1] is used. The conversion relation between the latitudes is in
%Section 3.4 of [2].
%
%The reduced latitude has been used for solving geodescic problems on an
%ellipsoid by transforming the problem to an equivalent problem on a
%sphere.
%
%The inverse of this function is ellipsLat2ReducedLat.
%
%REFERENCES:
%[1] J. P. Snyder, "Map projections- a working manual," U.S. Geological
%    Survey, Tech. Rep. 1395, 1987.
%[2] R. H. Rapp, "Geometric geodesy, part I," Ohio State University
%    Department of Geodetic Science and Surveying, Tech. Rep., Apr. 1991.
%    [Online]. Available: http://hdl.handle.net/1811/24333
%
%October 2014 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<2)
    f=Constants.WGS84Flattening;
end

%The first numerical eccentricity of the ellipsoid.
e=sqrt(2*f-f^2);

%The wrapping helps deal with precision limitations that might push the
%input value slightly above or below +/-pi/2. If the wrapping were not
%done, then instead of getting, for example, pi/2, one will get pi/2 as a
%return value.
reducedLat=wrapRange(reducedLat,-pi/2,pi/2,true);

ellipsLat=atan(tan(reducedLat)/sqrt(1-e^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.


function [theta] = normalEqn(X, y)
%NORMALEQN Computes the closed-form solution to linear regression
%   NORMALEQN(X,y) computes the closed-form solution to linear
%   regression using the normal equations.

theta = pinv(X' * X) * X' * y;

% ====================== YOUR CODE HERE ======================
% Instructions: Complete the code to compute the closed form solution
%               to linear regression and put the result in theta.
%

% ---------------------- Sample Solution ----------------------

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

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

end


function area = sphere_triangle_angles_to_area ( r, a, b, c )

%*****************************************************************************80
%
%% SPHERE_TRIANGLE_ANGLES_TO_AREA computes the area of a spherical triangle.
%
%  Discussion:
%
%    A sphere centered at 0 in 3D satisfies the equation:
%
%      X*X + Y*Y + Z*Z = R*R
%
%    A spherical triangle is specified by three points on the surface
%    of the sphere.
%
%    The area formula is known as Girard's formula.
%
%    The area of a spherical triangle is:
%
%      AREA = ( A + B + C - PI ) * R*R
%
%    where A, B and C are the (surface) angles of the triangle.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R, the radius of the sphere.
%
%    Input, real A, B, C, the angles of the triangle.
%
%    Output, real AREA, the area of the spherical triangle.
%

%
%  Apply Girard's formula.
%
  area = r * r * ( a + b + c - pi );

  return
end


function value = i4_log_2 ( i )

%*****************************************************************************80
%
%% I4_LOG_2 returns the integer part of the logarithm base 2 of |I|.
%
%  Discussion:
%
%    For positive I4_LOG_2(I), it should be true that
%      2**I4_LOG_2(X) <= |I| < 2**(I4_LOG_2(I)+1).
%    The special case of I4_LOG_2(0) returns -HUGE().
%
%  Example:
%
%     I  Value
%
%     0  -1
%     1,  0
%     2,  1
%     3,  1
%     4,  2
%     5,  2
%     6,  2
%     7,  2
%     8,  3
%     9,  3
%    10,  3
%   127,  6
%   128,  7
%   129,  7
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 April 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer I, the number whose logarithm base 2 is desired.
%
%    Output, integer VALUE, the integer part of the logarithm base 2 of
%    the absolute value of I.
%
  i = floor ( i );

  if ( i == 0 )

    value = -inf;

  else

    value = 0;

    i = abs ( i );

    while ( 2 <= i )
      i = i / 2;
      value = value + 1;
    end

  end

  return
end


function [B,C]=nearestKronProd(A,m1,m2,n1,n2)
%%NEARESTKRONPRODSVD Given an (m1*m2)X(n1*n2) matrix, determine the set of
%           matrices B and C that minimize norm(A-kron(B,C),'fro'). B is
%           m1Xn1 and C is m2Xn2. B and C are not unique. One can always
%           replace them with x*B and (1/x)*C for some arbitrary scalar x.
%
%INPUTS: A An (m1*m2)X(n1*n2) real matrix which is an m1Xn1 collection of
%          blocks of size m2Xn2. It has the form
%          A=[A_{1,1} ... A_{1,n1};
%             ...     ...      ...;
%             A_{m1,1} ... A_{m1,n1}];
% m1,m2,n1,n2 The dimensions specifying A and its submatrices as described
%          above. These specify the dimensions of B and C.
%
%OUTPUTS: B The m1Xn1 left matrix in the Kronecker product.
%         C The m2Xn2 right matrix in the Kronecker product.
%
%This function implements the algorithm described in Section 12.3.6 of [1].
%
%EXAMPLE:
%Here, we compute A explicitely from a Kronecker product of B and C
%matrices. The nearest Kronecker product obtained by this function should
%thus have zero error, which, within finite precision limits, is
%demonstrated.
% m1=2;
% m2=3;
% n1=5;
% n2=4;
% B=randn(m1,n1);
% C=randn(m2,n2);
% A=kron(B,C);
%
% [BK,CK]=nearestKronProd(A,m1,m2,n1,n2);
% norm(A-kron(BK,CK),'fro')%The error will be close to 0.
%
%REFERENCES:
%[1] G. H. Golub and C. F. Van Loan, Matrix Computations, 4th ed.
%    Baltimore: Johns Hopkins University Press, 2013.
%
%September 2019 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

[sigma,U,V]=KroneckerProdSVD(A,m1,n1,m2,n2);

sqrtSigma1=sqrt(sigma(1));

B=sqrtSigma1*U(:,:,1);
C=sqrtSigma1*V(:,:,1);

end

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


function [X_norm, mu, sigma] = featureNormalize(X)
%FEATURENORMALIZE Normalizes the features in X
%   FEATURENORMALIZE(X) returns a normalized version of X where
%   the mean value of each feature is 0 and the standard deviation
%   is 1. This is often a good preprocessing step to do when
%   working with learning algorithms.

% You need to set these values correctly
X_norm = X;
mu = zeros(1, size(X, 2));
sigma = zeros(1, size(X, 2));

% ====================== YOUR CODE HERE ======================
% Instructions: First, for each feature dimension, compute the mean
%               of the feature and subtract it from the dataset,
%               storing the mean value in mu. Next, compute the
%               standard deviation of each feature and divide
%               each feature by it's standard deviation, storing
%               the standard deviation in sigma.
%
%               Note that X is a matrix where each column is a
%               feature and each row is an example. You need
%               to perform the normalization separately for
%               each feature.
%
% Hint: You might find the 'mean' and 'std' functions useful.
%

mu = mean(X_norm);
sigma = std(X_norm);

tf_mu = X_norm - repmat(mu,length(X_norm),1);
tf_std = repmat(sigma,length(X_norm),1);

X_norm = tf_mu ./ tf_std;

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

end

github-repos/MATLAB/Borye-machine-learning-coursera-1/machine-learning-coursera-1-033fdc2e6da393eeb1179a09aafe92362021effb/Week 2 Assignments/Linear Regression with Multiple Variables/mlclass-ex1/featureNormalize.m


function area = triangleArea3d(pt1, pt2, pt3)
%TRIANGLEAREA3D Area of a 3D triangle.
%
%   AREA = triangleArea3d(P1, P2, P3)
%   Computes area of the 3D triangle whose vertices are given by P1, P2 and
%   P3. Each vertex is either a 1-by-3 row vector, or an array with 3
%   columns, each column representing coordinate of a vertex.
%   The result AREA has as many rows as the number of rows of the largest
%   input array.
%   Compared to polygonArea3d, this function is assumed to be faster, as it
%   does not requires iteration over vertices. Moreover, it can be used to
%   computes the area of several triangles simultaneously.
%
%   AREA = triangleArea3d(PTS)
%   Concatenates vertex coordinates in a 3-by-3 array. Each row of the
%   array contains coordinates of one vertex.
%
%
%   Example
%   triangleArea3d([10 10 10], [30 10 10], [10 40 10])
%   ans =
%       300
%
%   See also
%   polygons3d, polygonArea3d
%
% ------
% Author: David Legland
% e-mail: david.legland@grignon.inra.fr
% Created: 2011-08-23,    using Matlab 7.9.0.529 (R2009b)
% Copyright 2011 INRA - Cepia Software Platform.

% if data is given as one array, split vertices
if nargin == 1
    pt2 = pt1(2,:);
    pt3 = pt1(3,:);
    pt1 = pt1(1,:);
end

% compute individual vectors
v12 = bsxfun(@minus, pt2, pt1);
v13 = bsxfun(@minus, pt3, pt1);

% compute area from cross product
area = vectorNorm3d(cross(v12, v13, 2)) / 2;


function dist = lines_imp_dist_2d ( a1, b1, c1, a2, b2, c2 )

%*****************************************************************************80
%
%% LINES_IMP_DIST_2D determines the distance between two implicit lines in 2D.
%
%  Discussion:
%
%    If the lines intersect, then their distance is zero.
%    If the two lines are parallel, then they have a nonzero distance.
%
%    The implicit form of a line in 2D is:
%
%      A * X + B * Y + C = 0
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    24 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A1, B1, C1, define the first line.
%    At least one of A1 and B1 must be nonzero.
%
%    Input, real A2, B2, C2, define the second line.
%    At least one of A2 and B2 must be nonzero.
%
%    Output, real DIST, the distance between the two lines.
%
  dim_num = 2;
%
%  Refuse to handle degenerate lines.
%
  if ( a1 == 0.0 & b1 == 0.0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'LINES_IMP_DIST_2D - Fatal error!\n' );
    fprintf ( 1, '  Line 1 is degenerate.\n' );
    error ( 'LINES_IMP_DIST_2D - Fatal error!' );
  elseif ( a2 == 0.0 & b2 == 0.0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'LINES_IMP_DIST_2D - Fatal error!\n' );
    fprintf ( 1, '  Line 2 is degenerate.\n' );
    error ( 'LINES_IMP_DIST_2D - Fatal error!' );
  end
%
%  Determine if the lines intersect.
%
  if ( a1 * b2 ~= a2 * b1 )
    dist = 0.0;
    return
  end
%
%  Determine the distance between the parallel lines.
%
  dist = abs ( c2 / sqrt ( a2 * a2 + b2 * b2 ) - c1 / sqrt ( a1 * a1 + b1 * b1 ) );

  return
end


function pdf = cardioid_pdf ( x, a, b )

%*****************************************************************************80
%
%% CARDIOID_PDF evaluates the Cardioid PDF.
%
%  Discussion:
%
%    The cardioid PDF can be thought of as being applied to points on
%    a circle.  Compare this distribution with the "Cosine PDF".
%
%    PDF(A,B;X) = ( 1 / ( 2 * PI ) ) * ( 1 + 2 * B * COS ( X - A ) )
%    for 0 <= B <= 1/2.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 August 2005
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    N I Fisher,
%    Statistical Analysis of Circular Data,
%    Cambridge, 1993.
%
%  Parameters:
%
%    Input, real X, the argument of the PDF.
%
%    Input, real A, B, the parameters of the PDF.
%    0.0 <= B <= 0.5.
%
%    Output, real PDF, the value of the PDF.
%
  pdf = ( 1.0 + 2.0 * b * cos ( x - a ) ) / ( 2.0 * pi );

  return
end


function [means,Nmeans] = simple_kmeans(X,K,maxerr)

% function [medias,Nmedias] = simple_kmedias(X,K,maxerr)
%   Finds K prototypes representing the samples in data matrix X,
%   where each row of X represents a sample.
%   Iterates until maximum norm difference between
%   prototypes found in successive iterations is < maxerr
%
%   This script uses square Euclidean distance,
%   but can be easily modified to use other metrics
%
% Output arguments
%   means: matrix with each row a cluster prototype
%   Nmeans: Number of samples in each cluster
%
% Example:
%   X = [randn(100,1) ;  2+randn(100,1)];
%   K = 2;
%   [means Nmeans] = simple_kmeans(X,K,0)
%
%   Mauricio Martinez-Garcia, 2003,2007

[Ndata, dims] = size(X);
dist = zeros(1,K);

% Initial prototype assignment (arbitrary)
for i=1:K-1
   means(i,:) = X(i,:);
end
means(K,:) = mean(X(K:Ndata,:));

cmp = 1 + maxerr;
while (cmp > maxerr)
   % Sums (class) and data counters (Nclass) initialization
   class = zeros(K,dims);
   Nclass = zeros(K,1);

   % Groups each elements to the nearest prototype
   for i=1:Ndata
      for j=1:K
         % Euclidean distance from data to each prototype
         dist(j) = norm(X(i,:)-means(j,:))^2;
      end
      % Find indices of minimum distance
      index_min = find(~(dist-min(dist)));
      % If there are multiple min distances, decide randomly
      index_min = index_min(ceil(length(index_min)*rand));
      class(index_min,:) = class(index_min,:) + X(i,:);
      Nclass(index_min) = Nclass(index_min) + 1;
   end
   for i=1:K
      class(i,:) = class(i,:) / Nclass(i);
   end

   % Compare results with previous iteration
   cmp = 0;
   for i=1:K
      cmp = norm(class(i,:)-means(i,:));
   end

   % Prototype update
   means = class;
end

Nmeans = Nclass;


classdef PoissonD
%%POISSOND Functions to handle the Poisson distribution.
%Implemented methods are: mean, var, PMF, CDF, momentGenFun, cumGenFun,
%                         rand
%
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

methods(Static)

function val=mean(lambda)
%%MEAN Obtain the mean of the Poisson distribution for the specified mean
%      parameter.
%
%INPUTS: lambda The mean (and variance) of the Poisson distribution.
%
%OUTPUTS: val The mean of the Poisson distribution under consideration.
%
%The Poisson distribution is discussed in Chapter 2.8 of [1].
%
%EXAMPLE:
%We verify the computed mean by comparing it to the sample mean.
% lambda=10;
% meanVal=PoissonD.mean(lambda)
% numSamp=1e5;
% sampMeanVal=mean(PoissonD.rand([1,numSamp],lambda))
%One will find both values are about 10.
%
%REFERENCES:
%[1] S. M. Ross, Simulation, 4th ed. Amsterdam: Academic Press, 2006.
%
%October 2013 David F. Crouse, Naval Research Laboratory, Washington D.C.

    val=lambda;
end

function val=var(lambda)
%%VAR Obtain the variance of the Poisson distribution for the specified
%     mean parameter
%
%INPUTS: lambda The mean (and variance) of the Poisson distribution,
%
%OUTPUTS: val The variance of the Poisson distribution.
%
%The Poisson distribution is discussed in Chapter 2.8 of [1].
%
%EXAMPLE:
%We verify that the computed variance by comparing it to the sample
%variance.
% lambda=10;
% varVal=PoissonD.var(lambda)
% numSamp=1e5;
% sampVarVal=var(PoissonD.rand([1,numSamp],lambda))
%One will find both values are about 10.
%
%REFERENCES:
%[1] S. M. Ross, Simulation, 4th ed. Amsterdam: Academic Press, 2006.
%
%October 2013 David F. Crouse, Naval Research Laboratory, Washington D.C.

    val=lambda;
end

function val=PMF(x,lambda)
%%PMF Evaluate the Poisson probability mass function (PMF) at given points
%     with a specified mean parameter.
%
%INPUTS: x The point(s) at which the Poisson PMF is to be evaluated. x is
%          an integer. For nonzero PMF values, x>=0.
%   lambda The mean (and variance) of the Poisson distribution under
%          consideration.
%
%OUTPUTS: val The value(s) of the Poisson PMF with mean lambda.
%
%The Poisson distribution is discussed in Chapter 2.8 of [1].
%
%EXAMPLE:
%Here, we validate the PMF by generating random samples and comparing the
%PMF plot with a histogram of the random samples.
% lambda=6;
% numSamples=1e5;
% figure(1)
% clf
% histogram(PoissonD.rand([numSamples,1],lambda),'BinWidth',1,'Normalization','pdf')
% hold on
% x=0:16;
% vals=PoissonD.PMF(x,lambda);
% stem(x,vals,'linewidth',2)
% h1=xlabel('x');
% h2=ylabel('PDF(x)');
% set(gca,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h1,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h2,'FontSize',14,'FontWeight','bold','FontName','Times')
%One will see that the histogram matches well with the plot.
%
%REFERENCES:
%[1] S. M. Ross, Simulation, 4th ed. Amsterdam: Academic Press, 2006.
%
%September 2013 David F. Crouse, Naval Research Laboratory, Washington D.C.

    val=zeros(size(x));
    sel=(x>=0);

    val(sel)=(lambda.^x(sel)./factorial(x(sel)))*exp(-lambda);
end

function [FVal,pVal]=CDF(x,lambda)
%%CDF Evaluate the cumulative distribution function of the Poisson
%     distribution at desired points.
%
%INPUTS: x The integer point(s) at which the Poisson CDF is evaluated.
%   lambda The mean (and variance) of the Poisson distribution.
%
%OUTPUTS: FVal The CDF of the Poisson distribution evaluated at the desired
%              point(s).
%         pVal The value of the PMF of the Poisson distribution at the
%              desired point(s).
%
%The recursion is from Chapter 4.2 of [1].
%
%EXAMPLE:
%We validate the CDF value by comparing it to a value computed from random
%samples.
% lambda=6;
% x=3;
% numSamples=1e5;
% prob=PoissonD.CDF(x,lambda)
% probSamp=mean(PoissonD.rand([numSamples,1],lambda)<=x)
%One will find the values ot both be about 0.151.
%
%REFERENCES:
%[1] S. M. Ross, Simulation, 4th ed. Amsterdam: Academic Press, 2006.
%
%September 2013 David F. Crouse, Naval Research Laboratory, Washington D.C.

    FVal=zeros(size(x));
    pVal=zeros(size(x));

    x=floor(x);%In case decimals were passed.
    numEls=numel(x);

    for curEl=1:numEls
        p=exp(-lambda);
        F=p;
        for I=1:fix(x(curEl))
            p=p*lambda/I;
            F=F+p;
        end
        FVal(curEl)=F;
        pVal(curEl)=p;
    end
    FVal(x<0)=0;
    pVal(x<0)=0;
end

function momentVal=momentGenFun(lambda,numDerivs,t)
%%MOMENTGENFUN Evaluate the moment generating function (or one of its
%              derivatives) of the Poisson distribution. Taking the kth
%              derivative of the moment generating function and evaluating
%              it at t=0 provides the kth noncentral moment of the
%              distribution.
%
%INPUTS: lambda The mean (and variance) of the Poisson distribution.
%     numDerivs The number of derivatives to take with respect to the
%               argument of the moment generating function. numDerivs>=0.
%             t The numPointsX1 or 1XnumPoints vector of points where the
%               moment generating function should be evaluated. If this
%               parameter is omitted or an empty matrix is passed, the
%               default value of 0 is used.
%
%OUTPUTS: momentVal A numPointsX1 vector of the values of the derivatives
%                   of the moment generating function given at the points
%                   in t or at t=0 if t is omitted.
%
%The moment generating function of a random variable is defined to be
%E(exp(t*x)) where E is the expected value operator, x is the random
%variable and t is a real parameter. It can be shown that the moment
%generating function of the Poisson distribution is
%f^0(t)=exp(lambda*(exp(t)-1))
%By noting the pattern in differentiation (using the chain rule), it can be
%seen that the derivatives of the moment generating function can be
%recurively expressed. Specifically, if f^n(t) is the nth derivative, the
%value for n>0 is
%f^n(t)=lambda*exp(t)*(sum_{k=0}^(n-1) binomial(n-1,k)*f^k(t))
%This function evaluates the moments using the above recursion. The
%binomial terms are computed recurively using the recursion inherent to
%Pascal's triangle.
%
%Note that because the function recursively accumulates values for the
%derivatives, a lot of memory will be used if numDerivs is very large.
%
%August 2015 David F. Crouse, Naval Research Laboratory, Washington D.C.

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

numT=length(t);
momentVal=zeros(numT,1);%Allocate Space
for curT=1:numT
    tVal=t(curT);

    fVals=zeros(numDerivs+1,1);
    fVals(1)=exp(lambda*(exp(tVal)-1));%The moment generating function value.

    pascalTriangleRowOld=zeros(numDerivs+1,1);
    pascalTriangleRowOld(1)=1;
    expCoeff=exp(tVal)*lambda;
    for curDeriv=1:numDerivs
        %Get the next row of Pascal's triangle
        pascalTriangleRow=zeros(numDerivs+1,1);
        pascalTriangleRow(1)=1;
        for i=2:(curDeriv-1)
            pascalTriangleRow(i)=pascalTriangleRowOld(i-1)+pascalTriangleRowOld(i);
        end
        pascalTriangleRow(curDeriv)=1;

        fVals(curDeriv+1)=expCoeff*sum(pascalTriangleRow.*fVals);
        pascalTriangleRowOld=pascalTriangleRow;
    end

    momentVal(curT)=fVals(end);
end

end

function cumVal=cumGenFun(lambda,numDerivs,t)
%%CUMGENFUN Evaluate the cumulant generating function (or one of its
%           derivatives) of the Poisson distribution. The cumulant
%           generating function is the natural logarithm of the moment
%           generating function.
%
%INPUTS: lambda The mean (and variance) of the Poisson distribution.
%     numDerivs The number of derivatives to take with respect to the
%               argument of the cumulant generating function, numDerivs>=0.
%             t The numPointsX1 or 1XnumPoints vector of points where the
%               moment generating function should be evaluated. If this
%               parameter is omitted or an empty matrix is passed, the
%               default value of 0 is used.
%
%OUTPUTS: cumVal A numPointsX1 or 1XnumPoints vector of the values of the
%                derivatives of the cumulant generating function given at
%                the points in t or at t=0 if t is omitted.
%
%The moment generating function of a random variable is defined to be
%E(exp(t*x)) where E is the expected value operator, x is the random
%variable and t is a real parameter. The cumulant generating function is
%defined as the natural logarithm of the moment generating function. It can
%be shown that the moment generating function of the Poisson distribution
%is
%E(exp(t*x))=exp(lambda*(exp(t)-1))
%Thus, the cumulant generating function is just
%lambda*(exp(t)-1)
%All derivatives of the cumulant generating function are consequently
%exp(t)*lambda.
%
%September 2015 David F. Crouse, Naval Research Laboratory, Washington D.C.

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

if(numDerivs==0)
    cumVal=lambda*(exp(t)-1);
else
    cumVal=exp(t)*lambda;
end

end

function vals=rand(N,lambda)
%%RAND Generate Poisson random variables with a given mean.
%
%INPUTS: N If N is a scalar, then rand returns an NXN matrix of random
%          variables. If N=[M,N1] is a two-element row vector, then rand
%          returns an MXN1 matrix of random variables.
%   lambda The mean (and variance) of the Poisson distribution.
%
%OUTPUTS: vals A matrix whose dimensions are determined by N of the
%              generated Poisson random variables.
%
%The Poisson random variables are generated according to the simple
%method given in Chapter 4.2 of [1].
%
%The algorithm can handle small and large values of lambda. However, there
%is always a possibility that the value desired might be on the tail
%end of the distribution and be very slow. Thus, the number of iterations
%(the offset from the mean) is set to the maximum of 10 and 10* the
%variance.
%
%REFERENCES:
%[1] S. M. Ross, Simulation, 4th ed. Amsterdam: Academic Press, 2006.
%
%September 2013 David F. Crouse, Naval Research Laboratory, Washington D.C.

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

    maxIter=max(10,10*lambda);

    vals=zeros(dims);
    for curRow=1:dims(1)
        for curCol=1:dims(2)
            I=fix(lambda);
            [F,p]=PoissonD.CDF(I,lambda);
            U=rand(1);

            if(U<=F)
            %This means that the random number being generated is less than
            %or equal to I and we must search downward.
                while(U<F&&I>-1)
                    F=F-p;
                    p=p*(I/lambda);
                    I=I-1;
                end
                I=I+1;
            else
            %This means that the random number being generated is greater
            %than I and we must search upward starting from I+1.
                curIter=0;
                while(U>F&&curIter<maxIter)
                    p=p*lambda/(I+1);
                    F=F+p;
                    I=I+1;
                    curIter=curIter+1;
                end
            end

            vals(curRow ,curCol)=I;
        end
    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 c = vandermonde_approx_2d_coef ( n, m, x, y, z )

%*****************************************************************************80
%
%% VANDERMONDE_APPROX_2D_COEF computes a 2D polynomial approximant.
%
%  Discussion:
%
%    We assume the approximating function has the form of a polynomial
%    in X and Y of total degree M.
%
%      p(x,y) = c00
%             + c10 * x                + c01 *  y
%             + c20 * x^2   + c11 * xy + c02 * y^2
%             + ...
%             + cm0 * x^(m) + ...      + c0m * y^m.
%
%    If we let T(K) = the K-th triangular number
%            = sum ( 1 <= I <= K ) I
%    then the number of coefficients in the above polynomial is T(M+1).
%
%    We have n data locations (x(i),y(i)) and values z(i) to approximate:
%
%      p(x(i),y(i)) = z(i)
%
%    This can be cast as an NxT(M+1) linear system for the polynomial
%    coefficients:
%
%      [ 1 x1 y1  x1^2 ... y1^m ] [ c00 ] = [  z1 ]
%      [ 1 x2 y2  x2^2 ... y2^m ] [ c10 ] = [  z2 ]
%      [ 1 x3 y3  x3^2 ... y3^m ] [ c01 ] = [  z3 ]
%      [ ...................... ] [ ... ] = [ ... ]
%      [ 1 xn yn  xn^2 ... yn^m ] [ c0m ] = [  zn ]
%
%    In the typical case, N is greater than T(M+1) (we have more data and
%    equations than degrees of freedom) and so a least squares solution is
%    appropriate, in which case the computed polynomial will be a least squares
%    approximant to the data.
%
%    The polynomial defined by the T(M+1) coefficients C could be evaluated
%    at the Nx2-vector x by the command
%
%      pval = r8poly_value_2d ( m, c, n, x )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 September 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of data points.
%
%    Input, integer M, the maximum degree of the polynomial.
%
%    Input, real X(N,1), Y(N,1), the data locations.
%
%    Input, real Z(N,1), the data values.
%
%    Output, real C(T(M+1),1), the coefficients of the approximating
%    polynomial.  C(1) is the constant term, and C(T(M+1)) multiplies Y^M.
%
  tm = triangle_num ( m + 1 );

  A = vandermonde_approx_2d_matrix ( n, m, tm, x, y );

  c = A \ z(:);

  return
end


function Fx = central_diff( F, x )
% central_diff   Central Difference Gradient
%
% usage:    gradient = central_diff( F, x )
%
% inputs:   F - Values of a scalar function evaluated at x
%               to be differentiated with respect to x
%           x - vector of monotonically increasing coordinates where F is evaluated,
%               or a scalar for evenly spaced coordinates
%
% output:  gradient - numerically evaluated gradient by:
%                     forward difference at the left end;
%                     backward difference at the right end;
%                     central difference in the interior
%
% Written by:    Lt Col Robert A. Canfield
%                Air Force Institute of Technology
%                AFIT/ENY
%                2950 P Street, Bldg. 640
%                WPAFB, OH  45433-7765
%                Robert.Canfield@afit.af.mil
%
% Created:       10/19/00
% Last modified: 10/01/01
%
% Note:     MATLAB's gradient function is not second-order accurate
%           for un-evenly spaced coordinates.
%           This central_diff function uses the correct central difference
%           formula (for interior points) that is second-order accurate
%           for both evenly and un-evenly spaced coordinates.
%           Tested under MATLAB versions 5.2, 5.3.1, and 6.0.
%
% Alternatively, you may patch MATLAB's gradient function by
% replacing the lines...
%   % Take centered differences on interior points
%   if n > 2
%      h = h(3:n) - h(1:n-2);
%      g(2:n-1,:) = (f(3:n,:)-f(1:n-2,:))./h(:,ones(p,1));
%   end
%
% with...
%   % Take centered differences on interior points
%   if n > 2
%      if all(abs(diff(h,2)) < eps) % only use for uniform h (RAC)
%         h = h(3:n) - h(1:n-2);
%         g(2:n-1,:) = (f(3:n,:)-f(1:n-2,:))./h(:,ones(p,1));
%      else   % new formula for un-evenly spaced coordinates (RAC)
%         h = diff(h); h_i=h(1:end-1,ones(p,1)); h_ip1=h(2:end,ones(p,1));
%         g(2:n-1,:) =  (-(h_ip1./h_i).*f(1:n-2,:) + ...
%                         (h_i./h_ip1).*f(3:n,:)   )./ (h_i + h_ip1) + ...
%                         ( 1./h_i - 1./h_ip1 ).*f(2:n-1,:);
%      end
%   end

% Ensure compatible vectors and x monotonically increasing or decreasing
if nargin<2
	m = 1;
   h = 1;
   x = 1;
else
	m = length(x);
end
Tflag = 0;
if ndims(F)==2 & size(F,1)==1    % Treat row vector as a column vector
   F = F.';
   Tflag = 1;
end;

[n,p] = size(F);
if m==0
   error('x cannot be null')
elseif m~=1 & m~=n
	error('First dimension of F and x must be the same.')
elseif m>1 & ~( all(diff(x)>0) | all(diff(x)<0) )
	error('Vector x must be monotonically increasing or decreasing.')
elseif n<=1
   Fx = F / x;
   return
end

Fx = zeros(size(F));
x  = x(:);

% Forward difference at left end
if m==1
	h = x;
else
	h = x(2) - x(1);
end
Fx(1,:) = ( F(2,:) - F(1,:) ) / h;

% Backward difference at right end
if m>1, h = x(m) - x(m-1); end
Fx(n,:) = ( F(n,:) - F(n-1,:) ) / h;

% Central Difference in interior
if n > 3
	if m==1 | all(diff(x)==h) % Evenly spaced formula used in MATLAB's gradient routine
		Fx(2:n-1) = ( F(3:n,:) - F(1:n-2,:) ) / (2*h);
   else
		h = diff(x); h_i=h(1:m-2,ones(p,1)); h_ip1=h(2:m-1,ones(p,1));
		Fx(2:n-1,:) =  (-(h_ip1./h_i).*F(1:n-2,:) + ...
		                 (h_i./h_ip1).*F(3:n,:)   )./ (h_i + h_ip1) + ...
		        ( 1./h_i - 1./h_ip1 ).*F(2:n-1,:);
	end
end
if Tflag, Fx=Fx.'; end


function [ s, r, l ] = r8_mant ( x )

%*****************************************************************************80
%
%% R8_MANT computes the "mantissa" or "fraction part" of X.
%
%  Formula:
%
%    X = S * R * 2^L
%
%    S is +1 or -1,
%    R is a real value between 1.0 and 2.0,
%    L is an integer.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 April 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the number to be decomposed.
%
%    Output, integer S, the "sign" of the number.
%    S will be -1 if X is less than 0, and +1 if X is greater
%    than or equal to zero.
%
%    Output, real R, the mantissa of X.  R will be greater
%    than or equal to 1, and strictly less than 2.  The one
%    exception occurs if X is zero, in which case R will also
%    be zero.
%
%    Output, integer L, the integer part of the logarithm (base 2) of X.
%

%
%  Determine the sign.
%
  if ( x < 0.0 )
    s = -1;
  else
    s = 1;
  end
%
%  Set R to the absolute value of X, and L to zero.
%  Then force R to lie between 1 and 2.
%
  if ( x < 0.0 )
    r = -x;
  else
    r = x;
  end

  l = 0;
%
%  Time to bail out if X is zero.
%
  if ( x == 0.0 )
    return
  end

  while ( 2.0 <= r )
    r = r / 2.0;
    l = l + 1;
  end

  while ( r < 1.0 )
    r = r * 2.0;
    l = l - 1;
  end

  return
end


%ELIIPSOID  Plots the upper half of a parametric ellipsoid of rotation
%   Figure 13.10.For explanations see Subsection 13.26 in the book.

% define axes
a = 5;
b = 3;
c = 2;
% plot the boundary of the patch and define frame
w = 0: 0.01: 1;
x = a*cos(2*pi*w);
y = b*sin(2*pi*w);
z = zeros(size(x));
plot3(x, y, z, 'k-')
axis off, axis equal
axis([ -1.1*a 1.1*a -1.1*b 1.1*b -0.3 1.2*c ])
t = [ 'Ellipsoid x^2/a^2 + y^2/b^2 + z^2/c^2 = 1, a = ' num2str(a) ];
t = [ t ', b = ' num2str(b) ' c = ' num2str(c) ]
Ht = title(t);
set(Ht, 'FontSize', 14)
hold on
% plot now family of constant-w curves
u = 0: 0.01: 1;
for w = 0: 0.1: 1
    x = a*cos(pi*u).*cos(2*pi*w);
    y = b*cos(pi*u).*sin(2*pi*w);
    z = c*sin(pi*u);
    plot3(x, y, z, 'k-')
end
for w1 = 0.5: 0.1: 0.9
        t = [ 'w = ' num2str(w1) ];
        xt = a*cos(2*pi*w1);
        yt = b*sin(2*pi*w1);
        zt = -0.3;
        Ht = text(xt, yt, zt, t);
        set(Ht, 'FontSIze', 12)
end

% plot now family of constant-u curves
w2 = 0: 0.01: 1;
for u2 = 0: 0.1: 1
    x = a*cos(pi/2*u2).*cos(2*pi*w2);
    y = b*cos(pi/2*u2).*sin(2*pi*w2);
    z = c*sin(pi/2*u2).*ones(size(x));
    plot3(x, y, z, 'k-')
end
w3 = 0.6;
for u3   = 0: 0.1: 1
    x3   = a*cos(pi/2*u3).*cos(2*pi*w3);
    y3   = b*cos(pi/2*u3).*sin(2*pi*w3);
    z3   = c*sin(pi/2*u3).*ones(size(x3));
    t3  = [ 'u = ' num2str(u3) ];
    % xt1 = a*cos(2*pi*w3);
    % yt1 = b*sin(2*pi*w);
    % zt1 = c*sin(pi/2*u);
    Ht = text(x3, y3, z3, t3);
    set(Ht, 'FontSIze', 12)
end
hold off


function p = perms1(n,b)

% PERMS1(n,b), where n is a positive integer, creates a vector with n
% columns containing one permutation of the numbers from 1 to n. Input b is
% a number between 1 and n! which is the index of the required permutation,
% such that the output of PERMS1(n,b) for b from 1 to n! is equivalent to
% the output from perms(1:n). The order of the permutations is, however,
% different (e.g.,PERMS1(n,5) does not give the fifth row of the PERMS(1:n) output).

% The algorithm is based on imagining that the permutations are obtained by
% using n nested loops. The counter in each inner loop skips the values of all
% outer loops to generate the required permutations. A counter (index) in the
% innermost loop would count n! permutations. Working backwards, given the value
% of an index between 1 and n! this algorithm figures out the state of the
% counter in each these imaginary loops, which are actually the required
% permutation indices.

%K. H. Hamed,
%Sultan Qaboos University, Muscat, Oman
%khhamed@squ.edu.om
%21 November 2006

if nargin <2
    error('PERMS1:minrhs','Two Input Arguments are required.')
end;
if fix(n) ~= n || fix(b) ~= b ||n < 0 || b < 0 || ~isa(n,'double') || ~isa(b,'double') || ~isreal(n) || ~isreal(b)
  error('PERMS1:nnegint','Input Parameters n and b Must be Non-negative Integers');
end
a=factorial(n:-1:1);
if b>a;
    error('PERMS1:brange','Input Parameter b Should be between 1 and n!')
end;

p=zeros(1,n);                       %initialize output variable
idx=ones(1,n);                      %initialize loop counters
id=find(a<b,1);                     %locate the level at which the given index stands
for i=id-1:n-1                      %work down to figure out the counter states (idx) in each inner loop
    d=mod(b,a(i+1));                %how far down this loop?
    idx(i)=floor(b/a(i+1))+(d~=0);  %set counter, account for counter resetting
    b=d;
    if d==0;                        %adjust indices of inner loops if current loop is reset
        for j=i+1:n-1;
            idx(j)=n-j+1;
        end;
        break;
    end;
end;
m=1:n;                  %all possible indices
for i=1:n;
    p(i)=m(idx(i));     %set permutation index according to current counter index
    m=m(m~=p(i));       %current premutation index is no longer available
end;