function order = level_to_order_open ( dim_num, level )

%*****************************************************************************80
%
%% LEVEL_TO_ORDER converts a level to an order for open rules.
%
%  Discussion:
%
%    Sparse grids can naturally be nested.  A natural scheme is to use
%    a series of one-dimensional rules arranged in a series of "levels"
%    whose order roughly doubles with each step.
%
%    The arrangement described here works naturally for the Fejer Type 1,
%    Fejer Type 2, Newton Cotes Open, Newton Cotes Half Open,
%    and Gauss-Patterson rules.  It also can be used, partially, to describe
%    the growth of Gauss-Legendre rules.
%
%    The idea is that we start with LEVEL = 0, ORDER = 1 indicating the single
%    point at the center, and for all values afterwards, we use the relationship
%
%      ORDER = 2**(LEVEL+1) - 1.
%
%    The following table shows how the growth will occur:
%
%    Level    Order
%
%    0          1
%    1          3 =  4 - 1
%    2          7 =  8 - 1
%    3         15 = 16 - 1
%    4         31 = 32 - 1
%    5         63 = 64 - 1
%
%    For the Fejer Type 1, Fejer Type 2, Newton Cotes Open,
%    Newton Cotes Open Half, and Gauss-Patterson rules, the point growth is
%    nested.  If we have ORDER points on a particular LEVEL, the next level
%    includes all these old points, plus ORDER+1 new points, formed in the
%    gaps between successive pairs of old points plus an extra point at each
%    end.
%
%    Level    Order = New + Old
%
%    0          1   =  1  +  0
%    1          3   =  2  +  1
%    2          7   =  4  +  3
%    3         15   =  8  +  7
%    4         31   = 16  + 15
%    5         63   = 32  + 31
%
%    If we use a series of Gauss-Legendre rules, then there is almost no
%    nesting, except that the central point is shared.  If we insist on
%    producing a comparable series of such points, then the "nesting" behavior
%    is as follows:
%
%    Level    Order = New + Old
%
%    0          1   =  1  +  0
%    1          3   =  2  +  1
%    2          7   =  6  +  1
%    3         15   = 14  +  1
%    4         31   = 30  +  1
%    5         63   = 62  +  1
%
%    Moreover, if we consider ALL the points used in such a set of "nested"
%    Gauss-Legendre rules, then we must sum the "NEW" column, and we see that
%    we get roughly twice as many points as for the truly nested rules.
%
%    In this routine, we assume that a vector of levels is given,
%    and the corresponding orders are desired.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 April 2007
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Fabio Nobile, Raul Tempone, Clayton Webster,
%    A Sparse Grid Stochastic Collocation Method for Partial Differential
%    Equations with Random Input Data,
%    SIAM Journal on Numerical Analysis,
%    Volume 46, Number 5, 2008, pages 2309-2345.
%
%  Parameters:
%
%    Input, integer DIM_NUM, the spatial dimension.
%
%    Input, integer LEVEL(DIM_NUM), the nesting level.
%
%    Output, integer ORDER(DIM_NUM), the order (number of points) of the rule.
%
  for dim = 1 : dim_num

    if ( level(dim) < 0 )
      order(dim) = -1;
    elseif ( level(dim) == 0 )
      order(dim) = 1;
    else
      order(dim) = 2^( level(dim) + 1 ) - 1;
    end

  end

  return
end


function variance = arcsin_variance ( a )

%*****************************************************************************80
%
%% ARCSIN_VARIANCE returns the variance of the Arcsin PDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, the parameter of the CDF.
%    A must be positive.
%
%    Output, real VARIANCE, the variance of the PDF.
%
  variance = a * a / 2.0;

  return
end


function b = poisson_rhs ( nrow, ncol, rhs_num )

%*****************************************************************************80
%
%% POISSON_RHS returns the right hand side of a Poisson linear system.
%
%  Discussion:
%
%    The Poisson matrix is associated with an NROW by NCOL rectangular
%    grid of points.
%
%    Assume that the points are numbered from left to right, bottom to top.
%
%    If the K-th point is in row I and column J, set X = I + J.
%
%    This will be the solution to the linear system.
%
%    The right hand side is easily determined from X.  It is 0 for every
%    interior point.
%
%  Example:
%
%    NROW = 3, NCOL = 3
%
%    ^
%    |  7  8  9
%    J  4  5  6
%    |  1  2  3
%    |
%    +-----I---->
%
%    Solution vector X = ( 2, 3, 4, 3, 4, 5, 4, 5, 6 )
%
%    Right hand side B = ( 2, 2, 8, 2, 0, 6, 8, 6, 14 ).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Gene Golub, Charles Van Loan,
%    Matrix Computations, second edition,
%    Johns Hopkins University Press, Baltimore, Maryland, 1989
%    (Section 4.5.4).
%
%  Parameters:
%
%    Input, integer NROW, NCOL, the number of rows and columns
%    in the grid.
%
%    Input, integer RHS_NUM, the number of right hand sides.
%
%    Output, real B(NROW*NCOL,RHS_NUM), the right hand side.
%
  n = nrow * ncol;

  b = zeros ( n, rhs_num );

  k = 0;
  for j = 1 : nrow
    for i = 1 : ncol
      k = k + 1;
      b(k,1) = 0.0;
      if ( i == 1 )
        b(k,1) = b(k,1) + i + j - 1;
      end
      if ( j == 1 )
        b(k,1) = b(k,1) + i + j - 1;
      end
      if ( i == ncol )
        b(k,1) = b(k,1) + i + j + 1;
      end
      if ( j == nrow )
        b(k,1) = b(k,1) + i + j + 1;
      end
    end
  end

  return
end


function a = stirling_inverse ( n )

%*****************************************************************************80
%
%% STIRLING_INVERSE returns the inverse of the STIRLING matrix.
%
%  Comments:
%
%    The inverse of S1, the matrix of Stirling numbers of the first kind,
%    is S2, the matrix of Stirling numbers of the second kind.
%
%    S2(I,J) represents the number of distinct partitions of I elements
%    into J nonempty sets.  For any I, the sum over J of the Stirling
%    numbers S2(I,J) is represented by B(I), called "Bell's number",
%    and represents the number of distinct partitions of I elements.
%
%    For example, with 4 objects, there are:
%
%    1 partition into 1 set:
%
%      (A,B,C,D)
%
%    7 partitions into 2 sets:
%
%      (A,B,C) (D)
%      (A,B,D) (C)
%      (A,C,D) (B)
%      (A) (B,C,D)
%      (A,B) (C,D)
%      (A,C) (B,D)
%      (A,D) (B,C)
%
%    6 partitions into 3 sets:
%
%      (A,B) (C) (D)
%      (A) (B,C) (D)
%      (A) (B) (C,D)
%      (A,C) (B) (D)
%      (A,D) (B) (C)
%      (A) (B,D) (C)
%
%    1 partition into 4 sets:
%
%      (A) (B) (C) (D)
%
%    So S2(4,1) = 1, S2(4,2) = 7, S2(4,3) = 6, S2(4,4) = 1, and B(4) = 15.
%
%
%  First terms:
%
%    I/J: 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    1    3    1    0    0    0    0    0
%    4    1    7    6    1    0    0    0    0
%    5    1   15   25   10    1    0    0    0
%    6    1   31   90   65   15    1    0    0
%    7    1   63  301  350  140   21    1    0
%    8    1  127  966 1701 1050  266   28    1
%
%  Recursion:
%
%    S2(I,1) = 1 for all I.
%    S2(I,I) = 1 for all I.
%    S2(I,J) = 0 if I < J.
%
%    S2(I,J) = J * S2(I-1,J) + S2(I-1,J-1)
%
%  Properties:
%
%    A is generally not symmetric: A' /= A.
%
%    A is integral, therefore det ( A ) is integral, and
%    det ( A ) * inverse ( A ) is integral.
%
%    A is lower triangular.
%
%    A is nonnegative.
%
%    det ( A ) = 1.
%
%    A is unimodular.
%
%    LAMBDA(1:N) = 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%
%    Output, real A(N,N), the  matrix.
%
  a = zeros ( n, n );

  a(1,1) = 1.0;
  a(1,2:n) = 0.0;

  for i = 2 : n

    a(i,1) = 1.0;

    for j = 2 : n
      a(i,j) = j * a(i-1,j) + a(i-1,j-1);
    end

  end

  return
end


function value = r8_degrees ( radians )

%*****************************************************************************80
%
%% R8_DEGREES converts an angle from radian to degree measure.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 May 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real RADIANS, the angle measurement in radians.
%
%    Output, real VALUE, the angle measurement in degrees.
%
  value = radians * 180.0 / pi;

  return
end


function p = predict(theta, X)
%PREDICT Predict whether the label is 0 or 1 using learned logistic
%regression parameters theta
%   p = PREDICT(theta, X) computes the predictions for X using a
%   threshold at 0.5 (i.e., if sigmoid(theta'*x) >= 0.5, predict 1)

m = size(X, 1); % Number of training examples

% You need to return the following variables correctly
p = zeros(m, 1);

% ====================== YOUR CODE HERE ======================
% Instructions: Complete the following code to make predictions using
%               your learned logistic regression parameters.
%               You should set p to a vector of 0's and 1's
%

result = sigmoid(X * theta);
p = round(result);

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

end


function kf = gaussian_correlation(xf, yf, sigma)
%GAUSSIAN_CORRELATION Gaussian Kernel at all shifts, i.e. kernel correlation.
%   Evaluates a Gaussian kernel with bandwidth SIGMA for all relative
%   shifts between input images X and Y, which must both be MxN. They must
%   also be periodic (ie., pre-processed with a cosine window). The result
%   is an MxN map of responses.
%
%   Inputs and output are all in the Fourier domain.
%
%   Joao F. Henriques, 2014
%   http://www.isr.uc.pt/~henriques/

	N = size(xf,1) * size(xf,2);
	xx = xf(:)' * xf(:) / N;  %squared norm of x
	yy = yf(:)' * yf(:) / N;  %squared norm of y

	%cross-correlation term in Fourier domain
	xyf = xf .* conj(yf);
	xy = sum(real(ifft2(xyf)), 3);  %to spatial domain

	%calculate gaussian response for all positions, then go back to the
	%Fourier domain
	kf = fft2(exp(-1 / sigma^2 * max(0, (xx + yy - 2 * xy) / numel(xf))));

end


function [J, grad] = cofiCostFunc(params, Y, R, num_users, num_movies, ...
                                  num_features, lambda)
%COFICOSTFUNC Collaborative filtering cost function
%   [J, grad] = COFICOSTFUNC(params, Y, R, num_users, num_movies, ...
%   num_features, lambda) returns the cost and gradient for the
%   collaborative filtering problem.
%

% Unfold the U and W matrices from params
X = reshape(params(1:num_movies*num_features), num_movies, num_features);
Theta = reshape(params(num_movies*num_features+1:end), ...
                num_users, num_features);

% You need to return the following values correctly
J = 0;
X_grad = zeros(size(X));
Theta_grad = zeros(size(Theta));

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost function and gradient for collaborative
%               filtering. Concretely, you should first implement the cost
%               function (without regularization) and make sure it is
%               matches our costs. After that, you should implement the
%               gradient and use the checkCostFunction routine to check
%               that the gradient is correct. Finally, you should implement
%               regularization.
%
% Notes: X - num_movies  x num_features matrix of movie features
%        Theta - num_users  x num_features matrix of user features
%        Y - num_movies x num_users matrix of user ratings of movies
%        R - num_movies x num_users matrix, where R(i, j) = 1 if the
%            i-th movie was rated by the j-th user
%
% You should set the following variables correctly:
%
%        X_grad - num_movies x num_features matrix, containing the
%                 partial derivatives w.r.t. to each element of X
%        Theta_grad - num_users x num_features matrix, containing the
%                     partial derivatives w.r.t. to each element of Theta
%

% FIXME(SaveTheRbtz@): Not optical: preforms calculations on cells with R(i,j) == 0
J = sum(sum((R==1) .* ((X * Theta' - Y) .^ 2))) / 2;

X_grad = (R==1) .* (X * Theta' - Y) * Theta + lambda * X;
Theta_grad = (R==1)' .* (X * Theta' - Y)' * X + lambda * Theta;

Regularization = lambda * (sum(sum(Theta .^ 2)) + sum(sum(X .^ 2))) / 2;
J += Regularization;

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

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

end


function result = rectangle_sub_2d ( func, xval, yval, nsub, norder, xtab, ...
  ytab, weight )

%*****************************************************************************80
%
%% RECTANGLE_SUB_2D carries out a composite quadrature over a rectangle in 2D.
%
%  Integration region:
%
%    XVAL(1) <= X <= XVAL(2),
%    YVAL(1) <= Y <= YVAL(2).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, external FUNC, the name of the function to be
%    integrated.  The user must declare the name an EXTERNAL
%    parameter in the calling program, pass the name of the
%    function in FUNC, and write a function of the form
%      function value = func ( x, y )
%    which evaluates the function at the point (X,Y).
%
%    Input, real XVAL(2), the left and right X coordinates.
%
%    Input, real YVAL(2), the lower and upper Y coordinates.
%
%    Input, integer NSUB(2).
%    NSUB(1) is the number of subintervals to use in the X direction,
%    and NSUB(2) is the same thing for Y.
%
%    Input, integer NORDER, the order of the rule.
%
%    Input, real XTAB(NORDER), YTAB(NORDER), the abscissas.
%
%    Input, real WEIGHT(NORDER), the weights of the rule.
%
%    Output, real RESULT, the approximate integral of the function.
%
  a(1) = xval(1);
  a(2) = yval(1);
  b(1) = xval(2);
  b(2) = yval(2);

  for i = 1 : 2
    if ( a(i) == b(i) )
      result = 0.0E+00;
      return
    end
  end

  for i = 1 : 2
    if ( nsub(i) < 1 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'RECTANGLE_SUB_2D - Fatal error!\n' );
      fprintf ( 1, '  Nonpositive value of NSUB(I) = %d\n', nsub(i) );
      fprintf ( 1, '  for index I = %d\n', i );
      error ( 'RECTANGLE_SUB_2D - Fatal error!' );
    end
  end
%
%  Break up the X interval into NSUB(1) subintervals.
%
  volume = 0.0E+00;
  result = 0.0E+00;

  for i = 1 : nsub(1)

    xlo = r8vec_even_select ( a(1), b(1), nsub(1)+1, i );
    xhi = r8vec_even_select ( a(1), b(1), nsub(1)+1, i+1 );
%
%  Break up the Y interval into NSUB(2) subintervals.
%
    for j = 1 : nsub(2)

      ylo = r8vec_even_select ( a(2), b(2), nsub(2)+1, j );
      yhi = r8vec_even_select ( a(2), b(2), nsub(2)+1, j+1 );

      quad_sub = 0.0E+00;
      for k = 1 : norder

        x = xlo + 0.5E+00 * ( xtab(k) + 1.0E+00 ) * ( xhi - xlo );
        y = ylo + 0.5E+00 * ( ytab(k) + 1.0E+00 ) * ( yhi - ylo );

        quad_sub = quad_sub + weight(k) * feval ( func, x, y ) / 4.0E+00;

      end

      volume_sub = ( xhi - xlo ) * ( yhi - ylo );
      result_sub = quad_sub * volume_sub;

      volume = volume + volume_sub;
      result = result + result_sub;

    end

  end

  return
end


function tan = p00_tan ( problem, option, nvar, x )

%*****************************************************************************80
%
%% P00_TAN determines a tangent vector at X.
%
%  Discussion:
%
%    If X is a solution of F(Y) = 0, then the vector TAN
%    is tangent to the curve of solutions at X.
%
%    If X is not a solution of F(Y) = 0, then the vector TAN
%    is tangent to the curve F(Y) = F(X) at X.
%
%    The vector will have unit euclidean norm.
%
%    The sign of TAN will be chosen so that the determinant
%    of F'(X) augmented with a final row equal to TAN will be positive.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer PROBLEM, the problem index.
%
%    Input, integer OPTION, the option index.
%
%    Input, integer NVAR, the number of variables.
%
%    Input, real X(NVAR), the evaluation point.
%
%    Output, real TAN(NVAR), a tangent vector at X.
%

%
%  Compute the jacobian.
%
  jac = p00_jac ( problem, option, nvar, x );
%
%  Compute the QR factorization of JAC'.
%
  [ q, r ] = qr ( jac' );

  tan(1:nvar,1) = q(1:nvar,nvar);
%
%  Choose the sign of TAN by the determinant condition.
%
  jac(nvar,1:nvar) = tan(1:nvar,1);

  d = det ( jac );

  if ( d < 0.0 )
    tan(1:nvar) = - tan(1:nvar);
  end

  return
end


function value = r8vec_norm_lp ( n, a, p )

%*****************************************************************************80
%
%% R8VEC_NORM_LP returns the LP norm of an R8VEC.
%
%  Discussion:
%
%    The vector LP norm is defined as:
%
%      value = ( sum ( 1 <= I <= N ) ( abs ( A(I) ) )^P )^(1/P).
%
%    This routine allows P to have the special Matlab value Inf,
%    in which case the L-infinity norm is returned.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 September 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of entries in A.
%
%    Input, real A(N), the vector whose LP norm is desired.
%
%    Input, real P, the index of the norm.
%
%    Output, real VALUE, the LP norm of A.
%
  if ( p <= 0.0 )
    value = -1.0;
  elseif ( p == Inf )
    value = maxval ( abs ( a(1:n) ) );
  elseif ( p == 1.0 )
    value = sum ( abs ( a(1:n) ) );
  elseif ( p == 2.0 )
    value = sqrt ( sum ( a(1:n).^2 ) );
  else
    value = ( sum ( ( abs ( a(1:n) ) ).^p ) ).^( 1.0 / p );
  end

  return
end


% Section 8.1.1: Separating a point from a polyhedron
% Boyd & Vandenberghe "Convex Optimization"
% Joelle Skaf - 10/09/05
%
% The goal is to produce a hyperplane separating x0 and the polyhedron
% defined as {x | Ax <= b}
%           minimize    mu'*x0 - b'*lambda
%                       A'*lambda = mu
%                       norm(mu)* <= 1
%                       lambda >= 0

% Input data
randn('seed',0);
n  = 10;
m  = 2*n;
x0 = randn(n,1);
A  = randn(m,n);
b  = rand(m,1);

% CVX solution
fprintf(1,'Finding a separating hyperplane between the 2 polyhedra...');

cvx_begin quiet
    variables muu(n) lambda(m)
    maximize ( muu'*x0 - b'*lambda )
    A'*lambda == muu; %#ok
    norm(muu) <= 1; %#ok
    lambda >= 0; %#ok
cvx_end

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

% Verification
disp('------------------------------------------------------------------');
disp('Note that 0 is in {x | Ax <= b} by construction...' );
disp('Verifying that x0 is separated from {x | Ax <= b} i.e. mu^T*x0 > 0');
disp([' mu^T*x0 = ' num2str(muu'*x0) ]);


%% Create artificial low-rank image
perHei = 10;
perWid = 20;
hei = 50*perHei;
wid1 = 5*perWid;  rect1 = ones(hei, wid1) * 75;
wid2 = 15*perWid; rect2 = ones(hei, wid2) * 184;
wid3 = 8*perWid;  rect3 = ones(hei, wid3) * 223;
wid4 = 18*perWid; rect4 = ones(hei, wid4) * 113;
wid5 = 10*perWid; rect5 = ones(hei, wid5) * 38;
A = uint8([rect1 rect2 rect3 rect4 rect5]);
D = imnoise(A, 'salt & pepper');
A = double(A);
D = double(D);
E = D - A;
%% Create low-rank matrix
% m = 100; % m = 100, 200, 400, 800
% r = 5;  % rank(A) = 5, 10, 20, 40
% U = randn(m,r);
% V = randn(m,r);
% A = U*V';
% E = (imnoise(zeros(size(A)),'salt & pepper',0.1) > 0) .* (rand(size(A))-0.5)*2*500;
% D = A + E;
%% Apply APG to recover A_hat and E_hat
[rows, cols] = size(D);
lambda = rows^(-1/2);
tic
[A_hat,E_hat,numIter] = proximal_gradient_rpca(D, lambda);
toc

norm(A_hat-A, 'fro') / norm(A, 'fro')

figure; imshow(A,[]); title('original A');
figure; imshow(A_hat,[]); title('recovered A');

github-repos/MATLAB/YimianDai-Image-Processing-Codes-for-Easier-Understanding/Image-Processing-Codes-for-Easier-Understanding-874302799e48852624bc3760b58b46bd9360f238/src/(NIPS 2009) Robust Principal Component Analysis Exact Recovery of Corrupted Low-Rank Matrices by Convex Optimization/Demo_APG.m


function y = laplace_pdf(x,mu,sigma)
%LAPLACE_PDF     Laplace probability density function (pdf).
%
%   Y = LAPLACE_PDF(X,MU,SIGMA) Returns the Laplace pdf with
%   mean, MU, and scale, SIGMA, at the values in X.
%
%   The size of Y is the common size of the input arguments. A scalar input
%   functions as a constant matrix of the same size as the other inputs.
%
%   Default values for MU and SIGMA are 0 and 1 respectively.

% Copyright (c) 2005 Aki Vehtari

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

if nargin < 3,
  sigma = 1;
end

if nargin < 2;
  mu = 0;
end

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

y= -abs(x-mu)./sigma - log(2.*sigma);
y=exp(y);


function H = gmm_entropy(Priors,Mu,Sigma)
%GMM_ENTROPY: Computes the differentinal entropy of a Gaussian Mixture
%Model.

D = size(Mu,1);
K = size(Mu,2);
H = 0;

if D == 1
    for k=1:K
        H = H  + Priors(k) * (-log(Priors(k)) + 0.5 * log(((2*pi*exp(1))^(D)) * det(Sigma(k)) ));
    end
else
    for k=1:K
        H = H  + Priors(k) * (-log(Priors(k)) + 0.5 * log(((2*pi*exp(1))^(D)) * det(Sigma(:,:,k)) ));
    end
end

end


% function [A,truth]=create_SBM(N,q,c,epsi,com_size)
%
% This creates an SBM graph with
% Inputs:
% - N nodes,
% - q communites of sizes listed in com_size,
% - an average degree of c,
% - and a difficulty \epsilon=epsi.
% Outputs:
% - G the graph structure
%
% Copyright (C) 2016 Nicolas Tremblay, Gilles Puy.
% This file is part of the CSCbox (Compressive Spectral Clustering toolbox)
%
% The CSCbox 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 3 of the License, or
% (at your option) any later version.
%
% The CSCbox 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, see <http://www.gnu.org/licenses/>.
%
% If you use this toolbox please kindly cite
%     N. Tremblay, G. Puy, R. Gribonval and P. Vandergheynst.
%     Compressive Spectral Clustering.
%     ArXiv e-prints:1602.02018 Feb. 2016.

function [G]=create_SBM(N,q,c,epsi,com_size)

if sum(com_size)~=N
    error('error in create_SBM.m : sum(com_size)~=N!')
end

pin=(q*c)/(N-q+(q-1)*epsi*N);
pout=(q*c*epsi)/(N-q+(q-1)*epsi*N);

rng('shuffle');

% total # of intra community edges is taken from Bernouilli distrib
I=[]; J=[]; truth=zeros(N,1);
for k=1:q
    truth(sum(com_size(1:k-1))+1:sum(com_size(1:k)))=k;
    Numedgesk=my_binornd(com_size(k).*(com_size(k)-1)/2,pin); %normal approx
    while Numedgesk>com_size(k).*(com_size(k)-1)/2
        Numedgesk=my_binornd(com_size(k).*(com_size(k)-1)/2,pin); %normal approx
    end
    edges = randperm(com_size(k).*(com_size(k)-1)/2,Numedgesk);
    %edges=datasample([1:com_size(k).*(com_size(k)-1)./2],Numedgesk,'Replace',false);
    [Inew, Jnew] = ind2sub4up(edges);
    I=[I;Inew+sum(com_size(1:k-1))];
    J=[J;Jnew+sum(com_size(1:k-1))];
end

% for k=1:q-1
%     for kk=k+1:q
%         Numedgesk=my_binornd(com_size(k)*com_size(kk),pout); %normal approx
%         edges = randperm(com_size(k)*com_size(kk),Numedgesk);
%         %Numedgesk=binornd(com_size(k)*com_size(kk),pout);
%         %edges=datasample([1:com_size(k)*com_size(kk)],Numedgesk,'Replace',false);
%         [Inew, Jnew] = ind2sub([com_size(k),com_size(kk)],edges);
%         I=[I;Inew'+sum(com_size(1:k-1))];
%         J=[J;Jnew'+sum(com_size(1:kk-1))];
%     end
% end

for k=1:q-1
    Numedgesk=my_binornd(com_size(k)*sum(com_size(k+1:end)),pout); %normal approx
    edges = randperm(com_size(k)*sum(com_size(k+1:end)),Numedgesk);
    %Numedgesk=binornd(com_size(k)*sum(com_size(k+1:end)),pout);
    %edges=datasample([1:com_size(k)*sum(com_size(k+1:end))],Numedgesk,'Replace',false);
    [Inew, Jnew] = ind2sub([com_size(k),sum(com_size(k+1:end))],edges);
    I=[I;Inew'+sum(com_size(1:k-1))];
    J=[J;Jnew'+sum(com_size(1:k))];
end

A=sparse(I,J,1,N,N);
A=A+A';
G=gsp_graph(A);
G.type='SBM_CSC';
G.truth = truth;
G.k=q;


function [phi,lambda] = LC_froca(x,y,maxlat,minlat,maxlon,minlon)

    %LC_FROM_CARTESIAN
    %
    %	[phi,lambda] = LC_from_cartesian(x,y,maxlat,minlat,maxlon,minlon)
    %
    %	Function to compute the angular coordinates PHI (latitude) and
    %	LAMBDA (longitude) from the cartesian coordinates X and Y
    %	given the MAXLAT, MINLAT, MAXLON & MINLON of the Lambert
    %	conformal map on which these points have to be mapped.
    %
    %	where * phi: current location latitude
    %	      * lambda: current location longitude
    %	      * x & y : current cartesian coordinates
    %	      * maxlat: maximum latitude limit of the map
    %	      * minlat: minimum latitude limit of the map
    %	      * maxlon: maximum longitude limit of the map
    %	      * minlon: minimum longitude limit of the map
    %	               (remember: West longitude is < 0!)
    %
    %	If the LC_MAP function has been called before this function
    %	AND the same map limits are used, then it is not neccessary to
    %	enter the last 4 arguments:
    %
    %	[phi,lambda] = LC_to_cartesian(x,y)
    %
    %	Source: Equations taken from "Map Projections Used by the
    %	        U.S. Geological Survey" by John P. Snyder
    %	        Geological Survey Bulletin 1532, pg: 101-109.

    report_this_filefun();

    todeg = 180 / pi;

    % set the global variables
    global scale
    global phi0 lambda0 phi1 phi2
    global maxlatg minlatg maxlong minlong
    ZG = ZmapGlobal.Data;
    torad = ZG.torad;
    Re = ZG.Re;

    if nargin == 2
        %get data from global variables
        maxlat = maxlatg; minlat = minlatg;
        maxlon = maxlong; minlon = minlong;
    elseif nargin == 6
        % set the global variable for later use
        maxlatg = maxlat; minlatg = minlat;
        maxlong = maxlon; minlong = minlon;

        % set some constants
        scale = 1;

        % get the Standard Parallels and Center Coordinates
        phi2 = (minlat + ((maxlat + minlat) / 4)) * torad;
        phi1 = (maxlat - ((maxlat + minlat) / 4)) * torad;
        phi0 = (phi1 + phi2) / 2;
        lambda0 = ((minlon + maxlon) / 2) * torad;
    else
        disp('This function requires 2 or 6 input arguments!')
        help LC_to_cartesian
        return
    end

    % compute the constant of the cone: sine_phi0
    tan1 = tan((pi/4) + (phi1/2));
    tan2 = tan((pi/4) + (phi2/2));
    sine_phi0 = log(cos(phi1)/cos(phi2)) / log(tan2/tan1);

    % compute the auxiliary function: psi
    psi = (cos(phi1) * (tan1.^sine_phi0)) / sine_phi0;

    % compute the polar radius to the origin: rho0
    tan0 = tan((pi/4) + (phi0/2));
    rho0 = (Re * psi) / (tan0.^sine_phi0);

    % compute the polar angles: theta
    theta = atan(x ./ (rho0 - y));

    % compute rho (inverse)
    rho = sign(sine_phi0) * sqrt((x.^2) + (rho0 - y).^2);

    % store the latitudes and longitudes in output variables
    arctan = atan((Re * psi ./ rho).^(1/sine_phi0));
    phi = ((2 * arctan) - (pi/2)) * todeg;
    lambda = ((theta / sine_phi0) + lambda0) * todeg;
end


%% Example demonstrating MOL-WENO3-LF and MOL-WENO5-LF schemes
%% from J. Comp. Phys. 126, pp. 202-228 (1996) by Jiang and Shu
%% "Efficient Implementation of Weighted ENO Schemes"
function WENO_Buckley_Leverett
close all; clc;
global dx

% Spatial variable interval (-1, 1) from (8.1) example 2
x = linspace(-1.0, 1.0, 80);
N = length(x);
dx = x(2)-x(1);

% Initial conditions for 1D Buckey-Leverett problem
u0(1:N) = 0.0;
u0((N/4):(N/2)) = 1.0;

% Time interval (as in Example 2)
t = linspace(0.0, 0.4, 100);

% Solve MOL ODEs system for WENO3-LF and WENO5-LF schemes with RKF45 solver
tic;
[ZZ, u1] = ode45(@MOL_WENO3, t, u0);
[ZZ, u2] = ode45(@MOL_WENO5, t, u0);
toc

% Plot each solution
for I=1:100
    plot(x, u0, 'b-', x, u1(I,:), 'ro', x, u2(I,:), 'k-', 'LineWidth', 2);
    legend('Initial', 'MOL + WENO3-LF', 'MOL + WENO5-LF', 'Location', 'NorthEast');
    axis([x(1) x(end) 0 1.1]);
    grid on;
    pause(0.01)
    drawnow;
end

%% Buckey-Leverett flux F(u)
function res = Flux(u)
res = 4*u.^2./(4*u.^2+(1-u).^2);

%% Exact expression for partial derivative from F(u) by u
function res = Jacobian(u)
res = 8*u.*(1-u)./(5*u.^2-2*u+1).^2;

%% MOL ODEs for semi-discrete Buckley-Leverett equation with WENO3 flux
%% reconstruction
function [res] = MOL_WENO3(t, u)
global dx

N = length(u);   I = 2:(N+1);

% Preallocate memory and add ghost nodes at the ends
U(1) = u(1); U(I) = u(I-1); U(N+2) = u(end); U(N+3) = u(end);
alpha1 = zeros(size(U)); alpha2 = zeros(size(U));
R_minus = zeros(size(U)); R_plus = zeros(size(U));

% Lax-Friedrichs (LF) flux splitting
a = max(abs(Jacobian(U)));
Fp = 0.5*( Flux(U) + a*U ); Fm = 0.5*( Flux(U) - a*U );

% WENO3 "right" flux reconstruction
alpha1(I) = (1/3)./(eps + (Fp(I)-Fp(I-1)).^2).^2;   alpha2(I) = (2/3)./(eps + (Fp(I+1)-Fp(I)).^2).^2;
omega1 = alpha1./(alpha1 + alpha2);  omega2 = alpha2./(alpha1 + alpha2);
R_plus(I) = omega1(I).*(3/2*Fp(I) - 1/2*Fp(I-1)) + omega2(I).*(1/2*Fp(I) + 1/2*Fp(I+1));

% WENO3 "left" flux reconstruction
alpha1(I) = (1/3)./(eps + (Fm(I+2)-Fm(I+1)).^2).^2;   alpha2(I) = (2/3)./(eps + (Fm(I+1)-Fm(I)).^2).^2;
omega1 = alpha1./(alpha1 + alpha2);  omega2 = alpha2./(alpha1 + alpha2);
R_minus(I) = omega1(I).*(3/2*Fm(I+1) - 1/2*Fm(I+2)) + omega2(I).*(1/2*Fm(I) + 1/2*Fm(I+1));

% Combine fluxes and find finite volume spatial derivative
res(I-1) = -(R_plus(I)+R_minus(I)-R_plus(I-1)-R_minus(I-1))/dx;
res = res';

%% MOL ODEs for semi-discrete Buckley-Leverett equation with WENO5 flux
%% reconstruction
function [res] = MOL_WENO5(t, u)
global dx

N = length(u);   I = 3:(N+2);

% Preallocate memory and add ghost nodes at the ends
U(1) = u(1); U(2) = u(1); U(I) = u(I-2); U(N+3) = u(end); U(N+4) = u(end); U(N+5) = u(end);
alpha1 = zeros(size(U)); alpha2 = zeros(size(U)); alpha3 = zeros(size(U));
beta1 = zeros(size(U)); beta2 = zeros(size(U)); beta3 = zeros(size(U));
R_minus = zeros(size(U)); R_plus = zeros(size(U));

% Lax-Friedrichs (LF) flux splitting
a = max(abs(Jacobian(U)));
Fp = 0.5*( Flux(U) + a*U ); Fm = 0.5*( Flux(U) - a*U );

% WENO5 "right" flux reconstruction
beta1(I) = (13.0/12.0)*(Fp(I) - 2.0*Fp(I+1) + Fp(I+2)).^2 ...
         + (1.0/4.0)*(3.0*Fp(I) - 4.0*Fp(I+1) + Fp(I+2)).^2;
beta2(I) = (13.0/12.0)*(Fp(I-1) - 2.0*Fp(I) + Fp(I+1)).^2 ...
         + (1.0/4.0)*(Fp(I-1) - Fp(I+1)).^2;
beta3(I) = (13.0/12.0)*(Fp(I-2) - 2.0*Fp(I-1) + Fp(I)).^2 ...
         + (1.0/4.0)*(Fp(I-2) - 4.0*Fp(I-1) + 3.0*Fp(I)).^2;

alpha1(I) = (3.0/10.0)./(eps + beta1(I)).^2;
alpha2(I) = (3.0/5.0)./(eps + beta2(I)).^2;
alpha3(I) = (1.0/10.0)./(eps + beta3(I)).^2;

omega1 = alpha1./(alpha1 + alpha2 + alpha3);
omega2 = alpha2./(alpha1 + alpha2 + alpha3);
omega3 = alpha3./(alpha1 + alpha2 + alpha3);

R_plus(I) = omega1(I).*(1.0/3.0*Fp(I) + 5.0/6.0*Fp(I+1) - 1.0/6.0*Fp(I+2)) ...
          + omega2(I).*(-1.0/6.0*Fp(I-1) + 5.0/6.0*Fp(I) + 1.0/3.0*Fp(I+1)) ...
          + omega3(I).*(1.0/3.0*Fp(I-2) - 7.0/6.0*Fp(I-1) + 11.0/6.0*Fp(I));

% WENO5 "left" flux reconstruction
beta1(I) = (13.0/12.0)*(Fm(I+1) - 2.0*Fm(I+2) + Fm(I+3)).^2 ...
         + (1.0/4.0)*(3.0*Fm(I+1) - 4.0*Fm(I+2) + Fm(I+3)).^2;
beta2(I) = (13.0/12.0)*(Fm(I) - 2.0*Fm(I+1) + Fm(I+2)).^2 ...
         + (1.0/4.0)*(Fm(I) - Fm(I+2)).^2;
beta3(I) = (13.0/12.0)*(Fm(I-1) - 2.0*Fm(I) + Fm(I+1)).^2 ...
         + (1.0/4.0)*(Fm(I-1) - 4.0*Fm(I) + 3.0*Fm(I+1)).^2;

alpha1 = (1.0/10.0)./(eps + beta1).^2;
alpha2 = (3.0/5.0)./(eps + beta2).^2;
alpha3 = (3.0/10.0)./(eps + beta3).^2;

omega1 = alpha1./(alpha1 + alpha2 + alpha3);
omega2 = alpha2./(alpha1 + alpha2 + alpha3);
omega3 = alpha3./(alpha1 + alpha2 + alpha3);

R_minus(I) = omega1(I).*(1.0/3.0*Fm(I+3) - 7.0/6.0*Fm(I+2) + 11.0/6.0*Fm(I+1)) ...
           + omega2(I).*(-1.0/6.0*Fm(I+2) + 5.0/6.0*Fm(I+1) + 1.0/3.0*Fm(I)) ...
           + omega3(I).*(1.0/3.0*Fm(I+1) + 5.0/6.0*Fm(I) - 1.0/6.0*Fm(I-1));

% Combine fluxes and find finite volume spatial derivative
res(I-2) = -(R_plus(I)+R_minus(I)-R_plus(I-1)-R_minus(I-1))/dx;
res = res';


% Generate MAR(2) and fit MAR model

disp('Generating data from known MAR(2) model');
d=2;
p=2;
T=100;
w=[0;0];

% Coeffs at lag 1
A1 = [ 0.4   1.2;   0.3   0.7 ];
% Coeffs at lag 2
A2 = [ 0.35 -0.3;  -0.4  -0.5 ];
A = [ A1 A2 ];

C = [ 1.00  0.50;   0.50  1.50 ];
lambda_true=inv(C);

%  Generate observations
x = spm_mar_gen (w, A, C, T);

logev=[];
for m=1:5,
    disp(sprintf('Fitting MAR model with %d components',m));
    mar=spm_mar(x,m);
    logev=[logev; mar.fm];
end
logev=logev-min(logev);

figure
subplot(2,1,1);
plot(x);
title('Bivariate time series from MAR(2) model');
subplot(2,1,2);
bar(logev);
xlabel('Number of time lags');
ylabel('Log Evidence');

% Specify prior - this is optional.
% spm_mar.m runs without the prior being set.
prior=spm_mar_prior(d,p,'global');
[mar,y,y_pred]=spm_mar(x,2,prior);

disp(' ');
disp('Estimates from fitting MAR(2) model');
disp('Lag 1');
disp('True coefficients');
disp(A1);
disp('Estimated coefficients');
disp(-mar.lag(1).a)

disp('Lag 2');
disp('True coefficients');
disp(A2);
disp('Estimated coefficients');
disp(-mar.lag(2).a)

disp('Noise covariance');
disp('True:');
disp(C);
disp('Estimated:');
disp(mar.noise_cov);


function pdf = log_uniform_pdf ( x, a, b )

%*****************************************************************************80
%
%% LOG_UNIFORM_PDF evaluates the Log Uniform PDF.
%
%  Discussion:
%
%    PDF(A,B;X) = 1 / ( X * ( log ( B ) - log ( A ) ) ) for A <= X <= B
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the argument of the PDF.
%
%    Input, real A, B, the parameters of the PDF.
%    1.0 < A < B.
%
%    Output, real PDF, the value of the PDF.
%
  if ( x < a )
    pdf = 0.0;
  elseif ( x <= b )
    pdf = 1.0 / ( x * ( log ( b ) - log ( a ) ) );
  else
    pdf = 0.0;
  end

  return
end


function y=PSNR(noisyImage,restoredImage)

noisyImage = double(noisyImage);
restoredImage = double(restoredImage);
% Compute the PSNR of two gray scale image
% Traditional progarmming using loops
% Class input : [0,1]
% july, 25 , 2012
% KHMOU Youssef

N=size(noisyImage);
if length(N)> 2
    error('Input must be grayscale image');
end
if size(noisyImage)~=size(restoredImage)
    error('The images must have the same size');
end

%if ~isa(noisyImage,'double')
%   noisyImage=double(noisyImage)./255.00;
%end
%if  ~isa(restoredImage,'double')
%    restoredImage=double(restoredImage)./255.00;
%end

% begin

d1=max(noisyImage(:));
d2=max(restoredImage(:));
d=max(d1,d2);

MSE=0;
for i=1:N(1)
    for j=1:N(2)
        if isnan(noisyImage(i,j)) || isinf(restoredImage(i,j))...
                || isnan(restoredImage(i,j)) || isinf(noisyImage(i,j))
            continue;
        end
        MSE=MSE+((abs(noisyImage(i,j)-restoredImage(i,j))).^2);
    end
end

MSE=MSE./(N(1)*N(2));

y=10*log10((d.^2) /MSE);


function fx2 = p15_fx2 ( x )

%*****************************************************************************80
%
%% P15_FX2 evaluates the second derivative of the function for problem 15.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 May 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the abscissa.
%
%    Output, real FX2, the second derivative of the function at X.
%
  fx2 = ( - 2.0 - 30.0 * x.^2 + 36.0 * x.^4 ) * r8_cube_root ( x ) ...
    * exp ( - x.^2 ) / ( 9.0 * x.^2 );

  return
end


function U = randunitary(n, N)
% Generates uniformly random unitary matrices.
%
% function U = randunitary(n, N)
%
% U is a n-by-n-by-N array such that each slice U(:, :, i) is a random
% unitary matrix of size n (i.e., a matrix in the unitary group U(n)),
% sampled from the Haar measure (uniform distribution).
%
% By default, N = 1.
%
% Complexity: N times O(n^3).
% For details on the algorithm, see Mezzadri 2007,
% "How to generate random matrices from the classical compact groups."
%
% See also: randrot qr_unique

% This file is part of Manopt: www.manopt.org.
% Original author: Nicolas Boumal, June 18, 2019.
% Contributors:
% Change log:

    if nargin < 2
        N = 1;
    end

    if n == 1
        U = sign(randn(1, 1, N) + 1i*randn(1, 1, N));
        return;
    end

    % Generated as such, the slides of U are uniformly distributed over
    % U(n), the set of unitary matrices: see Mezzadri 2007, p597.
    U = qr_unique(randn(n, n, N) + 1i*randn(n, n, N));

end


function [alpha, beta, gamma, stability] = evalABGParam(process, noisy, dt)
% evalABGParam - evaluates alpha, beta and gamma parameters
% With this parameters, alpha-beta filter becomes a steady-state Kalman filter
%
% Syntax:  [alpha,beta,gamma,stability] = evalABGParam(process,noisy,dt)
%          [alpha,beta,gamma,stability] = evalABGParam([alpha,beta,gamma])
%
% Inputs:
%   process - real system state
%     noisy - measured system state
%        dt - delta time (sample rate)
%
% Outputs:
%     alpha - alpha parameter
%      beta - beta parameter
%     gamma - gamma parameter
% stability - Juri's Stability Test
%
% Other m-files required: none
% Subfunctions: none
% MAT-files required: none
%
% See also: abgFilter;

% Author: Marco Borges, Ph.D. Student, Computer/Biomedical Engineer
% UFMG, PPGEE, Neurodinamica Lab, Brazil
% email address: marcoafborges@gmail.com
% Website: http://www.cpdee.ufmg.br/
% References:
%   NEAL, S. R., Parametric relations for a-b-g filter predictor, IEEE
%      Trans. on Automatic Control, AC-12, June 1967
%   TENNE, D. and Singh, T., Characterizing Performance a-b-g Filters, IEEE
%      Transactions on Aerospace and Electronic Systems, 38, 2002
% September 2013; Version: v1; Last revision: 2013-09-18
% Changelog:
%
%------------------------------- BEGIN CODE -------------------------------

if nargin == 3
    varProcess = var(process);
    varNoise = var(noisy);
    l = varProcess * dt / varNoise; % lambda
    r = (4+l-sqrt(8*l+l^2))/4;
    alpha = 1 - r^2;
    beta = 2*(2-alpha)-4*sqrt(1-alpha);
    gamma = beta^2/(2*alpha);
elseif nargin == 1 && length(process) == 3
    alpha = process(1);
    beta = process(2);
    gamma = process(3);
else
    error('evalABGParam : Incorrect Parameters!');
end

if ( alpha > 0 && alpha < 2 && beta > 0 && beta < (4-2*alpha) && ...
        gamma > 0 && gamma < (4*alpha*beta)/(2*alpha) )
    stability = 'Stable';
else
    stability = 'Unstable';
end
%-------------------------------- END CODE --------------------------------


function f = p27_f ( n, x )

%*****************************************************************************80
%
%% P27_F evaluates the objective function for problem 27.
%
%  Discussion:
%
%    F can be regarded as a function of R = SQRT ( X(1)^2 + X(2)^2 ).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 January 2001
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Zbigniew Michalewicz,
%    Genetic Algorithms + Data Structures = Evolution Programs,
%    Third Edition,
%    Springer Verlag, 1996,
%    ISBN: 3-540-60676-9,
%    LC: QA76.618.M53.
%
%  Parameters:
%
%    Input, integer N, the number of variables.
%
%    Input, real X(N), the argument of the objective function.
%
%    Output, real F, the value of the objective function.
%
  r = sqrt ( x(1)^2 + x(2)^2 );

  a = ( 1.0 + 0.001 * r^2 )^( -2 );

  b = ( sin ( r ) )^2 - 0.5;

  f = 0.5 + a * b;

  return
end


function [ distMoment ] = CalcNormalDistributionMoments( paramMu, paramSigmaSquared, momentOrder )
% See https://en.wikipedia.org/wiki/Normal_distribution#Moments.

switch(momentOrder)
    case(1)
        distMoment = (paramMu ^ momentOrder);
    case(2)
        distMoment = (paramMu ^ momentOrder) + paramSigmaSquared;
    case(3)
        distMoment = (paramMu ^ momentOrder) + (3 * paramMu * paramSigmaSquared);
    case(4)
        distMoment = (paramMu ^ momentOrder) + (6 * (paramMu ^ 2) * paramSigmaSquared) + (3 * (paramSigmaSquared ^ 2));
    case(5)
        distMoment = (paramMu ^ momentOrder) + (10 * (paramMu ^ 3) * paramSigmaSquared) + (15 * paramMu * (paramSigmaSquared ^ 2));
    case(6)
        distMoment = (paramMu ^ momentOrder) + (15 * (paramMu ^ 4) * paramSigmaSquared) + (45 * (paramMu ^ 2) * (paramSigmaSquared ^ 2)) + (15 * (paramSigmaSquared ^ 3));
    case(7)
        distMoment = (paramMu ^ momentOrder) + (21 * (paramMu ^ 5) * paramSigmaSquared) + (105 * (paramMu ^ 3) * (paramSigmaSquared ^ 2)) + (105 * paramMu * (paramSigmaSquared ^ 3));
    case(8)
        distMoment = (paramMu ^ momentOrder) + (28 * (paramMu ^ 6) * paramSigmaSquared) + (210 * (paramMu ^ 4) * (paramSigmaSquared ^ 2)) + (420 * (paramMu ^ 2) * (paramSigmaSquared ^ 3)) + (105 * (paramSigmaSquared ^ 4));
    otherwise
        gridRadius      = 10 * sqrt(paramSigmaSquared);
        gridNaumSamles  = 1e6;
        vX = linspace(paramMu - gridRadius, paramMu + gridRadius, gridNaumSamles);
        dX = mean(diff(vX));
        vNormalPdf = (1 / sqrt(2 * pi * paramSigmaSquared)) * exp(-( (vX - paramMu) .^ 2 ) ./ (2 * paramSigmaSquared));
        distMoment = sum( (vX .^ momentOrder) .* vNormalPdf * dX);
end

end


function [ll,lls]=stdtloglik(x,mu,sigma2,nu)
% Log likelihood of the Standardized T distribution
%
% USAGE:
%   [LL,LLS]=stdtloglik(X,MU,SIGMA2,NU)
%
% INPUTS:
%   X      - Standardized T random variables, either scalar or column vector
%   MU     - Mean of X, either scalar or size(x)
%   SIGMA2 - Variance of X, either scalar or size(x)
%   V      - Degree of freedom parameters, either scalar or size(x)
%
% OUTPUTS:
%   LL    - Log-likelihood evaluated at X
%   LLS   - Vector of log-likelihoods corresponding to X
%
% COMMENTS:
%   V>2
%
% REFERENCES:
%   [1] Cassella and Berger (1990) 'Statistical Inference'
%
% See also STDTCDF, STDTINV, STDTRND, STDTPDF

% Copyright:
% Kevin Sheppard
% kevin.sheppard@economics.ox.ac.uk
% Revision: 1    Date: 9/1/2004

[T,K]=size(x);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Input Checking
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if K~=1
    error('X must be a column vector');
end

if nargin==4
    if length(mu)~=1 && ~all(size(mu)==[T K])
        error('mu must be either a scalar or the same size as X');
    end
    if any(sigma2<=0)
        error('sigma2 must contain only positive elements')
    end
    if length(sigma2)==1
        sigma2=sigma2*ones(T,K);
    elseif size(sigma2,1)~=T || size(sigma2,2)~=1
        error('sigma2 must be a scalar or a vector with the same dimensions as X');
    end
    if length(nu)>1 || nu<=2
        error('nu must be a scalar greater than 2');
    end
    x=x-mu;
else
    error('Only 4 inputs supported');
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Input Checking
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%Compute the log likelihood
ll = T*gammaln(0.5*(nu+1)) - T*gammaln(nu/2) - T/2*log(pi*(nu-2)) ...
    - 0.5*sum(log(sigma2)) - ((nu+1)/2)*sum(log(1 + (x.^2)./(sigma2*(nu-2))));

%Compute the individual log likelihoods if needed
if nargout>1
    lls = gammaln(0.5*(nu+1)) - gammaln(nu/2) - 1/2*log(pi*(nu-2))...
        - 0.5*(log(sigma2)) - ((nu+1)/2)*(log(1 + (x.^2)./(sigma2*(nu-2))));
end


% Box volume maximization
% Boyd, Kim, Vandenberghe, and Hassibi, "A Tutorial on Geometric Programming"
% Written for CVX by Almir Mutapcic 02/08/06
% (a figure is generated)
%
% Maximizes volume of a box-shaped structure which has constraints
% on its total wall area, its total floor area, and which has lower
% and upper bounds on the aspect ratios. This leads to a GP:
%
%   maximize   h*w*d
%       s.t.   2(h*w + h*d) <= Awall, w*d <= Afloor
%              alpha <= h/w <= beta
%              gamma <= d/w <= delta
%
% where variables are the box height h, width w, and depth d.

% problem constants
alpha = 0.5; beta = 2; gamma = 0.5; delta = 2;

% varying parameters for an optimal trade-off curve
N = 10;
Afloor = logspace(1,3,N);
Awall  = [100 1000 10000];
opt_volumes = zeros(length(Awall),N);

disp('Computing optimal box volume for:')

% setup various GP problems with varying parameters
cvx_setpath
cvx_setspath
for k = 1:length(Awall)
  Awall_k = Awall(k);
  fprintf( 'Awall = %d:\n', Awall(k) );
  for n = 1:N
    % resolve the problem with varying parameters
    Afloor_n = Afloor(n);
    fprintf( '    Afloor = %7.2f: ', Afloor(n) );
    cvx_begin gp quiet
      variables h w d
      % objective function is the box volume
      maximize( h*w*d )
      subject to
        2*(h*w + h*d) <= Awall_k; %#ok
        w*d <= Afloor_n; %#ok
        alpha <= h/w <= beta; %#ok
        gamma <= d/w <= delta; %#ok
    cvx_end
    fprintf( 'max_volume = %3.2f\n', cvx_optval );
    opt_volumes(k,n) = cvx_optval;
  end
end
cvx_clearspath
cvx_clearpath

% plot the tradeoff curve
figure, clf
loglog(Afloor,opt_volumes(1,:), Afloor,opt_volumes(2,:), Afloor,opt_volumes(3,:));
xlabel('Afloor'); ylabel('V');


function f1 = p09_f1 ( x )

%*****************************************************************************80
%
%% P09_F1 evaluates the first derivative for problem 9.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 January 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the value of the variable.
%
%    Output, real F1, the first derivative of the
%    objective function.
%
  f1 = 2.0 * x ...
    - 10.0 * cos ( x * x - 3.0 * x + 2.0 ) ...
    * ( 2.0 * x - 3.0 );

  return
end


function pdf = quasigeometric_pdf ( x, a, b )

%*****************************************************************************80
%
%% QUASIGEOMETRIC_PDF evaluates the Quasigeometric PDF.
%
%  Discussion:
%
%    PDF(A,B;X) =    A                     if 0  = X;
%               = (1-A) * (1-B) * B^(X-1)  if 1 <= X.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 January 2009
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Darren Glass, Philip Lowry,
%    Quasiquasigeometric Distributions and Extra Inning Baseball Games,
%    Mathematics Magazine,
%    Volume 81, Number 2, April 2008, pages 127-137.
%
%    Paul Nahin,
%    Digital Dice: Computational Solutions to Practical Probability Problems,
%    Princeton University Press, 2008,
%    ISBN13: 978-0-691-12698-2,
%    LC: QA273.25.N34.
%
%  Parameters:
%
%    Input, integer X, the independent variable.
%    0 <= X
%
%    Input, real A, the probability of 0 successes.
%    0.0 <= A <= 1.0.
%
%    Input, real B, the depreciation constant.
%    0.0 <= B < 1.0.
%
%    Output, real PDF, the value of the PDF.
%
  if ( x < 0 )

    pdf = 0.0;

  elseif ( x == 0 )

    pdf = a;

  elseif ( b == 0.0 )

    if ( x == 1 )
      pdf = 1.0;
    else
      pdf = 0.0;
    end

  else

    pdf = ( 1.0 - a ) * ( 1.0 - b ) * b^( x - 1 );

  end

  return
end


function normVal=dualQuatNorm(dq)
%%DUALQUATNORM Compute the norm of a dual quaternion. This is defined as
%           dq*dq^*, where dq^* is the conjugate of the dual quaternion.
%           The result is a dual quaternion with no hypercomplex components
%           (but it might have both a real and a dual component). Dual
%           quaternions are often used for simultaneously representing
%           orientation and position. A dual quaternion consists of two
%           parts dq=q1+eps*q2, where q1 and q2 are quaternions and eps is
%           a dual number. Dual numbers are such that eps^2=0 and have
%           various rules for multiplication with complex numbers. Note
%           that the norm does not depend on the handedness of the
%           quaternion algebra, even though the dualQuatMult and quatMult
%           functions do.
%
%INPUTS: dq A dual quaternion represented as a 4X2 matrix dq(:,1) is the
%           non-dual quaternion and dq(:,2) is the dual quaternion (the
%           ones times eps, the dual number). The elements of each
%           quaternion are ordered q(1,1)+i*q(2,1)+j*q(3,1)+k*q(4,1), where
%           i,j and k are the typical hypercomplex numbers.
%
%OUTPUTS: normVal The value of the norm of the dual quaternion. This is a
%                 dual quaternion with no complex parts, but it might have
%                 a dual part (normVal(1,:) can be nonzero). A unit dual
%                 quaternion has only a real part and no dual part
%                 (normVal(1,1)=1,normVal(2,1)=0) nor complex parts.
%
%Dual quaternions and common operations including computation of the norm
%of the dual quaternion are discussed in [1]. The norm of a standard
%(non-dual) quaternion is generally just taken to be the same as the norm
%of a typical 4X1 vector.
%
%REFERENCES:
%[1] B. Kenwright, "A beginners guide to dual-quaternions: What they are,
%    how they work, and how to use them for 3D character hierarchies," in
%    Proceedings of the 20th International Conference on Computer Graphics,
%    Visualization and Computer Vision, Prague, Czech Republic, 24-27 Jun.
%    2012.
%
%November 2015 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

normVal=dualQuatMult(dq,dualQuatConj(dq));

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 pass = test_periodic(pref)
% Test 'periodic' syntax for linear ODEs.

if ( nargin == 0 )
    pref = cheboppref();
end
tol = 1e4*pref.bvpTol;

%% A simple ODE:

% Chebop:
N = chebop(@(u) diff(u, 2) - u);

% Periodic RHS:
rhs = chebfun(@(x) sin(pi*x));

% Apply periodic BCs manually:
N.bc = @(u) [u(-1) - u(1) ; feval(diff(u),-1) - feval(diff(u), 1)];
u = mldivide(N, rhs, pref);

% Apply via 'periodic':
N.bc = 'periodic';
v = mldivide(N, rhs, pref);

% Compare results:
pass(1) = norm(u - v) < tol;

%% A periodic piecewise system:

d = [-pi, 0, pi];
A = chebop(d);
A.op = @(x, u, v) [u-diff(v) ; diff(u,2)+v];
x = chebfun('x',d);
f = [chebfun(0, d) ; cos(x)];
A.bc = 'periodic';
uv = mldivide(A, f, pref);

trueSoln = [cos(x+3*pi/4)/sqrt(2) ; cos(x+pi/4)/sqrt(2)];
pass(2) = norm(uv - trueSoln) < tol;

%% Eigenvalue problem:

d = [-pi, 0, pi];
A = chebop(d);
A.op = @(x, u, v) [u-diff(v) ; diff(u,2)+v];
A.bc = 'periodic';
B = chebop(d);
B.op = @(x, u, v) [v + u ; diff(v)];

[V, D] = eigs(A, B, 5, 0, pref);
e = diag(D);

% Sort the eigenvalues to ensure things will work on all machines. Eigs() does
% not appear to return the eigenvalues in a consistent way for different
% machines. We expect five pair of eigenvalues to appear, check whether they are
% all there
% `sort(x)` sorts complex values by abs() and then by angle(). In order have
% consistent sorting, we move all the eigenvalues up into the first quadrant
% before sorting them.
[ignored, idx] = sort(real(e));
e = e(idx);

e12 = e(1:2);
e35 = e(3:5);
[ignored, idx] = sort(imag(e12));
e12 = e12(idx);
[ignored, idx] = sort(imag(e35));
e35 = e35(idx);

e = [e12; e35];

pass(3) = norm(real(e) - [0 0 1 1 1].', inf) + ...
    norm(imag(e) - [-1 1 -1 0 1].', inf) < tol;
pass(4) = norm(V{1}(pi) - V{1}(pi), inf) + norm(V{2}(pi) - V{2}(pi), inf) < tol;

%% Test the TRIGCOLLOC class. FIRST ORDER AND CONSTANT COEFFICIENTS:
%  u' + u = cos(x), on [0 2*pi].

% Set domain, operator L, and rhs f.
dom = [0 2*pi];
L = chebop(@(u) diff(u) + u, dom);
f = chebfun(@(x) cos(x), dom);

% Solve with TRIGCOLLOC.
L.bc = 'periodic';
u = L \ f;

% Compare with exact solution.
exact = chebfun(@(x) 1/2*cos(x) + 1/2*sin(x), dom, 'periodic');
pass(5) = norm(u - exact, inf) < tol;
pass(6) = isequal(get(u.funs{1}, 'tech'), @trigtech);

%% Test the TRIGCOLLOC class. FIRST ORDER AND VARIABLES COEFFICIENTS:
%  u' + (1+cos(x))u = cos(2x), on [-2*pi 2*pi].

% Set domain, c, and rhs f.
dom = [-2*pi 2*pi];
f = chebfun(@(x) cos(2*x), dom);

% Set chebop L. We construct the variable coefficient inside the chebop.
L = chebop(@(x, u) diff(u) + (1 + cos(x)).*u, dom);
L.bc = 'periodic';

% Solve with TRIGCOLLOC.
u = L \ f;

pass(7) = norm(L*u - f) < tol;
pass(8) = abs(u(dom(1)) - u(dom(2))) < tol;
pass(9) = isequal(get(u.funs{1}, 'tech'), @trigtech);

%% Test the TRIGCOLLOC class. SECOND ORDER AND CONSTANT COEFFICIENTS:
%  u'' + 10u' + 5u = cos(x), on [-2*pi 2*pi].

% Set domain, constants coefficients a and b, operator L,
% and rhs f.
dom = [-2*pi 2*pi];
a = 10;
b = 5;
L = chebop(@(u) diff(u, 2) + a*diff(u) + b*u, dom);
L.bc = 'periodic';
f = chebfun(@(x) cos(x), dom);

% Solve with TRIGCOLLOC.
u = L \ f;

% Compare with exact solution.
exact = chebfun(@(x) 1/29*cos(x) + 5/58*sin(x), dom, 'periodic');
pass(10) = norm(u - exact, inf) < tol;
pass(11) = isequal(get(u.funs{1}, 'tech'), @trigtech);

%% Test the TRIGCOLLOC class. SECOND ORDER AND VARIABLE COEFFICIENTS:
%  (2+cos(4x))u'' + sin(cos(2x))u' + exp(cos(x))u = cos(x), on [-pi pi].

% Set domain, variable coefficients a, b and c, and rhs f.
dom = [-pi pi];
a = chebfun(@(x) 2 + cos(4*x), dom);
b = chebfun(@(x) sin(cos(2*x)), dom, 'periodic');
c = chebfun(@(x) exp(cos(x)), dom);
f = chebfun(@(x) cos(x), dom);

% Set chebop. The variale coefficients have been constructed outside the
% chebop, some with 'periodic', some without it.
L = chebop(@(u) a.*diff(u, 2) + b.*diff(u) + c.*u, dom);
L.bc = 'periodic';

% Solve with TRIGCOLLOC.
u = L \ f;

pass(12) = norm(L*u - f) < tol;
pass(13) = abs(u(dom(1)) - u(dom(2))) < tol;
pass(14) = abs(feval(diff(u), dom(1)) - feval(diff(u), dom(2))) < tol;
pass(15) = isequal(get(u.funs{1}, 'tech'), @trigtech);

%% Test the TRIGCOLLOC class. THIRD ORDER AND VARIABLE COEFFICIENTS:
%  (2+cos(x))u''' + sin(cos(2x))u'' + exp(cos(x))u' + sin(x)u = cos(x),
%  on [-pi pi].

% Set domain, variable coefficients a, b, c and d, and rhs f.
dom = [-pi pi];
a = chebfun(@(x) 2 + cos(x), dom);
b = chebfun(@(x) sin(cos(2*x)), dom);
c = chebfun(@(x) exp(cos(x)), dom);
d = chebfun(@(x) sin(x), dom);
f = chebfun(@(x) cos(x), dom);

% Set chebop.
L = chebop(@(u) a.*diff(u, 3) + b.*diff(u, 2) + c.*diff(u) + d.*u, dom);
L.bc = 'periodic';

% Solve with TRIGCOLLOC.
u = L \ f;

pass(16) = norm(L*u - f) < tol;
pass(17) = abs(u(dom(1)) - u(dom(2))) < tol;
pass(18) = abs(feval(diff(u), dom(1)) - feval(diff(u), dom(2))) < tol;
pass(19) = abs(feval(diff(u, 2), dom(1)) - feval(diff(u, 2), dom(2))) < tol;
pass(20) = isequal(get(u.funs{1}, 'tech'), @trigtech);

%% Test the TRIGCOLLOC class. FOURTH ORDER AND VARIABLE COEFFICIENTS:
%  (2+cos(x))u'''' + sin(cos(2x))u''' + exp(cos(x))u'' + ...
%  sin(x)u' + sin(2*x)u = cos(10*x), on [-pi pi].

% Set domain, variable coefficients aa, bb, cc, dd and ee, and rhs f.
dom = [-pi pi];
a = chebfun(@(x) 2 + cos(x), dom);
b = chebfun(@(x) sin(cos(2*x)), dom);
c = chebfun(@(x) exp(cos(x)), dom);
d = chebfun(@(x) sin(x), dom);
e = chebfun(@(x) sin(2*x), dom);
f = chebfun(@(x) cos(10*x), dom);

% Set chebop.
L = chebop(@(u) a.*diff(u, 4) + b.*diff(u, 3) + c.*diff(u, 2) + ...
    d.*diff(u) + e.*u, dom);
L.bc = 'periodic';

% Solve with TRIGCOLLOC.
u = L \ f;

pass(21) = norm(L*u - f) < tol;
pass(22) = abs(u(dom(1)) - u(dom(2))) < tol;
pass(23) = abs(feval(diff(u), dom(1)) - feval(diff(u), dom(2))) < tol;
pass(24) = abs(feval(diff(u, 2), dom(1)) - feval(diff(u, 2), dom(2))) < tol;
pass(25) = abs(feval(diff(u, 3), dom(1)) - feval(diff(u, 3), dom(2))) < tol;
pass(26) = isequal(get(u.funs{1}, 'tech'), @trigtech);

%% Test breakpoint introduced by the domain.
%  u' + u = cos(x), on [0 pi 2*pi].

dom = [0 pi 2*pi];
L = chebop(@(u) diff(u) + u, dom);
f = chebfun(@(x) cos(x), dom);
L.bc = 'periodic';
u = L \ f;

pass(27) = norm(L*u - f) < tol;
pass(28) = abs(u(dom(1)) - u(dom(end))) < tol;
pass(29) = isequal(get(u.funs{1}, 'tech'), @chebtech2);

%% Test breakpoint introduced by a coefficient.
%  u'' + abs(x)u = 1, on [-1 1].

dom = [-1 1];
L = chebop(@(x,u) diff(u,2) + abs(x).*u, dom);
L.bc = 'periodic';
u = L \ 1;

pass(30) = norm(L*u - 1) < tol;
pass(31) = abs(u(dom(1)) - u(dom(2))) < tol;
pass(32) = isequal(get(u.funs{1}, 'tech'), @chebtech2);

%% Test the TRIGSPEC class. FIRST ORDER AND VARIABLES COEFFICIENTS:
%  u' + (1+cos(x))u = cos(2x), on [-2*pi 2*pi].

% Set domain, c, and rhs f.
dom = [0 2*pi];
f = chebfun(@(x) cos(2*x), dom);

% Set chebop L. We construct the variable coefficient inside the chebop.
L = chebop(@(x, u) diff(u) + (1 + cos(x)).*u, dom);
L.bc = 'periodic';

% Solve with TRIGSPEC.
pref.discretization = @trigspec;
u = solvebvp(L, f, pref);

pass(33) = norm(L*u - f) < tol;
pass(34) = abs(u(dom(1)) - u(dom(2))) < tol;
pass(35) = isequal(get(u.funs{1}, 'tech'), @trigtech);
pass(36) = isreal(u);

%% Test the TRIGSPEC class. SECOND ORDER AND VARIABLE COEFFICIENTS:
%  (2+cos(4x))u'' + sin(cos(2x))u' + exp(cos(x))u = cos(x), on [-pi pi].

% Set domain, variable coefficients a, b and c, and rhs f.
dom = [-pi pi];
a = chebfun(@(x) 2 + cos(4*x), dom);
b = chebfun(@(x) sin(cos(2*x)), dom, 'periodic');
c = chebfun(@(x) exp(cos(x)), dom);
f = chebfun(@(x) cos(x), dom);

% Set chebop. The variale coefficients have been constructed outside the
% chebop, some with 'periodic', some without it.
L = chebop(@(u) a.*diff(u, 2) + b.*diff(u) + c.*u, dom);
L.bc = 'periodic';

% Solve with TRIGSPEC.
pref.discretization = 'coeffs';
u = solvebvp(L, f, pref);

pass(37) = norm(L*u - f) < tol;
pass(38) = abs(u(dom(1)) - u(dom(2))) < tol;
pass(39) = abs(feval(diff(u), dom(1)) - feval(diff(u), dom(2))) < tol;
pass(40) = isequal(get(u.funs{1}, 'tech'), @trigtech);
pass(41) = isreal(u);

end


function c = correlation_besselj ( n, rho, rho0 )

%*****************************************************************************80
%
%% CORRELATION_BESSELJ evaluates the Bessel J correlation function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 February 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Petter Abrahamsen,
%    A Review of Gaussian Random Fields and Correlation Functions,
%    Norwegian Computing Center, 1997.
%
%  Parameters:
%
%    Input, integer N, the number of arguments.
%
%    Input, real RHO(N,1), the arguments.
%
%    Input, real RHO0, the correlation length.
%
%    Output, real C(N,1), the correlations.
%
  rho = rho ( : );

  rhohat = abs ( rho ) / rho0;

  c = besselj ( 0, rhohat );

  return
end


%% Machine Learning Online Class
%  Exercise 8 | Anomaly Detection and Collaborative Filtering
%
%  Instructions
%  ------------
%
%  This file contains code that helps you get started on the
%  exercise. You will need to complete the following functions:
%
%     estimateGaussian.m
%     selectThreshold.m
%     cofiCostFunc.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

%% ================== Part 1: Load Example Dataset  ===================
%  We start this exercise by using a small dataset that is easy to
%  visualize.
%
%  Our example case consists of 2 network server statistics across
%  several machines: the latency and throughput of each machine.
%  This exercise will help us find possibly faulty (or very fast) machines.
%

fprintf('Visualizing example dataset for outlier detection.\n\n');

%  The following command loads the dataset. You should now have the
%  variables X, Xval, yval in your environment
load('ex8data1.mat');

%  Visualize the example dataset
plot(X(:, 1), X(:, 2), 'bx');
axis([0 30 0 30]);
xlabel('Latency (ms)');
ylabel('Throughput (mb/s)');

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

%% ================== Part 2: Estimate the dataset statistics ===================
%  For this exercise, we assume a Gaussian distribution for the dataset.
%
%  We first estimate the parameters of our assumed Gaussian distribution,
%  then compute the probabilities for each of the points and then visualize
%  both the overall distribution and where each of the points falls in
%  terms of that distribution.
%
fprintf('Visualizing Gaussian fit.\n\n');

%  Estimate my and sigma2
[mu, sigma2] = estimateGaussian(X);

%  Returns the density of the multivariate normal at each data point (row)
%  of X
p = multivariateGaussian(X, mu, sigma2);

%  Visualize the fit
visualizeFit(X,  mu, sigma2);
xlabel('Latency (ms)');
ylabel('Throughput (mb/s)');

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

%% ================== Part 3: Find Outliers ===================
%  Now you will find a good epsilon threshold using a cross-validation set
%  probabilities given the estimated Gaussian distribution
%

pval = multivariateGaussian(Xval, mu, sigma2);

[epsilon, F1] = selectThreshold(yval, pval);
fprintf('Best epsilon found using cross-validation: %e\n', epsilon);
fprintf('Best F1 on Cross Validation Set:  %f\n', F1);
fprintf('   (you should see a value epsilon of about 8.99e-05)\n\n');

%  Find the outliers in the training set and plot the
outliers = find(p < epsilon);

%  Draw a red circle around those outliers
hold on
plot(X(outliers, 1), X(outliers, 2), 'ro', 'LineWidth', 2, 'MarkerSize', 10);
hold off

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

%% ================== Part 4: Multidimensional Outliers ===================
%  We will now use the code from the previous part and apply it to a
%  harder problem in which more features describe each datapoint and only
%  some features indicate whether a point is an outlier.
%

%  Loads the second dataset. You should now have the
%  variables X, Xval, yval in your environment
load('ex8data2.mat');

%  Apply the same steps to the larger dataset
[mu, sigma2] = estimateGaussian(X);

%  Training set
p = multivariateGaussian(X, mu, sigma2);

%  Cross-validation set
pval = multivariateGaussian(Xval, mu, sigma2);

%  Find the best threshold
[epsilon, F1] = selectThreshold(yval, pval);

fprintf('-> Best epsilon found using cross-validation: %e\n', epsilon);
fprintf('-> Best F1 on Cross Validation Set:  %f\n', F1);
fprintf('# Outliers found: %d\n', sum(p < epsilon));
fprintf('   (you should see a value epsilon of about 1.38e-18)\n\n');
pause


% f6.m
% Schaffer's F6 function
% commonly used to test optimization/global minimization problems
%
% z = 0.5+ (sin^2(sqrt(x^2+y^2))-0.5)/((1+0.01*(x^2+y^2))^2)

function [out]=f6(in)
 x=in(:,1);
 y=in(:,2);
 num=sin(sqrt(x.^2+y.^2)).^2 - 0.5;
 den=(1.0+0.01*(x.^2+y.^2)).^2;

 out=0.5 +num./den;


function mean = rayleigh_mean ( a )

%*****************************************************************************80
%
%% RAYLEIGH_MEAN returns the mean of the Rayleigh PDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, the parameter of the PDF.
%    0.0 < A.
%
%    Output, real MEAN, the mean of the PDF.
%
  mean = a * sqrt ( 0.5 * pi );

  return
end


function g=firkaiser(L,beta,varargin)
%FIRKAISER  Kaiser-Bessel window
%   Usage:  g=firkaiser(L,beta);
%           g=firkaiser(L,beta,...);
%
%   `firkaiser(L,beta)` computes the Kaiser-Bessel window of length *L* with
%   parameter *beta*. The smallest element of the window is set to zero when
%   the window has an even length. This gives the window perfect whole-point
%   even symmetry, and makes it possible to use the window for a Wilson
%   basis.
%
%   `firkaiser` takes the following flags at the end of the input arguments:
%
%     'normal'   Normal Kaiser-Bessel window. This is the default.
%
%     'derived'  Derived Kaiser-Bessel window.
%
%     'wp'       Generate a whole point even window. This is the default.
%
%     'hp'       Generate half point even window.
%
%   Additionally, `firkaiser` accepts flags to normalize the output. Please
%   see the help of |setnorm|. Default is to use `'null'` normalization.
%
%   Note that odd-length Derived Kaiser-Bessel windows are not
%   mathematically defined, yet they are supported by this code.
%
%   See also: firwin, setnorm
%
%   References: opsc89

%   AUTHOR: unknown. Additions by Clara Hollomey

if nargin<2
  error('Too few input arguments.');
end;

if numel(beta)>1
  error('beta must be a scalar.');
end;

% Define initial value for flags and key/value pairs.
definput.import={'setnorm'};
definput.importdefaults={'null'};
definput.flags.centering={'wp','hp'};
definput.flags.stype={'normal','derived'};

[flags,keyvals]=ltfatarghelper({},definput,varargin);

cent=0;
if flags.do_hp
  cent=.5;
end;

if flags.do_normal

  if (L == 1)
    g = 1;
  else
    m = L - 1;
    k = (0:m)'+rem(L,2)/2-.5+cent;
    k = 2*beta/(m)*sqrt(k.*(m-k));
    g = besseli(0,k)/besseli(0,beta);
  end;

  g=ifftshift(g);

  if ((flags.do_wp && rem(L,2)==0) || ...
      (flags.do_hp && rem(L,2)==1))

    % Explicitly zero last element. This is done to get the right
    % symmetry, and because that element sometimes turns negative.
    g(floor(L/2)+1)=0;
  end;

else

  %if rem(L,2)==1
  %  error('The length of the choosen window must be even.');
  %end;

  if flags.do_wp
    %if rem(L,4)==0
    %  L2=L/2+2;
    %else
      L2=floor(L/2+1);
    %end;
  else
    L2=floor((L+1)/2);
  end;

  % Compute a normal Kaiser window
  g_normal=fftshift(firkaiser(L2,beta,flags.centering));

  g1=sqrt(cumsum(g_normal(1:L2))./sum(g_normal(1:L2)));

  if flags.do_wp
    if rem(L,2)==0
      g=[flipud(g1);...
         g1(2:L/2)];
    else
      g=[flipud(g1);...
         g1(1:floor(L/2))];
    end;
  else
      if rem(L,2)==0
         g=[flipud(g1);0;...
         g1(1:end-1)];
      else
         g=[flipud(g1);...
         g1(1:end-1)];
      end
  end;

  if ((flags.do_wp && rem(L,2)==0)) %|| ...
      %(flags.do_hp && rem(L,2)==1))

    % Explicitly zero last element. This is done to get the right
    % symmetry, and because that element sometimes turn negative.
    g(floor(L/2)+1)=0;
  end;

end;

% The besseli computation sometimes generates a zero imaginary component.
g=real(g);

g=setnorm(g,flags.norm);


%Recursive Zonal Equal Area Sphere Partitioning: Utilities
%
% Recursive Zonal Equal Area (EQ) Sphere Partitioning Toolbox.
% Release 1.10 2005-06-01
%
%Functions
%=========
%
%  area_of_cap            Area of spherical cap
%  area_of_collar         Area of spherical collar
%  area_of_ideal_region   Area of one region of an EQ partition
%  area_of_sphere         Area of sphere
%  cart2polar2            Convert Cartesian to spherical polar coordinates on S^2
%  euc2sph_dist           Convert Euclidean to spherical distance
%  euclidean_dist         Euclidean distance between two points
%  fatcurve               Create a parameterized cylindrical surface
%  haslight               Check if axis handle has a light attached
%  ideal_collar_angle     Ideal angle for spherical collars of an EQ partition
%  illustration_options   Options for illustrations of EQ partitions
%  partition_options      Options for EQ partition
%  polar2cart             Convert spherical polar to Cartesian coordinates
%  sph2euc_dist           Convert spherical to Euclidean distance
%  spherical_dist         Spherical distance between two points on the sphere
%  sradius_of_cap         Spherical radius of spherical cap of given area
%  volume_of_ball         Volume of the unit ball

% Copyright 2004-2005 Paul Leopardi for the University of New South Wales.
% $Revision 1.10 $ $Date 2005-06-01 $
% Function changed name from e2s to euc2sph_dist
% Function changed name from s2e to sph2euc_dist
% Function changed name from s2x to polar2cart
% Function changed name from x2s2 to cart2polar2
% Add new function fatcurve
% Add new function haslight
% Clean up descriptions
% Documentation files renamed
% $Revision 1.00 $ $Date 2005-02-13 $
%
% For licensing, see COPYING.
% For references, see AUTHORS.
% For revision history, see CHANGELOG.


function [X_mean]=wmean(X,W)

% function [X_mean]=wmean(X,W)
% ------------------------------------------------------------------------
% This function calculates the weighted mean of X using the weights defined
% in the vector W.
%
% Uses the following formula: X_mean=sum(X.*W)./sum(W);
%
% 12/09/2008
% ------------------------------------------------------------------------

%%

X=X(:);
W=W(:);
X_mean=sum(X.*W)./sum(W);

%% END

%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% 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 3 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, see <http://www.gnu.org/licenses/>.


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

choice = [0.01 0.03 0.1 0.3 1 3 10 30]';
minError = Inf;
curC = Inf;
cur_sigma = Inf;

for i = 1:8
	for j = 1:8
		model = svmTrain(X, y, choice(i), @(x1, x2) gaussianKernel(x1, x2, choice(j)));
		predictions = svmPredict(model,Xval);
		error = mean(double(predictions ~= yval));
		if error < minError
			minError = error;
			curC = choice(i);
			cur_sigma = choice(j);
		end
	end
end

C = curC;
sigma = cur_sigma;

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

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

end


function [ a, b, c ] = line_exp2imp_2d ( p1, p2 )

%*****************************************************************************80
%
%% LINE_EXP2IMP_2D converts an explicit line to implicit form in 2D.
%
%  Discussion:
%
%    The explicit form of a line in 2D is:
%
%      ( P1, P2 ) = ( (X1,Y1), (X2,Y2) ).
%
%    The implicit form of a line in 2D is:
%
%      A * X + B * Y + C = 0
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 December 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real P1(2,1), P2(2,1), two points on the line.
%
%    Output, real A, B, C, the implicit form of the line.
%

%
%  Take care of degenerate cases.
%
  if ( p1(1:2,1) == p2(1:2,1) )
    fprintf ( 1, '\n' );
    fprintf ( 1,  'LINE_EXP2IMP_2D - Fatal error!\n' );
    fprintf ( 1,  '  P1 = P2\n' );
    fprintf ( 1,  '  P1 = %f  %f\n', p1(1:2,1) );
    fprintf ( 1,  '  P2 = %f  %f\n', p2(1:2,1) );
    error ( 'LINE_EXP2IMP_2D - Fatal error!' );
  end

  a = p2(2,1) - p1(2,1);
  b = p1(1,1) - p2(1,1);
  c = p2(1,1) * p1(2,1) - p1(1,1) * p2(2,1);

  norm = a * a + b * b + c * c;

  if ( 0.0 < norm )
    a = a / norm;
    b = b / norm;
    c = c / norm;
  end

  if ( a < 0.0 )
    a = -a;
    b = -b;
    c = -c;
  end

  return
end


function A = genWattsStrogotzGraph(N,K,rewireProb)
%%GENWATTSSTROGOTZGRAPH Generates a random instance of the Watts-Strogotz
%                       model as described in [1].
%
%INPUT:
% N: The number of nodes to be used in generating the graph.
% K: The number of connected neighbors for each node. This must be an even
%    number.
% rewireProb: The probability that any single edge connecting a given node
%             to its neighbor will be changed to connect to a different
%             node chosen uniformly at random from the set of nodes which
%             do not at that time share an edge with the given node.
%
%OUTPUT:
% A: The adjacency matrix for the final graph.
%
%EXAMPLE: Generates an instance of the Watts-Strogotz model.
% N = 30;
% K = 4;
% rewireProb = 0.3;
% A = genWattsStrogotzGraph(N,K,rewireProb);
% g = graph(A);
% plot(g,"MarkerSize",degree(g),"Layout","circle")
%
%REFERENCES:
%[1] D. J. Watts and S. H. Strogatz, "Collective dynamics of 'small-world'
%    networks," Nature, vol. 393, no. 6684, pp. 440-442, 1998.
%
%August 2022 Codie T. Lewis, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if mod(K,2)==1
    error('K must be even')
end
if rewireProb>1 || rewireProb<0
    error('rewireProb must be in the interval [0,1]')
end

A = zeros(N);
for i = 1:N-1
    for j = i+1:N
        A(i,j) = mod(abs(i-1-(j-1)),N-K/2)<=K/2;
    end
end
for i = 1:N
    for j = i+1:i+K/2
        jNode = mod(j-1,N)+1;
        if rand()<rewireProb
            A(i,jNode) = 0;
            free = find(A(i,:)==0);
            newNode = i;
            while newNode==i
                newNode = free(randi(length(free)));
            end
            if newNode<i
                A(newNode,i) = 1;
            else
                A(i,newNode) = 1;
            end
        end
    end
end
A = A+A';
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.


%% AMG TEST V: DIFFERENT INTERPOLATION OPERATORS
%
% We consider the effect of using different interpolation operators to
% interpolate fine grid values by coarse grid values. It is tested through
% the following choices in option.interpolation
%
% * 's' standard interpolation. Use the matrix A_fc as a weighted average
% of all connected coarse nodes.
% * 't' two-points interpolation. Use at most two connected coarse
% nodes.
% * 'a' aggegration (one-point) interpolation. Use the strongest connected
% coarse node.

%%
clear all; close all;
%% Unstructured mesh in 2-D
load lakemesh
showmesh(node,elem);
%%
% Standard interpolation
option.interpolation = 's';
[N,itStep,time,err] = amgtest(node,elem,[],option);
%%
colHeaders = {'Unknowns','Iterations','Time (sec)','Error'};
makeHtmlTable([N itStep time err],[],[],colHeaders,[],6);
%%
clf;
r = showrate(N,time,1);
xlabel('N'); ylabel('Time');
title(['Complexity is N^{' num2str(r) '}'],'Fontsize', 14);
%%
% Two-points interpolation
load lakemesh
option.interpolation = 't';
[N,itStep,time,err] = amgtest(node,elem,[],option);
%%
colHeaders = {'Unknowns','Iterations','Time (sec)','Error'};
makeHtmlTable([N itStep time err],[],[],colHeaders,[],6);
%%
clf;
r = showrate(N,time,1);
xlabel('N'); ylabel('Time');
title(['Complexity is N^{' num2str(r) '}'],'Fontsize', 14);
%%
% One point interpolation
load lakemesh
option.interpolation = 'a';
[N,itStep,time,err] = amgtest(node,elem,[],option);
%%
colHeaders = {'Unknowns','Iterations','Time (sec)','Error'};
makeHtmlTable([N itStep time err],[],[],colHeaders,[],6);
%%
clf;
r = showrate(N,time,1);
xlabel('N'); ylabel('Time');
title(['Complexity is N^{' num2str(r) '}'],'Fontsize', 14);

%% Unstructured mesh in 3-D
clear all; close all
load bunny;
showboundary3(node,elem);
view([-179 74]);
%%
% Standard interpolation
option.interpolation = 's';
[N,itStep,time,err] = amgtest3(node,elem,1,option);
%%
colHeaders = {'Unknowns','Iterations','Time (sec)','Error'};
makeHtmlTable([N itStep time err],[],[],colHeaders,[],6);
%%
clf;
r = showrate(N,time,1);
xlabel('N'); ylabel('Time');
title(['Complexity is N^{' num2str(r) '}'],'Fontsize', 14);
%%
% Two-points interpolation
load bunny
option.interpolation = 't';
[N,itStep,time,err] = amgtest3(node,elem,1,option);
%%
colHeaders = {'Unknowns','Iterations','Time (sec)','Error'};
makeHtmlTable([N itStep time err],[],[],colHeaders,[],6);
%%
clf;
r = showrate(N,time,1);
xlabel('N'); ylabel('Time');
title(['Complexity is N^{' num2str(r) '}'],'Fontsize', 14);
%%
% One point interpolation
load bunny
option.interpolation = 'a';
[N,itStep,time,err] = amgtest3(node,elem,1,option);
%%
colHeaders = {'Unknowns','Iterations','Time (sec)','Error'};
makeHtmlTable([N itStep time err],[],[],colHeaders,[],6);
%%
clf;
r = showrate(N,time,1);
xlabel('N'); ylabel('Time');
title(['Complexity is N^{' num2str(r) '}'],'Fontsize', 14);

%% Conclusion
% In general, if we use more coarse grids, we get more accurate
% interpolation and require less iteration steps. But the matrix on coarse
% level becomes denser, see nnz/Nc, which requires, indeed, more
% computational time in both smoother and coarse grid solver. In the
% extremly case, the one-point interpolation almost keeps the sparsity but
% iteration steps increase as level increases in the speed of J. The
% average using all neighboring points keeps the iteration steps but the
% sparsity increase a lot, especially in 3-D. The two-points interpolation
% seems a good balance.


function a = dif1 ( m, n )

%*****************************************************************************80
%
%% DIF1 returns the DIF1 matrix.
%
%  Discussion:
%
%    For a set of N points X(I) with equal spacing H, and a set of data
%    values Y(I) associated with those points, the product
%    1/(2*H) * A * Y returns an approximation to the first derivative
%    of Y(X) at the interior points X(2:N-1).
%
%  Example:
%
%    N = 5
%
%    0 +1  .  .  .
%   -1  0 +1  .  .
%    . -1  0 +1  .
%    .  . -1  0 +1
%    .  .  . -1  0
%
%  Rectangular Properties:
%
%    A is banded, with bandwidth 3.
%
%    A is tridiagonal.
%
%    Because A is tridiagonal, it has property A (bipartite).
%
%    A is integral: int ( A ) = A.
%
%    A is Toeplitz: constant along diagonals.
%
%  Square Properties:
%
%    A is antisymmetric: A' = -A.
%
%    Because A is antisymmetric, it is normal.
%
%    Because A is normal, it is diagonalizable.
%
%    If N is even, then A is nonsingular.
%    If N is odd, then A is singular.
%
%    If N is even, det ( A ) = 1.0.
%    If N is odd, det ( A ) = 0.0.
%
%    If N is odd, a null vector is ( 1, 0, 1, 0, ..., 1, 0, 1 )..
%
%    The family of matrices is nested as a function of N.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, N, the number of rows and columns of A.
%
%    Output, real A(M,N), the matrix.
%
  a = zeros ( m, n );

  for i = 1 : m

    if ( 0 < i - 1 )
      a(i,i-1) = -1.0;
    end

    if ( i + 1 <= n )
      a(i,i+1) = +1.0;
    end

  end

  return
end


function error_frobenius = r8mat_is_eigen_right ( n, k, a, x, lambda )

%*****************************************************************************80
%
%% R8MAT_IS_EIGEN_RIGHT determines the error in a right eigensystem.
%
%  Discussion:
%
%    An R8MAT is a matrix of real values.
%
%    This routine computes the Frobenius norm of
%
%      A * X - X * LAMBDA
%
%    where
%
%      A is an N by N matrix,
%      X is an N by K matrix (each of K columns is an eigenvector)
%      LAMBDA is a K by K diagonal matrix of eigenvalues.
%
%    This routine assumes that A, X and LAMBDA are all real.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    24 November 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%
%    Input, integer K, the number of eigenvectors.
%    K is usually 1 or N.
%
%    Input, real A(N,N), the matrix.
%
%    Input, real X(N,K), the K eigenvectors.
%
%    Input, real LAMBDA(K), the K eigenvalues.
%
%    Output, real ERROR_FROBENIUS, the Frobenius norm
%    of the difference matrix A * X - X * LAMBDA, which would be exactly zero
%    if X and LAMBDA were exact eigenvectors and eigenvalues of A.
%
  c(1:n,1:k) = a(1:n,1:n) * x(1:n,1:k);

  for j = 1 : k
    c(1:n,j) = c(1:n,j) - lambda(j) * x(1:n,j);
  end

  error_frobenius = r8mat_norm_fro ( n, k, c );

  return
end


clc, close all, clear all

load('teapot'); %loading matrix S
% % Matrix S stores all the control points of all the patches of
% % teapot surface such that
% % S(:,:,:,k) control points of kth patch, where k=1..32
% % Size of S(:,:,:,k) is 4 x 4 x 3, i.e., 16 control points and each
% % control point has three values (x,y,z)

% % S(:,:,1,k): x-coordates of control points of kth patch as 4 x 4 matrix
% % S(:,:,2,k): y-coordates of control points of kth patch as 4 x 4 matrix
% % S(:,:,3,k): z-coordates of control points of kth patch as 4 x 4 matrix
% % ------------------------------------
[r c d np]=size(S);
% % np: number of patches
ni=20; %number of interpolated values between end control points
u=linspace(0,1,ni); v=u;  %uniform parameterization
% % Higher the value of ni smoother the surface but computationally
% % expensive
% % ------------------------------------
% % Cubic Bezier interpolation of control points of each patch
for k=1:np
    Q(:,:,:,k)=bezierpatchinterp(S(:,:,:,k),u,v); %interpolation of kth patch
end
% % ------------------------------------
% % Plotting a signle Bezier Patch in many ways
k=13; %ploting kth patch
plotbezierpatch3D(S(:,:,:,k),Q(:,:,:,k))

% % Plotting Bezier surface (all the patches) in many ways
plotbeziersurface3D(S,Q)
% % --------------------------------
% % This program or any other program(s) supplied with it does not provide any
% % warranty direct or implied.
% % This program is free to use/share for non-commerical purpose only.
% % Kindly reference the author.
% % Author: Dr. Murtaza Khan
% % URL : http://www.linkedin.com/pub/dr-murtaza-khan/19/680/3b3
% % --------------------------------


function [ fea, out ] = ex_laplace2( varargin )
%EX_LAPLACE2 2D Laplace equation on a circle with nonzero boundary conditions.
%
%   [ FEA, OUT ] = EX_LAPLACE2( VARARGIN ) Laplace equation on a circle with
%   source term 0, nonzero boundary conditions and exact solution u=r^3*sin(3*th).
%   Accepts the following property/value pairs.
%
%       Input       Value/{Default}        Description
%       -----------------------------------------------------------------------------------
%       radi        scalar {1}             Radius of circle
%       hmax        scalar {0.1}           Max grid cell size
%       sfun        string {sflag1}        Shape function
%       iphys       scalar 0/{1}           Use physics mode to define problem    (=1)
%                                          or directly define fea.eqn/bdr fields (=0)
%       iplot       scalar 0/{1}           Plot solution (=1)
%                                                                                .
%       Output      Value/(Size)           Description
%       -----------------------------------------------------------------------------------
%       fea         struct                 Problem definition struct
%       out         struct                 Output struct

% Copyright 2013-2022 Precise Simulation, Ltd.

cOptDef = { ...
  'radi',     1; ...
  'hmax',     0.1; ...
  'refsol',   'hypot(x,y)^3*sin(3*atan2(y,x))'; ...
  'sfun',     'sflag1'; ...
  'icub',     2; ...
  'iphys',    1; ...
  'iplot',    1; ...
  'fid',      1 };
[got,opt] = parseopt(cOptDef,varargin{:});
fid       = opt.fid;

% Geometry definition.
gobj = gobj_circle( [0 0], opt.radi );
fea.geom.objects = { gobj };

% Grid generation.
fea.grid = gridgen(fea,'hmax',opt.hmax,'fid',fid,'dprim',false);
n_bdr    = max(fea.grid.b(3,:));        % Number of boundaries.

% Problem definition.
fea.sdim  = { 'x' 'y' };                % Coordinate names.
if ( opt.iphys==1 )

  fea = addphys(fea,@poisson);          % Add Poisson equation physics mode.
  fea.phys.poi.sfun = { opt.sfun };     % Set shape function.
  fea.phys.poi.eqn.coef{3,4} = { 0 };   % Set source term to zero.
  fea.phys.poi.bdr.coef{1,end} = repmat({opt.refsol},1,n_bdr);
  fea = parsephys(fea);                 % Check and parse physics modes.

else

  fea.dvar  = { 'u' };                  % Dependent variable name.
  fea.sfun  = { opt.sfun  };            % Shape function.

  % Define equation system.
  fea.eqn.a.form = { [2 3;2 3] };       % First row indicates test function space   (2=x-derivative + 3=y-derivative),
                                        % second row indicates trial function space (2=x-derivative + 3=y-derivative).
  fea.eqn.a.coef = { 1 };               % Coefficient used in assembling stiffness matrix.

  fea.eqn.f.form = { 1 };               % Test function space to evaluate in right hand side (1=function values).
  fea.eqn.f.coef = { 0 };               % Coefficient used in right hand side.

  % Define boundary conditions.
  fea.bdr.d     = cell(1,n_bdr);
 [fea.bdr.d{:}] = deal(opt.refsol);     % Assign reference solution to all boundaries (Dirichlet).

  fea.bdr.n     = cell(1,n_bdr);        % No Neumann boundaries ('fea.bdr.n' empty).

end

% Parse and solve problem.
fea       = parseprob(fea);             % Check and parse problem struct.
fea.sol.u = solvestat(fea,'fid',fid,'icub',opt.icub);   % Call to stationary solver.

% Postprocessing.
s_err = ['abs(',opt.refsol,'-u)'];
if ( opt.iplot>0 )
  figure
  subplot(3,1,1)
  postplot(fea,'surfexpr','u','axequal','on')
  title('Solution u')
  subplot(3,1,2)
  postplot(fea,'surfexpr',opt.refsol,'axequal','on')
  title('Exact solution')
  subplot(3,1,3)
  postplot(fea,'surfexpr',s_err,'axequal','on')
  title('Error')
end

% Error checking.
if ( size(fea.grid.c,1)==4 )
  xi = [0;0];
else
  xi = [1/3;1/3;1/3];
end
err = evalexpr0(s_err,xi,1,1:size(fea.grid.c,2),[],fea);
ref = evalexpr0('u',xi,1,1:size(fea.grid.c,2),[],fea);
err = sqrt(sum(err.^2)/sum(ref.^2));

if( ~isempty(fid) )
  fprintf(fid,'\nL2 Error: %f\n',err)
  fprintf(fid,'\n\n')
end

out.err  = err;
out.pass = out.err<5e-3;
if ( nargout==0 )
  clear fea out
end


function z = v_polynomial_zeros ( n )

%*****************************************************************************80
%
%% V_POLYNOMIAL_ZEROS returns zeroes of the Chebyshev polynomial V(n,x).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 April 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the polynomial.
%
%    Output, real Z(N), the zeroes.
%
  for i = 1 : n
    angle = ( 2 * n - 2 * i + 1 ) * pi / ( 2 * n + 1 );
    z(i) = cos ( angle );
  end

  return
end


function value = octahedron_unit_volume_nd ( n )

%*****************************************************************************80
%
%% OCTAHEDRON_UNIT_VOLUME_ND returns the volume of the unit octahedron in ND.
%
%  Integration region:
%
%    Points X(1:N) such that:
%
%      Sum ( Abs ( X(1:N) ) ) <= 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 November 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the dimension of the space.
%
%    Output, real OCTAHEDRON_UNIT_VOLUME_ND, the volume of
%    the unit octahedron.
%
  value = 2^n / prod ( 1 : n );

  return
end


function geometry_test20321 ( )

%*****************************************************************************80
%
%% TEST20321 tests TETRAHEDRON_EDGE_LENGTH_3D;
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
  dim_num = 3;

  tetra = [ ...
     0.577350269189626,  0.0, 0.0; ...
    -0.288675134594813,  0.5, 0.0; ...
    -0.288675134594813, -0.5, 0.0; ...
     0.0,                0.0, 0.816496580927726 ]';

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST20321\n' );
  fprintf ( 1, '  For a tetrahedron in 3D,\n' );
  fprintf ( 1, '  TETRAHEDRON_EDGE_LENGTH_3D computes the edge lengths;\n' );

  r8mat_transpose_print ( dim_num, 4, tetra, '  Tetrahedron vertices:' );

  edge_length = tetrahedron_edge_length_3d ( tetra );

  r8vec_print ( 6, edge_length, '  Edge lengths:' );

  return
end


function [Rt]=RateSimCIR(theta,kappa,sigma,lambda,dt,ratestart,months,tau)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% CIR term structure simulation, inputs below
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% clear all
% theta=0.10;
% kappa=0.05;
% sigma=0.075;
% lambda=-0.4;
% dt=1/12;
% months=120;
% ratestart=0.10;
% tau=[3/12,6/12,2,5];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Short Rate Dynamics
rt(1)=ratestart;
for i=1:months*4
    rt(i+1)=rt(i)+kappa*(theta-rt(i))*dt/4+sqrt(rt(i))*sigma*sqrt(dt/4)*randn(1);
end
% Term Structure Dynamics
for i=1:months
    rttemp=rt(i*4-3);
    rttemp1(i)=rt(i*4-3);
    for j=1:numel(tau)
        AffineG=sqrt((kappa+lambda)^2+2*sigma^2);
        AffineB=2*(exp(AffineG*tau(j))-1)/((AffineG+kappa+lambda)...
            *(exp(AffineG*tau(j))-1)+2*AffineG);
        AffineA=2*kappa*theta/(sigma^2)*log(2*AffineG*...
            exp((AffineG+kappa+lambda)*tau(j)/2)/((AffineG+kappa+lambda)*...
            (exp(AffineG*tau(j))-1)+2*AffineG));
        A(j)=-AffineA/tau(j);
        B(j)=AffineB/tau(j);
        Rt(i,j)=A(j)+B(j)*rttemp;
    end
end
Rt;

%%%%%%%%%%%%% MAKE THE GRAPH %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Rt;
% figure(2)
% surf(tau,1:120,Rt)
% xlabel('Time to Maturity (Fixed)')
% ylabel('Months Passed')
% title('A Given Simulation of the Term Structure (CIR)')