function [s, err_mse, iter_time]=greed_omp_linsolve(x,A,m,varargin)
% greed_omp_linsolve: Orthogonal Matching Pursuit algorithm based on matlab
% linsolve solution. For reference only!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Usage
% [s, err_mse, iter_time]=greed_omp_linsolve(x,P,m,'option_name','option_value')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Input
%   Mandatory:
%               x   Observation vector to be decomposed
%               P   Either:
%                       1) An nxm matrix (n must be dimension of x)
%                       2) A function handle (type "help function_format"
%                          for more information)
%                          Also requires specification of P_trans option.
%                       3) An object handle (type "help object_format" for
%                          more information)
%               m   length of s
%
%   Possible additional options:
%   (specify as many as you want using 'option_name','option_value' pairs)
%   See below for explanation of options:
%__________________________________________________________________________
%   option_name    |     available option_values                | default
%--------------------------------------------------------------------------
%   stopCrit       | M, corr, mse, mse_change                   | M
%   stopTol        | number (see below)                         | n/4
%   P_trans        | function_handle (see below)                |
%   maxIter        | positive integer (see below)               | n
%   verbose        | true, false                                | false
%   start_val      | vector of length m                         | zeros
%
%   Available stopping criteria :
%               M           -   Extracts exactly M = stopTol elements.
%               corr        -   Stops when maximum correlation between
%                               residual and atoms is below stopTol value.
%               mse         -   Stops when mean squared error of residual
%                               is below stopTol value.
%               mse_change  -   Stops when the change in the mean squared
%                               error falls below stopTol value.
%
%   stopTol: Value for stopping criterion.
%
%   P_trans: If P is a function handle, then P_trans has to be specified and
%            must be a function handle.
%
%   maxIter: Maximum number of allowed iterations.
%
%   verbose: Logical value to allow algorithm progress to be displayed.
%
%   start_val: Allows algorithms to start from partial solution.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Outputs
%	 s              Solution vector
%    err_mse        Vector containing mse of approximation error for each
%                   iteration
%    iter_time      Vector containing computation times for each iteration
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Description
%   greed_omp_linsolve performs a greedy signal decomposition.
%   In each iteration a new element is selected depending on the inner
%   product between the current residual and columns in P.
%   The non-zero elements of s are approximated by orthogonally projecting
%   x onto the selected elements in each iteration.
%   The inverse problem is solved using matlabs linsolve command.
%   This is slow and is only provided for reference.
%
% See Also
%   greed_qr, greed_omp_chol, greed_omp_cg, greed_omp_cgp, greed_omp_pinv,
%   greed_gp, greed_nomp
%
% Copyright (c) 2007 Thomas Blumensath
%
% The University of Edinburgh
% Email: thomas.blumensath@ed.ac.uk
% Comments and bug reports welcome
%
% This file is part of sparsity Version 0.1
% Created: April 2007
%
% Part of this toolbox was developed with the support of EPSRC Grant
% D000246/1
%
% Please read COPYRIGHT.m for terms and conditions.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                    Default values and initialisation
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[n1 n2]=size(x);
if n2 == 1
    n=n1;
elseif n1 == 1
    x=x';
    n=n2;
else
   display('x must be a vector.');
   return
end

sigsize     = x'*x/n;
initial_given=0;
err_mse     = [];
iter_time   = [];
STOPCRIT    = 'M';
STOPTOL     = ceil(n/4);
MAXITER     = n;
verbose     = false;
s_initial   = zeros(m,1);
vectnfact   = ones(m,1);

if verbose
   display('Initialising...')
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                           Output variables
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

switch nargout
    case 3
        comp_err=true;
        comp_time=true;
    case 2
        comp_err=true;
        comp_time=false;
    case 1
        comp_err=false;
        comp_time=false;
    case 0
        error('Please assign output variable.')
    otherwise
        error('Too many output arguments specified')
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                       Look through options
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Put option into nice format
Options={};
OS=nargin-3;
c=1;
for i=1:OS
    if isa(varargin{i},'cell')
        CellSize=length(varargin{i});
        ThisCell=varargin{i};
        for j=1:CellSize
            Options{c}=ThisCell{j};
            c=c+1;
        end
    else
        Options{c}=varargin{i};
        c=c+1;
    end
end
OS=length(Options);
if rem(OS,2)
   error('Something is wrong with argument name and argument value pairs.')
end

for i=1:2:OS
   switch Options{i}
        case {'stopCrit'}
            if (strmatch(Options{i+1},{'M'; 'corr'; 'mse'; 'mse_change'},'exact'));
                STOPCRIT    = Options{i+1};
            else error('stopCrit must be char string [M, corr, mse, mse_change]. Exiting.'); end
        case {'stopTol'}
            if isa(Options{i+1},'numeric') ; STOPTOL     = Options{i+1};
            else error('stopTol must be number. Exiting.'); end
        case {'P_trans'}
            if isa(Options{i+1},'function_handle'); Pt = Options{i+1};
            else error('P_trans must be function _handle. Exiting.'); end
        case {'maxIter'}
            if isa(Options{i+1},'numeric'); MAXITER     = Options{i+1};
            else error('maxIter must be a number. Exiting.'); end
        case {'verbose'}
            if isa(Options{i+1},'logical'); verbose     = Options{i+1};
            else error('verbose must be a logical. Exiting.'); end
        case {'vecNormFac'}
            if isa(Options{i+1},'numeric')& length(Options{i+1}) == m , vectnfact = Options{i+1};
            else error('verbose must be a logical. Exiting.'); end
        case {'start_val'}
            if isa(Options{i+1},'numeric') & length(Options{i+1}) == m ;
                s_initial     = Options{i+1};
                initial_given=1;
            else error('start_val must be a vector of length m. Exiting.'); end
        otherwise
            error('Unrecognised option. Exiting.')
   end
end

if strcmp(STOPCRIT,'M')
    maxM=STOPTOL;
else
    maxM=MAXITER;
end

if nargout >=2
    err_mse = zeros(maxM,1);
end
if nargout ==3
    iter_time = zeros(maxM,1);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                        Make P and Pt functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if          isa(A,'float')      P =@(z) A*z;  Pt =@(z) A'*z;
elseif      isobject(A)         P =@(z) A*z;  Pt =@(z) A'*z;
elseif      isa(A,'function_handle')
    try
        if          isa(Pt,'function_handle'); P=A;
        else        error('If P is a function handle, Pt also needs to be a function handle. Exiting.'); end
    catch error('If P is a function handle, Pt needs to be specified. Exiting.'); end
else        error('P is of unsupported type. Use matrix, function_handle or object. Exiting.'); end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                        Do we start from zero or not?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if initial_given ==1;
    IN          = find(s_initial);
    s=zeros(m,1);
    if isa(A,'function_handle') || isobject(A)
         Pmat=zeros(n,length(IN));
         for i=1:length(IN)
             mask=zeros(m,1);
             mask(IN(i))=1;
             Pmat(:,i)=P(mask);
         end
         s(IN)=linsolve(Pmat,x);
     else
         s(IN)=linsolve(A(:,IN),x);
     end
    Residual    = x-P(s);
    oldERR      = Residual'*Residual/n;

else
    IN          = [];
    Residual    = x;
    s           = s_initial;
    sigsize     = x'*x/n;
    oldERR      = sigsize;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                 Random Check to see if dictionary is normalised
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%         mask=zeros(m,1);
%         mask(ceil(rand*m))=1;
%         nP=norm(P(mask));
%         if abs(1-nP)>1e-3;
%             display('Dictionary appears not to have unit norm columns.')
%         end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                        Main algorithm
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if verbose
   display('Main iterations...')
end
tic
t=0;
DR=Pt(Residual).*vectnfact;
done = 0;
iter=1;
while ~done
     DR(IN)=0;
     [v I]=max(abs(DR));
     IN=[IN I];
     if isa(A,'function_handle') || isobject(A)
         Pmat=zeros(n,length(IN));
         for i=1:length(IN)
             mask=zeros(m,1);
             mask(IN(i))=1;
             Pmat(:,i)=P(mask);
         end
         s(IN)=linsolve(Pmat,x);
     else
         s(IN)=linsolve(A(:,IN),x);
     end
     Residual=x-P(s);
     DR=Pt(Residual).*vectnfact;

     ERR=Residual'*Residual/n;
     if comp_err
         err_mse(iter)=ERR;
     end

     if comp_time
         iter_time(iter)=toc;
     end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                        Are we done yet?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     if strcmp(STOPCRIT,'M')
         if iter >= STOPTOL
             done =1;
         elseif verbose && toc-t>10
            display(sprintf('Iteration %i. --- %i iterations to go',iter ,STOPTOL-iter))
            t=toc;
         end
    elseif strcmp(STOPCRIT,'mse')
         if comp_err
            if err_mse(iter)<STOPTOL;
                done = 1;
            elseif verbose && toc-t>10
                display(sprintf('Iteration %i. --- %i mse',iter ,err_mse(iter)))
                t=toc;
            end
         else
             if ERR<STOPTOL;
                done = 1;
             elseif verbose && toc-t>10
                display(sprintf('Iteration %i. --- %i mse',iter ,ERR))
                t=toc;
             end
         end
     elseif strcmp(STOPCRIT,'mse_change') && iter >=2
         if comp_err && iter >=2
              if ((err_mse(iter-1)-err_mse(iter))/sigsize <STOPTOL);
                done = 1;
             elseif verbose && toc-t>10
                display(sprintf('Iteration %i. --- %i mse change',iter ,(err_mse(iter-1)-err_mse(iter))/sigsize ))
                t=toc;
             end
         else
             if ((oldERR - ERR)/sigsize < STOPTOL);
                done = 1;
             elseif verbose && toc-t>10
                display(sprintf('Iteration %i. --- %i mse change',iter ,(oldERR - ERR)/sigsize))
                t=toc;
             end
         end
     elseif strcmp(STOPCRIT,'corr')
          if max(abs(DR)) < STOPTOL;
             done = 1;
          elseif verbose && toc-t>10
                display(sprintf('Iteration %i. --- %i corr',iter ,max(abs(DR))))
                t=toc;
          end
     end

    % Also stop if residual gets too small or maxIter reached
     if comp_err
         if err_mse(iter)<1e-16
             display('Stopping. Exact signal representation found!')
             done=1;
         end
     else

         if iter>1
             if ERR<1e-16
                 display('Stopping. Exact signal representation found!')
                 done=1;
             end
         end
     end

     if iter >= MAXITER
         display('Stopping. Maximum number of iterations reached!')
         done = 1;
     end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                    If not done, take another round
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     if ~done
        iter=iter+1;
        oldERR=ERR;
     end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                  Only return as many elements as iterations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if nargout >=2
    err_mse = err_mse(1:iter);
end
if nargout ==3
    iter_time = iter_time(1:iter);
end

if verbose
   display('Done')
end

% Change history
%
% 8 of Februray: Algo does no longer stop if dictionary is not normaliesd.


classdef SMOP2 < PROBLEM
% <multi/many> <real> <large/none> <expensive/none> <sparse/none>
% Benchmark MOP with sparse Pareto optimal solutions
% theta --- 0.1 --- Sparsity of the Pareto set

%------------------------------- Reference --------------------------------
% Y. Tian, X. Zhang, C. Wang, and Y. Jin, An evolutionary algorithm for
% large-scale sparse multi-objective optimization problems, IEEE
% Transactions on Evolutionary Computation, 2020, 24(2): 380-393.
%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

    properties(Access = private)
        theta = 0.1;    % Sparsity of the Pareto set
    end
    methods
        %% Default settings of the problem
        function Setting(obj)
            obj.theta = obj.ParameterSet(0.1);
            if isempty(obj.M); obj.M = 2; end
            if isempty(obj.D); obj.D = 100; end
            obj.lower    = [zeros(1,obj.M-1)+0,zeros(1,obj.D-obj.M+1)-1];
            obj.upper    = [zeros(1,obj.M-1)+1,zeros(1,obj.D-obj.M+1)+2];
            obj.encoding = ones(1,obj.D);
        end
        %% Calculate objective values
        function PopObj = CalObj(obj,X)
            K = ceil(obj.theta*(obj.D-obj.M+1));
            g = sum(g2(X(:,obj.M:obj.M+K-1),pi/3),2) + sum(g3(X(:,obj.M+K:end),0),2);
            PopObj = repmat(1+g/(obj.D-obj.M+1),1,obj.M).*fliplr(cumprod([ones(size(X,1),1),X(:,1:obj.M-1)],2)).*[ones(size(X,1),1),1-X(:,obj.M-1:-1:1)];
        end
        %% Generate points on the Pareto front
        function R = GetOptimum(obj,N)
            R = UniformPoint(N,obj.M);
        end
        %% Generate the image of Pareto front
        function R = GetPF(obj)
            if obj.M == 2
                R = obj.GetOptimum(100);
            elseif obj.M == 3
                a = linspace(0,1,10)';
                R = {a*a',a*(1-a'),(1-a)*ones(size(a'))};
            else
                R = [];
            end
        end
    end
end

function g = g2(x,t)
    g = 2*(x-t).^2 + sin(2*pi*(x-t)).^2;
end

function g = g3(x,t)
    g = 4-(x-t)-4./exp(100*(x-t).^2);
end


function [S, V, D] = MySVDs(A, R)
[m, n] = size(A);
if 10*m < n
    AAT = A*A';
    [S, V, D] = svd(AAT);
    V = diag(V) .^ 0.5;
    tol = max(size(A)) * eps(max(V));
    R = min([R, sum(V > tol)]);
    V = V(1:R);
    S = S(:,1:R);
    D = A'*S*diag(1./V);
    V = diag(V);
    return;
end
if m > 10*n
    [S, V, D] = MySVD(A');
    mid = D;
    D = S;
    S = mid;
    return;
end
[S,V,D] = svd(A);
S = S(:, 1:R);
V = V(1:R, 1:R);
D = D(:, 1:R);


function A = int_area(X1,Y1,X2,Y2)
% Compute area of intersection:
%
% area = int_area(X1,Y1,X2,Y2)

X1 = double(X1);
Y1 = double(Y1);
X2 = double(X2);
Y2 = double(Y2);

max_res = 100;

min_x = min([X1(:); X2(:)]);
max_x = max([X1(:); X2(:)]);
min_y = min([Y1(:); Y2(:)]);
max_y = max([Y1(:); Y2(:)]);

X1 = X1-min_x;
X2 = X2-min_x;
Y1 = Y1-min_y;
Y2 = Y2-min_y;
max_x = max_x - min_x;
max_y = max_y - min_y;

max_dim = max(max_x,max_y);

ratio = 1;
% $$$   if max_dim > max_res
% $$$     ratio = max_res/max_dim;
% $$$     X1 = X1*ratio;
% $$$     X2 = X2*ratio;
% $$$     Y1 = Y1*ratio;
% $$$     Y2 = Y2*ratio;
% $$$     max_x = round(max_x*ratio);
% $$$     max_y = round(max_y*ratio);
% $$$   end

X1 = X1+1; X2 = X2+1;
Y1 = Y1+1; Y2 = Y2+1;
max_x = ceil(max_x+1);
max_y = ceil(max_y+1);

M1 = poly2mask(X1,Y1,max_y,max_x);
M2 = poly2mask(X2,Y2,max_y,max_x);

A = sum(sum(double(M1&M2)))/ratio;


function [F,sA] = spm_MDP_log_evidence(qA,pA,rA)
% Bayesian model reduction for Dirichlet hyperparameters
% FORMAT [F,sA] = spm_MDP_log_evidence(qA,pA,rA)
%
% qA  - sufficient statistics of posterior of full model
% pA  - sufficient statistics of prior of full model
% rA  - sufficient statistics of prior of reduced model
%
% F   - free energy or (negative) log evidence of reduced model
% sA  - sufficient statistics of reduced posterior
%
% This routine computes the negative log evidence of a reduced model of a
% categorical distribution parameterised in terms of Dirichlet
% hyperparameters (i.e., concentration parameters encoding probabilities).
% It uses Bayesian model reduction to evaluate the evidence for models with
% and without a particular parameter.
%
% It is assumed that all the inputs are column vectors.
%
% A demonstration of the implicit pruning can be found at the end of this
% routine
%__________________________________________________________________________
% Copyright (C) 2005 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_MDP_log_evidence.m 7326 2018-06-06 12:16:40Z karl $

% change in free energy or log model evidence
%--------------------------------------------------------------------------
sA = qA + rA - pA;
F  = spm_betaln(qA) + spm_betaln(rA) - spm_betaln(pA) - spm_betaln(sA);

return

% notes: Illustration of synaptic homoeostasis in terms of Bayesian model
% reduction that considers a competition between two inputs:
%--------------------------------------------------------------------------
x     = linspace(1,32,128);
pA    = [1; 1];
rA    = pA;
rA(2) = 8;
for i = 1:numel(x)
    for j = 1:numel(x)
        qA = [x(i);x(j)];
        F(i,j) = spm_MDP_log_evidence(qA,pA,rA);
    end
end

subplot(2,2,1), imagesc(x,x,F + (F > 0)*4),
title('Free energy landscape','FontSize',16), axis square xy
xlabel('concentration parameter'), ylabel('concentration parameter')
subplot(2,2,2), plot(x,F'),  title('log evidence','FontSize',16)
xlabel('concentration parameter'), ylabel('Log-evidence'), axis square


function w_lcmv = sphLCMV(sphCOV, constraint_dirs, constraints)
%SPHLCMV Get beamforming weights for a LCMV beamformer in the SHD
%
%   Computes the beamweights for a linearly constrained minimum variance
%   (LCMV) beamformer using SH signals.
%
%   Inputs:
%       sphCOV:     (order+1)^2x(order+1)^2 covariance/correlation matrix
%           of SH signals
%       constraint_dirs:    Kx2 [azi elev] directions that the beamformer
%           should achieve the user-specified constraints
%       constraints:        Kx1 constraint values
%
%   Outputs:
%       w_lcmv: (order+1)^2x1 vector of beamforming weights
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% SPHLCMV.M - 5/10/2016
% Archontis Politis, archontis.politis@aalto.fi
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

nSH = size(sphCOV,1);
order = sqrt(nSH)-1;

% steering vectors for distortionless constraints
constraint_dirs2 = [constraint_dirs(:,1) pi/2-constraint_dirs(:,2)]; % from azi-elevation to azi-inclination
Y_lcmv = getSH(order, constraint_dirs2, 'real');

% LCMV weights vector
stVecMtx = Y_lcmv.';
invA_B = sphCOV\stVecMtx;
B_invA_B = stVecMtx' * invA_B;
w_lcmv = (invA_B / B_invA_B) * constraints;

end


clear; clf;
		% Introducerea punctelor definite
t=[0,0.3,0.8,1.1,1.6,2.3]';
y=[0.5,0.82,1.14,1.25,1.35,1.4]';
		% Se reprezinta cu O-uri negre puntele date
plot(t,y,'Ko');
hold on;
        %Generarea matricei coeficientilor sistemului
A=[ones(size(t)),exp(-t),t.*exp(-t)];
        % Rezolvarea sistemului de ecuatii
a=A\y
        % Extragerea coeficientilor functiei de aproximare
a0=a(1); a1=a(2); a2=a(3);
        % Generarea punctelor in care se calculeaza
        % valorile functiei de aproximare
tt=linspace(0,2.5,200);
		% Calcularea valorilor functiei de aproximare
yy=a0+a1.*exp(-tt)+a2.*tt.*exp(-tt);
        % Reprezentarea grafica a functiei de aproximare
plot(tt,yy,'b','LineWidth', 1.5);
        % Personalizarea reprezentarii grafice
grid on;
xlabel('t');
ylabel('y');


function y = daub4_transform ( n, x )

%*****************************************************************************80
%
%% DAUB4_TRANSFORM computes the DAUB4 transform of a vector.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 July 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the dimension of the vector.
%    N must be a power of 2 and at least 4.
%
%    Input, real X(N), the vector to be transformed.
%
%    Output, real Y(N), the transformed vector.
%
  c = [  0.4829629131445341E+00; ...
         0.8365163037378079E+00; ...
         0.2241438680420133E+00; ...
        -0.1294095225512603E+00 ];

  y(1:n,1) = x(1:n);
  z(1:n,1) = 0.0;

  m = n;

  while ( 4 <= m )

    i = 1;

    for j = 1 : 2 : m - 1
      j0 = i4_wrap ( j,     1, m );
      j1 = i4_wrap ( j + 1, 1, m );
      j2 = i4_wrap ( j + 2, 1, m );
      j3 = i4_wrap ( j + 3, 1, m );
      z(i,1)     = c(1) * y(j0) + c(2) * y(j1) + c(3) * y(j2) + c(4) * y(j3);
      z(i+m/2,1) = c(4) * y(j0) - c(3) * y(j1) + c(2) * y(j2) - c(1) * y(j3);
      i = i + 1;
    end

    y(1:m,1) = z(1:m);

    m = floor ( m / 2 );

  end

  return
end


function lattice_rule_test11 ( )

%*****************************************************************************80
%
%% LATTICE_RULE_TEST11 tests MONTE_CARLO;
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 November 2008
%
%  Author:
%
%    John Burkardt
%
  dim_num = 2;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'LATTICE_RULE_TEST11\n' );
  fprintf ( 1, '  MONTE_CARLO applies a Monte Carlo scheme\n' );
  fprintf ( 1, '  to estimate the integral of a function\n' );
  fprintf ( 1, '  over the unit hypercube.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  The spatial dimension DIM_NUM = %d\n', dim_num );

  a(1:dim_num) = 0.0;
  b(1:dim_num) = 1.0;

  exact = e_01_2d ( dim_num, a, b );

  fprintf ( 1, '\n' );
  fprintf ( 1, '         M    EXACT       ESTIMATE  ERROR\n' );
  fprintf ( 1, '\n' );

  for k = 2 : 5

    m = 10^k;

    quad = monte_carlo ( dim_num, m, @f_01_2d );

    error = abs ( exact - quad );

    fprintf ( 1, '  %8d  %10.6f  %10.6f  %10.6e\n', m, exact, quad, error );

  end

  return
end


function ccfi_1_tabulate ( )

%*****************************************************************************80
%
%% CCFI_1_TABULATE tabulates CCFI_1 quadrature rules for the Laguerre integral.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 May 2014
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'CCFI_1_TABULATE\n' );
  fprintf ( 1, '  Tabulate CCFI_1 quadrature rules for the Laguerre integral.\n' );
  fprintf ( 1, '  Density function rho(x) = 1.\n' );
  fprintf ( 1, '  Region: 0 <= x < +oo.\n' );
  fprintf ( 1, '  Exactness: NONE.\n' );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Print the first 5 rules:\n' );
  fprintf ( 1, '   I          X(I)            W(I)\n' );
  fprintf ( 1, '\n' );

  ell = 1.0;

  for n = 1 : 5

    [ x, w ] = ccfi_1 ( n, ell );

    fprintf ( 1, '\n' );
    for i = 1 : n
      fprintf ( 1, '  %2d  %14.6f  %14.6f\n', i, x(i), w(i) );
    end
    fprintf ( 1, ' Sum                  %14.6f\n', sum ( w(1:n) ) );

  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Print the first 5 nested rules:\n' );
  fprintf ( 1, '   I          X(I)            W(I)\n' );
  fprintf ( 1, '\n' );

  ell = 1.0;

  for j = 1 : 5

    n = 2^j - 1;

    [ x, w ] = ccfi_1 ( n, ell );

    fprintf ( 1, '\n' );
    for i = 1 : n
      fprintf ( 1, '  %2d  %14.6f  %14.6f\n', i, x(i), w(i) );
    end
    fprintf ( 1, ' Sum                  %14.6f\n', sum ( w(1:n) ) );

  end

  return
end


%% Toolbox Sparsity - A toolbox for sparse coding and sparse regularization
%
% Copyright (c) 2008 Gabriel Peyre
%

%%
% The toolbox can be downloaded from Matlab Central
% http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=16204&objectType=FILE

%%
% We first includes in the path some additional useful scripts.
path(path, 'toolbox/');

%% Overview
%
% This toolbox implements several algorithms to compute sparse expansion in redundant dictionaries and to solve inverse problems with sparse regularization
% (and also TV regularization).
%

%%
% Sparse expansion of a signal |f| of size |n| in a redundant dictionary |D| (which is a matrix of size |n x p| with |p>n|, or an implicit operator)
% corresponds to the computation of coefficients |x| of size |p| such that |f=D*x| (or approximate equality |norm(y-D*x)<epsilon|). Since many |x| are possible, one
% can assume that |x| is sparse, for instance supposing that it as a small L1 norm |sum(abs(x))|. This can be achieved by Lagrangian optimization
%

%%
% |min_x 1/2*norm(f-D*x)^2 + T*sum(abs(x))|  (1)

%%
% where |T| is increased if |epsilon| is increased.

%%
% Sparse regularization for the resolution of |y=U*f + noise| (where |U| is a rank defficientis equivalent) corresponds to the computation of a solution
% |f| that is sparse in a dictionary |D|, thus being |f=D*x| with small L1 norm. This is performed by solving

%%
% |min_x 1/2*norm(y-U*D*x)^2 + T*sum(abs(x))|   (2)

%%
% And the solution is computed from the optimal coefficients |x| as |f=D*x|.
%
% Problems (1) and (2) are equivalent if one replaces the dictionary |D| of (1) by the transformed dictionary |U*D| in (2). One can thus use the same
% software to solve both (2) and (1).

%%
% TV regularization corresponds to replacing (2) by

%%
% |min_f 1/2*norm(y-U*f)^2 + T*TV(f)|   (3)
%
% where |TV(f)| is the discrete TV norm of the signal/image |f|. Intuitively, this corresponds to assuming that the gradient of |f| is sparse, so (3) is
% quite close to (2) if |D| is chosen a translation invariant Haar wavelet dictionary. But optimizing (3) and (2) necessitate different algorithms.

%%
%
% * To solve (1) or (2) with |epsilon=0| (no noise), which corresponds to the minimum L1 norm solution to |f=D*x| or |y=U*D*x|, this toolbox implements the Douglas-Rachford iterative algorithm.
% * To solve (1) or (2), this toolbox implements the iterative soft thresholding algorithm. If |T| is not known but |epsilon| is known, then the implementation automatically computes the correct |T| during the iterations.
% * To solve (3), this toolbox implements Chambolle's JMIV 2002 algorithm. If |T| is not known but |epsilon| is known, then the implementation automatically computes the correct |T| during the iterations.

%% Compressed sensing of exactely sparse signals with Fourier measurements.

%%
% First, we create an |s|-sparse signal with random spikes locations and
% random coefficients values.

% dimensionality
n = 1024;
% sparsity
s = 25;
% generate random spikes
x0 = compute_rand_sparse(n, s, 'uniform');

%%
% We select an operator |U|, which is a pre-defined implicit operator.
% This is done by filling in a structure |options| with the correct
% parameters. Many other measurement matrices are available for Compressive
% Sensing (Gaussian, Bernouilli, Fourier, Sinus, Hadamard, etc).

% number of measurements
p = 100;
% type of matrix
clear options;
options.cs_type = 'fourier';
options.n = n;
options.p = p;

%%
% We perform the measurements (without noise) by applying the sensing
% operator.

y = callback_sensing_rand(x0, +1, options);

%%
% We can display the signal vector and the measurements

clf;
subplot(2,1,1);
plot_sparse_diracs(x); title('Signal x_0');
subplot(2,1,2);
h = plot(real(y)); axis tight;
set(h, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Measurements y=U*x_0');

%%
% Since there is no noise, the recovery can be performed using
% Douglas-Rachford algorithm. Special thanks to Jalal Fadili for his help
% on this algorithm.

% set to 1 these options if you want cool displays
options.verb = 0;
options.draw_iter = 0;
% parameter of the algorithm
options.niter = 3000;
options.x = zeros(n,1);
[xlun,lun] = perform_douglas_rachford(@callback_sensing_rand, y, options);
xlun = real(xlun);

%%
% We can display the result. This is a case of perfect recovery, |xlun=x0|!
% However, if you increase slightly the value of |s|, then the recovery
% fails ...

clf;
options.title = {'Signal' 'Recovery'};
options.val = .01; % remove small residual
plot_sparse_diracs({x0 xlun}, options);

%%
% We can also display the decrease of the L1 norm of the solution during
% the iterations, to check that the algorithm really does a good job.

clf;
h = plot(lun); axis tight;
set(h, 'LineWidth', 2);
set(gca, 'FontSize', 20);
xlabel('#iteration'); ylabel('L_1 norm |x|_1');

%% Compressed sensing of a noisy sparse signals with Gaussian measurements.

%%
% To be more robust to noise, we need to decrease the number of
% measurements. Also, we are going to use Gaussian real measurements, which
% in fact perform twice less measurements than complex Fourier
% measurements.

% sparsity
s = 20;
% generate random spikes
x0 = compute_rand_sparse(n, s, 'uniform');

%%
% We perform noisy measurements.
% We also select an other kind of matrix, given in explicit form (an array |U|
% of double). This is possible only for small size problems.

% Generate a matrix for sensing
U = randn(p,n);
% noiseless measurements
y = U*x0;
% make some noise
sigma = .06*std(y(:)); % noise level
y = y + sigma*randn(size(y));

%%
% Since there is some noise, we need to use iterative thresholding.
% The regularization parameter is adapted automatically to fit the noise
% level |sigma|.

% amplification is >1 to further sparsify the solution
amplification = 2;
% norm of the noise |epsilon|
options.etgt = amplification * sigma*sqrt(p);
% initial regularization parameter
options.T = 1;
% perform iterative thresholding
options.niter = 4000;
[xlun,err,lun,lambda] = perform_iterative_thresholding( U,y,options);

%%
% We can display the evolution of the threshold |lambda| during the iterations
% and also display the decay of the Lagrangian to see what the algorithm is
% doing.

clf;
subplot(2,1,1);
h = plot(lambda); axis tight;
set(h, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Evolution of \lambda');
subplot(2,1,2);
lagr = .5*err.^2 + lambda(end)*lun;
h = plot(lagr); axis tight;
set(h, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Evolution of |y-U x|^2+\lambda |x|_1');
axis([1 options.niter min(lagr) min(lagr)*1.5]);

%%
% The solution of the L1 minimization is biased, because L1 tends to
% under-estimate the value of the true coefficients (this is very much
% similar to the issue with soft thresholding). To remediate to this
% issue, it is possible to "debiased" the solution by extracting the
% support and then performing an L2 best fit (which is not biased) of the
% measurements. Be aware that this might give bad results if the
% support is baddly estimated.

% remove small amplitude coefficients because they are not very reliable
xdeb = xlun .* (abs(xlun)>.05);
% perform L2 regression
xdeb = perform_debiasing(U,xdeb,y);

%%
% We can display the result. There is no more perfect recovery because of
% the noise, but the solution is close to the original signal.

clf;
options.title = {'Signal' 'Recovery' 'Debiased'};
options.val = .01; % remove small residual
plot_sparse_diracs({x0 xlun xdeb}, options);

%% Tomography inversion of an image with TV regularization.
% We can recover from partial Fourier measurements using TV regularization.
% We add some noise to the measurement, and perform the recovery using
% Chambolle's algorithm for TV regularization.

%%
% First we load the image.

n = 256;
M = load_image('phantom', n);
M = rescale(M,.05,.95);

%%
% Then we load the tomography mask.

nrays = 18; % Candes/Romberg/Tao set up
mask = compute_tomography_mask(n,nrays);
% number of measurements
p = sum(mask(:)==1);
% display
imageplot({M mask}, {'Signal' 'Frequencies'});

%%
% We set up |options| for the tomography operator (sub-sampling of the
% frequencies) and perform measurements.

options.size = size(M);
options.mask = mask;
y = callback_tomography(M,+1,options);
% add some noise
sigma = .01*std(y(:));
y = y + sigma*randn(size(y));

%%
% We can perform L2 pseudo-inversion (zero padding in Fourier) by just applying
% the transpose operator.

M2 = callback_tomography(y,-1,options); M2 = real(M2);
imageplot({M clamp(M2)}, {'Original' 'L2 inversion'});

%%
% We can perform inversion with TV regularization.

% set up parameter for the regularization
options.TVoperator = @callback_tomography;
options.TVrhs = y;
options.etgt = 4*sigma*sqrt(p); % target noise level
options.niter = 300;
options.niter_inner = 30; % iteration for inner loop of Chambolle's algorithm.
options.tol = 1e-4;
options.display = 0; % set to 1 for sexy display
options.verb = 0;
options.tau = 1/8;
% perform the regularization
[Mtv,err,tv,lambda] = perform_tv_denoising(zeros(n),options);

%%
% We can display the results.

clf;
imageplot({M clamp(Mtv)}, {'Original' 'Recovery'});

%%
% We can display the evolution of the regularization
% parameter and the TV energy.

clf;
subplot(2,1,1);
h = plot(lambda); axis tight;
set(h, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Evolution of \lambda');
subplot(2,1,2);
lagr = .5*err.^2 + lambda(end)*tv;
h = plot(lagr); axis tight;
set(h, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Evolution of |y-U x|^2+\lambda |x|_1');
axis([1 options.niter min(lagr) min(lagr)*1.5]);

%% Sparse spikes deconvolution with L1 regularization and Matching Pursuit
% sparse spikes deconvolution corresponds to inverting a band pass filter.
% This is very much used in seismic imaging where the filter is called a
% wavelet. Since the signal (reflecticity of the ground) is composed of
% isolated spikes, one uses L1 minimisation in the diract basis to recover
% the signal. This can also be performed by other sparse optimization
% technics such as greedy matching pursuit. Note that the operator |U| is
% equal to the dictionary |D| in this case, and is composed of translated
% copy of the filter. Since this results in a highly ill posed operator,
% one needs to sub-sample the dictionary a little.

%%
% First we load a filter which is a second derivative of a Gaussian

clear options;
n = 1024;
options.sigma = .02;
h = compute_sparse_spike_filter('dergauss',n,options);
h = h/max(h);

%%
% We can display the filter and its fourier transform (to see how much
% frequencies are removed by the filtering).

hf = real(fft(h)); hf = hf / max(hf);
clf;
subplot(2,1,1);
hh = plot(fftshift(h)); axis tight;
set(hh, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Filter');
subplot(2,1,2);
hh = plot(fftshift(hf)); axis tight;
set(hh, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Fourier Transform');

%%
% Then we build a dictionary of sub-sampled translated copies of |h|.

q = 2; % sub-sampling (distance between wavelets)
p = n/q;
[Y,X] = meshgrid(1:q:n,1:n);
D = h(mod(X-Y,n)+1);

%%
% We can display a sub-set of elements of the dictionary.

clf;
sel = round( linspace(1,p,5) ); sel(end) = [];
hh = plot(D(:,sel)); axis tight;
set(hh, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Translated wavelets');

%%
% Joel Tropp and Jean-Jacques Fuchs have derived in several IEEE Tr. Info.
% Theory papers some powerfull bounds of the recovery of signals with L1
% minimization. This includes the Fuchs (which depends on the sign of the coefficients),
% ERC and WERC (which depend only on the support of the coefficients) criterions.
% We display here these three criterions to see wether a Dirac spikes train
% of spacing |Delta| between two consecutive spikes can be recovered stably
% by both matching
% pursuit and L1 minimization (basis pursuit).
% The dashed vertical lines display the critical spacing as detected by
% these three criterions.

options.display = 1;
options.delta_max = 100;
options.verb = 0;
[minscale,crit,lgd] = compute_minimum_scale(D, options);
set(gca, 'FontSize', 20);
xlabel('\Delta');

%%
% We create a sparse spikes train, with a default in the middle (two close
% spikes). Note that we select the spacing between the spikes slightly below the minimum scale detected
% by ERC<1, which causes sparsity methods to become unstable, and matching pursuit to fail.

options.delta = 23; % regular spacing
options.delta0 = 3; % create default that is not recovered by BP
x = compute_rand_sparse(p, 0, 'seismic', options);

%%
% The signal is the convolution with the filters plus noise.

sigma = .03;
y = D*x + randn(n,1)*sigma;
% display
clf;
subplot(2,1,1);
plot_sparse_diracs(x);
title('Sparse spikes x');
subplot(2,1,2);
hh = plot(y); axis tight;
set(hh, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Signal y=Dx+w');

%%
% We can recover the signal using L1 minimisation plus debiasing.

options.T = 1;
options.niter = 1000;
options.etgt = 5*sigma*sqrt(n); % noise level
options.x = zeros(p,1); % initial solution
[xlun,err,lun,Tlist]  = perform_iterative_thresholding(D,y,options);
% perform debiasins
xlun(abs(xlun)<.08)=0;
xdeb = perform_debiasing(D,xlun,y);
% display
options.title = {'Signal' 'L1' 'Debiased'};
plot_sparse_diracs({x xlun xdeb}, options);

%%
% Another way to solve the problem is using greedy matching pursuit
% procedure. Most of the time, it gives results comparable or a little worse
% than basis pursuit, but it is faster. Here, we are in a critical set up
% where basis pursuit performs better than matching pursuit. The toolbox
% implements basis matching pursuit and its orthogonalized version. Only
% the basic pursuit is implemented with implicit operator, and orthogonalized
% pursuit requires the computation of many pseudo inverse (so it is quite slow).

% parameters for the pursuits
options.tol = 3*norm(w)/norm(y);
options.nbr_max_atoms = 80;
xmp = perform_mp(D,y,options);
xomp = perform_omp(D,y,options);
% display
options.title = {'Signal' 'Matching pursuit' 'Orthogonal Matching Pursuit'};
plot_sparse_diracs({x xmp xomp}, options);

%% Image inpainting with sparse wavelets regularization
% Image inpainting consists in filling missing pixels in an image. Many inpainting
% algorithm rely on a diffusion PDE that try to propagate information from
% the boundary of the missing region. An alternative methods consist in
% treating this problem as an inverse problem. Inpainting indeed
% corresponds to a diagonal operator |U| with 0 and 1 on the diagonal (0
% indicating missing pixels). This can be regularized using iterative
% thresholding. Since there is no noise, we want to use a very low
% threshold. This can be achieved by decaying the threshold during the
% iterations, and corresponds to the Morphological Component Analysis
% strategy of Jean-Luc Starck, Miki Elad and David Donoho.
% See also the homepage of Jalal Fadili for many example of inpainting.

%%
% First we load an image and a mask.

clear options;
n = 128;
M = load_image('lena');
M = rescale( crop(M,n) );
options.rho = .7; % remove 70% of pixels
mask = compute_inpainting_mask('rand',n,options);
options.mask = mask;

%%
% Apply the operator to remove pixels.

y = callback_inpainting(M, +1, options);
imageplot({M y}, {'Image' 'Data to inpaint'});

%%
% First we set up the dictionary: a translation invariant wavelet
% dictionary.

options.Jmin = 4;
options.wavelet_type = 'biorthogonal';
options.wavelet_vm = 3;
options.D = @callback_atrou;

%%
% Then we set up decaying thresholding parameter for the MCA solver.

options.thresh = 'soft';
options.Tmax = .1;
options.Tmin = 0;
options.niter = 200;
options.tau = 1;
options.drawiter = 0;
options.verb = 0;

%%
% Perform the inpainting using sparse wavelet expansion.

% do the resolution
[MW,err,lun,Tlist] = perform_iterative_thresholding(@callback_inpainting, y, options);
% retrieve the image from its coefficients
Mlun = callback_atrou(MW, +1, options);

%%
% Display the result

imageplot({M clamp(Mlun)},{'Original' 'Recovered'});

%% Dictionary Learning
% Instead of using a fixed dictionary |D| to compress or denoise a signal
% with sparse coding (or to solve an inverse problem), it is possible to
% optimize |D| in order to sparsify a set of given exemplar. In practice,
% these exemplar are taken as small patches extracted from tons of natural
% images. As first shown by Olshausen and Field, the optimized atoms then
% ressemble those of an oriented (steerable) wavelet frame.

%%
% The parameter of the dictionary

% size of the patches
w = 12; n = w^2;
% redundancy of the dictionary
redun = 1.5;
% number of atoms
p = round( n*redun );
% overtraining factor
overtraining = 6;
% number of example
m = round( overtraining*p );

%%
% First we load a set of images
Mlist = load_image({'lena' 'barb' 'boat'});

%%
% Then we extract a large set of patches from these images

Y = load_random_patches(Mlist,w,m);

%%
% Parameters for the learning of the dictionary (optimization of the atoms
% using an iterative method).

% number of atoms
options.K = p;
% number of iterations
options.niter_learning = 60;
% solver used for the sparse coding stage
options.sparse_coder = 'omp';
options.sparse_coder = 'mp';
% sparsity targeter for the sparse code
options.nbr_max_atoms = 5;
% initialization method
options.options.init_dico = 'input';

%%
% Perform the learning using an optimization procedure called the MOD
% (Method of Direction) algorithm.

options.learning_method = 'mod';
options.verb = 0;
[D1,X1,E1] = perform_dictionary_learning(Y,options);

%%
% Display the vectors of the dictionary as small images.
% You can notice that the texture of barbara is occupating many atoms !

clf;
options.ndim = 2;
options.normalization = 'clamp';
display_dictionnary(D1, X1, [10 14], options );


function label = DBSCAN(data, eps, minPts)
% label = DBSCAN(data, epsilon, minPts)
%   Main part of DBSCAN (Density-Based Spatial Clustering of Application with
% Noise)clustering algorithm.
% ----
% Args:
%   data: data to be clustered (n * p)
%   eps: distance threshold for finding neighbors
%   minPts: minimum required number of neighbor observations for one core object
% ----
% Returns:
%   label: corresponding class for each observation

% Initialization
core_object = [];
count = 1;
k = 1; % label index
vmask = ones(size(data, 1), 1); % variable used to record whether one observation has been visited (1: not visited, 0: visited)
label = zeros(size(data, 1), 1); % pre-allocate result

% Find core objects
for i = 1:size(data, 1)
    x = data(i, :); % current observation of interests
    [~, neighbors] = Find_Neighbor(data, x, eps);

    % Check if the number of observations in neighbors of x is larger than minPts
    if((size(neighbors,1)-1) >= minPts)

        % Add the index of x to the set of core object
        core_object(count, 1) = i;
        count = count + 1;
    end
end

fprintf('---- DBSCAN finds a total number of %i core objects ----\n', size(core_object, 1));

while(~isempty(core_object))

    % Construct one queue for further use
    queue = [];
    qcount = 1;

    % Update core_object, observations have been visited should be deleted
    tcount = 1;
    list = [];
    for i = 1:size(core_object, 1)
        if(vmask(core_object(i, 1),1) == 0)
            list(tcount ,1) = i;
            tcount = tcount + 1;
        end
    end
    core_object(list,:) = [];

    if(isempty(core_object))
        break;
    end

    % Randomly choose one core object
    index = core_object(randi(size(core_object, 1)), 1);
    queue(qcount, 1) = index; % add the selected core object to the queue
    qcount = qcount + 1;
    vmask(index, 1) = 0; % update vmask
    label(index, 1) = k; % assign result
    core_object(core_object == index, :) = []; % remove the selected core object from the set

    while(~isempty(queue))
        pivot = queue(1, 1);
        queue(1, :) = []; % remove the first element in queue
        qcount = qcount - 1;

        % Find neighbors for current observation of interests
        [tindex, tneighbors] = Find_Neighbor(data, data(pivot, :), eps);
        if(size(tneighbors, 1) >= minPts)
            for i = 1 : size(tindex, 1)
                % If one neighbor has not been visited, add it to the queue
                if(vmask(tindex(i, 1),1) == 1)
                    queue(qcount, 1) = tindex(i, 1);
                    qcount = qcount + 1;
                    vmask(tindex(i, 1),1) = 0; % update vmask
                    label(tindex(i, 1),1) = k; % assign result
                end
            end
        end
    end

    fprintf('---- Finish finding observations for class %i ----\n', k);
    k = k + 1; % next class
end
end

function d = Eculidean_Distance(x1, x2)
% Calculate eculidean distance between x1 and x2.
%
% Args:
%   x1: observation 1
%   x2: observation 2
%
% Returns:
%   d: Eculidean distance between x1 and x2

d = sqrt((x1 - x2) * (x1 - x2)');
end

function [index, neighbors] = Find_Neighbor(data, x, eps)
% Find neighbors for x, where neighbors are defined to be observations in data
% with eculidean distance from x smaller than epsilon.
%
% Args:
%   data: dataset
%   x: current observation of interests
%   eps: pre-defined distance threshold
%
% Returns:
%   index: the index of these neighbors in data
%   neighbors: neighbor set of x

neighbors = []; % pre-allocate neighbor result
count = 1;
for i = 1 : size(data,1)
    d = Eculidean_Distance(data(i,:), x);
    if(d <= eps)
        index(count, 1) = i;
        neighbors(count,:) = data(i,:);
        count = count + 1;
    end
end
end


function x = nco_abscissas ( n )

%*****************************************************************************80
%
%% NCO_ABSCISSAS computes the Newton Cotes Open abscissas.
%
%  Discussion:
%
%    The interval is [ -1, 1 ].
%
%    The abscissas are the equally spaced points between -1 and 1,
%    not including the endpoints.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 July 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the rule.
%
%    Output, real X(N), the abscissas.
%
  for i = 1 : n
    x(i) = ( ( n - i + 1 ) * ( -1.0 )   ...
           + (     i     ) * ( +1.0 ) ) ...
           / ( n     + 1 );
  end

  return
end


% Test: Mesh subdivision using the Loop scheme.
%
% Author: Jesus Mena

% Example: Box
vertices = [10 10 10; -10 10 10; 10 -10 10; -10 -10 10; 10 10 -10; -10 10 -10; 10 -10 -10; -10 -10 -10]';
faces = [1 2 3; 4 3 2; 1 3 5; 7 5 3; 1 5 2; 6 2 5; 8 6 7; 5 7 6; 8 7 4; 3 4 7; 8 4 6; 2 6 4]';

figure(1);
subplot(1,4,1);
plotMesh(vertices, faces);
for i=2:4
 subplot(1,4,i);
 [vertices, faces] = loopSubdivision(vertices, faces);
 plotMesh(vertices, faces);
end

% Example: Tetrahedron
vertices = [10 10 10; -100 10 -10; -100 -10 10; 10 -10 -10]';
faces = [1 2 3; 1 3 4; 1 4 2; 4 3 2]';

figure(2);
subplot(1,4,1);
plotMesh(vertices, faces);
for i=2:4
 subplot(1,4,i);
 [vertices, faces] = loopSubdivision(vertices, faces);
 plotMesh(vertices, faces);
end

% Example: Cylinder
vertices = [0 -5 0; 0 5 0; 10 -5 0; 9.65 -5 2.58; 8.66 -5 5; 7.07 -5 7.07; 5 -5 8.66; 2.58 -5 9.65; 0 -5 10; -2.58 -5 9.65; -5 -5 8.66; -7.07 -5 7.07; -8.66 -5 5; -9.65 -5 2.58; -10 -5 0; -9.65 -5 -2.58; -8.66 -5 -5; -7.07 -5 -7.07; -5 -5 -8.66; -2.58 -5 -9.65; -0 -5 -10; 2.58 -5 -9.65; 5 -5 -8.66; 7.07 -5 -7.07; 8.66 -5 -5; 9.65 -5 -2.58; 10 5 0 ; 9.65 5 2.58; 8.66 5 5; 7.07 5 7.07; 5 5 8.66; 2.58 5 9.65; 0 5 10; -2.58 5 9.65; -5 5 8.66; -7.07 5 7.07; -8.66 5 5; -9.65 5 2.58; -10 5 0; -9.65 5 -2.58; -8.66 5 -5; -7.07 5 -7.07; -5 5 -8.66; -2.58 5 -9.65; -0 5 -10; 2.58 5 -9.65; 5 5 -8.66; 7.07 5 -7.07; 8.66 5 -5; 9.65 5 -2.58]';
faces = [1 3 4; 1 4 5; 1 5 6; 1 6 7; 1 7 8; 1 8 9; 1 9 10; 1 10 11; 1 11 12; 1 12 13; 1 13 14; 1 14 15; 1 15 16; 1 16 17; 1 17 18; 1 18 19; 1 19 20; 1 20 21; 1 21 22; 1 22 23; 1 23 24; 1 24 25; 1 25 26; 1 26 3; 2 28 27; 2 29 28; 2 30 29; 2 31 30; 2 32 31; 2 33 32; 2 34 33; 2 35 34; 2 36 35; 2 37 36; 2 38 37; 2 39 38; 2 40 39; 2 41 40; 2 42 41; 2 43 42; 2 44 43; 2 45 44; 2 46 45; 2 47 46; 2 48 47; 2 49 48; 2 50 49; 2 27 50; 3 27 28; 3 28 4; 4 28 29; 4 29 5; 5 29 30; 5 30 6; 6 30 31; 6 31 7; 7 31 32; 7 32 8; 8 32 33; 8 33 9; 9 33 34; 9 34 10; 10 34 35; 10 35 11; 11 35 36; 11 36 12; 12 36 37; 12 37 13; 13 37 38; 13 38 14; 14 38 39; 14 39 15; 15 39 40; 15 40 16; 16 40 41; 16 41 17; 17 41 42; 17 42 18; 18 42 43; 18 43 19; 19 43 44; 19 44 20; 20 44 45; 20 45 21; 21 45 46; 21 46 22; 22 46 47; 22 47 23; 23 47 48; 23 48 24; 24 48 49; 24 49 25; 25 49 50; 25 50 26; 26 50 27; 26 27 3]';

figure(3);
subplot(1,4,1);
plotMesh(vertices, faces);
for i=2:4
 subplot(1,4,i);
 [vertices, faces] = loopSubdivision(vertices, faces);
 plotMesh(vertices, faces);
end

% Example: Grid
vertices = [-4 -4 0; -2 -4 0; 0 -4 0; 2 -4 0; 4 -4 0; -4 -2 0; -2 -2 0; 0 -2 0; 2 -2 0; 4 -2 0; -4 0 0; -2 0 0; 0 0 0; 2 0 0; 4 0 0; -4 2 0; -2 2 0; 0 2 0; 2 2 0; 4 2 0; -4 4 0; -2 4 0; 0 4 0; 2 4 0; 4 4 0]';
faces = [7 2 1; 1 6 7; 8 3 2; 2 7 8; 9 4 3; 3 8 9; 10 5 4; 4 9 10; 12 7 6; 6 11 12; 13 8 7; 7 12 13; 14 9 8; 8 13 14; 15 10 9; 9 14 15; 17 12 11; 11 16 17; 18 13 12; 12 17 18; 19 14 13; 13 18 19; 20 15 14; 14 19 20; 22 17 16; 16 21 22; 23 18 17; 17 22 23; 24 19 18; 18 23 24; 25 20 19; 19 24 25]';

figure(4);
subplot(1,4,1);
plotMesh(vertices, faces);
for i=2:4
 subplot(1,4,i);
 [vertices, faces] = loopSubdivision(vertices, faces);
 plotMesh(vertices, faces);
end


classdef CEC2020_F2 < PROBLEM
% <single> <real>
% Shifted and rotated Schwefel's function

%------------------------------- Reference --------------------------------
% C .T. Yue, K. V. Price, P. N. Suganthan, J. J. Liang, M. Z. Ali, B. Y.
% Qu, N. H. Awad, and P. P Biswas, Problem definitions and evaluation
% criteria for the CEC 2020 special session and competition on single
% objective bound constrained numerical optimization, Zhengzhou University,
% China and Nanyang Technological University, Singapore, 2019.
%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

    properties
        O;      % Optimal decision vector
        Mat;	% Rotation matrix
    end
    methods
        %% Default settings of the problem
        function Setting(obj)
            CallStack = dbstack('-completenames');
            load(fullfile(fileparts(CallStack(1).file),'CEC2020.mat'),'Data');
            obj.O = Data{2}.o;
            obj.M = 1;
            if isempty(obj.D) || obj.D < 10
                obj.D   = 5;
                obj.Mat = Data{2}.M_5;
            elseif obj.D < 15
                obj.D   = 10;
                obj.Mat = Data{2}.M_10;
            elseif obj.D < 20
                obj.D   = 15;
                obj.Mat = Data{2}.M_15;
            else
                obj.D   = 20;
                obj.Mat = Data{2}.M_20;
            end
            obj.lower    = zeros(1,obj.D) - 100;
            obj.upper    = zeros(1,obj.D) + 100;
            obj.encoding = ones(1,obj.D);
        end
        %% Calculate objective values
        function PopObj = CalObj(obj,PopDec)
            Z = PopDec - repmat(obj.O(1:size(PopDec,2)),size(PopDec,1),1);
            Y = 10*Z*obj.Mat';
            Z = Y + 4.2097e2;
            g         = Z.*sin(sqrt(abs(Z)));
            temp      = 500 - mod(Z(Z>500),500);
            g(Z>500)  = temp.*sin(sqrt(abs(temp))) - (Z(Z>500)-500).^2/10000/obj.D;
            temp      = mod(abs(Z(Z<-500)),500) - 500;
            g(Z<-500) = temp.*sin(sqrt(abs(temp))) - (Z(Z<-500)-500)/10000/obj.D;
            PopObj = 1100 + 418.9829*obj.D - sum(g,2);
        end
    end
end


function[sigma2, cv, mu, sig2inv, cvinv, S, lmu ] = estNoise_mask(I, w, mask, N, zoom);
%
%  Input parameters
%   I     : Input (noisy) image
%   w     : radius of analysis window
%   N     : Number of ellements to be considered (histogram) when
%           estimating sigma2 and cv2
%   zoom  : Conditional flag to improve the estimation of
%           sigma2 and cv2
%
%
%  Output parameters
%
%   sigma2  : estimation of the variance
%   cv2     : estimation of the coeficient of variation (cv2 = sigma^2 / mu^2)
%   mu      : estimation of the mean value
%   sig2inv : estimation of 1/sigma2
%   cvinv   : estimation of 1/cv2
%   S       : estimation of the local sample variance (same size as I)
%   lmu     : estimation of the local sample mean (same size as I)
%

% Based on
%   S. Aja-Fernandez, G. Vegas-Sanchez-Ferrero,
%   M. Martin-Fernandez, C. Alberola-Lopez
%   "Automatic noise estimation in images using local statistics.
%   Additive and multiplicative cases",
%   Image and Vision Computing 27 (2009) 756-770
%
% Legal:
%   estNoise.m is part of the INMD software
%   (http://sites.google.com/a/istec.net/prodrig/Home/sw). INMD is free
%   software, you can redistribute it and/or modify it under the terms of
%   the GNU General Public License (version 2).
%
% Authors
%   Paul Rodriguez    prodrig@pucp.edu.pe

if(nargin < 5)
  zoom = 0;
  if(nargin < 4)
    N = 100;
  end
end

  L=1;
  b = 0.5*( 1 - cos(pi*(0:2*L)/L) );

  [Nrows, Ncols, depth] = size(I);

for d = 1:depth,

  % Local noise estimation
  [S(:,:,d) lmu(:,:,d)] = localnoise_mask(I(:,:,d),w, mask);

  sigma2(d) = estimateMode(S(:,:,d), N, zoom, b, L, w, 0, 1);
  sig2inv(d) = estimateMode(1./S, N, zoom, b, L, w, 1, 1);

  mu(d) = estimateMode(lmu(:,:,d), N, zoom, b, L, w, 0, 1);

  cv(d) = estimateMode(S(:,:,d)./(lmu(:,:,d).*lmu(:,:,d)), N, zoom, b, L, w, 0, 0);
  cvinv(d) = estimateMode((lmu(:,:,d).*lmu(:,:,d))./S(:,:,d), N, zoom, b, L, w, 1, 0);

end

%    sigma2 = estimateMode(S, N, zoom, b, L, w, 0, 1);
%    sig2inv = estimateMode(1./S, N, zoom, b, L, w, 1, 1);
%
%    mu = estimateMode(lmu, N, zoom, b, L, w, 0, 1);
%
%    cv = estimateMode(S./(lmu.*lmu), N, zoom, b, L, w, 0, 0);
%    cvinv = estimateMode((lmu.*lmu)./S, N, zoom, b, L, w, 1, 0);

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

function[sigma2] = estimateMode(S, N, zoom, b, L, w, inv, factor)

v = S(:);

vmin = min(v);
vmax = max(v);
res = (vmax - vmin)/N;

[h bin] = hist(v, N);

if(inv == 1)
  tmp = conv(b, h) / (2*L+1);
  hs = tmp(L:N+L-1);
%    [dummy pos] = max(hs(end:-1:1));
  posvec = findmaxima( hs(end:-1:1) );
  if(length(posvec) >= 1)
    pos = posvec(1);
  else
    [dummy pos] = max(h(end:-1:1));
  end
else
  [dummy pos] = max(h(end:-1:1));
end

if(zoom)

  ind = find( abs( (v - bin(N-pos+1))  ) < 2*res );

  [h bin] = hist(v(ind), N);

  tmp = conv(b, h) / (2*L+1);
  hs = tmp(L:N+L-1);

  maxpos = findmaxima(hs);

  if( length(maxpos) >= 2 )
    sval = bin( maxpos(1) );
  else
    [dummy pos] = max(h(end:-1:1));
    sval = bin(N-pos+1);
  end

else
  sval = bin(N-pos+1);
end

if factor == 1,
  w_size = (2*w + 1)*(2*w + 1);
  sigma2 = (w_size - 3)/(w_size - 1)*sval;
else
  sigma2 = sval;
end

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

function minima = findminima(x)

minima = findmaxima(-x);

function maxima = findmaxima(x)

% Unwrap to vector
x = x(:);
% Identify whether signal is rising or falling
upordown = sign(diff(x));
% Find points where signal is rising before, falling after
maxflags = [upordown(1)<0; diff(upordown)<0; upordown(end)>0];
maxima   = find(maxflags);


function r = reval(zz, zj, fj, wj)
%REVAL   Evaluate rational function in barycentric form.
%   R = REVAL(ZZ, ZJ, FJ, WJ) returns R (vector of floats), the values of the
%   barycentric rational function with support points ZJ, function values FJ,
%   and barycentric weights WJ evaluated at the points ZZ.
%
% See also AAA, MINIMAX, PRZ.

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

zv = zz(:);                             % vectorize zz if necessary
CC = 1./bsxfun(@minus, zv, zj.');       % Cauchy matrix
r = (CC*(wj.*fj))./(CC*wj);             % vector of values

% Deal with input inf: r(inf) = lim r(zz) = sum(w.*f) / sum(w):
r(isinf(zv)) = sum(wj.*fj)./sum(wj);

% Deal with NaN:
ii = find(isnan(r));
for jj = 1:length(ii)
    if ( isnan(zv(ii(jj))) || ~any(zv(ii(jj)) == zj) )
        % r(NaN) = NaN is fine.
        % The second case may happen if r(zv(ii)) = 0/0 at some point.
    else
        % Clean up values NaN = inf/inf at support points.
        % Find the corresponding node and set entry to correct value:
        r(ii(jj)) = fj(zv(ii(jj)) == zj);
    end
end

% Reshape to input format:
r = reshape(r, size(zz));

end % End of REVAL().


function newval=meshremap(fromval,elemid,elembary,toelem,nodeto)
%
% newval=meshremap(fromval,elemid,elembary,toelem,nodeto)
%
% Redistribute nodal values from the source mesh to the target mesh so that
% the sum of each property on each mesh is the same
%
% author: Qianqian Fang (q.fang at neu.edu)
%
% input:
%	 fromval: values defined at the source mesh nodes, the row or column
%	          number must be the same as the source mesh node number, which
%	          is the same as the elemid length
%	 elemid: the IDs of the target mesh element that encloses the nodes of
%            the source mesh nodes; a vector of length of src mesh node
%            count; elemid and elembary can be generated by calling
%
%           [elemid,elembary]=tsearchn(node_target, elem_target, node_src);
%
%           note that the mapping here is inverse to that in meshinterp()
%
%	 elembary: the bary-centric coordinates of each source mesh nodes
%	         within the target mesh elements, sum of each row is 1, expect
%	         3 or 4 columns (or can be N-D)
%    toelem: the element list of the target mesh
%    nodeto: the total number of target mesh nodes
%
%
% output:
%	 newval: a 2D array with rows equal to the target mesh nodes (nodeto),
%            and columns equals to the value numbers defined at each source
%            mesh node
% example:
%
%    [n1,f1,e1]=meshabox([0 0 0],[10 20 5],1); % src mesh
%    [n2,f2,e2]=meshabox([0 0 0],[10 20 5],2); % target mesh
%    [id, ww]=tsearchn(n2,e2,n1);              % project src to target mesh
%    value_src=n1(:,[2 3 1]);             % create dummy values at src mesh
%    newval=meshremap(value_src,id,ww,e2,size(n2,1)); % map to target
%
% -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)
%

if(size(fromval,1)==1)
    fromval=fromval(:);
end

if(size(fromval,2)==length(elemid))
    fromval=fromval.';
end

newval=zeros(nodeto,size(fromval,2));

idx=~isnan(elemid);
fromval=fromval(idx,:);
elembary=elembary(idx,:);
idx=elemid(idx);

nodeval=repmat(fromval,[1,1,size(elembary,2)]).*repmat(permute(elembary,[1,3,2]),[1,size(fromval,2),1]);

for i=1:size(elembary,2)
    [ix,iy]=meshgrid(toelem(idx,i),1:size(fromval,2));
    nval=nodeval(:,:,i).';
    newval=newval + accumarray([ix(:),iy(:)],nval(:), size(newval));
end


function [ a_lu, info ] = r8cbb_fa ( n1, n2, ml, mu, a )

%*****************************************************************************80
%
%% R8CBB_FA factors a R8CBB matrix.
%
%  Discussion:
%
%    Note that in C++ and FORTRAN, we can look at A as an abstract
%    vector, but then look at parts of A as storing a two dimensional
%    array.  MATLAB assigns an inherent dimensionality to a data object,
%    and gets very unhappy when you try to manipulate the data yourself.
%    This means that the MATLAB implementation of this routine requires
%    the use of temporary 2D arrays.
%
%    The R8CBB storage format is for a compressed border banded matrix.
%    Such a matrix has the logical form:
%
%      A1 | A2
%      ---+---
%      A3 | A4
%
%    with A1 a (usually large) N1 by N1 banded matrix, while A2, A3 and A4
%    are dense rectangular matrices of orders N1 by N2, N2 by N1, and N2 by N2,
%    respectively.
%
%    The R8CBB format is the same as the DBB format, except that the banded
%    matrix A1 is stored in compressed band form rather than standard
%    banded form.  In other words, we do not include the extra room
%    set aside for fill in during pivoting.
%
%    A should be defined as a vector.  The user must then store
%    the entries of the four blocks of the matrix into the vector A.
%    Each block is stored by columns.
%
%    A1, the banded portion of the matrix, is stored in
%    the first (ML+MU+1)*N1 entries of A, using the obvious variant
%    of the LINPACK general band format.
%
%    The following formulas should be used to determine how to store
%    the entry corresponding to row I and column J in the original matrix:
%
%    Entries of A1:
%
%      1 <= I <= N1, 1 <= J <= N1, (J-I) <= MU and (I-J) <= ML.
%
%      Store the I, J entry into location
%      (I-J+MU+1)+(J-1)*(ML+MU+1).
%
%    Entries of A2:
%
%      1 <= I <= N1, N1+1 <= J <= N1+N2.
%
%      Store the I, J entry into location
%      (ML+MU+1)*N1+(J-N1-1)*N1+I.
%
%    Entries of A3:
%
%      N1+1 <= I <= N1+N2, 1 <= J <= N1.
%
%      Store the I, J entry into location
%      (ML+MU+1)*N1+N1*N2+(J-1)*N2+(I-N1).
%
%    Entries of A4:
%
%      N1+1 <= I <= N1+N2, N1+1 <= J <= N1+N2
%
%      Store the I, J entry into location
%      (ML+MU+1)*N1+N1*N2+(J-1)*N2+(I-N1).
%      (same formula used for A3).
%
%
%    Once the matrix has been factored by R8CBB_FA, R8CBB_SL may be called
%    to solve linear systems involving the matrix.
%
%    R8CBB_FA uses special non-pivoting versions of LINPACK routines to
%    carry out the factorization.  The special version of the banded
%    LINPACK solver also results in a space saving, since no entries
%    need be set aside for fill in due to pivoting.
%
%    The linear system must be border banded, of the form:
%
%      ( A1 A2 ) (X1) = (B1)
%      ( A3 A4 ) (X2)   (B2)
%
%    where A1 is a (usually big) banded square matrix, A2 and A3 are
%    column and row strips which may be nonzero, and A4 is a dense
%    square matrix.
%
%    The algorithm rewrites the system as:
%
%         X1 + inverse(A1) A2 X2 = inverse(A1) B1
%
%      A3 X1 +             A4 X2 = B2
%
%    and then rewrites the second equation as
%
%      ( A4 - A3 inverse(A1) A2 ) X2 = B2 - A3 inverse(A1) B1
%
%    The algorithm will certainly fail if the matrix A1 is singular,
%    or requires pivoting.  The algorithm will also fail if the A4 matrix,
%    as modified during the process, is singular, or requires pivoting.
%    All these possibilities are in addition to the failure that will
%    if the total matrix A is singular.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    24 March 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N1, N2, the order of the banded and dense blocks.
%    N1 and N2 must be nonnegative, and at least one must be positive.
%
%    Input, integer ML, MU, the lower and upper bandwidths.
%    ML and MU must be nonnegative, and no greater than N1-1.
%
%    Input, real A( (ML+MU+1)*N1 + 2*N1*N2 + N2*N2), the compact
%    border-banded coefficient matrix.
%
%    Output, real A_LU( (ML+MU+1)*N1 + 2*N1*N2 + N2*N2).
%    information describing a partial factorization
%    of the original coefficient matrix.
%
%    Output, integer INFO, singularity flag.
%    0, no singularity detected.
%    nonzero, the factorization failed on the INFO-th step.
%
  nband = (ml+mu+1)*n1;

  a_lu(1:nband+2*n1*n2+n2*n2) = a(1:nband+2*n1*n2+n2*n2);
%
%  Factor the A1 band matrix, overwriting A1 by its factors.
%
  if ( 0 < n1 )

    a1(1:ml+mu+1,1:n1) = r8vec_to_r8cb ( n1, n1, ml, mu, a(1:nband) );

    [ a1_lu, info ] = r8cb_np_fa ( n1, ml, mu, a1 );

    if ( info ~= 0 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'R8CBB_FA - Fatal error!\n' );
      fprintf ( 1, '  R8CB_NP_FA returned INFO = %d\n', info );
      fprintf ( 1, '  Factoring failed for column INFO.\n' );
      fprintf ( 1, '  The band matrix A1 is singular.\n' );
      fprintf ( 1, '  This algorithm cannot continue!\n' );
      error ( 'R8CBB_FA - Fatal error!' );
    end

    a_lu(1:nband) = r8cb_to_r8vec ( n1, n1, ml, mu, a1_lu );

  end

  if ( 0 < n1 & 0 < n2 )
%
%  Set A2 := -inverse(A1) * A2.
%
    job = 0;

    for j = 1 : n2
      b2(1:n1) = -a(nband+(j-1)*n1+1:nband+(j-1)*n1+n1);
      x2 = r8cb_np_sl ( n1, ml, mu, a1_lu, b2, job );
      a_lu(nband+(j-1)*n1+1:nband+(j-1)*n1+n1) = x2(1:n1);
    end
%
%  Set A4 := A4 + A3*A2
%
    for i = 1 : n2
      for j = 1 : n1
        ij = nband + n1*n2 + (j-1)*n2 + i;
        for k = 1 : n2
          ik = nband + 2*n1*n2 + (k-1)*n2 + i;
          jk = nband + (k-1)*n1 + j;
          a_lu(ik) = a_lu(ik) + a_lu(ij) * a_lu(jk);
        end
      end
    end

  end
%
%  Factor A4.
%
  if ( 0 < n2 )

    a4 = r8vec_to_r8ge ( n2, n2, a_lu(nband+2*n1*n2+1:nband+2*n1*n2+n2*n2) );

    [ a4_lu, info ] = r8ge_np_fa ( n2, a4 );

    if ( info ~= 0 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'R8CBB_FA - Fatal error!\n' );
      fprintf ( 1, '  R8GE_NP_FA returned INFO = %d\n',info );
      fprintf ( 1, '  This indicates singularity in column INFO\n' );
      info = n1 + info;
      fprintf ( 1, '  of the A4 submatrix, which is column %d\n', info );
      fprintf ( 1, '  of the full matrix.\n' );
      fprintf ( 1, '\n' );
      fprintf ( 1, '  It is possible that the full matrix is \n' );
      fprintf ( 1, '  nonsingular, but the algorithm R8CBB_FA may\n' );
      fprintf ( 1, '  not be used for this matrix.\n' );
      return
    end

    a_lu(nband+2*n1*n2+1:nband+2*n1*n2+n2*n2) = r8ge_to_r8vec ( n2, n2, a4_lu );

  end

  return
end


function[lat,lon]=uv2latlon(varargin)
%UV2LATLON  Integrates horizontal velocity to give latitude and longitude.
%
%   [LAT,LON]=UV2LATLON(NUM,U,V,LATO,LONO) where NUM is the data in DATENUM
%   format, integates velocities U and V from intial location (LATO,LONO)
%   to form a trajectory on the earth described by LAT and LON.
%
%   LATO and LONO are an initial latitude and longitude in degrees,
%   and U and V are eastward and northward velocity components in cm/s.
%
%   NUM, U, and V may be column vectors, in which case LATO and LONO are
%   both scalars.  Alternatively U and V may be matrices with time oriented
%   in rows.  NUM is then either an array of length SIZE(U,1), or a matrix
%   of the same size as U and V, while LATO and LONO are either scalars or
%   arrays of length SIZE(U,2).
%
%   [LAT,LON]=UV2LATLON(NUM,CV,LATO,LONO), where CV is the complex-valued
%   velocity CV=U+SQRT(-1)*V, also works.
%
%   UV2LATLON is inverted by LATLON2UV.
%   ___________________________________________________________________
%
%   Cell array input / output
%
%   UV2LATLON returns cell array output given cell array input.
%
%   That is, if NUM, U, and V, are all cell arrays of length K, containing
%   K different numerical arrays, then the output will also be cell arrays
%   of length K.
%
%   In this case LATO and LONO are either scalars, or arrays of length K.
%   ___________________________________________________________________
%
%   Algorithm
%
%   UV2LATLON works by converting the velocity at the current point into
%   a vector in 3D Cartesian coordinates, using SPHERE2UVW, finding the new
%   location in 3D space, and then converting this back into latitude
%   and longitude using XYZ2LATLON, and then interating for the next point.
%
%   By default, UV2LATLON uses a forward integration from an initial point.
%   This inverts LATLON2UV(...,'forward') to a high degree of precision for
%   typical drifter and float velocity values and sampling intervals.
%
%   UV2LATLON(NUM,CV,LATF,LONF,'backward') instead uses a *backward*
%   integration, and LATF and LONF are now the *final* points rather than
%   the initial points.  This inverts LATLON2UV(...,'backward').
%   ___________________________________________________________________
%
%   See also XY2LATLON, LATLON2XY, LATLON2UV.
%
%   'uv2latlon --t' runs a test.
%
%   Usage: [lat,lon]=uv2latlon(num,u,v,lato,lono);
%   __________________________________________________________________
%   This is part of JLAB --- type 'help jlab' for more information
%   (C) 2014 J.M. Lilly --- type 'help jlab_license' for details

if strcmpi(varargin{1}, '--t')
    uv2latlon_test,return
end

if ischar(varargin{end})
    str=varargin{end};
    varargin=varargin(1:end-1);
else
    str='forward';
end

na=length(varargin);
num=varargin{1};
if na==4
    if iscell(varargin{2})
        u=cellreal(varargin{2});
        v=cellimag(varargin{2});
    else
        u=real(varargin{2});
        v=imag(varargin{2});
    end
    varargin=varargin(3:end);
else
    u=varargin{2};
    v=varargin{3};
    varargin=varargin(4:end);
end
lato=varargin{1};
lono=varargin{2};

if ~iscell(num)
    if ~aresame(size(num),size(u))
        num=vrep(num(:),size(u,2),2);
    end
    if length(lato)==1
        lato=lato+zeros(size(u(1,:)));
    end
    if length(lono)==1
        lono=lono+zeros(size(u(1,:)));
    end
    %vsize(num,lato,lono,u,v)
    [lat,lon]=uv2latlon_one(num,lato,lono,u,v,str);
else
    if length(lato)==1
        lato=lato+zeros(size(u));
    end
    if length(lono)==1
        lono=lono+zeros(size(u));
    end
    for i=1:length(num)
        [lat{i,1},lon{i,1}]=uv2latlon_one(num{i},lato(i),lono(i),u{i},v{i},str);
    end
end

function[lat,lon]=uv2latlon_one(num,lato,lono,u,v,str)

switch str(1:3)
    case 'for'
        [lat,lon]=uv2latlon_integrator(num,lato,lono,u,v);
    case 'bac'
        [lat,lon]=uv2latlon_integrator(num,lato,lono,-flipud(u),-flipud(v));
        lat=flipud(lat);
        lon=flipud(lon);
%     case 'cen'
%         [lat1,lon1]=uv2latlon_integrator(num,lato(1),lono(1),u,v);
%         [lat2,lon2]=uv2latlon_integrator(num,lato(2),lono(2),-flipud(u),-flipud(v));
%         lat2=flipud(lat2);
%         lon2=flipud(lon2);
%         [x1,y1,z1]=latlon2xyz(lat1,lon1);
%         [x2,y2,z2]=latlon2xyz(lat2,lon2);
%         [lat,lon]=xyz2latlon((x1+x2)/2,(y1+y2)/2,(z1+z2)/2);
end

function[lat,lon]=uv2latlon_integrator(num,lato,lono,u,v)

dt=num(2)-num(1);
[xo,yo,zo]=latlon2xyz(lato,lono);
[lat,lon]=vzeros(size(u));
lat(1,:)=lato;
lon(1,:)=lono;

u=u(1:end-1,:);
v=v(1:end-1,:);

% if strcmpi(str(1:3),'for')
%     u=u(1:end-1,:);
%     u=u(1:end-1,:);
% elseif strcmpi(str(1:3),'for')
%     u=u(1:end-1,:);
%     u=u(1:end-1,:);
%
% u=1/2*(u+circshift(u,-1));
% u=u(1:end-1,:);
%
% v=1/2*(v+circshift(v,-1));
% v=v(1:end-1,:);

u=u*(dt*24*3600)/100/1000;%Now it's km
v=v*(dt*24*3600)/100/1000;%Now it's km

%vsize(lat,lon,u,v)
for i=1:size(u,1)
    [dx,dy,dz]=sphere2uvw(lat(i,:),lon(i,:),0,u(i,:),v(i,:));
    xo=xo+dx;
    yo=yo+dy;
    zo=zo+dz;
    [lat(i+1,:),lon(i+1,:)]=xyz2latlon(xo,yo,zo);
end

function[]=uv2latlon_test
load npg2006

use npg2006
vindex(num,lat,lon,1:max(find(~isnan(lat))),1);
cv=latlon2uv(num,lat,lon,'forward');
[lat2,lon2]=uv2latlon(num,cv,lat(1),lon(1),'forward');

bool1=allall(abs(frac(lon-lon2,lon))<5e-6);
bool2=allall(abs(frac(lat-lat2,lat))<5e-6);
reporttest('UV2LATLON inverts LATLON2UV to within 5e-6 for NPG2006 data, forward algorithm',bool1&&bool2)

[lat2,lon2]=uv2latlon([num num],[cv cv],[lat(1) lat(1)],[lon(1) lon(1)],'forward');
bool1=allall(abs(frac([lon lon]-lon2,[lon lon]))<5e-6);
bool2=allall(abs(frac([lat lat]-lat2,[lat lat]))<5e-6);
reporttest('UV2LATLON inverts LATLON2UV to within 5e-6 for NPG2006 data, forward algorithm, matrix input',bool1&&bool2)

use npg2006
vindex(num,lat,lon,1:max(find(~isnan(lat))),1);
cv=latlon2uv(num,lat,lon,'backward');
[lat3,lon3]=uv2latlon(num,cv,lat(end),lon(end),'backward');

bool1=allall(abs(frac(lon-lon3,lon))<5e-6);
bool2=allall(abs(frac(lat-lat3,lat))<5e-6);
reporttest('UV2LATLON inverts LATLON2UV to within 5e-6 for NPG2006 data, backward algorithm',bool1&&bool2)

% use npg2006
% vindex(num,lat,lon,1:max(find(~isnan(lat))),1);
% cv=latlon2uv(num,lat,lon);
% [lat4,lon4]=uv2latlon(num,cv,[lat(1) lat(end)],[lon(1) lon(end)],'central');
%
% bool1=allall(abs(frac(lon-lon4,lon))<5e-6);
% bool2=allall(abs(frac(lat-lat4,lat))<5e-6);
% reporttest('UV2LATLON inverts LATLON2UV to within 5e-6 for NPG2006 data, central algorithm',bool1&&bool2)


function [C, L] = wave_cross_cov(X, Y, LMAX)
%%
%% Compute wavelet cross-correlations for arbitrary lag
%% -----------------------------------------------------------------------
%% Input: X     Matrix containing wavelet coefficients with appropriate
%%              boundary condition
%%        Y     Matrix containing wavelet coefficients with appropriate
%%              boundary condition
%%        LMAX  Maximum lag to compute
%%
%% Output: C  Matrix containing the wavelet cross-correlation (same
%%            number of columns as X and Y)
%%         L  Vector of lags (for plotting)
%%
[I J] = size(X);
L = (-LMAX+1):(LMAX-1);

XYCrossCov = []; C = [];
for j = 1:J
  XNaN = X(~isnan(X(:,j)),j)';
  ZNaN = XNaN;
  YNaN = Y(~isnan(Y(:,j)),j)';
  NX = length(XNaN);
  NXX = min(length(XNaN) - 1, LMAX);
  XNaNVar = mean(XNaN.^2);
  YNaNVar = mean(YNaN.^2);

  LAG1 = []; LAG2 = [];
  for i = 1:NXX
    XYNaN = XNaN .* YNaN;
    ZYNaN = ZNaN .* YNaN;
    LAG1 = [LAG1 sum(XYNaN(~isnan(XYNaN))) / sqrt(XNaNVar * YNaNVar) / NX];
    LAG2 = [LAG2 sum(ZYNaN(~isnan(ZYNaN))) / sqrt(XNaNVar * YNaNVar) / NX];
    XNaN = [XNaN(2:NX) NaN];
    ZNaN = [NaN ZNaN(1:(NX-1))];
  end
  XYCrossCov = [fliplr(LAG2) LAG1(2:LMAX)];
  C = [C XYCrossCov'];
end


function y = daub6_scale ( n, x )

%*****************************************************************************80
%
%% DAUB6_SCALE recursively evaluates the DAUB6 scaling function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    31 July 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the recursion level.
%
%    Input, real X, the point at which the function is to be evaluated.
%
%    Output, real Y, the estimated value of the function.
%
  c = [  0.3326705529500826E+00; ...
         0.8068915093110925E+00; ...
         0.4598775021184915E+00; ...
       - 0.1350110200102545E+00; ...
       - 0.08544127388202666E+00; ...
         0.03522629188570953E+00 ];

  c = c * sqrt ( 2.0 );

  if ( 0 < n )
    y = c(1) * daub6_scale ( n - 1, 2 * x     ) ...
      + c(2) * daub6_scale ( n - 1, 2 * x - 1 ) ...
      + c(3) * daub6_scale ( n - 1, 2 * x - 2 ) ...
      + c(4) * daub6_scale ( n - 1, 2 * x - 3 ) ...
      + c(5) * daub6_scale ( n - 1, 2 * x - 4 ) ...
      + c(6) * daub6_scale ( n - 1, 2 * x - 5 );
  else
    y = ( 0 <= x & x < 1 );
  end

  return
end


function ccvt_reflect ( )

%*****************************************************************************80
%
%% CCVT_REFLECT generates and animates a CVT dataset.
%
%  Discussion:
%
%    This program is meant to be used interactively.  It's also
%    possible to prepare a simple input file beforehand and use it
%    in batch mode.
%
%    The program requests input values from the user:
%
%    * NDIM, the spatial dimension,
%    * N, the number of points to generate,
%    * SEED, a seed to use for random number generation;
%    * INIT, initialize the points:
%      ** file, by reading data from file;
%      ** 'GRID', picking points from a grid;
%      ** 'HALTON', from a Halton sequence;
%      ** 'RAND', using MATLAB's RAND function;
%      ** 'UNIFORM', using a simple uniform RNG;
%    * IT_MAX, the maximum number of iterations;
%    * IT_FIXED, the number of iterative steps to take
%      using a fixed set of sampling points.
%    * SAMPLE, how to conduct the sampling:
%      ** 'GRID', picking points from a grid;
%      ** 'HALTON', from a Halton sequence;
%      ** 'RAND', using MATLAB's RAND function;
%      ** 'UNIFORM', using a simple uniform RNG;
%    * SAMPLE_NUM, the number of sampling points;
%    * BATCH, the number of sampling points to create at one time;
%    * OUTPUT, a file into which the data can be stored.
%
%    To indicate that no further computations are desired, it is
%    enough to input a nonsensical value, such as -1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 December 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Qiang Du, Vance Faber, and Max Gunzburger,
%    Centroidal Voronoi Tessellations: Applications and Algorithms,
%    SIAM Review, Volume 41, 1999, pages 637-676.
%
  DEBUG = 1;

  timestamp ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'CCVT_REFLECT\n' );
  fprintf ( 1,   MATLAB version\n' );
  fprintf ( 1, '  Generate and animate a CVT dataset.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  This program is meant to be used interactively.\n' );
  fprintf ( 1, '  It is also possible to prepare a simple input \n' );
  fprintf ( 1, '  file beforehand and use it in batch mode.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  The program requests input values from the user:\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  * NDIM, the spatial dimension,\n' );
  fprintf ( 1, '  * N, the number of points to generate,\n' );
  fprintf ( 1, '  * SEED, a seed to use for random number generation,\n' );
  fprintf ( 1, '  * INIT, initialize the points:\n' );
  fprintf ( 1, '    ** file, read data from a file;\n' );
  fprintf ( 1, '    ** ''GRID'', by picking points from a grid;\n' );
  fprintf ( 1, '    ** ''HALTON'', from a Halton sequence;\n' );
  fprintf ( 1, '    ** ''RAND'', using MATLAB''s RAND function;\n' );
  fprintf ( 1, '    ** ''UNIFORM'', using a simple uniform RNG;\n' );
  fprintf ( 1, '  * IT_MAX, the maximum number of iterations.\n' );
  fprintf ( 1, '  * IT_FIXED, the number of iterative steps to take\n' );
  fprintf ( 1, '    using a fixed set of sampling points.\n' );
  fprintf ( 1, '  * SAMPLE, how to conduct the sampling.\n' );
  fprintf ( 1, '    ** ''GRID'', by picking points from a grid;\n' );
  fprintf ( 1, '    ** ''HALTON'', from a Halton sequence;\n' );
  fprintf ( 1, '    ** ''RAND'', using MATLAB''s RAND function;\n' );
  fprintf ( 1, '    ** ''UNIFORM'', using a simple uniform RNG;\n' );
  fprintf ( 1, '  * SAMPLE_NUM, the number of sample points;\n' );
  fprintf ( 1, '  * BATCH, the number of sampling points to create at one time;\n' );
  fprintf ( 1, '  * OUTPUT, a file into which the data is stored.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  To indicate that no further computations are \n' );
  fprintf ( 1, '  desired, it is enough to input a nonsensical value, \n' );
  fprintf ( 1, '  such as -1.\n' );

  while ( 1 )

    fprintf ( 1, '  *\n' );
    fprintf ( 1, ' *\n' );
    fprintf ( 1, '*  Ready to generate a new dataset:\n' );
    fprintf ( 1, ' *\n' );
    fprintf ( 1, '  *\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  NDIM is the spatial dimension.\n' );
    fprintf ( 1, '  (Try ''2'' if you have no preference.)\n' );
    fprintf ( 1, '  (Any value less than 1 terminates execution.)\n' );
    ndim = [];
    ndim = input ( '  Enter NDIM:  ' );

    fprintf ( 1, '  NDIM = %12d\n', ndim );

    if ( ndim < 1 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'CCVT_REFLECT\n' );
      fprintf ( 1, '  The input value of NDIM = %12d\n', ndim );
      fprintf ( 1, '  is interpreted as a request for termination.\n' );
      fprintf ( 1, '  Normal end of execution.\n' );
      break
    end

    fprintf ( 1, '\n' );
    fprintf ( 1, '  N is the number of points to generate.\n' );
    fprintf ( 1, '  (Try ''25'' if you have no preference.)\n' );
    fprintf ( 1, '  (Any value less than 1 terminates execution.)\n' );
    n = [];
    n = input ( '  Enter N:  ' );

    fprintf ( 1, '  User input N = %12d\n', n );

    if ( n < 1 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'CCVT_REFLECT\n' );
      fprintf ( 1, '  The input value of N = %12d\n', n );
      fprintf ( 1, '  is interpreted as a request for termination.\n' );
      fprintf ( 1, '  Normal end of execution.\n' );
      break
    end

    fprintf ( 1, '\n' );
    fprintf ( 1, '  NPP is the number of boundary sample points.\n' );
    fprintf ( 1, '  (Try ''1000'' if you have no preference.)\n' );
    fprintf ( 1, '  (Any value less than 1 terminates execution.)\n' );
    npp = [];
    npp = input ( '  Enter NPP:  ' );

    fprintf ( 1, '  User input NPP = %12d\n', npp );

    if ( npp < 1 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'CCVT_REFLECT\n' );
      fprintf ( 1, '  The input value of NPP = %12d\n', npp );
      fprintf ( 1, '  is interpreted as a request for termination.\n' );
      fprintf ( 1, '  Normal end of execution.\n' );
      break
    end

    fprintf ( 1, '\n' );
    fprintf ( 1, '  SEED is a seed for the random number generation.\n' );
    fprintf ( 1, '  (Try ''123456789'' if you have no preference.)\n' );
    fprintf ( 1, '  (Any value less than 0 terminates execution.)\n' );
    seed = [];
    seed = input ( '  Enter SEED:  ' );

    fprintf ( 1, '  User input SEED = %d\n', seed );

    if ( seed < 0 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'CCVT_REFLECT\n' );
      fprintf ( 1, '  The input value of SEED = %12d\n', seed );
      fprintf ( 1, '  is interpreted as a request for termination.\n' );
      fprintf ( 1, '  Normal end of execution.\n' );
      break
    end

    seed_init = seed;

    fprintf ( 1, '\n' );
    fprintf ( 1, '  INIT is the method of initializing the data:\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  file       read data from a file;\n' );
    fprintf ( 1, '  ''GRID''     by picking points from a grid;\n' );
    fprintf ( 1, '  ''HALTON''   from a Halton sequence;\n' );
    fprintf ( 1, '  ''RAND''     using MATLAB''s RAND function;\n' );
    fprintf ( 1, '  ''UNIFORM''  using a simple uniform RNG;\n' );
    fprintf ( 1, ' \n' );
    fprintf ( 1, '  (Try ''RAND'' if you have no preference.)\n' );
    fprintf ( 1, '  (A blank value terminates execution).\n' );
    fprintf ( 1, '  (Be sure to INCLUDE QUOTES around the string!\n' );
    fprintf ( 1, ' \n' );

    init_string = [];
    init_string = input ( '  Enter INIT:  ' );

    fprintf ( 1, '  User input INIT = "%s".\n', init_string );

    if ( s_len_trim ( init_string ) <= 0 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'CCVT_REFLECT\n' );
      fprintf ( 1, '  The input value of INIT \n' );
      fprintf ( 1, '  is interpreted as a request for termination.\n' );
      fprintf ( 1, '  Normal end of execution.\n' );
      break
    end

    if ( s_eqi ( init_string, 'RAND'  ) )
      init = -1;
    elseif ( s_eqi ( init_string, 'RANDOM' ) )
      init_string = 'RAND';
      init = -1;
    elseif ( s_eqi ( init_string, 'UNIFORM' ) )
      init = 0;
    elseif ( s_eqi ( init_string, 'HALTON'  ) )
      init = 1;
    elseif ( s_eqi ( init_string, 'GRID'    ) )
      init = 2;
    elseif ( 0 < s_len_trim ( init_string ) )
      init = 3;
    else
      fprintf ( 1, '\n' );
      fprintf ( 1, 'CCVT_REFLECT\n' );
      fprintf ( 1, '  The input value of INIT \n' );
      fprintf ( 1, '  is interpreted as a request for termination.\n' );
      fprintf ( 1, '  Normal end of execution.\n' );
      break
    end

    fprintf ( 1, '\n' );
    fprintf ( 1, '  IT_MAX is the maximum number of iterations.\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  An iteration carries out the following steps:\n' );
    fprintf ( 1, '  * the Voronoi region associated with each\n' );
    fprintf ( 1, '    generator is estimated by sampling;\n' );
    fprintf ( 1, '  * the centroid of each Voronoi region is estimated.\n' );
    fprintf ( 1, '  * the generator is replaced by the centroid.\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  If "enough" sampling points are used,\n' );
    fprintf ( 1, '  and "enough" iterations are taken, this process\n' );
    fprintf ( 1, '  will converge.\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  (Try ''50'' if you have no preference.)\n' );
    fprintf ( 1, '  (A negative value terminates execution).\n' );
    fprintf ( 1, '\n' );
    it_max = [];
    it_max = input ( '  Enter IT_MAX:  ' );

    fprintf ( 1, '  User input IT_MAX = %12d\n', it_max );

    if ( it_max < 0 )
      fprintf ( 1, ' \n' );
      fprintf ( 1, 'CCVT_REFLECT\n' );
      fprintf ( 1, '  The input value of IT_MAX = %12d\n', it_max );
      fprintf ( 1, '  is interpreted as a request for termination.\n' );
      fprintf ( 1, '  Normal end of execution.\n' );
      break
    end

    fprintf ( 1, '\n' );
    fprintf ( 1, '  IT_FIXED is the number of consecutive iterations\n' );
    fprintf ( 1, '  to take with a fixed set of sample points.\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  Setting IT_FIXED to 1 means a new set of sample\n' );
    fprintf ( 1, '  points is generated on every iterative step;\n' );
    fprintf ( 1, '  Setting IT_FIXED equal to IT_MAX means a single set\n' );
    fprintf ( 1, '  of sample points is used for the entire iteration.\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  Any value between 1 and IT_MAX is reasonable.\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  (Try "%d" if you do not have a preference).\n', it_max );
    fprintf ( 1, '  (A 0 or negative value terminates execution).\n' );
    fprintf ( 1, '\n' );
    it_fixed = [];
    it_fixed = input ( '  Enter IT_FIXED:  ' );

    fprintf ( 1, '  User input IT_FIXED = %12d\n', it_fixed );

    if ( it_max < 0 )
      fprintf ( 1, ' \n' );
      fprintf ( 1, 'CCVT_REFLECT\n' );
      fprintf ( 1, '  The input value of IT_FIXED = %12d\n', it_fixed );
      fprintf ( 1, '  is interpreted as a request for termination.\n' );
      fprintf ( 1, '  Normal end of execution.\n' );
      break
    end

    fprintf ( 1, '\n' );
    fprintf ( 1, '  SAMPLE is the method of sampling the region:\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  ''GRID''     by picking points from a grid;\n' );
    fprintf ( 1, '  ''HALTON''   from a Halton sequence;\n' );
    fprintf ( 1, '  ''RAND''     using MATLAB''s RAND function;\n' );
    fprintf ( 1, '  ''UNIFORM''  using a simple uniform RNG;\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  (Try ''RAND'' if you have no preference.)\n' );
    fprintf ( 1, '  (A blank value terminates execution).\n' );
    fprintf ( 1, '  (Be sure to INCLUDE QUOTES around the string!\n' );
    fprintf ( 1, '\n' );

    sample_string = [];
    sample_string = input ( '  Enter SAMPLE:  ' );

    fprintf ( 1, '  User input SAMPLE = "%s".\n', sample_string );

    if ( s_len_trim ( sample_string ) <= 0 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'CCVT_REFLECT\n' );
      fprintf ( 1, '  The input value of SAMPLE \n' );
      fprintf ( 1, '  is interpreted as a request for termination.\n' );
      fprintf ( 1, '  Normal end of execution.\n' );
      break
    end

    if ( s_eqi ( sample_string, 'RAND'  ) )
      sample = -1;
    elseif ( s_eqi ( sample_string, 'RANDOM' ) )
      sample = -1;
      sample_string = 'RAND';
    elseif ( s_eqi ( sample_string, 'UNIFORM' ) )
      sample = 0;
    elseif ( s_eqi ( sample_string, 'HALTON'  ) )
      sample = 1;
    elseif ( s_eqi ( sample_string, 'GRID'    ) )
      sample = 2;
    else
      fprintf ( 1, '\n' );
      fprintf ( 1, 'CCVT_REFLECT\n' );
      fprintf ( 1, '  The input value of SAMPLE \n' );
      fprintf ( 1, '  is interpreted as a request for termination.\n' );
      fprintf ( 1, '  Normal end of execution.\n' );
      break
    end

    fprintf ( 1, '\n' );
    fprintf ( 1, '  SAMPLE_NUM is the number of sample points.\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  The Voronoi regions will be explored by generating\n' );
    fprintf ( 1, '  SAMPLE_NUM points.  For each sample point, the\n' );
    fprintf ( 1, '  nearest generator is found.  Using more points\n' );
    fprintf ( 1, '  gives a better estimate of these regions.\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  SAMPLE_NUM should be much larger than N, the\n' );
    fprintf ( 1, '  number of generators.\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  (Try ''10000'' if you have no preference.)\n' );
    fprintf ( 1, '  (A zero or negative value terminates execution.)\n' );
    fprintf ( 1, '\n' );

    sample_num = [];
    sample_num = input ( '  Enter SAMPLE_NUM:  ' );

    fprintf ( 1, '  User input SAMPLE_NUM = %12d\n', sample_num );

    if ( sample_num <= 0 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'CCVT_REFLECT\n' );
      fprintf ( 1, '  The input value of SAMPLE_NUM = %12d\n', sample_num );
      fprintf ( 1, '  is interpreted as a request for termination.\n' );
      fprintf ( 1, '  Normal end of execution.\n' );
      break
    end

    fprintf ( 1, '\n' );
    fprintf ( 1, '  BATCH is the number of sample points to create\n' );
    fprintf ( 1, '  at one time\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  BATCH should be between 1 and SAMPLE_NUM.\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  It is FASTER to set BATCH to SAMPLE_NUM;\n' );
    fprintf ( 1, '  setting BATCH to 1 requires the least memory.\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  (Try ''%d'' if you have no preference.)\n', ...
      min ( 1000, sample_num ) );
    fprintf ( 1, '  (A zero or negative value terminates execution.)\n' );
    fprintf ( 1, '\n' );

    batch = [];
    batch = input ( '  Enter BATCH:  ' );

    fprintf ( 1, '  User input BATCH = %12d\n', batch );

    if ( batch <= 0 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'CCVT_REFLECT\n' );
      fprintf ( 1, '  The input value of BATCH = %12d\n', batch );
      fprintf ( 1, '  is interpreted as a request for termination.\n' );
      fprintf ( 1, '  Normal end of execution.\n' );
      break
    end

    fprintf ( 1, '\n' );
    fprintf ( 1, '  MOVIE_NAME is the name of the file in which the movie is stored;\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  (Try ''movie.avi'' if you have no preference.)\n' );
    fprintf ( 1, '  (A blank value terminates execution).\n' );
    fprintf ( 1, '  (Be sure to INCLUDE QUOTES around the string!\n' );
    fprintf ( 1, ' \n' );

    movie_name = [];
    movie_name = input ( '  Enter MOVIE_NAME:  ' );

    fprintf ( 1, '  User input MOVIE_NAME = %s\n', movie_name );
%
%  Initialize some movie information.
%
    if ( file_exist ( movie_name ) )
      file_delete ( movie_name )
    end

    num_frames_per_second = 10;
    aviobj = avifile ( movie_name, 'fps', num_frames_per_second );
%
%  Print the header for output.
%
    if ( DEBUG )
      fprintf ( 1, '\n' );
      fprintf ( 1, '  Step    SEED          L2-Change     Energy\n' );
      fprintf ( 1, '\n' );
    end
%
%  Initialize the generators.
%
    if ( init == 3 )

      r = data_read ( sample_string, ndim, n );

    else

      seed = seed_init;
      initialize = 1;

      [ r, seed ] = cvt_sample ( ndim, n, n, init, initialize, seed );

    end
%
%  If the initialization and sampling steps use the same random number
%  scheme, then the sampling scheme does not have to be initialized.
%
    if ( init == sample )
      initialize = 0;
    else
      initialize = 1;
    end
%
%  Compute the initial energy.
%
    seed_init2 = seed_init;

    [ energy, seed ] = cvt_energy ( ndim, n, batch, sample, initialize, ...
      sample_num, seed, r );

    initialize = 0;

    it_num = 0;

    if ( DEBUG )
      fprintf ( 1, '  %4d  %12d  %14e\n', ...
        it_num, seed_init2, energy );
    end
%
%  Write out the initial points.
%
    cvt_write ( ndim, n, batch, seed_init, seed, init_string, it_max, ...
      it_fixed, it_num, energy, sample_string, sample_num, ...
      r, 'initial.txt' );

    points_eps ( 'initial.eps', ndim, n, r, 'Initial points' );

    while ( it_num < it_max )
%
%  Once every IT_FIXED steps, update the base value of SEED,
%  either to SEED_INIT before the first call to CVT_ITERATE, or to the
%  output value of SEED from the previous call to CVT_ITERATE.
%
%  Otherwise, reset the value of SEED to SEED_BASE.
%
      if ( mod ( it_num, it_fixed ) == 0 )
        seed_base = seed;
      else
        seed = seed_base;
      end

      it_num = it_num + 1;
%
%  Sample the region.
%
      seed_init2 = seed;

      r2(1:ndim,1:n) = 0.0;
      count(1:n) = 0;

      outside = 0;

      [ s, seed ] = cvt_sample ( ndim, sample_num, sample_num, sample, ...
        initialize, seed );

      initialize = 0;
      energy = 0.0;

      for js = 1 : sample_num

        distance = Inf;
        nearest = -1;

        for jr = 1 : n

          dist_sq = 0.0E+00;
          for i = 1 : ndim
            dist_sq = dist_sq + ( r(i,jr) - s(i,js) )^2;
          end

          if ( dist_sq < distance )
            distance = dist_sq;
           nearest = jr;
          end

        end

        s2(1:ndim,1) = 2.0 * r(1:ndim,nearest) - s(1:ndim,js);

        if ( ...
          0.0 <= s2(1,1) & s2(1,1) <= 1.0 & ...
          0.0 <= s2(2,1) & s2(2,1) <= 1.0 )
          r2(1:ndim,nearest) = r2(1:ndim,nearest) + s(1:ndim,js);
          count(nearest) = count(nearest) + 1;
        else
          r2(1:ndim,nearest) = r2(1:ndim,nearest) + r(1:ndim,nearest);
          count(nearest) = count(nearest) + 1;
        end

        energy = energy + sum ( ( r(1:ndim,nearest) - s(1:ndim,js) ).^2 );

      end

      energy = energy / sample_num;

      for j = 1 : n
        r2(1:ndim,j) = r2(1:ndim,j) / count(j);
      end

      r(1:ndim,1:n) = r2(1:ndim,1:n);

      handle = scatter ( r(1,1:n), r(2,1:n), [],'r', 'filled' );
      line ( [ 0.0, 1.0, 1.0, 0.0, 0.0 ], [ 0.0, 0.0, 1.0, 1.0, 0.0 ] );
      axis ( [ -0.05, 1.05, -0.05, 1.05 ] );
      axis square
%
%  Label the axes and the plot.
%
      xlabel ( 'X', 'FontName', 'Helvetica', 'FontWeight', 'bold', ...
        'FontSize', 16 );

      ylabel ( 'Y', 'FontName', 'Helvetica', 'FontWeight', 'bold', ...
        'FontSize', 16, 'Rotation', 0 );

      it_string = sprintf ( 'Step %4d', it_num );

      title ( it_string, 'FontName', 'Helvetica', 'FontWeight', ...
        'bold', 'FontSize', 16 );

      frame = getframe ( gca );
      aviobj = addframe ( aviobj, frame );

      initialize = 0;
      if ( DEBUG )
        fprintf ( 1, '  %4d  %12d  %14e\n', ...
          it_num, seed_init2, energy );
      end

    end

    aviobj = close ( aviobj );
%
%  Write the final data to a file.
%
    cvt_write ( ndim, n, batch, seed_init, seed, init_string, it_max, ...
      it_fixed, it_num, energy, sample_string, sample_num, ...
      r, 'final.txt' );

    points_eps ( 'final.eps', ndim, n, r, 'Final points' );

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Press RETURN to proceed.\n' );

    pause

  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Final value of SEED = %d\n', seed );
  fprintf ( 1, '\n' );
  timestamp ( );

  return
end


function cvx_optval = norm_largest( x, k )

%NORM_LARGEST Sum of the k largest magnitudes of a vector.
%   NORM_LARGEST( X, k ) computes the 'largest-k' norm; that is, it computes
%   the sum of the magnitudes of the k largest elements in X. X must
%   be a vector, and k must be a real scalar.
%
%   Disciplined convex programming information:
%       NORM_LARGEST is convex and nonmonotonic of X, though it is monotonic for
%       positive values of X. So when used in CVX expressions, X must be affine,
%       monomial, or posynomial. k must be a real scalar constant.

error( nargchk( 2, 2, nargin ) );
if ~any( size( x ) ~= 1 ),
    error( 'The first argument must be a vector.' );
elseif ~isnumeric( k ) || ~isreal( k ) || length( k ) ~= 1,
    error( 'Third argument must be a scalar.' );
else
    cvx_optval = sum_largest( abs( x ), k );
end

% Copyright 2010 Michael C. Grant and Stephen P. Boyd.
% See the file COPYING.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


%% Setting of the problem
global s
pde = checkboarddata; % f = (x1^2-1)*(x2^2-1); Kellogg problem
pde.L = 1;
option.theta = 0.3;
option.estType = 'star';
option.maxIt = 25;
option.maxN = 2e4;
option.solver = 'mg';
option.tol = 1e-6;
[node,elem] = squaremesh([-1,1,-1,1],0.5);
bdFlag = setboundary(node,elem,'Dirichlet');

%% s = 0.2
s = 0.2; %#ok<*NASGU>
err1 = afemfracLap(node,elem,pde,bdFlag,option);

%% s = 0.4
s = 0.4;
err2 = afemfracLap(node,elem,pde,bdFlag,option);

%% s = 0.6
s = 0.6;
err3 = afemfracLap(node,elem,pde,bdFlag,option);

%% s = 0.8
s = 0.8;
err4 = afemfracLap(node,elem,pde,bdFlag,option);

%% save data and plot the table
save Kelloggcf err1 err2 err3 err4
load Kelloggcf
figure;
plot_error_table(err1.N,err1.energyError,err2.N,err2.energyError,...
                 err3.N,err3.energyError,err4.N,err4.energyError);
%Save figure
saveas(gcf, 'error_Kellogg_cf', 'pdf')
figure;
plot_error_table(err1.N,err1.eta,err2.N,err2.eta,err3.N,err3.eta,err4.N,err4.eta);
ylabel('Estimator','interpreter','latex', 'FontSize', 22)
saveas(gcf, 'eta_Kellogg_cf', 'pdf')