function par = parametrize(varargin)
%PARAMETRIZE Parametrization of a polyline, based on edges lengths.
%
%   PAR = parametrize(POLY);
%   Returns a parametrization of the curve defined by the serie of points,
%   based on euclidean distance between two consecutive points.
%   POLY is a N-by-2 array, representing coordinates of vertices. The
%   result PAR is N-by-1, and contains the cumulative length of edges until
%   corresponding vertex.
%
%   PAR = parametrize(PX, PY);
%   is the same, but specify points coordinates in separate column vectors.
%
%   PAR = parametrize(..., 'normalize', 1);
%   PAR = parametrize(..., 'normalize', true);
%   Rescales the result such that the last element of PAR is 1.
%
%   Example
%     % Parametrize a circle approximation
%     poly = circleToPolygon([0 0 1], 200);
%     p = parametrize(poly);
%     p(end)
%     ans =
%         6.2829
%
%   See also
%   polygons2d, polylineLength

% ------
% Author: David Legland
% E-mail: david.legland@inrae.fr
% Created: 2003-04-06
% Copyright 2003-2022 INRA - TPV URPOI - BIA IMASTE

%% Process inputs

% extract vertex coordinates
if size(varargin{1}, 2) > 1
    % vertices in a single array
    pts = varargin{1};
    varargin(1) = [];

elseif length(varargin) == 2
    % points as separate arrays
    pts = [varargin{1} varargin{2}];
    varargin(1:2) = [];

end

% by default, do not normalize
normalize = false;

% extract options
while length(varargin) > 1
    param = varargin{1};
    switch lower(param)
        case 'normalize'
            normalize = varargin{2};
        otherwise
            error('Unknown parameter name: %s', param);
    end
    varargin(1:2) = [];
end

%% Parametrize polyline

% compute cumulative sum of euclidean distances between consecutive
% vertices, setting distance of first vertex to 0.
if size(pts, 2) == 2
    % process points in 2D
    par = [0 ; cumsum(hypot(diff(pts(:,1)), diff(pts(:,2))))];
else
    % process points in arbitrary dimension
    par = [0 ; cumsum(sqrt(sum(diff(pts).^2, 2)))];
end

% eventually rescale between 0 and 1
if normalize
    par = par / par(end);
end


function area = triangle_area_2d ( t )

%*****************************************************************************80
%
%% TRIANGLE_AREA_2D computes the area of a triangle in 2D.
%
%  Discussion:
%
%    If the triangle's vertices are given in counterclockwise order,
%    the area will be positive.  If the triangle's vertices are given
%    in clockwise order, the area will be negative!
%
%    An earlier version of this routine always returned the absolute
%    value of the computed area.  I am convinced now that that is
%    a less useful result!  For instance, by returning the signed
%    area of a triangle, it is possible to easily compute the area
%    of a nonconvex polygon as the sum of the (possibly negative)
%    areas of triangles formed by node 1 and successive pairs of vertices.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 October 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real T(2,3), the triangle vertices.
%
%    Output, real AREA, the area of the triangle.
%
  area = 0.5 * ( ...
      t(1,1) * ( t(2,2) - t(2,3) ) ...
    + t(1,2) * ( t(2,3) - t(2,1) ) ...
    + t(1,3) * ( t(2,1) - t(2,2) ) );

  return
end


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

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

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

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

Sigma = (X'*X) ./ m;
[U, S, V] = svd(Sigma);

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

end


function value = angle_rad_nd ( dim_num, v1, v2 )

%*****************************************************************************80
%
%% ANGLE_RAD_ND returns the angle in radians between two rays in ND.
%
%  Discussion:
%
%    This routine always computes the SMALLER of the two angles between
%    two rays.  Thus, if the rays make an (exterior) angle of 1.5 PI,
%    then the (interior) angle of 0.5 PI is reported.
%
%    X dot Y = Norm(X) * Norm(Y) * Cos( Angle(X,Y) )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 March 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer DIM_NUM, the spatial dimension.
%
%    Input, real V1(DIM_NUM), V2(DIM_NUM), the two rays.
%
%    Output, real ANGLE_RAD_ND, the angle between the rays,
%    in radians.  This value will always be between 0 and PI.
%
  dot = v1(1:dim_num) * v2(1:dim_num)';

  v1norm = sqrt ( sum ( v1(1:dim_num).^2 ) );

  if ( v1norm == 0.0 )
    value = 0.0;
    return
  end

  v2norm = sqrt ( sum ( v2(1:dim_num).^2 ) );

  if ( v2norm == 0.0 )
    value = 0.0;
    return
  end

  value = r8_acos ( dot / ( v1norm * v2norm ) );

  return
end


function [img, nSamples] = ellipseInterior(varargin)
% Return an image (matrix) marking the interior of an ellipse
%
% Syntax
%   [img, nSamples] = ellipseInterior(varargin)
%
% Inputs
%   N/A
%
% Optional key/value pairs
%   center  - Center of the ellipse
%   sigma   - Sigma major and minor as a 2-vector
%   theta   - Angle of sigma major from the x-axis (counter clockwise)
%
% Returns
%   img:  1 in the interior and 0 in the exterior
%   nSamples:  Number of interior samples
%
% Description
%   We start with an ellipse with its major axis aligned to the
%   x-axis.  We then rotate (counter clockwise) by an amount theta.
%
%  This is the equation for the contour of the ellipse
%
%     1 = A*(x-h)^2 + 2B*(x-h)*(y-k) + C*(y-k)^2
%
%  The quadratic form is Q = [A B; B C];
%  We test that the parameters are valid (i.e., Q is positive-definite
%  (i.e., Q = M*M') by
%
%    A > 0
%    det(Q) > 0
%
%  We convert from sigma(1), sigma(2), theta to Q and inversely using
%
%        Q = Rotate(theta)'*[diag(a^2,b^2)]*Rotate(theta)
%{
%  [U,S,V] = svd(Q)
%  Figure out theta from U and get a, b from sqrt(S)
%  Since
%      rotMat = [cos(theta) -sin(theta); -sin(theta) -cos(theta)];
%      theta = acos(U(1,1))
%
% Some experimenting
%
% It must be a > b for major/minor axes
a = 3; b = 2; theta = pi/6;
rotMat = [cos(theta) -sin(theta); -sin(theta) -cos(theta)];
Q = rotMat' * diag([a^2, b^2]) * rotMat;

[U,S,V] = svd(Q);
abs(U) - abs(rotMat)  % Not sure why there can be a sign difference
thetaEst = min(acos(U(1,1)),acos(-1*U(1,1)));
theta - thetaEst
%}
%
% Notes:
%
%  https://math.stackexchange.com/questions/264446/the-fastest-way-to-obtain-orientation-%CE%B8-from-this-ellipse-formula
%
% Wandell, January 13 2020
%
% See also
%    ellipsePlot()

% Examples:
%{
   img = ellipseInterior;
   mrvNewGraphWin; imagesc(img); axis equal
%}
%{
   samples = [-3:0.1:3];
   [img, nSamples]  = ellipseInterior('center',[1 2],'spatial samples',samples);
   [img2, nSamples] = ellipseInterior('center',[0.5 2],'spatial samples',samples);

   % mrvNewGraphWin; imagesc(img); axis image
   % mrvNewGraphWin; imagesc(img2); axis image
   overlap = dot(img(:), img2(:))/nSamples;
   fprintf('Overlap is %f\n',overlap);
%}
%{
   samples = [-10:0.1:10];
   sigma = [3,1];
   [img, nSamples]   = ellipseInterior('center',[0 0],'sigma',sigma,'spatial samples',samples);
   [img2, nSamples]  = ellipseInterior('center',[-1 -4],'sigma',sigma,'spatial samples',samples);
   mrvNewGraphWin; imagesc(samples,samples,img); axis image
   mrvNewGraphWin; imagesc(samples,samples,img2); axis image
   overlap = dot(img(:), img2(:))/nSamples;
   fprintf('Overlap is %f\n',overlap);
%}
%{
   img = ellipseInterior('center',[1 1],'quadratic',0.3*eye(2));
   mrvNewGraphWin; imagesc(img);
%}
%% Input parameters

varargin = mrvParamFormat(varargin);

p = inputParser;
p.addParameter('center',[0 0],@isvector);
p.addParameter('spatialsamples',(-3:0.05:3),@isvector);
vFunc = @(x)(length(x) == 2 && x(1) >= x(2) && isnumeric(x));
p.addParameter('sigma',[1 1],vFunc);   % Length in degrees
p.addParameter('theta',0,@isvector);   % Radians

p.parse(varargin{:});
c = p.Results.center;
samples = p.Results.spatialsamples;
sigma   = p.Results.sigma;
theta   = p.Results.theta;

%%  Test that we have a true ellipse formula

rotMat = [cos(theta) -sin(theta); -sin(theta) -cos(theta)];
Q = rotMat' * diag([1/sigma(1)^2, 1/sigma(2)^2]) * rotMat;
if Q(1,1) <= 0 || det(Q) <= 0 || Q(1,2) ~= Q(2,1)
    error('Q is not positive definite');
end

%% Create the spatial samples and compute the values

[X,Y] = meshgrid(samples,samples);

X = X - c(1);
Y = Y - c(2);
V = Q(1,1)*X.^2 + 2*Q(1,2)*X.*Y + Q(2,2)*Y.^2;
% mrvNewGraphWin; mesh(V)

%% Binarize
img = zeros(size(X));
img(V<=1) = 1;

% mrvNewGraphWin; imagesc(img)

if nargout > 1
    nSamples = sum(img(:));
end

end


% Figure 8.10: Approximate linear discrimination via linear programming
% Section 8.6.1, Boyd & Vandenberghe "Convex Optimization"
% Original by Lieven Vandenberghe
% Adapted for CVX by Joelle Skaf - 10/16/05
% (a figure is generated)
%
% The goal is to find a function f(x) = a'*x - b that classifies the non-
% separable points {x_1,...,x_N} and {y_1,...,y_M} by allowing some
% misclassification. a and b can be obtained by solving the following
% problem:
%           minimize    1'*u + 1'*v
%               s.t.    a'*x_i - b >= 1 - u_i        for i = 1,...,N
%                       a'*y_i - b <= -(1 - v_i)     for i = 1,...,M
%                       u >= 0 and v >= 0

% data generation
n = 2;
randn('state',2);
N = 50; M = 50;
Y = [1.5+0.9*randn(1,0.6*N), 1.5+0.7*randn(1,0.4*N);
     2*(randn(1,0.6*N)+1), 2*(randn(1,0.4*N)-1)];
X = [-1.5+0.9*randn(1,0.6*M),  -1.5+0.7*randn(1,0.4*M);
      2*(randn(1,0.6*M)-1), 2*(randn(1,0.4*M)+1)];
T = [-1 1; 1 1];
Y = T*Y;  X = T*X;

% Solution via CVX
cvx_begin
    variables a(n) b(1) u(N) v(M)
    minimize (ones(1,N)*u + ones(1,M)*v)
    X'*a - b >= 1 - u; %#ok
    Y'*a - b <= -(1 - v); %#ok
    u >= 0; %#ok
    v >= 0; %#ok
cvx_end

% Displaying results
linewidth = 0.5;  % for the squares and circles
t_min = min([X(1,:),Y(1,:)]);
t_max = max([X(1,:),Y(1,:)]);
tt = linspace(t_min-1,t_max+1,100);
p = -a(1)*tt/a(2) + b/a(2);
p1 = -a(1)*tt/a(2) + (b+1)/a(2);
p2 = -a(1)*tt/a(2) + (b-1)/a(2);

graph = plot(X(1,:),X(2,:), 'o', Y(1,:), Y(2,:), 'o');
set(graph(1),'LineWidth',linewidth);
set(graph(2),'LineWidth',linewidth);
set(graph(2),'MarkerFaceColor',[0 0.5 0]);
hold on;
plot(tt,p, '-r', tt,p1, '--r', tt,p2, '--r');
axis equal
title('Approximate linear discrimination via linear programming');
% print -deps svc-discr.eps


% GAUSS3D - generate a 3-dimensional gaussian matrix
%
% Usage:
%   >> [ gaussmatrix ] = gauss2d( nX, nY, nZ);
%   >> [ gaussmatrix ] = gauss2d( nX, nY, nZ, ...
%                              sigmaX, sigmaY, sigmaZ, ...
%                              centerX, centerY, centerZ, mask)
%
% Example:
%   >> gauss3d(3,3,3); % generate a 3x3x3 gaussian matrix
%
% Inputs:
%   nX    - number of values in first dimension
%   nY    - number of values in second dimension
%   nZ    - number of values in third dimension
%   sigmaX  - width of standard deviation in first dim (default: nX/5)
%   sigmaY  - width of standard deviation in second dim (default: nY/5)
%   sigmaZ  - width of standard deviation in third dim (default: nZ/5)
%   centerX - location of center (default: nX/2)
%   centerY - location of center (default: nY/2)
%   centerZ - location of center (default: nZ/2)
%   mask    - (0->1) percentage of low values in the matrix to mask
%             with zeros (default: 0 or none)
%
% Output:
%   gaussmatrix - 3-D gaussian matrix
%
% Author: Arnaud Delorme, 2009

% Copyright (C) 2009 Arnaud Delorme, Salk Institute, arno@salk.edu
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.

function mat = gauss3d( sizeX, sizeY, sizeZ, sigmaX, sigmaY, sigmaZ, meanX, meanY, meanZ, cut);

if nargin < 2
	help gauss2d
	return;
end
if nargin < 4
	sigmaX = sizeX/5;
end
if nargin < 5
	sigmaY = sizeY/5;
end
if nargin < 6
	sigmaZ = sizeZ/5;
end
if nargin < 7
	meanX = (sizeX+1)/2;
end
if nargin < 8
	meanY = (sizeY+1)/2;
end
if nargin < 9
	meanZ = (sizeZ+1)/2;
end
if nargin < 10
	cut = 0;
end

[X,Y,Z] = ndgrid(1:sizeX,1:sizeY,1:sizeZ);

mat = exp(-0.5*(  ((X-meanX)/sigmaX).*((X-meanX)/sigmaX)...
				 +((Y-meanY)/sigmaY).*((Y-meanY)/sigmaY)...
				 +((Z-meanZ)/sigmaZ).*((Z-meanZ)/sigmaZ)))...
            			/((sigmaX*sigmaY*sigmaZ)^(0.5)*pi);

if cut > 0
	maximum = max(mat(:))*cut;
	I = find(mat < maximum);
	mat(I) = 0;
end

return;


x = load('ex3x.dat');
y = load('ex3y.dat');
m = length(y);
x = [ones(m, 1), x];

# figure;
# plot(x(:,2), y, 'x');
# ylabel('Price in $');
# xlabel('Living area in square feet');

# figure;
# plot(x(:,3), y, 'x');
# ylabel('Price in $');
# xlabel('Number of bedrooms');

sigma = std(x);
mu = mean(x);
x(:,2) = (x(:,2) - mu(2)) ./ sigma(2);
x(:,3) = (x(:,3) - mu(3)) ./ sigma(3);

num_iterations = 50;

alphas = [0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1, 1.3, 3, 10];
J = zeros(num_iterations, length(alphas));

for iter = 1:length(alphas)
  theta = zeros(size(x(1,:)))';
  alpha = alphas(iter);
  for num_iterations = 1:50
    J(num_iterations, iter) = (1/2*m) * (x * theta - y)' * (x * theta - y);
    theta = theta - alpha * (1/m) * x' * (x * theta - y);
  end
end

figure;
hold on;

for iter = 1:length(alphas)-2
  alpha = alphas(iter);

  % now plot J
  % technically, the first J starts at the zero-eth iteration
  % but Matlab/Octave doesn't have a zero index
  plot(0:49, J(1:50, iter), '-');
  xlabel(['Number of iterations, alpha = ' num2str(alpha)]);
  ylabel('Cost J');
end

alpha = 1;
theta = zeros(size(x(1,:)))';
for num_iterations = 1:100
  theta = theta - alpha * (1/m) * x' * (x * theta - y);
end

theta

x1 = ([2, 1650, 3] - mu) ./ (sigma + [1,0,0]);
y_predicted_1 = x1 * theta

% Normal Equations

% Reload data
x = load('ex3x.dat');
y = load('ex3y.dat');
m = length(y);
x = [ones(m, 1), x];

theta = (x' * x) \ (x' * y)

x2 = [1 1650 3];
y_predicted_2 = x2 * theta


function [post,lik,lli] = logistK_eval(beta,x,y)
% [post,lik,lli] = logistK_eval(beta,x,y)
%
% Evaluate logistic regression model.
%
% INPUT
% 	beta 	dxk model coefficients (as returned by logistK)
% 	x 	dxn matrix of n input column vectors
% 	[y] 	kxn vector of class assignments
%
% OUTPUT
% 	post 	kxn fitted class posteriors
% 	lik 	1xn vector of sample likelihoods
%	lli	log likelihood
%
% Let p(i,j) = exp(beta(:,j)'*x(:,i)),
% Class j posterior for observation i is:
%	post(j,i) = p(i,j) / (p(i,1) + ... p(i,k))
% The likelihood of observation i given soft class assignments
% y(:,i) is:
%	lik(i) = prod(post(:,i).^y(:,i))
% The log-likelihood of the model given the labeled samples is:
%	lli = sum(log(lik))
%
% See also logistK.
%
% David Martin <dmartin@eecs.berkeley.edu>
% May 7, 2002

% Copyright (C) 2002 David R. Martin <dmartin@eecs.berkeley.edu>
%
% This program is free software; you can redistribute it and/or
% modify it under the terms of the GNU General Public License as
% published by the Free Software Foundation; either version 2 of the
% License, or (at your option) any later version.
%
% This program is distributed in the hope that it will be useful, but
% WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
% General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
% 02111-1307, USA, or see http://www.gnu.org/copyleft/gpl.html.

error(nargchk(2,3,nargin));

% check sizes
if size(beta,1) ~= size(x,1),
  error('Inputs beta,x not the same height.');
end
if nargin > 3 & size(y,2) ~= size(x,2),
  error('Inputs x,y not the same length.');
end

% get sizes
[d,k] = size(beta);
[d,n] = size(x);

% class posteriors
post = zeros(k,n);
bx = zeros(k,n);
for j = 1:k,
  bx(j,:) = beta(:,j)'*x;
end
for j = 1:k,
  post(j,:) = 1 ./ sum(exp(bx - repmat(bx(j,:),k,1)),1);
end
clear bx;

% likelihood of each sample
if nargout > 1,
  y = y ./ repmat(sum(y,1),k,1); % L1-normalize class assignments
  lik = prod(post.^y,1);
end

% total log likelihood
if nargout > 2,
  lli = sum(log(lik+eps));
end;

% eof


function distVal=GaussianSimilarity(mu1,Sigma1,mu2,Sigma2)
%%GAUSSIANSIMILARITY This is the normalized similarity measure used between
%               two Gaussian distributions in the Appendix of [1]. It
%               ranges from 0 (completely different) to 1 (same
%               distribution).
%
%INPUTS: mu1 The xDimX1 mean of the first Gaussian distribution.
%     Sigma1 The xDimXxDim covariance matrix of the first Gaussian
%            distribution.
%        mu2 The xDimX1 mean of the second Gaussian distribution.
%     Sigma2 The xDimXxDim covariance matrix of the second Gaussian
%            distribution.
%
%OUTPUTS: distVal The scalar distance between the two distributions.
%
%EXAMPLE:
%We show the similairty of identical distirbutions, extremely different
%distributions, and distributions that just differ a little bit.
% mu1=[12;3];
% mu2=[2000;8000];
% Sigma1=[10, 6;
%          6, 9];
% Sigma2=[8, -3;
%        -3, 14];
% %Identical Distributions (Similarity is 1).
% GaussianSimilarity(mu1,Sigma1,mu1,Sigma1)
% %Distributions that are very different (Similarity is 0).
% GaussianSimilarity(mu1,Sigma1,mu2,Sigma2)
% %Distributions that only differ a little bit (Similarity is about
% %0.2163).
% GaussianSimilarity(mu1,Sigma1,mu1*0.5,Sigma1*0.5)
%
%REFERENCES:
%[1] F. Faubel, J. McDonough, and D. Klakow, "The split and merge unscented
%    Gaussian mixture filter," IEEE Signal Processing Letters, vol. 16, no.
%    9, pp. 786-789, Sep. 2009.
%
%January 2021 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

%Equation 16.
Sigma12Inv=inv(Sigma1)+inv(Sigma2);
%Equation 15.
mu12=Sigma12Inv\(Sigma1\mu1+Sigma2\mu2);

numDim=size(mu1,1);
z=zeros(numDim,1);

p1=GaussianD.PDF(z,mu1,Sigma1/2);
p2=GaussianD.PDF(z,mu2,Sigma2/2);
p12=GaussianD.PDFI(z,mu12,Sigma12Inv);

if(p1==0||p2==0||p12==0||p1*p2==0)
    distVal=0;
else
    distVal=sqrt(p1*p2)/p12;
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 = pyramid_volume_3d ( r, h )

%*****************************************************************************80
%
%% PYRAMID_VOLUME_3D returns the volume of a pyramid with square base in 3D.
%
%  Integration region:
%
%    Z - 1 <= X <= 1 - Z
%    Z - 1 <= Y <= 1 - Z
%    0 <= Z <= 1.
%
%  Discussion:
%
%    A pyramid with square base can be regarded as the upper half of a
%    3D octahedron.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R, the "radius" of the pyramid, that is, half the
%    length of one of the sides of the square base.
%
%    Input, real H, the height of the pyramid.
%
%    Output, real PYRAMID_VOLUME_3D, the volume of the pyramid.
%
  value = ( 4.0 / 3.0 ) * h * r * r;

  return
end


function value = lens_half_w_area_2d ( r, w )

%*****************************************************************************80
%
%% LENS_HALF_W_AREA_2D returns the area of a circular half lens in 2D.
%
%  Discussion:
%
%    A circular half lens is formed by drawing a circular arc, and joining its endpoints.
%    This particular half lens is described by the "width" of the region.  In other words,
%    it is the portion of the circle under water if the width
%    of the water surface is W.  There are two possible values for this
%    area, A and (PI*R**2-A).  The routine returns the smaller of the
%    two values.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R, the radius of the circle.
%
%    Input, real W, the width of the half lens.
%
%    Output, real VALUE, the area of the half lens.
%
  if ( w <= 0.0E+00 )

    value = 0.0E+00;

  elseif ( 2.0E+00 * r <= w )

    value = 0.5E+00 * pi * r * r;

  else

    half_width = 0.5E+00 * w;
    h = r - sqrt ( r * r - half_width * half_width );
    angle = 2.0E+00 * atan2 ( half_width, r - h );
    sector = r * r * angle / 2.0E+00;
    triangle = ( r - h ) * half_width;
    value = sector - triangle;

  end

  return
end


function intVal=monomialIntSpherSurf(alpha)
%%MONOMIALINTSPHERSURF Evaluate the integral of prod_{i=1}^Nx(i)^alpha(i)
%          over the surface defined by sum(x.^2)=1. That is, this function
%          gives the value of the desired monomial integral taken over the
%          surface of an n-dimensional hypersphere. The region is
%          designated as U_n in [1].
%
%INPUTS: alpha An NX1 or 1XN vector of the integer exponents of the
%              monomial term. All elements must be >=0.
%
%OUTPUTS: intVal The value of the specified integral.
%
%The formula is taken from Chapter 7.6 of [1]. These types of explicit
%moment formulae are useful for testing cubature integration points.
%
%EXAMPLE:
%Here we verify that the moment value produced here equals that obtained
%using cubature points of an appropriate order.
% [xi,w]=seventhOrderSpherSurfCubPoints(3);
% alpha=[0;4;2];
% theMoment=findMomentFromSamp(alpha,xi,w)
% intVal=monomialIntSpherSurf(alpha)
%One will see that theMoment and intVal are both about 0.3590.
%
%REFERENCES:
%[1] A.H. Stroud, Approximate Calculation of Multiple Integrals. Cliffs,
%    NJ: Prentice-Hall, Inc., 1971.
%
%February 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

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

    intVal=2*exp(sum(gammaln((alpha+1)/2))-gammaln((n+sum(alpha))/2));
else
    intVal=0;
end
end

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


function call_price=american_call_futures_currcy_bin(S, K, r, r_f, sigma, time, no_steps)

%--------------------------------------------------------------------------
%
% DESCRIPTION:
%
% Pricing a futures currency option using a binomial approximation
%
%
% Reference:
%
% John Hull, "Options, Futures and other Derivative Securities",
% Prentice-Hall, second edition, 1993.
%
%--------------------------------------------------------------------------
%
% INPUTS:
%
%  S:           spot price
%  K:           exercice price
%  r:           domestic interest rate
%  r_f:         foreign interest rate
%  sigma:       volatility
%  time:        time to maturity
%  no_steps:    number of steps in binomial tree
%
%--------------------------------------------------------------------------
%
% OUTPUT:
%
% call_price: price of a call option
%
%--------------------------------------------------------------------------
%
% Author:  Paolo Z., February 2012
%
%--------------------------------------------------------------------------

exchange_rates=zeros(no_steps+1,1);

call_values=zeros(no_steps+1,1);

t_delta= time/no_steps;
Rinv = exp(-r*(t_delta));
u = exp(sigma*sqrt(t_delta));
d = 1.0/u;
uu= u*u;
pUp = (exp((r-r_f)*t_delta)-d)/(u-d);
pDown = 1.0 - pUp;
exchange_rates(1) = S*(d^no_steps);

for ( i=2:(no_steps+1) )
    exchange_rates(i) = uu*exchange_rates(i-1);
end

for ( i=1:(no_steps+1) )
    call_values(i) = max(0.0, (exchange_rates(i)-K));
end

for ( step=no_steps:-1:1 )
    for ( i=1:1:(step) )
        exchange_rates(i) = d*exchange_rates(i+1);
        call_values(i) = (pDown*call_values(i)+pUp*call_values(i+1))*Rinv;
        call_values(i) = max(call_values(i), exchange_rates(i)-K);
    end
end

call_price = call_values(1);


function J=polarU2DCrossGrad(uList,systemType)
%%POLARU2DCROSSGRAD Given the direction cosine value u in 2D, obtain the
%              derivative of the polar azimuth angle with respect to u.
%
%INPUTS: uList A 1XnumPoints (for only u) or a 2XnumPoints (if full unit
%              vectors are given) set of direction cosines in 2D.
%   systemType An optional parameter specifying the axis from which the
%              angles are measured. Possible values are
%              0 (The default if omitted or an empty matrix is passed) The
%                azimuth angle is counterclockwise from the x axis.
%              1 The azimuth angle is measured clockwise from the y axis.
%
%OUTPUTS: J A 1XnumPoints set of derivatives of the azimuth angle with
%           respect to u evaluated at the given u values.
%
%EXAMPLE:
%Here, we verify that the derivatives returned by this function are about
%equal to those returned via numeric differentiation (forward
%differencing).
% points=[0.1,0.2,-0.2,0,-0.9];%u points
% systemType=1;
% epsVal=1e-9;
%
% az=u2PolAng2D(points,systemType);
% az1=u2PolAng2D(points+epsVal,systemType);
% JNumDiff=(az1-az)/epsVal;
% J=polarU2DCrossGrad(points,systemType);
%
% max(abs(JNumDiff-J))
%One will see that the difference is on the order of 3e-8, which is a good
%agreement.
%
%June 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

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

hasV=size(uList,1)>1;

N=size(uList,2);

J=zeros(1,N);
for curPoint=1:N
    u=uList(1,curPoint);

    if(hasV)
        v=uList(2,curPoint);
    else
        v=sqrt(1-u^2);
    end

    switch(systemType)
        case 0
            J(curPoint)=-1/v;
        case 1
            J(curPoint)=1/v;
        otherwise
            error('Invalid system type specified.')
    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 area = polygonArea(poly, varargin)
%POLYGONAREA Compute the signed area of a polygon.
%
%   A = polygonArea(POINTS);
%   Compute area of a polygon defined by POINTS. POINTS is a N-by-2 array
%   of double containing coordinates of vertices.
%
%   Vertices of the polygon are supposed to be oriented Counter-Clockwise
%   (CCW). In this case, the signed area is positive.
%   If vertices are oriented Clockwise (CW), the signed area is negative.
%
%   If polygon is self-crossing, the result is undefined.
%
%   Examples
%     % compute area of a simple shape
%     poly = [10 10;30 10;30 20;10 20];
%     area = polygonArea(poly)
%     area =
%         200
%
%     % compute area of CW polygon
%     area2 = polygonArea(poly(end:-1:1, :))
%     area2 =
%         -200
%
%     % Computes area of a paper hen
%     x = [0 10 20  0 -10 -20 -10 -10  0];
%     y = [0  0 10 10  20  10  10  0 -10];
%     poly = [x' y'];
%     area = polygonArea(poly)
%     area =
%        400
%
%     % Area of unit square with 25% hole
%     pccw = [0 0; 1 0; 1 1; 0 1];
%     pcw = pccw([1 4 3 2], :) * .5 + .25;
%     polygonArea ([pccw; nan(1,2); pcw])
%     ans =
%        0.75
%
%   References
%   algo adapted from P. Bourke web page
%   http://paulbourke.net/geometry/polygonmesh/
%
%   See also
%   polygons2d, polygonCentroid, polygonSecondAreaMoments, triangleArea
%

% ------
% Author: David Legland
% E-mail: david.legland@inrae.fr
% Created: 2004-05-05
% Copyright 2004-2022 INRA - TPV URPOI - BIA IMASTE

%% Process special cases

% in case of polygon sets, computes the sum of polygon areas
if iscell(poly)
    area = 0;
    for i = 1:length(poly)
        area = area + polygonArea(poly{i});
    end
    return;
end

% check there are enough points
if size(poly, 1) < 2
    area = 0;
    return;
end

% case of polygons with holes -> computes the sum of areas
if any(isnan(poly))
    area = sum(polygonArea(splitPolygons(poly)));
    return;
end

%% Process single polygons or single rings

% extract coordinates
if nargin == 1
    % polygon given as N-by-2 array
    px = poly(:, 1);
    py = poly(:, 2);

elseif nargin == 2
    % poylgon given as two N-by-1 arrays
    px = poly;
    py = varargin{1};
end

% indices of next vertices
N = length(px);
iNext = [2:N 1];

% compute area (vectorized version)
area = sum(px .* py(iNext) - px(iNext) .* py) / 2;


function [ c, ierror ] = r8mat_cholesky_factor ( n, a )

%*****************************************************************************80
%
%% R8MAT_CHOLESKY_FACTOR computes the Cholesky factor of a symmetric matrix.
%
%  Discussion:
%
%    The matrix must be symmetric and positive semidefinite.
%
%    For a positive semidefinite symmetric matrix A, the Cholesky factorization
%    is a lower triangular matrix L such that:
%
%      A = L * L'
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%
%    Input, real A(N,N), the matrix.
%
%    Output, real C(N,N), the lower triangular Cholesky factor.
%
%    Output, integer IERROR, error flag.
%    0, no error.
%    1, warning, the matrix is positive semidefinite.  The factorization
%    was carried out, but the matrix is singular.
%    2, error, the matrix has at least one negative eigenvalue.  The
%    factorization could not be completed.
%
  ierror = 0;

  c(1:n,1:n) = a(1:n,1:n);

  for j = 1 : n

    c(1:j-1,j) = 0.0;

    for i = j : n

      ctc = c(j,i) - c(i,1:j-1) c(j,1:j-1)';

      if ( i == j )
        if ( ctc < 0.0 )
          ierror = 2;
          return
        elseif ( ctc == 0.0 )
          ierror = 1;
        else
          c(i,j) = sqrt ( ctc );
        end
      else
        if ( c(j,j) ~= 0.0 )
          c(i,j) = ctc / c(j,j);
        else
          c(i,j) = 0.0;
        end
      end

    end

  end

  return
end


function value = sphere_area_3d ( r )

%*****************************************************************************80
%
%% SPHERE_AREA_3D computes the area of a sphere in 3D.
%
%  Integration region:
%
%    Points (X,Y,Z) such that
%
%      X**2 + Y**2 + Z**2 = R**2
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R, the radius of the sphere.
%
%    Output, real SPHERE_AREA_3D, the area of the sphere.
%
  value = 4.0E+00 * pi * r * r;

  return
end


function s = gen(mode, len, frequency, samplerate, amplitude, startphase, yunit)

% signal/gen
%
% generate various kind of signals with time axis
%
% si = gen(mode, len, frequency, samplerate, amplitude, startphase, yunit)
%
% len is measured in seconds
% frequency, samplerate in Hertz
% amplitude is measured in the current yunit (default is dimensionless)
% startphase in radians
% yunit is an optional argument
%
% mode may be one of the following :
% sine              - sinusodial signal between [-amplitude +amplitude]
% unoise            - uniform distrubuted random numbers in interval [-amplitude +amplitude]
% gnoise            - gaussian random numbers with zero mean
% fnoise            - spectral flat noise with zero mean (DC value = 0)
% rect				- rectangular signal with values discret values 0 and amplitude
% symmrect          - rectangular signal with values discret values -amplitude and amplitude
% comb              - train of (one sample wide) spikes of height amplitude, otherwise signal is zero
%
%
% cmerk Feb. 1998

if nargin < 1
	mode = 'sine';		% sine, uniform noise, gaussian noise, rect, puls ...
end
if nargin < 2
	len = 1;		% one second
end
if nargin < 3
	frequency = 1000;	% 1000 Hz
end
if nargin < 4
	samplerate = 8000;	% Hertz
end
if nargin < 5
	amplitude = 1.0;
end
if nargin < 6
	startphase = 0; 	% radian, 0..2pi
end
if nargin < 7
	yunit = unit;		% no dimension
end

len = ceil(len*samplerate);
xfirst = 0;
optinaltext = '';
switch mode
case	'sine'
	t = (2*pi*frequency/samplerate)*(0:len-1)' + startphase;
	tmp = amplitude * sin(t);
	optinaltext = [' with frequency : ' num2str(frequency) 'Hz'];
case	'unoise'
	tmp = (2* amplitude) * (rand(len,1)-0.5);
case	'gnoise'
	tmp = amplitude * gauss(len);
case	'fnoise'
	if mod(len, 2)
		N = (len-1)/2;
		r = exp(2*pi*i*rand(N,1));
		tmp = [0; r; conj(r(end:-1:1))];
	else							% even length
		N = (len/2)-1;
		r = exp(2*pi*i*rand(N,1));
		tmp = [0; r; 1; conj(r(end:-1:1))];
	end
	tmp = (amplitude/2) * real(ifft(tmp));
case	'rect'
	tolerance = 1e-8;
	t = (2*pi*frequency/samplerate)*(0:len-1)' + startphase;
	tmp = sin(t);
	ind = find(tmp>tolerance);
	tmp(ind) = amplitude;
	ind = find(abs(tmp)<=tolerance);
	tmp(ind(1:2:end)) = amplitude;	% zeros values are set to amplitude zero amplitude zero ...
	tmp(ind(2:2:end)) = 0;
	ind = find(tmp<tolerance);
	tmp(ind) = 0;
	optinaltext = [' with frequency : ' num2str(frequency) 'Hz'];
case	'symmrect'
	tolerance = 1e-8;
	t = (2*pi*frequency/samplerate)*(0:len-1)' + startphase;
	tmp = sin(t);
	ind = find(tmp>tolerance);
	tmp(ind) = amplitude;
	ind = find(abs(tmp)<=tolerance);
	tmp(ind(1:2:end)) = amplitude;	% zeros values are set to amplitude zero amplitude zero ...
	tmp(ind(2:2:end)) = 0;
	ind = find(tmp<tolerance);
	tmp(ind) = -amplitude;
	optinaltext = [' with frequency : ' num2str(frequency) 'Hz'];
case	'comb'
	t = (pi*frequency/samplerate)*(0:len-1)' + startphase;
	tmp = sin(t);
	zerocrossing = tmp(1:end-1) .* tmp(2:end);
	ind = find(zerocrossing<0);
	tmp = zeros(len,1);
	tmp(ind) = amplitude;
	if mod(startphase,2*pi) == 0
		tmp(1) = amplitude;
	end
	optinaltext = [' with frequency : ' num2str(frequency) 'Hz'];
case	'sinc'
	tolerance = 1e-10;
	t = (2* pi*frequency/samplerate)*(0:len-1)' + startphase;
	ind = find(abs(t)<tolerance);
	t(ind) = 1;
	tmp = amplitude * (sin(t)./t);
	tmp(ind) = amplitude;
	optinaltext = [' with frequency : ' num2str(frequency) 'Hz'];
otherwise
	error(['mode ' mode ' not supported']);
end

s = signal(tmp, ['Generated ' mode ' signal' optinaltext]);
s = setaxis(s, 1,achse(unit('s'), xfirst, 1/samplerate));
s = setyunit(s, yunit);
s = settype(s, 'scalar timeseries');


%--- help for sym/hessian ---
%
% HESSIAN Hessian matrix.
%    HESSIAN(f,x) computes the Hessian of the scalar f with respect
%    to the vector x. The (i,j)-th entry of the resulting matrix is
%    (d^2f/(dx(i)dx(j)). Note that scalar x is allowed although this
%    is just DIFF(f,x,2).
%
%    Example:
%        syms x y z; hessian(x*y + 2*z*x, [x, y, z])
%        returns  [0, 1, 2; 1, 0, 0; 2, 0, 0]
%
%    See also SYM/CURL, SYM/DIFF, SYM/GRADIENT, SYM/JACOBIAN, SYM/DIVERGENCE,
%    SYM/POTENTIAL, CURL, DIVERGENCE, HESSIAN, JACOBIAN, LAPLACIAN,
%    VECTORPOTENTIAL, SUBS.
%
%    Other functions named hessian
%
%       generic/hessian
%


function d = dcircle ( p, xc, yc, r )

%*****************************************************************************80
%
%% DCIRCLE returns the signed distance of one or more points to a circle.
%
%  Discussion:
%
%    The corresponding routine in 3D is DSPHERE.
%
%  Copyright:
%
%    (C) 2004 Per-Olof Persson.
%    See COPYRIGHT.TXT for details.
%
%  Reference:
%
%    Per-Olof Persson and Gilbert Strang,
%    A Simple Mesh Generator in MATLAB,
%    SIAM Review,
%    Volume 46, Number 2, June 2004, pages 329-345.
%
%  Parameters:
%
%    Input, real P(NP,2), the point coordinates.
%
%    Input, real XC, YC, the coordinates of the center of the circle.
%
%    Input, real R, the radius of the circle.
%
%    Output, real D(NP), the signed distance of each point to the
%    circle.  The point is inside, on, or outside the circle depending
%    on whether D is negative, zero, or positive.
%
  d = sqrt ( ( p(:,1) - xc ).^2 + ( p(:,2) - yc ).^2 ) - r;

  return
end


function A=signedPolygonArea(vertices)
%%SIGNEDPOLYGONAREA Calculate the signed area of a non-self-intersecting
%                   2D polygon given its vertices. The magnitude of the
%                   area is the typical definition of area that one might
%                   expect. The sign of the area is positive if the points
%                   are arranged in a counterclockwise order around the
%                   polygon and negative if the points are in a clockwise
%                   order.
%
%INPUTS: vertices A 2XN list of the N vertices of the polygon in order
%                 around the polygon. Duplicate vertices are allowed. It
%                 does not matter whether or not the first vertex is
%                 repeated at the end.
%
%OUTPUTS: A The signed area of the polygon.
%
%The formula for computing the signed area of a non-self-intersecting
%polygon is taken from [1].
%
%REFERENCES:
%[1] Weisstein, Eric W. "Polygon Area." From MathWorld--A Wolfram Web
%    Resource. http://mathworld.wolfram.com/PolygonArea.html
%
%December 2014 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

numVertices=size(vertices,2);

A=0;
prevVertex=vertices(:,end);
for curIdx=1:numVertices
    curVertex=vertices(:,curIdx);
    A=A+det([prevVertex,curVertex]);
    prevVertex=curVertex;
end
A=A/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.


% ------------------------------------------------------------------- %
% Matlab files listed in Appendix B of the following book by          %
% Xin-She Yang, Mathematical Modelling for Earth Sciences,            %
%               Dunedin Academic Presss, Edinburgh, UK, (2008).       %
% http://www.dunedinacademicpress.co.uk/ViewReviews.php?id=100        %
% ------------------------------------------------------------------- %

% ------------------------------------------------------------------- %
% Gauss Numerical Integration of I=\int_a^b f(x) dx
% by 7-point Gaussian Quadrature
% Programmed by Xin-She Yang (Cambridge University) @ 2008
% Usage: Gauss_quad(function_str,a,b)
%   E.g. Gauss_quad('(sin(x)./x).^2',0,pi);
% ------------------------------------------------------------------- %

function [I]=Gauss_quad(fstr,a,b)
format long;
if nargin<3,
 disp('Usage:Gauss_quad(integrand,a,b)');
 disp('E.g., Gauss_quad(''exp(-x^2)*2/sqrt(pi)'',-1,1);');
end
% Default function and values if no input
if nargin<1,
   help Gauss_quad.m;
   fstr='exp(-x^2)*2/sqrt(pi)';
   a=-1.0; b=1.0;
end
% Converting the input integrand, fstr, to a function f(x)
f=inline(vectorize(fstr));
% Seven-point integration scheme so zeta_1 to zeta_7
zeta=[-0.9491079123; -0.7415311855; -0.4058451513; 0.0;
       0.4058451513; 0.7415311855; 0.9491079123];
% Weighting coefficients
w=[0.1294849661; 0.2797053914; 0.3818300505; 0.4179591836;
   0.3818300505; 0.2797053914; 0.1294849661];
% Index for the seven points
Index=1:7;
Iunit=sum(w(Index).*f((b-a).*(zeta(Index)+1)/2+a));
I=(b-a)/2*Iunit;

disp(' '); disp(strcat('The integral is = ',num2str(I)));
% ------------------------end of program ---------------------------


function p = jaccard_similarity(A,B)
%% jaccard similarity
% This function calculates jaccard similarity index of inputs arrays A and
% B. The formula to find the Index is (number of entries in both sets) / (number of entries in either set) * 100
% The higher the percentage, the more similar the two arrays.
% For this, each of input arrays is modified by removing its same entries
% (except on them), then number of common entries between two new arrays is
% calculated by comparing them.

modified_A = unique(A);
modified_B = unique(B);

length_mA = length(modified_A);
length_mB = length(modified_B);
common_number = 0;                    %initialize the number of common entries

if length_mA <= length_mB
    X = modified_A;
    Y = modified_B;
else
    X = modified_B;
    Y = modified_A;
end

for i = 1:length(X)
    for j = 1:length(Y)
        if X(i) == Y(j)
           common_number = common_number + 1;
        end
    end
end

total_number = length_mA + length_mB - common_number;
p = (common_number/total_number)*100;
end


function value = ellipsoid_volume_3d ( r1, r2, r3 )

%*****************************************************************************80
%
%% ELLIPSOID_VOLUME_3D returns the volume of an ellipsoid in 3d.
%
%  Integration region:
%
%    Points (X,Y,Z) such that
%
%      ( ( X - XC ) / R1 )**2
%    + ( ( Y - YC ) / R2 )**2
%    + ( ( Z - ZC ) / R3 )**2 <= 1
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R1, R2, R3, the semi-axes of the ellipsoid.
%
%    Output, real VALUE, the volume of the ellipsoid.
%
  value = ( 4.0E+00 / 3.0E+00 ) * pi * r1 * r2 * r3;

  return
end


function X2=henon(X1)
%HENON   Henon map (a 2nd-order discrete system)
%
%             x(n+1) = 1 - a*x(n)^2 + y(n)
%             y(n+1) = b*x(n)
%
%        In this demo, a = 1.4, b = 0.3,
%        Initial conditions: x(0) = 0, y(0) = 0
%        Reference values are:  LE1 = 0.418, LE2 = -1.621, LD = 1.26
%
%        The reference values are from the following references:
%
%        [1] A. Wolf, J. B. Swift, H. L. Swinney and J. A. Vastano,
%           "Determining Lyapunov Exponents from a Time Series,"
%            Physica D, Vol. 16, pp. 285-317, 1985.
%
%        [2] Keith Briggs, "An Improved Method for Estimating Liapunov
%            Exponents of Chaotic Time Series," Phys. Lett. A, Vol. 151,
%            pp. 27-32, Nov. 1990.

%        by Steve Wai Kam SIU, Jun. 29, 1998.

%Parameters
a=1.4;
b=0.3;

%Rearrange input data in desired format
%Note: the input data is a column vector
x=X1(1);
y=X1(2);
Q=[X1(3),X1(5);
   X1(4),X1(6)];

%Henon map
X=1-a*(x^2)+y;
Y=b*x;

%Linearized system
J=[-2*a*x, 1;
        b, 0];

%Variational equation
F=J*Q;

%Output data
X2=[X; Y; F(:)];


function y = gsp_smooth_downstep(x, a, o)
%GSP_SMOOTH_DOWNSTEP Smooth downstep function from 1 to 0
%   Usage: y = gsp_smooth_downstep(x);
%          y = gsp_smooth_downstep(x, a);
%          y = gsp_smooth_downstep(x, a, o);
%
%   Input parameters:
%          x        : input value
%          a        : smoothing parameter (default 1)
%          o        : offset (default 1)
%   Ouput parameters:
%          y        : output value of the function
%
%   This function is a smooth downstep from 1 to 0 arround *o* using the
%   following function:
%
%   .. f(x) = s(o-x)
%
%   .. math:: f(x) = s(o-x)
%
%   where
%
%   ..          /   0                                      if x < -1
%   ..  s(x) = | exp(-a/x) / ( exp(-a/x) + exp(-a/(1-x)) ) if x in [-1, 1]
%   ..          \   1                                      if x > 1
%
%   .. math:: s(x)=\begin{cases} 0 & \mbox{if }x<-1 \\ \frac{e^{-\frac{a}{x}}}{e^{-\frac{a}{x}}+e^{-\frac{a}{1-x}}} & \mbox{if }x\in[-1,1]\\ 1 & \mbox{if }x>1 \end{cases}
%

% Author: Nathanael Perraudin
% Date  : 5 mai 2016

if nargin<3
    o = 1;
end

if nargin<3
    a = 1;
end

y = gsp_smooth_step(o-x, a);

end


function value = angle_rad_3d ( p1, p2, p3 )

%*****************************************************************************80
%
%% ANGLE_RAD_3D returns the angle in radians between two rays in 3D.
%
%  Discussion:
%
%    The routine always computes the SMALLER of the two angles between
%    two rays.  Thus, if the rays make an (exterior) angle of
%    1.5 pi radians, the (interior) angle of 0.5 pi radians will be reported.
%
%    X dot Y = Norm(X) * Norm(Y) * Cos ( Angle(X,Y) )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 May 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real P1(3), P2(3), P3(3), points defining an angle.
%    The rays are P1 - P2 and P3 - P2.
%
%    Output, real VALUE, the angle between the two rays,
%    in radians.  This value will always be between 0 and PI.  If either ray has
%    zero length, then the angle is returned as zero.
%
  dim_num = 3;

  v1norm = sqrt ( sum ( ( p2(1:dim_num) - p1(1:dim_num) ).^2 ) );

  if ( v1norm == 0.0 )
    value = 0.0;
    return
  end

  v2norm = sqrt ( sum ( ( p2(1:dim_num) - p3(1:dim_num) ).^2 ) );

  if ( v2norm == 0.0 )
    value = 0.0;
    return
  end

  dot = ( p1(1:dim_num) - p2(1:dim_num) ) * ( p3(1:dim_num) - p2(1:dim_num) )';

  value = r8_acos ( dot / ( v1norm * v2norm ) );

  return
end


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;
numColumns = size(X, 2);

mu = mean(X);
sigma = std(X);
for i = 1:numColumns
    X_norm(:,i) = (X(:, i) - mu(i)) / sigma(i);
end;

% ====================== 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.
%

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

end


function [ vX ] = ProjectSimplexExact( vY, ballRadius )
% ----------------------------------------------------------------------------------------------- %
% [ vX ] = ProjectSimplexExact( vY, ballRadius )
%   Solving the Orthogonal Projection Problem of the input vector onto the
%   Simplex Ball using Dual Function and exact solution by solving linear
%   equation.
% Input:
%   - vY            -   Input Vector.
%                       Structure: Vector (Column).
%                       Type: 'Single' / 'Double'.
%                       Range: (-inf, inf).
%   - ballRadius    -   Ball Radius.
%                       Sets the Radius of the Simplex Ball. For Unit
%                       Simplex set to 1.
%                       Structure: Scalar.
%                       Type: 'Single' / 'Double'.
%                       Range: (0, inf).
% Output:
%   - vX            -   Output Vector.
%                       The projection of the Input Vector onto the Simplex
%                       Ball.
%                       Structure: Vector (Column).
%                       Type: 'Single' / 'Double'.
%                       Range: (-inf, inf).
% References
%   1.  https://math.stackexchange.com/questions/2327504.
% Remarks:
%   1.  The solver finds 2 points which one is positive and the other is
%       negative. Then, since the objective function is linear, finds the
%       exact point where the linear function has value of zero.
% TODO:
%   1.  U.
% Release Notes:
%   -   1.0.000     14/04/2020  Royi Avital
%       *   First release version.
% ----------------------------------------------------------------------------------------------- %

FALSE   = 0;
TRUE    = 1;

OFF     = 0;
ON      = 1;

numElements = size(vY, 1);

if((abs(sum(vY) - ballRadius) < 1e-9) && all(vY >= 0))
    % The input is already within the Simplex.
    vX = vY;
    return;
end

vZ = sort(vY, 'ascend');

vParamMu = [vZ(1) - ballRadius; vZ; vZ(numElements) + ballRadius];
hObjFun = @(paramMu) sum( max(vY - paramMu, 0) ) - ballRadius;

vObjVal = zeros(numElements + 2, 1);
for ii = 1:(numElements + 2)
	vObjVal(ii) = hObjFun(vParamMu(ii));
end

if(any(vObjVal == 0))
    paramMu = vParamMu(vObjVal == 0);
else
    % Working on when an Affine Function have the value zero
    valX1Idx = find(vObjVal > 0, 1, 'last');
    valX2Idx = find(vObjVal < 0, 1, 'first');

    valX1 = vParamMu(valX1Idx);
    valX2 = vParamMu(valX2Idx);
    valY1 = vObjVal(valX1Idx);
    valY2 = vObjVal(valX2Idx);

    paramA = (valY2 - valY1) / (valX2 - valX1);
    paramB = valY1 - (paramA * valX1);
    paramMu = -paramB / paramA;
end

vX = max(vY - paramMu, 0);

end


function [ n_data_new, n, c ] = tau_values ( n_data )

%*****************************************************************************80
%
%% TAU_VALUES returns some values of the Tau function.
%
%  Discussion:
%
%    TAU(N) is the number of divisors of N, including 1 and N.
%
%  First values:
%
%     N   TAU(N)
%
%     1    1
%     2    2
%     3    2
%     4    3
%     5    2
%     6    4
%     7    2
%     8    4
%     9    3
%    10    4
%    11    2
%    12    6
%    13    2
%    14    4
%    15    4
%    16    5
%    17    2
%    18    6
%    19    2
%    20    6
%
%  Formula:
%
%    If the prime factorization of N is
%
%      N = P1**E1 * P2**E2 * ... * PM**EM,
%
%    then
%
%      TAU(N) = ( E1 + 1 ) * ( E2 + 1 ) * ... * ( EM + 1 ).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Milton Abramowitz and Irene Stegun,
%    Handbook of Mathematical Functions,
%    US Department of Commerce, 1964.
%
%  Parameters:
%
%    Input, integer N_DATA, indicates the index of the previous test data
%    returned, or is 0 if this is the first call.  For repeated calls,
%    set the input value of N_DATA to the output value of N_DATA_NEW
%    from the previous call.
%
%    Output, integer N_DATA_NEW, the index of the test data.
%
%    Output, integer N, the argument of the Tau function.
%
%    Output, integer C, the value of the Tau function.
%
  n_max = 20;
  c_vec = [ ...
    1,  2,  2,  3,  2,  4,  2,  4,  3,  4, ...
    2, 12, 12,  4, 18, 24,  2,  8, 14, 28 ];
  n_vec = [ ...
      1,   2,   3,   4,   5,   6,   7,   8,   9,  10, ...
     23,  72, 126, 226, 300, 480, 521, 610, 832, 960 ];

  n_data_new = n_data;

  if ( n_data_new < 0 )
    n_data_new = 0;
  end

  n_data_new = n_data_new + 1;

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

  return
end


function value = halfplane_contains_point_2d ( p1, p2, p )

%*****************************************************************************80
%
%% HALFPLANE_CONTAINS_POINT_2D reports if a half-plane contains a point in 2d.
%
%  Discussion:
%
%    The halfplane is assumed to be all the points "to the left" of the
%    line that passes from P1 through P2.  Thus, one way to
%    understand where the point P = (X,Y) is, is to compute the signed
%    area of the triangle ( P1, P2, P ).
%
%    If this area is
%      positive, the point is strictly inside the halfplane,
%      zero, the point is on the boundary of the halfplane,
%      negative, the point is strictly outside the halfplane.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real P1(2,1), P2(2,1), two distinct points
%    on the line defining the half plane.
%
%    Input, real P(2,1), the point to be checked.
%
%    Output, logical VALUE, is TRUE if the halfplane
%    contains the point.
%
  area_signed = 0.5 * ...
    ( p1(1,1) * ( p2(2,1) - p(2,1)  ) ...
    + p2(1,1) * ( p(2,1)  - p1(2,1) ) ...
    + p(1,1)  * ( p1(2,1) - p2(2,1) ) );

  value = ( 0.0 <= area_signed );

  return
end


%% Structured grid
% This is a sample code showing how to use ConstructProjector3D().
% This example is going to setup a transformation matrix based on forth
% order polynomials in 3D.
% Pay attention that no data is needed to construct the interpolator. Only
% the coordinates of the points on source and destination grid.
clear;clc;
%% Initializing Part I
disp('- Initializing')
xMin=0;
xMax=2*pi;
yMin=0;
yMax=2*pi;
zMin=0;
zMax=2*pi;

nx=20;
ny=20;
nz=20;

dx=(xMax-xMin)/(nx-1);
dy=(yMax-yMin)/(ny-1);
dz=(zMax-zMin)/(nz-1);

nPoly=1; % We gonna fit a fourth order polynomial,
         % i.e. sum_{n,m,t=0}^{n,m,t=nPoly} x^n*y^m*z^t
nInterp=8; % nPoly=4 requires 125 points. However,
            % we are going to use 150 points. This would be
            % the least-square fit of the surface.
            % Note that: min(nInterp)=(nPoly+1)^3. Otherwise it won't work.
%% Turning off the warnings
% Depending on the parameter that you choose the matrices might be nearly
% singular. In this example, despite being nearly singular, they are not
% affecting the final interpolation. Therefore, I set the warning to off.
% But generally do not turn it off and if you got this warning check if it
% is going to affect your results or not.
disp('- Turning the warnings off')
warning('OFF','MATLAB:nearlySingularMatrix');

%% Generating the Source Grid
disp('- Generating the source grid.')
[xn,yn,zn]=meshgrid(linspace(xMin,xMax,nx),linspace(yMin,yMax,ny),linspace(zMin,zMax,nz));

%% Finding the cell centers
disp('- Generating the destination grid')
xc=xn(1:ny-1,1:nx-1,1:nz-1)+dx/2;
yc=yn(1:ny-1,1:nx-1,1:nz-1)+dy/2;
zc=zn(1:ny-1,1:nx-1,1:nz-1)+dz/2;

figure
plot3(xn(:),yn(:),zn(:),'k.','MarkerSize',20);
hold on
plot3(xc(:),yc(:),zc(:),'b.','MarkerSize',20);
axis tight;
axis square;
title('Source Grid, black dots, & the destination grid, blue dots.', ...
      'FontName','Arial','FontSize',12,'FontWeight','Bold');

%% Constructing the Interpolant
% Note: that we do not need the data on the source grid to create the
% interpolant.
disp('- Constructing the interpolant')
P=ConstructProjector3D(xn(:),yn(:),zn(:),xc(:),yc(:),zc(:),nPoly,nInterp);

%% Generarting some Data
disp('- Generating some data and interpolating')
F1=@(x,y,z) (sin(sqrt(x.^2+y.^2+z.^2)));
Vn=F1(xn,yn,zn);
Vc_interp=reshape(P*Vn(:),size(xc));
Vc_Analytic=F1(xc,yc,zc);
RMSE=sqrt(mean((Vc_Analytic(:)-Vc_interp(:)).^2));
disp(['RMSE: ' num2str(RMSE)])

%% Generating some more data
disp('- Generating multiple data field on the source grid and interpolating them.')
F2=@(x,y,z) (sin(x).*cos(y).*sin(z));
F3=@(x,y,z) (exp(-sqrt(x.^2+y.^2+z.^2)));
F4=@(x,y,z,x0,y0,z0) (exp(-sqrt((x-x0).^2+(y-y0).^2+(z-z0).^2)));

Vn(:,:,:,1)=F1(xn,yn,zn);
Vn(:,:,:,2)=F2(xn,yn,zn);
Vn(:,:,:,3)=F3(xn,yn,zn);
Vn(:,:,:,4)=F4(xn,yn,zn,mean(mean(mean(xn))),mean(mean(mean(yn))),mean(mean(mean(zn))));

Vc_Analytic(:,:,:,1)=F1(xc,yc,zc);
Vc_Analytic(:,:,:,2)=F2(xc,yc,zc);
Vc_Analytic(:,:,:,3)=F3(xc,yc,zc);
Vc_Analytic(:,:,:,4)=F4(xc,yc,zc,mean(mean(mean(xn))),mean(mean(mean(yn))),mean(mean(mean(zn))));

% Now interpolating
% Note that the same interpolant is used for all data fields and they can
% be all interpolated with one sparse matrix multiplication.
Vc_interp=P*reshape(Vn,nx*ny*nz,4); % There are 4 data fields.
Vc_interp=reshape(Vc_interp,(ny-1),(nx-1),(nz-1),4); % these two commands can be combined in one.
                                              % They were separated for clarity.

% calculating the RMSE and plotting
RMSE=zeros(4,1);
for i=1:4
  RMSE(i)=sqrt(mean((reshape(Vc_Analytic(:,:,:,i),(nx-1)*(ny-1)*(nz-1),1)-reshape(Vc_interp(:,:,:,i),(nx-1)*(ny-1)*(nz-1),1)).^2));
  disp(['F' num2str(i) ', nPoly: ' num2str(nPoly) ', RMSE:' num2str(RMSE(i))])
end


function b = bell ( n )

%*****************************************************************************80
%
%% BELL returns the Bell numbers from 0 to N.
%
%  Discussion:
%
%    The Bell number B(N) is the number of restricted growth functions
%    on N.
%
%    Note that the Stirling numbers of the second kind, S^m_n, count the
%    number of partitions of N objects into M classes, and so it is
%    true that
%
%      B(N) = S^1_N + S^2_N + ... + S^N_N.
%
%  Definition:
%
%    The Bell number B(N) is defined as the number of partitions (of
%    any size) of a set of N distinguishable objects.
%
%    A partition of a set is a division of the objects of the set into
%    subsets.
%
%  Examples:
%
%    There are 15 partitions of a set of 4 objects:
%
%      (1234), (123)(4), (124)(3), (12)(34), (12)(3)(4),
%      (134)(2), (13)(24), (13)(2)(4), (14)(23), (1)(234),
%      (1)(23)(4), (14)(2)(3), (1)(24)(3), (1)(2)(34), (1)(2)(3)(4)
%
%    and so B(4) = 15.
%
%  First values:
%
%     N         B(N)
%     0           1
%     1           1
%     2           2
%     3           5
%     4          15
%     5          52
%     6         203
%     7         877
%     8        4140
%     9       21147
%    10      115975
%
%  Recursion:
%
%    B(I) = sum ( 1 <= J <= I ) Binomial ( I-1, J-1 ) * B(I-J)
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 June 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of Bell numbers desired.
%
%    Output, integer B(1:N+1), the Bell numbers from 0 to N.
%
  b(1) = 1;

  for i = 1 : n
    b(i+1) = 0;
    for j = 1 : i
      b(i+1) = b(i+1) + i4_choose ( i-1, j-1 ) * b(i-j+1);
    end
  end

  return
end


function wMed = weightedMedian(D,W)

% ----------------------------------------------------------------------
% Function for calculating the weighted median
% Sven Haase
%
% For n numbers x_1,...,x_n with positive weights w_1,...,w_n,
% (sum of all weights equal to one) the weighted median is defined as
% the element x_k, such that:
%           --                        --
%           )   w_i  <= 1/2   and     )   w_i <= 1/2
%           --                        --
%        x_i < x_k                 x_i > x_k
%
%
% Input:    D ... matrix of observed values
%           W ... matrix of weights, W = ( w_ij )
% Output:   wMed ... weighted median
% ----------------------------------------------------------------------

if nargin ~= 2
    error('weightedMedian:wrongNumberOfArguments', ...
      'Wrong number of arguments.');
end

if size(D) ~= size(W)
    error('weightedMedian:wrongMatrixDimension', ...
      'The dimensions of the input-matrices must match.');
end

% normalize the weights, such that: sum ( w_ij ) = 1
% (sum of all weights equal to one)

WSum = sum(W(:));
W = W / WSum;

% (line by line) transformation of the input-matrices to line-vectors
d = reshape(D',1,[]);
w = reshape(W',1,[]);

% sort the vectors
A = [d' w'];
ASort = sortrows(A,1);

dSort = ASort(:,1)';
wSort = ASort(:,2)';
sumVec = cumsum(wSort);

wMed = [];
j = 0;

while isempty(wMed)
    j = j + 1;
    if sumVec(j) >= 0.5
        wMed = dSort(j);    % value of the weighted median
    end
end

% final test to exclude errors in calculation
if ( sum(wSort(1:j-1)) > 0.5 ) & ( sum(wSort(j+1:length(wSort))) > 0.5 )
     error('weightedMedian:unknownError', ...
      'The weighted median could not be calculated.');
end


function outsig = noise(siglen,varargin)
% NOISE  Stochastic noise generator
%   Usage: outsig = noise(siglen,nsigs,type);
%
%   Input parameters:
%       siglen    : Length of the noise (samples)
%       nsigs     : Number of signals (default is 1)
%       type      : type of noise. See below.
%
%   Output parameters:
%       outsig    : $siglen \times nsigs$ signal vector
%
%   `noise(siglen,nsigs)` generates *nsigs* channels containing white noise
%   of the given type with the length of *siglen*. The signals are arranged as
%   columns in the output. If only *siglen* is given, a column vector is
%   returned.
%
%   `noise` takes the following optional parameters:
%
%     'white'  Generate white (gaussian) noise. This is the default.
%
%     'pink'   Generate pink noise.
%
%     'brown'  Generate brown noise.
%
%     'red'    This is the same as brown noise.
%
%   By default, the noise is normalized to have a unit energy, but this can
%   be changed by passing a flag to |setnorm|.
%
%   Examples:
%   ---------
%
%   White noise in the time-frequency domain:::
%
%     sgram(noise(5000,'white'),'dynrange',70);
%
%   Pink noise in the time-frequency domain:::
%
%     sgram(noise(5000,'pink'),'dynrange',70);
%
%   Brown/red noise in the time-frequency domain:::
%
%     sgram(noise(5000,'brown'),'dynrange',70);
%
%   See also: setnorm

%   AUTHOR: Hagen Wierstorf and Peter L. Søndergaard.

% ------ Checking of input parameter -------------------------------------

if nargin<1
  error('%s: Too few input parameters.',upper(mfilename));
end;

if ~isnumeric(siglen) || ~isscalar(siglen) || siglen<=0
    error('%s: siglen has to be a positive scalar.',upper(mfilename));
end

definput.import={'setnorm'};
definput.importdefaults={'2'};
definput.flags.noisetype={'white','pink','brown','red'};
definput.keyvals.nsigs=1;
[flags,kv,nsigs]  = ltfatarghelper({'nsigs'},definput,varargin);

if flags.do_white
  outsig=randn(siglen,nsigs);
end;

if flags.do_brown || flags.do_red
  outsig=cumsum(randn(siglen,nsigs));
end;

if flags.do_pink
  % --- Handle trivial condition

  if siglen==1
    outsig=ones(1,nsigs);
    return;
  end;

  % ------ Computation -----------------------------------------------------
  fmax = floor(siglen/2)-1;
  f = (2:(fmax+1)).';
  % 1/f amplitude factor
  a = 1./sqrt(f);
  % Random phase
  p = randn(fmax,nsigs) + i*randn(fmax,nsigs);
  sig = bsxfun(@times,a,p);

  outsig = ifftreal([ones(1,nsigs); sig; 1/(fmax+2)*ones(1,nsigs)],siglen);

end;

outsig=setnorm(outsig,flags.norm);


function cdf = gumbel_cdf ( x )

%*****************************************************************************80
%
%% GUMBEL_CDF evaluates the Gumbel CDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the argument of the CDF.
%
%    Output, real CDF, the value of the CDF.
%
  cdf = exp ( - exp ( - x ) );

  return
end


%Generate 2D Gabor Patch
%
% GABOR
%   Generates a spatially oriented sinusoidal grating multiplied by a gaussian
%   window. Gabor functions have been used to model simple cell receptive fields
%   and are commonly used filters for edge detection.
%
% USAGE
%   [x y F] = gabor(varargin)
%
%   Returns:
%       x: grid of x-values
%       y: grid of y-values
%       F: gabor function evaluated at (x,y) points
%
%   Parameters (Default):
%       theta (2*pi*rand): orientation of the gabor patch
%       lambda (20): spatial wavelength
%       Sigma (10): standard deviation of gaussian window
%       width (256): width of generated image
%       height (256): height of generated image
%       px (rand): horizontal center of gabor patch, relative to the image width (must be between 0 and 1)
%       py (rand): vertical center of gabor patch, relative to the image height (must be between 0 and 1)
%
% EXAMPLE
%   [x y F] = gabor;
%   pcolor(x,y,F); axis image;
%   shading('interp'); colormap copper;
%
% VERSION 1.0, Thu Jul 12 09:47:52 2012
%
% AUTHOR: Niru Maheswaranathan
%         nirum@stanford.edu

function [x y F] = gabor(varargin)

    % Parse Input
    p = inputParser;
    addParamValue(p,'theta',2*pi*rand,@isnumeric);
    addParamValue(p,'lambda',20,@isnumeric);
    addParamValue(p,'Sigma',10,@isnumeric);
    addParamValue(p,'width',256,@isnumeric);
    addParamValue(p,'height',256,@isnumeric);
    addParamValue(p,'px',rand*0.8 + 0.1,@isnumeric);
    addParamValue(p,'py',rand*0.8 + 0.1,@isnumeric);
    p.KeepUnmatched = true;
    parse(p,varargin{:});

    % Generate mesh
    [x y] = meshgrid(1:p.Results.width, 1:p.Results.height);

    % Center of gaussian window
    cx = p.Results.px*p.Results.width;
    cy = p.Results.py*p.Results.height;

    % Orientation
    x_theta=(x-cx)*cos(p.Results.theta)+(y-cy)*sin(p.Results.theta);
    y_theta=-(x-cx)*sin(p.Results.theta)+(y-cy)*cos(p.Results.theta);

    % Generate gabor
    F = exp(-.5*(x_theta.^2/p.Results.Sigma^2+y_theta.^2/p.Results.Sigma^2)).*cos(2*pi/p.Results.lambda*x_theta);

end


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

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

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

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

hx = sigmoid(X * theta); %hypothesis, m * 1

J = 1 / m * sum(-y' * log(hx) - (1 - y)' * log(1 - hx)) + lambda / (2 * m) * theta(2:end)' * theta(2:end);

gradf = (1 / m) * (X(:, 1)' * (hx - y));
gradb = (1 / m) * (X(:, 2:end)' * (hx - y)) + lambda * theta(2:end) / m;

grad = [gradf;gradb];

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

end


function fd=pderiv(f,dim,difforder)
%PDERIV   Derivative of smooth periodic function
%   Usage:  fd=pderiv(f);
%           fd=pderiv(f,dim);
%           fd=pderiv(f,dim,difforder);
%
%   `pderiv(f)` will compute the derivative of *f* using a using a 4th order
%   centered finite difference scheme. *f* must have been obtained by a
%   regular sampling. If *f* is a matrix, the derivative along the columns
%   will be found.
%
%   `pderiv(f,dim)` will do the same along dimension *dim*.
%
%   `pderiv(f,dim,difforder)` uses a centered finite difference scheme of
%   order *difforder* instead of the default.
%
%   `pderiv(f,dim,Inf)` will compute the spectral derivative using a DFT.
%
%   `pderiv` assumes that *f* is a regular sampling of a function on the
%   torus $[0,1)$. The derivative of a function on a general torus $[0,T)$
%   can be found by scaling the output by $1/T$.

% Assert correct input.

complainif_argnonotinrange(nargin,1,3,mfilename);

if nargin==1
  dim=[];
end;

if nargin<3
  difforder=4;
end;

[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,[],dim,'PDERIV');

switch(difforder)
 case 2
  fd = L*(circshift(f,-1)-circshift(f,1))/2;
 case 4
  fd = L*(-circshift(f,-2)+8*circshift(f,-1)-8*circshift(f,1)+ ...
          circshift(f,2))/12;
 case Inf
  n=fftindex(L,0);
  n=repmat(n,1,W);

  fd=2*pi*ifft(i*n.*fft(f));

  if isreal(f)
    fd=real(fd);
  end;

 otherwise
  error('The specified differentation order is not implemented.');
end;

fd=assert_sigreshape_post(fd,dim,permutedsize,order);


function xMax = SmoothMax(x,alpha)
%
% xMax = SmoothMax(x, alpha)
%
% This function is a smooth version of the max(x) function, commonly known
% as the 'soft-max' function. In the limit as the smoothing parameter goes
% to zero, this function will return max(x). In the limit as the smoothing
% parameter goes to infinity, this will return sum(x).
%
%INPUTS:
% x = a vector or matrix of inputs
% alpha = a smoothing parameter. Asymtotes:  0->max(x), inf->sum(x)
%
%OUTPUTS:
% xMax = the smooth maximum of x
%
%
% Written by Matthew Kelly
% October 2013
% Cornell University
%

if nargin==1
    alpha = 1;
end

xMax = alpha*log(sum(exp(x/alpha)));

if isinf(xMax)
   %Then the scaling was too sharp
    xMax = max(x);
end

end


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

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

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

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

h = sigmoid(X*theta);
% J = (1/m)*sum(-y .* log(h) - (1 - y) .* log(1-h));
shift_theta = theta(2:size(theta));
theta_reg = [0;shift_theta];

J = (1/m)*(-y'* log(h) - (1 - y)'*log(1-h))+(lambda/(2*m))*theta_reg'*theta_reg;

% grad_zero = (1/m)*X(:,1)'*(h-y);
% grad_rest = (1/m)*(shift_x'*(h - y)+lambda*shift_theta);
% grad      = cat(1, grad_zero, grad_rest);

grad = (1/m)*(X'*(h-y)+lambda*theta_reg);

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

end


function v = getNonUniformGrid(m_0, lx, ux, gridMethod, center, manualPoint, gridMultParam)
%UNTITLED Summary of this function goes here
%   Detailed explanation goes here

nx = m_0; dx = (ux-lx)/nx;

if gridMethod == 1  % uniform grid , doesn't include lower bound
    v = lx + (1:nx)'*dx;
elseif gridMethod == 2  %%Mijatovic and Pistorious
    v = zeros(m_0,1);
    v(1) = lx; v(m_0) = ux;
    mid = floor(m_0/2);
    for k = 2: mid
        v(k) = center + sinh( (1-(k-1)/(mid -1))*asinh(v(1)-center) );
    end
    for k = mid+1:m_0-1
        v(k) = center + sinh( ((k - mid)/(mid))*asinh(v(m_0) - center) );
    end
elseif gridMethod == 3 %%Carr and Mayo
    x=0:1/(m_0-1):1; %map [0,1] to new grid
    alpha = 0.8*(ux-lx);
    c1 = asinh((lx-center)/alpha);
    c2 = asinh((ux-center)/alpha);
    v  = center + alpha*(c2*sinh(c2.*x+c1.*(1-x)));
elseif gridMethod == 4 %% Tavella and Randall
    v = zeros(m_0,1);
    v(1)   = lx;
    v(m_0) = ux;
    alpha = gridMultParam*(v(m_0) - v(1));
    c1 = asinh((v(1) - center)/alpha);
    c2 = asinh((v(m_0) - center)/alpha);
    v(2:m_0-1) = center + alpha*sinh(c2/m_0*(2:m_0-1) + c1*(1 - (2:m_0-1)/m_0));
elseif gridMethod == 5 %% Tavella and Randall PLUS we put manualPoint (e.g. v0) on grid
    tol = 1e-7;
    v = zeros(m_0,1);
    v(1)   = lx;
    v(m_0) = ux;
    alpha = gridMultParam*(v(m_0) - v(1));
    c1 = asinh((v(1) - center)/alpha);
    c2 = asinh((v(m_0) - center)/alpha);
    vtil = zeros(m_0-1,1);
    vtil(2:m_0-2) = center + alpha*sinh(c2/(m_0 - 1)*(2:m_0-2) + c1*(1 - (2:m_0-2)/(m_0-1)));
    nnot_til = 1;
    while vtil(nnot_til) < manualPoint %Find the index left of the manualPoint point
        nnot_til = nnot_til + 1;
    end
    nnot_til = nnot_til - 1;
    v(2:nnot_til) = vtil(2:nnot_til);
    v(nnot_til + 2: m_0 - 1) = vtil(nnot_til + 1: m_0 - 2);
    if manualPoint - vtil(nnot_til)<tol %if you already have a point very close to manualPoint
        v(nnot_til) = manualPoint;
        v(nnot_til+1) = (manualPoint + vtil(nnot_til+1))/2;
    elseif vtil(nnot_til+1) - manualPoint <tol
        v(nnot_til+2) = manualPoint;
        v(nnot_til + 1) = (v(nnot_til+2) + v(nnot_til))/2;
    else
        v(nnot_til + 1) = manualPoint;
    end
end

end


function binomTable=makeBinomTable(maxDeg)
%%MAKEBINOMTABLE  Create a lookup table of binomial coefficients.
%                 binomTable(n+1,k+1) is the value of binomial(n,k). This
%                 just build's Pascal's triangle. Consider, for example [1].
%                 The table uses about twice the memory it actually needs
%                 just so that it can be easily accessed as a matrix. This
%                 function is easier to use than the output of the pascal
%                 command in Matlab.
%
%INPUTS: maxDeg The maximum degree of the table. This is a value >=0.
%
%OUTPUTS: binomTable A (maxDeg+1)X(maxDeg+1) matrix where
%               binomTable(n+1,k+1) is the value of binomial(n,k). Unused
%               components are set to zero.
%
%This function can be useful when a large number of low-order binomial
%values are needed. The recursion used to fill in the table is from [1].
%
%REFERENCES:
%[1] Stover, Christopher and Weisstein, Eric W. "Pascal's Triangle." From
%    MathWorld--A Wolfram Web Resource.
%    http://mathworld.wolfram.com/PascalsTriangle.html
%
%September 2015 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

    binomTable=zeros(maxDeg+1,maxDeg+1);
    binomTable(:,0+1)=1;%Boundary values.
    for n=1:maxDeg
        for k=1:(n-1)
            binomTable(n+1,k+1)=binomTable(n-1+1,k-1+1)+binomTable(n-1+1,k+1);
        end
        binomTable(n+1,n+1)=1;%Boundary value
    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 [AnDartest] = AnDartest(x,alpha)
%ANDARTEST Anderson-Darling test for assessing normality of a sample data.
% The Anderson-Darling test (Anderson and Darling, 1952) is used to test if
% a sample of data comes from a specific distribution. It is a modification
% of the Kolmogorov-Smirnov (K-S) test and gives more weight to the tails
% than the K-S test. The K-S test is distribution free in the sense that the
% critical values do not depend on the specific distribution being tested.
% The Anderson-Darling test makes use of the specific distribution in calculating
% critical values. This has the advantage of allowing a more sensitive test
% and the disadvantage that critical values must be calculated for each
% distribution.
% The Anderson-Darling test is only available for a few specific distributions.
% The test is calculated as:
%
%        AD2 = integral{[F_o(x)-F_t(x)]^2/[F_t(x)(1-F_t(x)0]}dF_t(x)
%
%        AD2a = AD2*a
%
% Note that for a given distribution, the Anderson-Darling statistic may be
% multiplied by a constant, a (which usually depends on the sample size, n).
% These constants are given in the various papers by Stephens (1974, 1977a,
% 1977b, 1979, 1986). This is what should be compared against the critical
% values. Also, be aware that different constants (and therefore critical
% values) have been published. You just need to be aware of what constant
% was used for a given set of critical values (the needed constant is typically
% given with the critical values).
% The critical values for the Anderson-Darling test are dependent on the
% specific distribution that is being tested. Tabulated values and formulas
% have been published for a few specific distributions (normal, lognormal,
% exponential, Weibull, logistic, extreme value type 1). The test is a one-sided
% test and the hypothesis that the distribution is of a specific form is
% rejected if the test statistic, AD2a, is greater than the critical value.
% Here we develop the m-file for detecting departure from normality. It is
% one of the most powerful statistics for test this.
%
% Syntax: function AnDartest(X)
%
%     Input:
%          x - data vector
%      alpha - significance level (default = 0.05)
%
%     Output:
%            - Complete Anderson-Darling normality test
%
% Example: From the Table 1 base data of secondary coating diameter, SCD
%    (micrometers) for an optical fiber manufacturing and testing [Application
%    and acceptance sampling in testing of optical fiber (Bhaumik and Bhargava,
%    2005)], taked from Internet:
%    http://www.sterliteoptical.com/pdf/ProdWithContents/Application%20of%
%    20acceptance%20sampling%20in%20testing%20of%20optical%20fiber.pdf
%    The measurements of the sample are analyzed for the normality using the
%    Anderson-Darling test with a significance of 0.05.
%
% Data vector is:
%  x=[245.3;245.6;245.0;244.7;244.6;244.6;245.9;245.2;245.5;246.1;246.5;246.7;
%  246.0;245.8;245.3;245.3;246.0;245.5;246.7;245.3;245.8;245.8;245.2;245.7;
%  244.8;246.7;246.5;245.5;246.0;244.8;244.8;244.4;244.8;245.6;245.5;244.0;
%  245.2;244.8;245.4;246.1;245.9;245.6;245.2];
%
% Calling on Matlab the function:
%            AnDartest(x)
%
% Answer is:
%
% Sample size: 43
% Anderson-Darling statistic: 0.2858
% Anderson-Darling adjusted statistic: 0.2912
% Probability associated to the Anderson-Darling statistic = 0.6088
% With a given significance = 0.050
% The sampled population is normally distributed.
% Thus, this sample have been drawn from a normal population with a mean & variance = 245.4814    0.4139
%
% Created by A. Trujillo-Ortiz, R. Hernandez-Walls, K. Barba-Rojo and
%             A. Castro-Perez
%             Facultad de Ciencias Marinas
%             Universidad Autonoma de Baja California
%             Apdo. Postal 453
%             Ensenada, Baja California
%             Mexico.
%             atrujo@uabc.mx
%
% Copyright. April 20, 2007.
%
% To cite this file, this would be an appropriate format:
% Trujillo-Ortiz, A., R. Hernandez-Walls, K. Barba-Rojo and A. Castro-Perez. (2007).
%   AnDartest:Anderson-Darling test for assessing normality of a sample data.
%   A MATLAB file. [WWW document]. URL http://www.mathworks.com/matlabcentral/
%   fileexchange/loadFile.do?objectId=14807
%
% References:
%  Anderson, T. W. and Darling, D. A. (1952), Asymptotic theory of certain
%      'goodness-of-fit' criteria based on stochastic processes. Annals of
%      Mathematical Statistics, 23:193-212.
%  Stephens, M. A. (1974), EDF Statistics for goodness of fit and some
%      comparisons. Journal of the American Statistical Association,
%      69:730-737.
%  Stephens, M. A. (1976), Asymptotic Results for goodness-of-fit statistics
%      with unknown parameters. Annals of Statistics, 4:357-369.
%  Stephens, M. A. (1977a), Goodness of fit for the extreme value distribution.
%      Biometrika, 64:583-588.
%  Stephens, M. A. (1977b), Goodness of fit with special reference to tests
%      for exponentiality. Technical Report No. 262, Department of Statistics,
%      Stanford University, Stanford, CA.
%  Stephens, M. A. (1979), Tests of fit for the logistic distribution based
%      on the empirical distribution function. Biometrika, 66:591-595.
%  Stephens, M. A. (1986), Tests based on EDF statistics. In: D'Agostino,
%      R.B. and Stephens, M.A., eds.: Goodness-of-Fit Techniques. Marcel
%      Dekker, New York.
%

switch nargin
    case{2}
        if isempty(x) == false && isempty(alpha) == false
            if (alpha <= 0 || alpha >= 1)
                fprintf('Warning: Significance level error; must be 0 < alpha < 1 \n');
                return;
            end
        end
    case{1}
        alpha = 0.05;
    otherwise
        error('Requires at least one input argument.');
end

n = length(x);

if n < 7,
    disp('Sample size must be greater than 7.');
    return,
else
    x = x(:);
    x = sort(x);
    fx = normcdf(x,mean(x),std(x));
    i = 1:n;

    S = sum((((2*i)-1)/n)*(log(fx)+log(1-fx(n+1-i))));
    AD2 = -n-S;

    AD2a = AD2*(1 + 0.75/n + 2.25/n^2); %correction factor for small sample sizes: case normal

    if (AD2a >= 0.00 && AD2a < 0.200);
        P = 1 - exp(-13.436 + 101.14*AD2a - 223.73*AD2a^2);
    elseif (AD2a >= 0.200 && AD2a < 0.340);
        P = 1 - exp(-8.318 + 42.796*AD2a - 59.938*AD2a^2);
    elseif (AD2a >= 0.340 && AD2a < 0.600);
        P = exp(0.9177 - 4.279*AD2a - 1.38*AD2a^2);
    else (AD2a >= 0.600 && AD2a <= 13);
        P = exp(1.2937 - 5.709*AD2a + 0.0186*AD2a^2);
    end
end

disp(' ')
fprintf('Sample size: %i\n', n);
fprintf('Anderson-Darling statistic: %3.4f\n', AD2);
fprintf('Anderson-Darling adjusted statistic: %3.4f\n', AD2a);
fprintf('Probability associated to the Anderson-Darling statistic = %3.4f\n', P);
fprintf('With a given significance = %3.3f\n', alpha);
if P >= alpha;
   disp('The sampled population is normally distributed.');
   s = [mean(x),var(x)];
   fprintf('Thus, this sample have been drawn from a normal population with a mean & variance = %6.4f  %8.4f\n',s);
else
   disp('The sampled population is not normally distributed.');
end

return,


function variance = i4row_variance ( m, n, a )

%*****************************************************************************80
%
%% I4ROW_VARIANCE returns the variances of an I4ROW.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 November 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, N, the number of rows and columns of data in TABLE.
%
%    Input, integer A(M,N), the array.
%
%    Output, real VARIANCE(M), the variance of each row of TABLE.
%
  for i = 1 : m

    mean = sum ( a(i,1:n) ) / n;

    variance(i) = 0.0;
    for j = 1 : n
      variance(i) = variance(i) + ( a(i,j) - mean )^2;
    end

    if ( 1 < n )
      variance(i) = variance(i) / ( n - 1 );
    else
      variance(i) = 0.0
    end

  end

  return
end


% Compute the link density of a graph, defined as the number of edges divided by
% number_of_nodes(number_of_nodes-1)/2 where the latter is the maximum possible number of edges.
%
% Inputs: adjacency matrix, nxn
% Outputs: link density, a float between 0 and 1
%
% Note 1: The graph has to be non-trivial (more than 1 node).
% Note 2: Routine works for both directed and undirected graphs.
%
% Other routines used: numNodes.m, numEdges.m, isDirected.m
% GB: last update Sep 19, 2012

function d=linkDensity(adj)

n = numNodes(adj);

coeff = 2;
if isDirected(adj); coeff = 1; end

d = coeff*numEdges(adj)/(n*(n-1));


%  Script file: calc_decay.m
%
%  Purpose:
%    This program calculates the amount of Thorium 227 and
%    Radium 223 left as a function of time, given an inital
%    concentration of 1 gram of Thorium 227 and no grams of
%    Radium 223.
%
%  Record of revisions:
%      Date       Programmer          Description of change
%      ====       ==========          =====================
%    03/15/07    S. J. Chapman        Original code
%
% Define variables:
%   odefun_handle -- Handle to function that defines the derivative
%   tspan         -- Duration to solve equation for
%   yo            -- Initial condition for equation
%   t             -- Array of solution times
%   y             -- Array of solution values

% Get a handle to the function that defines the derivative.
odefun_handle = @decay1;

% Solve the equation over the period 0 to 100 days
tspan = [0 100];

% Set the initial conditions
y0(1) = 1000000;     % Atoms of Thorium 227
y0(2) = 0;           % Atoms of Radium 223

% Call the differential equation solver.
[t,y] = ode45(odefun_handle,tspan,y0);

% Plot the result
figure(1);
plot(t,y(:,1),'b-','LineWidth',2);
hold on;
plot(t,y(:,2),'k--','LineWidth',2);
title('\bfAmount of Thorium 227 and Radium 223 vs Time');
xlabel('\bfTime (days)');
ylabel('\bfNumber of Atoms');
legend('Thorium 227','Radium 223');
grid on;
hold off;


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
%
z=X*theta;
h=sigmoid(z);
%logisf=-y*log(h)-(1-y)*log(1-h);
%logisf=log(h)*(-y)-log(1-h)*(1-y);
logisf=(-y)'*log(h)-(1-y)'*log(1-h);
J=(1/m)*sum(logisf);		% sum will only work for a column, will not sum over a row

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

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

end


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

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

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

% Estimation
% =============
x       = x(:);                 % should be column vectors !
N       = length(x);
u       = sum(x)/N;
sig2    = (x-u)'*(x-u)/N;
CRB_u   = sig2 / N;
CRB_sig2= (2*sig2^2) / N;
[n,x_c] = hist( x,100 );
n       = n / sum(n*abs(x_c(2)-x_c(1)));
y       = sqrt(1/2/pi/sig2)*exp(-((x_c-u).^2)/(2*sig2));
RMS     = sqrt( (y-n)*((y-n)')/ (x_c(2)-x_c(1))^2 / (length(x_c)-1) );

% finish summarizing results
% ============================
result = struct( 'u',u,'sig2',sig2,'CRB_u',CRB_u,'CRB_sig2',CRB_sig2,'RMS',RMS,'type','ML' );

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


function f = beale ( x )

%*****************************************************************************80
%
%% BEALE computes the Beale function.
%
%  Discussion:
%
%    This function has a global minimizer:
%
%      X = ( 3.0, 0.5 )
%
%    for which
%
%      F(X) = 0.
%
%    For a relatively easy computation, start the search at
%
%      X = ( 1.0, 1.0 )
%
%    A harder computation starts at
%
%      X = ( 1.0, 4.0 )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 January 2011
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Evelyn Beale,
%    On an Iterative Method for Finding a Local Minimum of a Function
%    of More than One Variable,
%    Technical Report 25,
%    Statistical Techniques Research Group,
%    Princeton University, 1958.
%
%    Richard Brent,
%    Algorithms for Minimization with Derivatives,
%    Dover, 2002,
%    ISBN: 0-486-41998-3,
%    LC: QA402.5.B74.
%
%  Parameters:
%
%    Input, real X(N,2), the argument of the function.
%
%    Output, real F, the value of the function at X.
%
  f1 = 1.5   - x(:,1) .* ( 1.0 - x(:,2)    );
  f2 = 2.25  - x(:,1) .* ( 1.0 - x(:,2).^2 );
  f3 = 2.625 - x(:,1) .* ( 1.0 - x(:,2).^3 );

  f = f1.^2 + f2.^2 + f3.^2;

  return
end


disp("Question 1")
A = [1 2; 3 4; 5 6]
B = [1 2 3; 4 5 6]

C = B' + A
#C = A' * B
#C = B + A
C = A * B

disp("Question 2")

A = [16,2,3,13;5,11,10,8;9,7,6,12;4,14,15,1]

#B = A(:, 0:2)
B = A(:, 1:2)
B = A(1:4, 1:2)
#B = A(0:4, 0:2)

disp("Question 3")
A = ones(10,10);
x = ones(10,1);

v = zeros(10, 1);

for i = 1:10
	 for j = 1:10
	   v(i) = v(i) + A(i, j) * x(j);
	 end
end

v

v = zeros(10, 1);
v = A * x

v = zeros(10, 1);
v = sum (A * x)

v = zeros(10, 1)
v = A .* x;

v = zeros(10, 1)
#v = Ax;

disp("Question 4")
v = ones(7,1);
w = ones(7,1);

z = 0;
for i = 1:7
  z = z + v(i) * w(i);
end

z

z = v' * w

#z = v * w

z = sum (v .* w)

z = v .* w

disp("Question 4")
X = ones(7,7)

for i = 1:7
  for j = 1:7
    	A(i, j) = log (X(i, j));
	    B(i, j) = X(i, j) ^ 2;
    	C(i, j) = X(i, j) + 1;
	    D(i, j) = X(i, j) / 4;
   end
end

A
B
C
D

B = X .^ 2

C = X + 1

D = X / 4

B = X ^ 2


function volume = torus_volume_3d ( r1, r2 )

%*****************************************************************************80
%
%% TORUS_VOLUME_3D computes the volume of a torus in 3D.
%
%  Discussion:
%
%    A torus with radii R1 and R2 is the set of points (X,Y,Z)
%    satisfying:
%
%    ( sqrt ( X**2 + Y**2 ) - R1 )**2 + Z**2 <= R2**2
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R1, R2, the "inner" and "outer" radii of the
%    torus.
%
%    Output, real VOLUME, the volume of the torus.
%
  volume = 2.0 * pi * pi * r1 * r2 * r2;

  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) * sum( -y'*log(sigmoid(X*theta)) - (1-y)'*log( 1 - sigmoid(X*theta)) );

grad = (1 / m) * sum( X .* repmat((sigmoid(X*theta) - y), 1, size(X,2)) );

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

end


function x=realCepstrum(x,N)
%%REALCEPSTRUM Compute the real cepstrum. The real cepstrum is the inverse
%              Fourier transform of the real logarithm of the magnitude of
%              the Fourier transform of a real sequence. The cepstrum is
%              often used in signal identification. The real cepstrum plays
%              a role in the design of certain filters.
%
%INPUTS: x An xDimX1 or 1XxDim real sequence.
%        N The length of the discrete Fourier transforms to use in the
%          computation of the cepstrum. If this parameter is omitted or an
%          empty matrix is passed, then the default of N=length(x) is used.
%
%OUTPUTS: x The real cepstrum of the input signal x. This will be length-N.
%
%The computation of the real cepstrum is described in [1]. However, the
%implementation here is more straighforward.
%
%REFERENCES:
%[1] T. F. Quatieri and J. M. Tribolet, "Computation of the real cepstrum
%    and minimum-phase reconstruction," in Programs for Digital Signal
%    Processing, Digital Signal Processing Committee, IEEE Acoustics,
%    Speech, and Signal Processing Society, Ed. New York: IEEE Press, 1979,
%    ch. 7.2.
%
%January 2016 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<2||isempty(N))
    N=length(x);
end

if(~isreal(x))
   error('The input must be real')
end

%The ifft should be real; this just deals with any possible finite
%precision issues.
x=real(ifft(log(abs(fft(x,N))),N));

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.