function [C,numberOfOverlapPixels] = normxcorr2_general(varargin)
%NORMXCORR2_GENERAL Normalized two-dimensional cross-correlation.
%   [C,numberOfOverlapPixels] = NORMXCORR2_GENERAL(TEMPLATE,A) computes the
%   normalized cross-correlation of matrices TEMPLATE and A. The resulting
%   matrix C contains correlation coefficients and its values may range
%   from -1.0 to 1.0.
%
%   [C,numberOfOverlapPixels] =
%   NORMXCORR2_GENERAL(TEMPLATE,A,requiredNumberOfOverlapPixels) sets to 0
%   all locations in C computed from positions where A and T overlap less
%   than requiredNumberOfOverlapPixels.
%   Larger values of requiredNumberOfOverlapPixels zero-out pixels on a
%   larger border around C.
%   Thus, larger values remove less stable computations but also limit the
%   capture range.
%   If the template is smaller than the image and it is desired that the
%   computation only be carried out when the template is fully overlapping
%   the image, requiredNumberOfOverlapPixels should be set to
%   numel(template).
%   The default is set to 0, meaning no modifications to C.
%
%   Limitations of normxcorr2:
%   The documentation of normxcorr2 states that, "The matrix A must be
%   larger than the matrix TEMPLATE for the normalization to be
%   meaningful." It is implemented following the details of the paper "Fast
%   Normalized Cross-Correlation", by J. P. Lewis, Industrial Light &
%   Magic. This approach assumes the template is small relative to the
%   image and proceeds to calculate the normalization across the entire
%   template. This leads to correct computations wherever the template is
%   wholly overlapping with the image, but the computation is incorrect in
%   the borders of the output (the border size is proportional to the
%   template size).  This problem is therefore worse for larger templates
%   to the point that, when the template is the same size as the image, the
%   only correct value is at the center pixel (where the images are fully
%   overlapping). Thus, if normxcorr2 is used for such things as
%   registering images of the same size, the result will be incorrect.
%
%   The new normxcorr2_general:
%   normxcorr2_general is more general than normxcorr2 in that it gives
%   correct results everywhere regardless of the relative size of A and
%   TEMPLATE. It accomplishes this by computing the normalized correlation
%   only in the overlap regions between the two matrices. Thus, the result
%   is correct for all locations of correlation.  The result is the same as
%   if the NCC were carried out in the spatial domain (which would take a
%   long time to compute for large matrices).
%
%   Class Support
%   -------------
%   The input matrices can be numeric. The output matrix C is double.
%
%   Example
%   -------
%   This example correlates an input with itself using normxcorr2 (the
%   built-in Matlab version) and normxcorr2_general (the general version).
%   Because the template is not small compared with the input image (they
%   are the same size in this case), the output of normxcorr2.m is
%   incorrect for most pixels.  On the other hand, the general version is
%   correct at all locations, which can be easily verified analytically or
%   visually.
%
%   Note that the image processing toolbox (IPT) is needed to run this
%   example since normxcorr2 is part of that toolbox.  However,
%   normxcorr2_general does not require the IPT.
%
%   input = repmat([1:6 5:-1:1],11,1);
%   normxcorr2_output = normxcorr2(input,input);
%   normxcorr2_general_output = normxcorr2_general(input,input);
%   figure;
%   subplot(2,2,1), imagesc(input); title('Input pattern');
%   subplot(2,2,3), imagesc(normxcorr2_output); title('Output of Matlab built-in normxcorr2');
%   subplot(2,2,4), imagesc(normxcorr2_general_output); title('Output of normxcorr2\_general');
%
%   See also NORMXCORR2.
%
%   References: Dirk Padfield. "Masked FFT registration". In Proc. Computer
%   Vision and Pattern Recognition, 2010.
%
%   Author: Dirk Padfield, GE Global Research, padfield@research.ge.com
%

%   Input-output specs
%   ------------------
%   T:    2-D, real, full matrix
%         logical, uint8, uint16, or double
%         no NaNs, no Infs
%         prod(size(T)) >= 2
%
%   A:    2-D, real, full matrix
%         logical, uint8, uint16, or double
%         no NaNs, no Infs
%         prod(size(A)) >= 2
%
%   C:    double

[T, A, requiredNumberOfOverlapPixels] = ParseInputs(varargin{:});

sizeA = size(A);
sizeT = size(T);

% Find the number of pixels used for the calculation as the two images are
% correlated.  The size of this image will be the same as the correlation
% image.
numberOfOverlapPixels = local_sum(ones(sizeA),sizeT(1),sizeT(2));

local_sum_A = local_sum(A,sizeT(1),sizeT(2));
local_sum_A2 = local_sum(A.*A,sizeT(1),sizeT(2));

% Note: diff_local_sums should be nonnegative, but it may have negative
% values due to round off errors. Below, we use max to ensure the radicand
% is nonnegative.
diff_local_sums_A = ( local_sum_A2 - (local_sum_A.^2)./ numberOfOverlapPixels );
clear local_sum_A2;
denom_A = max(diff_local_sums_A,0);
clear diff_local_sums_A;

% Flip T in both dimensions so that its correlation can be more easily
% handled.
rotatedT = rot90(T,2);
local_sum_T = local_sum(rotatedT,sizeA(1),sizeA(2));
local_sum_T2 = local_sum(rotatedT.*rotatedT,sizeA(1),sizeA(2));
clear rotatedT;

diff_local_sums_T = ( local_sum_T2 - (local_sum_T.^2)./ numberOfOverlapPixels );
clear local_sum_T2;
denom_T = max(diff_local_sums_T,0);
clear diff_local_sums_T;

denom = sqrt(denom_T .* denom_A);
clear denom_T denom_A;

xcorr_TA = xcorr2_fast(T,A);
clear A T;
numerator = xcorr_TA - local_sum_A .* local_sum_T ./ numberOfOverlapPixels;
clear xcorr_TA local_sum_A local_sum_T;

% denom is the sqrt of the product of positive numbers so it must be
% positive or zero.  Therefore, the only danger in dividing the numerator
% by the denominator is when dividing by zero. We know denom_T~=0 from
% input parsing; so denom is only zero where denom_A is zero, and in these
% locations, C is also zero.
C = zeros(size(numerator));
tol = 1000*eps( max(abs(denom(:))) );
i_nonzero = find(denom > tol);
C(i_nonzero) = numerator(i_nonzero) ./ denom(i_nonzero);
clear numerator denom;

% Remove the border values since they result from calculations using very
% few pixels and are thus statistically unstable.
% By default, requiredNumberOfOverlapPixels = 0, so C is not modified.
if( requiredNumberOfOverlapPixels > max(numberOfOverlapPixels(:)) )
    error(['ERROR: requiredNumberOfOverlapPixels ' num2str(requiredNumberOfOverlapPixels) ...
    ' must not be greater than the maximum number of overlap pixels ' ...
    num2str(max(numberOfOverlapPixels(:))) '.']);
end
C(numberOfOverlapPixels < requiredNumberOfOverlapPixels) = 0;

%-------------------------------
% Function  local_sum
%
function local_sum_A = local_sum(A,m,n)

% This algorithm depends on precomputing running sums.

% If m,n are equal to the size of A, a faster method can be used for
% calculating the local sum.  Otherwise, the slower but more general method
% can be used.  The faster method is more than twice as fast and is also
% less memory intensive.
if( m == size(A,1) && n == size(A,2) )
    s = cumsum(A,1);
    c = [s; repmat(s(end,:),m-1,1) - s(1:end-1,:)];
    s = cumsum(c,2);
    clear c;
    local_sum_A = [s, repmat(s(:,end),1,n-1) - s(:,1:end-1)];
else
    % Break the padding into parts to save on memory.
    B = zeros(size(A,1)+2*m,size(A,2));
    B(m+1:m+size(A,1),:) = A;
    s = cumsum(B,1);
    c = s(1+m:end-1,:)-s(1:end-m-1,:);
    d = zeros(size(c,1),size(c,2)+2*n);
    d(:,n+1:n+size(c,2)) = c;
    s = cumsum(d,2);
    local_sum_A = s(:,1+n:end-1)-s(:,1:end-n-1);
end

%-------------------------------
% Function  xcorr2_fast
%
function cross_corr = xcorr2_fast(T,A)

T_size = size(T);
A_size = size(A);
outsize = A_size + T_size - 1;

% Figure out when to use spatial domain vs. freq domain
conv_time = time_conv2(T_size,A_size); % 1 conv2
fft_time = 3*time_fft2(outsize); % 2 fft2 + 1 ifft2

if (conv_time < fft_time)
    cross_corr = conv2(rot90(T,2),A);
else
    cross_corr = freqxcorr(T,A,outsize);
end

%-------------------------------
% Function  freqxcorr
%
function xcorr_ab = freqxcorr(a,b,outsize)

% Find the next largest size that is a multiple of a combination of 2, 3,
% and/or 5.  This makes the FFT calculation much faster.
optimalSize(1) = FindClosestValidDimension(outsize(1));
optimalSize(2) = FindClosestValidDimension(outsize(2));

% Calculate correlation in frequency domain
Fa = fft2(rot90(a,2),optimalSize(1),optimalSize(2));
Fb = fft2(b,optimalSize(1),optimalSize(2));
xcorr_ab = real(ifft2(Fa .* Fb));

xcorr_ab = xcorr_ab(1:outsize(1),1:outsize(2));

%-------------------------------
% Function  time_conv2
%
function time = time_conv2(obssize,refsize)

% time a spatial domain convolution for 10-by-10 x 20-by-20 matrices

% a = ones(10);
% b = ones(20);
% mintime = 0.1;

% t1 = cputime;
% t2 = t1;
% k = 0;
% while (t2-t1)<mintime
%     c = conv2(a,b);
%     k = k + 1;
%     t2 = cputime;
% end
% t_total = (t2-t1)/k;

% % convolution time = K*prod(size(a))*prod(size(b))
% % t_total = K*10*10*20*20 = 40000*K
% K = t_total/40000;

% K was empirically calculated by the commented-out code above.
K = 2.7e-8;

% convolution time = K*prod(obssize)*prod(refsize)
time =  K*prod(obssize)*prod(refsize);

%-------------------------------
% Function  time_fft2
%
function time = time_fft2(outsize)

% time a frequency domain convolution by timing two one-dimensional ffts

R = outsize(1);
S = outsize(2);

% Tr = time_fft(R);
% K_fft = Tr/(R*log(R));

% K_fft was empirically calculated by the 2 commented-out lines above.
K_fft = 3.3e-7;
Tr = K_fft*R*log(R);

if S==R
    Ts = Tr;
else
%    Ts = time_fft(S);  % uncomment to estimate explicitly
   Ts = K_fft*S*log(S);
end

time = S*Tr + R*Ts;

%-----------------------------------------------------------------------------
function [T, A, requiredNumberOfOverlapPixels] = ParseInputs(varargin)

if( nargin < 2 || nargin > 3 )
    error('ERROR: The number of arguments must be either 2 or 3.  Please see the documentation for details.');
end

T = varargin{1};
A = varargin{2};

if( nargin == 3 )
    requiredNumberOfOverlapPixels =  varargin{3};
else
    requiredNumberOfOverlapPixels = 0;
end

% The following requires the image processing toolbox, so it is commented
% out here for generality.
%iptcheckinput(T,{'logical','numeric'},{'real','nonsparse','2d','finite'},mfilename,'T',1)
%iptcheckinput(A,{'logical','numeric'},{'real','nonsparse','2d','finite'},mfilename,'A',2)

checkSizesTandA(T,A)

% See geck 342320. If either A or T has a minimum value which is negative, we
% need to shift the array so all values are positive to ensure numerically
% robust results for the normalized cross-correlation.
A = shiftData(A);
T = shiftData(T);

checkIfFlat(T);

%-----------------------------------------------------------------------------
function B = shiftData(A)

B = double(A);

is_unsigned = isa(A,'uint8') || isa(A,'uint16') || isa(A,'uint32');
if ~is_unsigned

    min_B = min(B(:));

    if min_B < 0
        B = B - min_B;
    end

end

%-----------------------------------------------------------------------------
function checkSizesTandA(T,A)

if numel(T) < 2
    eid = sprintf('Images:%s:invalidTemplate',mfilename);
    msg = 'TEMPLATE must contain at least 2 elements.';
    error(eid,'%s',msg);
end

%-----------------------------------------------------------------------------
function checkIfFlat(T)

if std(T(:)) == 0
    eid = sprintf('Images:%s:sameElementsInTemplate',mfilename);
    msg = 'The values of TEMPLATE cannot all be the same.';
    error(eid,'%s',msg);
end

%-----------------------------------------------------------------------------
function [newNumber] = FindClosestValidDimension(n)

% Find the closest valid dimension above the desired dimension.  This
% will be a combination of 2s, 3s, and 5s.

% Incrementally add 1 to the size until
% we reach a size that can be properly factored.
newNumber = n;
result = 0;
newNumber = newNumber - 1;
while( result ~= 1 )
    newNumber = newNumber + 1;
    result = FactorizeNumber(newNumber);
end

%-----------------------------------------------------------------------------
function [n] = FactorizeNumber(n)

for ifac = [2 3 5]
    while( rem(n,ifac) == 0 )
        n = n/ifac;
    end
end


function [shortestPaths, totalCosts] = kShortestPath(netCostMatrix, source, destination, k_paths)
% Function kShortestPath(netCostMatrix, source, destination, k_paths)
% returns the K first shortest paths (k_paths) from node source to node destination
% in the a network of N nodes represented by the NxN matrix netCostMatrix.
% In netCostMatrix, cost of 'inf' represents the 'absence' of a link
% It returns
% [shortestPaths]: the list of K shortest paths (in cell array 1 x K) and
% [totalCosts]   : costs of the K shortest paths (in array 1 x K)
%==============================================================
% Meral Shirazipour
% This function is based on Yen's k-Shortest Path algorithm (1971)
% This function calls a slightly modified function dijkstra()
% by Xiaodong Wang 2004.
% * netCostMatrix must have positive weights/costs
%==============================================================
%  DATE :           December 9 decembre 2009
%  Last Updated:    August 2 2010; January 6 2011; August 2 2011
%  ----Changes April 2 2010:----
%  1-previous version(9/12/2009)did not handle some exceptions which should
%    have returned empty matrices for the return values (added lines 20 and 29)
%  2-includes the changes proposed by Darren Rowland
%  ----Changes January 6 2011:----
%  1-fixed a bug reported by Babak Zafari that prevented from finding ALL
%    the shortest paths in large networks
%==============================================================
if source > size(netCostMatrix,1) || destination > size(netCostMatrix,1)
    warning('The source or destination node are not part of netCostMatrix');
    shortestPaths=[];
    totalCosts=[];
else
    %---------------------INITIALIZATION---------------------
    k=1;
    [path cost] = dijkstra(netCostMatrix, source, destination);
    %P is a cell array that holds all the paths found so far:
    if isempty(path)
        shortestPaths=[];
        totalCosts=[];
    else
        path_number = 1;
        P{path_number,1} = path; P{path_number,2} = cost;
        current_P = path_number;
        %X is a cell array of a subset of P (used by Yen's algorithm below):
        size_X=1;
        X{size_X} = {path_number; path; cost};

        %S path_number x 1
        S(path_number) = path(1); %deviation vertex is the first node initially

        %***********************
        % K = 1 is the shortest path returned by dijkstra():
        shortestPaths{k} = path ;
        totalCosts(k) = cost;
        %***********************

        %--------------------------------------------------------
        while (k < k_paths   &&   size_X ~= 0 )
            %remove P from X
            for i=1:length(X)
                if  X{i}{1} == current_P
                    size_X = size_X - 1;
                    X(i) = [];%delete cell
                    break;
                end
            end

            %---------------------------------------
            P_ = P{current_P,1}; %P_ is current P, just to make is easier for the notations

            %Find w in (P_,w) in set S, w was the dev vertex used to found P_
            w = S(current_P);
            for i = 1: length(P_)
                if w == P_(i)
                    w_index_in_path = i;
                end
            end

            for index_dev_vertex= w_index_in_path: length(P_) - 1   %index_dev_vertex is index in P_ of deviation vertex
                temp_netCostMatrix = netCostMatrix;
                %------
                %Remove vertices in P before index_dev_vertex and there incident edges
                for i = 1: index_dev_vertex-1
                    v = P_(i);
                    temp_netCostMatrix(v,:)=inf;
                    temp_netCostMatrix(:,v)=inf;
                end
                %------
                %remove incident edge of v if v is in shortestPaths (K) U P_  with similar sub_path to P_....
                SP_sameSubPath=[];
                index =1;
                SP_sameSubPath{index}=P_;
                for i = 1: length(shortestPaths)
                    if length(shortestPaths{i}) >= index_dev_vertex
                        if P_(1:index_dev_vertex) == shortestPaths{i}(1:index_dev_vertex)
                            index = index+1;
                            SP_sameSubPath{index}=shortestPaths{i};
                        end
                    end
                end
                v_ = P_(index_dev_vertex);
                for j = 1: length(SP_sameSubPath)
                    next = SP_sameSubPath{j}(index_dev_vertex+1);
                    temp_netCostMatrix(v_,next)=inf;
                end
                %------

                %get the cost of the sub path before deviation vertex v
                sub_P = P_(1:index_dev_vertex);
                cost_sub_P=0;
                for i = 1: length(sub_P)-1
                    cost_sub_P = cost_sub_P + netCostMatrix(sub_P(i),sub_P(i+1));
                end

                %call dijkstra between deviation vertex to destination node
                [dev_p c] = dijkstra(temp_netCostMatrix, P_(index_dev_vertex), destination);
                if ~isempty(dev_p)
                    path_number = path_number + 1;
                    P{path_number,1} = [sub_P(1:end-1) dev_p] ;  %concatenate sub path- to -vertex -to- destination
                    P{path_number,2} =  cost_sub_P + c ;

                    S(path_number) = P_(index_dev_vertex);

                    size_X = size_X + 1;
                    X{size_X} = {path_number;  P{path_number,1} ;P{path_number,2} };
                else
                    %warning('k=%d, isempty(p)==true!\n',k);
                end
            end
            %---------------------------------------
            %Step necessary otherwise if k is bigger than number of possible paths
            %the last results will get repeated !
            if size_X > 0
                shortestXCost= X{1}{3};  %cost of path
                shortestX= X{1}{1};        %ref number of path
                for i = 2 : size_X
                    if  X{i}{3} < shortestXCost
                        shortestX= X{i}{1};
                        shortestXCost= X{i}{3};
                    end
                end
                current_P = shortestX;
                %******
                k = k+1;
                shortestPaths{k} = P{current_P,1};
                totalCosts(k) = P{current_P,2};
                %******
            else
                %k = k+1;
            end
        end
    end
end
%--------------------------------------------------------


function cc_grids_animate ( )

%*****************************************************************************80
%
%% CC_GRIDS_ANIMATE displays a sequence of merged 2D Clenshaw-Curtis grids.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 November 2006
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  timestamp ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'CC_GRIDS_ANIMATE:\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Display a sequence of merged 2D Clenshaw-Curtis grids.\n' );

  dim_num = 2;

  while ( 1 )

    fprintf ( 1, '\n' );
    order_max_1d = input ( 'Enter the maximum orders [A,B] or RETURN to exit;' );

    if ( isempty ( order_max_1d ) )
      break
    end

    points_old = [];
    points_old_num = 0;

    points = [];
    order_nd = 0;

    for order = 1 : max ( order_max_1d(1:2) )

      if ( 0 < order_nd )
        points_old(1:2,points_old_num+1:points_old_num+order_nd) = points(1:2,1:order_nd);
        points_old_num = points_old_num + order_nd;
      end

      clf
%
%  We have to name the axes in order to control the grid.
%
      axes_handle = axes;
%
%  Compute the new points and plot them in red.
%
      order_1d(1:2) = min ( order, order_max_1d(1:2) );
      order_nd = prod ( order_1d(1:2) );

      points = cc_grid ( dim_num, order_1d, order_nd );

      handle_new = scatter ( points(1,:), points(2,:), 'r', 'filled' );
%
%  Plot the old points in blue.
%
      hold on

      if ( 0 < points_old_num )
        handle_old = scatter ( points_old(1,:), points_old(2,:), 'b', 'filled' );
      end
%
%  Force the plotting region to be square, not rectangular.
%
      axis square
%
%  Request grid lines.
%
      grid on
%
%  Specify the location of the grid lines, and suppress labeling.
%
      set ( axes_handle, 'xtick', [ -1, -.75, -.5, -.25, 0, .25, .50, .75, 1] );
      set ( axes_handle, 'xticklabel', [] );
      set ( axes_handle, 'ytick', [ -1, -.75, -.5, -.25, 0, .25, .50, .75, 1] );
      set ( axes_handle, 'yticklabel', [] );
%
%  Make the plotting region slightly bigger than the data.
%
      axis ( [ -1.1, 1.1, -1.1, 1.1 ] )
%
%  Title
%
      s = sprintf ( '%dx%d Clenshaw-Curtis Grid', order_1d(1), order_1d(2) );
      title ( s );

      fprintf ( 1, '+%dx%d Clenshaw-Curtis Grid, Press return\n', ...
        order_1d(1), order_1d(2) );

      pause

      hold off

    end

    fprintf ( 1, 'Press return to CLEAR the grid!\n' );
    pause
    clf

  end

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

  fprintf ( 1, '\n' );
  timestamp ( );

  return
end


function [ ptab, b, c, d, eps, ierror ] =  least_set_old ( ...
  ntab, xtab, ytab, ndeg )

%*****************************************************************************80
%
%% LEAST_SET_OLD constructs the least squares polynomial approximation to data.
%
%  Discussion:
%
%    The least squares polynomial is not returned directly as a simple
%    polynomial.  Instead, it is represented in terms of a set of
%    orthogonal polynomials appopriate for the given data.  This makes
%    the computation more accurate, but means that the user can not
%    easily evaluate the computed polynomial.  Instead, the routine
%    LEAST_EVAL should be used to evaluate the least squares polynomial
%    at any point.  (However, the value of the least squares polynomial
%    at each of the data points is returned as part of this computation.)
%
%
%    A discrete unweighted inner product is used, so that
%
%      ( F(X), G(X) ) = sum ( 1 <= I <= NTAB ) F(XTAB(I)) * G(XTAB(I)).
%
%    The least squares polynomial is determined using a set of
%    orthogonal polynomials PHI.  These polynomials can be defined
%    recursively by:
%
%      PHI(0)(X) = 1
%      PHI(1)(X) = X - B(1)
%      PHI(I)(X) = ( X - B(I) ) * PHI(I-1)(X) - D(I) * PHI(I-2)(X)
%
%    The array B(1:NDEG) contains the values
%
%      B(I) = ( X*PHI(I-1), PHI(I-1) ) / ( PHI(I-1), PHI(I-1) )
%
%    The array D(2:NDEG) contains the values
%
%      D(I) = ( PHI(I-1), PHI(I-1) ) / ( PHI(I-2), PHI(I-2) )
%
%    Using this basis, the least squares polynomial can be represented as
%
%      P(X)(I) = sum ( 0 <= I <= NDEG ) C(I) * PHI(I)(X)
%
%    The array C(0:NDEG) contains the values
%
%      C(I) = ( YTAB(I), PHI(I) ) / ( PHI(I), PHI(I) )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 May 2004
%
%  Author:
%
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Gisela Engeln-Muellges and Frank Uhlig,
%    Numerical Algorithms with C, pages 191-193.
%    Springer, 1996.
%
%  Parameters:
%
%    Input, integer NTAB, the number of data points.
%
%    Input, real XTAB(NTAB), the X data.  The values in XTAB
%    should be distinct, and in increasing order.
%
%    Input, real YTAB(NTAB), the Y data values corresponding
%    to the X data in XTAB.
%
%    Input, integer NDEG, the degree of the polynomial which the
%    program is to use.  NDEG must be at least 1, and less than or
%    equal to NTAB-1.
%
%    Output, real PTAB(NTAB), the value of the least squares polynomial
%    at the points XTAB(1:NTAB).
%
%    Output, real B(1:NDEG), C(1:NDEG+1), D(1:NDEG-1), arrays containing
%    data about the polynomial.
%
%    Output, real EPS, the root-mean-square discrepancy of the
%    polynomial fit.
%
%    Output, integer IERROR, error flag.
%    zero, no error occurred;
%    nonzero, an error occurred, and the polynomial could not be computed.
%
  ierror = 0;
  C_OFFSET = 1;
  D_OFFSET = -1;
%
%  Check NDEG.
%
  if ( ndeg < 1 )
    ierror = 1;
    fprintf ( 1, '\n' );
    fprintf ( 1, 'LEAST_SET_OLD - Fatal error!\n' );
    fprintf ( 1, '  NDEG < 1.\n' );
    error ( 'LEAST_SET_OLD - Fatal error!' );
  end

  if ( ntab <= ndeg )
    ierror = 1;
    fprintf ( 1, '\n' );
    fprintf ( 1, 'LEAST_SET_OLD - Fatal error!\n' );
    fprintf ( 1, '  NTAB <= NDEG.\n' );
    error ( 'LEAST_SET_OLD - Fatal error!' );
  end
%
%  Check that the abscissas are strictly increasing.
%
  for i = 1 : ntab-1
    if ( xtab(i+1) <= xtab(i) )
      ierror = 1;
      fprintf ( 1, '\n' );
      fprintf ( 1, 'LEAST_SET_OLD - Fatal error!\n' );
      fprintf ( 1, '  XTAB must be strictly increasing, but\n' );
      fprintf ( 1, '  XTAB(%d) = %f\n', i,   xtab(i)   );
      fprintf ( 1, '  XTAB(%d) = %f\n', i+1, xtab(i+1) );
      error ( 'LEAST_SET_OLD - Fatal error!' );
    end
  end

  i0l1 = 0;
  i1l1 = ntab;
%
%  The polynomial is of degree at least 0.
%
  y_sum = sum ( ytab(1:ntab) );
  rn0 = ntab;
  c(0+C_OFFSET) = y_sum / ntab;

  ptab(1:ntab) = y_sum / ntab;

  if ( ndeg == 0 )
    eps = sum ( ( ptab(1:ntab) - ytab(1:ntab) ).^2 );
    eps = sqrt ( eps / ntab );
    b = [];
    d = [];
    return;
  end
%
%  The polynomial is of degree at least 1.
%
  b(1) = sum ( xtab(1:ntab) ) / ntab;

  s = 0.0E+00;
  sum2 = 0.0E+00;
  for i = 1 : ntab
    ztab(i1l1+i) = xtab(i) - b(1);
    s = s + ztab(i1l1+i)^2;
    sum2 = sum2 + ztab(i1l1+i) * ( ytab(i) - ptab(i) );
  end

  rn1 = s;
  c(1+C_OFFSET) = sum2 / s;

  for i = 1 : ntab
    ptab(i) = ptab(i) + c(1+C_OFFSET) * ztab(i1l1+i);
  end

  if ( ndeg == 1 )
    eps = sum ( ( ptab(1:ntab) - ytab(1:ntab) ).^2 );
    eps = sqrt ( eps / ntab );
    d = [];
    return;
  end

  ztable(1:ntab) = 1.0;

  mdeg = 2;
  k = 2;

  while ( 1 )

    d(k+D_OFFSET) = rn1 / rn0;

    sum2 = 0.0;
    for i = 1 : ntab
      sum2 = sum2 + xtab(i) * ztab(i1l1+i) * ztab(i1l1+i);
    end

    b(k) = sum2 / rn1;

    s = 0.0;
    sum2 = 0.0;
    for i = 1 : ntab
      ztab(i0l1+i) = ( xtab(i) - b(k) ) * ztab(i1l1+i) ...
        - d(k+D_OFFSET) * ztab(i0l1+i);
      s = s + ztab(i0l1+i) * ztab(i0l1+i);
      sum2 = sum2 + ztab(i0l1+i) * ( ytab(i) - ptab(i) );
    end

    rn0 = rn1;
    rn1 = s;

    c(k+C_OFFSET) = sum2 / rn1;

    it = i0l1;
    i0l1 = i1l1;
    i1l1 = it;

    for i = 1 : ntab
      ptab(i) = ptab(i) + c(k+C_OFFSET) * ztab(i1l1+i);
    end

    if ( ndeg <= mdeg )
      break;
    end

    mdeg = mdeg + 1;
    k = k + 1;

  end
%
%  Compute the RMS error.
%
  eps = sum ( ( ptab(1:ntab) - ytab(1:ntab) ).^2 );
  eps = sqrt ( eps / ntab );

  return
end


function julian = jed_to_yearcount_julian ( jed )

%*****************************************************************************80
%
%% JED_TO_YEARCOUNT_JULIAN converts a JED to a Julian year count.
%
%  Discussion:
%
%    An average year in the Julian calendar is exactly 365.25 days long.
%    This calculation counts the number of average Julian years from
%    the beginning of the year 2000.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 June 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real JED, the Julian Ephemeris Date.
%
%    Output, real JULIAN, the Julian year.
%
  year_length = 365.25;

  jed_epoch = epoch_to_jed_y2k ( );

  julian = 2000.0 + ( jed - jed_epoch ) / year_length;

  return
end


function face_normal = stla_face_normal_compute ( node_num, face_num, ...
  node_xyz, face_node )

%*****************************************************************************80
%
%% STLA_FACE_NORMAL_COMPUTE computes normal vectors for an ASCII StereoLithography file.
%
%  Discussion:
%
%    This routine computes the normal vector to each triangular face
%    in the STLA solid.  If the nodes of each triangular face are
%    listed in counterclockwise order (as seen from outside the solid),
%    then the normal vectors will be properly outward facing.
%
%    The normal vectors will have unit Euclidean norm.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    24 September 2005
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    3D Systems, Inc,
%    Stereolithography Interface Specification,
%    October 1989.
%
%  Parameters:
%
%    Input, integer NODE_NUM, the number of nodes.
%
%    Input, integer FACE_NUM, the number of faces.
%
%    Input, real NODE_XYZ(3,NODE_NUM), the node coordinates.
%
%    Input, integer FACE_NODE(3,FACE_NUM), the nodes making faces.
%
%    Input, integer FACE_MAX, the maximum number of faces.
%
%    Output, real FACE_NORMAL(3,FACE_NUM), the normal vector at each face.
%
  for face = 1 : face_num

    n1 = face_node(1,face);
    n2 = face_node(2,face);
    n3 = face_node(3,face);

    v1(1:3) = node_xyz(1:3,n2) - node_xyz(1:3,n1);
    v2(1:3) = node_xyz(1:3,n3) - node_xyz(1:3,n1);

    face_normal(1:3,face) = r8vec_cross_3d ( v1, v2 );

    norm = sqrt ( sum ( ( face_normal(1:3,face) ).^2 ) );

    if ( norm ~= 0.0 )
      face_normal(1:3,face) = face_normal(1:3,face) / norm;
    end

  end

  return
end


function a_inverse = r8ut_inverse ( n, a )

%*****************************************************************************80
%
%% R8UT_INVERSE computes the inverse of a R8UT matrix.
%
%  Discussion:
%
%    The R8UT storage format is used for an M by N upper triangular
%    matrix.  The format stores all M*N entries, even those which are zero.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 March 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    A Nijenhuis and H Wilf,
%    Combinatorial Algorithms,
%    Academic Press, 1978, second edition,
%    ISBN 0-12-519260-6
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%
%    Input, real A(N,N), the R8UT matrix to be inverted.
%
%    Output, real A_INVERSE(N,N), the inverse of the upper triangular matrix.
%

%
%  Check.
%
  for i = 1 : n
    if ( a(i,i) == 0.0 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'R8UT_INVERSE - Fatal error!\n' );
      fprintf ( 1, '  Zero diagonal element.\n' );
      error ( 'R8UT_INVERSE - Fatal error!' );
    end
  end

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

  for j = n : -1 : 1

    for i = n : -1 : 1

      if ( j < i )

        a_inverse(i,j) = 0.0;

      elseif ( i == j )

        a_inverse(i,j) = 1.0 / a_inverse(i,j);

      elseif ( i < j )

        a_inverse(i,j) = - ( a_inverse(i,i+1:j) * a_inverse(i+1:j,j) ) ...
          / a_inverse(i,i);

      end

    end
  end

  return
end


function gqn_sparse_test ( )

%*****************************************************************************80
%
%% GQN_SPARSE_TEST uses the GQN function to build a sparse grid.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 May 2014
%
%  Author:
%
%    Original MATLAB version by Florian Heiss, Viktor Winschel.
%    This MATLAB version by John Burkardt.
%
%  Local parameters:
%
%    Local, integer D, the spatial dimension.
%
  d = 5;
  trueval = hermite_integral ( d );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'GQN_SPARSE_TEST:\n' );
  fprintf ( 1, '  GQN sparse grid:\n' );
  fprintf ( 1, '  Gauss quadrature, Hermite weight over (-oo,+oo).\n' );
  fprintf ( 1, '  Exact integral is %g\n', trueval );
  fprintf ( 1, '\n' );
  fprintf ( 1, '   D  Level   Nodes    SG estimate MC estimate\n' );
  fprintf ( 1, '                       SG error    MC error\n' );
  fprintf ( 1, '\n' );

  for k = 1 : 8
%
%  Compute sparse grid estimate.
%
    [ x, w ] = nwspgr ( 'gqn', d, k );
    [ n, ~ ] = size ( x );
    fx = hermite_integrand ( d, n, x );
    sgappr = w' * fx;
    sgerror = sqrt ( ( sgappr - trueval ) .^ 2 ) / trueval;
%
%  Average 1000 Monte Carlo estimates.
%
    sim = zeros(1000,1);
    for r = 1 : 1000
      x = randn ( n, d );
      fx = hermite_integrand ( d, n, x );
      sim(r) = mean ( fx );
    end
    simappr = mean ( sim );
    simerror = sqrt ( mean ( ( sim - trueval ) .^ 2 ) ) / trueval;

    fprintf ( '  %2d     %2d  %6d  %10.5g  %10.5g\n', ...
      d, k, n, sgappr, simappr );
    fprintf ( '                     %10.5g  %10.5g\n', ...
               sgerror, simerror );

  end

  return
end


% Elmore delay sizing for a straight wire (GP)
% Boyd, "Problems in VLSI design" (Lecture)
% Written for CVX by Almir Mutapcic 02/08/06
%
% We consider the problem of finding optimal width profile
% for a straight wire segmented into N parts. We want to
% minimize the Elmore delay, subject to limits on wire width
% and the total area. We use a pi-model for each wire segment.
% Problem can be formulated as GP:
%
%   minimize   D
%       s.t.   w_min <= w <= w_max
%              area  <= Amax
%
% where variables are widths w (and arrival times T that are used
% to formulate the overall delay D expression).
%
% Important: We label root node as 1, and all the other nodes as
%            node_label_in_the_paper + 1 (due to Matlab's convention).
%            Also label nodes with increasing numbers downstream.

%********************************************************************
% user supplied data (problem constants and tree topology)
%********************************************************************
N = 10+1; % number of segments (including the root node which is labeled as 1)

% parent node array for the straight wire
% specifies which node is a unique parent for node i (always have a tree)
parent = [0:N-1];

% problem constants
Rsource = 0.1;
l = 1*ones(N-1,1);
alpha = 1*ones(N-1,1);
beta  = 1*ones(N-1,1);
gamma = 1*ones(N-1,1);

% load capacitance at each node
Cload = [0; ones(N-1,1)];

% minimum and maximum width and area specification
Wmin = 1;
Wmax = 10;
Amax = 50;

%********************************************************************
% derived data (computed from user's data)
%********************************************************************
% compute children cell array (evaluate who are children for each node)
children = cell(N,1);
leafs = [];
for node = [1:N]
  children{node} = find(parent == node);
  if isempty(children{node})
    leafs(end+1) = node; % leafs have no children
  end
end

%********************************************************************
% optimization
%********************************************************************

disp('Generating the tradeoff curve...')
Darray = []; widths = [];
for Amax = [10.05 10.5 11 12:2:20 22.5 25:5:60]
    fprintf( 'Amax = %5.2f: ', Amax );
    cvx_begin gp quiet
        % optimization variables
        variable w(N-1)     % wire width
        variable T(N)       % arrival time (Elmore delay to node i)

        % objective is the critical Elmore delay
        minimize( max( T(leafs) ) )
        subject to

          % wire segment resistance is inversely proportional to widths
          R = alpha.*l./w;
          R = [Rsource; R];

          % wire segment capacitance is an affine function of widths
          C_bar = beta.*l.*w + gamma.*l;
          C_bar = [0; C_bar];

          % compute common capacitances for each node (C_tilde in GP tutorial)
          C_tilde = cvx( zeros(N,1) );
          for node = [1:N]
            C_tilde(node,1) = Cload(node);
            for k = parent(node)
              if k > 0; C_tilde(node,1) = C_tilde(node,1) + C_bar(k); end;
            end
            for k = children{node}
              C_tilde(node,1) = C_tilde(node,1) + C_bar(k);
            end
          end

          % now compute total downstream capacitances
          C_total = C_tilde;
          for node = N:-1:1
            for k = children{node}
              C_total(node,1) = C_total(node,1) + C_total(k,1);
            end
          end

        % generate Elmore delay constraints
        R(1)*C_total(1) <= T(1,1);
        for node = 2:N
          R(node)*C_total(node) + T(parent(node),1) <= T(node,1);
        end

        % collect all the constraints
        sum(w.*l) <= Amax;
        Wmin <= w <= Wmax;
    cvx_end
    % display and store computed values
    fprintf('delay = %3.2f\n',cvx_optval);
    Darray = [Darray cvx_optval];
    widths = [widths w];
end

% indices of four taper designs on the tradeoff curve
Amax = [10.05 10.5 11 12:2:20 22.5 25:5:60];
A11ind = find(Amax == 11);
A20ind = find(Amax == 20);
A35ind = find(Amax == 35);
A50ind = find(Amax == 50);

% plot the tradeoff curve
figure, clf
plot(Darray,Amax, ...
     Darray(A11ind),Amax(A11ind),'ro',...
     Darray(A20ind),Amax(A20ind),'ro',...
     Darray(A35ind),Amax(A35ind),'ro',...
     Darray(A50ind),Amax(A50ind),'ro');
xlabel('Elmore delay D'); ylabel('Amax');
disp('Optimal tradeoff curve plotted.')

% plot four taper designs
figure, clf
w1 = widths(:,A50ind);
w2 = widths(:,A35ind);
w3 = widths(:,A20ind);
w4 = widths(:,A11ind);
plot_four_tapers(w1,w2,w3,w4);


function [lImFea] = extr_lIm_fea( lIm )

[nrow, ncol] = size(lIm);

lImFea = zeros([nrow, ncol, 4]);

% first order gradient filters
hf1 = [-1,0,1];
vf1 = [-1,0,1]';

lImFea(:, :, 1) = conv2(lIm, hf1, 'same');
lImFea(:, :, 2) = conv2(lIm, vf1, 'same');

% second order gradient filters
hf2 = [1,0,-2,0,1];
vf2 = [1,0,-2,0,1]';

lImFea(:, :, 3) = conv2(lIm,hf2,'same');
lImFea(:, :, 4) = conv2(lIm,vf2,'same');


function Lms = gallager_ach(Ns, delta, epsil)
% computes gallager's achievability bound for BSC
%
% We use it in the form
%
%     P_e \le M^s  (   Sum_y [ Sum_x Q(x) W(y|x)^{1/1+s} ]^(1+s)   )^n
%
% Note: we then conclude that from (M, P_e) code with AVG P_e
% we can get (M/2, 2 P_e) code with MAXIMAL. Thus we must take P_e = epsil/2 and then
% subtract 1 bit from gallager's result
%

Lms = [];

for n = Ns;

	f = @(x) -( log2(epsil/2) ./ x + n - n .* (1+x) ./ x .* log2( delta.^(1./(1+x)) + (1-delta).^(1./(1+x))));

	[lambda f] = fminbnd(f, 0, 1);

	% Cut half of the codewords

	logm = -f-1;

	disp(sprintf('--- Gallager: n=%d, best_lambda = %g, log M >= %g', n, lambda, logm));

	if ( lambda <= 0 ) || (lambda >= 1)
		disp(sprintf('------- WARNING: lambda on the boundary! params: n=%d, delta=%g, epsil=%g', n, delta, epsil));
	end
	Lms = [Lms logm];
end


% GET ROTATION MATRIX FROM QUATERNION
function [R] = R_q(q)
% This function defines the equivalent rotation matrix from the
% provided quaternion. (Associated block "Quaternion to DCM")
% INPUT:
% q    - The quaternion rotation
% OUTPUT:
% R_AB - The rotation matrix through A to B
% R_BA - The reverse rotation matrix from B to A

assert(numel(q) == 4,'Input quaternion has wrong dimensions');

R = zeros(3,3);
% Normalise the quaternion
q = unit(q);

% SAME AS THE ROBOTICS TOOL BOX....
R(1,1) = q(1)^2 + q(2)^2 - q(3)^2 - q(4)^2;
R(1,2) = 2*(q(2)*q(3) - q(1)*q(4));
R(1,3) = 2*(q(1)*q(3) + q(2)*q(4));
R(2,1) = 2*(q(2)*q(3) + q(1)*q(4));
R(2,2) = q(1)^2 - q(2)^2 + q(3)^2 - q(4)^2;
R(2,3) = 2*(q(3)*q(4) - q(1)*q(2));
R(3,1) = 2*(q(2)*q(4) - q(1)*q(3));
R(3,2) = 2*(q(1)*q(2) + q(3)*q(4));
R(3,3) = q(1)^2 - q(2)^2 - q(3)^2 + q(4)^2;
end


%
% This code calculates the interevent distances and the correlation integral
% of a subset selected with the sampling sphere. The code is called from circlefd.m.
% Francesco Pacchiani 1/2000
%
% Calculation of the 3D distances between all possible pairs
% (combination of n epicenters taken 2 at a time) of earthquakes of
% the given dataset.
%
%
% Variables
%
N = size(E,1);				% N= # of events in the catalogue; E= Earthquake catalogue
pairdist = []; 			% pairdist= Vector of interevent distances
j = nchoosek(N,2);			% j= # of interevent distances calculated
pairdist = zeros(j,1);
k = 0;
%E.Latitude= (max(Da(:,2))+min(Da(:,2)))/2;

Ho_Wb = waitbar(0,'Calculating the fractal dimension D');
Hf_Cfig = gcf;
Hf_child = get(groot,'children');
set(Hf_child,'pointer','watch','papertype','A4');
%
%
% Calculation of the interevent distances in 2D plus the depths differences.
%
%
for i = 1:(N-1)

    lon1 = repmat(E(i,1), [(N-i),1]);
    lat1 = repmat(E(i,2), [(N-i),1]);

    lon2 = E((i+1):end, 1);
    lat2 = E((i+1):end, 2);

    pairdist(k+1:k + size(lon1, 1)) = distance(lat1,lon1,lat2,lon2);

    k = k + size(lon1,1);

    waitbar((0.75/(N-1))*i, Ho_Wb);

end

clear i j k;
%
%
% Conversion of the interevent distances from degrees to kilometers and calculates
% the interevent distances in three dimensions.
%
%
if dtokm == 1
    pairdist = pairdist.*111;
end
%
%
% Calculation of the correlation integral using as input the
% pair distances computed above.
%
%
% Variables
%
d = 2;						%d = the dimension of the embedding volume.
rmax = max(pairdist);
rmin = min(pairdist);

if rmin == 0
    rmin = 0.01;
end

lrmin = log10(rmin);
lrmax = log10(max(pairdist));

%u = (log10(rmin):0.15:log10(rmax))';
%
% Defining the distance vector r in order that on the
% log-log graph all the points plot at equal distances from one another.
%
r = (logspace(lrmin, lrmax, 50))';
%r = zeros(size(u,1),1);
%r = 10.^u;
%
%
corint = [];						% corint= Vector of ?cumulative? correlation integral values for increasing interevent radius
corint = zeros(size(r,1),1);
k = 1;

for i = 1:size(r,1)

    j = [];
    j = pairdist < r(i);
    corint (k,1) = (2/(N*(N-1)))*sum(j);
    k = k + 1;
    waitbar(0.75 + (0.25/size(r,1))*i,Ho_Wb);

end

clear i j k;
close(Ho_Wb);
Hf_child = get(groot,'children');
set(Hf_child,'pointer','arrow');
%
%
dofd = 'fd';


function [x, c, funVal, ValueL]=sgLogisticR(A, y, z, opts)
%
%%
% Function sgLogisticR
%      Logistic Loss with the
%           sparse group Lasso Regularization
%
%% Problem
%
%  min  f(x,c) = - sum_i weight_i * log (p_i)
%                + z_1 \|x\|_1 + z_2 * sum_j w_j ||x_{G_j}||
%
%  a_i denotes a training sample,
%      and a_i' corresponds to the i-th row of the data matrix A
%
%  y_i (either 1 or -1) is the response
%
%  p_i= 1/ (1+ exp(-y_i (x' * a_i + c) ) ) denotes the probability
%
%  G_j's are nodes with tree structure
%
%  For this special case,
%    we have L1 for each element
%    and the L2 for the non-overlapping group
%
%  The tree overlapping group information is contained in
%  opts.ind, which is a 3 x nodes matrix, where nodes denotes the number of
%  nodes of the tree.
%  opts.ind(1,:) contains the starting index
%  opts.ind(2,:) contains the ending index
%  opts.ind(3,:) contains the corresponding weight (w_j)
%
%% Input parameters:
%
%  A-         Matrix of size m x n
%                A can be a dense matrix
%                         a sparse matrix
%                         or a DCT matrix
%  y -        Response vector (of size mx1)
%  z -        Regularization parameter (z >=0)
%  opts-      Optional inputs (default value: opts=[])
%             !!We require that opts.ind is specified.!!
%
%% Output parameters:
%  x-         The obtained weight of size n x 1
%  c-         The obtained intercept (scalar)
%  funVal-    Function value during iterations
%
%% Copyright (C) 2009-2010 Jun Liu, and Jieping Ye
%
% You are suggested to first read the Manual.
%
% For any problem, please contact with Jun Liu via j.liu@asu.edu
%
% Last modified on February 19, 2010.
%
%% Related papers
%
% [1] Jun Liu and Jieping Ye, Moreau-Yosida Regularization for
%     Grouped Tree Structure Learning, NIPS 2010
%
%% Related functions:
%
%  sll_opts
%
%%

%% Verify and initialize the parameters
%%
if (nargin <4)
    error('\n Inputs: A, y, z, and opts (.ind) should be specified!\n');
end

[m,n]=size(A);

if (length(y) ~=m)
    error('\n Check the length of y!\n');
end

if (z(1)<0 || z(2)<0)
    error('\n z should be nonnegative!\n');
end

lambda1=z(1);
lambda2=z(2);

opts=sll_opts(opts); % run sll_opts to set default values (flags)

% restart the program for better efficiency
%  this is a newly added function
if (~isfield(opts,'rStartNum'))
    opts.rStartNum=opts.maxIter;
else
    if (opts.rStartNum<=0)
        opts.rStartNum=opts.maxIter;
    end
end

%% Detailed initialization
%% Normalization

% Please refer to the function 'sll_opts'
%                 for the definitions of mu, nu and nFlag
%
% If .nFlag =1, the input matrix A is normalized to
%                     A= ( A- repmat(mu, m,1) ) * diag(nu)^{-1}
%
% If .nFlag =2, the input matrix A is normalized to
%                     A= diag(nu)^{-1} * ( A- repmat(mu, m,1) )
%
% Such normalization is done implicitly.
%     This implicit normalization is suggested for the sparse matrix,
%                                    but not for the dense matrix.
%

if (opts.nFlag~=0)
    if (isfield(opts,'mu'))
        mu=opts.mu;
        if(size(mu,2)~=n)
            error('\n Check the input .mu');
        end
    else
        mu=mean(A,1);
    end

    if (opts.nFlag==1)
        if (isfield(opts,'nu'))
            nu=opts.nu;
            if(size(nu,1)~=n)
                error('\n Check the input .nu!');
            end
        else
            nu=(sum(A.^2,1)/m).^(0.5); nu=nu';
        end
    else % .nFlag=2
        if (isfield(opts,'nu'))
            nu=opts.nu;
            if(size(nu,1)~=m)
                error('\n Check the input .nu!');
            end
        else
            nu=(sum(A.^2,2)/n).^(0.5);
        end
    end

    ind_zero=find(abs(nu)<= 1e-10);    nu(ind_zero)=1;
    % If some values in nu is typically small, it might be that,
    % the entries in a given row or column in A are all close to zero.
    % For numerical stability, we set the corresponding value to 1.
end

if (~issparse(A)) && (opts.nFlag~=0)
    fprintf('\n -----------------------------------------------------');
    fprintf('\n The data is not sparse or not stored in sparse format');
    fprintf('\n The code still works.');
    fprintf('\n But we suggest you to normalize the data directly,');
    fprintf('\n for achieving better efficiency.');
    fprintf('\n -----------------------------------------------------');
end

%% Group & Others

% Initialize ind
if (~isfield(opts,'ind'))
    error('\n In sgLogisticR, the field .ind should be specified');
else
    ind=opts.ind;

    if (size(ind,1)~=3)
        error('\n Check opts.ind');
    end
end

% The parameter 'weight' contains the weight for each training sample.
% See the definition of the problem above.
% The summation of the weights for all the samples equals to 1.
if (isfield(opts,'sWeight'))
    sWeight=opts.sWeight;

    if ( length(sWeight)~=2 || sWeight(1) <=0 || sWeight(2) <= 0)
        error('\n Check opts.sWeight, which contains two positive values');
    end

    % we process the weight, so that the summation of the weights for all
    % the samples is 1.

    p_flag=(y==1);                  % the indices of the postive samples
    m1=sum(p_flag) * sWeight(1);    % the total weight for the positive samples
    m2=sum(~p_flag) * sWeight(2);   % the total weight for the positive samples

    weight(p_flag,1)=sWeight(1)/(m1+m2);
    weight(~p_flag,1)=sWeight(2)/(m1+m2);
else
    weight=ones(m,1)/m;             % if not specified, we apply equal weight
end

%% Starting point initialization

p_flag=(y==1);                  % the indices of the postive samples
m1=sum(weight(p_flag));         % the total weight for the positive samples
m2=1-m1;                        % the total weight for the positive samples

% process the regularization parameter
if (opts.rFlag==0)
    lambda=z;
else % z here is the scaling factor lying in [0,1]
    if (lambda1<0 || lambda1>1 || lambda2<0 || lambda2>1)
        error('\n opts.rFlag=1, and z should be in [0,1]');
    end

    % we compute ATb for computing lambda_max, when the input z is a ratio

    b(p_flag,1)=m2;  b(~p_flag,1)=-m1;
    b=b.*weight;

    % compute AT b
    if (opts.nFlag==0)
        ATb =A'*b;
    elseif (opts.nFlag==1)
        ATb= A'*b - sum(b) * mu';  ATb=ATb./nu;
    else
        invNu=b./nu;               ATb=A'*invNu-sum(invNu)*mu';
    end

    % compute lambda1_max
    temp=abs(ATb);
    lambda1_max=max(temp);

    lambda1=lambda1*lambda1_max;

    % compute lambda2_max(lambda_1)
    temp=max(temp-lambda1,0);

    if ( min(ind(3,:))<=0 )
        error('\n In this case, lambda2_max = inf!');
    end
    lambda2_max=computeLambda2Max(temp,n,ind,size(ind,2));

    lambda2=lambda2*lambda2_max;
end

% initialize a starting point
if opts.init==2
    x=zeros(n,1); c=log(m1/m2);
else
    if isfield(opts,'x0')
        x=opts.x0;
        if (length(x)~=n)
            error('\n Check the input .x0');
        end
    else
        x=zeros(n,1);
    end

    if isfield(opts,'c0')
        c=opts.c0;
    else
        c=log(m1/m2);
    end
end

% compute A x
if (opts.nFlag==0)
    Ax=A* x;
elseif (opts.nFlag==1)
    invNu=x./nu; mu_invNu=mu * invNu;
    Ax=A*invNu -repmat(mu_invNu, m, 1);
else
    Ax=A*x-repmat(mu*x, m, 1);    Ax=Ax./nu;
end

%% The main program

if (opts.mFlag==0 && opts.lFlag==0)

    bFlag=0; % this flag tests whether the gradient step only changes a little

    L=1/m; % the intial guess of the Lipschitz continuous gradient

    weighty=weight.*y;
    % the product between weight and y

    % assign xp with x, and Axp with Ax
    xp=x; Axp=Ax; xxp=zeros(n,1);
    cp=c;         ccp=0;

    %% The Armijo Goldstein line search schemes + accelearted gradient descent

    alphap=0; alpha=1;

    for iterStep=1:opts.maxIter
        % --------------------------- step 1 ---------------------------
        % compute search point s based on xp and x (with beta)
        beta=(alphap-1)/alpha;    s=x + beta* xxp;  sc=c + beta* ccp;

        % --------------------------- step 2 ---------------------------
        % line search for L and compute the new approximate solution x

        % compute As=A*s
        As=Ax + beta* (Ax-Axp);

        % aa= - diag(y) * (A * s + sc)
        aa=- y.*(As+ sc);

        % fun_s is the logistic loss at the search point
        bb=max(aa,0);
        fun_s= weight' * ( log( exp(-bb) +  exp(aa-bb) ) + bb );

        % compute prob=[p_1;p_2;...;p_m]
        prob=1./( 1+ exp(aa) );

        % b= - diag(y.* weight) * (1 - prob)
        b= -weighty.*(1-prob);

        gc=sum(b); % the gradient of c

        % compute g= AT b, the gradient of x
        if (opts.nFlag==0)
            g=A'*b;
        elseif (opts.nFlag==1)
            g=A'*b - sum(b) * mu';  g=g./nu;
        else
            invNu=b./nu;              g=A'*invNu-sum(invNu)*mu';
        end

        % copy x and Ax to xp and Axp
        xp=x;    Axp=Ax;
        cp=c;

        while (1)
            % let s walk in a step in the antigradient of s to get v
            % and then do the L1/Lq-norm regularized projection
            v=s-g/L;  c= sc- gc/L;

            % tree overlapping group Lasso projection
            ind_work(1:2,:)=[ [-1, -1]', ind(1:2,:) ];
            ind_work(3,:)=[ lambda1/L, ind(3,:) * (lambda2 / L) ];

            x=altra(v, n, ind_work, size(ind_work,2));

            v=x-s;  % the difference between the new approximate solution x
            % and the search point s

            % compute A x
            if (opts.nFlag==0)
                Ax=A* x;
            elseif (opts.nFlag==1)
                invNu=x./nu; mu_invNu=mu * invNu;
                Ax=A*invNu -repmat(mu_invNu, m, 1);
            else
                Ax=A*x-repmat(mu*x, m, 1);     Ax=Ax./nu;
            end

            % aa= - diag(y) * (A * x + c)
            aa=- y.*(Ax+ c);

            % fun_x is the logistic loss at the new approximate solution
            bb=max(aa,0);
            fun_x= weight'* ( log( exp(-bb) +  exp(aa-bb) ) + bb );

            r_sum= (v'*v + (c-sc)^2) / 2;
            l_sum=fun_x - fun_s - v'* g - (c-sc)* gc;

            if (r_sum <=1e-20)
                bFlag=1; % this shows that, the gradient step makes little improvement
                break;
            end

            % the condition is fun_x <= fun_s + v'* g + c * gc
            %                           + L/2 * (v'*v + (c-sc)^2 )
            if(l_sum <= r_sum * L)
                break;
            else
                L=max(2*L, l_sum/r_sum);
                %fprintf('\n L=%e, r_sum=%e',L, r_sum);
            end
        end

        % --------------------------- step 3 ---------------------------
        % update alpha and alphap, and check whether converge
        alphap=alpha; alpha= (1+ sqrt(4*alpha*alpha +1))/2;

        ValueL(iterStep)=L;
        % store values for L

        xxp=x-xp;    ccp=c-cp;
        funVal(iterStep)=fun_x;

        % compute the regularization part
        ind_work(1:2,:)=[ [-1, -1]', ind(1:2,:) ];
        ind_work(3,:)=[ lambda1, ind(3,:) * lambda2 ];
        tree_norm=treeNorm(x, n, ind_work, size(ind_work,2));

        % function value = loss + regularizatioin
        funVal(iterStep)=fun_x + tree_norm;

        if (bFlag)
            % fprintf('\n The program terminates as the gradient step changes the solution very small.');
            break;
        end

        switch(opts.tFlag)
            case 0
                if iterStep>=2
                    if (abs( funVal(iterStep) - funVal(iterStep-1) ) <= opts.tol)
                        break;
                    end
                end
            case 1
                if iterStep>=2
                    if (abs( funVal(iterStep) - funVal(iterStep-1) ) <=...
                            opts.tol* funVal(iterStep-1))
                        break;
                    end
                end
            case 2
                if ( funVal(iterStep)<= opts.tol)
                    break;
                end
            case 3
                norm_xxp=sqrt(xxp'*xxp);
                if ( norm_xxp <=opts.tol)
                    break;
                end
            case 4
                norm_xp=sqrt(xp'*xp);    norm_xxp=sqrt(xxp'*xxp);
                if ( norm_xxp <=opts.tol * max(norm_xp,1))
                    break;
                end
            case 5
                if iterStep>=opts.maxIter
                    break;
                end
        end

        % restart the program every opts.rStartNum
        if (~mod(iterStep, opts.rStartNum))
            alphap=0; alpha=1;
            xp=x; Axp=Ax; xxp=zeros(n,1); L =L/2;
        end
    end
else
    error('\n The function does not support opts.mFlag neq 0 & opts.lFlag neq 0!');
end


% Minimum-phase spectrum of a given spectrum using the complex cepstrum
%
% Description
%  Compute the minimum-phase spectrum of a given spectrum X by dropping the
%  negative quefrencies of X.
%
% Input
%  X   : The spectrum to convert (full DFT length)
%
% Output
%  M   : The corresponding minimum-phase spectrum
%  lM  : The log minimum-phase spectrum
%
% References
%  [1] Alan V. Oppenheim and Ronald W. Schafer, "Digital Signal Processing",
%      Prentice-Hall, 2nd edition, 1978.
%      Note that this 2nd edition contains a chapter about complex cepstrum which
%      has been removed in the 3rd edition (and possibly came back in the 4th ed.)
%
% Copyright (c) 2011 University of Crete - Computer Science Department (UOC-CSD)
%
% License
%  This file is under the LGPL license,  you can
%  redistribute it and/or modify it under the terms of the GNU Lesser General
%  Public License as published by the Free Software Foundation, either version 3
%  of the License, or (at your option) any later version. This file is
%  distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
%  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
%  PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
%  details.
%
% This function is part of the Covarep project: http://covarep.github.io/covarep
%
% Author
%  Gilles Degottex <degottex@csd.uoc.gr>
%

function [M lM] = spec2minphasespec(X)

    X = X(:).';

    rcc = ifft(log(abs(X))); % Compute the real cepstrum

    if mod(length(X),2)==0
        % For even DFT length
        lM = fft([rcc(1),2*rcc(2:end/2),rcc(end/2+1)], length(X));% [1]
    else
        % For odd DFT length
        lM = fft([rcc(1),2*rcc(2:(end-1)/2+1)], length(X));       % [1]
    end

    M = exp(lM);

return


function pers=ordinal_persistence(S)
% ORDINAL_PERSISTENCE computes the persistence of an ordered multilayer partition
%
% Version: 2.2.0
% Date: Thu 11 Jul 2019 12:25:42 CEST
%
% pers = ORDINAL_PERSISTENCE(S) with a single multilayer partition or a
% cell of multilayer partitions S (with S{i} the ith multilayer partition
% of cell S) computes the "persistence" of ordered multilayer partitions. The
% output pers is a vector such that pers(i) is the persistence of multilayer
% partition S{i} (stored as an N*T matrix where N is the number of nodes in
% each layer and T is the number of layers). For a multilayer partition with
% ordered layers, the value of persistence is the number of nodes that do
% not change community assignments between consecutive layers (see Bazzi
% et al. 2016 for more detail). Ordinal persistence varies between 0 and 1.
% Ordinal persistence is related to the multilayer quality function
% developed in Mucha et al. 2010 when one uses ordinal interlayer coupling.
%
%   References:
%
%     Mucha, Peter J., Thomas Richardson, Kevin Macon, Mason A. Porter, and
%     Jukka-Pekka Onnela. "Community Structure in Time-Dependent,
%     Multiscale, and Multiplex Networks," Science 328, 876-878 (2010).
%
%     Bazzi, Marya, Mason A. Porter, Stacy Williams, Mark McDonald, Daniel
%     J. Fenn, and Sam D. Howison. "Community Detection in Temporal Multilayer
%     Networks, with an Application to Correlation Networks", MMS: A SIAM
%     Interdisciplinary Journal 14, 1-41 (2016).

if ~iscell(S)
    S={S};
end

[N,T]=size(S{1});
pers=zeros(length(S),1);
for i=1:length(S)
    pers(i)=sum(sum(S{i}(:,1:end-1)==S{i}(:,2:end)))/(N*(T-1));
end

end


%%***********************************************************
%% lmiexamp2: generate SDP data for the following LMI problem
%%
%%  max  -Tr(P)
%%  s.t. A1*P + P*A1' + B*diag(d)*B' <= 0
%%       A2*P + P*A2' + B*diag(d)*B' <= 0
%%                                -d <= 0
%%                            sum(d)  = 1
%%***********************************************************
%% Here is an example on how to use this function to
%% find an optimal P.
%%
%% A1 = [-1  0  0; 0 -2  0; 1  1 -1];
%% A2 = A1 + 0.1*A1';
%% B  = [1 2; 3 4; 5 6];
%%
%% [blk,Avec,C,b] = lmiexamp2(A1,A2,B);
%% [obj,X,y,Z] = sqlp(blk,Avec,C,b);
%% n = size(A1,2); N = n*(n+1)/2; dlen = size(B,2);
%% P = smat(blk(1,:),y(1:N));
%% d = y(N+[1:dlen]);
%%*****************************************************************
%% SDPT3: version 4.0
%% Copyright (c) 1997 by
%% Kim-Chuan Toh, Michael J. Todd, Reha H. Tutuncu
%% Last Modified: 16 Sep 2004
%%*****************************************************************

   function [blk,Avec,C,b] = lmiexamp2(A1,A2,B);

%%
   n1 = size(A1,2);  n2 = size(A2,2);
   if (n1 ~= n2); error('lmiexamp2: A1, A2 not compatible'); end;
%%
   n = n1;
   I = speye(n);
   blk{1,1}  = 's'; blk{1,2} = n;
   Avec{1,1} = lmifun(A1,I,B);
   C{1,1} = sparse(n,n);
%%
   blk{2,1}  = 's'; blk{2,2} = n;
   Avec{2,1} = lmifun(A2,I,B);
   C{2,1} = sparse(n,n);
%%
%% and constraints:  -d <= 0
%%
   N = n*(n+1)/2; dlen = size(B,2);
   blk{3,1}  = 'l'; blk{3,2} = dlen;
   Avec{3,1} = [sparse(dlen,N)    -speye(dlen,dlen)];
   C{3,1} = zeros(dlen,1);
%%
%% add in the constraint:  sum(d) = 1
%%
   blk{4,1}  = 'u'; blk{4,2} = 1;
   Avec{4,1} = sparse([zeros(1,N) ones(1,dlen)]);
   C{4,1} = 1;
%%
   blktmp{1,1} = 's'; blktmp{1,2} = n;
   b = [-svec(blktmp,I); zeros(dlen,1)];
%%**********************************************************


function lambdamax = tvdiplmax(y)
% Calculate the value of lambda so that if lambda >= lambdamax, the TVD
% functional solved by TVDIP is minimized by the trivial constant
% solution x = mean(y). This can then be used to determine a useful range
% of values of lambda, for example.
%
% Usage:
% lambdamax = tvdiplmax(y)
%
% Input arguments:
% - y          Original signal to denoise, size N x 1.
%
% Output arguments:
% - lambdamax  Value of at which x = mean(y) is the output of the TVDIP
%              function.
%
% (c) Max Little, 2010. Based around code originally written by
% S.J. Kim, K. Koh, S. Boyd and D. Gorinevsky. If you use this code for
% your research, please cite:
% M.A. Little, Nick S. Jones (2010)
% "Sparse Bayesian Step-Filtering for High-Throughput Analysis of Molecular
% Machine Dynamics", in 2010 IEEE International Conference on Acoustics,
% Speech and Signal Processing, 2010, ICASSP 2010 Proceedings.
%
% This code is released under the terms of GNU General Public License as
% published by the Free Software Foundation; version 2 or later.

error(nargchk(1,1,nargin));
y = y(:);
N = length(y);
M = N - 1;

% Construct sparse operator matrices
I1 = speye(M,M);
O1 = spalloc(M,1,M);
D = [I1 O1]-[O1 I1];

DDT = D*D';
Dy  = D*y;

lambdamax = max(abs(DDT\Dy));


function [ x, w ] = legendre_ek_compute ( n )

%*****************************************************************************80
%
%% LEGENDRE_EK_COMPUTE: Legendre quadrature rule by the Elhay-Kautsky method.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 April 2011
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by 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.
%
%    Output, real X(N), the abscissas.
%
%    Output, real W(N), the weights.
%

%
%  Define the zero-th moment.
%
  zemu = 2.0;
%
%  Define the Jacobi matrix.
%
  bj = zeros ( n, 1 );

  for i = 1 : n
    bj(i) = ( i * i ) / ( 4 * i * i - 1 );
  end
  bj(1:n) = sqrt ( bj(1:n) );

  x = zeros ( n, 1 );

  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 b = r8ge_ml ( n, a_lu, pivot, x, job )

%*****************************************************************************80
%
%% R8GE_ML computes A * x or A' * x, using R8GE_FA factors.
%
%  Discussion:
%
%    The R8GE storage format is used for a general M by N matrix.  A storage
%    space is made for each logical entry.  The two dimensional logical
%    array is mapped to a vector, in which storage is by columns.
%
%    It is assumed that R8GE_FA has overwritten the original matrix
%    information by LU factors.  R8GE_ML is able to reconstruct the
%    original matrix from the LU factor data.
%
%    R8GE_ML allows the user to check that the solution of a linear
%    system is correct, without having to save an unfactored copy
%    of the matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 March 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%    N must be positive.
%
%    Input, real A_LU(N,N), the LU factors from R8GE_FA.
%
%    Input, integer PIVOT(N), the pivot vector computed by R8GE_FA.
%
%    Input, real X(N), the vector to be multiplied.
%
%    Input, integer JOB, specifies the operation to be done:
%    JOB = 0, compute A * x.
%    JOB nonzero, compute A' * X.
%
%    Output, real B(N), the result of the multiplication.
%
  b(1:n) = x(1:n);

  if ( job == 0 )
%
%  Y = U * X.
%
    for j = 1 : n
      b(1:j-1) = b(1:j-1) + a_lu(1:j-1,j)' * b(j);
      b(j) = a_lu(j,j) * b(j);
    end
%
%  B = PL * Y = PL * U * X = A * x.
%
    for j = n-1 : -1 : 1

      b(j+1:n) = b(j+1:n) - a_lu(j+1:n,j)' * b(j);
      k = pivot(j);

      if ( k ~= j )
        t    = b(k);
        b(k) = b(j);
        b(j) = t;
      end

    end

  else
%
%  Y = (PL)' * X:
%
    for j = 1 : n-1

      k = pivot(j);

      if ( k ~= j )
        t    = b(k);
        b(k) = b(j);
        b(j) = t;
      end

      b(j) = b(j) - sum ( b(j+1:n) * a_lu(j+1:n,j) );

    end
%
%  B = U' * Y = ( PL * U )' * X = A' * X.
%
    for i = n : -1 : 1
      b(i+1:n) = b(i+1:n) + b(i) * a_lu(i,i+1:n);
      b(i) = b(i) * a_lu(i,i);
    end

  end

  return
end


function [z,e]=exactPairMult(xIn,yIn)
%%EXACTPAIRMULT Calculate the product of the floating point double values
%               x and y such that the result z+e (if added with infinite
%               precision) is exactly the product x*y, where z is the
%               floating point product and e is the part of the result that
%               cannot be expressed exactly. This is implemented for x and
%               y being floating point doubles.
%
%INPUTS xIn, yIn Two real arrays of sizes that can be added.
%
%OUTPUTS: z The real product x.*y as limited by floating point precision.
%         e The real error such that if done with inifite precision
%           (z+e)==x*y. This does not necessarily hold when numbers become
%           denormalized.
%
%This function implements Dekker's algorithm, which is given as Mul12 in
%[1]. Note that additional scaling is performed for the instance where
%Dekker's algorithm might result in an overflow. That is when x or y is
%above 2^(1023 (maximum exponent) -53 (mantissa length))=2^970.
%
%The output pair (z,e) can be considered to be a "doublelength" floating
%point number, as defined in [1]. This means that
%abs(e)<=abs(z+e)*2^(-t)/(1+2^(-t)) (considering exact arithmetic), where t
%is the number of bits in the mantissa of the floating point number. Here,
%that is 53.
%
%Note that this assumes that the processor rounding mode has been set to
%round to "nearest," which is the default in Matlab, but which can be
%changed using the function setProcRoundingMode.
%
%EXAMPLE:
%Consider the product
% [z,e]=exactPairMult(1+2^50,1+2^(-15))
%One will get z=1.125934266580993e+15 and e=3.051757812500000e-05.
%The exact value of the product can be found to be
%1125934266580993.000030517578125
%If one adds z and e exactly, one gets precisely that result.
%
%REFERENCES:
%[1] T. J. Dekker, "A Floating Point Technique for Extending the Available
%    Precision," Numerische Mathematik, vol. 18, no. 3, Jun. 1971, pp.
%    224-242.
%
%November 2018 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(~isa(xIn,'double')||~isa(yIn,'double'))
    error('This function is only implemented for x and y being double floating point values.')
end

if(isempty(xIn)||isempty(yIn))
    %Returning empty matrices if one input is an empty matrix is consistent
    %with what Matlab does when trying to multiply an empty matrix with
    %something.
    z=[];
    e=[];
    return
end

%This is 2^(1023 (maximum exponent) -53)=2^970
maxUnscaled=9.9792015476735990582818635651842e291;
two53=9007199254740992;%2^53;
twom53=1.1102230246251565404236316680908e-16;%2^(-53)

isScalX=isscalar(xIn);
isScalY=isscalar(yIn);

if(xor(isScalX,isScalY))
    %If one is scalar and the other is not.
    if(isScalX)
        dims=size(yIn);
        xIn=repmat(xIn,dims);
    else
        dims=size(xIn);
        yIn=repmat(yIn,dims);
    end
else
    %If neither is scalar or both are scalar, assume that they are the same
    %size.
    dims=size(xIn);
end

z=zeros(dims);
e=zeros(dims);
numEl=numel(z);

for curEl=1:numEl
    x=xIn(curEl);
    y=yIn(curEl);
    if(x>maxUnscaled)
        x=x*twom53;
        invScalFactX=two53;
    else
        invScalFactX=1;
    end

    if(y>maxUnscaled)
        y=y*twom53;
        invScalFactY=two53;
    else
        invScalFactY=1;
    end
    invScalFact=invScalFactX*invScalFactY;

    [zCur,eCur]=exactPairMultPrescaled(x,y);

    z(curEl)=zCur*invScalFact;
    e(curEl)=eCur*invScalFact;
end
end

function [z,e]=exactPairMultPrescaled(x,y)
    %The double mantissa is 53 bits (including the implicit one).
    const=134217729;%This is 2^ceil(53/2)+1=2^27+1

    p=x*const;
    hx=(x-p)+p;
    tx=x-hx;
    p=y*const;
    hy=(y-p)+p;
    ty=y-hy;
    p=hx*hy;
    q=(hx*ty)+(tx*hy);
    z=p+q;
    e=p-z+q+tx*ty;

end

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


function value = problem4 ( x, h, epsilon, o )

%*****************************************************************************80
%
%% PROBLEM4 evaluates problem data for problem 4.
%
%  Discussion:
%
%    case # 4: u_anl  =   x-1/4.......................................x<0.5
%                         x-1/2.......................................x>0.5
%
%              w_anl  =   0...................................x<0.5-epsilon
%                        -2/epsilon^2(-1/4(log(epsilon)-
%                         log(1/2-v)))....................0.5-epsilon<x<0.5
%                         2/epsilon^2( 1/4*(log(v-1/2)-
%                         log(epsilon)))..................0.5<x<0.5+epsilon
%                         0...................................x>0.5+epsilon
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 February 2012
%
%  Parameters:
%
%    Input, real X(:), the evaluation points.
%
%    Input, real H, the discretization parameter.
%
%    Input, real EPSILON, the nonlocalization parameter.
%
%    Input, string O, the option:
%    'U', evaluate the exact solution.
%    'D', evaluate the derivative of the exact solution.
%    'F', evaluate the right hand side.
%    'L', evaluate the lifting function.
%
  if ( o == 'u' )
    value = (x-1/4).*(x<0.5) + (x-1/2).*(x>=0.5);
  elseif ( o == 'd' )
    value = zeros ( size ( x ) );
  elseif ( o == 'f' )
    epsilon2 = epsilon * epsilon;
    value = (x<0.5-epsilon).*0 + ...
            (x>=0.5-epsilon & x<0.5).*(-2)/epsilon2.*(-1/4* (log(epsilon)-log(1/2-x))) + ...
            (x>0.5 & x<0.5+epsilon).*2/epsilon2.*(1/4*(log(x-1/2)-log(epsilon))) + ...
            (x>=0.5+epsilon).*0;
  elseif ( o == 'l' )
    value = (x<=0).*(x-1/4) + ...
            (x>0 & x<=h).* (1/4).*(x./h-1)+ ...
            (x>h & x< 1-h).* 0 * epsilon + ...
            (x>=1-h & x<=1).* (1/2).*(1. + (x-1)./h)  + ...
            (x>1).*(x-1/2);
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, 'PROBLEM4 - Fatal error!\n' );
    fprintf ( 1, '  Unrecognized option O = "%s"\n', o );
    error ( 'PROBLEM4 - Fatal error!\n' );
  end

  return
end


function spline_test17 ( )

%*****************************************************************************80
%
%% TEST17 tests SPLINE_CUBIC_SET, SPLINE_CUBIC_VAL.
%
%  Discussion:
%
%    For boundary condition 0, the spline should come very close within
%    the interpolation interval.
%
%    For conditions 1 and 2, the spline should be essentially exactly equal
%    to the data, inside and outside the interpolation interval.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 February 2009
%
%  Author
%
%    John Burkardt
%
  n = 11;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST17\n' );
  fprintf ( 1, '  SPLINE_CUBIC_SET sets up a cubic spline;\n' );
  fprintf ( 1, '  SPLINE_CUBIC_VAL evaluates it.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Cubic data, unevenly spaced knots.\n' );

  for i = 1 : n
    t(i) = ( ( i - 1 ) / ( n - 1 ) )^2;
  end

  for i = 1 : n
    y(i) =  fcube ( t(i) );
  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  The data to be interpolated:\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Number of data values = %d\n', n );
  fprintf ( 1, '\n' );
  fprintf ( 1, '       T             Y\n' );
  fprintf ( 1, '\n' );

  for i = 1 : n
    fprintf ( 1, '%14f  %14f\n', t(i), y(i) );
  end
%
%  Try boundary condition types 0, 1 and 2.
%
  for k = 0 : 2

    if ( k == 0 )

      ibcbeg = 0;
      ybcbeg = 0.0E+00;

      ibcend = 0;
      ybcend = 0.0E+00;

      fprintf ( 1, '\n' );
      fprintf ( 1, '  Boundary condition 0 at both ends:\n' );
      fprintf ( 1, '  Spline is quadratic in boundary intervals.\n' );

    elseif ( k == 1 )

      ibcbeg = 1;
      ybcbeg = fpcube ( t(1) );

      ibcend = 1;
      ybcend = fpcube ( t(n) );

      fprintf ( 1, '\n' );
      fprintf ( 1, '  Boundary condition 1 at both ends:\n' );
      fprintf ( 1, '  Y''(left) =  %f\n', ybcbeg );
      fprintf ( 1, '  Y''(right) = %f\n', ybcend );

    elseif ( k == 2 )

      ibcbeg = 2;
      ybcbeg = fppcube ( t(1) );

      ibcend = 2;
      ybcend = fppcube ( t(n) );

      fprintf ( 1, '\n' );
      fprintf ( 1, '  Boundary condition 2 at both ends:\n' );
      fprintf ( 1, '  YP"(left) =  %f\n', ybcbeg );
      fprintf ( 1, '  YP"(right) = %f\n', ybcend );

    end

    ypp = spline_cubic_set ( n, t, y, ibcbeg, ybcbeg, ibcend, ybcend );

    fprintf ( 1, '\n' );
    fprintf ( 1, '  SPLINE"(T), F"(T):\n' );
    fprintf ( 1, '\n' );
    for i = 1: n
      fprintf ( 1, '%14f  %14f\n', ypp(i), fppcube(t(i)) );
    end

    fprintf ( 1, '\n' );
    fprintf ( 1, '  T, SPLINE(T), F(T)\n' );
    fprintf ( 1, '\n' );

    for i = 0 : n

      if ( i == 0 )
        jhi = 1;
      elseif ( i < n )
        jhi = 2;
      else
        jhi = 2;
      end

      for j = 1 : jhi

        if ( i == 0 )
          tval = t(1) - 1.0E+00;
        elseif ( i < n )
          tval = ( ( jhi - j + 1 ) * t(i)     ...
                 + (       j - 1 ) * t(i+1) ) ...
                 / ( jhi );
        else
          if ( j == 1 )
            tval = t(n);
          else
            tval = t(n) + 1.0E+00;
          end
        end

        [ yval, ypval, yppval ] = spline_cubic_val ( n, t, y, ypp, tval );

        fprintf ( 1, '%14f  %14f  %14f\n', tval, yval, fcube ( tval ) );

      end
    end

  end

  return
end


function [ num1, num2 ] = myconvert( str )
% Function to convert the vector string to numbers
% By Kyriakos Tsourapas
% You may contact me through the Mathworks site
% University of Essex 2002

% CREATE THE NUMBERS FROM THE STRING
sign1    = str(1);
intpart1 = sprintf('%d%d', str(2:3));
decpart1 = sprintf('%d%d%d%d%d%d%d%d%d%d', str(4:13));
sign2    = str(14);
intpart2 = sprintf('%d%d', str(15:16));
decpart2 = sprintf('%d%d%d%d%d%d%d%d%d%d', str(17:26));

% CONVERT THEM TO DECIMAL FROM BINARY
num1 = bin2dec(intpart1) + bin2dec(decpart1)/1000;
num2 = bin2dec(intpart2) + bin2dec(decpart2)/1000;

if sign1 == 1
    num1 = - num1;
end

if sign2 == 1
    num2 = - num2;
end


function fd1d_advection_diffusion_steady ( )

%*****************************************************************************80
%
%% FD1D_ADVECTION_DIFFUSION_STEADY solves steady advection diffusion equation.
%
%  Discussion:
%
%    The steady advection diffusion equation has the form:
%
%      v ux - k * uxx = 0
%
%    where V (the advection velocity) and K (the diffusivity) are positive
%    constants, posed in the region
%
%      a = 0 < x < 1 = b
%
%    with boundary conditions
%
%      u(0) = 0, u(1) = 1.
%
%    The discrete solution is unreliable when dx > 2 * k / v / ( b - a ).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 May 2014
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Charles Hall, Thomas Porsching,
%    Numerical Analysis of Partial Differential Equations,
%    Prentice-Hall, 1990,
%    ISBN: 013626557X,
%    LC: QA374.H29.
%
  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'FD1D_ADVECTION_DIFFUSION_STEADY:\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Solve the 1D steady advection diffusion equation:\n' );
  fprintf ( 1, '    v du/dx - k d2u/dx2 = 0\n' );
  fprintf ( 1, '  with constant, positive velocity V and diffusivity K,\n' );
  fprintf ( 1, '  over the interval:\n' );
  fprintf ( 1, '    0.0 <= x <= 1.0\n' );
  fprintf ( 1, '  with boundary conditions:\n' );
  fprintf ( 1, '    u(0) = 0, u(1) = 1.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Use finite differences:\n' );
  fprintf ( 1, '    d u/dx  = (u(x+dx)-u(x-dx))/2/dx\n' );
  fprintf ( 1, '    d2u/dx2 = (u(x+dx)-2u(x)+u(x-dx))/dx^2\n' );
%
%  Physical constants.
%
  v = 1.0;
  k = 0.05;
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Diffusivity K = %g\n', k );
  fprintf ( 1, '  Constant velocity V = %g\n', v );
%
%  Spatial discretization.
%
  nx = 41;
  a = 0.0;
  b = 1.0;
  dx = ( b - a ) / ( nx - 1 );
  x = ( linspace ( a, b, nx ) )';

  fprintf ( 1, '  Number of nodes NX = %d\n', nx );
  fprintf ( 1, '  DX = %g\n', dx );
  fprintf ( 1, '  Maximum safe DX is %g\n', 2 * k / v / ( b - a ) );
%
%  Set up linear system corresponding to boundary conditions and
%  advection-diffusion equation.
%
  A = sparse ( nx, nx );
  f = zeros ( nx, 1 );

  A(1,1) = 1.0;
  f(1) = 0.0;

  for i = 2 : nx - 1
    A(i,i-1) = - v / dx / 2.0 -       k / dx / dx;
    A(i,i)   =                + 2.0 * k / dx / dx;
    A(i,i+1) = + v / dx / 2.0 -       k / dx / dx;
    f(i) = 0.0;
  end

  A(nx,nx) = 1.0;
  f(nx) = 1.0;
%
%  Solve linear system for U.
%
  u = A \ f;
%
%  The exact solution to the differential equation is known.
%
  r = v * ( b - a ) / k;
  w = ( 1.0 - exp ( r * x ) ) / ( 1.0 - exp ( r ) );
%
%  Plot discrete solution U (dots) and exact solution W (line).
%
  hold on
  plot ( x, w, 'b-', 'LineWidth', 2 );
  plot ( x, u, 'r.', 'LineWidth', 2, 'Markersize', 20 );

  grid on
  xlabel ( '<--X-->', 'Fontsize', 16 );
  ylabel ( '<--U(X)-->', 'Fontsize', 16 );
  title ( 'Solution of Steady Advection-Diffusion Equation', 'Fontsize', 24);
  hold off

  filename = 'fd1d_advection_diffusion_steady.png';
  print ( '-dpng', filename );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Saving plot as "%s".\n', filename );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'FD1D_ADVECTION_DIFFUSION_STEADY\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  return
end
function timestamp ( )

%*****************************************************************************80
%
%% TIMESTAMP prints the current YMDHMS date as a timestamp.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
  t = now;
  c = datevec ( t );
  s = datestr ( c, 0 );
  fprintf ( 1, '%s\n', s );

  return
end


function D=distMat(P1, P2)
%
% Euclidian distances between vectors
% each vector is one row

if nargin == 2
    P1 = double(P1);
    P2 = double(P2);

    X1=repmat(sum(P1.^2,2),[1 size(P2,1)]);
    X2=repmat(sum(P2.^2,2),[1 size(P1,1)]);
    R=P1*P2';
    D=real(sqrt(X1+X2'-2*R));
else
    P1 = double(P1);

    % each vector is one row
    X1=repmat(sum(P1.^2,2),[1 size(P1,1)]);
    R=P1*P1';
    D=X1+X1'-2*R;
    D = real(sqrt(D));
end


function [y,L] = mdwt(x,h,L);
%    [y,L] = mdwt(x,h,L);
%
%    Function computes the discrete wavelet transform y for a 1D or 2D input
%    signal x using the scaling filter h.
%
%    Input:
%	x : finite length 1D or 2D signal (implicitly periodized)
%       h : scaling filter
%       L : number of levels. In the case of a 1D signal, length(x) must be
%           divisible by 2^L; in the case of a 2D signal, the row and the
%           column dimension must be divisible by 2^L. If no argument is
%           specified, a full DWT is returned for maximal possible L.
%
%    Output:
%       y : the wavelet transform of the signal
%           (see example to understand the coefficients)
%       L : number of decomposition levels
%
%    1D Example:
%       x = makesig('LinChirp',8);
%       h = daubcqf(4,'min');
%       L = 2;
%       [y,L] = mdwt(x,h,L)
%
%    1D Example's  output and explanation:
%
%       y = [1.1097 0.8767 0.8204 -0.5201 -0.0339 0.1001 0.2201 -0.1401]
%       L = 2
%
%    The coefficients in output y are arranged as follows
%
%       y(1) and y(2) : Scaling coefficients (lowest frequency)
%       y(3) and y(4) : Band pass wavelet coefficients
%       y(5) to y(8)  : Finest scale wavelet coefficients (highest frequency)
%
%    2D Example:
%
%       load test_image
%       h = daubcqf(4,'min');
%       L = 1;
%       [y,L] = mdwt(test_image,h,L);
%
%    2D Example's  output and explanation:
%
%       The coefficients in y are arranged as follows.
%
%              .------------------.
%              |         |        |
%              |    4    |   2    |
%              |         |        |
%              |   L,L   |   H,L  |
%              |         |        |
%              --------------------
%              |         |        |
%              |    3    |   1    |
%              |         |        |
%              |   L,H   |  H,H   |
%              |         |        |
%              `------------------'
%
%       where
%            1 : High pass vertically and high pass horizontally
%            2 : Low pass vertically and high pass horizontally
%            3 : High pass vertically and low  pass horizontally
%            4 : Low pass vertically and Low pass horizontally
%                (scaling coefficients)
%
%
%
%
%    See also: midwt, mrdwt, mirdwt
%

%File Name: mdwt.m
%Last Modification Date: 08/07/95	15:13:25
%Current Version: mdwt.m	2.4
%File Creation Date: Wed Oct 19 10:51:58 1994
%Author: Markus Lang  <lang@jazz.rice.edu>
%
%Copyright (c) 2000 RICE UNIVERSITY. All rights reserved.
%Created by Markus Lang, Department of ECE, Rice University.
%
%This software is distributed and licensed to you on a non-exclusive
%basis, free-of-charge. Redistribution and use in source and binary forms,
%with or without modification, are permitted provided that the following
%conditions are met:
%
%1. Redistribution of source code must retain the above copyright notice,
%   this list of conditions and the following disclaimer.
%2. Redistribution 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. All advertising materials mentioning features or use of this software
%   must display the following acknowledgment: This product includes
%   software developed by Rice University, Houston, Texas and its contributors.
%4. 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 WILLIAM MARSH RICE UNIVERSITY, HOUSTON, TEXAS,
%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 RICE 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 INTERRUPTIONS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
%WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
%OTHERWISE), PRODUCT LIABILITY, OR OTHERWISE ARISING IN ANY WAY OUT OF THE
%USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%
%For information on commercial licenses, contact Rice University's Office of
%Technology Transfer at techtran@rice.edu or (713) 348-6173
%
%Change History:
%
%Modification #1
%Mon Aug  7 11:42:11 CDT 1995
%Rebecca Hindman <hindman@ece.rice.edu>
%Added L to function line so that it can be displayed as an output
%
%Change History:
%
%Modification #1
%Thu Mar  2 13:07:11 CDT 2000
%Ramesh Neelamani<neelsh@ece.rice.edu>
%Revamped the help file
%


function h = histc2( A, edges, wtMask )
% Multidimensional histogram count with weighted values.
%
% Creates a histogram h of the values in A [n x nd], with edges as
% specified. If nd==1, that is when A is a vector, the resulting histogram
% h is a vector of length nBins, where nBins=length(edges)-1. h(q) contains
% the weighted count of values v in A such that edges(q) <= v < edges(q+1).
% h(nBins) additionally contains the weighted count of values in A such
% that v==edges(nBins+1) -- which is different then how histc treates the
% boundary condition. Finally, h is normalized so that sum(h(:))==1.
%
% It usually makes sense to specify edges explicitly, especially if
% different histograms are going to be compared.  In general, edges must
% have monotonically non-decreasing values.  Also, if the exact bounds are
% unknown then it is convenient to set the first element in edges to -inf
% and the last to inf.  If h = histc2( A, nBins, ...), edges are
% automatically generated and have bins equally spaced between min(A) and
% max(A). That is the edges vector is generated by:
%  edges = linspace( min(A)-eps, max(A)+eps, nBins+1 );
%
% If nd>1, that is when A is a 2d matrix instead of a vector, the created
% histogram is multi-dimensional with dimensions nBins^nd, where each bin
% h(q1,...,qnd) contains the the weighted count of vectors v in A such that
% edges{k}(qk) <= v(k) < edges{k}(qk+1), for k=1,...,nd.  Note that if nd>1
% edges may be a cell vector where each element is a vector of edges or a
% scalar nBins as before.
%
% Each value in A may optionally have an associated weight given by wtMask,
% which should have the same number of elements as A. If not specified, the
% default is wtMask=ones(n,1).
%
% USAGE
%  h = histc2( A, edges, [wtMask] )
%
% INPUTS
%  A           - [n x nd] 2D numeric array
%  edges       - quantization bounds, see above
%  wtMask      - [] length [n] vector of weights
%
% OUTPUTS
%  h           - nd histogram [nBins^nd]
%
% EXAMPLE - 1D histograms
%  A=filterGauss([1000 1000],[],[],0); A=A(:); n=length(A);
%  h1 = histc2( A, 25 );              figure(1); bar(h1);
%  h2 = histc2( A, 25, ones(n,1) );   figure(2); bar(h2);
%  h3 = histc2( A, 25, A );           figure(3); bar(h3);
%
% EXAMPLE - 2D histograms
%  A=filterGauss([1000 1000],[],[],0); A=A(:); n=length(A);
%  h=histc2( [A A], 25 );    figure(1); im(h);  % decreasing along diag
%  h=histc2( [A A], 25, A ); figure(2); im(h);  % constant along diag
%
% See also HISTC, ASSIGNTOBINS, BAR
%
% Piotr's Computer Vision Matlab Toolbox      Version 2.0
% Copyright 2014 Piotr Dollar.  [pdollar-at-gmail.com]
% Licensed under the Simplified BSD License [see external/bsd.txt]

if( nargin<3 ); wtMask=[]; end;
if( ~isa(A,'double') ); A=double(A); end;
if( ~ismatrix(A) ); error('A must be a 2 dim array'); end;
[n,nd] = size(A);
if( ~isempty(wtMask) && n~=numel(wtMask) )
  error( 'wtMask must have n elements (A is nxnd)' ); end

if( nd==1 )
  % if nBins given instead of edges calculate edges
  if(length(edges)==1)
    edges = linspace(min(A)-eps,max(A)+eps,edges+1);
  end

  % create 1d histogram
  if(isempty(wtMask))
    h = histc( A, edges );
    h(end-1) = h(end-1)+h(end);
    h = h(1:end-1); h = h / sum(h);
  else
    h = histc2c( A, wtMask, edges );
    h = h / sum(h);
  end

else
  % if nBins given instead of edges calculate edges per dimension
  if( ~iscell(edges ) )
    edges=repmat({edges},[1 nd]);
  elseif( length(edges)~=nd )
    error( 'Illegal dimensions for edges' );
  end
  for i=1:length( edges );
    if(length(edges{i})==1)
      edges{i}=linspace(min(A(:,i))-eps,max(A(:,i))+eps,edges{i}+1);
    end
  end

  % create multidimensional histogram
  if( isempty(wtMask) ); wtMask=ones(1,n); end;
  h = histc2c( A, wtMask, edges{:} );
  h = h / sum(h(:));
end


function [E,v] = km_kpca(X,m,ktype,kpar)
% KM_KPCA performs kernel principal component analysis (KPCA) on a data set
% X.
% Input:	- X: data matrix in column format (each data point is a row)
%			- m: the number of principal components to return. If m is
%			smaller than 1, it is interpreted as the fraction of the signal
%			energy that is to be contained within the returned principal
%			components.
%			- ktype: string representing kernel type.
%			- kpar: vector containing the kernel parameters.
% Output:	- E: matrix containing the principal components.
%			- v: array containing the eigenvalues.
%			- Xep: projections of Xe on principal directions
% USAGE: [E,v] = km_kpca(X,m,ktype,kpar)
%
% Author: Steven Van Vaerenbergh (steven *at* gtas.dicom.unican.es), 2010.
%
% This file is part of the Kernel Methods Toolbox for MATLAB.
% https://github.com/steven2358/kmbox

n = size(X,1);

K = km_kernel(X,X,ktype,kpar);
[E,V] = eig(K);
v = diag(V);	% eigenvalues
[v,ind] = sort(v,'descend');
v = v(1:m);
E = E(:,ind(1:m));	% principal components
for i=1:m
	E(:,i) = E(:,i)/sqrt(n*v(i));	% normalization
end


function dz = dynamics_3_link(~,z,P)
%DZ = DYNAMICS_3_LINK(T,Z,P)
%
%FUNCTION:  This function computes the dynamics of a 3
%    link pendulum, and is designed to be called from ode45.
%    The model allows for arbitrary mass and inertia for each
%    link, but no friction or actuation
%
%INPUTS:
%    t = time. Dummy input for ode45. Not used.
%    z = [6 X nTime]  matrix of states
%    P = struct of parameters
%OUTPUTS:
%    dz = [6 X nTime]  matrix of state derivatives
%
%NOTES:
%    This file was automatically generated by writeDynamics.m

g  = P.g ; %gravity
m1 = P.m(1); % Link 1 mass
m2 = P.m(2); % Link 2 mass
m3 = P.m(3); % Link 3 mass
l1 = P.l(1); % Link 1 length
l2 = P.l(2); % Link 2 length
l3 = P.l(3); % Link 3 length
I1 = P.I(1); % Link 1 moment of inertia about its center of mass
I2 = P.I(2); % Link 2 moment of inertia about its center of mass
I3 = P.I(3); % Link 3 moment of inertia about its center of mass
d1 = P.d(1); % Link 1 distance between center of mass and parent joint
d2 = P.d(2); % Link 2 distance between center of mass and parent joint
d3 = P.d(3); % Link 3 distance between center of mass and parent joint

nTime = size(z,2);
dz = zeros(size(z));
M = zeros(3,3,nTime);
f = zeros(3,nTime);

th1 = z(1,:);
th2 = z(2,:);
th3 = z(3,:);

dth1 = z(4,:);
dth2 = z(5,:);
dth3 = z(6,:);

dz(1,:) = dth1;
dz(2,:) = dth2;
dz(3,:) = dth3;

M(1,1,:) = - I1 - d1.^2.*m1 - l1.^2.*m2 - l1.^2.*m3;
M(1,2,:) = - d2.*l1.*m2.*cos(th1 - th2) - l1.*l2.*m3.*cos(th1 - th2);
M(1,3,:) = -d3.*l1.*m3.*cos(th1 - th3);
M(2,1,:) = - d2.*l1.*m2.*cos(th1 - th2) - l1.*l2.*m3.*cos(th1 - th2);
M(2,2,:) = - I2 - d2.^2.*m2 - l2.^2.*m3;
M(2,3,:) = -d3.*l2.*m3.*cos(th2 - th3);
M(3,1,:) = -d3.*l1.*m3.*cos(th1 - th3);
M(3,2,:) = -d3.*l2.*m3.*cos(th2 - th3);
M(3,3,:) = - I3 - d3.^2.*m3;

f(1,:) = - d1.*g.*m1.*cos(th1) - g.*l1.*m2.*cos(th1) - g.*l1.*m3.*cos(th1) - d2.*dth2.^2.*l1.*m2.*sin(th1 - th2) - d3.*dth3.^2.*l1.*m3.*sin(th1 - th3) - dth2.^2.*l1.*l2.*m3.*sin(th1 - th2);
f(2,:) = d2.*dth1.^2.*l1.*m2.*sin(th1 - th2) - g.*l2.*m3.*cos(th2) - d2.*g.*m2.*cos(th2) - d3.*dth3.^2.*l2.*m3.*sin(th2 - th3) + dth1.^2.*l1.*l2.*m3.*sin(th1 - th2);
f(3,:) = d3.*dth1.^2.*l1.*m3.*sin(th1 - th3) - d3.*g.*m3.*cos(th3) + d3.*dth2.^2.*l2.*m3.*sin(th2 - th3);

for i=1:nTime
    MM = M(:,:,i);  ff = f(:,i);
    dz(4:6,i) = -MM \ ff;
end

end


function beampattern(N,d,w,steer_angle)
% beampattern(N,d,w,steer_angle)
% where:
% N = NO. OF ELEMENTS
% d = INTER-ELEMENT SPACINGS B/W ELEMENTS
% w = WEIGHTINGS
% steer_angle = STEERING ANGLE FOR BEAM PATTERN
% By: Muhammad Fahad
% 2005-MS-E-EE-38
if nargin < 4, steer_angle = 0; end    % for no steering direction
if nargin < 3, w = 1/N*ones(1,N); end   % for uniform linear arrays
if nargin < 2, d = 1/2; end   % for standard linear array

n = (-(N-1)/2:(N-1)/2).';
theta = pi*(-1:0.001:1);
u = cos(theta);
vv = exp(j*2*pi*d*n*u);
theta_T = steer_angle/180*pi;
ut=cos(theta_T);
W = w.*exp(j*n*pi*cos(theta_T))';
B = W*vv;
B = 10*log10(abs(B).^2);
figure
polardb(theta,B,-40)
return


% This function returns the oblique shock wave angle (beta) for a given
% deflection angle (theta) in degrees and ratio of specific heats (gamma).
% and Mach number M. Specify 0 for the weak oblique shock
% or 1 for the strong shock.
%
% Syntax:
% beta(M,theta,gamma,n)     where n specifies weak or strong shock returned
%
% NOTE: Angles supplied and returned from this function are in DEGREES.
%
% Based on an analytical solution to the theta-beta-Mach relation given in
% the following reference:  Rudd, L., and Lewis, M. J., "Comparison of
% Shock Calculation Methods", AIAA Journal of Aircraft, Vol. 35, No. 4,
% July-August, 1998, pp. 647-649.
%
% By Chris Plumley, undergraduate, University of Maryland.

function Beta=beta(M,theta,gamma,n)

theta=theta*pi/180;             % convert to radians
mu=asin(1/M);                   % Mach wave angle
c=tan(mu)^2;
a=((gamma-1)/2+(gamma+1)*c/2)*tan(theta);
b=((gamma+1)/2+(gamma+3)*c/2)*tan(theta);
d=sqrt(4*(1-3*a*b)^3/((27*a^2*c+9*a*b-2)^2)-1);
Beta=atan((b+9*a*c)/(2*(1-3*a*b))-(d*(27*a^2*c+9*a*b-2))/(6*a*(1-3*a*b))*tan(n*pi/3+1/3*atan(1/d)))*180/pi;


function y = wshift(type,x,p)
%WSHIFT Shift Vector or Matrix.
%   Y = WSHIFT(TYPE,X,P) with TYPE = {1,'1','1d' or '1D'}
%   performs a P-circular shift of vector X.
%   The shift P must be an integer, positive for right to left
%   shift and negative for left to right shift.
%
%   Y = WSHIFT(TYPE,X,P) with TYPE = {2,'2','2d' or '2D'}
%   performs a P-circular shift of matrix X.
%   The shifts P must be integers. P(1) is the shift for rows
%   and P(2) is the shift for columns.
%
%   WSHIFT('1D',X) is equivalent to WSHIFT('1D',X,1)
%   WSHIFT('2D',X) is equivalent to WSHIFT('2D',X,[1 1])
%
%   Example 1D:
%     x = [1 2 3 4 5]
%     wshift('1D',x,1)  = [2 3 4 5 1]
%     wshift('1D',x,-1) = [5 1 2 3 4]
%
%   Example 2D:
%     x = [1 2 3;5 6 7]
%     wshift('2D',x,[1 1])  = [6 7 5;2 3 1]
%     wshift('2D',x,[-1,0]) = [5 6 7;1 2 3]

%   M. Misiti, Y. Misiti, G. Oppenheim, J.M. Poggi 01-Dec-97.
%   Last Revision: 01-May-1998.
%   Copyright (c) 1995-98 by The MathWorks, Inc.
%   $Revision: 1.2 $  $Date: 1998/07/16 14:33:59 $

if isempty(x) | all(p==0) , y = x; return; end
switch type
  case {1,'1','1d','1D'}
    if nargin<3 , p = 1; end
    L = length(x);
    p = rem(p,L);
    if p<0 , p = L+p; end
    y = x([p+1:L,1:p]);

  case {2,'2','2d','2D'}
    if nargin<3 , p = [1 1]; end
    S = size(x);
    p = rem(p,S);
    k = (p<0);
    p(k) = S(k)+p(k);
    y = x([p(1)+1:S(1),1:p(1)],[p(2)+1:S(2),1:p(2)]);
end


function g = std(f, varargin)
%STD   Standard deviation of a CHEBFUN3 along one variable.
%   G = STD(F) returns the standard deviation of F in the x-variable
%   (default). If F is defined on the cuboid [a, b] x [c, d] x [e, g] then
%
%                      b
%                     /
%     G.^2 = 1/(b-a)  | (F(x,y,z) - mean(F, 1))^2 dx
%                     /
%                     a
%
%   The output G is a CHEBFUN2 object over the rectangle [c, d] x [e, g].
%
%   G = STD(F, FLAG, DIM) takes the standard deviation along the x, y, or
%   z directions if DIM = 1, 2, or 3, respectively.  FLAG is ignored and
%   kept in this function so the syntax agrees with the Matlab STD command.
%
% See also CHEBFUN/STD, CHEBFUN2/STD, CHEBFUN2/STD2, CHEBFUN3/STD2 and
% CHEBFUN3/STD3.

% Copyright 2017 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

% Empty check:
if ( isempty(f) )
    g = chebfun2();
    return
end

dom = f.domain;
if ( nargin < 3 )
    dim = 1;   % default to std over the x-variable.
elseif ( nargin == 3 )
    dim = varargin{ 2 };
else
    error( 'CHEBFUN:CHEBFUN3:std:nargin', 'Too many input arguments.' );
end

%   std(X) = sqrt( mean( (X - mean(X) )^2 ) ).
if ( dim == 1 )          % x-variable.
    mx = chebfun3(@(x,y,z) feval(mean(f, 1), y, z), dom);
    g = sqrt(1/(diff(dom(1:2))) * sum((f - mx).^2, 1)) ;

elseif ( dim == 2 )      % y-variable.
    my = chebfun3(@(x,y,z) feval(mean(f, 2), x, z), dom);
    g = sqrt(1/(diff(dom(3:4))) * sum((f - my).^2, 2));

elseif ( dim == 3 )      % z-variable.
    mz = chebfun3(@(x,y,z) feval(mean(f, 3), x, y), dom);
    g = sqrt(1/(diff(dom(5:6))) * sum((f - mz).^2, 3));

else
    error('CHEBFUN:CHEBFUN3:std:dim', ...
        'Third argument should have value 1, 2 or 3.');
end

end