function [ind,ind2,stats] = Gaussian_mix(x,niter,basepts,verbose,doplot, doplot2)
% Two-Gaussian mixture model
%
% :Usage:
% ::
%
%     [ind,ind2,stats] = Gaussian_mix(x,niter,basepts,verbose,doplot, doplot2)
%
% :Inputs:
%
%   **x:**
%        data
%
%   **iter:**
%        number of iterations
%
%   **basepts:**
%        number of baseline pts at start of run. The modal class in the
%        baseline period is defined as the 0-class
%
% :Outputs:
%
%   **ind:**
%        indicator function of class belonging
%
%   **ind2:**
%        indicator function of class belonging where 3 consecutive points
%        are needed to switch states
%
%   **mu:**
%        mean vector
%
%   **sigma:**
%        standard deviation
%
%   **p:**
%        probability that latent class random variable (delta) is equal
%        to [0,1]
%
% :Examples:
% ::
%
%    [ind,ind2,stats] = Gaussian_mix(linear_detrending(dat),20);
%    % dat is n subjects by t time points
%    % plotting is on
%
%    % Simulated data
%    r = normrnd(1, 1, 200, 1); r(1:50) = r(1:50) + normrnd(3, 1, 50, 1);
%    [ind, ind2, stats] = Gaussian_mix(r, 50, [], 0, 1);
%
% We recommend 50 iterations

% ..
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %
    % Set up inputs
    %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ..

    if ~(exist('doplot')==1) || isempty(doplot), doplot = 1; end
    if ~(exist('doplot2')==1) || isempty(doplot2), doplot2 = 1; end
    if ~(exist('verbose')==1) || isempty(verbose), verbose = 1; end
    if ~(exist('basepts')==1) || isempty(basepts), basepts = 1:length(x); end

    % make sure it's a column vector or vectors
    if size(x,1) ~= length(x), x = x'; end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %
    % Iterative mode
    %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    if size(x,2) > 1
        % multiple data vectors, run this function iteratively

        IND = []; IND2 = [];
        verbose = 0;
        if doplot, nrows = ceil(sqrt(size(x,2))); tor_fig(nrows,nrows); end

        for datavec = 1:size(x,2)
            if doplot, subplot(nrows,nrows,datavec);  end

            [IND(:,datavec),IND2(:,datavec),stats(datavec)] = Gaussian_mix(x(:,datavec),niter,basepts,verbose,doplot);
        end

        % save group stats/output

        ind = IND; ind2 = IND2;
        S.cp = cat(1,stats.cp);
        S.cnt = cat(1,stats.cnt);
        S.tot = cat(1,stats.tot);
        S.longest = cat(1,stats.longest);
        S.firstlen = cat(1,stats.firstlen);
        S.totaldur = cat(1,stats.totaldur);
        S.mu = cat(2,stats.mu);
        S.sigma = cat(2,stats.sigma);
        S.p = cat(1,stats.p);
        S.ind2 = IND2;
        S.ind = ind;

        S.cpmean = nanmean(S.cp);
        S.meancnt = mean(S.cnt);
        S.meantot = mean(S.tot);
        S.meantotaldur =  mean(S.totaldur);
        S.meanlongest = mean(S.longest);
        S.meanfirst = mean(S.firstlen);

        ind = mean(IND2')';     % group prob. of activation state
        stats = S;

        if doplot
            % group plot
            tor_fig; plot(ind,'k','LineWidth',2);
            hold on; plot(S.cpmean,ind(round(S.cpmean)),'ko','MarkerSize',12,'MarkerFaceColor',[.5 .5 .5]);
            xlabel('Time (images)'); ylabel('Probability of active state.');
        end

        return
    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    %

    % Initial values for EM-algorithm

    %

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    n = length(x);

    gam =zeros(n,2);

    p = [0.5 0.5];                      % probability that delta is [0,1]

    %mu = normrnd(0,1,1,2);              % means of Gaussian

    mu = zeros(1,2);
    mu(1) = min(x);
    mu(2) =max(x);

    sigma = zeros(1,1,2);               % covariance matrices

    for i=1:2,

        sigma(:,:,i) = std(x);

    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    %

    % EM -algorithm - repeat niter times

    %

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    if verbose,  fprintf(1,'iteration %03d',0); end

    for t=1:niter,

        if verbose, fprintf(1,'\b\b\b%03d',t); end

        % E-step

        for i=1:2,

            gam(:,i) = p(i)*det(sigma(:,:,i))^(-0.5)*exp(-0.5*sum((x'-repmat(mu(:,i),1,n))'*inv(sigma(:,:,i)).*(x'-repmat(mu(:,i),1,n))',2));

        end

        gam = gam./repmat(sum(gam,2),1,2);            % Normalize

        % M-step

        for i=1:2,

            mu(:,i) = (x'*gam(:,i))./sum(gam(:,i));                                                               % Update mean

            ind = (gam>0.5);
            dev = x-repmat(mu(:,i),n,1);

            sigma(:,:,i) = dev' *(gam(:,i).* dev) ./ sum(gam(:,i));           % Update covariance

            p(i) = mean(gam(:,i));                                                                                % Update probability

        end

        pooleds = sigma(:,:,1).*p(1) + sigma(:,:,2).*p(2);
        sigma(:,:,1:2) = pooleds;

    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    %

    % Classify points

    %

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    ind = (gam>0.5);

    [a,b]=max(mu);

    % Classify points using 3 consecutive alternate states in order to

    % switch states

    ind2 = zeros(n,1);

    state = 0;

    len = 3;

    for i=1:(length(ind(:,b))-(len-1)),

        if (state == 0),

            if(sum(ind(i:(i+(len-1)),b)) == len),

                state = 1;

            end;

        elseif (state == 1),

            if(sum(ind(i:(i+(len-1)),b)) == 0),

                state = 0;

            end;

        end;

        ind2(i) = state;

    end;

    ind2((length(ind(:,b))-(len-1)):end) = state;

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %
    % re-format output and do baseline pts.
    %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    ind = ind(:,1) - ind(:,2);
    %ind2 = ind2(:,1) - ind2(:,2);

    % wh is the class number (0 = class #1, 1 = class #2) of the most frequent
    % baseline class
    classes = [0 1];
    wh = [sum(ind2(1:basepts) == 0) sum(ind2(1:basepts) == 1)]; wh = find(wh==max(wh)); wh = wh(1);
    baseclass = classes(wh);    % 0 or 1

    whbase = find(ind2 == baseclass);
    whactive = find(ind2 ~= baseclass);

    % define so that base class is 0, active class is 1
    ind2(whbase) = 0; ind2(whactive) = 1;

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %
    % output stats and stats on runs
    %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    stats.cp = find(ind2);  % first point in active state -- CP estimate
    if isempty(stats.cp), stats.cp = NaN;
    else
        stats.cp = stats.cp(1);
    end

    [stats.cnt,stats.tot,lenmat] = cnt_runs(ind2);
    stats.longest = max(lenmat); stats.firstlen = lenmat(1);
    stats.totaldur = find(ind2);
    if isempty(stats.totaldur) || length(stats.totaldur) < 2, stats.totaldur = 0;
    else
        stats.totaldur = stats.totaldur(end) - stats.totaldur(1);
    end
    stats.mu = mu'; stats.sigma = squeeze(sigma); stats.p = p; stats.gam = gam;

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    %

    % Plot results

    %

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    if doplot

        xx = 1:length(x);

        hold off;
        plot(xx,x,'k','LineWidth',1);
        hold on;

        wh = find(~ind2); xtmp = x; xtmp(wh) = NaN;
        plot(xx,xtmp,'b','LineWidth',2);

        wh = find(ind2);xtmp = x; xtmp(wh) = NaN;
        plot(xx,xtmp,'g','LineWidth',2);

        %plot(ind2,'r','LineWidth',2);

        %axis([0 length(ind) -0.1 1.1])

    end

    if doplot2

        [h, x] = hist(x, ceil(length(x) ./ 5));
        h1 = normpdf(x, stats.mu(1), stats.sigma(1));
        h2 = normpdf(x, stats.mu(2), stats.sigma(2));

        stats.cnt1 = sum(ind > 0);
        stats.cnt2 = sum(ind < 0);

        try
            h1 = moving_average('gaussian', h1', 8)';
            h2 = moving_average('gaussian', h2', 8)';
        catch
            disp('problem with moving average')
        end

        h1 = stats.cnt1 .* h1 ./ sum(h1);
        h2 = stats.cnt2 .* h2 ./ sum(h2);

        create_figure('Gaussian mixture plot');
        plot(x, h, 'k', 'LineWidth', 2);
        hold on;
        plot(x, h1, 'r', 'LineWidth', 2);
        plot(x, h2, 'b', 'LineWidth', 2);

    end

    return


function pass = test_syntax( pref )
% Check the Chebfun2v constructor for different syntax.
% Alex Townsend, March 2013.

if ( nargin < 1 )
    pref = chebfunpref;
end
tol = 1e5 * pref.cheb2Prefs.chebfun2eps;

for jj = 1 : 2

    f = @(x,y) jj*sin(x.*y);  % simple function.
    g = @(x,y ) jj*cos(x.*y);

    fd = diskfun(f);
    gd = diskfun(g);

    F1 = diskfunv( f, g);
    F2 = diskfunv( fd, gd);
    F3 =  [ fd; gd];

    pass(1, jj) = ( norm(F1 - F2) < tol );
    pass(2, jj) = ( norm(F2 - F3) < tol );

end
pass = pass(:)';

end


function start_points = perform_lloyd_mesh(vertex,faces, start_points, options)

% perform_lloyd_mesh - perform lloyd relaxation to sample point on a mesh
%
%   start_points = perform_lloyd_mesh(vertex,faces, start_points, options);
%
%   Copyright (c) 2007 Gabriel Peyre

options.null = 0;

if size(vertex,1)>size(vertex,2)
    vertex = vertex';
end
if size(faces,1)>size(faces,2)
    faces = faces';
end

niter_lloyd = getoptions(options, 'niter_lloyd', 1);
if niter_lloyd>1
    for i=1:niter_lloyd
        start_points = perform_lloyd_mesh(vertex,faces, start_points, options)
        options.lambda = []; % enfore recomputing
    end
    return;
end

lambda = getoptions(options, 'lambda', []);
edges_id = getoptions(options, 'edges_id', []);
Q = getoptions(options, 'Q', []);
if isempty(lambda) || isempty(edges_id) || isempty(Q)
    % update voronoi
    [Q,DQ, ve, edges_id, lambda] = compute_voronoi_mesh(vertex,faces, start_points, options);
end

% compute distances for start
ne = length(lambda);
n = size(vertex,2);
% compute edge length
d = diff( reshape(vertex(:,edges_id'), [3 ne 2]), 1, 3 );
d = sqrt( sum(d.^2,1) );
d1 = (1-lambda).*d;
d2 = lambda.*d;
% compute initial values for FM
values = zeros(n,1); cnt = zeros(n,1);
for i=1:ne
    values(edges_id(1,i)) = values(edges_id(1,i)) + d1(i);
    cnt(edges_id(1,i)) = cnt(edges_id(1,i)) + 1;
    values(edges_id(2,i)) = values(edges_id(2,i)) + d1(i);
    cnt(edges_id(2,i)) = cnt(edges_id(2,i)) + 1;
end
values = values./cnt;
% perform FM from edge points
pts = unique( edges_id(:) );
options.values = values(pts);
options.values = [];
D = perform_fast_marching_mesh(vertex, faces, pts, options);

% seed new locations
nstart = length(start_points);
for i=1:nstart
    I = find(Q(:,1)==i);
    [v,k] = max(D(I));
    start_points(i) = I(k);
end
start_points = start_points(:);


% Extract critical features (junctions and endpoints).
%
% Rougly follows procedure of Liu et al. "Identification of Fork Points..." IEEE
% TAPMI
%
% For a circular stroke, there are no "features" by this definition.
% Thus, for any partition of the pixels into regions, there should
% be at least one feature for the tracing algorithm to find.
%
% Input
%  T: [n x n boolean] thinned image.
%    images are binary, where true means "black"
%
% Output
%  SN: [n x n boolean] extracted features.
function SN = extract_junctions(T)

    SE = bwmorph(T,'endpoints');
    SB = T; % black pixels
    sz = size(T,1);

    lutS3 = makelut( @(P)fS3(P) , 3);
    S3 = applylut(T,lutS3);

    % final criteria
    SN = SE | (SB & S3);

    % Check to see that each connected component has a feature.
    % This is necessary to process circles in the image.
    CC = bwconncomp(T,8);
    nCC = CC.NumObjects;
    for c=1:nCC

       pid = CC.PixelIdxList{c};

       % We have a circle. Circles are generally drawn from the
       % top, we choose the top pixel here
       if sum(SN(pid))==0
          [irow,icol] = ind2sub(sz,pid);
          sel = argmin(irow);
          SN(pid(sel)) = true;
       end

    end

end

% See Liu et al.
function Y=fS3(P)
    sz = size(P);
    assert(isequal(sz,[3 3]));

    % Get cross number
    NC = fNC(P);

    % Count black pixels
    PM = P;
    PM(2,2) = false;
    NB = sum(PM(:));

    % Criteria
    Y = (NC >= 3-eps) || (NB >= 4-eps);
end

% See Liu et al.
function Y=fNC(P)
    sum = 0;
    for i=0:7
        sum = sum + abs( P(fIP(i+1)) - P(fIP(i)) );
    end
    Y = sum./2;
end

% See Liu et al.
function newlindx = fIP(lindx)
    switch lindx
        case {0,8}
            i=1; j=2;
        case 1
            i=1; j=3;
        case 2
            i=2; j=3;
        case 3
            i=3; j=3;
        case 4
            i=3; j=2;
        case 5
            i=3; j=1;
        case 6
            i=2; j=1;
        case 7
            i=1; j=1;
    end
    newlindx = sub2ind([3 3],i,j);
end


classdef prtPreProcFilter < prtPreProc
    % prtPreProcFilter   Data filtering
    %   Apply the filter specified in the propertes a and b to the rows of
    %   the data in dataSet.X:
    %
    % ds = prtDataGenCylinderBellFunnel;
    % b = fir1(21,.5);
    % pp = prtPreProcFilter('b',b,'a',1);
    % pp = pp.train(ds);
    % dsLpf = pp.run(ds);
    % subplot(1,2,1); imagesc(ds);
    % subplot(1,2,2); imagesc(dsLpf);

    properties (SetAccess=private)
        name = 'Filter'  % Zero Mean Unit Variance
        nameAbbreviation = 'Filt'  % ZMUV
    end

    properties
        b = [];
        a = 1;
        filtfilt = true;
    end

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

    methods (Access=protected,Hidden=true)

        function self = trainAction(self,ds)
            % nothing to do
        end

        function ds = runAction(self,ds)
            % Remove the means and normalize the variance
            X = ds.X;
            if self.filtfilt
                X = filtfilt(self.b,self.a,X')';
            else
                X = filter(self.b,self.a,X')';
            end
            ds.X = X;
        end

        function xOut = runActionFast(self,xIn,ds) %#ok<INUSD>
           if self.filtfilt
                xOut = filtfilt(self.b,self.a,xIn')';
            else
                xOut = filter(self.b,self.a,xIn')';
            end
        end
    end

    methods (Hidden)

        function str = exportSimpleText(self) %#ok<MANU>
            error('Not implemented');
            %             titleText = sprintf('%% prtPreProcZmuv\n');
            %             zmuvMeansText = prtUtilMatrixToText(self.means,'varName','means');
            %             zmuvVarsText = prtUtilMatrixToText(self.stds,'varName','std');
            %             str = sprintf('%s%s%s',titleText,zmuvMeansText,zmuvVarsText);
        end
    end
end


% Weighted Prediction Error for dereverberation
% reference: Nakatani, Tomohiro, et al. "Speech dereverberation based on
% variance-normalized delayed linear prediction." IEEE TASLP 18.7 (2010)
% ZitengWANG@201903

clear all
addpath('..\STFT\')
addpath('..\Simulation\')
addpath('..\Simulation\RIR-Generator\')

%% simulation start
flatStart = 1;
prefix = '';   % for saving file

speechDir = '..\Simulation\Data\';
speechFile = 'fajw0_sa1.wav';
saveDir = 'GeneratedData\';
if ~exist(saveDir)
    mkdir(saveDir)
end
speech = audioread([speechDir speechFile]);

% configuration
cfg = [];
cfg.fs = 16000;                     % sampling rate
cfg.room = [6 5 3];                 % room dimension (m)
cfg.T60 = 0;                      % reverberation time (s)

cfg.Nch = 6;
cfg.micCenter = [2 3 1.5];          % array center (m)
cfg.micCoordinate =[0.0425,0.0,0.0;
        0.02125,0.03680608,0.0;
        -0.02125,0.03680608,0.0;
        -0.0425,0.0,0.0;
        -0.02125,-0.03680608,0.0;
        0.02125,-0.03680608,0.0;];  % microphone array coordinates

cfg.az = 180;
cfg.el = 0;
cfg.dist = 3;

cfg.SNR = 20;
if cfg.SNR ~= inf               % inf means no noise
    cfg.noiseType = 'white';    % choice {'white' 'diffuse' 'recorded'}
    if strcmp(cfg.noiseType, 'recorded')
        % check first the noise is longer than speech!
        cfg.noiseFile = '';
    end
end

cfg.SIR = inf;

% setup room and collect data
setup_room
setup_noise

%% offline processing start
% the following parts are specific to the algorithm
Nfft = 512;

Y = stft_multi_2(y, Nfft);
[Nframe, Nbin, Nch] = size(Y);

iterMax = 5;
wpe.delay = 3;
wpe.taps = 10;
XeEst = Y;
for bin = 1:Nbin
    % get audio context first
    YbarFrm = cell(Nframe, 1);
    for frm = (wpe.taps + wpe.delay):Nframe
        Ybar = squeeze(Y(frm - wpe.delay,bin,:));
        for tap=1:wpe.taps-1
            Ybar = [Ybar; squeeze(Y(frm - wpe.delay - tap,bin ,:))];
        end
        YbarFrm{frm} = Ybar;
    end

    % iterate
    X = squeeze(Y(:,bin,:));
    for iter = 1:iterMax
        % calculate mean signal power
        Xpow = mean(abs(X).^2, 2);
        XpowMax = max(Xpow);
        % calculate correlation matrix and correlation vector
        R = 0;
        P = 0;
        for frm = (wpe.taps + wpe.delay):Nframe
            Ybar = YbarFrm{frm};
            YbarTmp = Ybar / max(Xpow(frm), 1e-10*XpowMax);
            R = R + YbarTmp * Ybar' ;
            P = P + YbarTmp * squeeze(Y(frm,bin,:))';
        end
        hWPE = R \ P;

        % apply the filter
        for frm = (wpe.taps + wpe.delay):Nframe
            X(frm, :) = squeeze(Y(frm,bin,:)) - hWPE'*YbarFrm{frm};
        end
    end
    XeEst(:,bin,:) = permute(X,[1,3,2]);
end

xeEst = istft_multi_2(XeEst, length(speech));
audiowrite([saveDir prefix 'WPE' postfix '.wav'], xeEst, fs);


% predicting numerical values using Linear Regression
clear all;
format long
disp('===== Linear Regression ====');
disp('Reading featur vector');

for feat = 1:3
    featurs = csvread('data\forWeka_featuresonly.csv');
    num_data = size(featurs,1); %5000;
    disp(sprintf('Number of datapoints %d',num_data))

    possiblefeaturizations =  {'bernouli', 'tfidf','multinomial'};
    %featurization = 'bernouli'%'tfidf'%'tfidf'%'multinomial'%'tfidf' %'multinomial'; % 'bernouli', 'tfidf'
    featurization  = possiblefeaturizations{feat}

    featurs = featurs(:,2:size(featurs,2));
    if strcmp(featurization,'multinomial')
        %just pass
    elseif strcmp(featurization,'bernouli')
        featurs = bernoulli(featurs);
    elseif strcmp(featurization,'tfidf')
        featurs = tfidf(featurs);
    end

    size_training = floor(.8*num_data);

    trainingset = featurs(1:size_training,:);
    testset = featurs((size_training+1):num_data,:);

    disp('Splitting up data into training/test sets');
    [num,txt,raw] = xlsread('data\final104.xls');

    % reading the description of each shoe
    descriptions = raw(2:size(raw,1),2);
    style_ratings = num(1:size(num,1),1);
    comfort_ratings = num(1:size(num,1),4);
    overal_ratings = num(1:size(num,1),5);

    % only take m data points
    m=num_data;
    descriptions = descriptions(1:m);
    style_ratings = style_ratings(1:m);
    comfort_ratings = comfort_ratings(1:m);
    overal_ratings = overal_ratings(1:m);

    responsevals = [style_ratings, comfort_ratings, overal_ratings];

    responsevals_training = responsevals(1:size_training,:);
    responsevals_test = responsevals((size_training+1):num_data,:);

    disp('Discreminate Analsys');
    %

    tic;

    predictions = [];
    actual = [];
    for i =1:3
        a = responsevals_training(:,i);
        b = responsevals_test(:,i)';
        %regresscoeff = regress(a, trainingset);
        %C2 = (regresscoeff'*(testset'));
        class = classify(testset,trainingset,a)
        predictions = [predictions, class];
        actual = [actual, b'];
    end

    MSE = mean(sum(((predictions-actual).^2)'))
    toc;

end


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

function [S, u, d, df, p] = createbintree(S0, T, n, r, sigma)
% creates a simple binomial tree using repmat
    dt = T / n;                  % length of one period
    u = exp(sigma * sqrt(dt));   % up move
    d = 1 / u;                   % down move
    df = exp(-r * dt);           % discount
    p = (1/df - d) / (u - d);    % probability up

    S = zeros(2^n, n+1);
    S(:,1) = S0*ones(2^n,1);

    for i=1:1:n
        a = [u * ones(2^(n-i),1); d * ones(2^(n-i),1)];
        S(:,i+1) = S(:,i).*repmat(a, 2^(i-1),1);
    end

end


function desc = sift( patches )
psz = [size(patches, 1), size(patches, 2)];
frm = [(psz(1) ./ 2 + 0.5) * ones(2, 1) ; psz(1) ./ 2; 0];
desc = [];
for pi = 1:size(patches, 3)
  I = single(patches(:, :, pi));
  [Ix, Iy] = vl_grad(I) ;
  mod      = sqrt(Ix.^2 + Iy.^2) ;
  ang      = atan2(Iy, Ix) ;
  grd      = shiftdim(cat(3, mod, ang), 2) ;
  d        = vl_siftdescriptor(grd, frm, 'magnif', 0.5) ;
  if isempty(desc)
    desc = zeros(numel(d), size(patches, 3), 'single');
  end
  desc(:, pi) = d;
end

end


function s = resampdet(p,m,n);
%RESAMPDET Deterministic resampling
%
%   Description
%   S = RESAMPDET(P) returns a new set of indices according to the
%   probabilities P. P is array of probabilities, which are not
%   necessarily normalized, though they must be non-negative, and
%   not all zero. The size of S is the size of P.
%
%   S = RESAMPDET(P,M,N) returns M by N matrix.
%
%   S = RESAMPDET(P,M) returns M by M matrix.
%
%   Default is to use no-sort resampling. For sorted resampling use
%    [PS,PI]=SORT(P);
%    S=PI(RESAMPDET(PS));
%   Sorted re-sampling is slower but has smaller variance. Note
%   that deterministic resampling is not unbiased. Stratified
%   resampling (RESAMPSTR) is unbiased, almost as fast as
%   deterministic resampling, and has only slightly larger
%   variance.
%
%   In deterministic resampling indices are sampled using
%   deterministic numbers u_j~(j-a)/n, for fixed a in [0,1) and
%   n is length of P. Compare this to simple random resampling
%   where u_j~U[0,n]. See, Kitagawa, G., Monte Carlo Filter and
%   Smoother for Non-Gaussian Nonlinear State Space Models,
%   Journal of Computational and Graphical Statistics, 5(1):1-25,
%   1996.
%
%   See also RESAMPSIM, RESAMPRES, RESAMPSTR

% Copyright (c) 2003-2004 Aki Vehtari

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

if nargin<2
    [m,n]=size(p);
elseif nargin==2
    n=m;
end
mn=m.*n;
pn=p./sum(p(:)).*mn;
fpn=floor(pn);
s=zeros(m,n);
k=0;
c=0.5;
for i=1:numel(p)
  if pn(i)>=1
    a=fpn(i);
    pn(i)=pn(i)-a;
    s(k+[1:a])=i;
    k=k+a;
  end
  c=c+pn(i);
  if c>=1
    k=k+1;
    s(k)=i;
    c=c-1;
  end
end


function denoised_im = denoise_foe(im, basis, W, a, sigma)
%DENOISE_FOE Denoise image using Field of Experts prior model
%
%   denoised_im = denoise_foe(im, basis, W, a, sigma)
%
% Denoises the image im, using a Gaussian noise model with variance sigma,
% and a Field of Experts image prior specified by basis, W, and a.
%
%
% (C) Laurens van der Maaten, 2009
% Delft University of Technology

    % Initialize some variables
    eta = 10;
    max_iter = 275; %275 je bilo originalno
    im = double(im);
    dI = zeros(size(im));

    % Convert to YCbCr color space if input is RGB
    if size(im, 3) == 3
        im = 255 .* rgb2ycbcr(im ./ 255);
    end
    denoised_im = im;

    minEnergy = realmax;
    minEnergyImg = denoised_im;
    % Perform gradient iterations
    for iter=1:max_iter

        % Compute gradient of posterior log-likelihood
        for c=1:size(denoised_im, 3)
            dI(:,:,c) = reshape(foe_energy_grad_x(denoised_im(:,:,c), basis, W, a), [size(im, 1) size(im, 2)]);
        end
        dI = dI + (1 / sigma ^ 2) * (im - denoised_im);

        % Perform gradient update
        denoised_im = denoised_im - eta * dI;

        % Print progress
        if ~rem(iter, 10) || iter == max_iter

            % Compute energy of posterior
            E = foe_energy(denoised_im, basis, W, a, size(denoised_im)) + (1 ./ (sigma ^ 2)) * sum(((im(:) - denoised_im(:)) ./ 255) .^ 2);

            if E < minEnergy
                minEnergy = E;
                minEnergyImg = denoised_im;
                disp(['Iteration ' num2str(iter) ': energy is ' num2str(E)]);
            else
                disp('Finished because of energy increase.');
                denoised_im = minEnergyImg;
                break;
            end

            % Show intermediate result
            if size(im, 3) == 3
                tmp1 = uint8(round(255 .* ycbcr2rgb(im ./ 255)));
                tmp2 = uint8(round(255 .* ycbcr2rgb(denoised_im ./ 255)));
            else
                tmp1 = uint8(round(im));
                tmp2 = uint8(round(denoised_im));
            end
        end
    end

    subplot(1, 2, 1); imshow(tmp1); colormap(gray); title('Noisy image');
    subplot(1, 2, 2); imshow(tmp2); colormap(gray); title(['Denoised image (iteration ' num2str(iter) ')']);
    drawnow;

    % Convert back to RGB if necessary
    if size(denoised_im, 3) == 3
        denoised_im = 255 .* ycbcr2rgb(denoised_im ./ 255);
    end
    denoised_im = uint8(round(denoised_im));


function angles3d(varargin)
%ANGLES3D Conventions for manipulating angles in 3D.
%
%   The library uses both radians and degrees angles;
%   Results of angle computation between shapes usually returns angles in
%   radians.
%   Representation of 3D shapes use angles in degrees (easier to manipulate
%   and to save).
%
%   Contrary to the plane, there are no oriented angles in 3D. Angles
%   between lines or between planes are comprised between 0 and PI.
%
%   Spherical angles
%   Spherical angles are defined by 2 angles:
%   * THETA, the colatitude, representing angle with Oz axis (between 0 and
%       PI)
%   * PHI, the azimut, representing angle with Ox axis of horizontal
%       projection of the direction (between 0 and 2*PI)
%
%   Spherical coordinates can be represented by THETA, PHI, and the
%   distance RHO to the origin.
%
%   Euler angles
%   Some functions for creating rotations use Euler angles. They follow the
%   ZYX convention in the global reference system, that is eqivalent to the
%   XYZ convention ine a local reference system.
%   Euler angles are given by a triplet of angles [PHI THETA PSI] that
%   represents the succession of 3 rotations:
%   * rotation around X by angle PSI    ("roll")
%   * rotation around Y by angle THETA  ("pitch")
%   * rotation around Z by angle PHI    ("yaw")
%
%   In this library, euler angles are given in degrees. The functions that
%   use euler angles use the keyword 'Euler' in their name.
%
%
%   See also
%   cart2sph2, sph2cart2, cart2sph2d, sph2cart2d
%   anglePoints3d, angleSort3d, sphericalAngle, randomAngle3d
%   dihedralAngle, polygon3dNormalAngle, eulerAnglesToRotation3d
%   rotation3dAxisAndAngle, rotation3dToEulerAngles
%

% ------
% Author: David Legland
% e-mail: david.legland@inra.fr
% Created: 2008-10-13,    using Matlab 7.4.0.287 (R2007a)
% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas.


function [resp] = responseCox(X,coeff)
% -------------------------------------------------------------------------
% function [resp] = responseLR(X,coeff)
% -------------------------------------------------------------------------
% DESCRIPTION:
% This function computes the multivariable response of an input set of
% features from a given set of logistic regression coefficients.
% -------------------------------------------------------------------------
% INPUTS:
% - X: Matrix of size [nInst X nFeat], specifying the numerical data of the
%      features of the input training data, where 'nInst' refers to the
%      number of instances in X, and 'nFeat' to the number of features in
%      X. Each column is a different feature.
% - coeff: Column vector of size [nFeat+1 X 1] representing the set of
%          logistic regression coefficients computed from
%          drxlr_apply_logistic_regression.m. One coefficient is present
%          for each feature in 'X', in addition to one offset coefficient.
% -------------------------------------------------------------------------
% OUTPUTS:
% - resp: Multivariable response vector of size [nInst X 1].
% -------------------------------------------------------------------------
% AUTHOR(S): Martin Vallieres <mart.vallieres@gmail.com>
% -------------------------------------------------------------------------
% HISTORY:
% - Creation: May 2015
%--------------------------------------------------------------------------
% STATEMENT:
% This file is part of <https://github.com/mvallieres/radiomics/>,
% a package providing MATLAB programming tools for radiomics analysis.
% --> Copyright (C) 2015  Martin Vallieres
%
%    This package is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    This package is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with this package.  If not, see <http://www.gnu.org/licenses/>.
% -------------------------------------------------------------------------

nInst = size(X,1);
nFeat = size(X,2);
resp = zeros(nInst,1);
for j = 1:nFeat
    resp(:) = resp(:) + X(:,j).*coeff(j);
end

end


function [G, Y, optinf] = bpdndl(D0, S, lambda, opt)

% bpdndl -- BPDN Dictionary Learning
%
%         argmin_{D,X} (1/2)||D X - S||_2^2 + lambda ||X||_1
%
%         Dictionary learning consists of interleaved alternation of
%         the ADMM (see boyd-2010-distributed) steps for the BPDN (see
%         chen-1998-atomic) and MOD (see engan-1999-method) problems.
%
% Usage:
%       [D, X, optinf] = bpdndl(D0, S, lambda, opt)
%
% Input:
%       D0          Initial dictionary
%       S           Input image
%       lambda      Regularization parameter
%       opt         Options/algorithm parameters structure (see below)
%
% Output:
%       D           Dictionary
%       X           Coefficients
%       optinf      Details of optimisation
%
%
% Options structure fields:
%   Verbose          Flag determining whether iteration status is displayed.
%                    Fields are iteration number, functional value,
%                    data fidelity term, l1 regularisation term, and
%                    primal and dual residuals (see Sec. 3.3 of
%                    boyd-2010-distributed). The values of rho and sigma
%                    are also displayed if options request that they are
%                    automatically adjusted.
%   MaxMainIter      Maximum main iterations
%   AbsStopTol       Absolute convergence tolerance (see Sec. 3.3.1 of
%                    boyd-2010-distributed)
%   RelStopTol       Relative convergence tolerance (see Sec. 3.3.1 of
%                    boyd-2010-distributed)
%   L1Weight         Weight matrix for L1 norm
%   Y0               Initial value for Y
%   U0               Initial value for U
%   G0               Initial value for G (overrides D0 if specified)
%   H0               Initial value for H
%   rho              Augmented Lagrangian penalty parameter
%   AutoRho          Flag determining whether rho is automatically updated
%                    (see Sec. 3.4.1 of boyd-2010-distributed)
%   AutoRhoPeriod    Iteration period on which rho is updated
%   RhoRsdlRatio     Primal/dual residual ratio in rho update test
%   RhoScaling       Multiplier applied to rho when updated
%   AutoRhoScaling   Flag determining whether RhoScaling value is
%                    adaptively determined (see wohlberg-2015-adaptive). If
%                    enabled, RhoScaling specifies a maximum allowed
%                    multiplier instead of a fixed multiplier
%   sigma            Augmented Lagrangian penalty parameter
%   AutoSigma        Flag determining whether sigma is automatically
%                    updated (see Sec. 3.4.1 of boyd-2010-distributed)
%   AutoSigmaPeriod  Iteration period on which sigma is updated
%   SigmaRsdlRatio   Primal/dual residual ratio in sigma update test
%   SigmaScaling     Multiplier applied to sigma when updated
%   AutoSigmaScaling Flag determining whether SigmaScaling value is
%                    adaptively determined (see wohlberg-2015-adaptive). If
%                    enabled, SigmaScaling specifies a maximum allowed
%                    multiplier instead of a fixed multiplier.
%   StdResiduals     Flag determining whether standard residual definitions
%                    (see Sec 3.3 of boyd-2010-distributed) are used instead
%                    of normalised residuals (see wohlberg-2015-adaptive)
%   XRelaxParam      Relaxation parameter (see Sec. 3.4.3 of
%                    boyd-2010-distributed) for X update
%   DRelaxParam      Relaxation parameter (see Sec. 3.4.3 of
%                    boyd-2010-distributed) for D update
%   NonNegCoef       Flag indicating whether solution should be forced to
%                    be non-negative
%   AuxVarObj        Flag determining whether objective function is computed
%                    using the auxiliary (split) variable
%   ZeroMean         Force learned dictionary entries to be zero-mean
%
%
% Author: Brendt Wohlberg <brendt@lanl.gov>  Modified: 2015-07-30
%
% This file is part of the SPORCO library. Details of the copyright
% and user license can be found in the 'License' file distributed with
% the library.

if nargin < 4,
  opt = [];
end
checkopt(opt, defaultopts([]));
opt = defaultopts(opt);
Nx = size(D0,2)*size(S,2);
Nd = prod(size(D0));

% Set up status display for verbose operation
hstr = ['Itn   Fnc       DFid      l1        Cnstr     '...
        'r(X)      s(X)      r(D)      s(D) '];
sfms = '%4d %9.2e %9.2e %9.2e %9.2e %9.2e %9.2e %9.2e %9.2e';
nsep = 84;
if opt.AutoRho,
  hstr = [hstr '     rho  '];
  sfms = [sfms ' %9.2e'];
  nsep = nsep + 10;
end
if opt.AutoSigma,
  hstr = [hstr '     sigma  '];
  sfms = [sfms ' %9.2e'];
  nsep = nsep + 10;
end
if opt.Verbose && opt.MaxMainIter > 0,
  disp(hstr);
  disp(char('-' * ones(1,nsep)));
end

% Mean removal and normalisation projections
Pzmn = @(x) bsxfun(@minus, x, mean(x,1));
Pnrm = @(x) normalise(x);

% Projection of dictionary filters onto constraint set
if opt.ZeroMean,
  Pcn = @(x) Pnrm(Pzmn(x));
else
  Pcn = @(x) Pnrm(x);
end

% Start timer
tstart = tic;

% Project initial dictionary onto constraint set
D = Pnrm(D0);

% Set up algorithm parameters and initialise variables
rho = opt.rho;
if isempty(rho), rho = 50*lambda+1; end;
sigma = opt.sigma;
if isempty(sigma), sigma = size(S,2)/200; end;
optinf = struct('itstat', [], 'opt', opt);
rx = Inf;
sx = Inf;
rd = Inf;
sd = Inf;
eprix = 0;
eduax = 0;
eprid = 0;
eduad = 0;

% Initialise main working variables
X = [];
if isempty(opt.Y0),
  Y = zeros(size(D,2), size(S,2));
else
  Y = opt.Y0;
end
Yprv = Y;
if isempty(opt.U0),
  if isempty(opt.Y0),
    U = zeros(size(D,2), size(S,2), class(S));
  else
    U = (lambda/rho)*sign(Y);
  end
else
  U = opt.U0;
end
if isempty(opt.G0),
  G = D;
else
  G = opt.G0;
end
Gprv = G;
if isempty(opt.H0),
  if isempty(opt.G0),
    H = zeros(size(G), class(S));
  else
    H = G;
  end
else
  H = opt.H0;
end
GS = G'*S;

% Main loop
k = 1;
while k <= opt.MaxMainIter && (rx > eprix|sx > eduax|rd > eprid|sd >eduad),

  % Solve X subproblem, using G as the dictionary for improved stability
  [luLx, luUx] = factorise(G, rho);
  X = linsolveX(G, rho, luLx, luUx, GS + rho*(Y - U));

  % See pg. 21 of boyd-2010-distributed
  if opt.XRelaxParam == 1,
    Xr = X;
  else
    Xr = opt.XRelaxParam*X + (1-opt.XRelaxParam)*Y;
  end

  % Solve Y subproblem
  Y = shrink(Xr + U, (lambda/rho)*opt.L1Weight);
  if opt.NonNegCoef,
    Y(Y < 0) = 0;
  end
  SY = S*Y';

  % Update dual variable corresponding to X, Y
  U = U + Xr - Y;

  % Compute primal and dual residuals and stopping thresholds for X update
  nX = norm(X(:)); nY = norm(Y(:)); nU = norm(U(:));
  if opt.StdResiduals,
    % See pp. 19-20 of boyd-2010-distributed
    rx = norm(vec(X - Y));
    sx = norm(vec(rho*(Yprv - Y)));
    eprix = sqrt(Nx)*opt.AbsStopTol+max(nX,nY)*opt.RelStopTol;
    eduax = sqrt(Nx)*opt.AbsStopTol+rho*nU*opt.RelStopTol;
  else
    % See wohlberg-2015-adaptive
    rx = norm(vec(X - Y))/max(nX,nY);
    sx = norm(vec(Yprv - Y))/nU;
    eprix = sqrt(Nx)*opt.AbsStopTol/max(nX,nY)+opt.RelStopTol;
    eduax = sqrt(Nx)*opt.AbsStopTol/(rho*nU)+opt.RelStopTol;
  end

  % Solve D subproblem, using Y as the coefficients for improved stability
  [luLd, luUd] = factorise(Y, sigma);
  D = linsolveD(Y, sigma, luLd, luUd, SY + sigma*(G - H));

  % See pg. 21 of boyd-2010-distributed
  if opt.DRelaxParam == 1,
    Dr = D;
  else
    Dr = opt.DRelaxParam*D + (1-opt.DRelaxParam)*G;
  end

  % Solve G subproblem
  G = Pcn(Dr + H);
  GS = G'*S;

  % Update dual variable corresponding to D, G
  H = H + Dr - G;

  % Compute primal and dual residuals and stopping thresholds for D update
  nD = norm(D(:)); nG = norm(G(:)); nH = norm(H(:));
  if opt.StdResiduals,
    % See pp. 19-20 of boyd-2010-distributed
    rd = norm(vec(D - G));
    sd = norm(vec(sigma*(Gprv - G)));
    eprid = sqrt(Nd)*opt.AbsStopTol+max(nD,nG)*opt.RelStopTol;
    eduad = sqrt(Nd)*opt.AbsStopTol+sigma*nH*opt.RelStopTol;
  else
    % See wohlberg-2015-adaptive
    rd = norm(vec(D - G))/max(nD,nG);
    sd = norm(vec(Gprv - G))/nH;
    eprid = sqrt(Nd)*opt.AbsStopTol/max(nD,nG)+opt.RelStopTol;
    eduad = sqrt(Nd)*opt.AbsStopTol/(sigma*nH)+opt.RelStopTol;
  end

  % Objective function
  if opt.AuxVarObj,
    Jdf = sum(vec(abs(G*Y - S).^2))/2;
    Jl1 = sum(abs(vec(opt.L1Weight .* Y)));
  else
    Jdf = sum(vec(abs(D*X - S).^2))/2;
    Jl1 = sum(abs(vec(opt.L1Weight .* X)));
  end
  Jfn = Jdf + lambda*Jl1;
  Jcn = norm(vec(Pcn(D) - D));

  % Record and display iteration details
  tk = toc(tstart);
  optinf.itstat = [optinf.itstat; ...
        [k Jfn Jdf Jl1 rx sx rd sd eprix eduax eprid eduad rho sigma tk]];
  if opt.Verbose,
    dvc = [k Jfn Jdf Jl1 Jcn rx sx rd sd];
    if opt.AutoRho,
      dvc = [dvc rho];
    end
    if opt.AutoSigma,
      dvc = [dvc sigma];
    end
    disp(sprintf(sfms, dvc));
  end

  % See wohlberg-2015-adaptive and pp. 20-21 of boyd-2010-distributed
  if opt.AutoRho,
    if k ~= 1 && mod(k, opt.AutoRhoPeriod) == 0,
      if opt.AutoRhoScaling,
        rhomlt = sqrt(rx/sx);
        if rhomlt < 1, rhomlt = 1/rhomlt; end
        if rhomlt > opt.RhoScaling, rhomlt = opt.RhoScaling; end
      else
        rhomlt = opt.RhoScaling;
      end
      rsf = 1;
      if rx > opt.RhoRsdlRatio*sx, rsf = rhomlt; end
      if sx > opt.RhoRsdlRatio*rx, rsf = 1/rhomlt; end
      rho = rsf*rho;
      U = U/rsf;
    end
  end
  if opt.AutoSigma,
    if k ~= 1 && mod(k, opt.AutoSigmaPeriod) == 0,
      if opt.AutoSigmaScaling,
        sigmlt = sqrt(rd/sd);
        if sigmlt < 1, sigmlt = 1/sigmlt; end
        if sigmlt > opt.SigmaScaling, sigmlt = opt.SigmaScaling; end
      else
        sigmlt = opt.SigmaScaling;
      end
      ssf = 1;
      if rd > opt.SigmaRsdlRatio*sd, ssf = sigmlt; end
      if sd > opt.SigmaRsdlRatio*rd, ssf = 1/sigmlt; end
      sigma = ssf*sigma;
      H = H/ssf;
    end
  end

  Yprv = Y;
  Gprv = G;
  k = k + 1;

end

% Record run time and working variables
optinf.runtime = toc(tstart);
optinf.X = X;
optinf.Y = Y;
optinf.U = U;
optinf.D = D;
optinf.G = G;
optinf.H = H;
optinf.lambda = lambda;
optinf.rho = rho;
optinf.sigma = sigma;

if opt.Verbose && opt.MaxMainIter > 0,
  disp(char('-' * ones(1,nsep)));
end

return

function u = vec(v)

  u = v(:);

return

function u = shrink(v, lambda)

  u = sign(v).*max(0, abs(v) - lambda);

return

function u = normalise(v)

  vn = sqrt(sum(v.^2, 1));
  vn(vn == 0) = 1;
  u = bsxfun(@rdivide, v, vn);

return

function [L,U] = factorise(A, c)

  [N,M] = size(A);
  % If N < M it is cheaper to factorise A*A' + cI and then use the
  % matrix inversion lemma to compute the inverse of A'*A + cI
  if N >= M,
    [L,U] = lu(A'*A + c*eye(M,M));
  else
    [L,U] = lu(A*A' + c*eye(N,N));
  end

return

function x = linsolveX(A, c, L, U, b)

  [N,M] = size(A);
  if N >= M,
    x = U \ (L \ b);
  else
    x = (b - A'*(U \ (L \ (A*b))))/c;
  end

return

function x = linsolveD(A, c, L, U, b)

  [N,M] = size(A);
  if N >= M,
    x = (b - (((b*A) / U) / L)*A')/c;
  else
    x = (b / U) / L;
  end

return

function opt = defaultopts(opt)

  if ~isfield(opt,'Verbose'),
    opt.Verbose = 0;
  end
  if ~isfield(opt,'MaxMainIter'),
    opt.MaxMainIter = 1000;
  end
  if ~isfield(opt,'AbsStopTol'),
    opt.AbsStopTol = 1e-6;
  end
  if ~isfield(opt,'RelStopTol'),
    opt.RelStopTol = 1e-4;
  end
  if ~isfield(opt,'L1Weight'),
    opt.L1Weight = 1;
  end
  if ~isfield(opt,'Y0'),
    opt.Y0 = [];
  end
  if ~isfield(opt,'U0'),
    opt.U0 = [];
  end
  if ~isfield(opt,'G0'),
    opt.G0 = [];
  end
  if ~isfield(opt,'H0'),
    opt.H0 = [];
  end
  if ~isfield(opt,'rho'),
    opt.rho = [];
  end
  if ~isfield(opt,'AutoRho'),
    opt.AutoRho = 0;
  end
  if ~isfield(opt,'AutoRhoPeriod'),
    opt.AutoRhoPeriod = 10;
  end
  if ~isfield(opt,'RhoRsdlRatio'),
    opt.RhoRsdlRatio = 10;
  end
  if ~isfield(opt,'RhoScaling'),
    opt.RhoScaling = 2;
  end
  if ~isfield(opt,'AutoRhoScaling'),
    opt.AutoRhoScaling = 0;
  end
  if ~isfield(opt,'sigma'),
    opt.sigma = [];
  end
  if ~isfield(opt,'AutoSigma'),
    opt.AutoSigma = 0;
  end
  if ~isfield(opt,'AutoSigmaPeriod'),
    opt.AutoSigmaPeriod = 10;
  end
  if ~isfield(opt,'SigmaRsdlRatio'),
    opt.SigmaRsdlRatio = 10;
  end
  if ~isfield(opt,'SigmaScaling'),
    opt.SigmaScaling = 2;
  end
  if ~isfield(opt,'AutoSigmaScaling'),
    opt.AutoSigmaScaling = 0;
  end
  if ~isfield(opt,'StdResiduals'),
    opt.StdResiduals = 0;
  end
  if ~isfield(opt,'XRelaxParam'),
    opt.XRelaxParam = 1;
  end
  if ~isfield(opt,'DRelaxParam'),
    opt.DRelaxParam = 1;
  end
  if ~isfield(opt,'NonNegCoef'),
    opt.NonNegCoef = 0;
  end
  if ~isfield(opt,'AuxVarObj'),
    opt.AuxVarObj = 1;
  end
  if ~isfield(opt,'ZeroMean'),
    opt.ZeroMean = 0;
  end

return


% op_zeropad.m
% Jamie Near, McGill University 2014.
%
% USAGE:
% out=op_zeropad(in,zpFactor);
%
% DESCRIPTION:
% Apply zeropadding (a.k.a. zero-filling) to MRS data.
%
% INPUTS:
% in         = input data in matlab structure format.
% zpFactor   = the factor by which the number of points in the fid will be
%             increased.  ie.  if zpFactor =2, then the number of zeros
%             added to the end of the fid will be equal to the number of
%             points in the original spectrum.
%
% OUTPUTS:
% out        = Output dataset following zeropadding.

function out=op_zeropad(in,zpFactor);

if in.flags.zeropadded
    cont=input('WARNING:  Zero padding has already been performed!  Continue anyway?  (y or n)','s');
    if cont=='y'
        %continue;
    else
        error('STOPPING');
    end
end

%calculate how many zeros to add
zp=ceil((in.sz(1)*zpFactor)-in.sz(1));

%Add zeros using MATLAB array zeropadding function;
fids=padarray(in.fids,zp,'post');

%Calculate Specs using fft
specs=fftshift(ifft(fids,[],in.dims.t),in.dims.t);

%recalculate the sz vector
sz=size(fids);

%Now re-calculate t and ppm arrays using the calculated parameters:
f=[(-in.spectralwidth/2)+(in.spectralwidth/(2*sz(1))):...
    in.spectralwidth/(sz(1)):...
    (in.spectralwidth/2)-(in.spectralwidth/(2*sz(1)))];

ppm=-f/(in.Bo*42.577);
ppm=ppm+4.65;

t=[0:in.dwelltime:(sz(1)-1)*in.dwelltime];

%FILLING IN DATA STRUCTURE
out=in;
out.fids=fids;
out.specs=specs;
out.sz=sz;
out.ppm=ppm;
out.t=t;
out.n=sz(1);

%FILLING IN THE FLAGS
out.flags=in.flags;
out.flags.writtentostruct=1;
out.flags.zeropadded=1;


% Least Mean Squares algorithm
%
% From A. H. Sayed, "Fundamentals of adaptive filtering}", Wiley-IEEE
% Press, 2003, Chapter 5.
%
% This file is part of the Kernel Adaptive Filtering Toolbox for Matlab.
% https://github.com/steven2358/kafbox/

classdef lms < linear_filter

    properties (GetAccess = 'public', SetAccess = 'private')
        mu = 0.001; % learning rate
    end

    properties (GetAccess = 'public', SetAccess = 'private')
        w = []; % filter coefficients
    end

    methods
        function obj = lms(parameters) % constructor
            if (nargin > 0) % copy valid parameters
                for fn = fieldnames(parameters)'
                    if ismember(fn,fieldnames(obj))
                        obj.(fn{1}) = parameters.(fn{1});
                    end
                end
            end
        end

        function y_est = evaluate(obj,x) % evaluate the algorithm
            if numel(obj.w)>0
                y_est = x*obj.w;
            else
                y_est = zeros(size(x,1),1);
            end
        end

        function train(obj,x,y) % train the algorithm
            if numel(obj.w)==0 % initialize
                obj.w = zeros(length(x),1);
            end

            % Algorithm 5.2.1 in reference
            err = y - x*obj.w; % instantaneous error
            obj.w = obj.w + obj.mu*x'*err; % update filter coefficients
        end

    end
end


function [TW] = hpb2TW(hpb)
% Convert power from boiler horsepower to terawatts.
% Chad A. Greene 2012
TW = hpb*9809.5e-12;


function [ know, x ] = p11_sol ( )

%*****************************************************************************80
%
%% P11_SOL returns the solution for problem 11.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 February 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer KNOW.
%    If KNOW is 0, then the solution is not known.
%    If KNOW is positive, then the solution is known, and is returned in X.
%
%    Output, real X, the solution, if known.
%
  know = 1;

  x = 1.0 / 3.0;

  return
end


clc
clear all
seed = 601;
randn('state',seed); rand('state',seed);
tol = 5e-6; % optimality tolerance for stopping_type 1
DB=20; % SNR of the video
frame_array=[35,100,125]; % frames that will be shown at the end

global D X S
seed = 602;
randn('state',seed); rand('state',seed);
load Hall_airport_1000_1496_497_144_176_gray.mat;
D = images(:,1:201);
n1=144*176; n2=201;
stdev = norm(D,'fro')/(sqrt(144*176*201)*10^(DB/20))
D = D+stdev*randn(144*176,201);
[X,S]=nsa_v1(D,stdev,tol);
figure
plot_data(frame_array,D,X,S,144,176)


function [cpulse, verbose] = tapas_physio_findpeaks_template_xcorr(...
    c, pulseCleanedTemplate, cpulseSecondGuess, averageHeartRateInSamples, ...
    verbose, varargin)
% Finds peaks of a time series via pre-determined template via maxima of
% matlab cross correlations (xcorr) via going backward from search starting
% point in time series, and afterwards forward again
%
%   [cpulse, verbose] = tapas_physio_findpeaks_template_correlation(...
%       c, pulseCleanedTemplate, cpulseSecondGuess, ...
%           averageHeartRateInSamples, verbose)
%
% IN
%   varargin    property name/value pairs for additional options
%
%
% OUT
%
% EXAMPLE
%   tapas_physio_findpeaks_template_correlation
%
%   See also

% Author: Steffen Bollmann, cleanup, xcorr: Lars Kasper
% Created: 2014-08-05
% Copyright (C) 2014 TNU, Institute for Biomedical Engineering,
%                         University of Zurich and ETH Zurich.
%
% This file is part of the TAPAS PhysIO Toolbox, which is released under the terms of the GNU General Public
% Licence (GPL), version 3. You can redistribute it and/or modify it under the terms of the GPL
% (either version 3 or, at your option, any later version). For further details, see the file
% COPYING or <http://www.gnu.org/licenses/>.

% Determine starting peak for the search:
%   search for a representative R-peak a range of peaks

nSamples = size(c,1);

debug = verbose.level >= 4;

idxStartPeakSearch = [0 20];

halfTemplateWidthInSamples = floor(numel(pulseCleanedTemplate)/2);

[~,zTransformedTemplate] = tapas_physio_corrcoef12(pulseCleanedTemplate,...
    pulseCleanedTemplate);
isZTransformed = [0 1];

% start and end point of search for representative start cycle
centreSampleStart = round(2*halfTemplateWidthInSamples+1);

if idxStartPeakSearch(1) > 0
    centreSampleStart = centreSampleStart + ...
        cpulseSecondGuess(idxStartPeakSearch(1));
end
centreSampleEnd = cpulseSecondGuess(idxStartPeakSearch(2));

iSignalStart = centreSampleStart - halfTemplateWidthInSamples;
iSignalEnd = centreSampleEnd + halfTemplateWidthInSamples;
signalPart = c(iSignalStart:iSignalEnd);

similarityToTemplate = xcorr(zTransformedTemplate, flipud(signalPart));

% not needed, since only zero-filled
% similarityToTemplate = similarityToTemplate(1:centreSampleEnd);

[C_bestMatch, I_bestMatch] = max(similarityToTemplate);

%% now compute backwards to the beginning:
% go average heartbeat by heartbeat back and look (with
% decreasing weighting for higher distance) for highest
% correlation with template heartbeat

n = I_bestMatch;
bestPosition = n; % to capture case where 1st R-peak is best

peakNumber = 1;

similarityToTemplate = zeros(nSamples,1);

searchStepsTotal    = round(0.5*averageHeartRateInSamples);
searchPositionArray = -searchStepsTotal:searchStepsTotal;
nSamplesSignalPart  = 2*searchStepsTotal+1;
locationWeight      = ones(nSamplesSignalPart,1);

while n > 1+searchStepsTotal+halfTemplateWidthInSamples

    % Nested function, needs c, zTransformedTemplate, n, halfTemplateWidthInSamples,
    % searchStepsTotal, locationWeight
    similarityToTemplate(n+searchPositionArray) = ...
        get_similarity_to_template();

    %find biggest correlation-peak from the last search
    indexSearchStart    = n-searchStepsTotal;
    indexSearchEnd      = n+searchStepsTotal;

    indexSearchRange    = indexSearchStart:indexSearchEnd;
    searchRangeValues   = similarityToTemplate(indexSearchRange);
    [C_bestMatch,I_bestMatch] = max(searchRangeValues);
    bestPosition = indexSearchRange(I_bestMatch);

    cpulse(peakNumber) = bestPosition;
    peakNumber = peakNumber+1;

    n=bestPosition-averageHeartRateInSamples;
end % END: going backwards to beginning of time course

%% Now go forward through the whole time series
n           = bestPosition; % 1st R-peak
peakNumber  = 1;
clear cpulse;

% Now correlate template with PPU signal at the positions
% where we would expect a peak based on the average heartrate and
% search in the neighborhood for the best peak, but weight the peaks
% deviating from the initial starting point by a gaussian
searchStepsTotal = round(0.5*averageHeartRateInSamples);

% for weighted searching of max correlation
locationWeight = tapas_physio_gausswin(nSamplesSignalPart);

n = max(n, searchStepsTotal + halfTemplateWidthInSamples + 1);

% zero-pad c at end to allow for detection of last peak by
% template-matching up to the last sample of c
c = [c; zeros(searchStepsTotal + halfTemplateWidthInSamples + 1, 1)];

while n < nSamples % -searchStepsTotal - halfTemplateWidthInSamples

     similarityToTemplate(n+searchPositionArray) = ...
         get_similarity_to_template();

    %find biggest correlation-peak from the last search
    indexSearchStart    = n - searchStepsTotal;
    indexSearchEnd      = n + searchStepsTotal;

    indexSearchRange    = indexSearchStart:indexSearchEnd;
    searchRangeValues   = similarityToTemplate(indexSearchRange);
    [C_bestMatch,I_bestMatch] = max(searchRangeValues);
    bestPosition        = indexSearchRange(I_bestMatch);

    cpulse(peakNumber) = bestPosition;
    peakNumber = peakNumber+1;

    %only take the last 20 cpulses to compute the current HeartRate
    foundCpulses = size(cpulse,2);

    if  foundCpulses < 3
        currentHeartRateInSamples=averageHeartRateInSamples;
    end

    if (foundCpulses < 21) && (foundCpulses >= 3)
        currentHeartRateInSamples = round(mean(diff(cpulse)));
    end

    if foundCpulses >= 21
        currentCpulses = cpulse (foundCpulses-20:foundCpulses);
        currentHeartRateInSamples = round(mean(diff(currentCpulses)));
    end

    %check currentHeartRate
    checkSmaller    = currentHeartRateInSamples > 0.5*averageHeartRateInSamples;
    checkLarger     = currentHeartRateInSamples < 1.5*averageHeartRateInSamples;

    %jumpToNextPeakSearchArea
    if (checkSmaller && checkLarger)
        n = bestPosition + currentHeartRateInSamples;
    else
        n = bestPosition + averageHeartRateInSamples;
    end
end

%% Nested function,
% computes point-wise similarity (cross-correlation) of time course snippet
% to given peak template (z-transformed)
% nested function to improve performance
%
% needs c, zTransformedTemplate, n, halfTemplateWidthInSamples,
% searchStepsTotal, searchPositionArray, locationWeight
    function similarityToTemplateTmp = get_similarity_to_template()
        % (c, zTransformedTemplate, n, halfTemplateWidthInSamples, searchStepsTotal, locationWeight);
        iSignalStart    = n - halfTemplateWidthInSamples - searchStepsTotal;
        iSignalEnd      = n + halfTemplateWidthInSamples + searchStepsTotal;

        signalPart = c(iSignalStart:iSignalEnd);
        similarityToTemplateTmp = ...
            xcorr(zTransformedTemplate, flipud(signalPart));
        similarityToTemplateTmp = similarityToTemplateTmp(1:nSamplesSignalPart);
        % crop beginning and end
        %similarityToTemplateTmp(1:halfTemplateWidthInSamples) = [];
        %similarityToTemplateTmp(end-halfTemplateWidthInSamples+1:end) = [];

        % reweight correlations with distance from expected heart beat
        amplitudeWeight = abs(c((n+1)-searchPositionArray));
        similarityToTemplateTmp =  locationWeight.*amplitudeWeight .* ...
            similarityToTemplateTmp;

    end

end


function n = exploration_noise(t, params)
n = params.noiseLevel * sin(1*t) + ...
    params.noiseLevel * sin(7*t)  + ...
    params.noiseLevel * sin(3*t);
end


function A = slgda(K, nums, sol)
%SLGDA Performs Baudat's Generalized Discriminant Analysis
%
% $ Syntax $
%   - A = slgda(K, nums)
%   - A = slgda(K, nums, sol)
%
% $ Arguments $
%   - K:        the kernel gram matrix
%   - nums:     the numbers of samples in each classes
%   - sol:      the cell containing the parameter for generalized eigen
%               decomposition
%   - A:        the resulting projection coefficient matrix
%
% $ Description $
%   - A = slgda(K, nums) performs Generalized Discriminant Analysis(GDA),
%     an representative work in using kernel method to extend LDA,
%     proposed by Baudat et al. The generalized eigen-problem is
%     solved in a default way by slsymgeig.
%
%   - A = slgda(K, nums, sol) in the function, slsymgeig will be invoked
%     to solve the generalized eigen-decomposition problem. sol is
%     a cell containing the parameters for slsymgeig.
%
% $ Remarks $
%   - The function follows the instructions given in the original paper
%     on GDA.
%
%   - The projection is learned after the kernel gram matrix is
%     centralized.
%
%   - The aim of the function is to give an exact implementation of
%     of representative work GDA, so it does not offer other facilities
%     such as weighting and other ways of scatter computation. For higher
%     flexibility, please use the function slkfd.
%
% $ History $
%   - Created by Dahua Lin on May 3rd, 2005
%

%% parse and verify input arguments

if nargin < 2
    raise_lackinput('slkernelscatter', 2);
end

if ndims(K) ~= 2 || size(K, 1) ~= size(K, 2)
    error('sltoolbox:invaliddims', ...
        'The gram matrix K should be a square matrix');
end

M = size(K, 1);         % number of samples
N = length(nums);       % number of classes
if ~isequal(size(nums), [1, N])
    error('sltoolbox:invaliddims', ...
        'The nums should be a 1 x N row vector');
end
if sum(nums) ~= M
    error('sltoolbox:sizmismatch', ...
        'The total number in nums is inconsistent with that in K');
end

if nargin < 3
    sol = {};
end

%% Compute

%% Centralize

K = slcenkernel(K);

%% Construct the eigen-problem

[sp, ep] = slnums2bounds(nums);
W = zeros(M, M);
for i = 1 : N
    ni = nums(i);
    spi = sp(i); epi = ep(i);
    W(spi:epi, spi:epi) = 1 / ni;
end
clear sp ep;

B = K * W * K;
clear W;

V = K * K;

%% Resolve the eigen-problem

[evs, A] = slsymgeig(B, V, sol{:});
d = sldim_by_eigval(evs);
A = A(:, 1:d);


% K-nearest Neighbor (9/12/2020)

function Acc = jknn(feat,label,opts)
% Default of k-value
k = 5;

if isfield(opts,'k'), k = opts.k; end
if isfield(opts,'Model'), Model = opts.Model; end

% Define training & validation sets
trainIdx = Model.training;    testIdx = Model.test;
xtrain   = feat(trainIdx,:);  ytrain  = label(trainIdx);
xvalid   = feat(testIdx,:);   yvalid  = label(testIdx);
% Training model
My_Model = fitcknn(xtrain,ytrain,'NumNeighbors',k);
% Prediction
pred     = predict(My_Model,xvalid);
% Accuracy
Acc      = sum(pred == yvalid) / length(yvalid);

fprintf('\n Accuracy: %g %%',100 * Acc);
end


classdef CEC2008_F5 < PROBLEM
% <single> <real> <large/none> <expensive/none>
% Shifted Griewank's function

%------------------------------- Reference --------------------------------
% K. Tang, X. Yao, P. N. Suganthan, C. MacNish, Y.-P. Chen, C.-M. Chen, and
% Z. Yang, Benchmark functions for the CEC'2008 special session and
% competition on large scale global optimization, Nature Inspired
% Computation and Applications Laboratory, USTC, China, 2007.
%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

    properties
        O;  % Optimal decision vector
    end
    methods
        %% Default settings of the problem
        function Setting(obj)
            CallStack = dbstack('-completenames');
            load(fullfile(fileparts(CallStack(1).file),'CEC2008.mat'),'Data');
            obj.O = Data{5};
            obj.M = 1;
            if isempty(obj.D); obj.D = 100; end
            obj.D = min(obj.D,length(obj.O));
            obj.lower    = zeros(1,obj.D) - 600;
            obj.upper    = zeros(1,obj.D) + 600;
            obj.encoding = ones(1,obj.D);
        end
        %% Calculate objective values
        function PopObj = CalObj(obj,PopDec)
            Z = PopDec - repmat(obj.O(1:size(PopDec,2)),size(PopDec,1),1);
            PopObj = 1/4000*sum(Z.^2,2) - prod(cos(Z./sqrt(repmat(1:size(Z,2),size(Z,1),1))),2) + 1;
        end
    end
end


function y = modulate2(x, type, center)
% MODULATE2	2D modulation
%
%	y = modulate2(x, type, [center])
%
% With TYPE = {'r', 'c' or 'b'} for modulate along the row, or column or
% both directions.
%
% CENTER secify the origin of modulation as floor(size(x)/2)+1+center
% (default is [0, 0])

if ~exist('center', 'var')
    center = [0, 0];
end

% Size and origin
s = size(x);
o = floor(s / 2) + 1 + center;

n1 = [1:s(1)] - o(1);
n2 = [1:s(2)] - o(2);

switch lower(type(1))
    case 'r'
	m1 = (-1) .^ n1;
	y = x .* repmat(m1', [1, s(2)]);

    case 'c'
	m2 = (-1) .^ n2;
	y = x .* repmat(m2, [s(1), 1]);

    case 'b'
	m1 = (-1) .^ n1;
	m2 = (-1) .^ n2;
	m = m1' * m2;
	y = x .* m;

    otherwise
	error('Invalid input type');
end


function stroud_test35 ( )

%*****************************************************************************80
%
%% TEST35 tests SQUARE_UNIT_SET, RECTANGLE_SUB_2D.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 April 2009
%
%  Author:
%
%    John Burkardt
%
  global FUNC_2D_INDEX;

  num = function_2d_num ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST35\n' );
  fprintf ( 1, '  SQUARE_UNIT_SET sets up a quadrature rule\n' );
  fprintf ( 1, '    on a unit square.\n' );
  fprintf ( 1, '  RECTANGLE_SUB_2D applies it to subrectangles of an\n' );
  fprintf ( 1, '    arbitrary rectangle.\n' );
  fprintf ( 1, '\n' );
%
%  Set the location of the square.
%
  xval(1) = 1.0;
  yval(1) = 2.0;

  xval(2) = 3.0;
  yval(2) = 3.0;

  fprintf ( 1, '\n' );
  fprintf ( 1, '  The corners of the rectangle are:\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  %12f  %12f\n', xval(1), yval(1) );
  fprintf ( 1, '  %12f  %12f\n', xval(2), yval(2) );
%
%  Get the quadrature abscissas and weights for a unit square.
%
  rule = 2;

  order = square_unit_set ( rule );

  [ xtab, ytab, weight ] = square_unit_set ( rule, order );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Using unit square integration rule number %d\n', rule );
%
%  Set the function.
%
  for i = 1 : num

    FUNC_2D_INDEX = i;
%
%  Try an increasing number of subdivisions.
%
    fprintf ( 1, '\n' );
    fprintf ( 1, '    Function  Subdivisions  Integral\n' );
    fprintf ( 1, '\n' );

    for j = 1 : 5

      nsub(1) = j;
      nsub(2) = 2 * j;

      result = rectangle_sub_2d ( 'function_2d', xval, yval, nsub, order, xtab, ...
        ytab, weight );

      fname = function_2d_name ( i );

      fprintf ( 1, '  %s  %2d  %2d  %14f\n', fname, nsub(1), nsub(2), result );

    end

  end

  return
end


function uknt = kntunclamp (knt, deg, k, dim)
% KNTUNCLAMP: Compute the unclamped knot vector starting from an open one.
%
% Calling Sequence:
%
%   uknt = kntunclamp (knt, deg, k)
%   uknt = kntunclamp (knt, deg, k, dim)
%
% INPUT:
%
%   knt	: open knot vector: see kntrefine
%   deg : polynomial degree of the spline space
%   k   : continuity for the unclamping (from 0 up to p-1)
%   dim : dimensions in which to unclamp (all by default).
%
% OUTPUT:
%
%   uknt: unclamped knot vector, see nrbmak
%
% Description:
%
%     Unclamps directly the open knot vector. See nrbunclamp
%    for further information.
%
%    Copyright (C) 2013, 2014 Rafael Vazquez
%    Copyright (C) 2020, Bernard Kapidani
%
%    This program is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.

%    This program is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with this program.  If not, see <http://www.gnu.org/licenses/>.

  knt_is_cell = true;
  if (~iscell (knt))
    knt = {knt};
    knt_is_cell = false;
  end
  uknt = knt;

  ndim = numel (knt);
  if (nargin < 4)
    dim = 1:ndim;
  end

% if (iscell (knt))
  if (numel(k) < ndim)
    k = [k(:).', k(end) * ones(1, ndim-numel(k))];
  end

  assert (numel(deg) == ndim, 'degrees and knots must have the same size');
  for idim = dim

    U  = knt{idim};

    p  = deg(idim);
    n  = numel(U) - p - 1;
    m  = n + p + 1;
    kk = k(idim);

    if (kk >= p)
      warning ('Taking the maximum k allowed, degree - 1')
      kk = p - 1;
    end

  % Unclamp at left end
    for ii=0:kk
      U(kk-ii+1) = U(kk-ii+2) - (U(n+1-ii) - U(n-ii));
    end

  % Unclamp at right end
    for ii=0:kk
      U(m-kk+ii) = U(m-kk+ii-1) + U(p+ii+1+1) - U(p+ii+1);
    end

    uknt{idim} = U;

  end

  if (~knt_is_cell)
    uknt = uknt{1};
  end

end


function Line=findlyap(MainHandles)
%FINDLYAP  determines the Lyapunov exponents and dimension
%
%    The alogrithm employed in this toolbox for determining Lyapunov
%    exponents is according to the algorithms proposed in
%
%    [1] A. Wolf, J. B. Swift, H. L. Swinney, and J. A. Vastano,
%        "Determining Lyapunov Exponents from a Time Series," Physica D,
%        Vol. 16, pp. 285-317, 1985.
%
%    [2] J. P. Eckmann and D. Ruelle, "Ergodic Theory of Chaos and Strange
%        Attractors," Rev. Mod. Phys., Vol. 57, pp. 617-656, 1985.
%
%    The algorithm given in [1] is used for first-order systems while
%    the QR-based algorithm proposed in [2] is applied for higher order
%    systems.

%   by Steve W. K. SIU, July 5, 1998.

%Print the results to the file every iteration
PrintStep=10;
%Display the results on the screen every iteration
DisplayStep=1;

%Clear the current axis objects
cla;
v=axis;
xc=(v(2)+v(1))/2;	%Center of the axis box [xc,y]
y=(v(4)+v(3))/2;
aW=v(2)-v(1);		%Axis width
x=xc-1/4*aW;

%Display the text "Loading... Please wait!"
th=text(x,y,'Loading... Please wait!','Color','r','FontSize',15,...
   	'FontAngle','italic');
drawnow;
%Clear the bottom text if any
set(MainHandles(1),'String','');

%Get the data stored in 'UserData' of the setting button
DATA=get(MainHandles(4),'UserData');
%Restore the data input by the user
output=DATA(1);		%Output checkbox: "on"=1; "off"=0
LEout=DATA(2);			%Output Lyapunov exponents to file: "yes"=1; "no"=0
LEprec=DATA(3);      %Precision of the output Lyapunov exponents
LDout=DATA(4);			%Output Lyapunov dimension to file: "yes"=1; "no"=0
LDprec=DATA(5);      %Precision of the Lyapunov dimension
IntMethod=DATA(6);	%Integration method: 1=Discrete map, 2=ODE45, 3=ODE23
							% 4=ODE113, 5=ODE23S, 6=ODE15S
InitialTime=DATA(7);	%Initial time
FinalTime=DATA(8);	%Final time
TimeStep=DATA(9);		%Time step
RelTol=DATA(10);		%Relative tolerance
AbsTol=DATA(11);		%Absolute tolerance
plot1=DATA(12);		%Plot imediately: 1="checked", 0="unchecked"
plot2=DATA(13);		%Plot according to specified iterations
ItrNum=DATA(14);		%No. of iteration for updating the plot
Color=DATA(15);		%Line Color option
							%Line color: 1="blue", 2="balck", 3="green", 4="red",
                     %5="yellow", 6="magenta", 7="cyan"
DiscardItr=DATA(16);	%Iterations to be discarded
UpdateStepNum=DATA(17);	%Lyapunov exponents updating steps
linODEnum=DATA(18);	%No. of linearized ODEs
ic=DATA(19:length(DATA));	%Initial conditions

%Get the output file and ODE function names stored in
%'UserData' of the "Start" button.
%Handles(2) is the handle of "Start" button
NAMES=get(MainHandles(2),'UserData');
OutputFile=rmspace(NAMES(1,:));
odefun=rmspace(NAMES(2,:));

%Construct a look-up table for the line colors
COLORS='bkgrymc';
%Map the "Line color" pop-up menu position to the look-up table
LineColor=COLORS(Color);

%Construct a look-up table for integration methods
Methods=char('Discrete map', 'ode45','ode23','ode113','ode23s','ode15s');
ODEsolver=strcat(Methods(IntMethod,:));

%Dimension of the linearized system (total: d x d ODEs)
d=sqrt(linODEnum);
%Initial conditions for the linearized ODEs
Q0=eye(d);
IC=[ic(:);Q0(:)];
ICnum=length(IC);		%Total no. of initial coniditions
%One iteration: Duration for updating the LEs
Iteration=UpdateStepNum*TimeStep;
DiscardTime=DiscardItr*Iteration+InitialTime;

%MATLAB's ODE functions will give the intermediate solutions if
%the duration between the initial time and the final time is only
%one time step, this will slow down the whole iteration process.
%To avoid this, reduce the time step by half.
if (UpdateStepNum==1 & IntMethod~=3)
   TimeStep=TimeStep/2;
end

T1=InitialTime;
T2=T1+Iteration;
TSpan=[T1:TimeStep:T2];
%Absolute tolerance of each components is set to the same value
options=odeset('RelTol',RelTol,'AbsTol',ones(1,ICnum)*AbsTol);

%Initialize variables
n=0;			%Iteration counter
k=0;			%Effective iteration counter
				% (discarded iterations are not counted)
h=1;			%No. of line handles sets (1 set = d line handles)
delLine=0;  %Indicator for deleting the drawn lines
Sum=zeros(1,d);
xData=[];
yData=[];
Line=[];
bufferSize=10000; %Max. no. of data can be stored in the buffer before creating a new line.
if ( output & (LEout | LDout) )
   %If the output file cannot be opened, warn the user
   msg=['Unable to open "' sprintf(OutputFile) '".'];
   Warn='errordlg(msg,''ERROR'',''replace''); problem=1;';
   eval('fid=fopen(OutputFile,''wt''); problem=0;',Warn)
   %Construct a look-up table for precision format
   Prec=char('%.4f','%.6f','%.8f','%.10f','%.12f');
   %Map the pop-up menu position to its corresponding format
   LEprecision=strcat(Prec(LEprec,:));
   LDprecision=strcat(Prec(LDprec,:));
   if ~problem
      fprintf(fid,'Time');
      if LEout
         for i=1:d
            Str1=['\tLE%d'];
            fprintf(fid,Str1,i);
         end
      end
      if LDout
         Str2=['\tLD'];
         fprintf(fid,Str2);
      end
      fprintf(fid,'\n');
   end
else
   problem=0;
end

%Start the stop watch
tic;
%Get the state of the "Stop" button
stop=get(MainHandles(3),'UserData');
if DiscardTime>0
   %Display the text "Discarding transient steps..."
   set(MainHandles(1),'String','Discarding transient steps...');
end

A=[];

%String that contains the integration command
IntegrationStr=['[t,X]=',ODEsolver,'(odefun,TSpan,IC,options);'];
%Main loop
while (~stop & ~problem)
   n=n+1;
   %Integration
   if IntMethod>1
      eval(IntegrationStr);
   else	%If it is a discrete map
      for i=1:UpdateStepNum
         X(i,:)=(feval(odefun,IC))';
      end
   end
   [rX,cX]=size(X);
   L=cX-linODEnum;      %No. of initial conditions for
                        %the original system
   for i=1:d
      m1=L+1+(i-1)*d;
      m2=m1+d-1;
      A(:,i)=(X(rX,m1:m2))';
   end
   %QR decomposition
   if d>1
      %The algorithm for 1st-order system doesn't require
      %QR decomposition
      [Q,R]=qr(A);
      if T2>DiscardTime
         Q0=Q;
      else
         Q0=eye(d);
      end
   else
      R=A;
   end

   %Delete the text "Loading...Please wait!"
   %before the first iteration
   if n==1
      delete(th);
      drawnow;
      %Display the final time
      set(MainHandles(11),'String',FinalTime);
   end

  %Any zero diagonal element will cause overflow
  %in the following calculation, so discard this step.
   permission=1;
   for i=1:d
      if R(i,i)==0
         permission=0;
         break;
      end
   end
  %To determine the Lyapunov exponents
   if (T2>DiscardTime & permission)
      k=k+1;
      T=k*Iteration;
      TT=n*Iteration+InitialTime;
      %There are d Lyapunov exponents
      Sum=Sum+log(abs(diag(R))');
      lambda=Sum/T;

      %Sort the Lyapunov exponents in descenting order
      Lambda=fliplr(sort(lambda));
      %To calculate the Lyapunov dimension (or Kaplan-Yorke dimension)
      LESum=Lambda(1);
      LD=0;
      if (d>1 & Lambda(1)>0)
         for N=1:d-1
            if Lambda(N+1)~=0
               LD=N+LESum/abs(Lambda(N+1));
               LESum=LESum+Lambda(N+1);
               if LESum<0
                  break;
               end
            end
         end
      end
      %Store the [x,y] data for plotting
      [rxD,cxD]=size(xData);
      [ryD,cyD]=size(yData);
      if rxD<=bufferSize
         xData=[xData;TT];
         yData=[yData;lambda];
      else
         %When the buffers are full, refresh them
         %Max. size of buffers = 10000 data
         xData=[xData(rxD);TT];
         yData=[yData(ryD,:);lambda];
         h=h+1;		%add one set of line handles
         delLine=0;	%After refreshing the buffers, the
                     % previous drawn lines must not be deleted
      end

      if ( output & ~problem & (LEout | LDout) & rem(k,PrintStep)==0)
         fprintf(fid,'%.2f',TT);
         if LEout
            for i=1:d
               Str1=['\t',LEprecision];
               fprintf(fid,Str1,Lambda(i));
            end
         end
         if LDout
            Str2=['\t',LDprecision];
            fprintf(fid,Str2,LD);
         end
         fprintf(fid,'\n');
      end

      %Draw lines immediately if "update the plot immediately" was chosen.
      if (plot1==1 | plot2==1 & rem(k,ItrNum)==0)
         if delLine
            %Clear the previous drawn line if any
            delete(Line(h,:));
         end
      	%Draw d lines
         for i=1:d
            %Set "Erase Mode" to "none" for increasing speed (less refresh)
            Line(h,i)=line('EraseMode','none','Color',LineColor,...
                      'xData',xData,'yData',yData(:,i));
            %Force MATLAB to draw immediately
            drawnow;
         end
         delLine=1;	%Set a flag to indicate that the lines now can be deleted
      end
      %Display the calculated Lyapunov exponents
      if rem(k,DisplayStep)==0
         set(MainHandles(1),'String',[num2str(Lambda),blanks(3),'( ',num2str(LD),' )']);
      end
   end

   %To see whether "Stop" is pressed
   stop=get(MainHandles(3),'UserData');

   %Display current time, and time used
   set(MainHandles(10),'String',num2str(round(T2)));		%Current time
   set(MainHandles(12),'String',num2str(round(toc)));		%Used time
   drawnow;

   %If calculation is finished or "stop" button is pressed, exit the loop.
   if (stop | T2>=FinalTime)
      %Reset the "Erase mode" to normal
      set(Line,'EraseMode','normal');
      %Show the final results (for making sure the final results being shown if DisplayStep>1)
      if (T2>DiscardTime & permission)
         set(MainHandles(1),'String',[num2str(Lambda),blanks(3),'( ',num2str(LD),' )']);
      end
      break;
   end
   %Update the initial conditions and time span for the next iteration
   if IntMethod>1
      ic=X(rX,1:L);
      T1=T1+Iteration;
      T2=T2+Iteration;
      TSpan=[T1:TimeStep:T2];
   else %For discrete map
      ic=X(UpdateStepNum,1:L);
      T2=T2+Iteration;
   end
   IC=[ic(:);Q0(:)];
end		%End of main loop

if T2>=FinalTime
   set(MainHandles([2,4,13,15]),'Enable','On');
   set(MainHandles(3),'Enable','Off');
end
if (output & ~problem)
   fclose(fid);
end

%----------------Subroutine-----------------------------------
function outStr=rmspace(inStr)
%RMSPACE		Function for removing the beginning and ending
%				spaces of a string

%Remove spaces at the end of the string
outStr=strcat(inStr);
%Delete spaces at the beginning of the string
if ~isempty(outStr)
   while isspace(outStr(1))
   	outStr=outStr(2:length(outStr));
   end
end


function [ n_data, x, cbi ] = airy_cbi_values ( n_data )

%*****************************************************************************80
%
%% AIRY_CBI_VALUES returns some values of the Airy Bi(x) with complex argument.
%
%  Discussion:
%
%    The Airy functions Ai(X) and Bi(X) are a pair of linearly independent
%    solutions of the differential equation:
%
%      W'' - X * W = 0
%
%    In Mathematica, the function can be evaluated by:
%
%      AiryBi[x]
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    13 April 2007
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Milton Abramowitz, Irene Stegun,
%    Handbook of Mathematical Functions,
%    National Bureau of Standards, 1964,
%    ISBN: 0-486-61272-4,
%    LC: QA47.A34.
%
%    Stephen Wolfram,
%    The Mathematica Book,
%    Fourth Edition,
%    Cambridge University Press, 1999,
%    ISBN: 0-521-64314-7,
%    LC: QA76.95.W65.
%
%  Parameters:
%
%    Input/output, integer N_DATA.  The user sets N_DATA to 0 before the
%    first call.  On each call, the routine increments N_DATA by 1, and
%    returns the corresponding data; when there is no more data, the
%    output value of N_DATA will be 0 again.
%
%    Output, complex X, the argument of the function.
%
%    Output, complex CBI, the value of the Airy BI function.
%
  n_max = 10;

  cbi_vec = [ ...
    1.207423594952871  + 0.0000000000000000 * i, ...
    0.9127160108293936 + 0.3800456133135556 * i, ...
    0.6824453575635721 + 0.3343047153635002 * i, ...
    0.5726265660086474 + 0.3988641086982559 * i, ...
    0.2511841251049547 + 0.3401447690712719 * i, ...
    0.1039973894969446 + 0.0000000000000000 * i, ...
    0.2511841251049547 - 0.3401447690712719 * i, ...
    0.5726265660086474 - 0.3988641086982559 * i, ...
    0.6824453575635721 - 0.3343047153635002 * i, ...
    0.9127160108293936 - 0.3800456133135556 * i ];

  x_vec = [ ...
     1.0000000000000000 + 0.0000000000000000 * i, ...
     0.8090169943749474 + 0.5877852522924731 * i, ...
     0.3090169943749474 + 0.9510565162951536 * i, ...
    -0.3090169943749474 + 0.9510565162951536 * i, ...
    -0.8090169943749474 + 0.5877852522924731 * i, ...
    -1.0000000000000000 + 0.0000000000000000 * i, ...
    -0.8090169943749474 - 0.5877852522924731 * i, ...
    -0.3090169943749474 - 0.9510565162951536 * i, ...
     0.3090169943749474 - 0.9510565162951536 * i, ...
     0.8090169943749474 - 0.5877852522924731 * i ];

  if ( n_data < 0 )
    n_data = 0;
  end

  n_data = n_data + 1;

  if ( n_max < n_data )
    n_data = 0;
    x = 0.0;
    cbi = 0.0;
  else
    x = x_vec(n_data);
    cbi = cbi_vec(n_data);
  end

  return
end


function z=fun00(x)
z=0;
for i=1:length(x)
    z=z+x(i)*sin(abs(x(i)));
end


function u = acsc(a)
%ACSC         Slope inverse cosecant acsc(a)
%

% written  12/06/98     S.M. Rump
% modified 04/04/04     S.M. Rump  set round to nearest for safety
% modified 04/06/05     S.M. Rump  rounding unchanged
% modified 09/28/08     S.M. Rump  check for rounding to nearest improved
% modified 08/26/12     S.M. Rump  global variables removed
%

  e = 1e-30;
  if 1+e==1-e                           % fast check for rounding to nearest
    rndold = 0;
  else
    rndold = getround;
    setround(0)
  end

  INTLAB_SLOPE = getappdata(0,'INTLAB_SLOPE');

  u = a;

  u.r = acsc(a.r);
  indexc = 1:INTLAB_SLOPE.NUMVAR;
  indexr = 2:INTLAB_SLOPE.NUMVAR+1;
  Xxs = hull(a.r(:,indexc),a.r(:,indexr));
  Index = 1:size(a.r.inf,1);

  index = all( a.r.sup<=0 , 2);
  if any(index)
    aindex.r = a.r(index,:);
    aindex.s = a.s(index,:);
    u.s(index,:) = ...
      slopeconvexconcave('acsc','-1./(abs(%).*sqrt(sqr(%)-1))',aindex,0);
    Index(index) = 0;
  end

  index = all( a.r.inf>=0 , 2);
  if any(index)
    aindex.r = a.r(index,:);
    aindex.s = a.s(index,:);
    u.s(index,:) = ...
      slopeconvexconcave('acsc','-1./(abs(%).*sqrt(sqr(%)-1))',aindex,1);
    Index(index) = 0;
  end

  if any(Index)
    Index( Index==0 ) = [];
    Xxs = Xxs(Index);
    u.s(Index,:) = - a.s(Index,:) ./ ( abs(Xxs) .* sqrt( sqr(Xxs)-1 ) );
  end

  if rndold
    setround(rndold)
  end


function varargout = nifti_stats(varargin)
% Conversion among various statistics
% FORMAT P = nifti_stats(VAL,CODE,OPT,PARAM)
%   CODE can be one of
%     'CORREL'      'TTEST'       'FTEST'       'ZSCORE'
%     'CHISQ'       'BETA'        'BINOM'       'GAMMA'
%     'POISSON'     'NORMAL'      'FTEST_NONC'  'CHISQ_NONC'
%     'LOGISTIC'    'LAPLACE'     'UNIFORM'     'TTEST_NONC'
%     'WEIBULL'     'CHI'         'INVGAUSS'    'EXTVAL'
%     'PVAL'
%   With only one input argument, CODE defaults to 'ZSCORE'
%
%   OPT can be one of
%     '-p' ==> output P = Prob(statistic < VAL).
%     '-q' ==> output is 1-p.
%     '-d' ==> output is probability density.
%     '-1' ==> output is X such that Prob(statistic < x) = VAL.
%     '-z' ==> output is Z such that Normal cdf(Z) = p(VAL).
%     '-h' ==> output is Z such that 1/2-Normal cdf(Z) = p(VAL).
%   With less than three input arguments, OPT defaults to '-p'.
%
%   PARAM are up to three distribution parameters.
%   These default to zero if unspecified.
%
%   P is an array with the same dimensions as VAL.
%
%__________________________________________________________________________
% 99.99% of the work by RW Cox - SSCC/NIMH/NIH/DHHS/USA/EARTH - March 2004
%  0.01% of the work (the mex wrapper) by John Ashburner - FIL/ION/UCL
% Copyright (C) 2005-2017 Wellcome Trust Centre for Neuroimaging

%
% $Id: nifti_stats.m 7147 2017-08-03 14:07:01Z spm $

fprintf('******************************************\n');
fprintf('Compile the nifti_stats function with\n');
fprintf('    mex nifti_stats.c nifti_stats_mex.c -O\n');
fprintf('******************************************\n');

error('nifti_stats is not compiled.');


function val = m00Q0011(F00, F11)
%------------------------------------------------------------------------------
%
% Integrates interpolated gridfunction F on quincunx grid (F00 united with F11)
% where interpolation is assumed piecewise constant.
%
%
% Design and implementation by:
% Dr. Paul M. de Zeeuw <Paul.de.Zeeuw@cwi.nl>  http://homepages.cwi.nl/~pauldz/
% Last Revision: February 1, 2001.
%  2001 Stichting CWI, Amsterdam
%------------------------------------------------------------------------------
[hx, hy] = Q0011gridfdims(F00, F11);
Qhxy = 2 * hx * hy;
val = ( sum(sum(F00)) + sum(sum(F11)) ) * Qhxy;
%------------------------------------------------------------------------------