function [dist, t] = distancePointEdge3d(point, edge)
%DISTANCEPOINTEDGE3D Minimum distance between a 3D point and a 3D edge
%
%   DIST = distancePointEdge3d(POINT, EDGE);
%   Return the euclidean distance between edge EDGE and point POINT.
%   EDGE has the form: [x1 y1 z1 x2 y2 z2], and POINT is [x y z].
%
%   If EDGE is N-by-6 array, result is N-by-1 array computed for each edge.
%   If POINT is a N-by-3 array, the result is computed for each point.
%   If both POINT and EDGE are array, they must have the same number of
%   rows, and the result is computed for each couple point(i,:);edge(i,:).
%
%   [DIST POS] = distancePointEdge3d(POINT, EDGE);
%   Also returns the position of closest point on the edge. POS is
%   comprised between 0 (first point) and 1 (last point).
%
%   See also:
%   edges3d, points3d, distancePoints3d, distancePointLine3d
%

%   ---------
%   author : David Legland
%   INRA - CEPIA URPOI - MIA MathCell
%   created the 07/04/2004.
%

%   HISTORY
%   2005-06-24 rename, and change arguments sequence
%   2009-04-30 add possibility to return position of closest point
%   2011-04-14 add checkup for degenerate edges, improve speed, update doc

% direction vector of each edge
vl = edge(:, 4:6) - edge(:, 1:3);

% compute position of points projected on the supporting line
% (Size of t is the max number of edges or points)
t = linePosition3d(point, [edge(:,1:3) vl]);

% change position to ensure projected point is located on the edge
t(t < 0) = 0;
t(t > 1) = 1;

% difference of coordinates between projected point and base point
p0 = bsxfun(@plus, edge(:,1:3), [t .* vl(:,1) t .* vl(:,2) t .* vl(:,3)]);
p0 = bsxfun(@minus, point, p0);

% compute distance between point and its projection on the edge
dist = sqrt(sum(p0 .* p0, 2));


%  Computing an numerical Jordan decomposition
%                      X*J*inv(X)
%  of a given matrix A within a distance threshold theta, formulated under
%  a 'three-strikes principle'.  For details, see
%     Z. Zeng and T.Y. Li,  A numerical algorithm for computing the Jordan
%        Canonical Form, preprint, 2007
%
%  In a nutshell, let A be a matrix whose entries are given approximately
%  with error magnitude being small.  The exact JCF of A will be degraded.
%  However, it is possible to recover the underlying Jordan structure and
%  approximate X and J by NumericalJoranForm
%
%  Syntax:  There are several choices for either LHS or RHS
%        >>   LHS      =      RHS
%  ------------------- | --------------------------------------
%   [J,X]              |   RegularizedJCF(A)
%   [J,X,e,s,t]        |   RegularizedJCF(A,theta)
%                      |   RegularizedJCF(A,theta,tau,gap)
%
% Input:    A -- matrix whose AJCF is to be computed
%       theta -- (optional) distance threshold
%         tau -- (optional) deflation threshold, simple eigenvalues
%                  whose geometric condition numbers above tau will be deflated
%         gap -- (optional) singular value gap used in rank revealing
%
% Output:   J -- The numerical Jordan Canonical Form
%           X -- The principle vector matrix
%           e -- the list of distinct eigenvalues
%           s -- The Jordan block sizes of the eigenvalues
%           t -- the residuals (backward errors) and the staircase condition
%                  numbers of the eigenvalues


function [Afp,Bfp]=freeprecess(T,T1,T2,df)
%
%	Function simulates free precession and decay
%	over a time interval T, given relaxation times T1 and T2
%	and off-resonance df.  Times in ms, off-resonance in Hz.

phi = 2*pi*df*(T/1000);	% Off-resonance precession, radians.

% Relaxation exponentials
E1 = exp(-T/T1);
E2 = exp(-T/T2);

% Decay and phase due to off-resonance
Afp = [E2 0 0;0 E2 0;0 0 E1]*zrot(phi); % Mathieu, check order of matrix multiplication

% Regrowth
Bfp = [0 0 1-E1]';


function u=transsplit(u0,a,b,x,y,T,nstep)
%%
% Computes an approximation to the solution of
%
% $$ u_t+  a u_x + b u_y=0 $$
%
% with initial data u0 on the rectangle spanned by the vectors x and y. u0 must be
% of the size |[length(x),length(y)]|.
%
% Output is a 3d matrix of size |[lentgth(x),length(y),((T/dt)+1)]|.
%
%% Initial setup
dt=T/nstep; Nt=ceil(T/dt); dt=T/Nt;
dx=x(2)-x(1); dy=y(2)-y(1);
u=zeros(length(x),length(y),Nt+1);

%% Solving by Strang splitting
u(:,:,1) = u0;
u1 = transport(b,u(:,:,1),0.5*dt,dx,1);   % Transport in the x-direction
for i=2:Nt,
   u(:,:,i) = transport(a,u1,      dt,dy,2);   % Transport in the y-direction
   u1       = transport(b,u(:,:,i),dt,dx,1);   % Transport in the x-direction
end
u(:,:,Nt+1) = transport(a,u1,            dt,dy,2);   % Transport in the y-direction
u(:,:,Nt+1) = transport(b,u(:,:,Nt+1),0.5*dt,dx,1);   % Transport in the x-direction


close all;
clear all;
clc;
rng('default');
% Create the directory for storing images
[status_code,message,message_id] = mkdir('bin');
% Signal space
N = 256;
% Number of measurements
M = 32;
% Number of signals
Ss = [1, 2, 4, 8, 16, 32];
% Sparsity levels
Ks = 1:25;
num_trials = 100;
num_ks = length(Ks);
num_ss = length(Ss);
bp_success_with_k = zeros(num_ss, num_ks);

snr_threshold = 100;

for ns=1:num_ss
    % Current sparsity level
    S = Ss(ns);
    for nk=1:num_ks
        K = Ks(nk);
        num_bp_successes = 0;
        for nt=1:num_trials
            % Sensing matrix
            Phi = spx.dict.simple.gaussian_dict(M, N);
            X = model_1_data(N, K, S);
            % Measurement vectors
            Y = Phi * X;

            % OMP MMV solver instance (using P = 2 for P-SOMP)
            omp_solver = spx.pursuit.joint.OrthogonalMatchingPursuit(Phi, K, 2);
            % Solve the sparse recovery problem
            result = omp_solver.solve(Y);
            % Solution vectors
            X_OMP = result.Z;
            % Comparison
            cs = spx.commons.SparseSignalsComparison(X, X_OMP, K);
            snr = cs.cum_signal_to_noise_ratio;
            bp_success = snr > snr_threshold;
            num_bp_successes = num_bp_successes + bp_success;
            fprintf('S: %d, K=%d, trial=%d, residual omp: %e, SNR: %f dB\n'...
                , S, K, nt, cs.cum_difference_norm, snr);
        end
        bp_success_with_k(ns, nk) = num_bp_successes / num_trials;
    end
end

save ('bin/figure_1_spherical_dict_model_1_somp_success_with_k.mat');


%--------------------------------------------------------------------------
%   W = word(N, theta_tgt, window_N, lamda, position, theta_jam)
%--------------------------------------------------------------------------
%   功能：
%   正交投影加宽零陷抗干扰
%--------------------------------------------------------------------------
%   输入:
%           N                       阵元数
%           theta_tgt               波束指向 度
%           window_N                指向加窗
%           lambda                  波长
%           position                阵列坐标
%           theta_jam               干扰来向
%   输出：
%           W                       加权系数
%--------------------------------------------------------------------------
%   例子:
%   N = 64;
%   lambda = 1;                                                             %波长
%   dd = lambda/2;                                                          %阵元间距d = lambda/2
%   d = 0:dd:(N-1)*dd;                                                      %构建阵列坐标
%   W= word( 64, 0,@taylorwin, lambda, d, theta_jam);                       %生成权系数
%--------------------------------------------------------------------------
function  W = word(N, theta_tgt, window_N, lamda, position, theta_jam)
%--------------------------------------------------------------------------
%   指向角的导向矢量
%--------------------------------------------------------------------------
As = window_N(N).* ...
     exp(1j*2*pi*position*sind(theta_tgt)/lamda).';

%--------------------------------------------------------------------------
%   生成单位阵
%--------------------------------------------------------------------------
In= eye( N);
Ai = [Ai exp( 1j* 2* pi* position* sind( theta_jam(idx))/ lamda).'];

%--------------------------------------------------------------------------
%   干扰来向构造矩阵
%--------------------------------------------------------------------------
P =  In - Ai*( Ai'* Ai)^-1*Ai';                                             %干扰来向的投影矩阵的 正交子空间
W_temp=(As'*P)';
W= W_temp/sqrt( W_temp'* W_temp);                                           %归一化


function extended_rosenbrock_test ( )

%*****************************************************************************80
%
%% EXTENDED_ROSENBROCK_TEST works with the extended Rosenbrock function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 January 2012
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'EXTENDED_ROSENBROCK_TEST:\n' );
  fprintf ( 1, '  Test COMPASS_SEARCH with the extended Rosenbrock function.\n' );
  m = 4;
  delta_tol = 0.00001;
  delta = 0.3;
  k_max = 20000;

  x = [ - 1.2, 1.0,  -1.5, 1.2 ];
  r8vec_print ( m, x, '  Initial point X0:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X0) = %g\n', extended_rosenbrock ( m, x ) );

  [ x, fx, k ] = compass_search ( @extended_rosenbrock, m, x, delta_tol, delta, k_max );
  r8vec_print ( m, x, '  Estimated minimizer X1:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X1) = %g, number of steps = %d\n', fx, k );
%
%  Demonstrate correct minimizer.
%
  x = [ 1.0, 1.0, 1.0, 1.0 ];
  r8vec_print ( m, x, '  Correct minimizer X*:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X*) = %g\n', extended_rosenbrock ( m, x ) );

  return
end


function f = f10_f0 ( n, x, y )

%*****************************************************************************80
%
%% F10_F0 returns the value of function 10.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 January 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of evaluation points.
%
%    Input, real X(N,1), Y(N,1), the evalution points.
%
%    Output, real F(N,1), the function values.
%
  t1(1:n,1) = sqrt ( ( 80.0 * x(1:n,1) - 40.0 ).^2 + ( 90.0 * y(1:n,1) - 45.0 ).^2 );
  t2(1:n,1) = exp ( - 0.04 * t1(1:n,1) );
  t3(1:n,1) = cos ( 0.15 * t1(1:n,1) );

  f(1:n,1) = t2(1:n,1) .* t3(1:n,1);

  return
end


function [ prediction, value ] = LRClassify( weights, xTest )
    [dataSize, ~] = size(xTest);

    % Add the column of ones for the bias feature
    xTest = [ones(dataSize, 1) xTest];

    % Find the probability of the image being in each class
    probability = sigmoid(xTest * weights');

    % Find the best class label for the image
    % The best class is one with the highest probability
    [value, index] =  max(probability, [], 2);
    prediction = index - 1;
end


function sc = ssd(I,J,SII,SJJ)

% SSD  Sum of Squared Differences coefficient
%   SSD(I,J) computes the SSD score of matrices I and J:
%
%     SSD = 1/N*sum((I-J).^2)
%
%   where N = prod(size(I))
%   and   size(I) = size(J)
%
%   SSD(I,J,SII,SJJ) accepts useful intermediate results
%   that permit to speed up the calculations. These are:
%
%     SII = sum(sum(I.*I))
%     SJJ = sum(sum(J.*J))
%
%   See also PATCHCORR, ZNCC, CENSUS

% (c) 2005 Joan Sola

if size(I) ~= size(J)
    error ('Matrices must be the same size.')
else
    switch nargin
        case {1,2}
            SII = sum(sum(I.*I));
            SJJ = sum(sum(J.*J));
        case 3
            SJJ = sum(sum(J.*J));
    end

    SIJ = sum(sum(I.*J));

    N   = numel(I);

    sc  = sqrt((SII+SJJ-2*SIJ)/(N+eps));

end
% ========== End of function - Start GPL license ==========

%   # START GPL LICENSE

%---------------------------------------------------------------------
%
%   This file is part of SLAMTB, a SLAM toolbox for Matlab.
%
%   SLAMTB 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.
%
%   SLAMTB 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 SLAMTB.  If not, see <http://www.gnu.org/licenses/>.
%
%---------------------------------------------------------------------

%   SLAMTB is Copyright:
%   Copyright (c) 2008-2010, Joan Sola @ LAAS-CNRS,
%   Copyright (c) 2010-2013, Joan Sola,
%   Copyright (c) 2014-2015, Joan Sola @ IRI-UPC-CSIC,
%   SLAMTB is Copyright 2009
%   by Joan Sola, Teresa Vidal-Calleja, David Marquez and Jean Marie Codol
%   @ LAAS-CNRS.
%   See on top of this file for its particular copyright.

%   # END GPL LICENSE


function p = hexagon_shape_2d ( angle )

%*****************************************************************************80
%
%% HEXAGON_SHAPE_2D returns points on the unit regular hexagon in 2D.
%
%  Diagram:
%
%      120_____60
%        /     \
%    180/       \0
%       \       /
%        \_____/
%      240     300
%
%  Discussion:
%
%    The unit regular hexagon has radius 1.  The radius is the distance from
%    the center to any vertex, and it is also the length of any side.
%    An example of a unit hexagon is the convex hull of the points:
%
%      (   1,              0 ),
%      (   0.5,   sqrt (3)/2 ),
%      ( - 0.5,   sqrt (3)/2 ),
%      ( - 1,              0 ),
%      ( - 0.5, - sqrt (3)/2 ),
%      (   0.5, - sqrt (3)/2 ).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 May 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real ANGLE, the angle, in degrees, of the point.
%
%    Output, real P(2,1), the coordinates of the point.
%

%
%  Ensure that 0 <= ANGLE < 360.
%
  angle2 = r8_modp ( angle, 360.0 );
%
%  y = - sqrt(3) * x + sqrt(3)
%
  if ( 0.0 <= angle2 & angle2 <= 60.0 )

    p(1,1) = sqrt ( 3.0 ) / ( tan_deg ( angle2 ) + sqrt ( 3.0 ) );
    p(2,1) = tan_deg ( angle2 ) * p(1,1);
%
%  y = sqrt(3) / 2
%
  elseif ( angle2 <= 120.0 )

    p(2,1) = sqrt ( 3.0 ) / 2.0;
    p(1,1) = cot_deg ( angle2 ) * p(2,1);
%
%  y = sqrt(3) * x + sqrt(3)
%
  elseif ( angle2 <= 180.0 )

    p(1,1) = sqrt ( 3.0 ) / ( tan_deg ( angle2 ) - sqrt ( 3.0 ) );
    p(2,1) = tan_deg ( angle2 ) * p(1,1);
%
%  y = - sqrt(3) * x - sqrt(3)
%
  elseif ( angle2 <= 240.0 )

    p(1,1) = - sqrt ( 3.0 ) / ( tan_deg ( angle2 ) + sqrt ( 3.0 ) );
    p(2,1) = tan_deg ( angle2 ) * p(1,1);
%
%  y = - sqrt(3) / 2
%
  elseif ( angle2 <= 300.0 )

    p(2,1) = - sqrt ( 3.0 ) / 2.0;
    p(1,1) = cot_deg ( angle2 ) * p(2,1);
%
%  y = sqrt(3) * x - sqrt(3)
%
  elseif ( angle2 <= 360.0 )

    p(1,1) = - sqrt ( 3.0 ) / ( tan_deg ( angle2 ) - sqrt ( 3.0 ) );
    p(2,1) = tan_deg ( angle2 ) * p(1,1);

  end

  return
end


function K = gaussian_correlation ( s, t )

%*****************************************************************************80
%
%% GAUSSIAN_CORRELATION evaluates the Gaussian correlation function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 February 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Petter Abrahamsen,
%    A Review of Gaussian Random Fields and Correlation Functions,
%    Norwegian Computing Center, 1997.
%
%  Parameters:
%
%    Input, real S(*), T(*), pairs of argument values.
%
%    Output, real K(*), the correlation function values
%
  K = exp ( - ( s - t ).^2 );

  return
end


function [all_theta] = oneVsAll(X, y, num_labels, lambda)
%ONEVSALL trains multiple logistic regression classifiers and returns all
%the classifiers in a matrix all_theta, where the i-th row of all_theta
%corresponds to the classifier for label i
%   [all_theta] = ONEVSALL(X, y, num_labels, lambda) trains num_labels
%   logisitc regression classifiers and returns each of these classifiers
%   in a matrix all_theta, where the i-th row of all_theta corresponds
%   to the classifier for label i

% Some useful variables
m = size(X, 1);
n = size(X, 2);

% You need to return the following variables correctly
all_theta = zeros(num_labels, n + 1);

% Add ones to the X data matrix
X = [ones(m, 1) X];

% ====================== YOUR CODE HERE ======================
% Instructions: You should complete the following code to train num_labels
%               logistic regression classifiers with regularization
%               parameter lambda.
%
% Hint: theta(:) will return a column vector.
%
% Hint: You can use y == c to obtain a vector of 1's and 0's that tell use
%       whether the ground truth is true/false for this class.
%
% Note: For this assignment, we recommend using fmincg to optimize the cost
%       function. It is okay to use a for-loop (for c = 1:num_labels) to
%       loop over the different classes.
%
%       fmincg works similarly to fminunc, but is more efficient when we
%       are dealing with large number of parameters.
%
% Example Code for fmincg:
%
%     % Set Initial theta
%     initial_theta = zeros(n + 1, 1);
%
%     % Set options for fminunc
%     options = optimset('GradObj', 'on', 'MaxIter', 50);
%
%     % Run fmincg to obtain the optimal theta
%     % This function will return theta and the cost
%     [theta] = ...
%         fmincg (@(t)(lrCostFunction(t, X, (y == c), lambda)), ...
%                 initial_theta, options);
%

for c = 1:num_labels
    init_theta = zeros(n + 1, 1);
    options = optimset('GradObj', 'on', 'MaxIter', 50);
    [theta] = fmincg (@(t)(lrCostFunction(t, X, (y == c), lambda)), init_theta, options);
    all_theta(c,:) = theta';
end;

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

end


%
%  Univariate factorization that is capable of identifying multiple roots
%  and multiplicities accurately even if the polynomial is perturbed
%
%   Input    p -- coefficient vector of the polynomial to be factored
%          tol -- (optional) backward error tolerance
%    showroots -- (optional, 0 or 1) showing roots or not
%
%  Output    F -- kx3 matrix containing factors with
%                    each row [a,b,m] representing a factor (a*x+b)^m
%
%   Syntax:  >> LHS = RHS
%            where LHS and RHS can be any one of the following:
%
%               LHS options:   |  RHS options:
%               ---------------|------------------
%                 F            |  uvFactor(p)
%                [F,res]       |  uvFactor(p,tol)
%                [F,res,fcnd]  |  uvFactor(p,tol,1)
%


function b = isPointOnRay(point, ray, varargin)
%ISPOINTONRAY Test if a point belongs to a ray
%
%   B = isPointOnRay(PT, RAY);
%   Returns 1 if point PT belongs to the ray RAY.
%   PT is given by [x y] and RAY by [x0 y0 dx dy].
%
%   If PT is a N-by-2 array, and RAY is a M-by-4 array, then the result is
%   a N-by-M array containing the result of each pair-wise test.
%
%   B = isPointOnRay(PT, RAY, TOL);
%   Specifies the tolerance to use for testing if point is on the ray.
%
%   Example
%     ray = [10 20 3 4];
%     % test for a point on the ray
%     p1 = [16 28];
%     isPointOnRay(p1, ray)
%     ans =
%       logical
%        0
%     % test for a point on the supporting line but "before" the origin
%     p2 = [7 16];
%     isPointOnRay(p1, ray)
%     ans =
%       logical
%        0
%
%   See also:
%   rays2d, points2d, isPointOnLine, isPointOnEdge
%

%   ---------
%   author : David Legland
%   INRA - TPV URPOI - BIA IMASTE
%   created the 31/10/2003.
%

%   HISTORY
%   07/07/2005 normalize condition to test if on the line and add support
%       of multiple rays or points
%   22/05/2009 rename to isPointOnRay, add psb to specify tolerance
%   26/01/2010 was drawing a line before making test

% extract computation tolerance
tol = 1e-14;
if ~isempty(varargin)
    tol = varargin{1};
end

% number of rays and points
Nr = size(ray, 1);
Np = size(point, 1);

% if several rays or several points, adapt sizes of arrays
x0 = repmat(ray(:,1)', Np, 1);
y0 = repmat(ray(:,2)', Np, 1);
dx = repmat(ray(:,3)', Np, 1);
dy = repmat(ray(:,4)', Np, 1);
xp = repmat(point(:,1), 1, Nr);
yp = repmat(point(:,2), 1, Nr);

% test if points belongs to the supporting line
b1 = abs((xp-x0).*dy - (yp-y0).*dx) ./ (dx.*dx + dy.*dy) < tol;

% check if points lie the good direction on the rays
ind     = abs(dx) > abs(dy);
t       = zeros(size(b1));
t(ind)  = (xp(ind) - x0(ind)) ./ dx(ind);
t(~ind) = (yp(~ind) - y0(~ind)) ./ dy(~ind);

% combine the two tests
b = b1 & (t >= 0);


function a = line_adj_eigen_right ( n )

%*****************************************************************************80
%
%% LINE_ADJ_EIGEN_RIGHT returns the right eigenvectors of the LINE_ADJ matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 April 2015
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of A.
%
%    Output, real A(N,N), the right eigenvector matrix.
%
  a = zeros ( n, n );

  for i = 1: n
    for j = 1 : n
      angle = ( i * j ) * pi / ( n + 1 );
      a(i,j) = sqrt ( 2.0 / ( n + 1 ) ) * sin ( angle );
    end
  end

  return
end


function prob_test130 ( )

%*****************************************************************************80
%
%% TEST130 tests POWER_MEAN, POWER_SAMPLE, POWER_VARIANCE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
  nsample = 1000;
  seed = 123456789;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST130\n' );
  fprintf ( 1, '  For the Power PDF:\n' );
  fprintf ( 1, '  POWER_MEAN computes the mean;\n' );
  fprintf ( 1, '  POWER_SAMPLE samples;\n' );
  fprintf ( 1, '  POWER_VARIANCE computes the variance.\n' );

  a = 2.0;
  b = 3.0;

  check = power_check ( a, b );

  if ( ~check );
    fprintf ( 1, '\n' );
    fprintf ( 1, 'TEST130 - Fatal error!\n' );
    fprintf ( 1, '  The parameters are not legal.\n' );
    return
  end

  mean = power_mean ( a, b );
  variance = power_variance ( a, b );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  PDF parameter A =             %14f\n', a );
  fprintf ( 1, '  PDF parameter B =             %14f\n', b );
  fprintf ( 1, '  PDF mean =                    %14f\n', mean );
  fprintf ( 1, '  PDF variance =                %14f\n', variance );

  for i = 1 : nsample
    [ x(i), seed ] = power_sample ( a, b, seed );
  end

  mean = r8vec_mean ( nsample, x );
  variance = r8vec_variance ( nsample, x );
  xmax = max ( x(1:nsample) );
  xmin = min ( x(1:nsample) );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Sample size =     %6d\n', nsample );
  fprintf ( 1, '  Sample mean =     %14f\n', mean );
  fprintf ( 1, '  Sample variance = %14f\n', variance );
  fprintf ( 1, '  Sample maximum =  %14f\n', xmax );
  fprintf ( 1, '  Sample minimum =  %14f\n', xmin );

  return
end


function fx1 = p04_fx1 ( x )

%*****************************************************************************80
%
%% P04_FX1 evaluates the derivative of the function for problem 4.
%
%  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 FX1, the first derivative of the function at X.
%
  fx1 = exp ( x ) + 2.0 / ( 100.0 * x * x * x );

  return
end


function dist = distancePoints(p1, p2, varargin)
%DISTANCEPOINTS Compute distance between two points.
%
%   D = distancePoints(P1, P2)
%   Return the Euclidean distance between points P1 and P2.
%
%   If P1 and P2 are two arrays of points, result is a N1-by-N2 array
%   containing distance between each point of P1 and each point of P2.
%
%   D = distancePoints(P1, P2, NORM)
%   Compute distance using the specified norm. NORM=2 corresponds to usual
%   euclidean distance, NORM=1 corresponds to Manhattan distance, NORM=inf
%   is assumed to correspond to maximum difference in coordinate. Other
%   values (>0) can be specified.
%
%   D = distancePoints(..., 'diag')
%   compute only distances between P1(i,:) and P2(i,:).
%
%   See also:
%   points2d, minDistancePoints, nndist, hausdorffDistance
%

% ------
% Author: David Legland
% e-mail: david.legland@nantes.inra.fr
% Copyright 2009 INRA - Cepia Software Platform.
% created the 24/02/2004.
%

%   HISTORY :
%   25/05/2004: manage 2 array of points
%   07/04/2004: add option for computing only diagonal.
%   30/10/2006: generalize to any dimension, and manage different norms
%   03/01/2007: bug for arbitrary norm, and update doc
%   28/08/2007: fix bug for norms 2 and infinite, in diagonal case

%% Setup options

% default values
diag = false;
norm = 2;

% check first argument: norm or diag
if ~isempty(varargin)
    var = varargin{1};
    if isnumeric(var)
        norm = var;
    elseif strncmp('diag', var, 4)
        diag = true;
    end
    varargin(1) = [];
end

% check last argument: diag
if ~isempty(varargin)
    var = varargin{1};
    if strncmp('diag', var, 4)
        diag = true;
    end
end

% number of points in each array and their dimension
n1  = size(p1, 1);
n2  = size(p2, 1);
d   = size(p1, 2);

if diag
    % compute distance only for apparied couples of pixels
    dist = zeros(n1, 1);

    if norm == 2
        % Compute euclidian distance. this is the default case
        % Compute difference of coordinate for each pair of point
        % and for each dimension. -> dist is a [n1*n2] array.
        for i = 1:d
            dist = dist + (p2(:,i)-p1(:,i)).^2;
        end
        dist = sqrt(dist);

    elseif norm == inf
        % infinite norm corresponds to maximal difference of coordinate
        for i = 1:d
            dist = max(dist, abs(p2(:,i)-p1(:,i)));
        end

    else
        % compute distance using the specified norm.
        for i = 1:d
            dist = dist + power((abs(p2(:,i)-p1(:,i))), norm);
        end
        dist = power(dist, 1/norm);
    end
else
    % compute distance for all couples of pixels
    dist = zeros(n1, n2);

    if norm == 2
        % Compute euclidian distance. This is the default case.
        % Compute difference of coordinate for each pair of point
        % and for each dimension. -> dist is a [n1*n2] array.
        for i = 1:d
            % equivalent to:
            % dist = dist + ...
            %   (repmat(p1(:,i), [1 n2])-repmat(p2(:,i)', [n1 1])).^2;
            dist = dist + bsxfun (@minus, p1(:,i), p2(:, i)').^2;
        end
        dist = sqrt(dist);

    elseif norm == inf
        % infinite norm corresponds to maximal difference of coordinate
        for i = 1:d
            dist = max(dist, abs(bsxfun (@minus, p1(:,i), p2(:, i)')));
        end

    else
        % compute distance using the specified norm.
        for i = 1:d
            % equivalent to:
            % dist = dist + power((abs(repmat(p1(:,i), [1 n2]) - ...
            %     repmat(p2(:,i)', [n1 1]))), norm);
            dist = dist + power(abs(bsxfun(@minus, p1(:,i), p2(:, i)')), norm);
        end
        dist = power(dist, 1/norm);
    end
end


function [ err ] = residual_KR_robust( X1, X2, imsize1, imsize2, paras, sigma )

% parameretes sigma indicates the distance scope for inliers with homopraphy matrix, in pixels

k1 = paras(1);
k2 = paras(2);
theta = paras(3:5);
% yaw = paras(3);
% pitch = paras(4);
% roll = paras(5);

K1 = [k1, 0, imsize1(2)/2;
     0, k1, imsize1(1)/2;
     0,  0, 1];
K2 = [k2, 0, imsize2(2)/2;
      0, k2, imsize2(1)/2;
      0,  0, 1];
theta_m = [0         -theta(3) theta(2)
           theta(3)  0         -theta(1)
           -theta(2) theta(1)  0];
R = expm(theta_m);
% Ry = [cos(yaw),     0,              -sin(yaw);
%       0,            1,              0;
%       sin(yaw),     0,              cos(yaw)] ;
% Rp = [1,            0               0;
%       0,            cos(pitch),     sin(pitch);
%       0,            -sin(pitch),    cos(pitch)] ;
% Rr = [cos(roll),    sin(roll),      0;
%       -sin(roll),   cos(roll),      0;
%       0,            0,              1] ;
% R = Rr * Rp * Ry;

err = residual_H(X1, X2, K1, K2, R);

outlier = (abs(err) > sigma);
err(outlier) = sign(err(outlier)) .* (sigma + sigma * log(abs(err(outlier))/sigma));
% err(outlier) = sign(err(outlier)) .* sqrt(2*sigma*abs(err(outlier)) - sigma*sigma);

end


function [xs,ys] = snakeIterate(alpha,beta,gamma,x,y,NI,Fx,Fy)
%SNAKEITERATE Iterative solution of the snake equation.
%   [XS,YS] = SNAKEITERATE(ALPHA,BETA,GAMMA,X,Y,NI,Fx,Fy) computes the
%   [XS,YS] coordinates of a segmentation snake using the iterative
%   solution in Eq.(12-7) of DIPUM3E. Vectors X and Y are the initial
%   coordinates of the snake (provided in sequential order). These
%   vectors are updated during iteration. ALPHA, BETA, and GAMMA are
%   parameters in Eq. (12-7) and (12-8), and Fx, Fy are the 2D force
%   arrays obtained, for example, using DIPUM3E function snakeForce.
%
%   This function is normally run within an outer loop with snake-point
%   respacing after each execution of the loop. NI controls the number
%   of iterations of Eq. (12-7) before the snake points are respaced. A
%   common value of NI is 1, indicating one execution of point respacing
%   after each iteration of Eq. (12-7).
%
%   Copyright 2002-2020 Gatesmark
%
%   This function, and other functions in the DIPUM Toolbox, are based
%   on the theoretical and practical foundations established in the
%   book Digital Image Processing Using MATLAB, 3rd ed., Gatesmark
%   Press, 2020.
%
%   Book website: http://www.imageprocessingplace.com
%   License: https://github.com/dipum/dipum-toolbox/blob/master/LICENSE.txt

% PRELIMINARIES.
K = numel(x);
% Multiply the forces by gamma.
Fx = gamma*Fx;
Fy = gamma*Fy;

% CONSTRUCT MATRIX A IN EQ. (12-8) FOR USE IN EQ. (12-7).
% First construct matrix D2 in Eq. (12-9).
a = -2*ones(K,1);
b = 1*ones(K-1,1);
D2 = diag(a) + diag(b,-1) + diag(b,1);
D2(1,K) = 1;
D2(K,1) = 1;
% Next construct D4 in Eq. (12-10).
a = 6*ones(K,1);
b = -4*ones(K-1,1);
c = 1*ones(K-2,1);
D4 = diag(a) + diag(b,-1) + diag(b,1) + diag(c,-2) + diag(c,2);
D4(1,K) = -4;
D4(K,1) = -4;
D4(1,K-1) = 1;
D4(K-1,1) = 1;
D4(2,K) = 1;
D4(K,2) = 1;
% Construct matrix A. The inverse operation is performed during
% iteration.
D = alpha*D2 - beta*D4;
A = eye(K) - D;

% ITERATIVE SOLUTION.
for I = 1:NI
	% Obtain the force vectors fx and fy in Eq. (12-7). These are
	% obtained from Fx and Fy, the 2-D array components of the force
	% field F, by interpolating values of Fx and Fy at the locations of
	% the current snake coordinates, x and y. The 0 in the following
	% function call avoids NaNs in areas where there are no points to
	% interpolate. The order y,x is because function interp2 works with
	% (col,row), as opposed to (row,col) as in the book.
	fx = interp2(Fx,y,x,'linear',0);
	fy = interp2(Fy,y,x,'linear',0);

	% Compute new values of x and y using Eq. (12-7). Note the use of x =
	% A\(x + fx), as opposed to x = inv(A)*(x + fx), and similarly for y.
	% The former method is faster and more accurate.
	x = A\(x + fx);
	y = A\(y + fy);
end

% FORM THE SNAKE.
xs = x;
ys = y;


function v = legendre_van ( m, a, b, n, x )

%*****************************************************************************80
%
%% LEGENDRE_VAN returns the LEGENDRE_VAN matrix for [A,B].
%
%  Discussion:
%
%    The LEGENDRE_VAN matrix is the Legendre Vandermonde-like matrix.
%
%    Normally, the Legendre polynomials are defined on -1 <= XI <= +1.
%    Here, we assume the Legendre polynomials have been defined on the
%    interval A <= X <= B, using the mapping
%      XI = ( - ( B - X ) + ( X - A ) ) / ( B - A )
%    so that
%      Lab(A,B;X) = L(XI).
%
%    if ( I = 1 ) then
%      V(1,1:N) = 1
%    else if ( I = 2 ) then
%      V(2,1:N) = XI(1:N)
%    else
%      V(I,1:N) = ( (2*I-1) * XI(1:N) * V(I-1,1:N) - (I-1)*V(I-2,1:N) ) / I
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 April 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the number of rows of the matrix.
%
%    Input, real A, B, the limits of the interval.
%
%    Input, integer N, the number of columns of the matrix.
%
%    Input, real X(N), the abscissas.
%
%    Output, real V(M,N), the matrix.
%

%
%  Force X to be a row vector.
%
  x = ( x(:) .' );
%
%  Compute the normalized abscissas in [-1,+1].
%
  xi(1,1:n) = ( - 1.0 * ( b - x(1,1:n)     )   ...
                + 1.0 * (     x(1,1:n) - a ) ) ...
              /         ( b            - a );
%
%  Set up the matrix.
%
  v = zeros ( m, n );

  for i = 1 : m

    if ( i == 1 )
      v(i,1:n) = 1.0;
    elseif ( i == 2 )
      v(i,1:n) = xi(1,1:n);
    else
      v(i,1:n) = ( ( 2 * i - 1 ) * xi(1,1:n) .* v(i-1,1:n)   ...
                 + (   - i + 1 ) *              v(i-2,1:n) ) ...
                 / (     i );
    end

  end

  return
end


function [ xdp, ydp ] = dif_deriv_table ( nd, xd, yd )

%*****************************************************************************80
%
%% DIF_DERIV_TABLE computes the divided difference table for a derivative.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 June 2013
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Carl deBoor,
%    A Practical Guide to Splines,
%    Springer, 2001,
%    ISBN: 0387953663,
%    LC: QA1.A647.v27.
%
%  Parameters:
%
%    Input, integer ND, the size of the input table.
%
%    Input, real XD(ND), the abscissas for the divided
%    difference table.
%
%    Input, real YD(ND), the divided difference table.
%
%    Output, real XDP(ND-1), the abscissas for the divided
%    difference table for the derivative.
%
%    Output, real YDP(ND-1), the divided difference
%    table for the derivative.
%

%  Using a temporary copy of the difference table, shift the
%  abscissas to zero.
%
  xd_temp(1:nd) = xd(1:nd);
  yd_temp(1:nd) = yd(1:nd);

  [ xd_temp, yd_temp ] = dif_shift_zero ( nd, xd_temp, yd_temp );
%
%  Construct the derivative.
%
  xdp(1:nd-1) = 0.0;

  for i = 1 : nd - 1
    ydp(i) = i * yd_temp(i+1);
  end

  return
end


function [Fh,Vh]=honeyCombMesh(minV,maxV,pointSpacing)

% function [Fh,Vh]=honeyCombMesh(minV,maxV,pointSpacing)
% -----------------------------------------------------------------------
% This function creates the faces (Fh) and vertices (Vh) for a hexagon
% (honey comb) mesh. The hexagons are created between the limits minV
% (containing desired minimum X and Y coordinates) and maxV (containing
% desired maximum X and Y coordinates). The size of the hexagons is set by
% the desired point spacing.
%
% -----------------------------------------------------------------------

%% CREATE TRIANGULATION

maxV(2)=maxV(2)+pointSpacing;
[F,V]=triMeshEquilateral(minV,maxV,pointSpacing);

%% GET DUAL FOR HONEY-COMB

[Vh,Fd]=patch_dual(V,F,0);
numVert=cellfun(@(x) size(x,2),Fd);
Fh=Fd{numVert==6};

[Fh,Vh]=patchCleanUnused(Fh,Vh);

%%
% _*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 R = wishrand(S,nu);
%WISHRND Random matrices from Wishard distribution.
%   R = WISHRAND(S,N) returns a matrix of random numbers chosen
%   from the central Wishard distribution with parameters S and NU.
%
%   S is a symmetric positive definite scale matrix
%   NU is degrees of freedom
%
%   Note: E[R]=S
%
%   References: Gelman, Carlin, Stern, Dunson, Vehtari, and Rubin (2013).
%                 Bayesian Data Analysis, third edition.
%               Gentle (2003), Random Number Generation and Monte Carlo
%                 Methods, 2nd ed, Springer, p. 199, Algorithm 5.8.
%               Smith & Hocking (1972), Algorithm AS 53: Wishard Variate
%                 Generator, Applied Statistics, 21(3), pp. 341-345.
%
%	See also INVWISHRAND
%
% Copyright (c) 1999-2004 Aki Vehtari

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

if nargin < 2
  error('Requires two input arguments.');
end;

[d d2] = size(S);
if d ~= d2
  error('Matrix S must be square');
end

% Algorithm 5.8 step 0.
[T,p]=chol(S);
if p > 0
  error('Matrix S must be positive definite.');
end

if (nu >= d) && (nu == round(nu))
  % distribution is proper and degrees of freedom is integer
  % brute-force may be used, which is surprisingly faster in Matlab
  % at least up to d>10, nu>1000
  % Algorithm described e.g. in (Gelman et al., 2013)
  Y = T'*randn(d,nu);
  R = Y*Y'./nu;
else
  % distribution is not proper or degrees of freedom is not integer
  % (Gentle, 2003) Algorithm 5.8
  % Algorithm 5.8 step 1.
  Z=zeros(d);
  for j=2:d
    Z(1:j,j)=randn(j,1);
  end
  % Algorithm 5.8 step 2. Note that there is error in the book.
  % Book says nu-i, while it should be nu+1-i
  % See errata <http://www.scs.gmu.edu/~jgentle/rngbk/errata.htm>
  % gamrand below is same as chi2rnd(nu-(1:d)+1), but much faster using c-code
  y=gamrand((nu+1-(1:d)),nu+1-(1:d));
  % Algorithm 5.8 step 3.
  Z2=Z.^2;
  sy=sqrt(y);
  B=zeros(d);
  B(1,1)=y(1);
  % In Matlab 6.5 following loop is accelerated and thus quite fast
  for j=2:d
    B(j,j)=y(j)+sum(Z2(1:(j-1),j));
    B(1,j)=Z(1,j).*sy(1);
    B(j,1)=B(1,j);
    for i=2:(j-1)
      B(i,j)=Z(i,j).*sy(i)+sum(Z(1:(i-1),i).*Z(1:(i-1),j));
      B(j,i)=B(i,j);
    end
  end
  % Algorithm 5.8 step 4.
  R=T'*B*T/nu;
end


function [C,vol] = centroid(V,F,varargin)
  % CENTROID Compute the centroid of a closed polyhedron boudned by (V,F)
  %
  % C = centroid(V,F)
  % [C,vol] = centroid(V,F,'ParameterName',ParameterValue, ...)
  %
  % Inputs:
  %   V  #V by 3 list of mesh vertex positions
  %   F  #F by 3 list of triangle mesh indices
  %   Optional:
  %     'Robust' followed by whether to use more robust but costlier method for
  %       nearly closed input. {false}
  % Outputs:
  %   C  3-vector of centroid location
  %   vol  total volume of polyhedron
  %

  % default values
  robust = false;
  % Map of parameter names to variable names
  params_to_variables = containers.Map( {'Robust'}, {'robust'});
  v = 1;
  while v <= numel(varargin)
    param_name = varargin{v};
    if isKey(params_to_variables,param_name)
      assert(v+1<=numel(varargin));
      v = v+1;
      % Trick: use feval on anonymous function to use assignin to this workspace
      feval(@()assignin('caller',params_to_variables(param_name),varargin{v}));
    else
      error('Unsupported parameter: %s',varargin{v});
    end
    v=v+1;
  end

  if robust
    assert(size(V,2) == 3,'Only 3d supported');
    [TV,TT] = cdt(V,F);
    BC = barycenter(TV,TT);
    w = winding_number(V,F,barycenter(TV,TT))/(4*pi);
    TT = TT(abs(w)>0.5,:);
    BC = BC(abs(w)>0.5,:);
    vol = volume(TV,TT);
    C = sum(bsxfun(@times,vol,BC))/sum(vol);
    vol = sum(vol);
  else
    % "Calculating the volume and centroid of a polyhedron in 3d" [Nuernberg 2013]
    % http://www2.imperial.ac.uk/~rn/centroid.pdf
    switch size(V,2)
    case 2
      % https://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon
      % Rename corners
      A = V(F(:,1),:);
      B = V(F(:,2),:);
      D = A(:,1).*B(:,2) - B(:,1).*A(:,2);
      vol = 0.5*sum(D);
      C = (1/(6*vol)).*sum((A+B).*D);
    case 3
      % Rename corners
      A = V(F(:,1),:);
      B = V(F(:,2),:);
      C = V(F(:,3),:);
      % Needs to be **unnormalized** normals
      N = cross(B-A,C-A,2);
      % total volume via divergence theorem: ∫ 1
      vol = sum(sum(A.*N))/6;
      % centroid via divergence theorem and midpoint quadrature: ∫ x
      C = 1/(2*vol)*(1/24* sum(N.*((A+B).^2 + (B+C).^2 + (C+A).^2)));
    end
  end

end


function [mu vr] = ricestat(v, s)
%RICESTAT Mean and variance of Rice/Rician probability distribution.
%   [mu vr] = ricestat(v, s) returns the mean and variance of the Rice
%   distribution with parameters v and s.
%
%   R ~ Rice(v, s) if R = sqrt(X^2 + Y^2), where X ~ N(v*cos(a), s^2) and
%   Y ~ N(v*sin(a), s^2) are independent normal distributions (any real a).
%   Note that v and s are *not* the mean and standard deviation of R!
%
%   Reference: http://en.wikipedia.org/wiki/Rice_distribution (!)
%
%   Example:
%
%     % Compare expected and sample stats:
%     v = 5; s = 4; N = 1000;
%     r = ricernd(v*ones(1, N), s);
%     mu = mean(r), vr = var(r)
%     [Mu Vr] = ricestat(v, s)
%     % Plot histogram and mark expected mean +/- 1 stdev:
%     c = linspace(0, ceil(max(r)), 20);
%     w = c(2); % histogram bin-width
%     h = histc(r, c); bar(c, h, 'histc'); hold on
%     pk = N*w*ricepdf(Mu, v, s);
%     plot([Mu-sqrt(Vr) Mu+sqrt(Vr)], [pk pk]/2, 'ro-')
%     plot(Mu, pk/2, 'rx')
%
%   See also RICEPDF, RICERND, RICEFIT

%   Missing (?) 'See also's RICECDF, RICEINV, RICELIKE

%   Inspired by normstat from the MATLAB statistics toolbox
%   Copyright 2008 Ged Ridgway (Ged at cantab dot net)

L = Lhalf(-0.5 * v^2 / s^2);
mu = s * sqrt(pi/2) * L;
vr = 2*s^2 + v^2 - (pi * s^2 / 2) * L^2;

function l = Lhalf(x)
% Laguerre polynomial L_{1/2}(x)
% see Moments section of http://en.wikipedia.org/wiki/Rice_distribution
l = exp(x/2) * ( (1-x) * besseli(0, -x/2) - x*besseli(1, -x/2) );


function OutputName = Recognition(TestImage, m, A, Eigenfaces)
%-------------Project the selected test image and all of the training
%images into Eigenfaces space. Compare the Euclidean distances between them and find the
%  index of image who gets minmum Euclidean distances.
ProjectedImages = [];
Train_Number = size(A,2);
for i = 1 : Train_Number
    temp = Eigenfaces' * A(:,i); % Projection of centered images into facespace
    ProjectedImages = [ProjectedImages temp];
end

%-------------Project the test image you selected into Eigenfaces space-------------
InputImage = imread(TestImage);
temp = InputImage(:,:,1);

[irow icol] = size(temp);
InImage = reshape(temp',irow*icol,1);
Difference = double(InImage)-m;
Projected_TestImage = Eigenfaces'*Difference; % Test image feature vector

%----------------------- Calculate Euclidean distances and find the
%  index of image of minmum Euclidean distances--------------------
Euc_dist = [];
for i = 1 : Train_Number
    q = ProjectedImages(:,i);
    temp = ( norm( Projected_TestImage - q ) )^2;
    Euc_dist = [Euc_dist temp];
end

[Euc_dist_min , Recognized_index] = min(Euc_dist);
OutputName = strcat(int2str(Recognized_index),'.jpg');


function [sigma,mu,A]=mygaussfit(x,y,h)

%
% [sigma,mu,A]=mygaussfit(x,y)
% [sigma,mu,A]=mygaussfit(x,y,h)
%
% this function is doing fit to the function
% y=A * exp( -(x-mu)^2 / (2*sigma^2) )
%
% the fitting is been done by a polyfit
% the lan of the data.
%
% h is the threshold which is the fraction
% from the maximum y height that the data
% is been taken from.
% h should be a number between 0-1.
% if h have not been taken it is set to be 0.2
% as default.
%

%% threshold
if nargin==2, h=0.2; end

%% cutting
ymax=max(y);
xnew=[];
ynew=[];
for n=1:length(x)
    if y(n)>ymax*h;
        xnew=[xnew,x(n)];
        ynew=[ynew,y(n)];
    end
end

%% fitting
ylog=log(ynew);
xlog=xnew;
p=polyfit(xlog,ylog,2);
A2=p(1);
A1=p(2);
A0=p(3);
sigma=sqrt(-1/(2*A2));
mu=A1*sigma^2;
A=exp(A0+mu^2/(2*sigma^2));


function heated_plate ( epsilon, output_filename )

%*****************************************************************************80
%
%  Purpose:
%
%    MAIN is the main program for HEATED_PLATE.
%
%  Discussion:
%
%    This code solves the steady state heat equation on a rectangular region.
%
%    The sequential version of this program needs approximately
%    18/eps iterations to complete.
%
%
%    The physical region, and the boundary conditions, are suggested
%    by this diagram;
%
%                   W = 0
%             +------------------+
%             |                  |
%    W = 100  |                  | W = 100
%             |                  |
%             +------------------+
%                   W = 100
%
%    The region is covered with a grid of M by N nodes, and an N by N
%    array W is used to record the temperature.  The correspondence between
%    array indices and locations in the region is suggested by giving the
%    indices of the four corners:
%
%                  I = 0
%          [0][0]-------------[0][N-1]
%             |                  |
%      J = 0  |                  |  J = N-1
%             |                  |
%        [M-1][0]-----------[M-1][N-1]
%                  I = M-1
%
%    The steady state solution to the discrete heat equation satisfies the
%    following condition at an interior grid point:
%
%      W[Central] = (1/4) * ( W[North] + W[South] + W[East] + W[West] )
%
%    where "Central" is the index of the grid point, "North" is the index
%    of its immediate neighbor to the "north", and so on.
%
%    Given an approximate solution of the steady state heat equation, a
%    "better" solution is given by replacing each interior point by the
%    average of its 4 neighbors - in other words, by using the condition
%    as an ASSIGNMENT statement:
%
%      W[Central]  <=  (1/4) * ( W[North] + W[South] + W[East] + W[West] )
%
%    If this process is repeated often enough, the difference between successive
%    estimates of the solution will go to zero.
%
%    This program carries out such an iteration, using a tolerance specified by
%    the user, and writes the final estimate of the solution to a file that can
%    be used for graphic processing.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 July 2010
%
%  Author:
%
%    This MATLAB version by John Burkardt.
%
%  Reference:
%
%    Michael Quinn,
%    Parallel Programming in C with MPI and OpenMP,
%    McGraw-Hill, 2004,
%    ISBN13: 978-0071232654,
%    LC: QA76.73.C15.Q55.
%
%  Parameters:
%
%    Commandline argument 1, real EPSILON, the error tolerance.
%
%    Commandline argument 2, string OUTPUT_FILENAME, the name of the file into which
%    the steady state solution is written when the program has completed.
%
%  Local parameters:
%
%    Local, real DIFF, the norm of the change in the solution from
%    one iteration to the next.
%
%    Local, real MEAN, the average of the boundary values, used
%    to initialize the values of the solution in the interior.
%
%    Local, real U(M,N), the solution at the previous iteration.
%
%    Local, real W(M,N), the solution computed at the latest
%    iteration.
%
  m = 500;
  n = 500;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'HEATED_PLATE\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  A program to solve for the steady state temperature distribution\n' );
  fprintf ( 1, '  over a rectangular plate.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Spatial grid of %d by %d points.\n', m, n );
%
%  Read EPSILON from the command line or the user.
%
  if ( nargin < 1 )
    epsilon = input ( '  Enter EPSILON, the error tolerance.' );
  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  The iteration will repeat until the change is <= %e\n', epsilon );
%
%  Read OUTPUT_FILENAME from the command line or the user.
%
  if ( nargin < 2 )
    output_filename = input ( ...
      '  Enter OUTPUT_FILENAME, the name of the output file.' );
  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  The steady state solution will be written to "%s".\n', ...
    output_filename );
%
%  Set the boundary values, which don't change.
%
  w(2:m-1,1) = 100.0;
  w(2:m-1,n) = 100.0;
  w(m,1:n) = 100.0;
  w(1,1:n) =   0.0;
%
%  Average the boundary values, to come up with a reasonable
%  initial value for the interior.
%
  mean = ( ...
      sum ( w(2:m-1,1) ) ...
    + sum ( w(2:m-1,n) ) ...
    + sum ( w(m,1:n)   ) ...
    + sum ( w(1,1:n)   ) ) ...
    / ( 2 * m + 2 * n - 4 );
%
%  Initialize the interior solution to the mean value.
%
  w(2:m-1,2:n-1) = mean;
%
%  iterate until the  new solution W differs from the old solution U
%  by no more than EPSILON.
%
  iterations = 0;
  iterations_print = 1;
  diff = epsilon;

  fprintf ( 1, '\n' );
  fprintf ( 1, ' Iteration  Change\n' );
  fprintf ( 1, '\n' );

  tic;

  while ( epsilon <= diff )

    u(1:m,1:n) = w(1:m,1:n);

    w(2:m-1,2:n-1) = 0.25 * ( ...
        u(1:m-2,2:n-1) ...
      + u(3:m,2:n-1) ...
      + u(2:m-1,1:n-2) ...
      + u(2:m-1,3:n) );

    diff = max ( max ( abs ( u(1:m,1:n) - w(1:m,1:n) ) ) );

    iterations = iterations + 1;

    if ( iterations == iterations_print )
      fprintf ( 1, '  %8d  %14f\n', iterations, diff );
      iterations_print = 2 * iterations_print;
    end

  end

  wtime = toc;

  fprintf ( 1, '\n' );
  fprintf ( 1, '  %8d  %14f\n', iterations, diff );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Error tolerance achieved.\n' );
  fprintf ( 1, '  Wallclock time = %f\n', wtime );
%
%  Write the solution to the output file.
%
  output_unit = fopen ( output_filename, 'wt' );

  fprintf ( output_unit, '%d\n', m );
  fprintf ( output_unit, '%d\n', n );
  for i = 1 : m
    for j = 1 : n
      fprintf (output_unit, '  %f', w(i,j) );
    end
    fprintf ( output_unit, '\n' );
  end

  fclose ( output_unit );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Solution written to the output file "%s".\n', output_filename );
%
%  Terminate.
%

  fprintf ( 1, '\n' );
  fprintf ( 1, 'HEATED_PLATE:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );

  return
end


function X=solveSylvesterEq(A,B,C)
%%SOLVESYLVESTEREQ Solve the Sylester equation A*X+X*B=C for X, where A, B,
%           and C can be real or complex. This implementation only works
%           when a unique solution for X exists, which is the case when
%           none of the eigenvalues of A and B when summed together equals
%           0.
%
%INPUTS: A A pXp matrix.
%        B An rXr matrix.
%        C A pXr matrix.
%
%OUTPUTS: X The pXr matrix solving A*X+X*B=C.
%
%This function implements the Bartels-Stewart algorithm of [1]. The back
%substitution algorithm of Algorithm 7.6.2 in [2] is used for the second
%half of the algorithm, which also means that upper-triangular Schur
%decompositions are used for the first half of the algorithm.
%
%EXAMPLE:
%In this example, we solve a Sylvester equation and show that the result
%Tolerance is about 7e-14, which is good agreement.
% A=[3,  0,   0, 23;
%   -2,  5, -14, -6;
%   11, 11,  -7,  7;
%  -10, 15, -10, -1];
% B=[8,  4,   2,  6;
%   -7, -1,   1,  8;
%  -14, -1,  15, -2;
%  -14, 14,  -8,  2];
% C=[16,  3,  6,  8;
%     3, 11,  8, 11;
%     6,  8,  6, 13;
%     8, 11, 13,  1];
% X=solveSylvesterEq(A,B,C);
% AbsTol=max(max(abs(A*X+X*B-C)))
%
%REFERENCES
%[1] R. H. Bartels and G. W. Stewart, "Algorithm 432: Solution of the
%    matrix equation AX+XB=C [F4]," Communications of the ACM, pp. 820-826,
%    Sep. 1972.
%[2] G. H. Golub and C. F. Van Loan, Matrix Computations, 4th ed.
%    Baltimore: The Johns Hopkins Press, 2013.
%
%December 2022 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

%We use the complex Schur decomposition. If we used the real one, then
%Ap and Bp are not guaranteed to be upper triangular if the matrices have
%complex eigenvalues.
[U,Ap]=schur(A,'complex');
[V,Bp]=schur(B,'complex');
Cp=U'*C*V;

%Solve the transformed system using Algorithm 6.7.2 of [1].
Bp=-Bp;

r=size(Ap,1);
p=size(Bp,1);

I=eye(r,r);

for k=1:r
    Cp(1:p,k)=Cp(1:p,k)+Cp(1:p,1:(k-1))*Bp(1:(k-1),k);
    z=(Ap-Bp(k,k)*I)\Cp(1:p,k);
    Cp(1:p,k)=z;
end

%Cp hold the transformed result. Now undo the transformation.
X=U*Cp*V';

if(isreal(A)&&isreal(B)&&isreal(C))
    %If all of the inputs are real, then Cp should be real, not accounting
    %for finite precision limits.
    X=real(X);
end
end

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


function pass = test_curl( )
% Test curl

tol = 1e2*chebfunpref().cheb2Prefs.chebfun2eps;

% Check curl of a spherefun is a spherefunv.
u = spherefun(@(x,y,z) x.*y.*z);
u = curl(u);
pass(1) = isa(u,'spherefunv');

% Check curl of the zero function is zero
f = spherefun(@(x,y,z) 0*x);
pass(2) = norm(curl(f)) < tol;

%
% Check curl of a non-zero function gives the correct result
%

% Example 1
u = curl(spherefun(@(x,y,z) (x-y).*z));
% Exact curl
f = spherefun(@(x,y,z) (x-y).*y + z.^2);
g = spherefun(@(x,y,z) (y-x).*x + z.^2);
h = spherefun(@(x,y,z) -(x+y).*z);
exact = spherefunv(f,g,h);
pass(3) = norm(u-exact) < tol;

% Example 2
u = curl(spherefun(@(x,y,z) cos(4*z)));
% Exact curl
f = spherefun(@(x,y,z) -4*y.*sin(4*z));
g = spherefun(@(x,y,z) 4*x.*sin(4*z));
h = spherefun(@(x,y,z) 0*x);
exact = spherefunv(f,g,h);
pass(4) = norm(u-exact) < tol;

% Example 3
u = curl(spherefun(@(x,y,z) cos(4*x)));
% Exact curl
f = spherefun(@(x,y,z) 0*x);
g = spherefun(@(x,y,z) -4*z.*sin(4*x));
h = spherefun(@(x,y,z) 4*y.*sin(4*x));
exact = spherefunv(f,g,h);
pass(5) = norm(u-exact) < 100*tol;

% Example 4
u = curl(spherefun(@(x,y,z) cos(4*y)));
% Exact curl
f = spherefun(@(x,y,z) 4*z.*sin(4*y));
g = spherefun(@(x,y,z) 0*x);
h = spherefun(@(x,y,z) -4*x.*sin(4*y));
exact = spherefunv(f,g,h);
pass(6) = norm(u-exact) < 100*tol;

end


function [ G ] = gsp_non_uniform(N, r)
%GSP_NON_UNIFORM Create a random graph from non_uniform sampling of points
%   Usage:  G = gsp_non_uniform(N, r)
%           G = gsp_non_uniform(N)
%           G = gsp_non_uniform()
%
%   Input parameters:
%         N     : Number of nodes (default 200)
%         r     : Factor of non-uniformity (default 3)
%                 the histogram of x axis of samples is proportional to
%                 exp(x*r)
%   Output parameters:
%         G     : Graph structure.
%
%
%   Example:::
%
%          G = gsp_non_uniform(200, 1);
%          figure; gsp_plot_graph(G)
%          G = gsp_non_uniform(200, 5);
%          figure; gsp_plot_graph(G)
%
%
% see also: gsp_sensor, gsp_non_uniform_patch

% Author : Vassilis Kalofolias

% Optional input arguments
% if nargin < 2
%     k = 6;
% end

if nargin < 1
    N = 200;
end
if nargin < 2
    r = 3;
end

% sample x exponentially from [0,5]
x = exp(rand(N, 1) * r);
x = lin_map(sort(x), [0, 5]);
% sample y uniformly from [0,1]
y = rand(N, 1);
y = lin_map(y, [0, 1]);

coords = [x, y];

D = gsp_distanz(coords');

Ds = sort(D, 'ascend');
%max_min_dist = max(min(D + realmax * eye(N)));
s2 = mean(Ds(2,:).^2);
%s2 = mean(Ds(5,:).^2) / 9;

W = exp(- D.^2 / s2 / 4);
W(1:N+1:end) = 0;

% keep a neighbour for the most distant
min_kept_w = min(max(W));

%

% Kill all small connections but always have at least one neighbor
W = W .* (W >= min(min_kept_w, 0.1));

% binary?
%W = double(W>0);

G = gsp_graph(W, coords, [0 5 0 1]);
G.type = 'non_uniform';

end


function w = Lambert_W(x,branch)
% Lambert_W  Functional inverse of x = w*exp(w).
% w = Lambert_W(x), same as Lambert_W(x,0)
% w = Lambert_W(x,0)  Primary or upper branch, W_0(x)
% w = Lambert_W(x,-1)  Lower branch, W_{-1}(x)
%
% See: http://blogs.mathworks.com/cleve/2013/09/02/the-lambert-w-function/

% Copyright 2013 The MathWorks, Inc.

% Effective starting guess
if nargin < 2 || branch ~= -1
   w = ones(size(x));  % Start above -1
else
   w = -2*ones(size(x));  % Start below -1
end
v = inf*w;

% Haley's method
while any(abs(w - v)./abs(w) > 1.e-8)
   v = w;
   e = exp(w);
   f = w.*e - x;  % Iterate to make this quantity zero
   w = w - f./((e.*(w+1) - (w+2).*f./(2*w+2)));
end


% RING_POLAR_MAP_DER: Jacobian of the parameterization given in ring_polar_map.

function varargout = ring_polar_map_der (pts)

  if (iscell (pts))
    u = reshape (repmat (pts{1}(:), 1, numel (pts{2})), 1, []);
    v = reshape (repmat (pts{2}(:)', numel (pts{1}), 1), 1, []);
  else
    u = pts(1,:); v = pts(2,:);
  end

  jac = zeros (2, 2, numel (u));
  jac(1,1,:) =  cos (pi.*v/2);
  jac(2,1,:) =  sin (pi.*v/2);
  jac(1,2,:) = -pi*(u+1) .* sin (pi.*v/2)/2;
  jac(2,2,:) =  pi*(u+1) .* cos (pi.*v/2)/2;

  if (nargout == 1)
    varargout{1} = jac;
  elseif (nargout == 2)
    F = ring_polar_map (pts);
    varargout{1} = F;
    varargout{2} = jac;
  end

end


function x = Adj_Evaluate_FT(y,shift,boxlen,center,w)
% Adj_Evaluate_FT -- 1d unequispaced adjoint Fourier transform
% (with windowing). Adjoint of Evaluate_FT.
% Usage:
%   x = Evaluate_FT(y,shift,boxlen,center,w)
% Inputs:
%   y	      vector of length 2n
%   shift     vector of shifts
%   boxlen    half length of interval around each value of shift
%   center    boolean variable: 0/1 = unbiased/biased FT
%   w         tapering window of size 2*boxlen
% Outputs:
%   x      vector of length: n
% Description:
%  For w = 1, evaluates the Adj FT of a signal irregularly
%  sampled in frequency omega(j,k) = shift(j) + k, -boxlen <= k
%  <boxlen If center = 0,
%
%  x(t) = sum_m exp(i 2pi omega(m) t/n) y(k), -n/2 <= t < n/2
%
%  If center = 1,
%
%  x(t) = sum_m exp(i 2pi omega(m) t/n) y(k), 0 <= t < n
%
%  For arbitrary windows, y is first tapered with w.
%
%  Adj_Evaluate_FT uses two different methods for computing the
%  unesquispaced Fourier transform. If the number of shifts is less
%  than 8, it uses an exact method, otherwise it uses the
%  accelerated Adjoint USFFT.
%  See Also
%    Evaluate_FT, Adj_USFFT, Adj_USFT_simple
%
% By Emmanuel candes, 2003-2004

if nargin < 5,
  w = ones(1,2*boxlen);
end

if nargin < 4,
  center = 0;
end

n  = length(y)/2;
boxcnt = length(shift);

if (boxcnt <= 16)
  x = Adj_USFT_simple(y,shift,boxlen,center,w);
else
  % Make frequency grid
  k = (-boxlen):(boxlen -1);
  omega = meshgrid(shift,k) + meshgrid(k,shift).';
  omega = 2*pi*(omega(:))./n;

  y = repmat(w(:),boxcnt,1) .* y; % Tapering
  x = Adj_USFFT(n,y,omega,16,6,center)./sqrt(n); % Take Adjoint USFFT
end


function [x,y,w] = gqcircsegm ( n, omega, r )

%
%% GQCIRCSEGM computes the nodes and weights of a product gaussian formula
% on a circle segment of a disk centered at the origin
% with angles in [0,omega]

% uses the routines:
%
% r_jacobi.m, gauss.m from
% www.cs.purdue.edu/archives/2002/wxg/codes/OPQ.html
%
% trigauss.m
% http://www.math.unipd.it/~marcov/mysoft/trigauss.m
%
%  Modified:
%
%    16 May 2013
%
%  Author:
%
%    Gaspare Da Fies, Marco Vianello,
%    University of Padova
%
%  Parameters:
%
%    Input, integer n: algebraic degree of exactness.
%
%    Input, real omega: half-length of the angular interval, 0<omega<=pi
%
%    Input, r: radius of the disk
%
%    Output, xyw: (ceil((n+1)/2) x ceil((n+2)/2) x 3 array of (xnodes,ynodes,weights)

%
%  Compute the trigonometric gaussian formula on the arc.
%
  tw = trigauss ( n + 2, 0, omega );
%
%  Compute the algebraic gaussian formula on [-1,1];
%
  ab = r_jacobi ( ceil((n+1)/2), 0, 0 );
  xw = gauss ( ceil((n+1)/2), ab );
%
%  Create the grid.
%
  [ t, theta ] = meshgrid ( xw(:,1), tw(:,1) );
  [ w1, w2 ]   = meshgrid ( xw(:,2), tw(:,2) );
%
%  Nodal cartesian coordinates and weights.
%
  s = sin ( theta(:) );
  x = (r * cos ( theta(:) ))';
  y = (r * t(:) .* s)';
  w = (r^2 * s.^2 .* w1(:) .* w2(:))';

  return
end


function [nll,g,H,T] = LogisticLoss(w,X,y)
% w(feature,1)
% X(instance,feature)
% y(instance,1)

[n,p] = size(X);

Xw = X*w;
yXw = y.*Xw;

nll = sum(	([zeros(n,1) -yXw]));

if nargout > 1
    if nargout > 2
        sig = 1./(1+exp(-yXw));
        g = -X.'*(y.*(1-sig));
    else
        g = -X.'*(y./(1+exp(yXw)));
    end
end

if nargout > 2
    H = X.'*diag(sparse(sig.*(1-sig)))*X;
end

if nargout > 3
    T = zeros(p,p,p);
    for j1 = 1:p
        for j2 = 1:p
            for j3 = 1:p
                T(j1,j2,j3) = sum(y(:).^3.*X(:,j1).*X(:,j2).*X(:,j3).*sig.*(1-sig).*(1-2*sig));
            end
        end
    end
end


% Mathematics Q2791227
% https://math.stackexchange.com/questions/2301266
% Proximal Operator of Huber Loss Function (For L1 Regularized Huber Loss)
% References:
%   1.  aa
% Remarks:
%   1.  sa
% TODO:
% 	1.  ds
% Release Notes
% - 1.0.000     20/03/2020
%   *   First release.

%% General Parameters

subStreamNumberDefault = 0; %<! Set to 0 for Random

run('InitScript.m');

figureIdx           = 0; %<! Continue from Question 1
figureCounterSpec   = '%04d';

generateFigures = ON;

%% Parameters

numElements = 25;

outOfSetThr     = 1e-6;
outOfSetCost    = 1e9;

paramLambda = rand(1);
paramDelta = 3;

%% Load / Generate Data

vY      = 2 * randn(numElements, 1);
hObjFun = @(vX) 0.5 * sum((vX - vY) .^ 2) + (paramLambda * HuberLoss(vX, paramDelta));
% From https://math.stackexchange.com/a/1650535
% This is the Proximal Operator for the case paramDelta = 1.
hProxHuberLoss1 = @(vX, paramLambda) vX - ((paramLambda * vX) ./ (max(abs(vX), paramLambda + 1)));
% Supporting any Huber Loss Function by Scaling of the Prox
% HuberLoss(vY, paramDelta) = paramDelta * paramDelta * HuberLoss(vY / paramDelta, 1)
hProxHuberLoss = @(vX, paramDelta, paramLambda) paramDelta * hProxHuberLoss1(vX / paramDelta, paramLambda);

%% Solution by CVX

solverString = 'CVX';

tic();

cvx_begin('quiet')
    % cvx_precision('best');
    variable vX(numElements, 1);
    minimize( 0.5 * sum_square(vX - vY) + (0.5 * paramLambda * sum(huber(vX, paramDelta))) );
cvx_end

toc();

disp([' ']);
disp([solverString, ' Solution Summary']);
disp(['The ', solverString, ' Solver Status - ', cvx_status]);
% disp(['The Optimal Value Is Given By - ', num2str(cvx_optval)]);
disp(['The Optimal Value Is Given By - ', num2str(hObjFun(vX))]);
disp(['The Optimal Argument Is Given By - [ ', num2str(vX.'), ' ]']);
disp([' ']);

%% Solution by Analytic

solverString = 'Analytic';

tic();

% From https://math.stackexchange.com/a/1650535/33
vX = hProxHuberLoss(vY, paramDelta, paramLambda);

toc();

disp([' ']);
disp([solverString, ' Solution Summary']);
disp(['The Optimal Value Is Given By - ', num2str(hObjFun(vX))]);
disp(['The Optimal Argument Is Given By - [ ', num2str(vX.'), ' ]']);
disp([' ']);

%% Solution by Analytic

solverString = 'Analytic';

tic();

% By Boyd's Book
vX = ProxHuberLossBoyd(vY, paramDelta, paramLambda);

toc();

disp([' ']);
disp([solverString, ' Solution Summary']);
disp(['The Optimal Value Is Given By - ', num2str(hObjFun(vX))]);
disp(['The Optimal Argument Is Given By - [ ', num2str(vX.'), ' ]']);
disp([' ']);

%% Restore Defaults

% set(0, 'DefaultFigureWindowStyle', 'normal');
% set(0, 'DefaultAxesLooseInset', defaultLoosInset);


function [dimension standard_dev] = fractalvol(data)
%[DIMENSION STANDARD_DEV] = fractalvol(DATA) calculates the fractal
%dimension of the 1 dimensional random walk, DATA. DATA is assumed to be a
%function of its indices.
%   Finds fractal volatility by embedding in the unit square and box
%   counting. Y axis will be rescaled values of DATA, x axis is
%   (1:length(DATA))/length(DATA).
%
%   Uncomment the else construction if you have the parallel computing
%   toolbox and wish to run the code in parallel (it scales linearly in instances).

if size(data,1) < size(data,2)
    data = data';
end

if size(data,2) == 1
    data = [(1:length(data))' data];
end

max1 = max(data(:,1));
min1 = min(data(:,1));
max2 = max(data(:,2));
min2 = min(data(:,2));

%normalize all to unit square
normdata = data;
normdata(:,1) = normdata(:,1)-min1;
normdata(:,1) = normdata(:,1)./(max1-min1);
normdata(:,2) = normdata(:,2)-min2;
normdata(:,2) = normdata(:,2)./(max2-min2);

%make sure nothing falls through the x axis
minwidth = min(diff(normdata(:,1)));
minwidth = log2(minwidth);
minwidth = abs(ceil(minwidth));
minwidth = minwidth-1;

n = zeros(minwidth,1);

% parallcntrl = matlabpool('size');

% if parallcntrl == 0
    for j = 1:minwidth
        width = 2^-j;
        xaxis_pos = 0;
        boxcount = 0;
        while xaxis_pos<1
            indx = (xaxis_pos <= normdata(:,1) &...
                normdata(:,1)<xaxis_pos+width);
            if 1-xaxis_pos == width
                indx(end) = true;
            end

            vertical_column = normdata(indx,2);

            if length(vertical_column) == 1
                boxcount = boxcount + 1;
            else
                rawcount = (max(vertical_column)-min(vertical_column))/width;
                rawcount = rawcount + rem(min(vertical_column),width);
                count = ceil(rawcount);
                boxcount = boxcount + count;
            end
            xaxis_pos = xaxis_pos + width; %advance on x axis
        end
        n(j) = boxcount;
    end
% else
%     parfor j = 1:minwidth
%         width = 2^-j;
%         xaxis_pos = 0;
%         boxcount = 0;
%         while xaxis_pos<1
%             indx = (xaxis_pos <= normdata(:,1) &...
%                 normdata(:,1)<xaxis_pos+width);
%             if 1-xaxis_pos == width
%                 indx(end) = true;
%             end
%
%             vertical_column = normdata(indx,2);
%
%             if length(vertical_column) == 1
%                 boxcount = boxcount + 1;
%             else
%                 rawcount = (max(vertical_column)-min(vertical_column))/width;
%                 rawcount = rawcount + rem(min(vertical_column),width);
%                 count = ceil(rawcount);
%                 boxcount = boxcount + count;
%             end
%             xaxis_pos = xaxis_pos + width; %advance on x axis
%         end
%         n(j) = boxcount;
%     end
% end

r = 2.^-(1:minwidth);
r = r';

s=-gradient(log(n))./gradient(log(r));
IQR = iqr(s);

indx2 = abs(s-median(s)) > IQR/2;

x2 = log(r);
y2 = log(n);

s(indx2)= [];
x2(indx2) = [];
y2(indx2) = [];

%std is the variance of the slope according to OLS theory

X = [ones(size(x2)) x2];
beta = pinv(X)*y2;
C = pinv(X'*X);
e=y2-X*pinv(X)*y2;
sigma = e'*e*C;
sigma = sqrt(sigma);

dimension = -beta(2);
standard_dev = sigma(2,2);


function toms446_test04 ( )

%*****************************************************************************80
%
%% TOMS446_TEST04 tests EDCHEB, which evaluates the derivative of a Chebyshev series.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 September 2011
%
%  Author:
%
%    John Burkardt
%
  nf = 5;
  npl = 10;

  nx = 6;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TOMS446_TEST04\n' );
  fprintf ( 1, '  Test EDCHEB, which evaluates the \n' );
  fprintf ( 1, '  derivative of a Chebyshev series.\n' );

  x = cheby ( nf, npl, @functn );

  for j = 1 : nf

    x2(1:npl) = x(1:npl,j);

    fprintf ( 1, '\n' );
    if ( j == 1 )
      fprintf ( 1, '  d/dx Sin(x)\n' );
    elseif ( j == 2 )
      fprintf ( 1, '  d/dx Cos(x)\n' );
    elseif ( j == 3 )
      fprintf ( 1, '  d/dx Sin(2x)\n' );
    elseif ( j == 4 )
      fprintf ( 1, '  d/dx Cos(2x)\n' );
    elseif ( j == 5 )
      fprintf ( 1, '  d/dx x^5\n' );
    end

    fprintf ( 1, '\n' );

    for k = 1 : nx

      xval = 2.0 * ( k - 1 ) / ( nx - 1 ) - 1.0;

      fxj = functn_d ( xval );

      fval = edcheb ( xval, x2, npl );

      fprintf ( 1, '  %10.4f  %10.4f  %10.4f\n', xval, fxj(j), fval );

    end

  end

  return
end


function p=v_normcdflog(x,m,s)
%V_NORMCDFLOG calculates log of Normal Cumulative Distribution function p=(x,m,s)
%
% Inputs:
%
%     X        Input data (vector or matrix)
%     M        Mean of Normal distribution [default 0]
%     S        Std deviation of Normal distribution [default 1]
%
% Outputs:
%
%     P        P = log(normcdf(X)); same size as X
%
% The routine gives accurate values even if X is large and negative

%      Copyright (C) Mike Brookes 2016
%      Version: $Id: v_normcdflog.m 10865 2018-09-21 17:22:45Z dmb $
%
%   VOICEBOX is a MATLAB toolbox for speech processing.
%   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   This program is free software; you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation; either version 2 of the License, or
%   (at your option) any later version.
%
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You can obtain a copy of the GNU General Public License from
%   http://www.gnu.org/copyleft/gpl.html or by writing to
%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
persistent a b
if isempty(a)
    a=0.996;
%   f=@(x) -0.5*(x.^2+log(2*pi))-real(log(-(a+x.^2)./x))-real(log(normcdf(x)));
%   b=fzero(f,-22);         % cutoff value for conventional formula
    b=-22.2491306156561;    % precalculated value
end
if nargin>2
    x=(x-m)/s;
elseif nargin>1
    x=x-m;
end
t=x<b;                                                  % mask for large negative values
p=zeros(size(x));
p(~t)=real(log(0.5*erfc(-x(~t).*sqrt(0.5))));           % use this formula normally
p(t)=-0.5*(x(t).^2+log(2*pi))-real(log(-x(t)-a./x(t))); % use this approximation for large negative x


function result = sphere_unit_07_3d ( func )

%*****************************************************************************80
%
%% SPHERE_UNIT_07_3D approximates surface integrals on the unit sphere in 3D.
%
%  Integration region:
%
%    Points (X,Y,Z) such that:
%
%      X**2 + Y**2 + Z**2 = 1.
%
%  Discussion:
%
%    A 32 point 7-th degree formula is used.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 May 2004
%
%  Author:
%
%    MATLAB version by John Burkardt
%
%  Reference:
%
%    Arthur H Stroud,
%    Approximate Calculation of Multiple Integrals,
%    Prentice Hall, 1971.
%
%  Parameters:
%
%    Input, external FUNC, the name of the user supplied
%    function which evaluates F(X,Y,Z), of the form
%      function value = func ( x, y, z )
%
%    Output, real RESULT, the approximate integral of the function.
%
  norder1 = 2;
  norder2 = 4;
  norder3 = 4;
%
%  Set XTAB1 and WATE1.
%
  xtab1(1) = -1.0E+00;
  xtab1(2) =  1.0E+00;
  weight1(1) = 1.0E+00;
  weight1(2) = 1.0E+00;
%
%  Set XTAB2 and WATE2.
%
  for j = 1 : norder2
    angle = pi * ( 2 * j - 1 ) / ( 2 * norder2 );
    xtab2(j) = cos ( angle );
  end

  weight2(1:norder2) = 1.0E+00 / ( 4 * norder2 );
%
%  Set XTAB3 and WATE3.
%
  [ xtab3, weight3 ] = legendre_set ( norder3 );

  quad = 0.0E+00;
  for i = 1 : norder1
    for j = 1 : norder2
      for k = 1 : norder3

        x = xtab1(i) * sqrt ( 1.0E+00 - xtab2(j)^2 ) ...
                     * sqrt ( 1.0E+00 - xtab3(k)^2 );
        y = xtab1(i) * xtab2(j) * sqrt ( 1.0E+00 - xtab3(k)^2 );
        z = xtab1(i) * xtab3(k);

        quad = quad + weight1(i) * weight2(j) * weight3(k) ...
          * feval ( func, x, y, z );

      end
    end
  end

  volume = sphere_unit_area_3d ( );
  result = quad * volume;

  return
end


function [ x, w ] = j_quadrature_rule ( n, alpha, beta )

%*****************************************************************************80
%
%% J_QUADRATURE_RULE: Gauss-Jacobi quadrature based on J(n,a,b,x).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 March 2012
%
%  Author:
%
%    John Burkardt.
%
%  Reference:
%
%    Sylvan Elhay, Jaroslav Kautsky,
%    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
%    Interpolatory Quadrature,
%    ACM Transactions on Mathematical Software,
%    Volume 13, Number 4, December 1987, pages 399-415.
%
%  Parameters:
%
%    Input, integer N, the order.
%
%    Input, real ALPHA, BETA, the parameters.
%    -1 < ALPHA, BETA.
%
%    Output, real X(N), the abscissas.
%
%    Output, real W(N), the weights.
%
  ab = alpha + beta;
  abi = 2.0 + ab;
%
%  Define the zero-th moment.
%
  zemu = 2.0^( ab + 1.0 ) * gamma ( alpha + 1.0 ) ...
    * gamma ( beta + 1.0 ) / gamma ( abi );
%
%  Define the Jacobi matrix.
%
  x = zeros ( n, 1 );
  bj = zeros ( n, 1 );

  x(1) = ( beta - alpha ) / abi;
  bj(1) = 4.0 * ( 1.0 + alpha ) * ( 1.0 + beta ) ...
    / ( ( abi + 1.0 ) * abi * abi );
  a2b2 = beta * beta - alpha * alpha;

  for i = 2 : n
    abi = 2.0 * i + ab;
    x(i) = a2b2 / ( ( abi - 2.0 ) * abi );
    abi = abi^2;
    bj(i) = 4.0 * i * ( i + alpha ) * ( i + beta ) * ( i + ab ) ...
      / ( ( abi - 1.0 ) * abi );
  end
  bj(1:n) =  sqrt ( bj(1:n) );

  w = zeros ( n, 1 );
  w(1) = sqrt ( zemu );
%
%  Diagonalize the Jacobi matrix.
%
  [ x, w ] = imtqlx ( n, x, bj, w );

  w(1:n) = w(1:n).^2;

  return
end


function tests = test_operator
  tests = functiontests(localfunctions);
end

function test_1(testCase)
    b = [ 1 2 3; 3 4 3];
    bb = spx.dict.MatrixOperator(b);
    [m, n] = size(bb);
    verifyEqual(testCase, [m, n], size(b));
    bbb = double(bb);
    verifyEqual(testCase, bbb, b);
    v = [1 2 3]';
    verifyEqual(testCase, b*v, bb*v);
    v = [1 2]';
    verifyEqual(testCase, b'*v, bb'*v);
    c = bb';
    verifyEqual(testCase, b', c.A);
    c = bb.';
    verifyEqual(testCase, b.', c.A);
    b2 = bb.columns_operator([1 2]);
    verifyEqual(testCase, double(b2), b(:, [1 2]));
end

function test_dct_basis(testCase)
    N = 4;
    Dict = spx.dict.DCTBasis(N);
    A = double(Dict);

    tolerance = 1e-10;
    verifyEqual(testCase, A, dctmtx(N)', 'AbsTol', tolerance);

    tolerance = 1e-3;
    x = [1 1 1 1]';
    y = Dict * x;
    verifyEqual(testCase, y, [1.9239
   -0.3827
    0.3827
    0.0761], 'AbsTol', tolerance);

    x = [1 1 1 1]';
    y = Dict.apply_transpose(x);
    verifyEqual(testCase, y, [2.0000
         0
         0
         0], 'AbsTol', tolerance);
    y = Dict.adjoint(x);
    verifyEqual(testCase, y, [2.0000
         0
         0
         0], 'AbsTol', tolerance);

end

function test_dft_basis(testCase)
    N = 4;
    Dict = spx.dict.DFTBasis(N);
    A = double(Dict);

    tolerance = 1e-10;
    verifyEqual(testCase, A, dftmtx(N)' / sqrt(N), 'AbsTol', tolerance);

    A = Dict.apply(eye(4));
    verifyEqual(testCase, A, dftmtx(N)' / sqrt(N), 'AbsTol', tolerance);

    A = Dict.adjoint(eye(4));
    verifyEqual(testCase, A, dftmtx(N) / sqrt(N), 'AbsTol', tolerance);

    tolerance = 1e-3;
    x = [1 1 1 1]';
    y = Dict * x;
    verifyEqual(testCase, y, [2
     0
     0
     0], 'AbsTol', tolerance);

    x = [1 1 1 1]';
    y = Dict.apply_transpose(x);
    verifyEqual(testCase, y, [2.0000
         0
         0
         0], 'AbsTol', tolerance);
    y = Dict.adjoint(x);
    verifyEqual(testCase, y, [2.0000
         0
         0
         0], 'AbsTol', tolerance);

end

function test_partial_dct_1(testCase)
    rng default;
    M = 2;
    N = 4;
    p = randperm(N);
    % select some rows randomly
    row_pics = sort(p(1:M));
    % make sure that the first row is there
    row_pics(1) = 1;
    col_perm = randperm(N);
    Dict = spx.dict.PartialDCT(row_pics, col_perm);
    x = ones(N, 1);
    y  = Dict.apply(x);
    z = Dict.adjoint(y);
    tolerance = 1e-3;
    verifyEqual(testCase, y, [2.0000
         0], 'AbsTol', tolerance);
    verifyEqual(testCase, z, [1.0000
    1.0000
    1.0000
    1.0000], 'AbsTol', tolerance);

    x(1) = x(1) + 2;
    y  = Dict.apply(x);
    z = Dict.adjoint(y);
    verifyEqual(testCase, y, [3.0000
    1.0000], 'AbsTol', tolerance);
    verifyEqual(testCase, z, [2.0000
    2.0000
    1.0000
    1.0000], 'AbsTol', tolerance);

end

function test_partial_dct_orthogonal(testCase)
    rng default;
    M = 32;
    N = 64;
    p = randperm(N);
    % select some rows randomly
    row_pics = sort(p(1:M));
    % make sure that the first row is there
    row_pics(1) = 1;
    col_perm = randperm(N);
    Dict = spx.dict.PartialDCT(row_pics, col_perm);
    y = eye(M);
    z = Dict.adjoint(y);
    u = Dict.apply(z);
    tolerance = 1e-8;
    verifyEqual(testCase, y, u, 'AbsTol', tolerance);
end

function test_partial_dft_1(testCase)
    rng default;
    M = 8;
    N = 16;
    p = randperm(N);
    % select some rows randomly
    row_pics = sort(p(1:M));
    % make sure that the first row is there
    row_pics(1) = 1;
    col_perm = randperm(N);
    Dict = spx.dict.PartialDFT(row_pics, col_perm);
    x = ones(N, 1);
    y  = Dict.apply(x);
    z = Dict.adjoint(y);
    tolerance = 1e-3;
    verifyEqual(testCase, y, [4
     0
     0
     0
     0
     0
     0
     0], 'AbsTol', tolerance);
    verifyEqual(testCase, z, [1
     1
     1
     1
     1
     1
     1
     1
     1
     1
     1
     1
     1
     1
     1
     1], 'AbsTol', tolerance);

    x(1) = x(1) + 2;
    y  = Dict.apply(x);
    z = Dict.adjoint(y);
    verifyEqual(testCase, y, [4.5000 + 0.0000i
   0.5000 + 0.0000i
   0.0000 - 0.5000i
  -0.5000 + 0.0000i
   0.0000 + 0.5000i
  -0.5000 + 0.0000i
   0.0000 - 0.5000i
   0.0000 + 0.5000i], 'AbsTol', tolerance);
   verifyEqual(testCase, z, [2.0000 + 0.0000i
   0.9482 + 0.1250i
   0.9482 - 0.1250i
   1.3018 - 0.1250i
   1.0000 - 0.3536i
   1.3018 + 0.1250i
   1.0000 + 0.0000i
   1.0000 + 0.3536i
   1.3018 - 0.1250i
   1.0000 - 0.3536i
   1.3018 + 0.1250i
   0.9482 - 0.1250i
   0.9482 + 0.1250i
   1.0000 + 0.3536i
   1.0000 + 0.0000i
   1.0000 + 0.0000i], 'AbsTol', tolerance);
end

function test_partial_dft_orthogonal(testCase)
    rng default;
    M = 32;
    N = 64;
    p = randperm(N);
    % select some rows randomly
    row_pics = sort(p(1:M));
    % make sure that the first row is there
    row_pics(1) = 1;
    col_perm = randperm(N);
    Dict = spx.dict.PartialDFT(row_pics, col_perm);
    y = eye(M);
    z = Dict.adjoint(y);
    u = Dict.apply(z);
    tolerance = 1e-8;
    verifyEqual(testCase, y, u, 'AbsTol', tolerance);
end


function [ x, w ] = bdfp_set ( n )

%*****************************************************************************80
%
%% BDFP_SET sets weights for backward differentiation predictor quadrature.
%
%  Discussion:
%
%    A backward differentiation predictor formula is defined for a set
%    of evenly spaced abscissas X(I) with X(1) = 1 and X(2) = 0.  Assuming
%    that the values of the function to be integrated are known at the
%    abscissas, the formula is written in terms of the function value at
%    X(2), and the backward differences at X(2) that approximate the
%    derivatives there.  A backward differentiation predictor formula
%    is equivalent to an Adams-Bashforth formula of the same order.
%
%    The integral:
%
%      Integral ( 0 <= X <= 1 ) F(X) dX
%
%    The quadrature rule:
%
%      Sum ( 1 <= I <= N ) W(I) * BD**(I-1) F ( 0 ),
%
%    Here, "BD**(I-1) F ( 0 )" denotes the (I-1)st backward difference
%    of F at X = 0, using a spacing of 1.  In particular,
%
%    BD**0 F(0) = F(0)
%    BD**1 F(0) = F(0) - F(-1)
%    BD**2 F(0) = F(0) - 2 * F(-1) + F(-2 )
%
%    The relationship between a backward difference predictor and the
%    corresponding Adams-Bashforth formula may be illustrated for the
%    BDF predictor of order 3:
%
%      BD**0 F(0) + 0.5 * BD**1 F(0) + 5/12 * BD**2 F(0)
%      =            F(0)
%        + 1/2  * ( F(0) -         F(1) )
%        + 5/12 * ( F(0) - 2     * F(-1) +      F(-2) )
%      =  23/12 *   F(0) - 16/12 * F(-1) + 5/12 F(-2)
%
%    which is the Adams-Bashforth formula of order 3.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 October 2005
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Simeon Fatunla,
%    Numerical Methods for Initial Value Problems in Ordinary Differential
%    Equations,
%    Academic Press, 1988.
%
%  Parameters:
%
%    Input, integer N, the order.
%    1 <= N <= 19.
%
%    Output, real X(N), the abscissas.
%
%    Output, real W(N), the weights.
%
  x = zeros ( n, 1 );
  w = zeros ( n, 1 );

  n_max = 19;

  w_save(1) =                       1.0;
  w_save(2) =                       1.0 /                2.0;
  w_save(3) =                       5.0 /               12.0;
  w_save(4) =                       3.0 /                8.0;
  w_save(5) =                     251.0 /              720.0;
  w_save(6) =                      95.0 /              288.0;
  w_save(7) =                   19087.0 /            60480.0;
  w_save(8) =                    5257.0 /            17280.0;
  w_save(9) =                 1070017.0 /          3628800.0;
  w_save(10) =                  25713.0 /            89600.0;
  w_save(11) =               26842253.0 /         95800320.0;
  w_save(12) =                4777223.0 /         17418240.0;
  w_save(13) =           703604254357.0 /    2615348736000.0;
  w_save(14) =           106364763817.0 /     402361344000.0;
  w_save(15) =          1166309819657.0 /    4483454976000.0;
  w_save(16) =               25221445.0 /         98402304.0;
  w_save(17) =       8092989203533249.0 /    3201186852864.0;
  w_save(18) =         85455477715379.0 /      34237292544.0;
  w_save(19) =   12600467236042756559.0 / 5109094217170944.0;

  if ( n_max < n )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'BDFP_SET - Fatal error!\n' );
    fprintf ( 1, '  N = %d exceeds N_MAX = %d\n', n, n_max );
    error ( 'BDFP_SET - Fatal error!' );
  end

  w(1:n) = w_save(1:n);

  for i = 1 : n
    x(i) = 1 - i;
  end

  return
end


clear all; close all;
[x, y]=meshgrid(-128:2:127, -128:2:127);
D=sqrt((x).^2+(y).^2);
D0=50;
W=30;
n=5;
H=1./(1+(D*W./(D.^2-D0^2)).^(2*n));
H2=1-H;
figure;
mesh(double(H));
% axis tight;


function z = logMn(x, p)
% Compute log pdf of a multinomial distribution.
% Input:
%   x: d x 1 integer vector
%   p: d x 1 probability
% Output:
%   z: probability density in logrithm scale z=log p(x)
% Written by Mo Chen (sth4nth@gmail.com).
z = gammaln(sum(x)+1)-sum(gammaln(x+1))+dot(x,log(p));


function [bandsLin2D, bandsLinAv, ...
    mB2D, mBAv, ...
    names2D, namesAv, ...
    namesmB2D, namesmBAv] = extractBandsLin(data, params)
% Do FFT over whole segement and return average bin power
% Later maybe add time divisions

% Delta: 1-3Hz
% Theta: 4-7Hz
% Alpha1: 8-9Hz
% Alpha2: 10-12Hz
% Beta1: 13-17Hz
% Beta2: 18-30Hz
% Gamma1: 31-40Hz
% Gamma2: 41-50Hz
% Higher: 51->200 Hz
bLims = [[1;3], [4;7], [8;9], [10;12], [13;17], [18;30], [31;40], ...
    [41;50], [51;70], [71;150], [151;250]]; % Last 3 mod M37
nBands = size(bLims,2);
nChans = 16;

bands2D = NaN(nBands, 16, 'single');

mB2D =  NaN(1, 16, 'single');

for c = 1:nChans

    Fs = 400;
    T = 1/Fs;
    L = size(data,1);

    Y = fft(data(:,c));

    P2 = abs(Y/L);
    P1 = P2(1:L/2+1);
    P1(2:end-1) = 2*P1(2:end-1);

    f = Fs*(0:(L/2))/L;

    if params.plotOn
        plot(f,P1)
        title('Single-Sided Amplitude Spectrum of X(t)')
        xlabel('f (Hz)')
        ylabel('|P1(f)|')
    end

    for b = 1:nBands
        bIdx = f>=bLims(1,b) & f<=bLims(2,b);

        mPower = mean(P1(bIdx));

        bands2D(b, c) = mPower;
    end

    [~, mB2D(1,c)] = max(bands2D(:,c));
end

% Max bands
mBAv = single(mean(mB2D));
namesmB2D = (string('maxBand_c') + (1:16)')';
namesmBAv = 'maxBandAv';

% Bands lin
bandsLinAv = mean(bands2D,2)';
bandsLin2D = reshape(bands2D, 1, nChans*nBands);

names2D = cellstr([repmat('bandsLin2D_b', nChans*nBands,1), ...
    num2str(repmat((1:nBands)', nChans, 1)), ...
    repmat('_c', nChans*nBands, 1), ...
    num2str(reshape(repmat((1:16), nBands, 1), nBands*nChans,1))]);
names2D = strrep(names2D, ' ' , '')';

namesAv = cellstr([repmat('bandsLinAv_b', nBands,1), ...
    num2str((1:nBands)')])';


clear all, close all, clc

xC = [2; 1;];                           % Center of data (mean)
sig = [2; .5;];                         % Principal axes

theta = pi/3;                           % Rotate cloud by pi/3
R = [cos(theta) -sin(theta);            % Rotation matrix
    sin(theta) cos(theta)];

nPoints = 10000;                        % Create 10,000 points
X = R*diag(sig)*randn(2,nPoints) + diag(xC)*ones(2,nPoints);

subplot(1,2,1)                          % Plot cloud of noisy data
scatter(X(1,:),X(2,:),'k.','LineWidth',2)
hold on, box on, grid on
axis([-6 8 -6 8])

%% f_ch01_ex03_1b

Xavg = mean(X,2);                       % Compute mean
B = X - Xavg*ones(1,nPoints);           % Mean-subtracted Data
[U,S,V] = svd(B/sqrt(nPoints),'econ');  % Find principal components (SVD)

subplot(1,2,2)
scatter(X(1,:),X(2,:),'k.','LineWidth',2)  % Plot data to overlay PCA
hold on, box on, grid on
axis([-6 8 -6 8])

theta = (0:.01:1)*2*pi;
[Xstd] = U*S*[cos(theta); sin(theta)];  % 1-std confidence interval
plot(Xavg(1)+Xstd(1,:),Xavg(2) + Xstd(2,:),'r-','LineWidth',1.5)
plot(Xavg(1)+2*Xstd(1,:),Xavg(2) + 2*Xstd(2,:),'r-','LineWidth',1.5)
plot(Xavg(1)+3*Xstd(1,:),Xavg(2) + 3*Xstd(2,:),'r-','LineWidth',1.5)

% Plot principal components U(:,1)S(1,1) and U(:,2)S(2,2)
plot([Xavg(1) Xavg(1)+U(1,1)*S(1,1)],[Xavg(2) Xavg(2)+U(2,1)*S(1,1)],'c-','LineWidth',2)
plot([Xavg(1) Xavg(1)+U(1,2)*S(2,2)],[Xavg(2) Xavg(2)+U(2,2)*S(2,2)],'c-','LineWidth',2)

set(gcf,'Position',[100 100 600 300])


function [HotellingT2] = HotellingT2(X,alpha)
%Hotelling T-Squared testing procedures for multivariate samples.
%
%   Syntax: function [HotellingT2] = HotellingT2(X,alpha)
%
%     Inputs:
%          X - multivariate data matrix.
%      alpha - significance level (default = 0.05).
%
%     Outputs:
%          It depends of the Hotelling's T-Squared multivariate test of interest,
%          being able to be:
%
%            |-One-sample
%            |                          |-Homoskedasticity (to test)
%            |            |-Independent |
%            |            |             |-Heteroskedasticity (to test)
%            |-Two-sample |
%                         |
%                         |-Dependent
%
%          Each case calls to a corresponding function that contains a complete
%          explanation.
%
%  Created by A. Trujillo-Ortiz and R. Hernandez-Walls
%             Facultad de Ciencias Marinas
%             Universidad Autonoma de Baja California
%             Apdo. Postal 453
%             Ensenada, Baja California
%             Mexico.
%             atrujo@uabc.mx
%             And the special collaboration of the post-graduate students of the 2002:2
%             Multivariate Statistics Course: Karel Castro-Morales, Alejandro Espinoza-Tenorio,
%             Andrea Guia-Ramirez.
%
%  Copyright (C) December 2002.
%

if nargin < 2,
    alpha = 0.05; %(default)
end;

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

sam = input('Do you have one multivariate sample (1) or two multivariate samples (2)?: ');
if sam == 1;
   T2Hot1(X,alpha)
else
   id = input('They are independent (1) or dependent (2)?: ');
   if id == 1;
      disp('The covariance matrix homogeneity will be testing.:');
      MBoxtest(X,alpha);
      disp(' ')
      dc = input('Do they were significant? (y/n): ','s');
      if dc == 'y'
         T2Hot2ihe(X,alpha);
      else
         T2Hot2iho(X,alpha);
      end;
   else
      T2Hot2d(X,alpha);
   end;
end;

return;


% DIRECT JACOBIAN DEMO
function jacobian_planar_3gdl

%a)
q1=0
q2 = pi/2
q3 = pi/2
J = [-sin(q1)-sin(q1+q2)-sin(q1+q2+q3)  -sin(q1+q2)-sin(q1+q2+q3) -sin(q1+q2+q3);
     cos(q1)+cos(q1+q2)+cos(q1+q2+q3)    cos(q1+q2)+cos(q1+q2+q3)  cos(q1+q2+q3);
      0 0 0;
      0 0 0;
      0 0 0;
      1 1 1];
 f = [ 1 1 1 1 1 1]';

 tau = J'*f

 %b)
q1=pi/4
q2 = pi/4
q3 = pi/4
J = [-sin(q1)-sin(q1+q2)-sin(q1+q2+q3)  -sin(q1+q2)-sin(q1+q2+q3) -sin(q1+q2+q3);
     cos(q1)+cos(q1+q2)+cos(q1+q2+q3)    cos(q1+q2)+cos(q1+q2+q3)  cos(q1+q2+q3);
      0 0 0;
      0 0 0;
      0 0 0;
      1 1 1];

 tau = [1 1 1]';

 f = J*inv(J'*J)*tau

%c)
q1=pi/2
q2 = pi/2
q3 = pi/2
syms q1 q2 q3 real
J = [-sin(q1)-sin(q1+q2)-sin(q1+q2+q3)  -sin(q1+q2)-sin(q1+q2+q3) -sin(q1+q2+q3);
     cos(q1)+cos(q1+q2)+cos(q1+q2+q3)    cos(q1+q2)+cos(q1+q2+q3)  cos(q1+q2+q3)];

 %Jp = pinv(J);
 Jp = J'*inv(J*J');
 P = (eye(3) - Jp*J)
 P = simplify(P)
 qdn = P*[0 0 1]'
 qdn = simplify(qdn)


function value = gen_hermite_integral ( expon, alpha )

%*****************************************************************************80
%
%% GEN_HERMITE_INTEGRAL evaluates a monomial generalized Hermite integral.
%
%  Discussion:
%
%    The integral:
%
%      integral ( -oo < x < +oo ) x^n |x|^alpha exp(-x^2) dx
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 February 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, int EXPON, the exponent of the monomial.
%
%    Input, real ALPHA, the exponent of |X| in the integral.
%    -1.0 < ALPHA.
%
%    Output, real VALUE, the value of the integral.
%
  if ( mod ( expon, 2 ) == 1 )

    value = 0.0;

  else

    a = alpha + expon;

    if ( a <= -1.0 )

      value = - r8_huge ( );

    else

      value = gamma ( ( a + 1.0 ) / 2.0 );

    end

  end

  return
end


function T=transitivity_bd(A)
%TRANSITIVITY_BD    Transitivity
%
%   T = transitivity_bd(A);
%
%   Transitivity is the ratio of 'triangles to triplets' in the network.
%   (A classical version of the clustering coefficient).
%
%   Input:      A       binary directed connection matrix
%
%   Output:     T       transitivity scalar
%
%   Reference:  Rubinov M, Sporns O (2010) NeuroImage 52:1059-69
%               based on Fagiolo (2007) Phys Rev E 76:026107.
%
%
%   Contributors:
%   Mika Rubinov, UNSW/University of Cambridge
%   Christoph Schmidt, Friedrich Schiller University Jena
%   Andrew Zalesky, University of Melbourne
%   2007-2015

%   Modification history:
%   2007: original (MR)
%   2013, 2015: removed tests for absence of nodewise 3-cycles (CS,AZ)

%   Methodological note: In directed graphs, 3 nodes generate up to 8
%   triangles (2*2*2 edges). The number of existing triangles is the main
%   diagonal of S^3/2. The number of all (in or out) neighbour pairs is
%   K(K-1)/2. Each neighbour pair may generate two triangles. "False pairs"
%   are i<->j edge pairs (these do not generate triangles). The number of
%   false pairs is the main diagonal of A^2. Thus the maximum possible
%   number of triangles = (2 edges)*([ALL PAIRS] - [FALSE PAIRS])
%                       = 2 * (K(K-1)/2 - diag(A^2))
%                       = K(K-1) - 2(diag(A^2))

S    = A+A.';                           % symmetrized input graph
K    = sum(S,2);                        % total degree (in + out)
cyc3 = diag(S^3)/2;                     % number of 3-cycles (ie. directed triangles)
CYC3 = K.*(K-1)-2*diag(A^2);            % number of all possible 3-cycles
T    = sum(cyc3)./sum(CYC3);            % transitivity


function [flow,labels] = test1()

% TEST1 Shows how to use the library to compute
%   a minimum cut on the following graph:
%
%                SOURCE
%		       /       \
%		     1/         \2
%		     /      3    \
%		   node0 -----> node1
%		     |   <-----   |
%		     |      4     |
%		     \            /
%		     5\          /6
%		       \        /
%		          SINK
%
%   (c) 2008 Michael Rubinstein, WDI R&D and IDC
%   $Revision: 140 $
%   $Date: 2008-09-15 15:35:01 -0700 (Mon, 15 Sep 2008) $
%

A = sparse(2,2);
A(1,2)=3;
A(2,1)=4;
T = sparse(2,2);
T(1,1)=1;
T(2,1)=2;
T(1,2)=5;
T(2,2)=6;

[flow,labels] = maxflow(A,T)


 function [fun, d1, d2] = ir_poly2_fun(order, varargin)
%function [fun, d1, d2] = ir_poly2_fun(order, [options])
%|
%| create anonymous functions @(x,y) with all the terms in a 2d polynomial
%| up to given order, e.g. [1+0*x x y ...]
%| also return partial derivatives w.r.t. x and y
%|
%| in
%|	order
%|
%| options
%|	maxdegree	maximum of sum of degrees (default: 2*order)
%|	dc		set to 1 to include dc (constant) term (default: 1)
%|
%| out
%|	fun		use fun(x, y) to evaluate the polynomial
%|	d1,d2		likewise, for 1st partial derivatives thereof
%|
%| Copyright 2005-6-18, Jeff Fessler, The University of Michigan

if nargin < 1, ir_usage, end
if nargin == 1 && streq(order, 'test'), ir_poly2_fun_test, return, end

arg.maxdegree = []; % se below
arg.dc = true;
arg = vararg_pair(arg, varargin);

if isempty(arg.maxdegree), arg.maxdegree = 2 * order; end

str = '';
d1 = '';
d2 = '';
for i2=0:order
	for i1=0:order
		if i1+i2 == 0 && ~arg.dc
			continue
		end
		if i1 + i2 > arg.maxdegree
			continue
		end

		str = [str sprintf(' (x.^%d).*(y.^%d)', i1, i2)];
		if i1 == 0
			s1 = '0*x';
		else
			s1 = sprintf('%d*x.^%d', i1, i1-1);
		end
		if i2 == 0
			s2 = '0*y';
		else
			s2 = sprintf('%d*y.^%d', i2, i2-1);
		end
		d1 = [d1 sprintf(' (%s).*(y.^%d)', s1, i2)];
		d2 = [d2 sprintf(' (x.^%d).*(%s)', i1, s2)];
	end
end
str = ['[ ' str ' ]'];
d1 = ['[ ' d1 ' ]'];
d2 = ['[ ' d2 ' ]'];

% create appropriate anonymous functions
fun = ir_str2func(['@(x,y) ' str]);
d1 = ir_str2func(['@(x,y) ' d1]);
d2 = ir_str2func(['@(x,y) ' d2]);

% ir_poly2_fun_test()
function ir_poly2_fun_test
[fun d1 d2] = ir_poly2_fun(1, 'dc', 0);
x = 1:5; y = 2:6; fun(x,y); d1(x,y); d2(x,y);
[fun d1 d2] = ir_poly2_fun(2, 'maxdegree', 3);
fun(x,y); d1(x,y); d2(x,y);
if im
	pr fun
end


function [PErrorOutput, PErrorOutputmean, PErrorOutputvar] = PError(N,Ptrue,Pestimate)

% This function computes the proportion erros per pixel per endmember
%       given true and estimated proportion values.
%
% SYNTAX : [PErrorOutput, PErrorOutputmean, PErrorOutputvar] = PError(N,Ptrue,Pestimate)
%
% INPUTS
%     N:             Total number of data points. N=N1*N2 in hyperspectral
%                    image data.
%     Ptrue:         True proportion values. N*M, where M is the number of
%                    endmembers.
%     Pestimate:     Estimated proportion values. N*M.
% OUTPUTS
%     PErrorOutput:       PError per pixel
%     PErrorOutputmean:   Mean of PErrorOutput, PError per pixel per
%                         endmember. (This is the result in the Tables in the paper)
%     PErrorOutputvar:    Variance of PErrorOutput across endmembers.
%
% This product is Copyright (c) 2014 University of Missouri
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions
% are met:
%
%   1. Redistributions of source code must retain the above copyright
%      notice, this list of conditions and the following disclaimer.
%   2. Redistributions in binary form must reproduce the above copyright
%      notice, this list of conditions and the following disclaimer in the
%      documentation and/or other materials provided with the distribution.
%   3. Neither the name of the University nor the names of its contributors
%      may be used to endorse or promote products derived from this software
%      without specific prior written permission.
%
% THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF MISSOURI AND
% CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
% INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
% DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS
% BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
% LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
% LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
% HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
% OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  M = size(Ptrue,2);
  t =   (Ptrue- Pestimate).^2;
  PErrorOutput = sum(sum(t)) / N; % PError per pixel

PErrorOutputmean = PErrorOutput/M; %Mean of PErrorOutput, PError per pixel per endmember
PErrorOutputvar= var(PErrorOutput); %Variance of PErrorOutput

%%Plot histogram across iterations for one N. FOR DEMO PURPOSES.
% figure(100);
% plot(PErrorOutput);
% xlabel('N');ylabel('PError');
% title('Plot of PErrorOutput');
% figure(200);
% hist(PErrorOutput);
% xlabel('PError');ylabel('# of Data Points');
% title('Histogram of PErrorOutput');

end


%demo for affine_fit
%Author: Adrien Leygue
%Date: December 3 2014
close all
clear all
figure;
%generate points that lie approximately in the Z=0 plane
N = 10;
[X,Y] = meshgrid(linspace(0,1,N));
XYZ_1 = [X(:) Y(:) 0.05*randn(N^2,1)];
plot3(XYZ_1(:,1),XYZ_1(:,2),XYZ_1(:,3),'r.');
hold on
%compute the normal to the plane and a point that belongs to the plane
[n_1,~,p_1] = affine_fit(XYZ_1);

%generate points that lie approximately in the Z=X plane
%the normal vector is
n_2_exact = [-sqrt(2)/2 0 sqrt(2)/2];
N = 12;
[X,Y] = meshgrid(linspace(0,1,N));
XYZ_2 = [X(:) Y(:) X(:)] + bsxfun(@times,0.05*randn(N^2,1),n_2_exact);
plot3(XYZ_2(:,1),XYZ_2(:,2),XYZ_2(:,3),'b.');

%compute the normal to the plane and a point that belongs to the plane
[n_2,V_2,p_2] = affine_fit(XYZ_2);

%plot the two points p_1 and p_2
plot3(p_1(1),p_1(2),p_1(3),'ro','markersize',15,'markerfacecolor','red');
plot3(p_2(1),p_2(2),p_2(3),'bo','markersize',15,'markerfacecolor','blue');

%plot the normal vector
quiver3(p_1(1),p_1(2),p_1(3),n_1(1)/3,n_1(2)/3,n_1(3)/3,'r','linewidth',2)
h = quiver3(p_2(1),p_2(2),p_2(3),n_2(1)/3,n_2(2)/3,n_2(3)/3,'b','linewidth',2)

%plot the two adjusted planes
[X,Y] = meshgrid(linspace(0,1,3));

%first plane
surf(X,Y, - (n_1(1)/n_1(3)*X+n_1(2)/n_1(3)*Y-dot(n_1,p_1)/n_1(3)),'facecolor','red','facealpha',0.5);

%second plane
%NB: if the plane is vertical the above method cannot be used, one should
%use the secont output of affine_fit which contains a base of the plane.
%this is illustrated below
%S1 and S2 are the coordinates of the plane points in the basis made of the
%columns ov V_2
[S1,S2] = meshgrid([-1 0 1]);
%generate the pont coordinates
X = p_2(1)+[S1(:) S2(:)]*V_2(1,:)';
Y = p_2(2)+[S1(:) S2(:)]*V_2(2,:)';
Z = p_2(3)+[S1(:) S2(:)]*V_2(3,:)';
%plot the plane
surf(reshape(X,3,3),reshape(Y,3,3),reshape(Z,3,3),'facecolor','blue','facealpha',0.5);

xlabel('x');
ylabel('y');
zlabel('z');
axis equal
%compute the angle between the planes in [0 90] degrees
angle = acosd(dot(n_1,n_2));
if angle>90
    angle = 180-angle;
end
angle