function ImgOut = fftsf(ImgIn,degree)
% FFTSF Frequency domain auto filtering (enhances powerfull frequencies)
%
% Input :	ImgIn  - grayscale image
%             degree - emphasis given to regular patterns
%                    values: 1, 2, 3, {4} (default)
%
%                     Filtering    |   soft    strong
%                     ------------------------------
%                     emphasis     |   1       2
%                     attenuation  |   3       4
%
% Output: class double data
% Display:
%
% im = imread('kb818c.jpg');
% figure
% subplot(2,3,2)
% imshow(im,[])
% title('Input')
% subplot(2,3,3)
% imshow(fftsf(im,1),[])
% title('1. Soft emphazis')
% subplot(2,3,6)
% imshow(fftsf(im,2),[])
% title('2. Strong emphazis')
% subplot(2,3,5)
% title([{'Self-filtering'},{'emphasizes or attenuates'},{'regular patterns'}])
% axis off
% subplot(2,3,1)
% imshow(fftsf(im,3),[])
% title('3. Soft attenuation')
% subplot(2,3,4)
% imshow(fftsf(im,4),[])
% title('4. Strong attenuation')
%
% Proceedure: The most powerfull frequencies in an image are enhanced /
%   attenuated by multiplying / dividing the complex FFT signal with the
%   magnitude of the same FFT.
%
% Reference: This code is based on the technique described in:
%   D.G. Bailey - Detecting regular patterns using frequency domain
%   self-filtering, 1997 Intl. Conf. on Image Processing, 1:440-3.
%
% Written by Vlad Atanasiu 2003.09.25
% 2008.11.07 - modified sample code
% 2007.07.07 - added new magnitude enhancement options
%            - removed bug in 'switch'
%            - changed name from 'fftselffilter' to 'fftsf' (is shorter)

F = fft2(double(ImgIn));	% FFT
R = abs(F);                     % magnitude
Z = angle(F);                   % phase
switch degree                  % filtering
case(2)
    F2 = F.*R.*sqrt(R.^2+Z.^2);
case(3)
    R = R + eps;
    F2 = sqrt(R).*exp(i*Z);
case(4)
    R = R + eps;
    F2 = F./R;
otherwise
    F2 = F.*R;
end
ImgOut = real(ifft2(F2));		% filtered image


function s1 = stirling1 ( n, m )

%*****************************************************************************80
%
%% STIRLING1 computes the Stirling numbers of the first kind.
%
%  Discussion:
%
%    The absolute value of the Stirling number S1(N,M) gives the number
%    of permutations on N objects having exactly M cycles, while the
%    sign of the Stirling number records the sign (odd or even) of
%    the permutations.  For example, there are six permutations on 3 objects:
%
%      A B C   3 cycles (A) (B) (C)
%      A C B   2 cycles (A) (BC)
%      B A C   2 cycles (AB) (C)
%      B C A   1 cycle  (ABC)
%      C A B   1 cycle  (ABC)
%      C B A   2 cycles (AC) (B)
%
%    There are
%
%      2 permutations with 1 cycle, and S1(3,1) = 2
%      3 permutations with 2 cycles, and S1(3,2) = -3,
%      1 permutation with 3 cycles, and S1(3,3) = 1.
%
%    Since there are N! permutations of N objects, the sum of the absolute
%    values of the Stirling numbers in a given row,
%
%      sum ( 1 <= I <= N ) abs ( S1(N,I) ) = N!
%
%  First terms:
%
%    N/M:  1     2      3     4     5    6    7    8
%
%    1     1     0      0     0     0    0    0    0
%    2    -1     1      0     0     0    0    0    0
%    3     2    -3      1     0     0    0    0    0
%    4    -6    11     -6     1     0    0    0    0
%    5    24   -50     35   -10     1    0    0    0
%    6  -120   274   -225    85   -15    1    0    0
%    7   720 -1764   1624  -735   175  -21    1    0
%    8 -5040 13068 -13132  6769 -1960  322  -28    1
%
%  Recursion:
%
%    S1(N,1) = (-1)^(N-1) * (N-1)! for all N.
%    S1(I,I) = 1 for all I.
%    S1(I,J) = 0 if I < J.
%
%    S1(N,M) = S1(N-1,M-1) - (N-1) * S1(N-1,M)
%
%  Properties:
%
%    sum ( 1 <= K <= M ) S2(I,K) * S1(K,J) = Delta(I,J)
%
%    X_N = sum ( 0 <= K <= N ) S1(N,K) X^K
%    where X_N is the falling factorial function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 August 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of rows of the table.
%
%    Input, integer M, the number of columns of the table.
%
%    Output, integer S1(N,M), the Stirling numbers of the first kind.
%
  if ( n <= 0 )
    s1 = [];
    return
  end

  if ( m <= 0 )
    s1 = [];
    return
  end

  s1(1,1) = 1;
  s1(1,2:m) = 0;

  for i = 2 : n

    s1(i,1) = - ( i - 1 ) * s1(i-1,1);

    for j = 2 : m
      s1(i,j) = s1(i-1,j-1) - ( i - 1 ) * s1(i-1,j);
    end

  end

  return
end


function Z = poly2DApproxLocal( D,  lsX, nrBfsX, lsY, nrBfsY )
%
% Purpose : This function performs local polynomial approximation for
% data which lie on a 2D grid.
%
% This function uses the discrete orthogonal polynomial toolbox DOPbox. The
% toolbox is available at MATLAB file exchange:
%
%   http://www.mathworks.com/matlabcentral/fileexchange/41250
%
% The use of the DOPbox enable the computation with polynomials of very
% high degree. There is no problem to compute a polynomial of degree d =
% 1000, the only disadvantage is the corresponding loss in speed.
%
% Some of the theory associated with this function can be found in the
% publication, Discrete Polynomial Moments and Savitzky-Golay Smoothing,
% available at:
%
% www.waset.org/journals/waset/v48/v48-85.pdf
%
% Use (syntax):
%   Z =  poly2DApproxLocal( D,  lsX, nrBfsX, lsY, nrBfsY )
%
% Input Parameters :
%   D: The 2D data lying on a grid, the function can be applied to any
%   form of data, e.g. surface data or images.
%   nrBfsX: the number of basis functions used in the x direction.
%   lsX: the support length in the x direction.
%   nrBfsY: the number of basis functions used in the y direction.
%   lsY: the support length in the y direction.
%
% Return Parameters :
%   Z: The 2D local polynomial approximation to the data.
%
% Description and algorithms:
%
% References :
%
% Author :  Matther Harker and Paul O'Leary
% Date :    29. Jan 2013
% Version : 1.0
%
% (c) 2013 Matther Harker and Paul O'Leary
% url: www.harkeroleary.org
% email: office@harkeroleary.org
%
% History:
%   Date:           Comment:
%
[ny, nx] = size( D );
%
% generate the rquired polynomial bases
%
xs = (1:nx)';
ys = (1:ny)';
%
Sx = dopApproxLocal( xs, lsX, nrBfsX, 'sparse' );
Sy = dopApproxLocal( ys, lsY, nrBfsY, 'sparse' );
%
%
% Generate the 2D local approximation
%
Z = Sy * D * Sx';


function [data_mean,data_diff,md,sd] = bland_altman_x_gt(data1,data2)
% Function to generate Bland Altman plots. Barry Greene, September 2008
% Bland, J.M., Altman, D.G. 'Statistical methods for assessing agreement ...
% between two methods of clinical measurement'(1986) Lancet, 1 (8476), pp. 307-310.
%
% Inputs: data1: ground truth
%         data2: estimated
%
% Produces Bland Altman plot with mean difference and mean difference +/-
% 2*SD difference lines.

[m,n] = size(data1);
if(n>m)
    data1 = data1';
end

if(size(data1)~=size(data2))
    error('Data matrices must be the same size')
end

data_mean = data1;  % Mean of values from each instrument
data_diff = data2 - data1;              % Difference between data from each instrument
md = mean(data_diff);               % Mean of difference between instruments
sd = std(data_diff);                % Std dev of difference between instruments

% figure;
plot(data_mean,data_diff,'ok','MarkerSize',3,'LineWidth',1);   % Bland Altman plot
hold on; x = [min(data_mean),max(data_mean)];
y = md*ones(1,2); plot(x,y,'-k'); % Mean difference line
y = md+2*sd*ones(1,2);
plot(x,y,'--k'); % Mean plus 2*SD line
% text(x(2),y(2),'+2 SD');
y = md-2*sd*ones(1,2);
plot(x,y,'--k'); % Mean minus 2*SD line

% text(x(2),y(2),'-2 SD');
% grid on
% title('Bland Altman plot','FontSize',9)
% xlabel('Mean of two measures','FontSize',8)
% ylabel('Difference between two measures','FontSize',8)


function g = sigmoidGradient(z)
%SIGMOIDGRADIENT returns the gradient of the sigmoid function
%evaluated at z
%   g = SIGMOIDGRADIENT(z) computes the gradient of the sigmoid function
%   evaluated at z. This should work regardless if z is a matrix or a
%   vector. In particular, if z is a vector or matrix, you should return
%   the gradient for each element.

g = zeros(size(z));

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

g = sigmoid(z) .* (1 - sigmoid(z));

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

end


function centroids = computeCentroids(X, idx, K)
%COMPUTECENTROIDS returs the new centroids by computing the means of the
%data points assigned to each centroid.
%   centroids = COMPUTECENTROIDS(X, idx, K) returns the new centroids by
%   computing the means of the data points assigned to each centroid. It is
%   given a dataset X where each row is a single data point, a vector
%   idx of centroid assignments (i.e. each entry in range [1..K]) for each
%   example, and K, the number of centroids. You should return a matrix
%   centroids, where each row of centroids is the mean of the data points
%   assigned to it.
%

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

% You need to return the following variables correctly.
centroids = zeros(K, n);

% ====================== YOUR CODE HERE ======================
% Instructions: Go over every centroid and compute mean of all points that
%               belong to it. Concretely, the row vector centroids(i, :)
%               should contain the mean of the data points assigned to
%               centroid i.
%
% Note: You can use a for-loop over the centroids to compute this.
%

count = zeros(K, 1);
for i = 1 : m
    count(idx(i,1),1) = count(idx(i,1),1) + 1;
    centroids(idx(i,1),:) = centroids(idx(i,1),:) + X(i,:);
end

for i = 1 : K
    centroids(i,:) = centroids(i,:) ./ count(i,1);
end

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

end


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

% DTFT properties

% Differentiation in frequency

syms n
x=0.8.^n
L=symsum(n/j*x*exp(-j*w*n),n,0,inf);
subplot(211);
w1=-pi:.01:pi;
Li=subs(L,w,w1);
plot(w1,abs(Li));
legend('magnitude of DTFT of left part')
subplot(212);
plot(w1,angle(Li))
legend('angle of DTFT of left part')

figure
syms n w
X=1/(1-0.8*exp(-j*w));
R=diff(X,w);
subplot(211);
w1=-pi:.01:pi;
Ri=subs(R,w,w1);
plot(w1,abs(Ri));
legend('magnitude of right part')
subplot(212);
plot(w1,angle(Ri))
legend('angle of right part')


function [ xtab, weight ] = ncc_rule ( norder )

%*****************************************************************************80
%
%% NCC_RULE computes the coefficients of a Newton-Cotes closed quadrature rule.
%
%  Discussion:
%
%    For the interval [-1,1], the Newton-Cotes quadrature rule estimates
%
%      Integral ( -1 <= X <= 1 ) F(X) dX
%
%    using NORDER equally spaced abscissas XTAB(I) and a weight vector
%    WEIGHT(I):
%
%      Sum ( 1 <= I <= N ) WEIGHT(I) * F ( XTAB(I) ).
%
%    For the CLOSED rule, the abscissas include A and B.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NORDER, the order of the rule.
%
%    Output, real XTAB(NORDER), the abscissas of the rule.
%
%    Output, real WEIGHT(NORDER), the weights of the rule.
%

%
%  Compute a closed quadrature rule.
%
  a = -1.0;
  b =  1.0;

  for i = 1 : norder
    xtab(i) = ( ( norder - i     ) * a   ...
              + (          i - 1 ) * b ) ...
              / ( norder - 1     );
  end

  weight = nc_rule ( norder, a, b, xtab );

  return
end


function [err,Eq] = Plane_Equation (Triplets, verbose)
%
%   [err,Eq] = Plane_Equation (Triplets, [verbose])
%
%Purpose:
%   Determine the equation of the plane passing through three points
%
%
%Input Parameters:
%   Triplets is an Nx1 vector of strucutres. Each structure defines a plane
%    .XYZ : is a 3x3 matrix containing the XYZ of each of the three points
%           Each row is a point. ie: XYZ = [0 0 0; 1 0 0; 1 1 1]; is for the
%           three points (0 0 0), (1 0 0) and (1 1 1).
%           If the three points are colinear, Eq = [0 0 0 0]
%
%   verbose (0/1), default is 1
%
%Output Parameters:
%   err : 0 No Problem
%       : 1 Mucho Problems
%
%   Eq is a Nx4 matrix containing the equation of the plane containing each
%       triplet in  Triplets. The plane passing by triplet i is speicifed in
%       Eq(i,:) the plane would be Eq(i,1)x + Eq(i,2)y + Eq(i,3)z + Eq(i,4) = 0
%
%More Info :
%
%   see also ShowPlane
%   try
%       Triplets(1).XYZ = [0 0 0; 1 0 0; 1 1 0];
%       Triplets(2).XYZ = [0 0 0; 1 0 0; 1 1 1];
%       Triplets(3).XYZ = [0 5 0; 1 5 0; 1 1 1];
%
%       [err,Eq] = Plane_Equation (Triplets);
%       [err,PatchHandles] = ShowPlane (Eq); view(3)
%
%     Author : Ziad Saad
%     Date : Thu Oct 22 16:09:56 CDT 1998

%Define the function name for easy referencing
FuncName = 'Plane_Equation';

%initailize return variables
err = 1;

if (nargin == 1), 	verbose = 1;	end

if (is_row(Triplets) == -1),	err = ErrEval(FuncName,'Err_Triplets must be an Nx1 vector');	return;	end

Triplets = Triplets(:);
Nplanes = size(Triplets,1);
Eq = zeros(Nplanes,4); %allocate

for (i=1:1:Nplanes),
	%Form the equation of the plane
	x1 = Triplets(i).XYZ(1,1); y1 = Triplets(i).XYZ(1,2); z1 = Triplets(i).XYZ(1,3);
	x2 = Triplets(i).XYZ(2,1); y2 = Triplets(i).XYZ(2,2); z2 = Triplets(i).XYZ(2,3);
	x3 = Triplets(i).XYZ(3,1); y3 = Triplets(i).XYZ(3,2); z3 = Triplets(i).XYZ(3,3);
	Eq(i,1) = y1.*(z2-z3) + y2.*(z3-z1) + y3.*(z1-z2);
	Eq(i,2) = z1.*(x2-x3) + z2.*(x3-x1) + z3.*(x1-x2);
	Eq(i,3) = x1.*(y2-y3) + x2.*(y3-y1) + x3.*(y1-y2);
	Eq(i,4) = -x1.*(y2.*z3 - y3.*z2) - x2.*(y3.*z1 - y1.*z3) - x3.*(y1.*z2 - y2.*z1);

	if (verbose),
		if (~rem (i,200)),
			fprintf (1,'[%g/%g]\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b',i,Nplanes);
		end

	end
end

err = 0;
return;


function [U,T,mu] = pcasecon(X,k)
% Input:
% X : m x n matrix
% Each column of X is a feature vector
%
% Output:
% X = U*T approximately (up to k)
%
% Description:
% Principal Component Analysis (PCA) while trying to conserve memory and be faster
% Requires that k <= min(m,n) where [m,n] = size(X)
% This function is useful if k is much smaller than m and n
% or if X is sparse (see doc eigs)
%
% Vipin Vijayan (2014)

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

[m,n] = size(X);
assert(k <= m && k <= n, 'k needs to be smaller than size(X,1) and size(X,2)');

if  m <= n
    C = X*X';
    [U,~] = eigs(C,k);
    clear C;

    T = U'*X;
else
    C = X'*X;
    [V,D] = eigs(C,k);
    clear C;

    U = X*V; % convert evecs from X'*X to X*X'. the evals are the same.
    %s = sqrt(sum(U.^2,1))';
    s = sqrt(abs(diag(D)));
    U = bsxfun(@(x,c)x./c, U, s');
    %S = diag(s);
    %T = S*V';
    T = bsxfun(@(c,vt)c.*vt,s,V');
end


%% RATE OF CONVERGENCE OF BILINEAR FINITE ELEMENT METHOD
%
% This example is to show the rate of convergence of bilinear finite
% element approximation of the Poisson equation on the unit square:
%
% $$- \Delta u = f \; \hbox{in } (0,1)^2$$
%
% for the following boundary condition:
%
% # Non-empty Dirichlet boundary condition. $u=g_D \hbox{ on }\Gamma_D, \quad \nabla u\cdot n=g_N \hbox{ on }\Gamma_N. \Gamma _D = \{(x,y): x=0, y\in [0,1]\}, \; \Gamma _N = \partial \Omega \backslash \Gamma _D$.
% # Pure Neumann boundary condition. $\Gamma _N = \partial \Omega$.
% # Robin boundary condition. $g_R u + \nabla u\cdot n=g_N \hbox{ on }\partial \Omega$

%%
clear all; close all; clc;
[node,elem] = squarequadmesh([0,1,0,1],1/2^5);
option.L0 = 1;
option.maxIt = 4;
option.printlevel = 1;
option.plotflag = 0;
option.elemType = 'Q1';

%% Non-empty Dirichlet boundary condition.
pde = sincosdata;
bdFlag = setboundary(node,elem,'Dirichlet','~(x==0)','Neumann','x==0');
% bdFlag = setboundary(node,elem,'Dirichlet');
femPoisson(node,elem,pde,bdFlag,option);
return

%% Pure Neumann boundary condition.
pde = sincosNeumanndata;
bdFlag = setboundary(node,elem,'Neumann');
femPoisson(node,elem,pde,bdFlag,option);

%% Pure Robin boundary condition.
option.plotflag = 0;
pdeRobin = sincosRobindata;
bdFlag = setboundary(node,elem,'Robin');
femPoisson(node,elem,pdeRobin,bdFlag,option);

%% Conclusion
%
% The optimal rate of convergence of the H1-norm (2nd order) and L2-norm
% (3rd order) is observed. The order of ||DuI-Duh|| is almost 3rd order and
% thus superconvergence exists.
%
% MGCG converges uniformly in all cases.


function inside = triangle_contains_point_2d_1 ( t, p )

%*****************************************************************************80
%
%% TRIANGLE_CONTAINS_POINT_2D_1 finds if a point is inside a triangle in 2D.
%
%  Discussion:
%
%    It is conventional to list the triangle vertices in counter clockwise
%    order.  However, this routine does not require a particular order
%    for the vertices.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 December 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real T(2,3), the triangle vertices.
%
%    Input, real P(2,1), the point to be checked.
%
%    Output, logical INSIDE, is TRUE if the point is inside
%    the triangle or on its boundary.
%
  xsi = triangle_barycentric_2d ( t, p );

  if ( any ( xsi(1:3,1) < 0.0 ) )
    inside = 0;
  else
    inside = 1;
  end

  return
end


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

M=[-1,  0,  0,  1.3333333333333333333333333333333333333;
    0,  0,  1,  1.3333333333333333333333333333333333333;
    0,  1,  0,  1.3333333333333333333333333333333333333;
    0,  0, -1,  1.3333333333333333333333333333333333333;
    1,  0,  0,  1.3333333333333333333333333333333333333;
    0, -1,  0,  1.3333333333333333333333333333333333333];

w=M(:,4);
xi=M(:,1:3)';

end

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


function [a,f,B,W]=ldatrace(b,w,n,c)
%LDATRACE Calculates an LDA transform to maximize trace discriminant [a,f,B,W]=(b,w,n,c)
% If a feature vector X can come from one of several class and W and B are respectively
% the within-class and between-class covariance matrices, then the generalized Fisher discriminant
% F=trace(W\B) is a measure of how well the feature vector discriminates between the classes.
% If we choose a rectangular (tall, skinny) transformation matrix, we can define a smaller
% feature vector Y=A'*X. The aim of this routine is to choose A to maximize the Fisher
% discriminant. We assume that W is positive definite and B is positive semi-definite.
% The input argument C allows the uset to pre-specify some of the columns of A.
%
% Inputs:
%     w[m,m] = within class covariance matrix of x
%     b[m,m] = between class covariance matrix of x [default = I]
%     n is the number of columns in output matrix A [default = M]
%     c[m,r] specifies the first few columns of A to be predefined values [default = null)
%
% Outputs:
%     a[m,n] is the transformation matrix: y=a'*x
%     f[n,1] gives the incremental gain in f value for successive columns of A
%     B(n,n) gives the between-class covariance matrix of y
%     W[n,n] gives the within-class covariance matrix of y

%      Copyright (C) Mike Brookes 1997
%      Version: $Id: ldatrace.m 713 2011-10-16 14:45:43Z dmb $
%
%   VOICEBOX is a MATLAB toolbox for speech processing.
%   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   This program is free software; you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation; either version 2 of the License, or
%   (at your option) any later version.
%
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You can obtain a copy of the GNU General Public License from
%   http://www.gnu.org/copyleft/gpl.html or by writing to
%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

m=size(b,1);    % dimension of data vectors
if nargin<4
    r=0;
    if nargin<3
        n=m;
        if nargin<2
            w=eye(m);
        end
    end
else
    r=size(c,2);    % number of columns that are pre-specified
end
if r
    if n>r          % need to find additional vectors
        g=chol(w);
        v=g\null(c'*g');
        [p,l,q]=svd(v'*b*v);
        a(:,r+1:n)=v*p(:,1:n-r);
        a(:,1:r)=c;
    else
        a=c;        % no new vectors to find
    end
    if nargout>1
        ari=a/triu(qr(chol(a'*w*a))); % matrix a must be of full rank
        f=diag(ari'*b*ari);
    end
else
    [g,d]=eig(b,w,'qz');
    [ds,is]=sort(-diag(d));
    a=g(:,is(1:n));
    if nargout>1
        f=-ds(1:n);
    end
end
if nargout > 2
    B=a'*b*a;
    if nargout > 3
        W=a'*w*a;
    end

end


% IMAGE_COMPLEX Return a color image that for a complex 2d signal.
%
% Usage
%	x_rgb = IMAGE_COMPLEX(x)
%
% Input
%    x (complex 2d matrix): the signals to be displayed
%
% Output
%    x_rgb (numeric): a color image of the signal.
%
% Description
%    Compute a color image corresponding to a complex 2d signal.
%    The saturation corresponds to the complex modulus while the hue
%    corresponds to the complex argument.
%
% See also
%    DISPLAY_FILTER_BANK_2D_COMPLEX, IMAGE_COMPLEX_CELL
function x_rgb = image_complex(x)
	x = x / max(abs(x(:)) + 1e-10);
	x_hsv(:,:,1) = (pi + 1e-5 + angle(x)) / (2*pi);
	x_hsv(:,:,2) = abs(x);
	x_hsv(:,:,3) = 1;
	x_rgb = hsv2rgb(x_hsv);
end


function [rwproc] = ranwalk(npoints, p)
% RANWALK generate and plot a trajectory of a random walk which
%    starts at 0, jumps up with probability p and down with
%    probability 1-p
%
% [rwproc] = ranwalk(npoints, p)
%
% Inputs: npoints - length of the trajectory
%         p - probability of the jump upwards
%
% Outputs: rwproc - trajectory of the process

% Authors: R.Gaigalas, I.Kaj
% v1.2 07-Oct-02

  % default parameter values
  if (nargin==0)
    npoints = 100;
    p = 0.5;
  end

  % generate jumps and sum up
  rwproc = [0 cumsum(2.*(rand(1, npoints-1)<p)-1)];

  stairs(rwproc);


function fs = get_seq ( d, norm )

%*****************************************************************************80
%
%% GET_SEQ generates all positive integer D-vectors that sum to NORM.
%
%  Discussion:
%
%    This function computes a list, in reverse dictionary order, of
%    all D-vectors of positive values that sum to NORM.
%
%    For example, fs = get_seq ( 3, 5 ) returns
%
%      3  1  1
%      2  2  1
%      2  1  2
%      1  3  1
%      1  2  2
%      1  1  3
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 May 2010
%
%  Author:
%
%    Original MATLAB version by Florian Heiss, Viktor Winschel.
%    This MATLAB version by John Burkardt.
%
%  Reference:
%
%    Florian Heiss, Viktor Winschel,
%    Likelihood approximation by numerical integration on sparse grids,
%    Journal of Econometrics,
%    Volume 144, 2008, pages 62-80.
%
%  Parameters:
%
%    Input, integer D, the dimension.
%
%    Input, integer NORM, the value that each row must sum to.
%    NORM must be at least D.
%
%    Output, integer FS(*,D).  Each row of FS represents one vector
%    with all elements positive and summing to NORM.
%
  if ( norm < d )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'GET_SEQ - Fatal error!\n' );
    fprintf ( 1, '  NORM = %d < D = %d.\n', norm, d );
    error ( 'GET_SEQ - Fatal error!' );
  end

  seq = zeros ( 1, d );
%
%  The algorithm is written to work with vectors whose minimum value is
%  allowed to be zero.  So we subtract D from NORM at the beginning and
%  then increment the result vectors by 1 at the end!
%
  a = norm - d;
  seq(1) = a;
  fs = seq;
  c = 1;

  while ( seq (d) < a )

    if ( c == d )
      for i = (c-1) : -1 : 1
        c = i;
        if ( seq(i) ~= 0 )
          break
        end
      end
    end

    seq(c) = seq(c) - 1;
    c = c + 1;
    seq(c) = a - sum ( seq(1:(c-1)) );

    if ( c < d )
      seq((c+1):d) = zeros ( 1, d - c );
    end

    fs = [ fs; seq ];

  end
%
%  Increment all entries by 1.
%
  fs = fs + 1;

  return
end


%% Test suite for Minimum bounding objects: RECT, CIRCLE, SPHERE, ELLIPSE

%% Minimal area rectangle around random data

% Random points in the unit square
x = rand(1000,1);
y = rand(1000,1);

% should have a nearly square bounding rectangle
tic,[xrect,yrect] = minboundrect(x,y),toc

%
plot(x,y,'ro',xrect,yrect,'b-')

%% Minimal circle around (normally distributed) random data
x = randn(100000,1);
y = randn(100000,1);

% It should have a center of roughly (0,0).
tic,[center,radius] = minboundcircle(x,y),toc

theta = linspace(0,2*pi,100);
xc = center(1) + radius*cos(theta);
yc = center(2) + radius*sin(theta);

% The circle will generally pass exactly through
% three of the points.
plot(x,y,'ro',xc,yc,'b-')

%% Minimal circle around nearly linear data.
x = rand(5,1);
y = x + (rand(size(x))-.5)/10;

[center,radius] = minboundcircle(x,y)

theta = linspace(0,2*pi,100);
xc = center(1) + radius*cos(theta);
yc = center(2) + radius*sin(theta);

% Sometimes the minimal radius circle may pass
% through only two points.
plot(x,y,'ro',xc,yc,'b-')
axis equal

%% Degenerate cases - a minimal circle around exactly two points
x = [0 1];
y = x;

[center,radius] = minboundcircle(x,y)

%% Degenerate cases - a minimal circle around exactly one point
x = 1;
y = 2;

% The radius must be zero
[center,radius] = minboundcircle(x,y)

%% Minimum radius sphere around random data
xyz = rand(10000,3);

% The sphere should have approximate center [.5 .5 .5]
% and approximate radius sqrt(3)/2 = .86603...
[center,radius] = minboundsphere(xyz)

%% Minimum area ellipse around exactly circular data
theta = linspace(0,2*pi,100);
x = cos(theta);
y = sin(theta);

% will have center == [0,0], radius = 1, both to within
% double precision accuracy in Matlab.
[center,H,xe,ye] = minboundellipse(x,y)

plot(x,y,'ro',xe,ye,'b-')
axis equal

%% Minimum area ellipse around correlated data
xy = randn(100,2);
xy = xy*rand(2)^2;

% will have center [0,0], radius = 1, both to within
% double precision accuracy in Matlab.
[center,H,xe,ye] = minboundellipse(xy(:,1),xy(:,2))

plot(xy(:,1),xy(:,2),'ro',xe,ye,'b-')
axis equal

%%


function angVal=angleBetweenLineAndPlane(a,n)
%%ANGLEBETWEENLINEANDPLANE Given a line specified in parameteric form as
%       x=x0+a*t, where t is the scalar parametric parameter, and a plane
%       given in parameteric form as x'*n=d, return the (acute) angle
%       between the line and the plane.
%
%INPUTS: a The xDimX1 parameteric slope vector of the line.
%        n An xDimX1 normal to the plane. If this is omitted or an empty
%          matrix is passed, then n is a vector that is all zero except for
%          the last element, which is 1. In 3D that is equivalent to using
%          the x-y plane.
%
%OUTPUTS: angVal The angle between the line and the plane given in radians.
%
%This just uses the identity that
%sin(angVal)=abs(dot(a,n)/(norm(a)*norm(n)))
%
%EXAMPLE:
%An easy test for the function is to use the x-y plane and just have a line
%in the x-z plane defined at a specified angle to the x axis. In that
%instance, the result of this function can be quickly compared ot the
%truth.
% n=[0;0;1];
% theta=pi/3;
% a=[cos(theta);0;sin(theta)];
% AbsErr=abs(angleBetweenLineAndPlane(a,n)-theta)
%In this instance the absolute error is 0.
%
%July 2021 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

angVal=asin(abs(dot(a,n)/(norm(a)*norm(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.


function [fdx, fdy, fdz] = calcFdr(N, directionFlag)
%CALCFDR Function who's
%diagonals are the k-space representation of the image-domain differencing
%operator. See "vx" in the reference below.
%
%   N: Size of volume
%   directionFlag: 'forward' or 'backward', direction of the
%   differentiation.
%
%   Code refractored from Berkin Bilgic's scripts: "script_Laplacian_unwrap_Sharp_Fast_TV_gre3D.m"
%   and "script_Laplacian_unwrap_Sharp_Fast_TV_gre3D.m"
%   Original source: https://martinos.org/~berkin/software.html
%
%   Original reference:
%   Bilgic et al. (2014), Fast quantitative susceptibility mapping with
%   L1-regularization and automatic parameter selection. Magn. Reson. Med.,
%   72: 1444-1459. doi:10.1002/mrm.25029
%

    [k2,k1,k3] = meshgrid(0:N(2)-1, 0:N(1)-1, 0:N(3)-1);

    switch directionFlag
        case 'forward'
            fdx = 1 - exp(-2*pi*1i*k1/N(1));
            fdy = 1 - exp(-2*pi*1i*k2/N(2));
            fdz = 1 - exp(-2*pi*1i*k3/N(3));
        case 'backward'
            fdx = -1 + exp(2*pi*1i*k1/N(1));
            fdy = -1 + exp(2*pi*1i*k2/N(2));
            fdz = -1 + exp(2*pi*1i*k3/N(3));
    end

end


%% Machine Learning Online Class - Exercise 2: Logistic Regression
%
%  Instructions
%  ------------
%
%  This file contains code that helps you get started on the logistic
%  regression exercise. You will need to complete the following functions
%  in this exericse:
%
%     sigmoid.m
%     costFunction.m
%     predict.m
%     costFunctionReg.m
%
%  For this exercise, you will not need to change any code in this file,
%  or any other files other than those mentioned above.
%

%% Initialization
clear ; close all; clc

%% Load Data
%  The first two columns contains the exam scores and the third column
%  contains the label.

data = load('ex2data1.txt');
X = data(:, [1, 2]); y = data(:, 3);

%% ==================== Part 1: Plotting ====================
%  We start the exercise by first plotting the data to understand the
%  the problem we are working with.

fprintf(['Plotting data with + indicating (y = 1) examples and o ' ...
         'indicating (y = 0) examples.\n']);

plotData(X, y);

% Put some labels
hold on;
% Labels and Legend
xlabel('Exam 1 score')
ylabel('Exam 2 score')

% Specified in plot order
legend('Admitted', 'Not admitted')
hold off;

fprintf('\nProgram paused. Press enter to continue.\n');
pause;

%% ============ Part 2: Compute Cost and Gradient ============
%  In this part of the exercise, you will implement the cost and gradient
%  for logistic regression. You neeed to complete the code in
%  costFunction.m

%  Setup the data matrix appropriately, and add ones for the intercept term
[m, n] = size(X);

% Add intercept term to x and X_test
X = [ones(m, 1) X];

% Initialize fitting parameters
initial_theta = zeros(n + 1, 1);

% Compute and display initial cost and gradient
[cost, grad] = costFunction(initial_theta, X, y);

fprintf('Cost at initial theta (zeros): %f\n', cost);
fprintf('Gradient at initial theta (zeros): \n');
fprintf(' %f \n', grad);

fprintf('\nProgram paused. Press enter to continue.\n');
pause;

%% ============= Part 3: Optimizing using fminunc  =============
%  In this exercise, you will use a built-in function (fminunc) to find the
%  optimal parameters theta.

%  Set options for fminunc
options = optimset('GradObj', 'on', 'MaxIter', 400);

%  Run fminunc to obtain the optimal theta
%  This function will return theta and the cost
[theta, cost] = ...
	fminunc(@(t)(costFunction(t, X, y)), initial_theta, options);

% Print theta to screen
fprintf('Cost at theta found by fminunc: %f\n', cost);
fprintf('theta: \n');
fprintf(' %f \n', theta);

% Plot Boundary
plotDecisionBoundary(theta, X, y);

% Put some labels
hold on;
% Labels and Legend
xlabel('Exam 1 score')
ylabel('Exam 2 score')

% Specified in plot order
legend('Admitted', 'Not admitted')
hold off;

fprintf('\nProgram paused. Press enter to continue.\n');
pause;

%% ============== Part 4: Predict and Accuracies ==============
%  After learning the parameters, you'll like to use it to predict the outcomes
%  on unseen data. In this part, you will use the logistic regression model
%  to predict the probability that a student with score 45 on exam 1 and
%  score 85 on exam 2 will be admitted.
%
%  Furthermore, you will compute the training and test set accuracies of
%  our model.
%
%  Your task is to complete the code in predict.m

%  Predict probability for a student with score 45 on exam 1
%  and score 85 on exam 2

prob = sigmoid([1 45 85] * theta);
fprintf(['For a student with scores 45 and 85, we predict an admission ' ...
         'probability of %f\n\n'], prob);

% Compute accuracy on our training set
p = predict(theta, X);

fprintf('Train Accuracy: %f\n', mean(double(p == y)) * 100);

fprintf('\nProgram paused. Press enter to continue.\n');
pause;


function [X_poly] = polyFeatures(X, p)
%POLYFEATURES Maps X (1D vector) into the p-th power
%   [X_poly] = POLYFEATURES(X, p) takes a data matrix X (size m x 1) and
%   maps each example into its polynomial features where
%   X_poly(i, :) = [X(i) X(i).^2 X(i).^3 ...  X(i).^p];
%

% You need to return the following variables correctly.
X_poly = zeros(numel(X), p);

% ====================== YOUR CODE HERE ======================
% Instructions: Given a vector X, return a matrix X_poly where the p-th
%               column of X contains the values of X to the p-th power.

m = size(X, 1);

for i=1:m

    poly_feature = zeros(p, 1);

    for j=1:p
        poly_feature(j) =  X(i).^j;
    end

    X_poly(i, :) = poly_feature;
end

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

end


function varargout = createRhombododecahedron()
%CREATERHOMBODODECAHEDRON Create a 3D mesh representing a rhombododecahedron
%
%   [V, E, F] = createRhombododecahedron
%   V is a 14-by-3 array with vertex coordinate,
%   E is a 12-by-2 array containing indices of neighbour vertices,
%   F is a 8-by-3 array containing vertices array of each face.
%
%   [V, F] = createRhombododecahedron;
%   Returns only the vertices and the face vertex indices.
%
%   MESH = createRhombododecahedron;
%   Returns the data as a mesh structure, with fields 'vertices', 'edges'
%   and 'faces'.
%
%   Example
%   [v, e, f] = createRhombododecahedron;
%   drawMesh(v, f);
%
%
%   See also
%   meshes3d, drawMesh

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

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

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

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

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

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


  function distance = penalty_distance(offsets, sizes)
%|function distance = penalty_distance(offsets, sizes)
%|
%| convert scalar offsets to Euclidean distances to neighbors,
%| with the exception that '0' is mapped to 1 for identity case
%|
%| in
%|	offsets		[MM]
%|	sizes		[1 ndim]
%| out
%|	distance	[MM 1]
%|
%| Copyright 2006-12-6, Jeff Fessler, University of Michigan

if nargin == 1 && streq(offsets, 'test'), penalty_distance_test, return, end
if nargin < 2, ir_usage, end

displace = penalty_displace(offsets(:), sizes);
distance = sqrt(sum(displace.^2, 2));
distance(offsets == 0) = 1; % trick: for identity case

%
% penalty_distance_test()
%
function penalty_distance_test

nx = 100; ny = 80; % 2d
[ix iy] = ndgrid(-2:2, -2:2);
offsets = col(ix + iy * nx);
dis = penalty_distance(offsets, [nx ny]);
tru = sqrt(ix(:).^2 + iy(:).^2);
tru(ix == 0 & iy == 0) = 1; % trick: to match identity case
jf_equal(dis, tru)

nx = 10; ny = 8; nz = 7; % 3d
[ix iy iz] = ndgrid(-2:2, -2:2, -2:2);
offsets = col(ix + iy * nx + iz * nx * ny);
dis = penalty_distance(offsets, [nx ny nz]);
tru = sqrt(ix(:).^2 + iy(:).^2 + iz(:).^2);
tru(ix == 0 & iy == 0 & iz == 0) = 1; % trick: to match identity case
jf_equal(dis, tru)


function pn = line_par_point_near_3d ( f, g, h, x0, y0, z0, p )

%*****************************************************************************80
%
%% LINE_PAR_POINT_NEAR_3D: nearest point on parametric line to given point, 3D.
%
%  Discussion:
%
%    The parametric form of a line in 3D is:
%
%      X = X0 + F * T
%      Y = Y0 + G * T
%      Z = Z0 + H * T
%
%    We may normalize by choosing F*F + G*G + H*H = 1, and F nonnegative.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    13 April 2013
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Adrian Bowyer, John Woodwark,
%    A Programmer's Geometry,
%    Butterworths, 1983,
%    ISBN: 0408012420.
%
%  Parameters:
%
%    Input, real F, G, H, X0, Y0, Z0, the parametric
%    line parameters.
%
%    Input, real P(3,1), the point whose distance from the line is
%    to be measured.
%
%    Output, real PN(3,1), the point on the parametric line which
%    is nearest to P.
%
  t = ( f * ( p(1) - x0 ) + g * ( p(2) - y0 ) + h * ( p(3) - z0 ) ) ...
    / ( f * f + g * g + h * h );

  pn(1,1) = x0 + t * f;
  pn(2,1) = y0 + t * g;
  pn(3,1) = z0 + t * h;

  return
end


function [x y]=bresenham(x1,y1,x2,y2)

%Matlab optmized version of Bresenham line algorithm. No loops.
%Format:
%               [x y]=bham(x1,y1,x2,y2)
%
%Input:
%               (x1,y1): Start position
%               (x2,y2): End position
%
%Output:
%               x y: the line coordinates from (x1,y1) to (x2,y2)
%
%Usage example:
%               [x y]=bham(1,1, 10,-5);
%               plot(x,y,'or');
x1=round(x1); x2=round(x2);
y1=round(y1); y2=round(y2);
dx=abs(x2-x1)
dy=abs(y2-y1)
steep=abs(dy)>abs(dx)
if steep t=dx;dx=dy;dy=t; end

%The main algorithm goes here.
if dy==0
    q=zeros(dx+1,1);
else
    q=[0;diff(mod([floor(dx/2):-dy:-dy*dx+floor(dx/2)]',dx))>=0]
end

%and ends here.

if steep
    if y1<=y2 y=[y1:y2]'; else y=[y1:-1:y2]'; end
    if x1<=x2 x=x1+cumsum(q);else x=x1-cumsum(q); end
else
    if x1<=x2 x=[x1:x2]'; else x=[x1:-1:x2]'; end
    if y1<=y2 y=y1+cumsum(q);else y=y1-cumsum(q); end
end


%% Creating one filter
% In this demo, we will show how to build some filters in spatial domain or
% Fourier domain. Gabor, Morlet and Gaussian filters are pointed out.
%
%% Reviewed functions
% The following function will be demonstrated:
%%
%
% # gabor_2d
% # gaussian_2d
% # morlet_2d_noDC
% # morlet_2d_pyramid
%
%% Demonstration
%
% Here are shown 4 examples of filters:

N=50;
M=50;
sigma=10;
slant=3;
theta=pi/3;
xi=2;

gab = gabor_2d(N, M, sigma, slant, xi, theta);
morlet = morlet_2d_noDC(N, M, sigma, slant, xi, theta);
morlet2 = morlet_2d_pyramid(N, M, sigma, slant, xi, theta);
gaussian = gaussian_2d(N, M, sigma);
subplot(2,2,1)
imagesc(real(gab));
axis off
title('Real part of Gabor wavelet in Fourier domain')
subplot(2,2,2)
imagesc(real(morlet));
axis off
title('Real part of Morlet wavelet in Fourier domain')
subplot(2,2,3)
imagesc(real(morlet2));
axis off
title('Real part of Morlet wavelet in Spatial domain')
subplot(2,2,4)
imagesc(gaussian);
axis off
title('Gaussian wavelet')


function [ x, seed ] = truncated_normal_ab_sample ( mu, sigma, a, b, seed )

%*****************************************************************************80
%
%% TRUNCATED_NORMAL_AB_SAMPLE samples the truncated Normal PDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 August 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real MU, SIGMA, the mean and standard deviation of the
%    parent Normal distribution.
%
%    Input, real A, B, the lower and upper truncation limits.
%
%    Input/output, integer SEED, a seed for the random number
%    generator.
%
%    Output, real X, a sample of the PDF.
%
  alpha = ( a - mu ) / sigma;
  beta = ( b - mu ) / sigma;

  alpha_cdf = normal_01_cdf ( alpha );
  beta_cdf = normal_01_cdf ( beta );

  [ u, seed ] = r8_uniform_01 ( seed );
  xi_cdf = alpha_cdf + u * ( beta_cdf - alpha_cdf );
  xi = normal_01_cdf_inv ( xi_cdf );

  x = mu + sigma * xi;

  return
end


%ZNCC  Normalized cross correlation
%
% M = ZNCC(I1, I2) is the zero-mean normalized cross-correlation between the
% two equally sized image patches I1 and I2.  The result M is a scalar in
% the interval -1 to 1 that indicates similarity.  A value of 1 indicates
% identical pixel patterns.
%
% Notes::
% - The ZNCC similarity measure is invariant to affine changes in image
%   intensity (brightness offset and scale).
%
% See also NCC, SAD, SSD, ISIMILARITY.

% Copyright (C) 1993-2011, by Peter I. Corke
%
% This file is part of The Machine Vision Toolbox for Matlab (MVTB).
%
% MVTB is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% MVTB 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 Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with MVTB.  If not, see <http://www.gnu.org/licenses/>.

function m = zncc(w1, w2)

	w1 = w1 - mean(w1(:));
	w2 = w2 - mean(w2(:));

	denom = sqrt( sum(sum(w1.^2))*sum(sum(w2.^2)) );

	if denom < 1e-10,
		m = 0;
	else
		m = sum(sum((w1.*w2))) / denom;
	end


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

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

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

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

h = sigmoid(X * theta);
J = sum(-y .* log(h) - (1 - y) .* log(1 - h)) / m;
% regularization for cost function
J = J + (lambda / (2 * m)) * sum(theta(2:end) .^ 2);
grad = (1 / m) * X' * (h - y);
% regularization for gradient values
grad = grad + (lambda / m) * [0; theta(2:end)];

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

grad = grad(:);

end


function varargout = rotation3dToEulerAngles(mat, varargin)
%ROTATION3DTOEULERANGLES Extract Euler angles from a rotation matrix.
%
%   [PHI, THETA, PSI] = rotation3dToEulerAngles(MAT)
%   Computes Euler angles PHI, THETA and PSI (in degrees) from a 3D 4-by-4
%   or 3-by-3 rotation matrix.
%
%   ANGLES = rotation3dToEulerAngles(MAT)
%   Concatenates results in a single 1-by-3 row vector. This format is used
%   for representing some 3D shapes like ellipsoids.
%
%   ... = rotation3dToEulerAngles(MAT, CONVENTION)
%   CONVENTION specifies the axis rotation sequence.
%   Supported conventions are: 'ZYX', 'ZYZ'. Default is 'ZYX'
%
%   Example
%   rotation3dToEulerAngles
%
%   References
%   Code from Graphics Gems IV on euler angles
%   http://tog.acm.org/resources/GraphicsGems/gemsiv/euler_angle/EulerAngles.c
%   Modified using explanations in:
%   http://www.gregslabaugh.name/publications/euler.pdf
%
%   See also
%   transforms3d, rotation3dAxisAndAngle, createRotation3dLineAngle,
%   eulerAnglesToRotation3d
%
%
% ------
% Author: David Legland
% e-mail: david.legland@grignon.inra.fr
% Created: 2010-08-11,    using Matlab 7.9.0.529 (R2009b)
% Copyright 2010 INRA - Cepia Software Platform.

p = inputParser;
validStrings = {'ZYX','ZYZ'};
addOptional(p,'convention','ZYX',@(x) any(validatestring(x,validStrings)));
parse(p,varargin{:});
convention=p.Results.convention;

% conversion from radians to degrees
k = 180 / pi;

switch convention
    case 'ZYX'
        % extract |cos(theta)|
        cy = hypot(mat(1,1), mat(2,1));
        % avoid dividing by 0
        if cy > 16*eps
            % normal case: theta <> 0
            phi   = k * atan2( mat(2,1), mat(1,1));
            theta = k * atan2(-mat(3,1), cy);
            psi   = k * atan2( mat(3,2), mat(3,3));
        else
            %
            phi   = 0;
            theta = k * atan2(-mat(3,1), cy);
            psi   = k * atan2(-mat(2,3), mat(2,2));
        end
    case 'ZYZ'
        cy = hypot(mat(3,2), mat(3,1));
        if cy > 16*eps
            phi   = k * -atan2(mat(2,3), -mat(1,3));
            theta = k * -atan2(cy, mat(3,3));
            psi   = k * -atan2(mat(3,2), mat(3,1));
        else
            phi   = 0;
            theta = k * atan2(cy, mat(3,3));
            psi   = k * atan2(mat(2,1), mat(2,2));
        end
end

% format output arguments
if nargout <= 1
    % one array
    varargout{1} = [phi theta psi];
else
    % three separate arrays
    varargout = {phi, theta, psi};
end


function STATS=mwwtest(x1,x2)
% Mann-Whitney-Wilcoxon non parametric test for two unpaired groups.
% This file execute the non parametric Mann-Whitney-Wilcoxon test to evaluate the
% difference between unpaired samples. If the number of combinations is less than
% 20000, the algorithm calculates the exact ranks distribution; else it
% uses a normal distribution approximation. The result is not different from
% RANKSUM MatLab function, but there are more output informations.
% There is an alternative formulation of this test that yields a statistic
% commonly denoted by U. Also the U statistic is computed.
%
% Syntax: 	STATS=MWWTEST(X1,X2)
%
%     Inputs:
%           X1 and X2 - data vectors.
%     Outputs:
%           - T and U values and p-value when exact ranks distribution is used.
%           - T and U values, mean, standard deviation, Z value, and p-value when
%           normal distribution is used.
%        If STATS nargout was specified the results will be stored in the STATS
%        struct.
%
%      Example:
%
%         X1=[181 183 170 173 174 179 172 175 178 176 158 179 180 172 177];
%
%         X2=[168 165 163 175 176 166 163 174 175 173 179 180 176 167 176];
%
%           Calling on Matlab the function: mwwtest(X1,X2)
%
%           Answer is:
%
% MANN-WHITNEY-WILCOXON TEST
%
%                        Group_1    Group_2
%                        _______    _______
%
%     Numerosity          15         15
%     Sum_of_Rank_W      270        195
%     Mean_Rank           18         13
%     Test_variable_U     75        150
%
% Sample size is large enough to use the normal distribution approximation
%
%     Mean       SD        Z       p_value_one_tail    p_value_two_tails
%     _____    ______    ______    ________________    _________________
%
%     112.5    24.047    1.5386    0.061947            0.12389
%
%           Created by Giuseppe Cardillo
%           giuseppe.cardillo-edta@poste.it
%
% To cite this file, this would be an appropriate format:
% Cardillo G. (2009). MWWTEST: Mann-Whitney-Wilcoxon non parametric test for two unpaired samples.
% http://www.mathworks.com/matlabcentral/fileexchange/25830
%Input Error handling
p = inputParser;
addRequired(p,'x1',@(x) validateattributes(x,{'numeric'},{'row','real','finite','nonnan','nonempty'}));
addRequired(p,'x2',@(x) validateattributes(x,{'numeric'},{'row','real','finite','nonnan','nonempty'}));
parse(p,x1,x2);
%set the basic parameter
n1=length(x1); n2=length(x2); NP=n1*n2; N=n1+n2; N1=N+1; k=min([n1 n2]);
[A,B]=tiedrank([x1(:); x2(:)]); %compute the ranks and the ties
R1=A(1:n1); R2=A(n1+1:end);
T1=sum(R1); T2=sum(R2);
U1=NP+(n1*(n1+1))/2-T1; U2=NP-U1;
disp('MANN-WHITNEY-WILCOXON TEST')
disp(' ')
disp(table([n1;T1;T1/n1;U1],[n2;T2;T2/n2;U2],...
    'VariableNames',{'Group_1' 'Group_2'},...
    'RowNames',{'Numerosity' 'Sum_of_Rank_W' 'Mean_Rank' 'Test_variable_U'}))
if nargout
    STATS.n=[n1 n2];
    STATS.W=[T1 T2];
    STATS.mr=[T1/n1 T2/n2];
    STATS.U=[U1 U2];
end
if round(exp(gammaln(N1)-gammaln(k+1)-gammaln(N1-k))) > 20000
    mU=NP/2;
    if B==0
        sU=realsqrt(NP*N1/12);
    else
        sU=realsqrt((NP/(N^2-N))*((N^3-N-2*B)/12));
    end
    Z1=(abs(U1-mU)-0.5)/sU;
    p=1-normcdf(Z1); %p-value
    disp('Sample size is large enough to use the normal distribution approximation')
    disp(' ')
    disp(table(mU,sU,Z1,p,2*p,'VariableNames',{'Mean' 'SD' 'Z' 'p_value_one_tail' 'p_value_two_tails'}))
    if nargout
        STATS.method='Normal approximation';
        STATS.mU=mU;
        STATS.sU=sU;
        STATS.Z=Z1;
        STATS.p=[p 2*p];
    end
else
    disp('Sample size is small enough to use the exact Mann-Whitney-Wilcoxon distribution')
    disp(' ')
    if n1<=n2
        w=T1;
    else
        w=T2;
    end
    pdf=sum(nchoosek(A,k),2);
    P = [sum(pdf<=w) sum(pdf>=w)]./length(pdf);
    p = min(P);
    disp(table(w,p,2*p,'VariableNames',{'W' 'p_value_one_tail' 'p_value_two_tails'}))
    if nargout
        STATS.method='Exact distribution';
        STATS.T=w;
        STATS.p=[p 2*p];
    end
end
disp(' ')


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

% Symmetry

% 	Even symmetry

syms x t k T
w=2*pi/T;
c1=(2/T)*int(x*sin(k*w*t),t,-T/2,0);

c2=(2/T)*int(x*sin(k*w*t),t,0,T/2);
c=c1+c2

t0=-2;
T=4;
w=2*pi/T;
syms t
x=t^2;
k=-5:5;
a=(1/T)*int(x*exp(-j*k*w*t),t,t0,t0+T);
stem(k,eval(a))
legend('a_k')

% 	Odd symmetry
figure
syms x t k T
w=2*pi/T;
b1=(2/T)*int(-x*cos(k*w*t),t,-T/2,0);

b2=(2/T)*int(x*cos(k*w*t),t,0,T/2);
b=b1+b2

t0=-2;
T=4;
w=2*pi/T;
syms t
x=t;
k=-5:5;
a=(1/T)*int(x*exp(-j*k*w*t),t,t0,t0+T);

stem(k,imag(eval(a)))
legend('a_k')


function p = multivariateGaussian(X, mu, Sigma2)
%MULTIVARIATEGAUSSIAN Computes the probability density function of the
%multivariate gaussian distribution.
%    p = MULTIVARIATEGAUSSIAN(X, mu, Sigma2) Computes the probability
%    density function of the examples X under the multivariate gaussian
%    distribution with parameters mu and Sigma2. If Sigma2 is a matrix, it is
%    treated as the covariance matrix. If Sigma2 is a vector, it is treated
%    as the \sigma^2 values of the variances in each dimension (a diagonal
%    covariance matrix)
%

k = length(mu);

if (size(Sigma2, 2) == 1) || (size(Sigma2, 1) == 1)
    Sigma2 = diag(Sigma2);
end

X = bsxfun(@minus, X, mu(:)');
p = (2 * pi) ^ (- k / 2) * det(Sigma2) ^ (-0.5) * ...
    exp(-0.5 * sum(bsxfun(@times, X * pinv(Sigma2), X), 2));

end


%% Runge-Kutta 2
%
% for solving
%
% $\frac{dv}{dt}=-\alpha (t)v+\beta (t)$
%
% where $\alpha (t) = \frac{3t}{1-t}$ and $\beta (t)=2(1-t)^3 e^{-t}$
%
% Assuming v(0)=1.0 for the period 0<t<15

clc
clear
%close all

%% Discretization of t
ti=0;    % Initial Time
tf=150;   % Final Time

% Time step
% h = 0.2;
% h = 0.8;
% h = 1.1;
 h = 0.68;

% Discretization of t
i=1;
t(1)=ti;
while t(i)<tf
        i=i+1;
        t(i)=t(i-1)+h;
end
t(i)=tf; clear i;
n=length(t);

%% Discretization of v

v = zeros(n,1);
alpha = zeros(n,1);
beta  = zeros(n,1);
t2 = zeros(n,1);
alpha2 = zeros(n,1);
beta2  = zeros(n,1);

for i=1:n-1
    t2(i)     = t(i)+1/2*h;
    % compute variables alpha(t) and beta(t)
    alpha(i)  = 3*t(i)/(1+t(i));
    alpha2(i) = 3*t2(i)/(1+t2(i)); % alpha(t + 1/2h)
    beta(i)   = 2*(1+t(i))^3*exp(-t(i));
    beta2(i)  = 2*(1+t2(i))^3*exp(-t2(i)); % beta(t + 1/2h)
end

% initial condition (v(0))
v(1)=1;

for i=1:n-1
    % main discrete equation
    k1 = h*(-alpha(i)*v(i)+beta(i));
    k2 = h*(-alpha2(i)*(v(i)+1/2*k1)+beta2(i));
    v(i+1) = v(i)+k2;
end

%% Exact solution
v2 = zeros(n,1);
for i=1:n
     v2(i) = exp(-t(i))*(1+t(i))^3;
end
error=v2-v;
figure
plot(t,v,'.',t,v2,'-')
%figure
%plot(t,error,'.')


function area = polygon_area_2d_2 ( n, v )

%*****************************************************************************80
%
%% POLYGON_AREA_2D_2 computes the area of a polygon in 2D.
%
%  Discussion:
%
%    The area is the sum of the areas of the triangles formed by
%    node N with consecutive pairs of nodes.
%
%    If the vertices are given in counterclockwise order, the area
%    will be positive.  If the vertices are given in clockwise order,
%    the area will be negative.
%
%    Thanks to Martin Pineault for noticing that an earlier version
%    of this routine would not correctly compute the area of a nonconvex
%    polygon.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 October 2005
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Adrian Bowyer and John Woodwark,
%    A Programmer's Geometry,
%    Butterworths, 1983.
%
%  Parameters:
%
%    Input, integer N, the number of vertices of the polygon.
%
%    Input, real V(2,N), the coordinates of the vertices.
%
%    Output, real AREA, the area of the polygon.
%
  area = 0.0;

  for i = 1 : n - 2

    t(1:2,1:3) = [ v(1:2,i)'; v(1:2,i+1)'; v(1:2,n)' ]';

    area_triangle = triangle_area_2d ( t );

    area = area + area_triangle;

  end

  return
end


function [khs, ghs, def] = HashinShtrikmanModulus(C,Ko,Go)
% Hashin Shtrikman moduli
%
% Description
% The equations are from Peselnick and Meister 1965 through Watt and
% Peselnick 1980 which are based on Hashin and Shtrikman 1963 JMB 8/2013
%
% Syntax:
%
%   [khs, ghs, def] = HashinShtrikmanModulus(C,Ko,Go)
%
% Input
%  C  - @stiffnessTensor
%  Ko - bulk modulus of the reference isotropic material
%  Go - shear modulus of the reference isotropic material
%
% Output
%  khs - Hashin Shtrikman bulk modulus
%  ghs - Hashin Shtrikman shear modulus
%  def - +1 positive definite, -1 for negative definite R
%

% ensure K0 and G0 have same size
if numel(Go) == 1, Go = repmat(Go,size(Ko)); end

% the isotropic compliances elements (eq. 10-11 Watt Peselnick 1980)
alpha = -3 ./ (3*Ko + 4*Go);
beta = -3 * (Ko + 2*Go) ./ ( 5*Go .* (3*Ko + 4*Go) );
gamma = (alpha - 3 * beta) ./ 9;

% define the isotropic tensor corresponding to Ko and Go
Co = 2 * Go .* stiffnessTensor.eye + (Ko - 2/3 * Go) .* dyad(tensor.eye,tensor.eye);

% take difference between anisotropic and isotropic matrices and take
% inverse to get the residual compliance matrix (eq 4 & 8 Watt Peselnick 1980)
R = C - Co;
H = inv(R);

% Subtract the isotropic compliances from the residual compliance matrix
% and invert back to moduli space.  The matrix B is the moduli matrix that
% when multiplied by the strain difference between the reference isotropic
% response and the isotropic response of the actual material gives the
% average stres <pij> (eq 15 - 16 Watt Peselnick 1980).
A = H - beta .* complianceTensor.eye - gamma .* dyad(tensor.eye,tensor.eye);
B = inv(A);

% now perform the averaging of the B matrix to get two numbers (B1 and B2)
% that are related to the two isotropic moduli - perturbations of the
% reference values (eq 21 and 22 Watt Peselnick 1980)
sB1 = EinsteinSum(B,[-1 -1 -2 -2]);
sB2 = EinsteinSum(B,[-1 -2 -1 -2]);

B1 = (2*sB1 - sB2) / 15;
B2 = (3*sB2 - sB1) / 30;

% The Hashin-Shtrikman moduli are then calculated as changes from the
% reference isotropic body. (eq 25 & 27 Watt and Peselnick 1980)
khs = Ko + ( 3 * B1 + 2 * B2 ) ./ ( 3 + alpha .* (3 * B1 + 2 * B2) );
ghs = Go + B2 ./ ( 1 + 2 * beta .* B2 );

% The moduli are valid in two limits - minimizing or maximizing the
% anisotropic difference elastic energy. Think of it as the maximum
% positive deviations from the reference state or the maximum negative
% deviations from the reference state. These are either in the positive
% definite or negative definite regime of the matrix R. Here is a test of
% the properties of R.  A +1 is returned if positive definite, a -1 is
% retunred if negative definite.  0 returned otherwise.

def = zeros(size(R));
D = eig(R);
def(all(D>0,1)) = 1;
def(all(D<0,1)) = -1;

% isf minmax == 0 this means ...
khs(def==0) = NaN;
ghs(def==0) = NaN;


function [A, b] = sllinrega(X, Y, varargin)
%SLLINREGA Performs Augmented Multivariate Linear Regression
%
% $ Syntax $
%   - [A, b] = sllinrega(X, Y, ...)
%
% $ Arguments $
%   - X:        The sample matrix of x
%   - Y:        The sample matrix of y
%   - A:        The solved transform matrix
%   - b:        The solved shift vector
%
% $ Description $
%   - [A, b] = sllinrega(X, Y, ...) solves the regression problem given
%     by the following formula:
%           y = A * x + b
%     in least square error sense. The samples are stored in X and Y
%     in column-wise manner.
%     You can specify properties for regression as in sllinreg.
%
% $ Remarks $
%   - The implementation is based on sllinreg with an augmented
%     formulation as follows:
%           y = [A, b] * [x; 1]
%
% $ History $
%   - Created by Dahua Lin, on Sep 15th, 2006
%

%% parse and verify input arguments

if nargin < 2
    raise_lackinput('sllinrega', 2);
end

if ~isnumeric(X) || ~isnumeric(Y) || ndims(X) ~= 2 || ndims(Y) ~= 2
    error('sltoolbox:invalidarg', ...
        'The X and Y should be both 2D numeric matrices');
end

%% main

% augment formulation
[dx, nx] = size(X);
Xa = [X; ones(1, nx)];

% solve
Aa = sllinreg(Xa, Y, varargin{:});
clear Xa;

% extract
A = Aa(:, 1:dx);
b = Aa(:, dx+1);


function y = compute_orthogonal_projection( x, A, C )

% compute_orthogonal_projection - computer orthogonal projection
%
%   y = compute_orthogonal_projection( x, A, C );
%
%   y is the pojection of x onto the intersection of the sets
%       { y \ <x-cj,aj>=0 }
%   where the cj and the aj are the columns of C and A.
%
%   Copyright (c) 2007 Gabriel Peyre

% compute solution as
%   y = x + A*lambda

D = (A'*A);
if abs(det(D))<1e-9
    D = D+rand(size(D))*1e-9;
end
lambda = D \ ( -A'*x + diag(A'*C) );
y = x + A*lambda;


clear all; close all;
figure(1)
% underdetermined
n=20; m=100
A=rand(n,m); b=rand(n,1);

cvx_begin;
variable x2(m)
minimize( norm(x2,2) );
subject to
A*x2 == b;
cvx_end;

cvx_begin;
variable x1(m)
minimize( norm(x1,1) );
subject to
A*x1 == b;
cvx_end;

subplot(3,1,1), bar(x2)
subplot(3,1,2), bar(x1)
subplot(3,2,5), hist(x2,40)
subplot(3,2,6), hist(x1,40)

subplot(3,1,1), axis([0 100 -.2 .2]), subplot(3,1,2), axis([0 100 -.4 .4])
subplot(3,2,5), axis([-.15 .15 0 82]), set(gca,'Ytick',[0 40 80],'Xtick',[-0.1 0 0.1])
h = findobj(gca,'Type','patch'); h.FaceColor = [0.6 0.6 0.6]; h.EdgeColor = 'k';
subplot(3,2,6), axis([-.15 .15 0 82]), set(gca,'Ytick',[0 40 80],'Xtick',[-0.1 0 0.1])
h = findobj(gca,'Type','patch'); h.FaceColor = [0.6 0.6 0.6]; h.EdgeColor = 'k';

%%
clear A
clear b
clear x
figure(2)

% overdetermined
n=500; m=100;
A=rand(n,m);
b=rand(n,1);
xdag=pinv(A)*b;

lam=[0 0.1 0.5];
for j=1:3

    cvx_begin;
    variable x(m)
    minimize( norm(A*x-b,2) + lam(j)*norm(x,1) );
    cvx_end;

    subplot(4,1,j),bar(x)
    subplot(4,3,9+j), hist(x,20)
end

for j=1:3

    subplot(4,1,j), axis([0 100 -.15 .15])
    subplot(4,3,9+j), axis([-.15 .15 0 80]), set(gca,'Ytick',[0 40 80])
    h = findobj(gca,'Type','patch');
    h.FaceColor = [0.6 0.6 0.6];
    h.EdgeColor = 'k';
end

%%
% matrix overdetermined system

clear A
clear b
clear x
figure(3)

% overdetermined
n=300; m=60; p=20;
A=rand(n,m); b=rand(n,p);

lam=[0 0.1];
for j=1:2
    cvx_begin;
    variable x(m,p)
    minimize(norm(A*x-b,2) + lam(j)*norm(x,1));
    cvx_end;
    subplot(2,1,j), pcolor(x.'), colormap(hot), colorbar
end

%%
subplot(2,1,1), set(gca,'Fontsize',[15],'Xtick',[1 20 40 60],'Ytick',[1 10 20])
subplot(2,1,2), set(gca,'Fontsize',[15],'Xtick',[1 20 40 60],'Ytick',[1 10 20])


function hsi = rgb2hsi(rgb)
%RGB2HSI Converts an RGB image to HSI.
%   HSI = RGB2HSI(RGB) converts an RGB image to HSI. The input image is
%   assumed to be of size M-by-N-by-3, where the third dimension
%   accounts for three image planes: red, green, and blue, in that
%   order. If all RGB component images are equal, the HSI conversion is
%   undefined. The input image can be of class double (with values in
%   the range [0, 1]), uint8, or uint16.
%
%   The output image, HSI, is of class double, where:
%     HSI(:,:,1) = hue image normalized to the range [0,1] by dividing
%                  all angle values by 2*pi.
%     HSI(:,:,2) = saturation image, in the range [0,1].
%     HSI(:,:,3) = intensity image, in the range [0,1].
%
%   All the conversion equations are explained in Chapter 7 of DIPUM3E.
%
%   Copyright 2002-2020 Gatesmark
%
%   This function, and other functions in the DIPUM Toolbox, are based
%   on the theoretical and practical foundations established in the
%   book Digital Image Processing Using MATLAB, 3rd ed., Gatesmark
%   Press, 2020.
%
%   Book website: http://www.imageprocessingplace.com
%   License: https://github.com/dipum/dipum-toolbox/blob/master/LICENSE.txt

% Extract the individual component images.
rgb = im2double(rgb);
r = rgb(:,:,1);
g = rgb(:,:,2);
b = rgb(:,:,3);

% Implement the conversion equations.
num = 0.5*((r - g) + (r - b));
den = sqrt((r - g).^2 + (r - b).*(g - b));
theta = acos(num./(den + eps));

H = theta;
H(b > g) = 2*pi - H(b > g);
H = H/(2*pi);

num = min(min(r,g),b);
den = r + g + b;
den(den == 0) = eps;
S = 1 - 3.* num./den;

H(S == 0) = 0;

I = (r + g + b)/3;

% Combine all three results into an hsi image.
hsi = cat(3,H,S,I);


function dist = segment_point_dist_2d ( p1, p2, p )

%*****************************************************************************80
%
%% SEGMENT_POINT_DIST_2D: distance ( line segment, point ) in 2D.
%
%  Discussion:
%
%    A line segment is the finite portion of a line that lies between
%    two points.
%
%    The nearest point will satisfy the condition
%
%      PN = (1-T) * P1 + T * P2.
%
%    T will always be between 0 and 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 December 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real P1(2,1), P2(2,1), the endpoints of the line segment.
%
%    Input, real P(2,1), the point whose nearest neighbor on the line
%    segment is to be determined.
%
%    Output, real DIST, the distance from the point to the line segment.
%

%
%  If the line segment is actually a point, then the answer is easy.
%
  if ( p1(1:2,1) == p2(1:2,1) )

    t = 0.0;

  else

    bot = sum ( ( p2(1:2,1) - p1(1:2,1) ).^2 );

    t = ( p(1:2,1) - p1(1:2,1) )' * ( p2(1:2,1) - p1(1:2,1) ) / bot;

    t = max ( t, 0.0 );
    t = min ( t, 1.0 );

  end

  pn(1:2,1) = p1(1:2,1) + t * ( p2(1:2,1) - p1(1:2,1) );

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

  return
end


function [C, sigma] = dataset3Params(X, y, Xval, yval)
%EX6PARAMS returns your choice of C and sigma for Part 3 of the exercise
%where you select the optimal (C, sigma) learning parameters to use for SVM
%with RBF kernel
%   [C, sigma] = EX6PARAMS(X, y, Xval, yval) returns your choice of C and
%   sigma. You should complete this function to return the optimal C and
%   sigma based on a cross-validation set.
%

% You need to return the following variables correctly.
C = 1;
sigma = 0.3;

% ====================== YOUR CODE HERE ======================
% Instructions: Fill in this function to return the optimal C and sigma
%               learning parameters found using the cross validation set.
%               You can use svmPredict to predict the labels on the cross
%               validation set. For example,
%                   predictions = svmPredict(model, Xval);
%               will return the predictions on the cross validation set.
%
%  Note: You can compute the prediction error using
%        mean(double(predictions ~= yval))
%

steps = [ 0.01 0.03 0.1 0.3 1 3 10 30 ];
minError = Inf;
minC = Inf;
minSigma = Inf;

for i = 1:length(steps)
    for j = 1:length(steps)
        currentC = steps(i);
        currentSigma = steps(j);
        model = svmTrain(X, y, currentC, @(x1, x2) gaussianKernel(x1, x2, currentSigma));
        predictions = svmPredict(model, Xval);
        error = mean(double(predictions ~= yval));

        if error < minError
            minError = error;
            minC = currentC;
            minSigma = currentSigma;
        end
    end
end

C = minC;
sigma = minSigma;

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

end


function [pgx,pgy,area,perim] = minboundparallelogram(x,y,metric)
% minboundparallelogram: Compute the minimal bounding parallelogram of points in the plane
% usage: [pgx,pgy,area,perimeter] = minboundparallelogram(x,y,metric)
%
% While minboundrect allows you to choose between a minimal area or
% perimeter, it turns out that the minimal area paralellogram is not
% always unique. However, there will exist a unique parallelogram of
% minimal perimeter.
%
% arguments: (input)
%  x,y - vectors of points, describing points in the plane as
%        (x,y) pairs. x and y must be the same lengths.
%
%  metric - (OPTIONAL) - single letter character flag which
%        denotes the use of minimal area or perimeter as the
%        metric to be minimized. metric may be either 'a' or 'p',
%        capitalization is ignored. Any other contraction of 'area'
%        or 'perimeter' is also accepted.
%
%        DEFAULT: 'a'    ('area')
%
% arguments: (output)
%  pgx,pgy - 5x1 vectors of points that define the minimal
%        bounding parallelogram.
%
%  area - (scalar) area of the minimal parallelogram itself.
%
%  perimeter - (scalar) perimeter of the minimal parallelogram as found
%
%
% Example usage:
%  x = rand(50000,1);
%  y = rand(50000,1);
%  tic,[px,py,area,perim] = minboundparallelogram(x,y);toc
%
%  Elapsed time is 0.083340 seconds.
%
% [px,py]
% ans =
%       8.73336658824275e-05      3.51448852413649e-05
%           1.00002616513798       3.7428827532671e-05
%          0.999923888887252         0.999977663164396
%      -1.49425848464391e-05         0.999975379222104
%       8.73336658824275e-05      3.51448852413649e-05
%
% area
% area =
%          0.999879069698332
%
% perim
% perim =
%            3.9997581420842
%
%
% See also: minboundcircle, minboundtri, minboundrect
%
%
% Author: John D'Errico
% E-mail: woodchips@rochester.rr.com
% Release: 1.0
% Release date: 8/19/2010

% default for metric
if (nargin<3) || isempty(metric)
  metric = 'a';
elseif ~ischar(metric)
  error('metric must be a character flag if it is supplied.')
else
  % check for 'a' or 'p'
  metric = lower(metric(:)');
  ind = strmatch(metric,{'area','perimeter'});
  if isempty(ind)
    error('metric does not match either ''area'' or ''perimeter''')
  end

  % just keep the first letter.
  metric = metric(1);
end

% preprocess data
x=x(:);
y=y(:);

% not many error checks to worry about
n = length(x);
if n~=length(y)
  error('x and y must be the same sizes')
end

% start out with the convex hull of the points to
% reduce the problem dramatically. Note that any
% points in the interior of the convex hull are
% never needed, so we drop them.
if n>3
  edges = convhull(x,y);  % 'Pp' will silence the warnings

  % exclude those points inside the hull as not relevant
  % also sorts the points into their convex hull as a
  % closed polygon

  x = x(edges(1:(end-1)));
  y = y(edges(1:(end-1)));

  % probably fewer points now, unless the points are fully convex
  nedges = length(x) - 1;

elseif n > 1
  % n must be 2 or 3
  nedges = n;
  x(end+1) = x(1);
  y(end+1) = y(1);
else
  % n must be 0 or 1
  nedges = n;
end

% now we must find the bounding parallelogram of those
% that remain.

% special case small numbers of points. If we trip any
% of these cases, then we are done, so return.
switch nedges
  case 0
    % empty begets empty
    pgx = [];
    pgy = [];
    area = [];
    perimeter = [];
    return
  case 1
    % with one point, the rect is simple.
    pgx = repmat(x,1,5);
    pgy = repmat(y,1,5);
    area = 0;
    perimeter = 0;
    return
  case 2
    % only two points. also simple.
    pgx = x([1 2 2 1 1]);
    pgy = y([1 2 2 1 1]);
    area = 0;
    perimeter = 2*sqrt(diff(x).^2 + diff(y).^2);
    return
end
% 3 or more points.

% will need a 2x2 rotation matrix through an angle theta
Rmat = @(theta) [cos(theta) sin(theta);-sin(theta) cos(theta)];

% get the angle of each edge of the hull polygon.
nx = length(x);
ind1 = 1:nx;
ind2 = circshift(ind1,[0 -1]);
edgeangles = atan2(y(ind2) - y(ind1),x(ind2) - x(ind1));
% move the angle to be in [0,pi).
edgeangles = mod(edgeangles,pi);

% now just check each edge of the convex hull
nang = length(edgeangles);
area = inf;
perim = inf;
met = inf;
xy = [x,y];
for i = 1:nang
  % line that defines the base of the parallelogram
  p1 = xy(i,:);

  % we will rotate and translate the points so this
  % edge lies on the x axis. The rotation matrix is...
  rot = Rmat(-edgeangles(i));
  xyr = (xy - repmat(p1,nx,1))*rot;

  % the height of the parallelogram is
  if max(xyr(:,2)) >= max(-xyr(:,2))
    pgheight = max(xyr(:,2));
  else
    pgheight = min(xyr(:,2));
  end

  % rotate everything, but keep the angles in the interval [0,pi)
  anglesr = mod(edgeangles - edgeangles(i),pi);

  % what are the smallest and largest possible angles of the
  % remaining edges? This will define the limits of where the
  % secondary sides of the bounding parallelogram may lie.
  anglesr(i) = [];
  anglesr(anglesr == 0) = [];
  anglebounds = [min(anglesr), max(anglesr)];

  % use fminbnd to search over the family of parallelograms with
  % the given base.
  sideang = fminbnd(@(ang) pgramobj(ang,xyr,pgheight),anglebounds(1),anglebounds(2));

  % get the final parallelogram
  [pmin,amin,pgxy] = pgramobj(sideang,xyr,pgheight);

  if metric=='a'
    M_i = amin;
  else
    M_i = pmin;
  end

  % A new metric value for the current interval.
  % Is it better than the previous best?
  if M_i < met
    % keep this one
    met = M_i;
    area = amin;
    perim = pmin;

    % recover the parallelogram in the original coordinate system
    pgxy = pgxy*rot' + repmat(p1,5,1);

    pgx = pgxy(:,1);
    pgy = pgxy(:,2);

%    plot(x,y,'kx',pgx,pgy,'-ro')
%    title(num2str([perim,area]))
%    axis equal
%    pause

  end
end

% all done
% plot(x,y,'kx',pgx,pgy,'-ro')
% title(num2str([perim,area]))
% axis equal

% =================================================================
function [perim,area,pgxy] = pgramobj(ang,xyr,pgheight)
%  For a given angle (in radians) computes the bounding
%  parallelogram where the base is assumed to lie on the
%  x axis. Thus the upper face must be parallel to the x axis.

% ang will always be in the open interval (0,pi)

% The vector that points along the sides will be
sidevec = [cos(ang),sin(ang)];

% for this value of ang, what is the normal vector to
% that side of the parallelogram? It always points in
% the positive x direction, by the way it is constructed.
nvec = [sin(ang);-cos(ang)];

% What is the left most point that a side will hit against?
% The rightmost? get that information from a dot product of
% the points with the normal vector of the sides.
dp = xyr*nvec;
leftmost = min(dp);
rightmost = max(dp);

% a point on the line that contains the left side of the
% parallelogram is
leftpoint = leftmost*nvec.';

% and the right hand side line passes through this point.
rightpoint = rightmost*nvec.';

% we can define each line by the parametric equations
%  Pleft(t) = leftpoint + t*sidevec
%  Pright(t) = rightpoint + s*sidevec
%
% now find the values of s and t, such that those lines
% intersect the x axis (thus y == 0)
t0 = -leftpoint(2)./sidevec(2);
s0 = -rightpoint(2)./sidevec(2);

% the actual x axis intercepts are at
x1 = leftpoint(1) + t0*sidevec(1);
x2 = rightpoint(1) + s0*sidevec(1);

% the length of a side of the parallelogram is given by the
% definition of the trig function from triangle sides.
sidelength = pgheight./cos(pi/2 - ang);
baselength = abs(x2 - x1);

% so the perimeter of the parallellogram is given by
perim = 2*(abs(sidelength) + baselength);

% don't bother to do these unless necessary
if nargout > 1
  % the area is also trivial to compute, as
  area = abs(pgheight)*baselength;

  % and the vertices of the parallelogram are
  pgxy = [[x1,0]; [x2,0]; ...
    [x2,0] + sidelength*sidevec ; ...
    [x1,0] + sidelength*sidevec ; ...
    [x1,0]];

end


function [xi,w]=thirdOrderCrossPolyCubPoints(numDim,algorithm)
%%THIRDORDERCROSSPOLYCUBPOINTS Generate third order cubature points for
%               integration over the region sum(abs(x))<=1 with weighting
%               function w(x)=1. In two dimensions, this is a square, in
%               three an octohedron, in n a cross polytope (or
%               n-dimensional octahedron).
%
%INPUTS: numDim An integer specifying the dimensionality of the points to
%               be generated.
%     algorithm A value indicating which algorithm should be used. Possible
%               values are:
%               0 (The default if omitted or an empty matrix is passed)
%                 Formula G_n 3-1 in [1], pg. 304, 2*numDim points.
%               1 Formula G_n 3-2 in [1], pg. 304, 2^numDim points,
%                 numDim<4.
%
%OUTPUTS: xi A numDim X numCubaturePoints matrix containing the cubature
%            points. (Each "point" is a vector)
%          w A numCubaturePoints X 1 vector of the weights associated with
%            the cubature points.
%
%REFERENCES:
%[1] A.H. Stroud, Approximate Calculation of Multiple Integrals. Cliffs,
%    NJ: Prentice-Hall, Inc., 1971.
%
%November 2015 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release

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

switch(algorithm)
    case 0%G_n 3-1 in [1], pg. 304, 2*numDim points.
        V=exp(numDim*log(2)-gammaln(numDim+1));
        n=numDim;

        r=sqrt(2*n/((n+1)*(n+2)));

        w=V/(2*n)*ones(2*n,1);
        xi=fullSymPerms([r;zeros(numDim-1,1)]);
    case 1%G_n 3-2 in [1], pg. 304, 2^numDim points, numDim<4.
        if(numDim>=4)
           error('This algorithm requires numDim<4')
        end

        V=exp(numDim*log(2)-gammaln(numDim+1));
        n=numDim;

        r=sqrt(2/((n+1)*(n+2)));

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

%*****************************************************************************80
%
%% POLYGON_AREA_2 computes the area of a polygon.
%
%  Discussion:
%
%    The area is the sum of the areas of the triangles formed by
%    node N with consecutive pairs of nodes.
%
%    If the vertices are given in counterclockwise order, the area
%    will be positive.  If the vertices are given in clockwise order,
%    the area will be negative.
%
%    Thanks to Martin Pineault for noticing that an earlier version
%    of this routine would not correctly compute the area of a nonconvex
%    polygon.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 May 2014
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Adrian Bowyer, John Woodwark,
%    A Programmer's Geometry,
%    Butterworths, 1983.
%
%  Parameters:
%
%    Input, integer N, the number of vertices of the polygon.
%
%    Input, real V(2,N), the coordinates of the vertices.
%
%    Output, real AREA, the area of the polygon.
%
  area = 0.0;

  for i = 1 : n - 2

    area_triangle = triangle_area ( ...
      v(1,i),   v(2,i),   ...
      v(1,i+1), v(2,i+1), ...
      v(1,n),   v(2,n) );

    area = area + area_triangle;

  end

  return
end


function f = make_gaussian_filter(sigma, cutoff)
%MAKE_GAUSSIAN_FILTER   Create Gaussian filter
%   MAKE_GAUSSSIAN_FILTER(SIGMA[, CUTOFF]) creates a Gaussian filter with
%   standard deviation SIGMA.  The filter mask is cut off at CUTOFF times
%   the standard deviation.  If CUTOFF is omitted, a default value of 3
%   is assumed.
%
%   See also FSPECIAL.
%
%   Author:  Stefan Roth, Department of Computer Science, TU Darmstadt
%   Contact: sroth@cs.tu-darmstadt.de
%   $Date$
%   $Revision$

% Copyright 2004-2007, Brown University, Providence, RI. USA
% Copyright 2007-2010 TU Darmstadt, Darmstadt, Germany.
%
%                          All Rights Reserved
%
% All commercial use of this software, whether direct or indirect, is
% strictly prohibited including, without limitation, incorporation into in
% a commercial product, use in a commercial service, or production of other
% artifacts for commercial purposes.
%
% Permission to use, copy, modify, and distribute this software and its
% documentation for research purposes is hereby granted without fee,
% provided that the above copyright notice appears in all copies and that
% both that copyright notice and this permission notice appear in
% supporting documentation, and that the name of the author and Brown
% University not be used in advertising or publicity pertaining to
% distribution of the software without specific, written prior permission.
%
% For commercial uses contact the Technology Venture Office of Brown University
%
% THE AUTHOR AND BROWN UNIVERSITY DISCLAIM ALL WARRANTIES WITH REGARD TO
% THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
% FITNESS FOR ANY PARTICULAR PURPOSE.  IN NO EVENT SHALL THE AUTHOR OR
% BROWN UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
% DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
% PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
% ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
% THIS SOFTWARE.

  if (nargin < 2)
    cutoff = 3;
  end

  sz = ceil(cutoff * sigma);

  f = exp(-(-sz:sz).^2 / (2*sigma^2));
  f = f ./ sum(f);


function g = localthresh(f, nhood, a, b, meantype)
%LOCALTHRESH Local thresholding.
%	G = LOCALTHRESH(F, NHOOD, A, B, MEANTYPE) thresholds image F by
%	computing a local threshold at the center,(x, y), of every
%	neighborhood in F. The size of the neighborhoods is defined by
%	NHOOD, an array of zeros and ones in which the nonzero elements
%	specify the neighbors used in the computation of the local mean
%	and standard deviation. The size of NHOOD must be odd in both
%	dimensions.
%
%	The segmented image is given by
%
%           1  if (F > A*SIG) AND (F > B*MEAN)
%       G =
%           0  otherwise
%
%	where SIG is an array of the same size as F containing the local
%	standard deviations. If MEANTYPE = 'local' (the default), then
%	MEAN is an array of local means.  If MEANTYPE = 'global', then
%	MEAN is the global (image) mean, a scalar.  Constants A and B
%	are nonnegative scalars.
%
%   Copyright 2002-2020 Gatesmark
%
%   This function, and other functions in the DIPUM Toolbox, are based
%   on the theoretical and practical foundations established in the
%   book Digital Image Processing Using MATLAB, 3rd ed., Gatesmark
%   Press, 2020.
%
%   Book website: http://www.imageprocessingplace.com
%   License: https://github.com/dipum/dipum-toolbox/blob/master/LICENSE.txt

% Intialize.
f = tofloat(f);

% Compute the local standard deviations.
SIG = stdfilt(f, nhood);
% Compute MEAN.
if nargin == 5 && strcmp(meantype,'global')
   MEAN = mean2(f);
else
   MEAN = localmean(f, nhood); % This is a custom function.
end

% Obtain the segmented image.
g = (f > a*SIG) & (f > b*MEAN);


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

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

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

% for i=1: size(X,1);
%   x = X(i, :)';
%   for k=1: K;
%     Z(i, k) = x' * U(:, k);
%   end
% end

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

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

end


function [ r, pc ] = tetrahedron_insphere_3d ( tetra )

%*****************************************************************************80
%
%% TETRAHEDRON_INSPHERE_3D finds the insphere of a tetrahedron in 3D.
%
%  Discussion:
%
%    The insphere of a tetrahedron is the inscribed sphere, which touches
%    each face of the tetrahedron at a single point.
%
%    The points of contact are the centroids of the triangular faces
%    of the tetrahedron.  Therefore, the point of contact for a face
%    can be computed as the average of the vertices of that face.
%
%    The sphere can then be determined as the unique sphere through
%    the four given centroids.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 December 2010
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Philip Schneider, David Eberly,
%    Geometric Tools for Computer Graphics,
%    Elsevier, 2002,
%    ISBN: 1558605940,
%    LC: T385.G6974.
%
%  Parameters:
%
%    Input, real TETRA(3,4), the vertices of the tetrahedron.
%
%    Output, real R, PC(3,1), the radius and the center
%    of the sphere.
%
  dim_num = 3;

  v21(1:dim_num,1) = tetra(1:dim_num,2) - tetra(1:dim_num,1);
  v31(1:dim_num,1) = tetra(1:dim_num,3) - tetra(1:dim_num,1);
  v41(1:dim_num,1) = tetra(1:dim_num,4) - tetra(1:dim_num,1);
  v32(1:dim_num,1) = tetra(1:dim_num,3) - tetra(1:dim_num,2);
  v42(1:dim_num,1) = tetra(1:dim_num,4) - tetra(1:dim_num,2);
  v43(1:dim_num,1) = tetra(1:dim_num,4) - tetra(1:dim_num,3);

  n123 = r8vec_cross_product_3d ( v21, v31 );
  n124 = r8vec_cross_product_3d ( v41, v21 );
  n134 = r8vec_cross_product_3d ( v31, v41 );
  n234 = r8vec_cross_product_3d ( v42, v32 );

  l123 = norm ( n123 );
  l124 = norm ( n124 );
  l134 = norm ( n134 );
  l234 = norm ( n234 );

  pc(1:dim_num,1) = ( l234 * tetra(1:dim_num,1)   ...
                    + l134 * tetra(1:dim_num,2)   ...
                    + l124 * tetra(1:dim_num,3)   ...
                    + l123 * tetra(1:dim_num,4) ) ...
                  / ( l234 + l134 + l124 + l123 );

  b(1:dim_num,1:4) = tetra(1:dim_num,1:4);
  b(4,1:4) = 1.0;

  gamma = abs ( r8mat_det_4d ( b ) );

  r = gamma / ( l234 + l134 + l124 + l123 );

  return
end


function cdf = log_series_cdf ( x, a )

%*****************************************************************************80
%
%% LOG_SERIES_CDF evaluates the Logarithmic Series CDF.
%
%  Discussion:
%
%    Simple summation is used, with a recursion to generate successive
%    values of the PDF.
%
%    Thanks to Oscar van Vlijmen.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 December 1999
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer X, the argument of the PDF.
%    0 < X
%
%    Input, real A, the parameter of the PDF.
%    0.0 < A < 1.0.
%
%    Output, real CDF, the value of the CDF.
%
  cdf = 0.0;

  for x2 = 1 : x

    if ( x2 == 1 )
      pdf = - a / log ( 1.0 - a );
    else
      pdf = ( x2 - 1 ) * a * pdf / x2;
    end

    cdf = cdf + pdf;

  end

  return
end


function [A,b,x] = shaw(n)
%SHAW Test problem: one-dimensional image restoration model.
%
% [A,b,x] = shaw(n)
%
% Discretization of a first kind Fredholm integral equation with
% [-pi/2,pi/2] as both integration intervals.  The kernel K and
% the solution f, which are given by
%    K(s,t) = (cos(s) + cos(t))*(sin(u)/u)^2
%    u = pi*(sin(s) + sin(t))
%    f(t) = a1*exp(-c1*(t - t1)^2) + a2*exp(-c2*(t - t2)^2) ,
% are discretized by simple quadrature to produce A and x.
% Then the discrete right-hand b side is produced as b = A*x.
%
% The order n must be even.

% Reference: C. B. Shaw, Jr., "Improvements of the resolution of
% an instrument by numerical solution of an integral equation",
% J. Math. Anal. Appl. 37 (1972), 83-112.

% Per Christian Hansen, IMM, 08/20/91.

% Check input.
if (rem(n,2)~=0), error('The order n must be even'), end

% Initialization.
h = pi/n; A = zeros(n,n);

% Compute the matrix A.
co = cos(-pi/2 + (.5:n-.5)*h);
psi = pi*sin(-pi/2 + (.5:n-.5)*h);
for i=1:n/2
  for j=i:n-i
    ss = psi(i) + psi(j);
    A(i,j) = ((co(i) + co(j))*sin(ss)/ss)^2;
    A(n-j+1,n-i+1) = A(i,j);
  end
  A(i,n-i+1) = (2*co(i))^2;
end
A = A + triu(A,1)'; A = A*h;

% Compute the vectors x and b.
a1 = 2; c1 = 6; t1 =  .8;
a2 = 1; c2 = 2; t2 = -.5;
if (nargout>1)
  x =   a1*exp(-c1*(-pi/2 + (.5:n-.5)'*h - t1).^2) ...
      + a2*exp(-c2*(-pi/2 + (.5:n-.5)'*h - t2).^2);
  b = A*x;
end


% QP test problem. Demo file
%
clc;

disp('----------------------------------');
disp('Problem #1:');
disp(' ');
disp('min x1^2 + x^2  - 3*x1 - 1/4*x2');
disp(' ');
disp('subject to');
disp(' |x1|+|x2| <= 1');
disp('----------------------------------');

H=2*eye(2);
q=[-3,-1/4]';
A=[1 1;1 -1;-1 1;-1 -1];
b=ones(4,1);

[x, obj, lambda, info] = qpng (H, q, A, b)

pause;
clc

disp('----------------------------------');
disp('Problem #2:');
disp(' ');
disp('min 4*x1^2 + 1 x1*x2 + 4*x2^2 + 3*x1 ? 4*x2');
disp(' ');
disp('s.t. x1+x2 <= 5');
disp('     x1-x2 == 0');
disp('     x1 >= 0');
disp('     x2 >= 0');
disp('----------------------------------');

H=[8 1;1 8];
q=[3 -4]';
A=[1 1; 1 -1];
b=[5 0]';
ctype=char(['U', 'E']');
lb=[0 0]';
ub=[];

[x, obj, lambda, info] = qpng (H, q, A, b,ctype,lb,ub)

pause;
clc

disp('----------------------------------');
disp('Problem #3:');
disp(' ');
disp('min .5*x1''*H*x + q''*x');
disp(' ');
disp('s.t. -2.5 <= x1 <= 2.5');
disp('----------------------------------');

H=[.16 -1.2 2.4 -1.4;
   -1.2 12.0 -27.0 16.8;
   2.4 -27.0 64.8 -42.0;
   -1.4 16.8 -42.0 28.0];
q=[5.04 -59.4 146.4 -96.6]';
A=[-1 0 0 0; 1 0 0 0];
b=[2.5; 2.5];

[x, obj, lambda, info] = qpng (H, q, A, b)

pause;
clc

disp('----------------------------------');
disp('Problem #4:');
disp(' Solve a portfolio example. ');
disp(' See Section 13.7 of "Applications of optimization with Xpress-MP.');
disp('----------------------------------');

H=[4 3 -1 0;
   3 6 1 0;
   -1 1 10 0;
   0 0 0 10];
q=[];
A=[1 1 1 1;
   8 9 12 7];
b=[1; 7];
ctype=char(['E', 'L']');
lb=zeros(4,1);
ub=[];

[x, obj, lambda, info] = qpng (H, q, A, b, ctype, lb, ub)

pause;
clc

disp('----------------------------------');
disp('Problem #5:');
disp(' An indefinite QP problem is not solved x*=(3, 25/4). ');
disp(' ');
disp('min .5*x1^2 - .5*x2^2');
disp(' ');
disp('s.t. x2 >= 0');
disp('s.t. x1+x2 >= 2');
disp('s.t. -5x1+4x2 <= 10');
disp('s.t. x1 <= 3');
disp('----------------------------------');

H=[1 0;0 -1];
q=[];
A=[0 1;1 2;-5 4;1 0];
b=[0 2 10 3]';
ctype=char(['L', 'L', 'U', 'U']);

[x, obj, lambda, info]=qpng(H, q, A, b)


function [r, c] = partial_corr_coef(S, i, j, Y)
% PARTIAL_CORR_COEF Compute a partial correlation coefficient
% [r, c] = partial_corr_coef(S, i, j, Y)
%
% S is the covariance (or correlation) matrix for X, Y, Z
% where X=[i j], Y is conditioned on, and Z is marginalized out.
% Let S2 = Cov[X | Y] be the partial covariance matrix.
% Then c = S2(i,j) and r = c / sqrt( S2(i,i) * S2(j,j) )
%

% Example: Anderson (1984) p129
% S = [1.0 0.8 -0.4;
%     0.8 1.0 -0.56;
%     -0.4 -0.56 1.0];
% r(1,3 | 2) = 0.0966
%
% Example: Van de Geer (1971) p111
%S = [1     0.453 0.322;
%     0.453 1.0   0.596;
%     0.322 0.596 1];
% r(2,3 | 1) = 0.533

X = [i j];
i2 = 1; % find_equiv_posns(i, X);
j2 = 2; % find_equiv_posns(j, X);
S2 = S(X,X) - S(X,Y)*inv(S(Y,Y))*S(Y,X);
c = S2(i2,j2);
r = c / sqrt(S2(i2,i2) * S2(j2,j2));


function [x,gpd,nu]=gdpower(N,k,c)
%GDPOWER Signal with power-law group delay.
%	[X,GPD,F]=GDPOWER(N,K,C) generates a signal with a
%	power-law group delay of the form tx(f) = T0 + C*f^(K-1).
%	The output signal is of unit energy.
%
%	N   : number of points in time		(must be even)
%	K   : degree of the power-law		(default : 0)
%	C   : rate-coefficient of the power-law group delay.
%	      C must be non-zero. 		(default : 1)
%	X   : time row vector containing the modulated signal samples
%	GPD : group delay	      (length : round(N/2)-1)
%	F   : frequency bins
%
%	Examples :
%	 sig=gdpower(64,0); tfrbert(sig,1:64,0.01,0.32,256,1);
%	 [sig,gpd,f]=gdpower(256,1/2); plot(gpd,f);
%
%	See also FMPOWER.

%	O. Lemoine - April, July 1996
%	Copyright (c) 1996 by CNRS (France).
%
%  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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

if (nargin < 1),
 error ( 'At least one parameter.' );
elseif nargin==1,
 k=0; c=1;
elseif nargin==2,
 c=1;
end

if (N <= 0),
 error ('The signal length N must be strictly positive' );
end

t0=0;

Lnu=round(N/2);
nu=linspace(0,0.5,Lnu+1); nu=nu(2:Lnu+1);
AM=nu.^((k-2)/6);

if c==0,
 error('C must be non-zero');
end

t=1:N;
TFx=zeros(1,N);

if (k<1 & k~=0),
 d=N^k*c; t0=N/10;
 TFx(1:Lnu)=exp(-j*2*pi*(t0*(nu)+d*(nu).^k/k)).*AM;
 x=ifft(TFx).';
elseif k==0,
 d=c; t0=N/10;
 TFx(1:Lnu)=exp(-j*2*pi*(t0*(nu)+d*log(nu))).*AM;
 x=ifft(TFx).';
elseif k==1,
 t0=N;
 x=anapulse(N,t0);
elseif (k>1),
 d=N*2^(k-1)*c;
 TFx(1:Lnu)=exp(-j*2*pi*(t0*(nu)+d*(nu).^k/k)).*AM;
 x=ifft(TFx).';
end

if k~=1,
 gpd=t0+abs(sign(c)-1)/2*(N+1)+d*nu.^(k-1);
else
 gpd=t0*ones(1,N/2);
end

x=x-mean(x);
x=x/norm(x);


% IM = mkZonePlate(SIZE, AMPL, PHASE)
%
% Make a "zone plate" image:
%     AMPL * cos( r^2 + PHASE)
% SIZE specifies the matrix size, as for zeros().
% AMPL (default = 1) and PHASE (default = 0) are optional.

% Eero Simoncelli, 6/96.

function [res] = mkZonePlate(sz, ampl, ph)

sz = sz(:);
if (size(sz,1) == 1)
  sz = [sz,sz];
end

mxsz = max(sz(1),sz(2));

%------------------------------------------------------------
%% OPTIONAL ARGS:

if (exist('ampl') ~= 1)
  ampl = 1;
end

if (exist('ph') ~= 1)
  ph = 0;
end

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

res = ampl * cos( (pi/mxsz) * mkR(sz,2) + ph );


function loc=LMSloc(X)
%Syntax: loc=LMSloc(X)
%_____________________
%
% Calculates the Least Median of Squares (LMS) location parameter
% of the columns of a matrix X. If X is a vector, it returns the LMS
% location parameter of its components. If X is a scalar, it returns
% X.
%
% loc is the LMS estimated vector of locations.
% X is the matrix with the data sets.
%
% Reference:
% Rousseeuw PJ, Leroy AM (1987): Robust regression and outlier detection. Wiley.
%
%
% Alexandros Leontitsis
% Institute of Mathematics and Statistics
% University of Kent at Canterbury
% Canterbury
% Kent, CT2 7NF
% U.K.
%
% University e-mail: al10@ukc.ac.uk (until December 2002)
% Lifetime e-mail: leoaleq@yahoo.com
% Homepage: http://www.geocities.com/CapeCanaveral/Lab/1421
%
% Sep 3, 2001.

if nargin<1 | isempty(X)==1
   error('Not enough input arguments.');
else
   % X must be 2-dimensional
   if ndims(X)>2
      error('Invalid data set.');
   end
   % If X is a row vector make it a column vector
   if size(X,1)==1
      X=X';
   end

   % n is the length of the data set
   n=size(X,1);
end

% For a single data point there is no need to proceed
if n==1
   loc=X;
else
   % Sort the data set to ascending order
   X=sort(X);

   % P. 169: the length of the "half" of the data points
   h=floor(n/2)+1;

   % P. 169: determine the shortest half and compute its midpoint
   j=1:n-h+1;
   range=X(j+h-1,:)-X(j,:);

   % Calculate the location parameter for every column of X
   for i=1:size(X,2);
      f=find(range(:,i)==min(range(:,i)));
      loc(i)=median((X(f+h-1,i)+X(f,i))/2);
   end
end


function z = g_three ( x, y )

%*****************************************************************************80
%
%% G_THREE evaluates a function which has 6 minima, 2 global, in [-3,3]x[-2,2].
%
%  Discussion:
%
%    Actually, F_THREE evaluates that function; this function returns the
%    log of that function plus 2, which is useful when trying to draw contours.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 March 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, Y, the arguments.
%
%    Output, real Z, the function value.
%
  z = ( 4.0 - 2.1 * x.^2 + x.^4 / 3.0 ) .* x.^2 ...
    + x .* y + ( - 4.0 + 4.0 * y.^2 ) .* y.^2;

  z = log ( 2 + z );

  return
end


function z = log_sigmoid(x)
% computes and returns the logistic sigmoid of x. Operation is performed
% element-wise if x is a vector or matrix.
%
%       z = 1 ./ (1-exp(-x))

z = (1+exp(-x)).^-1;

end