function element_node = grid_q16_element ( nelemx, nelemy )

%*****************************************************************************80
%
%% GRID_Q16_ELEMENT produces a grid of 16 node quadrilaterals.
%
%  Example:
%
%    Input:
%
%      NELEMX = 2, NELEMY = 2
%
%    Output:
%
%      ELEMENT_NODE =
%         1,  2,  3,  4,  8,  9, 10, 11, 15, 16, 17, 18, 22, 23, 24, 25;
%         4,  5,  6,  7, 11, 12, 13, 14, 18, 19, 20, 21, 25, 26, 27, 28;
%        22, 23, 24, 25, 29, 30, 31, 32, 36, 37, 38, 39, 43, 44, 45, 46;
%        25, 26, 27, 28, 32, 33, 34, 35, 39, 40, 41, 42, 46, 47, 48, 49.
%
%  Grid:
%
%   43-44-45-46-47-48-49
%    |        |        |
%    |        |        |
%   36 37 38 39 40 41 42
%    |        |        |
%    |        |        |
%   29 30 31 32 33 34 35
%    |        |        |
%    | 3      | 4      |
%   22-23-24-25-26-27-28
%    |        |        |
%    |        |        |
%   15 16 17 18 19 20 21
%    |        |        |
%    |        |        |
%    8  9 10 11 12 13 14
%    |        |        |
%    | 1      | 2      |
%    1--2--3--4--5--6--7
%
%  Reference Element Q16:
%
%    |
%    1 13--14--15--16
%    |  |   :   :   |
%    |  |   :   :   |
%    |  9..10..11..12
%    S  |   :   :   |
%    |  |   :   :   |
%    |  5...6...7...8
%    |  |   :   :   |
%    |  |   :   :   |
%    0  1---2---3---4
%    |
%    +--0-----R-----1-->
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 April 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NELEMX, NELEMY, the number of elements along the
%    X and Y directions.  The number of elements generated will be
%    NELEMX * NELEMY.
%
%    Output, integer ELEMENT_NODE(16,NELEMX*NELEMY), the nodes that form
%    each element.
%
  element = 0;

  for j = 1 : nelemy
    for i = 1 : nelemx

      base = ( j - 1 ) * 3 * ( 3 * nelemx + 1 ) + 3 * i - 2;

      element = element + 1;

      element_node( 1,element) = base;
      element_node( 2,element) = base                          + 1;
      element_node( 3,element) = base                          + 2;
      element_node( 4,element) = base                          + 3;
      element_node( 5,element) = base +     ( 3 * nelemx + 1 );
      element_node( 6,element) = base +     ( 3 * nelemx + 1 ) + 1;
      element_node( 7,element) = base +     ( 3 * nelemx + 1 ) + 2;
      element_node( 8,element) = base +     ( 3 * nelemx + 1 ) + 3;
      element_node( 9,element) = base + 2 * ( 3 * nelemx + 1 );
      element_node(10,element) = base + 2 * ( 3 * nelemx + 1 ) + 1;
      element_node(11,element) = base + 2 * ( 3 * nelemx + 1 ) + 2;
      element_node(12,element) = base + 2 * ( 3 * nelemx + 1 ) + 3;
      element_node(13,element) = base + 3 * ( 3 * nelemx + 1 );
      element_node(14,element) = base + 3 * ( 3 * nelemx + 1 ) + 1;
      element_node(15,element) = base + 3 * ( 3 * nelemx + 1 ) + 2;
      element_node(16,element) = base + 3 * ( 3 * nelemx + 1 ) + 3;

    end
  end

  return
end


%% Niblack Image Thresholding
% Sample to compare Niblack thresholding against other algorithms
% (global thresholding and adaptive thresholding) for an image with varying
% illumination.
%
% Sources:
%
% * <https://github.com/opencv/opencv_contrib/blob/3.2.0/modules/ximgproc/samples/niblack_thresholding.cpp>
% * <https://docs.opencv.org/3.2.0/d7/d4d/tutorial_py_thresholding.html>
%

function niblack_thresholding_demo()
    % Input 8-bit grayscale image + Parameters
    % - BS: block size (local neighborhood) [niblack, adaptive]
    % - K : constant multiplied by std dev next subtracted from mean [niblack]
    % - C : constant subtracted from mean [adaptive]
    if ~mexopencv.isOctave() && mexopencv.require('images')
        % image with dark pixels being foreground
        im = which('printedtext.png');
        K = -0.7;
        C = 7;
    elseif true
        % image with dark pixels being foreground
        im = fullfile(mexopencv.root(),'test','sudoku.jpg');
        K = -0.7;
        C = 7;
    elseif ~mexopencv.isOctave() && mexopencv.require('images')
        % image with white pixels being foreground
        im = which('rice.png');
        K = 0.7;
        C = -17;
    end
    assert(~isempty(im) && exist(im, 'file') == 2);
    img = cv.imread(im, 'Grayscale',true);
    BS = min(floor(size(img)/16) * 2 + 1);
    assert(~isempty(img), 'Failed to load image');

    % Preprocess image
    if true
        % no processing
        src = img;
    elseif false
        src = cv.medianBlur(img, 'KSize',3);
    elseif true
        % really effective for global thresholding [otsu]
        src = localNormalization(img, 11, 33);
    else
        % rice image, estimate and subtract non-uniform illumination background
        % (see NonuniformIlluminationExample.mlx example)
        if mexopencv.require('images')
            src = imtophat(img, strel('disk',15));
            src = imadjust(src);
        else
            el = cv.getStructuringElement('Shape','Ellipse', 'KSize',[15 15]*2-1);
            src = cv.morphologyEx(img, 'Tophat', 'Element',el);
            obj = cv.SimpleWB();
            src = obj.balanceWhite(src);
        end
    end

    % Threshold
    opts = {'Type','Binary', 'MaxValue',255};
    bw1 = cv.threshold(src, 'Otsu', opts{:});
    bw2 = cv.adaptiveThreshold(src, 'Method','Mean', ...
        'C',C, 'BlockSize',BS, opts{:});
    bw3 = cv.adaptiveThreshold(src, 'Method','Gaussian', ...
        'C',C, 'BlockSize',BS, opts{:});
    bw4 = cv.niBlackThreshold(src, K, 'Method','Niblack', ...
        'BlockSize',BS, opts{:});
    bw5 = cv.niBlackThreshold(src, -K, 'Method','Sauvola', ...
        'BlockSize',BS, opts{:});
    bw6 = cv.niBlackThreshold(src, -K, 'Method','Wolf', ...
        'BlockSize',BS, opts{:});
    bw7 = cv.niBlackThreshold(src, K, 'Method','Nick', ...
        'BlockSize',BS, opts{:});
    %bw8 = my_niblack(src, K, BS);

    % Results
    subplot(331), imshow(img), title('Source')
    subplot(332), imshow(src), title('Processed')
    subplot(333), imshow(bw1), title('Otsu')
    subplot(334), imshow(bw2), title('Adaptive Mean')
    subplot(335), imshow(bw3), title('Adaptive Gaussian')
    subplot(336), imshow(bw4), title('Niblack')
    subplot(337), imshow(bw5), title('Sauvola')
    subplot(338), imshow(bw6), title('Wolf')
    subplot(339), imshow(bw7), title('Nick')
end

%% Helper function

function out = localNormalization(img, s1, s2)
    %LOCALNORMALIZATION  local normalization to get uniform local mean and variance
    %
    %     out = localNormalization(img)
    %     out = localNormalization(img, s1, s2)
    %
    % The local normalization tends to uniformize the mean and variance of an
    % image around a local neighborhood. This is especially useful for correct
    % non-uniform illumination or shading artifacts.
    %
    % ## Input
    % * __img__ 8-bit input image
    %
    % ## Output
    % * __out__ output image of same size and type.
    %
    % ## Options
    % * __s1__ sigma to estimate the local mean. default 5
    % * __s2__ sigma to estimate the local variance. Often `s2` should be
    %   larger than `s1`. default 15
    %
    % ## References
    % > http://bigwww.epfl.ch/sage/soft/localnormalization/
    %

    % check arguments
    if nargin < 2, s1 = 5; end
    if nargin < 3, s2 = 15; end
    validateattributes(img, {'uint8'}, {});

    % convert to grayscale
    if size(img,3) == 3
        gray = cv.cvtColor(img, 'RGB2GRAY');
    else
        gray = img;
    end

    % convert to floating-point image
    gray = cv.convertTo(gray, 'RType','single', 'Alpha',1.0/255.0);

    % numerator = img - gauss_blur(img)
    blur = cv.GaussianBlur(gray, 'KSize',[0 0], 'SigmaX',s1, 'SigmaY',s1);
    num = gray - blur;

    % denominator = sqrt(gauss_blur(img^2))
    den = sqrt(cv.GaussianBlur(num.^2, 'KSize',[0 0], 'SigmaX',s2, 'SigmaY',s2));

    % output = numerator / denominator
    out = num ./ den;

    % normalize output into [0,1]
    out = cv.normalize(out, 'Alpha',0.0, 'Beta',1.0, 'NormType','MinMax');

    % convert to 8-bit
    out = cv.convertTo(out, 'RType','uint8', 'Alpha',255.0);
end

function bw = my_niblack(img, K, BS)
    %MY_NIBLACK  Manual implementation of Niblack thresholding

    img = im2double(img);
    mu = imboxfilt(img, [BS BS]);
    sd = sqrt(imboxfilt(img.^2, [BS BS]) - mu.^2);
    bw = img > (mu + K*sd);
end


% SYNTAX:
% dod = hmrR_Intensity2OD( intensity )
%
% UI NAME:
% Intensity_to_Delta_OD
%
% DESCRIPTION:
% Converts intensity data to optical density
%
% INPUT:
% intensity - SNIRF data type where the d matrix is intensity
%
% OUTPUT:
% dod - SNIRF data type where the d matrix is change in optical density
%
% USAGE OPTIONS:
% Intensity_to_Delta_OD: dod = hmrR_Intensity2OD(data)
%
function dod = hmrR_Intensity2OD( intensity )

% convert to dod
dod = DataClass().empty();
for ii=1:length(intensity)
    dod(ii) = DataClass();
    d = intensity(ii).GetDataTimeSeries();
    dm = mean(abs(d),1);
    nTpts = size(d,1);
    dod(ii).SetTime(intensity(ii).GetTime());
    dod(ii).SetDataTimeSeries(-log(abs(d)./(ones(nTpts,1)*dm)));
    dod(ii).SetMl(intensity(ii).GetMl());
    dod(ii).SetDataTypeDod();
end


f = [143 60];
A = [120 210; 110 30; 1 1];
b = [15000; 4000; 75];
lp = lp_maker(f, A, b, [-1; -1; -1], [], [], [], 1, 0);
solvestat = mxlpsolve('solve', lp)
format bank
obj = mxlpsolve('get_objective', lp)
format short
x = mxlpsolve('get_variables', lp)
mxlpsolve('delete_lp', lp);


function [n,msg1,msg2] = firchk(n,Fend,a,exception)
%FIRCHK   Check if specified filter order is valid.
%   FIRCHK(N,Fend,A) checks if the specified order N is valid given the
%   final frequency point Fend and the desired magnitude response vector A.
%   Type 2 linear phase FIR filters (symmetric, odd order) must have a
%   desired magnitude response vector that ends in zero if Fend = 1.  This
%   is because type 2 filters necessarily have a zero at w = pi.
%
%   If the order is not valid, a warning is given and the order
%   of the filter is incremented by one.
%
%   If A is a scalar (as when called from fircls1), A = 0 is
%   interpreted as lowpass and A = 1 is interpreted as highpass.
%
%   FIRCHK(N,Fend,A,EXCEPTION) will not warn or increase the order
%   if EXCEPTION = 1.  Examples of EXCEPTIONS are type 4 filters
%   (such as differentiators or hilbert transformers) or non-linear
%   phase filters (such as minimum and maximum phase filters).

%   Author : R. Losada
%   Copyright 1988-2004 The MathWorks, Inc.
%   $Revision: 1.7.4.5 $  $Date: 2007/12/14 15:15:06 $

matlab_v = version('-release');
matlab_v = str2double(matlab_v(1:4));

if matlab_v > 2012
    narginchk(3,4)
else
    error(nargchk(3,4,nargin,'struct'))
end

if nargin == 3,
    exception = false;
end

msg1 = '';
msg2 = '';
oddord = false; % Flag, initially we assume even order

if isempty(n) || length(n) > 1 || ~isnumeric(n) || ~isreal(n) || n~=round(n) || n<=0,
    msg1 = 'Filter order must be a real, positive integer.';
    return
end

if rem(n,2) == 1,
    oddord = true; % Overwrite flag
end

if (a(end) ~= 0) && Fend == 1 && oddord && ~exception,
    str = ['Odd order symmetric FIR filters must have a gain of zero \n'...
     'at the Nyquist frequency. The order is being increased by one.'];
    msg2 = sprintf(str);
    n = n+1;
end


function gen_hermite_poly_test ( )

%******************************hermite****************************************80
%
%% GEN_HERMITE_POLY_TEST tests GEN_HERMITE_POLY.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 February 2015
%
%  Author:
%
%    John Burkardt
%
  i_test = 6;
  n = 10;

  mu_test = [ 0.0, 0.0, 0.1, 0.1, 0.5, 1.0 ];
  x_test = [ 0.0, 1.0, 0.0, 0.5, 0.5, 0.5 ];

  fprintf ( 1, '\n' );
  fprintf ( 1, 'GEN_HERMITE_POLY_TEST\n' );
  fprintf ( 1, '  GEN_HERMITE_POLY evaluates the generalized Hermite \n' );
  fprintf ( 1, '  polynomials.\n' );

  for i = 1 : i_test

    x = x_test(i);
    mu = mu_test(i);

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Table of L(N,MU)(X) for\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '    N(max) = %d\n', n );
    fprintf ( 1, '    MU =     %f\n', mu );
    fprintf ( 1, '    X =      %f\n', x );
    fprintf ( 1, '\n' );

    c = gen_hermite_poly ( n, x, mu );

    for j = 0 : n
      fprintf ( 1, '  %4d  %12f\n', j, c(j+1) );
    end

  end

  return
end


function t = ktensor(varargin)
%KTENSOR Tensor stored as a Kruskal operator (decomposed).
%
%   K = KTENSOR(lambda,U1,U2,...,UM) creates a Kruskal tensor from its
%   constituent parts. Here lambda is a k-vector and each Um is a
%   matrix with k columns.
%
%   K = KTENSOR(lambda, U) is the same as above except that U is a
%   cell array containing matrix Um in cell m.
%
%   K = KTENSOR(U) assumes U is a cell array containing matrix Um in
%   cell m and assigns the weight of each factor to be one.
%
%   K = KTENSOR(T) creates a ktensor by copying an existing ktensor.
%
%   Examples
%   K = ktensor([3; 2], rand(4,2), rand(5,2), rand(3,2))
%
%   See also TENSOR, TTENSOR, KTENSOR/FULL.
%
%MATLAB Tensor Toolbox.
%Copyright 2012, Sandia Corporation.

% This is the MATLAB Tensor Toolbox by T. Kolda, B. Bader, and others.
% http://www.sandia.gov/~tgkolda/TensorToolbox.
% Copyright (2012) Sandia Corporation. Under the terms of Contract
% DE-AC04-94AL85000, there is a non-exclusive license for use of this
% work by or on behalf of the U.S. Government. Export of this data may
% require a license from the United States Government.
% The full license terms can be found in the file LICENSE.txt

% EMPTY CONSTRUCTOR
if nargin == 0
    t.lambda = [];
    t.u = {};
    t = class(t,'ktensor');
    return;
end

% Copy CONSTRUCTOR
if (nargin == 1) && isa(varargin{1}, 'ktensor')
    t.lambda = varargin{1}.lambda;
    t.u = varargin{1}.u;
    t = class(t, 'ktensor');
    return;
end

if isa(varargin{1},'cell')

    u = varargin{1};
    t.lambda = ones(size(u{1},2),1);
    t.u = u;

else

    t.lambda = varargin{1};
    if ~isa(t.lambda,'numeric') || ndims(t.lambda) ~=2 || size(t.lambda,2) ~= 1
	error('LAMBDA must be a column vector.');
    end

    if isa(varargin{2},'cell')
	t.u = varargin{2};
    else
	for i = 2 : nargin
	    t.u{i-1} = varargin{i};
	end
    end

end

% Check that each Um is indeed a matrix
for i = 1 : length(t.u)
    if ndims(t.u{i}) ~= 2
	error(['Matrix U' int2str(i) ' is not a matrix!']);
    end
end

% Size error checking
k = length(t.lambda);
for i = 1 : length(t.u)
    if  size(t.u{i},2) ~= k
       error(['Matrix U' int2str(i) ' does not have ' int2str(k) ' columns.']);
    end
end

t = class(t, 'ktensor');
return;


function UNew = fluidDirichlet3D(varargin);
% fluidDirichlet3D: solve fluid registraion in 3D with Dirichlet
%        boundary conditions
%
%
% author: Nathan D. Cahill
% email: nathan.cahill@rit.edu
% affiliation: Rochester Institute of Technology
% date: January 2014
% licence: GNU GPL v3
%
% Copyright Nathan D. Cahill
% Code available from https://github.com/tomdoel/npReg
%
%

% parse input arguments
[DU,F,mu,lambda,PixSize,M,N,P,RegularizerFactor,HX,HY,HZ] = parse_inputs(varargin{:});

% multiply F by adjoint of Navier-Lame equations
FNew = adjointNL(F/RegularizerFactor,mu,lambda,0,M,N,P);

% compute sine transform of new force field
FS = discreteSineTransform(FNew,M,N,P);

% construct images of coordinates scaled by pi/(N or M or P)
[a,b,c] = ndgrid(pi*(0:(M-1))/(M-1),pi*(0:(N-1))/(N-1),pi*(0:(P-1))/(P-1));

% construct LHS factor
LHSfactor = mu.*(lambda+2*mu).*(2*cos(a) + 2*cos(b) + 2*cos(c) - 6).^2;

% if gamma is zero, set origin term to 1, as DC term does not matter
LHSfactor(1,1,1) = 1;

% solve for FFT of U
VS = cat(4,FS(:,:,:,1)./LHSfactor,FS(:,:,:,2)./LHSfactor,FS(:,:,:,3)./LHSfactor);

% perform inverse DST
V = discreteSineTransform(VS,M,N,P);

% now perform Euler integration to construct new displacements
UNew = zeros(M,N,P,3);
UNew(:,:,:,1) = (1 - imfilter(V(:,:,:,1),HX,'replicate','same')).*V(:,:,:,1) - ...
    imfilter(V(:,:,:,2),HY,'replicate','same').*V(:,:,:,2) - ...
    imfilter(V(:,:,:,3),HZ,'replicate','same').*V(:,:,:,3);
UNew(:,:,:,2) = -imfilter(V(:,:,:,1),HY,'replicate','same').*V(:,:,:,1) + ...
    (1 - imfilter(V(:,:,:,2),HY,'replicate','same')).*V(:,:,:,2) - ...
    imfilter(V(:,:,:,3),HY,'replicate','same').*V(:,:,:,3);
UNew(:,:,:,3) = -imfilter(V(:,:,:,1),HZ,'replicate','same').*V(:,:,:,1) - ...
    imfilter(V(:,:,:,2),HZ,'replicate','same').*V(:,:,:,2) + ...
    (1 - imfilter(V(:,:,:,3),HZ,'replicate','same')).*V(:,:,:,3);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function FS = discreteSineTransform(F,M,N,P);
% compute discrete sine transform of 3-D vector field

% initialize resulting array
FS = F;

% first perform sine transform down columns
len = 2*M-2; ind = 1:M;
for p=1:P
    for n=1:N
        s = fft(FS(:,n,p,:),len,1);
        FS(:,n,p,:) = imag(s(ind,:,:,:));
    end
end
FS = sqrt(2/(M-1))*FS;

% next perform sine transform across rows
len = 2*N-2; ind = 1:N;
for p=1:P
    for m=1:M
        s = fft(FS(m,:,p,:),len,2);
        FS(m,:,p,:) = imag(s(:,ind,:,:));
    end
end
FS = sqrt(2/(N-1))*FS;

% finally perform sine transform across pages
len = 2*P-2; ind = 1:P;
for n=1:N
    for m=1:M
        s = fft(FS(m,n,:,:),len,3);
        FS(m,n,:,:) = imag(s(:,:,ind,:));
    end
end
FS = sqrt(2/(P-1))*FS;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function FNew = adjointNL(F,mu,lambda,gamma,M,N,P);
% multiply vector field F by adjoint Navier-Lame equations

% initialize FNew
FNew = zeros(M,N,P,3);

% construct filter that implements 3-D Laplacian
L = (lambda+2*mu)*cat(3,[0 0 0;0 1 0;0 0 0],[0 1 0;1 -6 1;0 1 0],[0 0 0;0 1 0;0 0 0]);

% we will need to use L to form two different filters
% L1 = -(lambda+2*mu)*L; L1(2,2,2) = gamma + L1(2,2,2);
% L2 = -mu*L; L2(2,2,2) = gamma + L2(2,2,2);

% construct grad div filters
GD11 = (lambda+mu)*cat(3,zeros(3,3),[0 1 0;0 -2 0;0 1 0],zeros(3,3));
GD22 = ipermute(GD11,[2 1 3]);
GD33 = ipermute(GD11,[3 2 1]);
GD23 = zeros(3,3,3);
GD23(2,1,1) = 1; GD23(2,3,3) = 1; GD23(2,1,3) = -1; GD23(2,3,1) = -1;
GD23 = GD23*(lambda+mu)/4;
GD12 = ipermute(GD23,[3 1 2]);
GD13 = ipermute(GD23,[2 3 1]);

% perform filtering
FNew(:,:,:,1) = imfilter(F(:,:,:,1),L-GD11,'replicate') + ...
    imfilter(F(:,:,:,2),-GD12,'replicate') + ...
    imfilter(F(:,:,:,3),-GD13,'replicate');
FNew(:,:,:,2) = imfilter(F(:,:,:,1),-GD12,'replicate') + ...
    imfilter(F(:,:,:,2),L-GD22,'replicate') + ...
    imfilter(F(:,:,:,3),-GD23,'replicate');
FNew(:,:,:,3) = imfilter(F(:,:,:,1),-GD13,'replicate') + ...
    imfilter(F(:,:,:,2),-GD23,'replicate') + ...
    imfilter(F(:,:,:,3),L-GD33,'replicate');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [DU,F,mu,lambda,PixSize,M,N,P,RegularizerFactor,HX,HY,HZ] = parse_inputs(varargin);

% get displacement field and check size
F = varargin{2};
PixSize = varargin{4}(1:3);
M = varargin{5};
N = varargin{6};
P = varargin{7};
mu = varargin{8};
lambda = varargin{9};
RegularizerFactor = varargin{10};
DU = varargin{11};
HX = varargin{12};
HY = varargin{13};
HZ = varargin{14};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


function x_hat=phit_fp(y,m,n,ops)
% function x_hat=phit_fp(y,m,n,ops)
% PHIT_FP projects a length m signal onto the transpose of an mxn measurment matrix.
% Input:
%       y   : length m signals (for example a vectorized image)
%       m   : the number of measurements
%       n   : the signal length
%       ops : currently unused argument
%Output:
%       x   : result of projecting y onto phi'.
    x_hat=zeros(n,1);
    remaining_rows=n;
    K=4096;
    iters=ceil(n/K);
    for i=0:iters-1
        rng(i);
        row_num=min(K,remaining_rows);
        phi_columns=randn(m,row_num);
        column_norms=sqrt(sum(abs(phi_columns).^2,1));
        phi_columns=bsxfun(@rdivide,phi_columns,column_norms);
        phit_rows=phi_columns';
        x_hat(K*i+1:K*i+row_num)=phit_rows*y;
        remaining_rows=remaining_rows-K;
    end
end


function state = viterbi(feature, hmm)
%VITERBI    Viterbi decoding of HMM.
%   Format: state = viterbi(feature, hmm)
%   Inputs:
%       feature:    Feature matrix, where each column stands for a time
%                   step.
%       HMM:        HMM model.
%   Output:
%       state:      Decoded state sequence.

    frames = size(feature, 2);
    states = length(hmm.init);
    decision = zeros(frames, states);

    emit = -inf(frames, states);
    for u = 1:states
        if (~isempty(hmm.gmm{u}))
            emit(:,u) = log(hmm.gmm{u}.pdf(feature'));
        end
    end

    trans = log(hmm.trans);
    prob = log(hmm.init);
    for f = 1:frames
        newProb = zeros(1, states);
        for u = 1:states
            [newProb(u) decision(f,u)] = max(prob + trans(:,u)');
        end
        prob = newProb + emit(f,:);
    end

    [temp state(frames)] = max(prob);
    for f = frames:-1:2
        state(f-1) = decision(f, state(f));
    end
end


function [x,b,a] = bst_bandpass_filtfilt(x, Fs, HighPass, LowPass, isStopBand, FilterType)
% BST_BANDPASS_FILTFILT: Bandpass filter for the signal x, using the filtfilt function (used by default after Nov 2014)
%
% USAGE:  [x,b,a] = bst_bandpass_filtfilt(x, Fs, HighPass, LowPass, isStopBand=0, FilterType='fir')
%
% INPUT:
%    - x          : [nChannels,nTime] signal to process
%    - Fs         : Sampling frequency
%    - HighPass   : Frequency below this value are filtered (set to 0 for low-pass filter only)
%    - LowPass    : Frequency above this value are filtered (set to 0 for high-pass filter only)
%    - isStopBand : If 1, create a stop-band filter instead of a pass-band filter
%    - FilterType : 'fir' or 'iir'
%
% OUTPUT:
%    - x   : Filtered signals
%    - b,a : Filter coefficients, as defined in all the Matlab functions
%
% DESCRIPTION:
%    - A linear phase FIR filter is created and applied both forward and backward using filtfilt.
%    - Function "filtfilt" is used to employ the filtering "mirror" trick, and to reset automatically the group delay.
%    - Function "kaiserord" and "kaiser" are used to set the necessary order for fir1.
%    - The transition band is hard-coded.
%    - Requires Signal Processing Toolbox for the following functions: kaiserord, kaiser, ellipord,
%      If not, using Octave-based alternatives

% @=============================================================================
% This function is part of the Brainstorm software:
% https://neuroimage.usc.edu/brainstorm
%
% Copyright (c) University of Southern California & McGill University
% This software is distributed under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPLv3
% license can be found at http://www.gnu.org/copyleft/gpl.html.
%
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%
% For more information type "brainstorm license" at command prompt.
% =============================================================================@
%
% Authors: John Mosher, Francois Tadel, 2014

% ===== PARSE INPUTS =====
if (nargin < 6) || isempty(FilterType)
    FilterType = 'fir';
end
if (nargin < 5) || isempty(isStopBand)
    isStopBand = 0;
end
if isempty(HighPass)
    HighPass = 0;
end
if isempty(LowPass)
    LowPass = 0;
end
% If both high-pass and low-pass are zero: return signals unaltered
if (HighPass == 0) && (LowPass == 0)
    disp('BST_BANDPASS> Error: No frequency band in input');
    return;
end

% ===== FILTER PARAMETERS =====
PASSBAND_RIPPLE = 5;    % percent pass band ripple
PASSBAND_DB     = 1;    % dB of pass band ripple
STOP_ATTEN_DB   = 40;   % dB of attenuation in the stop band
TRANSITION_BAND = 0.05; % normalized to Nyquist, the allowed transition band
% We use filtfilt, which doubles the effect (attenuation and ripple)
PASSBAND_RIPPLE = PASSBAND_RIPPLE/2;
STOP_ATTEN_DB   = STOP_ATTEN_DB/2;
% Conversion from percent
Ripple = PASSBAND_RIPPLE/100;
% Stop band attenuation
Atten  = 10^(-STOP_ATTEN_DB/20);

% Convert frequencies to normalized form
Nyquist = Fs/2;
f_highpass = HighPass / Nyquist;
f_lowpass  = LowPass  / Nyquist;
% Reasonable digital transition band
f_highstop = f_highpass - TRANSITION_BAND;
f_lowstop  = f_lowpass  + TRANSITION_BAND;

% ===== CREATE FILTER =====
switch FilterType
    % ===== FIR =====
    case 'fir'
        % Build the general case first
        fcuts = [f_highstop, f_highpass, f_lowpass, f_lowstop];
        % Stop-band
        if isStopBand
            mags = [1 0 1];               % filter magnitudes
            devs = [Ripple Atten Ripple]; % deviations
        % Pass-band
        else
            mags = [0 1 0];               % filter magnitudes
            devs = [Atten Ripple Atten];  % deviations
        end
        % Now adjust for desired properties
        fcuts = max(0,fcuts);     % Can't go below zero
        fcuts = min(1-eps,fcuts); % Can't go above or equal to 1
        % We have implicitly created a bandpass, but now adjust for desired filter
        if (f_lowpass == 0)  % User didn't want a lowpass
            fcuts(3:4) = [];
            mags(3) = [];
            devs(3) = [];
        end
        if (f_highpass == 0)  % User didn't want a highpass
            fcuts(1:2) = [];
            mags(1) = [];
            devs(1) = [];
        end
        % Generate FIR filter
        [n,Wn,beta,ftype] = kaiserord(fcuts,mags,devs,2);
        n = n + rem(n,2);  % ensure even order
        b = fir1(n,Wn,ftype,kaiser(n+1,beta),'noscale');
        a = 1;

    % ===== IIR =====
    case 'iir'
        % Stop-band
        if isStopBand
            ftype = 'stop';
            Ws = [f_highpass f_lowpass]; % the range of stopped
            Wp = [f_highstop f_lowstop]; % the transition band
        % Pass-band
        else
            ftype = 'bandpass';
            Ws = [f_highstop f_lowstop]; % the transition band
            Wp = [f_highpass f_lowpass]; % the passband
        end
        % Now handle extremes
        Ws = max(eps,Ws);   % Can't be zero or less
        Wp = max(eps,Wp);
        Ws = min(1-eps,Ws); % Can't be 1
        Wp = min(1-eps,Wp);
        % Now handle highpass or lowpass only
        if (f_lowpass == 0)  % User didn't want a lowpass
            ftype = 'high';
            Ws(2) = [];
            Wp(2) = [];
        end
        if (f_highpass == 0)  % User didn't want a highpass
            ftype = 'low';
            Ws(1) = [];
            Wp(1) = [];
        end
        % Generate IIR filter
        [n,WP] = ellipord(Wp,Ws,PASSBAND_DB,STOP_ATTEN_DB);
        [b,a]  = ellip(n,PASSBAND_DB,STOP_ATTEN_DB,WP,ftype);
end

% ===== FILTER THE DATA =====
Ntime = size(x,2);
% Remove the mean of the data before filtering, which wrecks most filters
xmean = mean(x,2);
x = bst_bsxfun(@minus, x, xmean)';    % Transposed output (time is now down the columns)
% Using filtfilt to use the mirroring trick and remove group delay
try
    x = filtfilt(b,a,x)';     % Transposed output

    % OCTAVE IMPLEMENTATION
    % http://octave-signal.sourcearchive.com/documentation/1.0.8/filtfilt_8m-source.html
catch
    fprintf('Sequence too short for filtfilt, using alternate approach.\n')
    xmirror = [flipud(x); x; flipud(x)];      % Mirror either end
    xmirror = filter(b,1,xmirror);            % Filter
    xmirror = flipud(xmirror);                % Reverse in time
    xmirror = flipud(filter(b,1,xmirror));    % Filter and flip again
    x = xmirror(Ntime + (1:Ntime),:)';        % Transposed output
end
% Restore the mean of the signal (only if there is no high-pass filter)
if (f_highpass == 0)
    x = bst_bsxfun(@plus, x, xmean);
end


function margLogPr = calcLogMargPrObsSeqFAST( LL, Eta )
% calcLogMargPrObsSeqFAST
% Provides fast calculation of marginal likelihood
%    for a particular sequence of data, given HMM parameters in the form
%      soft evidence LL, where LL(kk,tt) = p( X{ii}(tt) | theta(kk) )
%      transition weights Pz, which may be non-normalized
% Massages input data and then calls a super-efficient MEX function
%   "FilterFwdC" to perform dynamic programming.
%INPUT
% LL  := KiixTii matrix of log likelihoods soft evidence
% Pz  := KiixKii matrix of transition weights (non-normalized)
%OUTPUT
%  margLogPr  := scalar value of log( X_ii | F_ii, theta, Eta_ii )

K = size(Eta,2);
if K == 0
    margLogPr = -Inf;
    return;
end

Pi = bsxfun( @rdivide, Eta, sum(Eta,2) );

% Need to turn log_lik into lik.  We know lik = exp( log_lik )
%   For numerical stability, we find M = max( log_lik )
%       we compute L = exp( log_lik - M  )
%       and we thus have lik up to multiplicative constant
%              since lik \propto L = exp( log_lik ) / exp( M )
%   We find a unique "normalizer" M_t  for each time step

% normC = 1 x T
normC = max( LL,[],1);

if K == 1
    margLogPr = sum(normC );
    return;
end
Lik = exp( bsxfun( @minus, LL, normC ) );

[~,margLogPr] = FilterFwdC( Pi, Lik, 1/K*ones(1,K) );
margLogPr = margLogPr + sum( normC );

end % main function


function [number_of_objectives, number_of_decision_variables, min_range_of_decesion_variable, max_range_of_decesion_variable] = objective_description_function()

%% function [number_of_objectives, number_of_decision_variables, min_range_of_decesion_variable, max_range_of_decesion_variable] = objective_description_function()
% This function is used to completely describe the objective functions and
% the range for the decision variable space etc. The user is prompted for
% inputing the number of objectives, numebr of decision variables, the
% maximum and minimum range for each decision variable and finally the
% function waits for the user to modify the evaluate_objective function to
% suit their need.

%  Copyright (c) 2009, Aravind Seshadri
%  All rights reserved.

% g = sprintf('Input the number of objective: ');
% Obtain the number of objective function
number_of_objectives = input('Input the number of objective: '); % modified by zzb
if number_of_objectives < 2
    error('This is a multi-objective optimization function hence the minimum number of objectives is two');
end
% g = sprintf('\nInput the number of decision variables: ');
% Obtain the number of decision variables
number_of_decision_variables = input('Input the number of decision variables: '); % modified by zzb
min_range_of_decesion_variable = input('Input the array of minimum value for decision variable: '); % modified by zzb
while(length(min_range_of_decesion_variable) ~= number_of_decision_variables)
    min_range_of_decesion_variable = input('The size is wrong. \nInput the array of minimum value for decision variable: ');
end
max_range_of_decesion_variable = input('Input the array of maximum value for decision variable: '); % modified by zzb
while(length(max_range_of_decesion_variable) ~= number_of_decision_variables)
    max_range_of_decesion_variable = input('The size is wrong. \nInput the array of maximum value for decision variable: ');
end
clc;
% for i = 1 : number_of_decision_variables
%     clc
%     g = sprintf('\nInput the minimum value for decision variable %d : ', i);
%     % Obtain the minimum possible value for each decision variable
%     min_range_of_decesion_variable(i) = input(g);
%     g = sprintf('\nInput the maximum value for decision variable %d : ', i);
%     % Obtain the maximum possible value for each decision variable
%     max_range_of_decesion_variable(i) = input(g);
%     clc
% end
open('D:\ProgramFiles\MATLAB\toolbox\genetic\NSGA-II\evaluate_objective.m');  % modified by zzb
g = sprintf('Now edit the function named "evaluate_objective" appropriately to match your needs.\nMake sure that the number of objective functions and decision variables match your numerical input. \nMake each objective function as a corresponding array element. \nAfter editing do not forget to save. \nPress "c" and enter to continue... ');
% Prompt the user to edit the evaluate_objective function and wait until
% 'c' is pressed.
x = input(g, 's');
if isempty(x)
    x = 'x';
end
while x ~= 'c'
    clc;
    x = input(g, 's');
    if isempty(x)
        x = 'x';
    end
end


function treepack_test04 ( )

%*****************************************************************************80
%
%% TREEPACK_TEST04 tests TREE_ARC_CENTER.
%
%  Discussion:
%
%    The tree is
%
%    2---3---6---8---1---9
%       /       / \
%      7       5   4
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 June 2013
%
%  Author:
%
%    John Burkardt
%
  nnode = 9;

  inode = [ 2, 3, 3, 6, 8, 8, 8, 1 ];
  jnode = [ 3, 7, 6, 8, 4, 5, 1, 9 ];

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TREEPACK_TEST04\n' );
  fprintf ( 1, '  TREE_ARC_CENTER computes the center of a tree.\n' );

  graph_arc_print ( nnode-1, inode, jnode, '  The edge list of the tree:' );

  [ center, eccent, parity ] = tree_arc_center ( nnode, inode, jnode );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Parity = %d\n', parity );
  fprintf ( 1, '  Eccentricity is %d\n', eccent );

  if ( parity == 0 )
    fprintf ( 1, '  No center node (degenerate case).\n' );
  elseif ( parity == 1 )
    fprintf ( 1, '  Center node: %d\n', center(1) );
  else
   fprintf ( 1, '  Center nodes: %d %d\n', center(1), center(2) );
  end

  return
end


classdef ZDT3 < PROBLEM
% <multi> <real> <large/none> <expensive/none>
% Benchmark MOP proposed by Zitzler, Deb, and Thiele

%------------------------------- Reference --------------------------------
% E. Zitzler, K. Deb, and L. Thiele, Comparison of multiobjective
% evolutionary algorithms: Empirical results, Evolutionary computation,
% 2000, 8(2): 173-195.
%------------------------------- 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".
%--------------------------------------------------------------------------

    methods
        %% Default settings of the problem
        function Setting(obj)
            obj.M = 2;
            if isempty(obj.D); obj.D = 30; end
            obj.lower    = zeros(1,obj.D);
            obj.upper    = ones(1,obj.D);
            obj.encoding = ones(1,obj.D);
        end
        %% Calculate objective values
        function PopObj = CalObj(obj,PopDec)
            PopObj(:,1) = PopDec(:,1);
            g = 1 + 9*mean(PopDec(:,2:end),2);
            h = 1 - (PopObj(:,1)./g).^0.5 - PopObj(:,1)./g.*sin(10*pi*PopObj(:,1));
            PopObj(:,2) = g.*h;
        end
        %% Generate points on the Pareto front
        function R = GetOptimum(obj,N)
            R(:,1) = linspace(0,1,N)';
            R(:,2) = 1 - R(:,1).^0.5 - R(:,1).*sin(10*pi*R(:,1));
            R      = R(NDSort(R,1)==1,:);
        end
        %% Generate the image of Pareto front
        function R = GetPF(obj)
            R(:,1) = linspace(0,1,100)';
            R(:,2) = 1 - R(:,1).^0.5 - R(:,1).*sin(10*pi*R(:,1));
            R(NDSort(R,1)>1,:) = nan;
        end
    end
end


%% Colormaps that are pretty awesome: DEMO1
% this is an exampe of 4 colormaps that are being considered as the default
% colormap in python's matplotlib lybrary.
%
% All of them look quite good and they don't have any official name, so at
% the moment they are A,B,C,D.
%
% colormaps from https://github.com/bids/colormap
%
% Ander Biguri
%% Clear workspace and get screen data
clear;
clc
close all;

screen=get(0,'ScreenSize') ;
w0=screen(1);
h0=screen(2);
w =screen(3);
h =screen(4);
%% Generate sample data
load flujet
X=X.';

%% Plot original with jet and parula
% Parula
h2=figure('name','Sample data with "parula" colormap');
set(h2,'position',[w0,h0,w/3,h/2])
imagesc(X)

if verLessThan('matlab', '8.4')
   % if parula is the "future"
   colormap(parula());
else
   % if parula is already in Matlab
   colormap('parula');
end
axis image
xlabel('Parula Colormap')
set(gca,'xtick',[],'ytick',[]) % This is axis off without offing the labels

% Jet
h1=figure('name','Sample data with "jet" colormap');
set(h1,'position',[w0,h/2,w/3,h/2])
imagesc(X)
colormap('jet')
xlabel('jet Colormap')
set(gca,'xtick',[],'ytick',[]) % This is axis off without offing the labels
axis image

%% Load new colormaps

m=100;
cm_magma=magma(m);
cm_inferno=inferno(m);
cm_plasma=plasma(m);
cm_viridis=viridis(m);

%% Plot new colormaps
h3=figure('name','Super-cool new colormaps that you can easily use');
set(h3,'position',[w/3,h0,2*w/3,h])
if verLessThan('matlab', '8.4')
% If you are using old Matlab figure engine do  it this way
% (some very lousy colormap problems before)
    subplot(2,2,1,'Position',[0.05 0.55 0.4 0.4])
    subimage(uint8(X/max(X(:))*255),cm_magma)
    xlabel('MAGMA')
    set(gca,'xtick',[],'ytick',[])

    subplot(2,2,2,'Position',[0.55 0.55 0.4 0.4])
    subimage(uint8(X/max(X(:))*255),cm_inferno)
    xlabel('INFERNO')
    set(gca,'xtick',[],'ytick',[])

    subplot(2,2,3,'Position',[0.05 0.05 0.4 0.4])
    subimage(uint8(X/max(X(:))*255),cm_plasma)
    xlabel('PLASMA')
    set(gca,'xtick',[],'ytick',[])

    subplot(2,2,4,'Position',[0.55 0.05 0.4 0.4])
    subimage(uint8(X/max(X(:))*255),cm_viridis)
    xlabel('VIRIDIS')
    set(gca,'xtick',[],'ytick',[])
else
    sp1=subplot(2,2,1,'Position',[0.05 0.55 0.4 0.4]);
    imagesc(X)
    colormap(sp1,cm_magma)
    xlabel('MAGMA')
    set(gca,'xtick',[],'ytick',[])

    sp2=subplot(2,2,2,'Position',[0.55 0.55 0.4 0.4]);
    imagesc(X)
    colormap(sp2,cm_inferno)
    xlabel('INFERNO')
    set(gca,'xtick',[],'ytick',[])

    sp3=subplot(2,2,3,'Position',[0.05 0.05 0.4 0.4]);
    imagesc(X)
    colormap(sp3,cm_plasma)
    xlabel('PLASMA')
    set(gca,'xtick',[],'ytick',[])

    sp4=subplot(2,2,4,'Position',[0.55 0.05 0.4 0.4]);
    imagesc(X)
    colormap(sp4,cm_viridis)
    xlabel('VIRIDIS')
    set(gca,'xtick',[],'ytick',[])
end


% sample = samplep(p,n)
% returns n samples, where the probability of i is p(i) for 1 <=i
% <= length(p), 0 otherwise.

function s = samplep(p,n)

% normalize, just in case
p = p(:);
p = normalizep(p);
p(end) = 1;
m = length(p);

% compute the cumulative sum of probabilities
c = cumsum(p);

% choose n random numbers uniformly between 0 and 1
r = rand(1,n);

% find the first element of c >= r
s = findfirstdim(repmat(c,[1,n])>=repmat(r,[m,1]),1);


classdef UF1 < PROBLEM
% <multi> <real> <large/none>
% Unconstrained benchmark MOP

%------------------------------- Reference --------------------------------
% Q. Zhang, A. Zhou, S. Zhao, P. N. Suganthan, W. Liu, and S. Tiwari,
% Multiobjective optimization test instances for the CEC 2009 special
% session and competition, School of CS & EE, University of Essex, Working
% Report CES-487, 2009.
%------------------------------- 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".
%--------------------------------------------------------------------------

    methods
        %% Default settings of the problem
        function Setting(obj)
            obj.M = 2;
            if isempty(obj.D); obj.D = 30; end
            obj.lower    = [0,zeros(1,obj.D-1)-1];
            obj.upper    = ones(1,obj.D);
            obj.encoding = ones(1,obj.D);
        end
        %% Calculate objective values
        function PopObj = CalObj(obj,X)
            J1 = 3 : 2 : obj.D;
            J2 = 2 : 2 : obj.D;
            Y  = X - sin(6*pi*repmat(X(:,1),1,obj.D)+repmat(1:obj.D,size(X,1),1)*pi/obj.D);
            PopObj(:,1) = X(:,1)         + 2*mean(Y(:,J1).^2,2);
            PopObj(:,2) = 1-sqrt(X(:,1)) + 2*mean(Y(:,J2).^2,2);
        end
        %% Generate points on the Pareto front
        function R = GetOptimum(obj,N)
            R(:,1) = linspace(0,1,N)';
            R(:,2) = 1 - R(:,1).^0.5;
        end
        %% Generate the image of Pareto front
        function R = GetPF(obj)
        	R = obj.GetOptimum(100);
        end
    end
end


classdef IntersectionCoordComputer < TotalCoordinatesCalculator

    properties (Access = public)
        c
        theta
        nodes
        vertCoord
        boundCoord
        div
        totalCoord
    end

    properties (Access = private)
        vA
        vB
    end

    methods (Access = public)

        function obj = IntersectionCoordComputer(cParams)
            obj.init(cParams);
            obj.initBoundary();
            obj.obtainPrincipalVectors();
            obj.computeIntersections();
        end

    end

    methods (Access = private)

        function obtainPrincipalVectors(obj)
            A = obj.vertCoord(1,:);
            B = obj.vertCoord(2,:);
            C = obj.vertCoord(3,:);
            obj.vA = IntersectionCoordComputer.computeUnitaryVector(A,B);
            obj.vB = IntersectionCoordComputer.computeUnitaryVector(B,C);
        end

        function computeIntersections(obj)
            nodesX = obj.div(1)-1;
            nodesY = obj.div(2)-1;
            intNode = obj.nodes.bound +1;
            for jNodes = 1:nodesY
                pB = obj.boundCoord(obj.nodes.bound+1-jNodes,:);
                for iNodes = 1:nodesX
                    pA = obj.boundCoord(obj.nodes.vert+iNodes,:);
                    if obj.vA(1) == 0
                        [x,y] = IntersectionCoordComputer.computeVerticalIntersection(pA,pB,obj.vB);
                    elseif obj.vB(1) == 0
                        [x,y] = IntersectionCoordComputer.computeVerticalIntersection(pB,pA,obj.vA);
                    else
                        [x,y] = IntersectionCoordComputer.computeGeneralIntersection(pA,pB,obj.vA,obj.vB);
                    end
                    obj.totalCoord(intNode,:) = [x y];
                    intNode = intNode+1;
                end
            end
        end

    end

    methods (Static)

        function v_norm = computeUnitaryVector(A,B)
            v = B-A;
            m = norm(v);
            v_norm = v/m;
        end

        function [x,y] = computeVerticalIntersection(p1,p2,v)
            x = p2(1);
            y = (x-p1(1))*v(2)/v(1)+p1(2);
        end

        function [x,y] = computeGeneralIntersection(p1,p2,v1,v2)
            x = (p2(2)-p1(2)+p1(1)*v2(2)/v2(1)-p2(1)*v1(2)/v1(1))/(v2(2)/v2(1)-v1(2)/v1(1));
            y = (x-p2(1))*v1(2)/v1(1)+p2(2);
        end

    end

end


% Copyright (c) Roman Garnett, 2012--2014.

function pdfs = evaluate_pdfs(mus, Ks, x, weights)

  persistent individual_pdfs;

  % reset if no arguments given
  if (nargin == 0)
    individual_pdfs = [];
    return;
  end

  % precompute N(x; mu, K) for every x
  if (isempty(individual_pdfs))
    num_points = size(x, 1);
    num_nodes  = size(mus, 1);

    individual_pdfs = zeros(num_nodes, num_points);
    for i = 1:num_nodes
        individual_pdfs(i, :) = mvnpdf(x, mus(i, :), Ks(:, :, i))';
    end
  end

  pdfs = weights * individual_pdfs;

end


function r8mat_house_form_test ( )

%*****************************************************************************80
%
%% R8MAT_HOUSE_FORM_TEST tests R8MAT_HOUSE_FORM.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 April 2009
%
%  Author:
%
%    John Burkardt
%
  n = 5;

  v = [ 0.0, 0.0, 1.0, 2.0, 3.0 ];

  fprintf ( 1, '\n' );
  fprintf ( 1, 'R8MAT_HOUSE_FORM_TEST\n' );
  fprintf ( 1, '  R8MAT_HOUSE_FORM forms a Householder\n' );
  fprintf ( 1, '  matrix from its compact form.\n' );

  r8vec_print ( n, v, '  Compact vector form V:' );

  h = r8mat_house_form ( n, v );

  r8mat_print ( n, n, h, '  Householder matrix H:' );

  return
end


function [perimeterEdges,eulerCondition] = findLegalPerimeters2(mesh,perimDist)
% Calculate edges that on distinct perimeters perimDist mm from startVertex
%
%  [perimeterEdges,eulerCondition] = findLegalPerimeters2(mesh,perimDist)
%
% Given a mesh structure (nodes, edges, distances from start point) and a
% threshold distance return a list of edges that constitute separate
% perimeters at a distance of perimDist from the start point.
%
% Note that because of intrinsic curvature, there can be more than one
% perimeter at the required distance. This routine makes sure that it
% returns separate perimeters (ones with no common nodes).
%

% Find perims with simple threshold
insideNodes = find(mesh.dist<=perimDist);
insideNodes = insideNodes(:);

% Some triangles have one or two vertices outside the perimeter.  These
% triangles will not be included; any nodes that are within the perimeter
% but only part of these excluded triangles are removed here.
insideNodes = removeHangingNodes2(mesh,insideNodes);

% We could write a short piece of code that verifies these new nodes have
% no hanging nodes ...

numBadNodes = 1;

while (numBadNodes>0)

    [perimeterEdges,eulerCondition] = findGroupPerimeter2(mesh,insideNodes);

    length(perimeterEdges);
    length(unique(perimeterEdges,'rows'));
    fprintf('Euler number=%d\n',eulerCondition);

    badPerimNodes = findBadPerimNodes2(mesh,perimeterEdges);
    numBadNodes   = length(badPerimNodes);
    fprintf('There are %d bad perim nodes.\n',numBadNodes);

    if(numBadNodes)
        % Splits up joined perimeters
        [insideNodes] = correctBadNodes2(mesh,insideNodes,badPerimNodes);

        % Cleans up mesh again
        insideNodes = removeHangingNodes2(mesh,insideNodes);
    end
end

return;


classdef TP8 < PROBLEM
% <multi> <real> <large/none> <robust>
% Test problem for robust multi-objective optimization
% delta --- 0.05 --- Maximum disturbance degree
% H     ---   50 --- Number of disturbances

%------------------------------- Reference --------------------------------
% A. Gaspar-Cunha, J. Ferreira, and G. Recio, Evolutionary robustness
% analysis for multi-objective optimization: benchmark problems, Structural
% and Multidisciplinary Optimization, 2014, 49: 771-793.
%------------------------------- 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
        delta;      % Maximum disturbance degree
        H;          % Number of disturbances
    end
    methods
        %% Default settings of the problem
        function Setting(obj)
            [obj.delta,obj.H] = obj.ParameterSet(0.05,50);
            obj.M = 2;
            if isempty(obj.D); obj.D = 5; end
            obj.lower    = [0,0,-ones(1,obj.D-2)];
            obj.upper    = [1,1, ones(1,obj.D-2)];
            obj.encoding = ones(1,obj.D);
        end
        %% Calculate objective values
        function PopObj = CalObj(~,PopDec)
            PopObj(:,1) = PopDec(:,1);
            h = 2 - 0.8*exp(-((PopDec(:,2)-0.35)/0.25).^2) - exp(-((PopDec(:,2)-0.85)/0.03).^2);
            g = 50*sum(PopDec(:,3:end).^2,2);
            S = 1 - sqrt(PopObj(:,1));
            PopObj(:,2) = h.*(g+S);
        end
        %% Generate points on the Pareto front
        function R = GetOptimum(obj,N)
            R(:,1) = linspace(0,1,N)';
            R(:,2) = 1 - sqrt(R(:,1));
        end
        %% Generate the image of Pareto front
        function R = GetPF(obj)
            R = obj.GetOptimum(100);
        end
        %% Calculate the metric value
        function score = CalMetric(obj,metName,Population)
            switch metName
                case {'Mean_IGD','Mean_HV','Worst_IGD','Worst_HV'}
                    score = feval(metName,Population,obj);
                otherwise
                    score = feval(metName,Population,obj.optimum);
            end
        end
        %% Perturb solutions multiple times
        function PopX = Perturb(obj,PopDec,N)
            if nargin < 3; N = obj.H; end
            Delta = repmat(obj.delta.*(obj.upper-obj.lower),N*size(PopDec,1),1);
            w     = UniformPoint(N,obj.D,'Latin');
            Dec   = 2*Delta.*w(reshape(repmat(1:end,size(PopDec,1),1),1,[]),:) + repmat(PopDec,N,1) - Delta;
            Dec   = obj.CalDec(Dec);
            PopX  = SOLUTION(Dec,obj.CalObj(Dec),obj.CalCon(Dec));
        end
    end
end


function suborder_num = dunavant_suborder_num ( rule )

%*****************************************************************************80
%
%% DUNAVANT_SUBORDER_NUM returns the number of suborders for a Dunavant rule.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 December 2006
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    David Dunavant,
%    High Degree Efficient Symmetrical Gaussian Quadrature Rules
%    for the Triangle,
%    International Journal for Numerical Methods in Engineering,
%    Volume 21, 1985, pages 1129-1148.
%
%    James Lyness, Dennis Jespersen,
%    Moderate Degree Symmetric Quadrature Rules for the Triangle,
%    Journal of the Institute of Mathematics and its Applications,
%    Volume 15, Number 1, February 1975, pages 19-32.
%
%  Parameters:
%
%    Input, integer RULE, the index of the rule.
%
%    Output, integer SUBORDER_NUM, the number of suborders of the rule.
%
  suborder = [ ...
     1,  1 , 2,  2,  3,  3,  4,  5,  6,  6, ...
     7,  8, 10, 10, 11, 13, 15, 17, 17, 19 ];

  if ( 1 <= rule & rule <= 20 )
    suborder_num = suborder(rule);
  else

    suborder_num = -1;
    fprintf ( 1, '\n' );
    fprintf ( 1, 'DUNAVANT_SUBORDER_NUM - Fatal error!\n' );
    fprintf ( 1, '  Illegal RULE = %d\n', rule );
    error ( 'DUNAVANT_SUBORDER_NUM - Fatal error!\n' )

  end

  return
end


function x = blend_rst_2dn ( r, s, t, n, bound_rst )

%*****************************************************************************80
%
%% BLEND_RST_2DN extends vector data on faces into a cube.
%
%  Diagram:
%
%    010-----r10-----110        011-----r11-----111
%      |       .       |          |       .       |
%      |       .       |          |       .       |
%    0s0.....rs0.....1s0        0s1.....rs1.....1s1     S
%      |       .       |          |       .       |     |
%      |       .       |          |       .       |     |
%    000-----r00-----100        001-----r01-----101     +----R
%           BOTTOM                      TOP
%
%    011-----0s1-----001        111-----1s1-----101
%      |       .       |          |       .       |
%      |       .       |          |       .       |
%    01t.....0st.....00t        11t.....1st.....10t          T
%      |       .       |          |       .       |          |
%      |       .       |          |       .       |          |
%    010-----0s0-----000        110-----1s0-----100     S----+
%           LEFT                       RIGHT
%
%    001-----r01-----101        011-----r11-----111
%      |       .       |          |       .       |
%      |       .       |          |       .       |
%    00t.....r0t.....100        01t.....r1t.....11t     T
%      |       .       |          |       .       |     |
%      |       .       |          |       .       |     |
%    000-----r00-----100        010-----r10-----110     +----R
%           FRONT                       BACK
%
%  Discussion:
%
%    BLEND_RST_2DN is NOT equivalent to a trilinear finite element
%    method, since the data is sampled everywhere along the corners,
%    edges, and faces, rather than at a finite number of nodes.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 October 2008
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    William Gordon,
%    Blending-Function Methods of Bivariate and Multivariate Interpolation
%    and Approximation,
%    SIAM Journal on Numerical Analysis,
%    Volume 8, Number 1, March 1971, pages 158-177.
%
%    William Gordon and Charles Hall,
%    Transfinite Element Methods: Blending-Function Interpolation over
%    Arbitrary Curved Element Domains,
%    Numerische Mathematik,
%    Volume 21, Number 1, 1973, pages 109-129.
%
%    William Gordon and Charles Hall,
%    Construction of Curvilinear Coordinate Systems and Application to
%    Mesh Generation,
%    International Journal of Numerical Methods in Engineering,
%    Volume 7, 1973, pages 461-477.
%
%    Joe Thompson, Bharat Soni, Nigel Weatherill,
%    Handbook of Grid Generation,
%    CRC Press, 1999.
%
%  Parameters:
%
%    Input, real R, S, T, the (R,S,T) coordinates of the point
%    to be evaluated.
%
%    Input, integer N, the dimension of the vector space.
%
%    External, BOUND_RST, is a function which is given (R,S,T)
%    coordinates and an component value I, and returns XI, the value
%    of the I-th component of the N-vector at that point.  BOUND_RST
%    will only be called for "faces", that is, for values (R,S,T) where
%    at least one of R, S and T is either 0.0 or 1.0.  BOUND_RST has
%    the form:
%      function xi = bound_rst ( r, s, t, i )
%
%    Output, real X(N), the interpolated value at the
%    point (R,S,T).
%
  for i = 1 : n
%
%  Get the I-th coordinate component at the corners.
%
    x000 = bound_rst ( 0.0, 0.0, 0.0, i );
    x001 = bound_rst ( 0.0, 0.0, 1.0, i );
    x010 = bound_rst ( 0.0, 1.0, 0.0, i );
    x011 = bound_rst ( 0.0, 1.0, 1.0, i );
    x100 = bound_rst ( 1.0, 0.0, 0.0, i );
    x101 = bound_rst ( 1.0, 0.0, 1.0, i );
    x110 = bound_rst ( 1.0, 1.0, 0.0, i );
    x111 = bound_rst ( 1.0, 1.0, 1.0, i );
%
%  Get the I-th coordinate component at the edges.
%
    xr00 = bound_rst ( r, 0.0, 0.0, i );
    xr01 = bound_rst ( r, 0.0, 1.0, i );
    xr10 = bound_rst ( r, 1.0, 0.0, i );
    xr11 = bound_rst ( r, 1.0, 1.0, i );

    x0s0 = bound_rst ( 0.0, s, 0.0, i );
    x0s1 = bound_rst ( 0.0, s, 1.0, i );
    x1s0 = bound_rst ( 1.0, s, 0.0, i );
    x1s1 = bound_rst ( 1.0, s, 1.0, i );

    x00t = bound_rst ( 0.0, 0.0, t, i );
    x01t = bound_rst ( 0.0, 1.0, t, i );
    x10t = bound_rst ( 1.0, 0.0, t, i );
    x11t = bound_rst ( 1.0, 1.0, t, i );
%
%  Get the I-th component on the faces.
%
    x0st = bound_rst ( 0.0, s, t, i );
    x1st = bound_rst ( 1.0, s, t, i );
    xr0t = bound_rst ( r, 0.0, t, i );
    xr1t = bound_rst ( r, 1.0, t, i );
    xrs0 = bound_rst ( r, s, 0.0, i );
    xrs1 = bound_rst ( r, s, 1.0, i );
%
%  Interpolate the I-th coordinate component of the interior point.
%
    x(i) = blend_123 ( r, s, t, x000, x001, x010, x011, x100, x101, x110, x111, ...
      xr00, xr01, xr10, xr11, x0s0, x0s1, x1s0, x1s1, x00t, x01t, x10t, x11t, ...
      x0st, x1st, xr0t, xr1t, xrs0, xrs1 );

  end

  return
end


function brnd = betarand(a,b,r,c)
%  BETARAND Random matrices from beta distribution.
%     R = BETARAND(A,B) returns an array of random numbers chosen from the
%     beta distribution with parameters A and B.  The size of R is the common
%     size of A and B if both are arrays.  If either parameter is a scalar,
%     the size of R is the size of the other parameter.
%
%     R = BETARAND(A,B,M,N) returns an M-by-N matrix.

% Copyright (c) 1995-1997, 2005-2007 Kurt Hornik

% This software is distributed under the GNU General Public
% License (version 3 or later); please refer to the file
% License.txt, included with the software, for details.
if (nargin > 1)
  if (~isscalar(a) || ~isscalar(b))
    if (size(a,1) ~= size(b,1))
      error ('betarnd: a and b must be of common size or scalar');
    end
  end
end

if (nargin == 4)
  if (~(isscalar(r) && (r > 0) && (r == round(r))))
    error ('betarnd: r must be a positive integer');
  end
  if (~(isscalar (c) && (c > 0) && (c == round (c))))
    error ('betarnd: c must be a positive integer');
  end
  sz = [r, c];

  if (any (size (a) ~= 1) && (length (size (a)) ~= length (sz) || any (size (a) ~= sz)))
    error ('betarnd: a and b must be scalar or of size [r,c]');
  end
elseif (nargin == 3)
  if (isscalar (r) && (r > 0))
    sz = [r, r];
  elseif (isvector(r) && all (r > 0))
    sz = r(:)';
  else
    error ('betarnd: r must be a positive integer or vector');
  end

  if (any (size (a) ~= 1) && (length (size (a)) ~= length (sz) || any (size (a) ~= sz)))
    error ('betarnd: a and b must be scalar or of size sz');
  end
elseif (nargin == 2)
  sz = size(a);
else
  error('must provide atleast 2 parameters')
end

if (isscalar(a) && isscalar(b))
  if (find ((a < 0) | isinf(a) | (b < 0) | isinf(b)))
    brnd = NaN * ones (sz);
  else
    r1 = gamrand(a,2.*a,sz(1),sz(2));
    brnd = r1 ./ (r1 + gamrand(b,2.*b,sz(1),sz(2)));
  end
else
  brnd = zeros (sz);

  k = find ((a < 0) | isinf(a) | (b < 0) | isinf(b));
  if (any (k))
    brnd(k) = NaN * ones (size (k));
  end

  k = find ((a > 0) & (a < Inf) & (b > 0) & (b < Inf));
  if (any (k))
    r1 = gamrnd(a(k),1,size(k,1),size(k,2));
    brnd(k) = r1 ./ (r1 + gamrnd(b(k),1,size(k,1),size(k,2)));
  end
end

end


% LFBuild4DFreqHyperfan - construct a 4D hyperfan passband filter in the frequency domain
%
% Usage:
%
%     [H, FiltOptions] = LFBuild4DFreqHyperfan( LFSize, Slope1, Slope2, BW, FiltOptions )
%     H = LFBuild4DFreqHyperfan( LFSize, Slope1, Slope2, BW )
%
% This file constructs a real-valued magnitude response in 4D, for which the passband is a hyperfan.
% This is useful for selecting objects over a range of depths from a lightfield, i.e. volumetric
% focus.
%
% Once constructed the filter must be applied to a light field, e.g. using LFFilt4DFFT. The
% LFDemoBasicFilt* files demonstrate how to contruct and apply frequency-domain filters.
%
% A more technical discussion, including the use of filters for denoising and volumetric focus, and
% the inclusion of aliases components, is included in:
%
% [2] D.G. Dansereau, O. Pizarro, and S. B. Williams, "Linear Volumetric Focus for Light Field
% Cameras," to appear in ACM Transactions on Graphics (TOG), vol. 34, no. 2, 2015.
%
% Inputs:
%
%     LFSize : Size of the frequency-domain filter. This should match or exceed the size of the
%     light field to be filtered. If it's larger than the input light field, the input is
%     zero-padded to match the filter's size by LFFilt4DFFT.
%
%     Slope : The slope of the planar passband. If different slopes are desired in s,t and u,v,
%     the optional aspect parameter should be used.
%
%     BW : 3-db Bandwidth of the planar passband.
%
%     [optional] FiltOptions : struct controlling filter construction
%            HyperfanMethod : 'sweep' or 'direct', controls how the hyperfan is constructed. 'sweep'
%                             concatenates frequency planes, while 'direct' evaluates a single 4D
%                             equation; default 'direct'. Warning: sweep can be very slow.
%               HyperconeBW : Sets the underlying hypercone's BW separately from the dual-fan,
%                             default is to use the BW parameter for both; only applies when
%                             HyperfanMethod is 'direct'
%               SlopeMethod : 'Skew' or 'Rotate' default 'skew'
%                 Precision : 'single' or 'double', default 'single'
%                   Rolloff : 'Gaussian' or 'Butter', default 'Gaussian'
%                     Order : controls the order of the filter when Rolloff is 'Butter', default 3
%                  Aspect4D : aspect ratio of the light field, default [1 1 1 1]
%                    Window : Default false. By default the edges of the passband are sharp; this adds
%                             a smooth rolloff at the edges when used in conjunction with Extent4D or
%                             IncludeAliased.
%                  Extent4D : controls where the edge of the passband occurs, the default [1 1 1 1]
%                             is the edge of the Nyquist box. When less than 1, enabling windowing
%                             introduces a rolloff after the edge of the passband. Can be greater
%                             than 1 when using IncludeAliased.
%            IncludeAliased : default false; allows the passband to wrap around off the edge of the
%                             Nyquist box; used in conjunction with Window and/or Extent4D. This can
%                             increase processing time dramatically, e.g. Extent4D = [2,2,2,2]
%                             requires a 2^4 = 16-fold increase in time to construct the filter.
%                             Useful when passband content is aliased, see [2].
%                SweepSteps : For HyperfanMethod 'sweep', how many steps to use in the sweep.
%
% Outputs:
%
%                 H : real-valued frequency magnitude response
%       FiltOptions : The filter options including defaults, with an added PassbandInfo field
%                     detailing the function and time of construction of the filter
%
% User guide: LFToolbox.pdf
% See also:  LFDemoBasicFiltGantry, LFDemoBasicFiltIllum, LFDemoBasicFiltLytroF01,
% LFBuild2DFreqFan, LFBuild2DFreqLine, LFBuild4DFreqDualFan, LFBuild4DFreqHypercone,
% LFBuild4DFreqHyperfan, LFBuild4DFreqPlane, LFFilt2DFFT, LFFilt4DFFT, LFFiltShiftSum

% Copyright (c) 2013-2020 Donald G. Dansereau

function [H, FiltOptions] = LFBuild4DFreqHyperfan( LFSize, Slope1, Slope2, BW, FiltOptions )

FiltOptions = LFDefaultField('FiltOptions', 'HyperfanMethod', 'Direct'); % 'Direct', 'Sweep'

switch( lower(FiltOptions.HyperfanMethod ))
	case 'sweep'
		FiltOptions = LFDefaultField('FiltOptions', 'SweepSteps', 5);
		SweepVec = linspace(Slope1, Slope2, FiltOptions.SweepSteps);
		[H, FiltOptions] = LFBuild4DFreqPlane( LFSize, SweepVec(1), BW, FiltOptions );
		for( CurSlope = SweepVec(2:end) )
			H = max(H, LFBuild4DFreqPlane( LFSize, CurSlope, BW, FiltOptions ));
		end

	case 'direct'
		FiltOptions = LFDefaultField('FiltOptions', 'HyperconeBW', BW);
		[H, FiltOptions] = LFBuild4DFreqHypercone( LFSize, FiltOptions.HyperconeBW, FiltOptions );
		[Hdf, FiltOptions] = LFBuild4DFreqDualFan( LFSize, Slope1, Slope2, BW, FiltOptions );
		H = H .* Hdf;

	otherwise
		error('Unrecognized hyperfan construction method');
end

TimeStamp = datestr(now,'ddmmmyyyy_HHMMSS');
FiltOptions.PassbandInfo = struct('mfilename', mfilename, 'time', TimeStamp, 'VersionStr', LFToolboxVersion);


function [path, j1, j2] = hmmViterbiCM(logpi, logA, logB)
% Find the most-probable (Viterbi) path through the HMM state trellis.
% logpi(j) = log of initial state distribution
% logA(i,j) = log of transition matrix
% logB(k,t) = log of soft evidence
% * we use log of inputs for compatability with .mex version *
% * called hmmViterbiC since Matlab has an hmmViterbi function already *
%%

% This file is from pmtk3.googlecode.com

pi = exp(logpi);
A = exp(logA);
B = exp(logB);

[K T] = size(B);
delta = zeros(K,T);
psi = zeros(K,T);
path = zeros(1,T);
t=1;
delta(:,t) = normalize(pi(:) .* B(:,t));
psi(:,t) = 0; % arbitrary value, since there is no predecessor to t=1
for t=2:T
    for j=1:K
        [delta(j,t), psi(j,t)] = max(delta(:,t-1) .* A(:,j));
        delta(j,t) = delta(j,t) * B(j,t);
    end
    delta(:,t) = normalize(delta(:,t));
end

% Traceback
[p, path(T)] = max(delta(:,T));
for t=T-1:-1:1
    path(t) = psi(path(t+1),t+1);
end

j1 = []; % for .mex compatability
j2 = [];
end


function [ x, status ] = p00_newton ( problem, option, nvar, x, par_index )

%*****************************************************************************80
%
%% P00_NEWTON applies Newton's method to an approximate root.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer PROBLEM, the problem index.
%
%    Input, integer OPTION, the option index.
%
%    Input, integer NVAR, the number of variables.
%
%    Input, real X(NVAR), the starting point of Newton's method.
%
%    Input, integer PAR_INDEX, the index of the parameter to be held fixed.
%    This variable should be between 1 and NVAR.  However, the user can
%    set it to 0, indicating that the program should make an intelligent
%    choice for the index.
%
%    Output, real X(NVAR), an improved estimate of the root of F(X)=0.
%
%    Output, integer STATUS, the status of the iteration.
%    -3, the full number of steps was taken without convergence.
%        (however, the output X might be CLOSE to a good solution).
%    -2, the iteration seemed to be diverging, and was halted.
%    -1, the jacobian was singular, and the iteration was halted.
%     nonnegative, the convergence test was satisfied, and this is the
%        number of steps taken (possibly 0).
%
  COND_MAX = 1.0E+10;
  FX_ABS_TOL = 0.000001;
  IT_MAX = 20;
  VERBOSE = 0;

  x = x(:);

  if ( par_index < 1 | nvar < par_index )
    par_index = p00_par_index ( problem, option, nvar, x );
    if ( VERBOSE )
      fprintf ( 1, '\n' );
      fprintf ( 1, '  Iteration will hold index %d fixed.\n', par_index );
    end
  end
  par_value = x(par_index);

  if ( VERBOSE )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'P00_NEWTON\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '      Step    ||F(X)||\n' );
    fprintf ( 1, '\n' );
  end

  for it = 0 : IT_MAX
%
%  Compute the function value.
%
    fx = p00_fun ( problem, option, nvar, x );
    fx(nvar) = x(par_index) - par_value;
%
%  Compute the norm of the function value.
%
    fx_max = max ( abs ( fx(1:nvar) ) );

    if ( VERBOSE )
      fprintf ( 1, '  %8d  %14e\n', it, fx_max );
    end

    if ( it == 0 )
      fx_max_init = fx_max;
    end
%
%  If the function norm is small enough, return.
%
    if ( abs ( fx_max ) < FX_ABS_TOL )
      status = it;
      break
    end
%
%  If the function norm seems to be exploding, halt.
%
    if ( 1000.0 * fx_max_init < abs ( fx_max ) )
      status = -2;
      break
    end

    if ( it == IT_MAX )
      status = -3;
      break
    end
%
%  Compute the jacobian.
%
    jac = p00_jac ( problem, option, nvar, x );

    jac(nvar,1:nvar) = 0.0;
    jac(nvar,par_index) = 1.0;
%
%  Solve the system JAC * DX = - FX
%
    if ( cond ( jac ) < COND_MAX )
      dx = - jac \ fx;
    else
      if ( VERBOSE )
        fprintf ( 1, '  (Using pseudoinverse.)\n' );
      end
      dx = - pinv ( jac ) * fx;
    end
%
%  Update X = X - DX.
%
    x(1:nvar) = x(1:nvar) + dx(1:nvar);

  end

  return
end


function iOut = iVals(trialOrder,ignoreNulls);
% iOut = iVals(trialOrder,ignoreNulls);
% iVals: Calculate i-value (intervening trials) for fMR-A Expts (but maybe more generally useful).
%
% Here's the idea: trialOrder is an array of numbers, generally with values that are repeated.
% The i-value of each element counts the number of intervening entries between repeated values.
% If the value for a given element in trialOrder has not occurred before in trialOrder, i = -1.
% If the value has occurred immediately before the current element, i = 0;
% If the value last occurred two elements before, i = 1 (one element between repetitions), and so on.
%
% So if trialOrder is:
%
% 1 1 2 1 3 3 1 1 1 2
%
% nOut will be:
%
% -1 0 -1 1 -1 -1 2 0 0 6
%
% If ignoreNulls is set to 1, iOut will ignore intervening elements with a value of 0 in counting
% (e.g., 1 0 0 1 will have an iOut of -1 -1 -1 0 instead of -1 -1 0 2).
%
% 1/03 by ras.
% 10/03 ras: updated to work with matrices. If a matrix is passed, it will run through eac
% row and get the ivals.
if ~exist('ignoreNulls','var')	ignoreNulls = 0;		end

if size(trialOrder,1) > 1 & size(trialOrder,2) > 1
	iOut = [];
	for i = 1:size(trialOrder,1)
		iOut = [iOut; iVals(trialOrder(i,:))];
	end
	return
end

if ignoreNulls
	nonNulls = find(trialOrder~=0);
	nulls = find(trialOrder==0);
	fullOrder = trialOrder;
	trialOrder = trialOrder(nonNulls);
end

for i = 1:length(trialOrder)
	currVal = trialOrder(i);
	ind = find(trialOrder==currVal);
	if ind(1)==i
		iOut(i) = -1;
	else
		loc = find(ind==i);
		lastInstance = ind(loc-1);
		iOut(i) = i - lastInstance - 1;
	end
end

if ignoreNulls
	tmp = iOut;
	iOut = zeros(1,length(fullOrder));
	iOut(nonNulls) = tmp;
	iOut(nulls) = -1;
end

return


function Ainv = incremental_invert(Pinv,Q,S)
%
%   Computes the new inverse of a symmetric matrix from an old submatrix inverse and the new parts.
%
%   So if   A = [P,Q;Q',S] incremental_invert gets inv(P) , Q and S and
%   returns inv(A)
%
%

if isempty(S) && isempty(Q)
    Ainv = Pinv; return
end

Qt = Q';
M = S-Qt*Pinv*Q;
Minv = pinv(M);

Ptmp = Pinv + Pinv*Q*Minv*Qt*Pinv;
Qtmp = -Pinv*Q*Minv;

Ainv = [Ptmp,Qtmp;Qtmp',Minv];


% This is material illustrating the methods from the book
% Financial Modelling  - Theory, Implementation and Practice with Matlab
% source
% Wiley Finance Series
% ISBN 978-0-470-74489-5
%
% Date: 02.05.2012
%
% Authors:  Joerg Kienitz
%           Daniel Wetterau
%
% Please send comments, suggestions, bugs, code etc. to
% kienitzwetterau_FinModelling@gmx.de
%
% (C) Joerg Kienitz, Daniel Wetterau
%
% Since this piece of code is distributed via the mathworks file-exchange
% it is covered by the BSD license
%
% This code is being provided solely for information and general
% illustrative purposes. The authors will not be responsible for the
% consequences of reliance upon using the code or for numbers produced
% from using the code.

clear; clc;
%% Parameters
S = 100;                                   % Spot prices
T = 5;      % maturities

r = 0;                      % discount factors
d = 0;                              % dividends

titS = 'MC NIG CIR - Asset Paths';

legend_base = 'Base scenario';

alpha = 10;
beta = -3;                            % CEV exponent base scenario
delta = 1;
mu = 0;
lambda = 2;
kappa = 1;
eta = 0.5;

%% Simulation parameters
NTime = 120; NSim = 1; NBatches = 1;
NTime_clock = 10;
K = ones(NTime+1,1);
K = T*cumsum(K)/(NTime+1);
K1 = K(2:end);

rstream = RandStream('mt19937ar','Seed',12345);
rstreamstate = rstream.State;

PathS = MC_NIGCIR(S,r,d,T,alpha,beta,delta,kappa,eta,lambda,NTime,NSim,NBatches);
%% Changing lambda
lambda_low = 1;
lambda_high = 3;

    rstream.State = rstreamstate;
    PathS_low = MC_NIGCIR(S,r,d,T,alpha,beta,delta,kappa,eta,lambda_low,NTime,NSim,NBatches);
    rstream.State = rstreamstate;
    PathS_high = MC_NIGCIR(S,r,d,T,alpha,beta,delta,kappa,eta,lambda_high,NTime,NSim,NBatches);

legend_low = 'Changing \lambda low';
legend_high = 'Changing \lambda high';

createfigure_path(K,PathS_low, PathS, PathS_high, titS, legend_low, legend_base, legend_high);

% calculate the returns
ReturnsS1_low = calcreturns(PathS_low,0);
ReturnsS1 = calcreturns(PathS,0);
ReturnsS1_high = calcreturns(PathS_high,0);

createfigure_returns(K1,ReturnsS1_low, ReturnsS1, ReturnsS1_high, titS, legend_low, legend_base, legend_high);

%% Changing kappa
kappa_low = 0.5;
kappa_high = 2;

    rstream.State = rstreamstate;
    PathS_low = MC_NIGCIR(S,r,d,T,alpha,beta,delta,kappa_low,eta,lambda,NTime,NSim,NBatches);
    rstream.State = rstreamstate;
    PathS_high = MC_NIGCIR(S,r,d,T,alpha,beta,delta,kappa_high,eta,lambda,NTime,NSim,NBatches);

legend_low = 'Changing \kappa low';
legend_high = 'Changing \kappa high';

createfigure_path(K,PathS_low, PathS, PathS_high, titS, legend_low, legend_base, legend_high);

% calculate the returns
ReturnsS1_low = calcreturns(PathS_low,0);
ReturnsS1 = calcreturns(PathS,0);
ReturnsS1_high = calcreturns(PathS_high,0);

createfigure_returns(K1,ReturnsS1_low, ReturnsS1, ReturnsS1_high, titS, legend_low, legend_base, legend_high);

%% Changing eta
eta_low = 0.25;
eta_high = 0.75;

    rstream.State = rstreamstate;
    PathS_low = MC_NIGCIR(S,r,d,T,alpha,beta,delta,kappa,eta_low,lambda,NTime,NSim,NBatches);
    rstream.State = rstreamstate;
    PathS_high = MC_NIGCIR(S,r,d,T,alpha,beta,delta,kappa,eta_high,lambda,NTime,NSim,NBatches);

legend_low = 'Changing \eta low';
legend_high = 'Changing \eta high';

createfigure_path(K,PathS_low, PathS, PathS_high, titS, legend_low, legend_base, legend_high);

% calculate the returns
ReturnsS1_low = calcreturns(PathS_low,0);
ReturnsS1 = calcreturns(PathS,0);
ReturnsS1_high = calcreturns(PathS_high,0);

createfigure_returns(K1,ReturnsS1_low, ReturnsS1, ReturnsS1_high, titS, legend_low, legend_base, legend_high);

clear; clc;


% Create some data.  First pick out the test dimensions, and the locations
% of some files.
D = 4;
PythonCmd = 'python2.6';
LSHCmd = 'lsh.py';
tmpFile = '/tmp/lshtest.out';
tmpFile2 = '/tmp/lshtest.out2';
subPlots = 1;

%%
% Now run the python command to create the data.
cmd = sprintf('%s %s -d %d -create', PythonCmd, LSHCmd, D);
fprintf('Running the command: %s\n', cmd);
system(cmd);
%%
% Now run the python command to measure the distance data
cmd = sprintf('%s %s -d %d -histogram', PythonCmd, LSHCmd, D);
fprintf('Running the command: %s\n', cmd);
system(cmd);
%%
% Load in the distance data and calculate the distance histograms.
testData = load(sprintf('testData%03d.distances', D));
nBins = 40;
[dnnHist, dnnBins] = hist(testData(:,1), nBins);
[danyHist, danyBins] = hist(testData(:,2), nBins);
if subPlots
    subplot(2,2,1);
end
plot(dnnBins, dnnHist, danyBins, danyHist);
legend('Nearest Neighbor', 'Any Neighbor');
xlabel('Distance')
ylabel('Frequency of Occurance');
title(sprintf('Distance Histogram for %d-D data', D));
%%
% Now calculate the optimum LSH parameters.
N=100000;
deltaTarget = 0.5;
r = 0;
uHash = 1;
uCheck = 1;
results = CalculateMPLSHParameters(N, ...
    dnnHist, dnnBins, danyHist, danyBins, deltaTarget, r, uHash, uCheck);
%%
% Now let's run the W test.
w = results.exactW;
cmd = sprintf('%s %s -d %d -w %g -wTest > %s', PythonCmd, LSHCmd, ...
    D, w, tmpFile);
fprintf('Running the command: %s\n', cmd);
system(cmd);

%%
% And load the W-test results.
cmd = sprintf('egrep -v "[a-zA-Z]" %s | tail -20 > %s', tmpFile, tmpFile2);
[s,res] = system(cmd);
wTest = load(tmpFile2);

%%
% And now create the w-test plot.
if subPlots
    subplot(2,2,2);
end

semilogx(results.wList/results.dScale, results.binNnProb, ...
    wTest(:,1), wTest(:,2), 'bx', ...
    results.wList/results.dScale, results.binAnyProb, ...
    wTest(:,1), wTest(:,3), 'gx', ...
    [results.exactW, results.exactW], [0 1], 'r--');

xlabel('W');
ylabel('Probability of Collision');
legend('p_{nn}', 'p_{nn} experimental', ...
    'p_{any}', 'p_{any} experimental', ...
    'Optimum W', ...
    'Location', 'SouthEast');
title(sprintf('wTest for %d-D data', D));

%%
% Now let's run the K test
cmd = sprintf('%s %s -d %d -w %g -kTest > %s', PythonCmd, LSHCmd, ...
    D, w, tmpFile);
fprintf('Running the command: %s\n', cmd);
system(cmd);

%%
% And grab the K-test results.
cmd = sprintf('grep " 10 " %s > %s', tmpFile, tmpFile2);
system(cmd);
kTest = load(tmpFile2);

%%
% Now plot the k-test results.
if subPlots
    subplot(2,2,3);
end

semilogy(kTest(:,2), kTest(:,4), 'bx', ...
    kTest(:,2), kTest(1,4).^kTest(:,2), 'g-', ...
    kTest(:,2), ...
        results.binNnProb(results.exactBin).^kTest(:,2), 'r--');
xlabel('Number of Projections (K)');
ylabel('Probability');
legend('Experimental Data', 'Extrapolated Prediction', ...
    'Theoretical Prediction', 'Location', 'SouthWest');
title(sprintf('kTest for %d-D data', D));

%%
% Now let's run the L test.
cmd = sprintf('%s %s -d %d -w %g -lTest > %s', PythonCmd, LSHCmd, ...
    D, w, tmpFile);
fprintf('Running the command: %s\n', cmd);
system(cmd);

%%
% And grab the L-test results
cmd = sprintf('grep " 10 " %s > %s', tmpFile, tmpFile2);
system(cmd);
lTest = load(tmpFile2);

%%
% Now plot the results.
if subPlots
    subplot(2,2,4);
end

baseNN = results.binNnProb(results.exactBin).^lTest(1,2);
baseAny = results.binAnyProb(results.exactBin).^lTest(1,2);
semilogy(lTest(:,3), lTest(:,4), 'rx',  ...
    lTest(:,3), lTest(:,5), 'kx', ...
    lTest(:,3), (1-(1-baseNN).^lTest(:,3)), ...
    lTest(:,3), (1-(1-baseAny).^lTest(:,3)), ...
    lTest(:,3), (1-(1-kTest(8,4)).^lTest(:,3)), ...
    lTest(:,3), (1-(1-kTest(8,5)).^lTest(:,3)));

legend('p_{nn} Experimental', 'p_{any} Experimental', ...
    'p_{nn} Theory', 'p_{any} Theory',...
    'p_{nn} k-Prediction', 'p_{any} k-Prediction', ...
    'Location', 'SouthEast');
xlabel('Number of Tables (L)');
ylabel('Probability');
title(sprintf('kTest for %d-D data', D));

%%
save TestLSHCode wTest lTest kTest results D subplots ...
    dnnHist dnnBins danyHist danyBins

%%
% set(gcf,'Position', [100 100 900 800])
pictureFile = sprintf('TestLSHCode-%s.eps', date);
print('-depsc', pictureFile);


function node = meshsmoothing(node,elem,step,rho,method,fixedNode)
%% MESHSMOOTHING improves the geometric mesh quality
%
% node = meshsmoothing(node,elem) improves shape regularity of
% triangles while keeping the density of vertices.
%
% node = meshsmoothing(node,elem,m) performs m steps mesh smoothing.
% The default setting is m=3.
%
% node = meshsmoothing(node,elem,m,rho) accept a non-uniform density
% given by elementwise function rho. The default choice rho = 1/|t|. The
% quasi-uniform grids corresponds to rho=1. The density function rho can be
% given by a user specified function or a posteriori error estimator in the
% setting of adaptive finite element method.
%
% node = meshsmoothing(node,elem,m,rho,method,fixedNode) accept the
% extra input arguments method and fixedNode. The string |method| is to
% specify the smoothing method: either 'CPT' or 'ODT'. The fixedNode array
% will fix certain nodes, e.g., vertices on a interface. The boundary nodes
% of the mesh will be automatically considered as fixed.
%
% The function meshsmoothing will keep the topology of the input mesh,
% i.e., the node index and connectivity of nodes are unchanged. In
% contrast, the edgeswap function will keep the node but change elem.
%
% The algorithm implemented is the simplified version of ODT smoothing; see
% ODTmesh.
%
% Example:
%     load airfoilperturbmesh
%     meshquality(node,elem);
%     node = meshsmoothing(node,elem);
%     meshquality(node,elem);
%
% See also  optmesh, bdsmoothing, edgeswap, rmisopoint
%
% Copyright (C) Long Chen. See COPYRIGHT.txt for details.

if ~exist('step','var'), step = 3; end
if ~exist('method','var'), method = 'ODT'; end

%% Smooth boundary nodes
% [node,elem,bdNode] = bdsmoothing(node,elem);

%% Find boundary and interior ndoes
[bdNode,bdEdge,isBdNode,isBdElem] = findboundary(elem); %#ok<*ASGLU>
N = size(node,1);  NT = size(elem,1);

%% Compute mesh quality associated to elements and nodes
qt = 1 - simpqual(node,elem);
qtp = sparse([1:NT,1:NT,1:NT], elem(1:NT,:), [qt, qt, qt], NT, N);
qp = max(qtp);
qp = qp' + 0.01*rand(N,1);  % break the equal case
qp(bdNode) = 0;             % do not include bdNode and fixed nodes
if exist('fixedNode','var'), qp(fixedNode) = 0; end

%% Decompose nodes into independent sets
t2p = sparse([1:NT,1:NT,1:NT], elem(1:NT,:), 1, NT, N);
A = t2p'*t2p;  % connectness of nodes
nodeSet = coloring(A,5,qp);

%% Move nodes one by one
for m = 1:step
    for k = 1:5
        % find elements containing nodeSet
        movingNode = nodeSet{k};
        if isempty(movingNode)
            break;
        end
        [i,j] = find(t2p(:,movingNode)); %#ok<*NASGU>
        idx = false(NT,1);
        idx(i) = true;
        idx = find(idx);
        % compute centers and areas
        switch upper(method)
          case 'CPT'
               center = (node(elem(idx,1),:)+node(elem(idx,2),:)+node(elem(idx,3),:))/3;
          case 'ODT'
               center = circumcenter(node,elem(idx,:));
               % modification neary boundary elements: using barycenter to replace circumcenter
               center(isBdElem(idx),:) = (node(elem(idx(isBdElem(idx)),1),:) ...
                                        + node(elem(idx(isBdElem(idx)),2),:) ...
                                        + node(elem(idx(isBdElem(idx)),3),:))/3;
        end
        % compute the weight
        if exist('rho','var') && ~isempty(rho)
            weight = simplexvolume(node,elem(idx,:));
            if (rho~=1)
                weight = rho(idx).*weight;
            end
        end
        % update to new averaging center
        oldpi = node(movingNode,:);     % keep the location before moving
        if exist('rho','var') && ~isempty(rho) % weighted average
            newnode(:,1) = accumarray([elem(idx,1);elem(idx,2);elem(idx,3)],...
                                repmat(weight.*center(:,1),3,1),[N,1]);
            newnode(:,2) = accumarray([elem(idx,1);elem(idx,2);elem(idx,3)],...
                                repmat(weight.*center(:,2),3,1),[N,1]);
            valence = accumarray([elem(idx,1);elem(idx,2);elem(idx,3)], ...
                                 [weight; weight; weight],[N 1]);
        else % simple average of centers
            newnode(:,1) = accumarray([elem(idx,1);elem(idx,2);elem(idx,3)],...
                                      [center(:,1);center(:,1);center(:,1)],[N,1]);
            newnode(:,2) = accumarray([elem(idx,1);elem(idx,2);elem(idx,3)],...
                                      [center(:,2);center(:,2);center(:,2)],[N,1]);
            valence = accumarray([elem(idx,1);elem(idx,2);elem(idx,3)],...
                                  ones(3*length(idx),1),[N 1]);
        end
        node(movingNode,:) = newnode(movingNode,:)./[valence(movingNode) valence(movingNode)];
        % check if the moving is valid
        ve2 = node(elem(idx,1),:)-node(elem(idx,3),:);
        ve3 = node(elem(idx,2),:)-node(elem(idx,1),:);
        area = 0.5*(-ve3(:,1).*ve2(:,2)+ve3(:,2).*ve2(:,1));
        invalidElem = idx(area<0);
        if any(invalidElem)
            isNotmoving = false(N,1);
            isNotmoving(elem(invalidElem,:)) = true;
            pidx = isNotmoving(movingNode);
            node(movingNode(pidx),:) = oldpi(pidx,:);
        end
    end
end


classdef prtKernelRbfNeighborhoodScaled < prtKernel
    % prtKernelRbfNeighborhoodScaled  Radial basis function kernel where
    % each entry is scaled according to the distance to neighbors in the
    % training set.
    %
    %  KERNOBJ = prtKernelRbfNeighborhoodScaled Generates a kernel object
    %  implementing a radial basis function.  Kernel objects are widely
    %  used in several prt classifiers, such as prtClassRvm and
    %  prtClassSvm.  RBF kernels implement the following function for 1 x N
    %  vectors x1 and x2:
    %
    %   k(x1,x2) = exp(-sum((x1-x2).^2)./sigma1.^2);
    %
    %  sigma1 is learned based on the neighboord of the data in
    %  feature space.
    %
    %  KERNOBJ = prtKernelRbfNeighborhoodScaled(PROPERTY1, VALUE1, ...) constructs a
    %  prtKernelRbfNeighborhoodScaled object KERNOBJ with properties as specified by
    %  PROPERTY/VALUE pairs. prtKernelRbfNeighborhoodScaled objects have the following
    %  user-settable properties:
    %
    %   neighborhoodPercentile - Quantile distance that is used to define
    %       the neighboorhood. THis is a value between 1 and 100. Smaller
    %       values will make more local kernels. (Default value is 5)
    %
    %   prtKernelRbf objects inherit the TRAIN and RUN methods from prtKernel.
    %
    %   % Example
    %   ds = prtDataGenMoon;                     % Generate a dataset
    %   k1 = prtKernelRbfNeighborhoodScaled;    % Create a prtKernel object with
    %                                            % default value of neighborhoodPercentile
    %   k2 = prtKernelRbfNeighborhoodScaled('neighborhoodPercentile',2); % Create a prtKernel object with
    %                                                                     % the specified value of neighborhoodPercentile
    %
    %   k1 = k1.train(ds); % Train
    %   g1 = k1.run(ds); % Evaluate
    %
    %   k2 = k2.train(ds); % Train
    %   g2 = k2.run(ds); % Evaluate
    %
    %   subplot(2,1,1); imagesc(g1.getObservations);  %Plot the results
    %   subplot(2,1,2); imagesc(g2.getObservations);
    %
    %   See also: prtKernel,prtKernelSet, prtKernelDc, prtKernelRbf, prtKernelDirect,
    %   prtKernelHyperbolicTangent, prtKernelPolynomial,
    %   prtKernelRbfNdimensionScale,

    properties (SetAccess = private)
        name = 'RBF Kernel Scaled'; % RBF Kernel Scaled
        nameAbbreviation = 'RBF'; % RBF
    end

    properties
        neighborhoodPercentile = 5;
        sigmas = []; % The inverse kernel width for each dimension
    end

    methods (Access = protected, Hidden = true)
        function Obj = trainAction(Obj,ds)
            Obj.internalDataSet = ds;

            D = prtDistanceEuclidean(ds,ds);
            D = sort(D,'ascend');

            nPointsAway = min(max(round(size(D,1)*Obj.neighborhoodPercentile/100),1),size(D,1));

            Obj.sigmas = sqrt(D(nPointsAway,:))';
            Obj.sigmas(Obj.sigmas<=0) = 1; % Put weird values to 1

            Obj.isTrained = true;
        end

        function dsOut = runAction(Obj,ds)
            if ~Obj.isTrained
                error('prtKernelRbfNeighboorhoodScaled:run','Attempt to run an untrained kernel; use kernel.train(ds) to train');
            end
            if Obj.internalDataSet.nObservations == 0
                dsOut = prtDataSetClass;
            else
                gram = prtKernelRbfNeighborhoodScaled.kernelFn(ds.getObservations,Obj.internalDataSet.getObservations,Obj.sigmas);
                dsOut = ds.setObservations(gram);
            end
        end
    end

    methods
        function Obj = prtKernelRbfNeighborhoodScaled(varargin)
            Obj = prtUtilAssignStringValuePairs(Obj,varargin{:});
        end
    end

    methods(Hidden = true)
        function Obj = retainKernelDimensions(Obj,keepLogical)
            Obj.sigmas = Obj.sigmas(keepLogical);
            Obj = retainKernelDimensions@prtKernel(Obj,keepLogical);
        end

        function varargout = plot(obj)
            x = obj.internalDataSet.getObservations;

            if size(x,2) <= 3
                if size(x,2) == 1 && obj.internalDataSet.isLabeled
                    xy = cat(2,x,obj.internalDataSet.getTargets);
                    h = prtPlotUtilScatter(xy, {}, obj.plotOptions.symbol, obj.plotOptions.markerFaceColor, obj.plotOptions.color, obj.plotOptions.symbolLineWidth, obj.plotOptions.symbolSize);
                else
                    h = prtPlotUtilScatter(x, {}, obj.plotOptions.symbol, obj.plotOptions.markerFaceColor, obj.plotOptions.color, obj.plotOptions.symbolLineWidth, obj.plotOptions.symbolSize);
                end
            else
                h = nan;
            end

            varargout = {};
            if nargout
                varargout = {h};
            end
        end
    end

    methods (Static, Hidden = true)
        function gram = kernelFn(x,y,sigmas)
            [n1, d] = size(x);
            [n2, nin] = size(y);
            if d ~= nin
                error('size(x,2) must equal size(y,2)');
            end

            %dist2 = prtDistanceLNorm(x,y,2);
            dist2 = repmat(sum((x.^2), 2), [1 n2]) + repmat(sum((y.^2),2), [1 n1]).' - 2*x*(y.');

            if numel(sigmas) == 1
                gram = exp(-dist2/(sigmas.^2));
            else
                gram = exp(-bsxfun(@rdivide,dist2,(sigmas.^2)'));
            end
        end
    end
end


function [mGal] = mmps22mGal(mmps2)
% Convert acceleration from millimeters per square-second to milligalileos
% Chad A. Greene 2012
mGal = mmps2*1e+2;


function fused = Ying_2017_CAIP(I, mu, k, a, b) % camera a, b
%%
% @inproceedings{ying2017new,
%   title={A New Image Contrast Enhancement Algorithm Using Exposure Fusion Framework},
%   author={Ying, Zhenqiang and Li, Ge and Ren, Yurui and Wang, Ronggang and Wang, Wenmin},
%   booktitle={International Conference on Computer Analysis of Images and Patterns},
%   pages={36--46},
%   year={2017},
%   organization={Springer}
% }
%
% Please feel free to contact me (yingzhenqiang-at-gmail-dot-com) if you
% have any questions or concerns.

if  ~exist( 'mu', 'var' )
    mu = 0.5;
end

if ~exist( 'a', 'var' )
    a = -0.3293;
end

if ~exist( 'b', 'var' )
    b = 1.1258;
end

if ~isfloat(I)
    I = im2double( I );
end

lambda = 0.5;
sigma = 5;

%% t: scene illumination map
t_b = max( I, [], 3 ); % also work for single-channel image
t_our =  imresize( tsmooth( imresize( t_b, 0.5 ), lambda, sigma ), size( t_b ) );

%% k: exposure ratio
if  ~exist( 'k', 'var' ) || isempty(k)
    isBad = t_our < 0.5;
    J = maxEntropyEnhance(I, isBad);
else
    J = applyK(I, k, a, b); %k
    J = min(J, 1); % fix overflow
end

%% W: Weight Matrix
t = repmat(t_our, [1 1 size(I,3)]);
W = t.^mu;

I2 = I.*W;
J2 = J.*(1-W);

fused = I2 + J2;

    function J = maxEntropyEnhance(I, isBad)
        Y = rgb2gm(real(max(imresize(I, [50 50]), 0))); % max - avoid complex number

        if exist('isBad', 'var')
            isBad = (imresize(isBad, [50 50]));
            Y = Y(isBad);
        end

        if isempty(Y)
           J = I; % no enhancement k = 1
           return;
        end

        opt_k = fminbnd(@(k) ( -entropy(applyK(Y, k)) ),1, 7);
        J = applyK(I, opt_k, a, b) - 0.01;

    end
end

function I = rgb2gm(I)
if size(I,3) == 3
    I = im2double(max(0,I)); % negative double --> complex double
    I = ( I(:,:,1).*I(:,:,2).*I(:,:,3) ).^(1/3);
end
end

function J = applyK(I, k, a, b)

if ~exist( 'a', 'var' )
    a = -0.3293;
end

if ~exist( 'b', 'var' )
    b = 1.1258;
end

f = @(x)exp((1-x.^a)*b);
beta = f(k);
gamma = k.^a;
J = I.^gamma.*beta;
end

function S = tsmooth( I, lambda, sigma, sharpness)
if ( ~exist( 'lambda', 'var' ) )
    lambda = 0.01;
end
if ( ~exist( 'sigma', 'var' ) )
    sigma = 3.0;
end
if ( ~exist( 'sharpness', 'var' ) )
    sharpness = 0.001;
end
I = im2double( I );
x = I;
[ wx, wy ] = computeTextureWeights( x, sigma, sharpness);
S = solveLinearEquation( I, wx, wy, lambda );
end

function [ W_h, W_v ] = computeTextureWeights( fin, sigma, sharpness)

dt0_v = [diff(fin,1,1);fin(1,:)-fin(end,:)];
dt0_h = [diff(fin,1,2)';fin(:,1)'-fin(:,end)']';

gauker_h = filter2(ones(1,sigma),dt0_h);
gauker_v = filter2(ones(sigma,1),dt0_v);
W_h = 1./(abs(gauker_h).*abs(dt0_h)+sharpness);
W_v = 1./(abs(gauker_v).*abs(dt0_v)+sharpness);

end

function OUT = solveLinearEquation( IN, wx, wy, lambda )
[ r, c, ch ] = size( IN );
k = r * c;
dx =  -lambda * wx( : );
dy =  -lambda * wy( : );
tempx = [wx(:,end),wx(:,1:end-1)];
tempy = [wy(end,:);wy(1:end-1,:)];
dxa = -lambda *tempx(:);
dya = -lambda *tempy(:);
tempx = [wx(:,end),zeros(r,c-1)];
tempy = [wy(end,:);zeros(r-1,c)];
dxd1 = -lambda * tempx(:);
dyd1 = -lambda * tempy(:);
wx(:,end) = 0;
wy(end,:) = 0;
dxd2 = -lambda * wx(:);
dyd2 = -lambda * wy(:);

Ax = spdiags( [dxd1,dxd2], [-k+r,-r], k, k );
Ay = spdiags( [dyd1,dyd2], [-r+1,-1], k, k );

D = 1 - ( dx + dy + dxa + dya);
A = (Ax+Ay) + (Ax+Ay)' + spdiags( D, 0, k, k );

if exist( 'ichol', 'builtin' )
    L = ichol( A, struct( 'michol', 'on' ) );
    OUT = IN;
    for ii = 1:ch
        tin = IN( :, :, ii );
        [ tout, ~ ] = pcg( A, tin( : ), 0.1, 50, L, L' );
        OUT( :, :, ii ) = reshape( tout, r, c );
    end
else
    OUT = IN;
    for ii = 1:ch
        tin = IN( :, :, ii );
        tout = A\tin( : );
        OUT( :, :, ii ) = reshape( tout, r, c );
    end
end
end


function [EigenvectorsDiscrete,EigenVectors]=discretisation(EigenVectors)
%
% EigenvectorsDiscrete=discretisation(EigenVectors)
%
% Input: EigenVectors = continuous Ncut vector, size = ndata x nbEigenvectors
% Output EigenvectorsDiscrete = discrete Ncut vector, size = ndata x nbEigenvectors
%
% Timothee Cour, Stella Yu, Jianbo Shi, 2004

[n,k]=size(EigenVectors);

vm = sqrt(sum(EigenVectors.*EigenVectors,2));
EigenVectors = EigenVectors./repmat(vm,1,k);

R=zeros(k);
R(:,1)=EigenVectors(1+round(rand(1)*(n-1)),:)';
c=zeros(n,1);
for j=2:k
    c=c+abs(EigenVectors*R(:,j-1));
    [minimum,i]=min(c);
    R(:,j)=EigenVectors(i,:)';
end

lastObjectiveValue=0;
exitLoop=0;
nbIterationsDiscretisation = 0;
nbIterationsDiscretisationMax = 20;%voir
while exitLoop== 0
    nbIterationsDiscretisation = nbIterationsDiscretisation + 1 ;
    EigenvectorsDiscrete = discretisationEigenVectorData(EigenVectors*R);
    [U,S,V] = svd(EigenvectorsDiscrete'*EigenVectors,0);
    NcutValue=2*(n-trace(S));

    if abs(NcutValue-lastObjectiveValue) < eps | nbIterationsDiscretisation > nbIterationsDiscretisationMax
        exitLoop=1;
    else
        lastObjectiveValue = NcutValue;
        R=V*U';
    end
end


function [cor_ini, score_all] = sample_opt_pano(cor_id, im_w, im_h, corn, edg, edg2, options)

	score_all = 0;
        [wall_d, x, f] = pano_line_solver(cor_id, im_w, options); % bos-shape case
        cor_id_t = cor_id;
        d_m = 0;
        % initialization
        for j = 1:2:size(cor_id_t,1)
            theta_y = pi*cor_id_t(j+1,2)/im_h-pi/2;
            theta_y_ = pi/2 - pi*cor_id_t(j,2)/im_h;
            d = abs(cot(theta_y));
            d_m = d_m + d/wall_d((j+1)/2);
        end
        d_m = d_m/4;
        cor_ini = [];
        for j = 1:2:size(cor_id_t,1)
            line_d = d_m*wall_d((j+1)/2);
            line_theta_y = acot(line_d);
            line_y = (line_theta_y + pi/2)*im_h/pi;
            cor_ini = [cor_ini;cor_id_t(j,1) line_y];
            cor_ini = [cor_ini;cor_id_t(j,1) line_y];
        end

        score_btn = interp2(corn,cor_ini(2:2:end,1),cor_ini(2:2:end,2));
        score_btn = sum(log(score_btn));

        % add floor score
        cor_all = [cor_ini(2,:);cor_ini(4,:);cor_ini(4,:);cor_ini(6,:);
               cor_ini(6,:);cor_ini(8,:);cor_ini(8,:);cor_ini(2,:)];
    	[ uv ] = coords2uv( cor_all, im_w, im_h );
    	[ xyz ] = uv2xyzN( uv);
    	[ lines ] = lineFromTwoPoint( xyz(1:2:end,:), xyz(2:2:end,:) );
    	im = zeros(im_h, im_w, 3);
    	[ panoEdgeC ] = paintParameterLine_my(lines, im_w, im_h, im);
    	score_fl = zeros(1,4);
    	score_fl(1) = max(max(edg2(:,:,3).*(panoEdgeC(:,:,1) == 1)));
    	score_fl(2) = max(max(edg2(:,:,3).*(panoEdgeC(:,:,1) == 2)));
    	score_fl(3) = max(max(edg2(:,:,3).*(panoEdgeC(:,:,1) == 3)));
    	score_fl(4) = max(max(edg2(:,:,3).*(panoEdgeC(:,:,1) == 4)));
    	score_fl = sum(log(score_fl));
    	score_btn = score_btn + score_fl;

        % sampling
        % horizontal, bottoms
        d_m_max = d_m + d_m*0.1;
        d_m_min = d_m - d_m*0.1;
        score_best = -Inf;

        for j = d_m_min:d_m*0.02:d_m_max
            cor_opt = [];
            for k = 1:2:size(cor_id_t,1)
                line_d = j*wall_d((k+1)/2);
                line_theta_y = acot(line_d);
                line_y = (line_theta_y + pi/2)*im_h/pi;
                cor_opt = [cor_opt;cor_id_t(k,1) line_y];
            end
            % compute score
            score = interp2(corn,cor_opt(:,1),cor_opt(:,2));
            score = sum(log(score));

            cor_all = [cor_opt(1,:);cor_opt(2,:);cor_opt(2,:);cor_opt(3,:);
               cor_opt(3,:);cor_opt(4,:);cor_opt(4,:);cor_opt(1,:)];
    		[ uv ] = coords2uv( cor_all, im_w, im_h );
    		[ xyz ] = uv2xyzN( uv);
    		[ lines ] = lineFromTwoPoint( xyz(1:2:end,:), xyz(2:2:end,:) );
    		[ panoEdgeC ] = paintParameterLine_my(lines, im_w, im_h, im);
    		score_fl = zeros(1,4);
    		score_fl(1) = max(max(edg2(:,:,3).*(panoEdgeC(:,:,1) == 1)));
    		score_fl(2) = max(max(edg2(:,:,3).*(panoEdgeC(:,:,1) == 2)));
    		score_fl(3) = max(max(edg2(:,:,3).*(panoEdgeC(:,:,1) == 3)));
    		score_fl(4) = max(max(edg2(:,:,3).*(panoEdgeC(:,:,1) == 4)));
    		score_fl = sum(log(score_fl));
    		score = score + score_fl;

            if score > score_best
                score_best = score;
                cor_best = cor_opt;
                d_m_best = j;
            end
        end
        if score_best > score_btn
            cor_ini(2:2:end,:) = cor_best;
        else
           score_best = score_btn;
           d_m_best = d_m;
        end
        score_all = score_all + score_best;
        % horizontal, top
        h_m = 0;
        for j = 1:2:size(cor_id_t,1)
            theta_y_ = pi/2 - pi*cor_id_t(j,2)/im_h;
            d = d_m_best*wall_d((j+1)/2);
            h = d*tan(theta_y_);
            h_m = h_m + h;
        end
        h_m = h_m/4;
        for j = 1:2:size(cor_id_t,1)
            line_d = d_m_best*wall_d((j+1)/2);
            line_y_ = atan(h_m/line_d);
            line_y_ = (pi/2-line_y_)*im_h/pi;
            cor_ini(j,2) = line_y_;
        end
        score_tp = interp2(corn,cor_ini(1:2:end,1),cor_ini(1:2:end,2));
        score_tp = sum(log(score_tp));

        % add ceiling score
        cor_all = [cor_ini(1,:);cor_ini(3,:);cor_ini(3,:);cor_ini(5,:);
               cor_ini(5,:);cor_ini(7,:);cor_ini(7,:);cor_ini(1,:)];
    	[ uv ] = coords2uv( cor_all, im_w, im_h );
    	[ xyz ] = uv2xyzN( uv);
    	[ lines ] = lineFromTwoPoint( xyz(1:2:end,:), xyz(2:2:end,:) );
    	im = zeros(im_h, im_w, 3);
    	[ panoEdgeC ] = paintParameterLine_my(lines, im_w, im_h, im);
    	score_cl = zeros(1,4);

    	score_cl(1) = max(max(edg2(:,:,2).*(panoEdgeC(:,:,1) == 1)));
    	score_cl(2) = max(max(edg2(:,:,2).*(panoEdgeC(:,:,1) == 2)));
    	score_cl(3) = max(max(edg2(:,:,2).*(panoEdgeC(:,:,1) == 3)));
    	score_cl(4) = max(max(edg2(:,:,2).*(panoEdgeC(:,:,1) == 4)));
    	score_cl = sum(log(score_cl));
    	score_tp = score_tp + 0.5*score_cl;

        h_m_max = h_m + h_m*0.1;
        h_m_min = h_m - h_m*0.1;
        score_best = -Inf;
        for j = h_m_min:h_m*0.02:h_m_max
            cor_opt = [];
            for k = 1:2:size(cor_ini,1)
                line_d = d_m_best*wall_d((k+1)/2);
                line_y_ = atan(j/line_d);
                line_y_ = (pi/2-line_y_)*im_h/pi;
                cor_opt = [cor_opt;cor_ini(k,1) line_y_];
            end
            % compute score
            score = interp2(corn,cor_opt(:,1),cor_opt(:,2));
            score = sum(log(score));
            if 1
            % add ceiling score
        	cor_all = [cor_opt(1,:);cor_opt(2,:);cor_opt(2,:);cor_opt(3,:);
               	cor_opt(3,:);cor_opt(4,:);cor_opt(4,:);cor_opt(1,:)];
    		[ uv ] = coords2uv( cor_all, im_w, im_h );
    		[ xyz ] = uv2xyzN( uv);
    		[ lines ] = lineFromTwoPoint( xyz(1:2:end,:), xyz(2:2:end,:) );
    		im = zeros(im_h, im_w, 3);
    		[ panoEdgeC ] = paintParameterLine_my(lines, im_w, im_h, im);
    		score_cl = zeros(1,4);

    		score_cl(1) = max(max(edg2(:,:,2).*(panoEdgeC(:,:,1) == 1)));
    		score_cl(2) = max(max(edg2(:,:,2).*(panoEdgeC(:,:,1) == 2)));
    		score_cl(3) = max(max(edg2(:,:,2).*(panoEdgeC(:,:,1) == 3)));
    		score_cl(4) = max(max(edg2(:,:,2).*(panoEdgeC(:,:,1) == 4)));
    		score_cl = sum(log(score_cl));
    		score = score + 0.5*score_cl;
    	end

            if score > score_best
                score_best = score;
                cor_best = cor_opt;
                h_m_best = j;
            end
        end
        if score_best > score_tp
            cor_ini(1:2:end,:) = cor_best;
        else
            score_best = score_tp;
            h_m_best = h_m;
        end
        score_all = score_all + score_best;
end