function sphere_grid_test07 ( )

%*****************************************************************************80
%
%% SPHERE_GRID_TEST07 tests SPHERE_GRID_Q4.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 August 2010
%
%  Author:
%
%    John Burkardt
%
  lat_num = 3;
  long_num = 4;
  rectangle_num = lat_num * long_num;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'SPHERE_GRID_TEST07\n' );
  fprintf ( 1, '  SPHERE_GRID_Q4 computes a grid\n' );
  fprintf ( 1, '  of Q4 rectangular elements on a sphere in 3D.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Number of latitudes is      %d\n', lat_num );
  fprintf ( 1, '  Number of longitudes is     %d\n', long_num );
  fprintf ( 1, '  The number of rectangles is %d\n', rectangle_num );

  rectangle_node = sphere_grid_q4 ( lat_num, long_num );

  i4mat_transpose_print ( 4, rectangle_num, rectangle_node, ...
    '  Rectangle vertices:' );

  return
end


function test_suite = test_confusion_matrix
% tests for cosmo_confusion_matrix
%
% #   For CoSMoMVPA's copyright information and license terms,   #
% #   see the COPYING file distributed with CoSMoMVPA.           #
    try % assignment of 'localfunctions' is necessary in Matlab >= 2016
        test_functions=localfunctions();
    catch % no problem; early Matlab versions can use initTestSuite fine
    end
    initTestSuite;

function classes=test_confusion_matrix_basics()
    nsamples=30;
    ntargets=5;
    delta=10;

    targets=[ceil(ntargets*rand(nsamples,1));randperm(ntargets)']+delta;
    predicted=[ceil(ntargets*rand(nsamples,1));randperm(ntargets)']+delta;

    [mx,classes]=cosmo_confusion_matrix(targets,predicted);

    assertEqual(classes,delta+(1:ntargets)');

    assertEqual(size(mx),[ntargets,ntargets]);

    for k=1:ntargets
        for j=1:ntargets
            count=sum(targets==(k+delta) & predicted==(j+delta));
            assertEqual(count, mx(k,j));
        end
    end

    ds=struct();
    ds.samples=predicted;
    ds.sa.targets=targets;

    [mx2,classes2]=cosmo_confusion_matrix(ds);
    assertEqual(mx,mx2);
    assertEqual(classes,classes2);

    predicted3=predicted(randperm(numel(predicted)));
    mx3=cosmo_confusion_matrix(targets,predicted3);

    ds.samples=[predicted predicted3(:)];
    [mx_both,classes3]=cosmo_confusion_matrix(ds);
    assertEqual(mx_both,cat(3,mx2,mx3));
    assertEqual(classes3,classes);

function test_confusion_matrix_exceptions
    aet=@(varargin)assertExceptionThrown(@()...
                            cosmo_confusion_matrix(varargin{:}),'');
    % size mismatch
    aet([1;1],1);

    % missing target
    aet([1;1],[1;2]);

    % no dataset
    aet(struct());
    aet({});

    ds=struct();
    ds.samples=1;
    aet(ds,1);
    ds.sa.targets=1;
    % second argument with dataset
    aet(ds,1);

    % missing argument with numeric
    aet(1)

    % target row vector
    aet([1 1],[1;1])
    aet([1;1],[1 1])

    % no target vector
    aet(eye(2),[1;1]);

    % no target vector
    aet(ones([2 2 2]),[1;1]);
    aet([1;1], ones([2 2 2]));


function test_deep_nmf(varargin)
%
% demonstration file for NMFLibrary.
%
% This file is part of NMFLibrary.
%
% Created by H.Kasai on Apr. 05, 2017

    if nargin < 1
        clc;
        clear;
        close all;
        rng('default')

        m = 300;
        n = 500;
        V = rand(m,n);
        options = [];
        options.verbose = 1;
        options.max_epoch = 100;
        health_check_mode = false;
    else
        V = varargin{1};
        %rank = varargin{2};
        options = varargin{3};
        health_check_mode = true;
    end

    %% Initialize of rank to be factorized
    rank_layers = [49 25 16];

    %% Deep-Semi-NMF
    [w_deep_semi_nmf, infos_deep_semi_nmf] = deep_semi_nmf(V, rank_layers, options);

    %% Deep-ns-NMF
    options.theta = 0.5;
    %options.update_alg = 'mu';
    options.update_alg = 'apg';
    options.apg_maxiter = 10;
    [w_deep_ns_nmf, infos_deep_ns_nmf] = deep_ns_nmf(V, rank_layers, options);

    [w_deep_bi_nmf, infos_deep_bi_nmf] = deep_bidirectional_nmf(V, rank_layers, options);

    %% Plotting
    if ~health_check_mode
        display_graph('iter','cost', {'Deep-SemiNMF', 'Deep-nsNMF', 'Deep-Bidir-SemiNMF'}, {w_deep_semi_nmf, w_deep_ns_nmf, w_deep_bi_nmf}, {infos_deep_semi_nmf, infos_deep_ns_nmf, infos_deep_bi_nmf});
    end

end


function [Estimation_X, FirstPosition] = FEKF_propagate(Estimation_X, OdometryFromThis2Next, Sigma_ODO , FirstPosition )
v = OdometryFromThis2Next(1:3);
w = OdometryFromThis2Next(4:6);

% update position and orientation
Estimation_X.position = Estimation_X.position+Estimation_X.orientation*v;
orientation=Estimation_X.orientation;
Estimation_X.orientation = Estimation_X.orientation*Exp(w);

NumberOfLandmarks = size(Estimation_X.landmarks, 2);
Jrw = J_r(-w);

G1 = [-orientation*Jrw zeros(3,3);zeros(3,3)  -orientation];
G= [G1; zeros(3* NumberOfLandmarks ,6)];
odoCov=diag([w.^2;v.^2])*Sigma_ODO^2;
W = G*odoCov*G';

% compute matrix A_{n}
temp = repmat({ eye(3) }, NumberOfLandmarks+2,1 );
A = blkdiag(temp{:});
A(1:3,1:3) = eye(3);% ExpMinusM;

if isempty(FirstPosition)
   A(4:6,1:3) = -skew(orientation*v);
else
   A(4:6,1:3) = -skew(Estimation_X.position-FirstPosition);
end

% final update the covariance
Estimation_X.cov = A*Estimation_X.cov*A'+W;

FirstPosition=Estimation_X.position;
end


function [F_RF,F_BB]=OMP_Precoding()
global Ns Nt Nrf H Codebook_v
F_RF = [];
[~,~,V] = svd(H);
F_opt = V(:,1:Ns);
Fres = F_opt;
for i = 1:Nrf
    y = Codebook_v'*Fres;
    k = find(diag(y*y')==max(diag(y*y')));
    F_RF (:,i) = Codebook_v(:,k);
    F_BB = (F_RF' * F_RF)^(-1) * F_RF' *F_opt;
    Fres = (F_opt - F_RF * F_BB)/norm(F_opt - F_RF * F_BB,'fro');
end
F_BB = sqrt(Ns) * F_BB / norm(F_RF * F_BB,'fro');


function A = convertRadToDegrees(InA)
    A = InA*180/pi;
end


function yms=EWT2D_Curvelet_Scaling(Radius,w1,gamma,W,H)

%==================================================
% function ymw=EWT2D_Curvelet_Scaling(w1,gamma,W,H)
%
% Generate the 1D Littlewood-Paley wavelet in the
% Fourier domain associated to the disk [0,w1]
% with transition ratio gamma
%
% Input parameters:
%   -Radius : matrix giving the radius at each pixel
%   -w1 : boundary
%   -gamma : transition ratio
%   -W : image width
%   -H : image height
%
% Output:
%   -yms: Fourier transform of the scaling function
%
% Author: Jerome Gilles - Giang Tran
% Institution: UCLA - Department of Mathematics
% Year: 2013
% Version: 1.0
%===================================================

an=1/(2*gamma*w1);
pbn=(1+gamma)*w1;
mbn=(1-gamma)*w1;

yms=zeros(H,W);

for i=1:W
   for j=1:H
      if (Radius(j,i)<mbn)
        yms(j,i)=1;
      elseif ((Radius(j,i)>=mbn) && (Radius(j,i)<=pbn))
        yms(j,i)=cos(pi*EWT_beta(an*(Radius(j,i)-mbn))/2);
      end
   end
end


function DataSet = prtDataGenFeatureSelection(N, nExtraDims)
%prtDataGenFeatureSelection   Generates some unimodal example data for the prt.
%  DataSet = prtDataGenFeatureSelection
%  The data is distributed:
%       H0: N([0 0 0 0 0 0 0 0 0 0],eye(10))
%       H1: N([0 2 0 1 0 2 0 1 0 2],eye(10))
%
% Syntax: [X, Y] = prtDataGenFeatureSelection(N)
%
% Inputs:
%       N ~ number of samples per class (200)
%
% Outputs:
%   X - 2Nx2 Unimodal data
%   Y - 2Nx1 Class labels
%
% Example:
%   DataSet = prtDataGenFeatureSelection;
%   explore(DataSet)
%
% Other m-files required: none
% Subfunctions: none
% MAT-files required: none
%
% See also: prtDataGenUnimodal

if nargin < 1 || isempty(N);
    nSamples = 200;
else
    nSamples = N;
end

if nargin < 2 || isempty(nExtraDims)
    nExtraDims = 0;
end

mu0 = [0 0 0 0 0 0 0 0 0 0];
mu1 = [0 1 0 .5 0 1 0 .5 0 1]*2;

sigma0 = eye(length(mu0));
sigma1 = eye(length(mu1));
rv(1) = prtRvMvn('mu',mu0,'sigma',sigma0);
rv(2) = prtRvMvn('mu',mu1,'sigma',sigma1);

X = cat(1,draw(rv(1),nSamples),draw(rv(2),nSamples));

if nExtraDims > 0
    rvNoise = prtRvMvn('mu',zeros(1,nExtraDims),'sigma',eye(nExtraDims));

    X = cat(2, X, rvNoise.draw(nSamples*2));
end

Y = prtUtilY(nSamples,nSamples);

DataSet = prtDataSetClass(X,Y,'name',mfilename);


function W = unfold( U, dir )
    %UNFOLD Left/right-unfold a 3D array.
    %   W = UNFOLD(U, DIR) unfolds the 3-dim. tensor U in direction DIR, where
    %   DIR is either 'LEFT' or 'RIGHT' (case insensitive).
    %
    %   See also MATRICIZE, TENSORIZE, TENSORPROD_TTEMPS.

    %   TTeMPS Toolbox.
    %   Michael Steinlechner, 2013-2016
    %   Questions and contact: michael.steinlechner@epfl.ch
    %   BSD 2-clause license, see LICENSE.txt

    d = size(U);
    % pad with 1 for the last dim (annoying)
    if length(size(U)) == 2
        d = [d, 1];
    end

    if strcmpi(dir, 'left')
        W = reshape( U, [d(1)*d(2), d(3)] );
    elseif strcmpi(dir, 'right')
        W = reshape( U, [d(1), d(2)*d(3)] );
    else
        error('Unknown direction specified. Choose either LEFT or RIGHT')
    end
end


function []=repop_testcases(testType)
%
% This file contains lots of test-cases to test the performance of the repop
% files vs. the matlab built-ins.
%
% N.B. there appears to be a bug in MATLAB when comparing mixed
% complex/real + double/single values in a max/min
%
% Copyright 2006-     by Jason D.R. Farquhar (jdrf@zepler.org)
% Permission is granted for anyone to copy, use, or modify this
% software and accompanying documents for any uncommercial
% purposes, provided this copyright notice is retained, and note is
% made of any changes that have been made. This software and
% documents are distributed without any warranty, express or
% implied
if ( nargin<1 || isempty(testType) ) testType={'acc','timing'}; end;

if ( ~isempty(strmatch('acc',testType)) )
fprintf('-------------------  Accuracy tests -------------------\n');

X=complex(randn(10,100),randn(10,100));
Y=complex(randn(size(X)),randn(size(X)));
fprintf('\n****************\n Double Real X, Double Real Y\n******************\n')
accuracyTests(real(X),real(Y),'dRdR')
fprintf('\n****************\n Double Complex X, Double Real Y\n******************\n')
accuracyTests(X,real(Y),'dCdR')
fprintf('\n****************\n Double Real X, Double Complex Y\n******************\n')
accuracyTests(real(X),Y,'dRdC')
fprintf('\n****************\n Double Complex X, Double Complex Y\n******************\n')
accuracyTests(X,Y,'dCdC')

fprintf('\n****************\n Double Real X, Single Real Y\n******************\n')
accuracyTests(real((X)),real(single(Y)),'dRsR')
fprintf('\n****************\n Double Complex X, Single Real Y\n******************\n')
accuracyTests((X),real(single(Y)),'dCsR')
fprintf('\n****************\n Double Real X, Single Complex Y\n******************\n')
accuracyTests((real(X)),single(Y),'dRsC')
fprintf('\n****************\n Double Complex X, Single Complex Y\n******************\n')
accuracyTests((X),single(Y),'dCsC')

fprintf('\n****************\n Single Real X, Double Real Y\n******************\n')
accuracyTests(real(single(X)),real((Y)),'sRdR')
fprintf('\n****************\n Single Complex X, Double Real Y\n******************\n')
accuracyTests(single(X),real((Y)),'sCdR')
fprintf('\n****************\n Single Real X, Double  Complex Y\n******************\n')
accuracyTests(single(real(X)),(Y),'sRdC')
fprintf('\n****************\n Single Complex X,Double Complex Y\n******************\n')
accuracyTests(single(X),(Y),'sCdC')

fprintf('\n****************\n Single Real X, Single Real Y\n******************\n')
accuracyTests(real(single(X)),real(single(Y)),'sRsR')
fprintf('\n****************\n Single Complex X, Single Real Y\n******************\n')
accuracyTests(single(X),real(single(Y)),'sCsR')
fprintf('\n****************\n Single Real X, Single Complex Y\n******************\n')
accuracyTests(single(real(X)),single(Y),'sRsC')
fprintf('\n****************\n Single Complex X, Single Complex Y\n******************\n')
accuracyTests(single(X),single(Y),'sCsC')

fprintf('All tests passed\n');
end

if ( ~isempty(strmatch('timing',testType)) )
fprintf('-------------------  Timing tests -------------------\n');

X=complex(randn(100,1000),randn(100,1000));
Y=complex(randn(size(X)),randn(size(X)));
timingTests(real(X),real(Y),'[100x1000] RR');
timingTests(X,Y,'[100x1000] CC');

end

return;

function []=accuracyTests(X,Y,str)
% PLUS
unitTest([str ' Matx + col Vec'],X,'+',Y(:,1),repop(X,'+',Y(:,1)),X+repmat(Y(:,1),[1,size(X,2)]));
unitTest([str ' Matx + row Vec'],X,'+',Y(1,:),repop(X,'+',Y(1,:)),X+repmat(Y(1,:),[size(X,1),1]));
unitTest([str ' Matx + Matx(:,1:2)'],X,'+',Y(:,1:2),repop(X,'+',Y(:,1:2),'m'),X+repmat(Y(:,1:2),[1,size(X,2)/2]));
unitTest([str ' Matx + Matx'],X,'+',Y(:,:),repop(X,'+',Y(:,:)),X+repmat(Y(:,:),[1,1]));
% TIMES
unitTest([str ' Matx * col Vec'],X,'*',Y(:,1),repop(X,'*',Y(:,1)),X.*repmat(Y(:,1),[1,size(X,2)]));
unitTest([str ' Matx * row Vec'],X,'*',Y(1,:),repop(X,'*',Y(1,:)),X.*repmat(Y(1,:),[size(X,1),1]));
unitTest([str ' Matx * Matx(:,1:2)'],X,'*',Y(:,1:2),repop(X,'*',Y(:,1:2),'m'),X.*repmat(Y(:,1:2),[1,size(X,2)/2]));
unitTest([str ' Matx * Matx'],X,'*',Y(:,:),repop(X,'*',Y(:,:)),X.*repmat(Y(:,:),[1,1]));

% other operations
unitTest([str ' Matx - row vec'],X,'-',Y(:,1),repop(X,'-',Y(:,1)),X-repmat(Y(:,1),[1,size(X,2)]));
unitTest([str ' Matx / row vec'],X,'/',Y(:,1),repop(X,'/',Y(:,1)),X./repmat(Y(:,1),[1,size(X,2)]));
unitTest([str ' Matx \ row vec'],X,'\',Y(:,1),repop(X,'\',Y(:,1)),X.\repmat(Y(:,1),[1,size(X,2)]));
unitTest([str ' Matx ^ row vec'],X,'^',Y(:,1),repop(X,'^',Y(:,1)),X.^repmat(Y(:,1),[1,size(X,2)]),1e-5);
unitTest([str ' Matx == row vec'],X,'==',Y(:,1),repop(X,'==',Y(:,1)),X==repmat(Y(:,1),[1,size(X,2)]));
unitTest([str ' Matx ~= row vec'],X,'~=',Y(:,1),repop(X,'~=',Y(:,1)),X~=repmat(Y(:,1),[1,size(X,2)]));
% N.B. repop tests with complex inputs use the magnitude of the input!
tX=X; tY=Y; if( ~isreal(X) | ~isreal(Y) ) tX=abs(X); tY=abs(Y); end;
unitTest([str ' Matx < row vec'],X,'<',Y(:,1),repop(X,'<',Y(:,1)),tX<repmat(tY(:,1),[1,size(X,2)]));
unitTest([str ' Matx > row vec'],X,'>',Y(:,1),repop(X,'>',Y(:,1)),tX>repmat(tY(:,1),[1,size(X,2)]));
unitTest([str ' Matx <= row vec'],X,'<=',Y(:,1),repop(X,'<=',Y(:,1)),tX<=repmat(tY(:,1),[1,size(X,2)]));
unitTest([str ' Matx >= row vec'],X,'>=',Y(:,1),repop(X,'>=',Y(:,1)),tX>=repmat(tY(:,1),[1,size(X,2)]));
%unitTest([str ' min Matx, row vec'],repop('min',X,Y(:,1)),min(X,repmat(Y(:,1),[1, size(X,2)])));
%unitTest([str ' max Matx, row vec'],repop('max',X,Y(:,1)),max(X,repmat(Y(:,1),[1,size(X,2)])));
%return;
%function []=inplaceaccuracyTests(X,Y,str)

return;

% Inplace operations test
% PLUS
% N.B. need the Z(1)=Z(1); to force to make a "deep" copy, i.e. not just
% equal pointers
Z=X;unitTest([str ' Matx + col Vec (inplace)'],Z,'+',Y(:,1),repop(Z,'+',Y(:,1),'i'),X+repmat(Y(:,1),[1,size(X,2)]));
Z=X;unitTest([str ' Matx + row Vec (inplace)'],Z,'+',Y(1,:),repop(Z,'+',Y(1,:),'i'),X+repmat(Y(1,:),[size(X,1),1]));
Z=X;unitTest([str ' Matx + Matx(:,1:2) (inplace)'],Z,'+',Y(:,1:2),repop(Z,'+',Y(:,1:2),'mi'),X+repmat(Y(:,1:2),[1,size(X,2)/2]));
Z=X;unitTest([str ' Matx + Matx (inplace)'],Z,'+',Y(:,:),repop(Z,'+',Y(:,:),'i'),X+repmat(Y(:,:),[1,1]));
% TIMES
Z=X;unitTest([str ' Matx * col Vec (inplace)'],Z,'*',Y(:,1),repop(Z,'*',Y(:,1),'i'),X.*repmat(Y(:,1),[1,size(X,2)]));
Z=X;unitTest([str ' Matx * row Vec (inplace)'],Z,'*',Y(1,:),repop(Z,'*',Y(1,:),'i'),X.*repmat(Y(1,:),[size(X,1),1]));
Z=X;unitTest([str ' Matx * Matx(:,1:2) (inplace)'],Z,'*',Y(:,1:2),repop(Z,'*',Y(:,1:2),'mi'),X.*repmat(Y(:,1:2),[1,size(X,2)/2]));
Z=X;unitTest([str ' Matx * Matx (inplace)'],Z,'*',Y(:,:),repop(Z,'*',Y(:,:),'i'),X.*repmat(Y(:,:),[1,1]));
% other operations
Z=X;unitTest([str ' Matx - row vec (inplace)'],Z,'-',Y(:,1),repop(Z,'-',Y(:,1),'i'),X-repmat(Y(:,1),[1,size(X,2)]));
Z=X;unitTest([str ' Matx \ row vec (inplace)'],Z,'\',Y(:,1),repop(Z,'\',Y(:,1),'i'),X.\repmat(Y(:,1),[1,size(X,2)]));
Z=X;unitTest([str ' Matx / row vec (inplace)'],Z,'/',Y(:,1),repop(Z,'/',Y(:,1),'i'),X./repmat(Y(:,1),[1,size(X,2)]));
Z=X;unitTest([str ' Matx ^ row vec (inplace)'],Z,'^',Y(:,1),repop(Z,'^',Y(:,1),'i'),X.^repmat(Y(:,1),[1,size(X,2)]),1e-5);
%unitTest([str ' min Matx, row vec (inplace)'],repop('min',X,Y(:,1),'i'),min(X,repmat(Y(:,1),[1, size(X,2)])));
%unitTest([str ' max Matx, row vec (inplace)'],repop('max',X,Y(:,1),'i'),max(X,repmat(Y(:,1),[1,size(X,2)])));

function []=timingTests(X,Y,str)
%PLUS
fprintf('%s Matx + Scalar\n',str);
tic; for i=1:1000; Z=repop(X,'+',10); end;
fprintf('%30s %gs\n','repop',toc/1000);
tic; Z=X;Z(1)=Z(1);for i=1:1000; Z=repop(Z,'+',10,'i'); end;
fprintf('%30s %gs\n','repop (inplace)',toc/1000);
tic; for i=1:1000; T=X+10;end;
fprintf('%30s %gs\n','MATLAB',toc/1000);

fprintf('%s Matx + col vec\n',str);
tic, for i=1:1000; Z=repop(X,'+',Y(:,1)); end;
fprintf('%30s %gs\n','repop',toc/1000); % = .05  / .01
tic, Z=X;Z(1)=Z(1); for i=1:1000; Z=repop(Z,'+',Y(:,1),'i'); end;
fprintf('%30s %gs\n','repop (inplace)',toc/1000); % = .05  / .01
tic, for i=1:1000; Z=X+repmat(Y(:,1),1,size(X,2));end;
fprintf('%30s %gs\n','MATLAB',toc/1000); % = .05  / .01

fprintf('%s Matx + row vec\n',str);
tic, for i=1:1000; Z=repop(X,'+',Y(1,:)); end;
fprintf('%30s %gs\n','repop',toc/1000); % = .05  / .01
tic, Z=X;Z(1)=Z(1); for i=1:1000; Z=repop(Z,'+',Y(1,:),'i'); end;
fprintf('%30s %gs\n','repop (inplace)',toc/1000); % = .05  / .01
tic, for i=1:1000; Z=X+repmat(Y(1,:),size(X,1),1);end;
fprintf('%30s %gs\n','MATLAB',toc/1000); % = .05  / .01

fprintf('%s Matx + Matx(:,1:2)\n',str);
tic; for i=1:1000; Z=repop(X,'+',Y(:,1:2),'m'); end;
fprintf('%30s %gs\n','repop',toc/1000); % = .05  / .01
tic, Z=X;Z(1)=Z(1); for i=1:1000; Z=repop(Z,'+',Y(:,1:2),'im'); end;
fprintf('%30s %gs\n','repop (inplace)',toc/1000); % = .05  / .01
tic; for i=1:1000; T=X+repmat(Y(:,1:2),[1,size(X,2)/2]);end;
fprintf('%30s %gs\n','MATLAB',toc/1000); % = .05  / .01

%TIMES
fprintf('%s Matx * col Vec\n',str);
tic; for i=1:1000; Z=repop(X,'*',Y(:,1)); end;
fprintf('%30s %gs\n','repop',toc/1000);
tic; Z=X;Z(1)=Z(1); for i=1:1000; Z=repop(Z,'*',Y(:,1),'i'); end;
fprintf('%30s %gs\n','repop (inplace)',toc/1000);
tic; for i=1:1000; Z=X.*repmat(Y(:,1),1,size(X,2));end;
fprintf('%30s %gs\n','MATLAB',toc/1000);
tic; for i=1:1000; Z=spdiags(Y(:,1),0,size(X,1),size(X,1))*X;end;
fprintf('%30s %gs\n','MATLAB (spdiags)',toc/1000);

fprintf('%s Matx * row Vec\n',str);
tic; for i=1:1000; Z=repop(X,'*',Y(1,:)); end;
fprintf('%30s %gs\n','repop',toc/1000);
tic; Z=X;Z(1)=Z(1); for i=1:1000; Z=repop(Z,'*',Y(1,:),'i'); end;
fprintf('%30s %gs\n','repop (inplace)',toc/1000);
tic; for i=1:1000; Z=X.*repmat(Y(:,1),1,size(X,2));end;
fprintf('%30s %gs\n','MATLAB',toc/1000);
tic; for i=1:1000; Z=X*spdiags(Y(1,:)',0,size(X,2),size(X,2));end;
fprintf('%30s %gs\n','MATLAB (spdiags)',toc/1000);

fprintf('%s Matx * Matx(:,1:2)\n',str);
tic; for i=1:1000; Z=repop(X,'*',Y); end;
fprintf('%30s %gs\n','repop',toc/1000);
tic; Z=X;Z(1)=Z(1); for i=1:1000; Z=repop(Z,'*',Y,'i'); end;
fprintf('%30s %gs\n','repop (inplace)',toc/1000);
tic; for i=1:1000; Z=X.*repmat(Y(:,1:2),[1,size(X,2)/2]);end;
fprintf('%30s %gs\n','MATLAB',toc/1000);

return;

% simple function to check the accuracy of a test and report the result
function [testRes,trueRes,diff]=unitTest(testStr,A,op,B,testRes,trueRes,tol)
global LOGFILE;
if ( ~isempty(LOGFILE) ) % write tests and result to disc
   writeMxInfo(LOGFILE,A);
   fprintf(LOGFILE,'%s\n',op);
   writeMxInfo(LOGFILE,B);
   fprintf(LOGFILE,'=\n');
   writeMxInfo(LOGFILE,trueRes);
   fprintf(LOGFILE,'\n');
end
if ( nargin < 7 )
   if ( isa(trueRes,'double') ) tol=1e-11;
   elseif ( isa(trueRes,'single') ) tol=1e-5;
   elseif ( isa(trueRes,'integer') )
      warning('Integer inputs!'); tol=1;
   elseif ( isa(trueRes,'logical') ) tol=0;
   end
end;
diff=abs(testRes-trueRes)./max(1,abs(testRes+trueRes));
fprintf('%45s = %0.3g ',testStr,max(diff(:)));
if ( max(diff(:)) > tol )
   if ( exist('mimage') )
      mimage(squeeze(testRes),squeeze(trueRes),squeeze(diff))
   end
   warning([testStr ': failed!']);
   fprintf('Type return to continue\n'); keyboard;
else
   fprintf('Passed \n');
end


%% (Internal) Calculate an estimate of the SNR of ECG signal, considering signal the ensemble average, and noise each realization minus the ensemble average.
%
%   corr_gain = calc_correlation_gain(signal, heasig, references, limits, bRobust)
%
% Arguments:
%
%      + signal: signal to use
%
%      + heasig: header information about the signal.
%
%      + references: temporal samples where the synch occurs (QRS complex locations)
%
%      + limits: the amount of samples w.r.t. references(i) to consider a a
%                time window around references(i), from references(i) -
%                limits(1) to references(i) + limits(2)
%
%      + bRobust: Calculate the esemble average using mean or median.
%                 Default: use median.
%
% Output:
%
%      + corr_gain: Estimate of the SNR considering signal the ensemble
%                   average, and noise each realization minus the ensemble
%                   average.
%
% Example:
%
% See also CalcRRserieQuality
%
% Author: Mariano Llamedo Soria llamedom@electron.frba.utn.edu.ar
% Version: 0.1 beta
% Last update: 14/5/2014
% Birthdate  : 21/4/2015
% Copyright 2008-2015
%
function corr_gain = calc_correlation_gain(signal, heasig, references, limits, bRobust)

corr_gain = nan;
[nsamp, nsig] = size(signal);
pattern_size = sum(limits);
lreferences = length(references);

sig_pack = pack_signal(signal, references(references > limits(1) & references < (nsamp-limits(2) )), limits, true);

if( isempty(sig_pack) )
    noise_power = nan;
    return
end

if( nargin < 5 || isempty(bRobust) )
    pattern_avg = squeeze(median(sig_pack,3));
else
    pattern_avg = squeeze(mean(sig_pack,3));
end

sig_pack_sub_avg = bsxfun(@minus, sig_pack, pattern_avg);

corr_gain = 10*log10( mean(pattern_avg.^2) ./ 10.^squeeze(mean(log10(mean(sig_pack_sub_avg.^2,1)),3)) );

% % Obsolete: estimate noise from a random sampling simulating guessing the QRS locations.
%
% if( nargin < 4 || isempty(noise_power) )
%     noise_power = nan(30,nsig);
%     noise_disp = nan(30,nsig);
%     for ii = 1:30
%         noise_pack = pack_signal(signal, sort(randsample(limits(1):(nsamp-limits(2)), lreferences)), limits);
% %         noise_avg = flipud(reshape(squeeze(median(noise_pack,3)), pattern_size, nsig));
%         noise_limits = prctile(noise_pack, [5 50 95], 3);
%
%         noise_down = squeeze(noise_limits(:,:,1));
%         noise_avg = squeeze(noise_limits(:,:,2));
%         noise_up = squeeze(noise_limits(:,:,3));
%
%         noise_power(ii,:) = mean(noise_avg.^2);
%         noise_disp(ii,:) = mean(noise_up - noise_down);
%     end
%     noise_power = nanmedian(noise_power);
%     noise_disp = nanmedian(noise_disp);
% end
%
% corr_gain = 10*log10(mean(pattern_avg.^2) ./ noise_power );

% pattern_limits = prctile(sig_pack, [5 50 95], 3);
%
% pattern_down = squeeze(pattern_limits(:,:,1));
% pattern_up = squeeze(pattern_limits(:,:,3));
% mean_pattern_disp = mean(pattern_up - pattern_down);

% corr_gain_2 = 20*log10( noise_disp ./ mean_pattern_disp );

% debug
% aux_val = [];
% for ii  = 1:100
%     noise_pack = pack_signal(signal, sort(randsample(limits(1):(nsamp-limits(2)), length(references))), limits);
%     noise_avg = flipud(reshape(squeeze(median(noise_pack)), pattern_size, nsig));
%     aux_val = [aux_val; mean(noise_avg.^2)];
% end
%
% figure
% hist( aux_val, 100)
% legend()


function [A,B] = vrep2hrep(pts);
%
% Given a set of points, computes an H-representation of its convex hull
%
%  A x <= B
%
% Calls Komei Fukuda's CDD (floating point version)

% This file is part of SOSTOOLS - Sum of Squares Toolbox ver 3.00.
%
% Copyright (C)2002, 2004, 2013  A. Papachristodoulou (1), J. Anderson (1),
%                                G. Valmorbida (1), S. Prajna (2),
%                                P. Seiler (3), P. A. Parrilo (4)
% (1) Department of Engineering Science, University of Oxford, Oxford, U.K.
% (2) Control and Dynamical Systems - California Institute of Technology,
%     Pasadena, CA 91125, USA.
% (3) Aerospace and Engineering Mechanics Department, University of
%     Minnesota, Minneapolis, MN 55455-0153, USA.
% (4) Laboratory for Information and Decision Systems, M.I.T.,
%     Massachusetts, MA 02139-4307
%
% Send bug reports and feedback to: sostools@cds.caltech.edu
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program. If not, see <http://www.gnu.org/licenses/>.

% PP 22/10/2002

[npts,dim]=size(pts);

cdd = cddpath;

filename = 'temp.ext' ;

fid = fopen(filename,'w');

fprintf(fid,'*\n');
fprintf(fid,'* Generated automatically by vrep2hrep.m\n');
fprintf(fid,'*\n');
fprintf(fid,'V-representation\n');
fprintf(fid,'begin\n');
fprintf(fid,'%d %d real\n',npts,dim+1);

fmt = ['1 ' repmat('%.15E ',1,dim) '\n'];

% Print the data
fprintf(fid,fmt,pts');

fprintf(fid,'end\n');
fprintf(fid,'stdout_off\n');
fclose(fid);

% Now, run CDD
cmd = [cdd ' ' filename];

vv = version;
if str2num(vv(1))>5
  [dummy1,dummy2] = system(cmd);
else
  if ~isunix
    [dummy1,dummy2] = dos(cmd);
  else
    [dummy1,dummy2] = unix(cmd);
  end;
end;

% Read the output

filename = 'temp.ine' ;

fid = fopen(filename,'r');

% Skip everything, until 'begin'
tline = [];
while strcmp(tline,'begin') == 0;
 tline = fgetl(fid) ;
end

nineqs = fscanf(fid,'%d',1);
dims   = fscanf(fid,'%d',1);
dummy2 = fscanf(fid,'%s',1);

H = fscanf(fid,'%E',[dims,nineqs]);
fclose(fid);

% Get rid of the files
delete('temp.ext');
delete('temp.ine');

H = H' ;

B = H(:,1);
A = -H(:,2:dims);


clear all
close all
clc

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Demo file for deconvtv
% Image 'salt and pepper' noise removal
%
% Stanley Chan
% University of California, San Diego
% 20 Jan, 2011
%
% Copyright 2011
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Prepare images
f_orig  = im2double(imread('C:\Users\Stanley Chan\Dropbox\TestImages\Lena.bmp'));
[rows cols frames] = size(f_orig);
H       = fspecial('gaussian', [9 9], 2);
g       = imfilter(f_orig, H, 'circular');
g       = imnoise(g, 'salt & pepper', 0.05);

% Setup parameters (for example)
opts.rho_r   = 5;
opts.rho_o   = 100;
opts.beta    = [1 1 0];
opts.print   = true;
opts.alpha   = 0.7;
opts.method  = 'l1';

% Setup mu
mu           = 20;

% Main routine
tic
out = deconvtv(g, H, mu, opts);
toc

% Display results
figure(1);
imshow(g);
title('input');

figure(2);
imshow(out.f);
title('output');


% 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 phi = CharacteristicFunctionLib(model,u,lnS,T,r,d,varargin)
%---------------------------------------------------------
% Characteristic Function Library of the following models:
%---------------------------------------------------------
% Black Scholes
% Merton Jump Diffusion
% Heston Stochastic Volatility Model
% Bates Stochastic Volatility / Jump Diffusion Model
% Variance Gamma
% Normal Inverse Gaussian
% Meixner
% Generalized Hyperbolic
% CGMY
% Variance Gamma with Gamma Ornstein Uhlenbeck clock
% Variance Gamma with CIR clock
%---------------------------------------------------------

optAlfaCalculation = true;

ME1 = MException('VerifyInput:InvalidNrOfArguments',...
    'Invalid number of Input arguments');
ME2 = MException('VerifyInput:InvalidModel',...
    'Undefined Model');

if strcmp(model,'BlackScholes')
    if nargin == 7
        funobj = @Black_characteristicFn;
    else
        throw(ME1)
    end
elseif strcmp(model,'Heston')
    if nargin == 11
        funobj = @Heston_characteristicFn;
    else
        throw(ME1)
    end
elseif strcmp(model,'Merton')
    if nargin == 10
        funobj = @Merton_characteristicFn;
    else
        throw(ME1)
    end
elseif strcmp(model,'Bates')
    if nargin == 14
        funobj = @Bates_characteristicFn;
    else
        throw(ME1)
    end
elseif strcmp(model,'VarianceGamma')
    if nargin == 9
        funobj = @VG_characteristicFn;
    else
        throw(ME1)
    end
elseif strcmp(model,'NIG')
    if nargin == 10
        funobj = @NIG_characteristicFn;
    else
        throw(ME1)
    end
elseif strcmp(model,'CGMY')
    if nargin == 10
        funobj = @CGMY_characteristicFn;
    else
        throw(ME1)
    end
elseif strcmp(model,'Meixner')
    if nargin == 9
        funobj = @Meixner_characteristicFn;
    else
        throw(ME1)
    end
elseif strcmp(model,'GH')
    if nargin == 10
        funobj = @GH_characteristicFn;
    else
        throw(ME1)
    end
elseif strcmp(model,'IntegratedCIR')
    if nargin == 13
        funobj = @VarianceGammaCIR_characteristicFn;
    else
        throw(ME1)
    end
elseif strcmp(model,'VarianceGammaOU')
    if nargin == 12
        funobj = @VarianceGammaOU_characteristicFn;
    else
        throw(ME1)
    end
else
    throw(ME2)
end

fval = feval(funobj,u,lnS,T,r,d,varargin{:});

if optAlfaCalculation == true
    phi = fval;
else
    phi = exp(fval);
end

end

%% Explicit Implementation of the characteristic Functions E[exp(iu*lnS_T)]
%-----------------------------------------------------------------------

% Black Scholes
function phi = Black_characteristicFn(u,lnS,T,r,d,sigma)
    %phi = exp(i*u*(lnS+(r-d-0.5*sigma*sigma)*T) - 0.5*sigma*sigma*u.*u*T);
    phi = 1i*u*(lnS+(r-d-0.5*sigma*sigma)*T) - 0.5*sigma*sigma*u.*u*T;
end

% Merton Jump Diffusion
function phi = Merton_characteristicFn(u,lnS,T,r,d,sigma,a,b,lambda)
    phi = Black_characteristicFn(u,lnS,T,r,d,sigma) + LogNormalJump_characteristicFn(u,a,b,lambda,T);
end

% Heston
function phi = Heston_characteristicFn(u,lnS,T,r,d,V0,theta,kappa,omega,rho)

alfa = -0.5*(u.*u + u*1i);
beta = kappa - rho*omega*u*1i;

omega2 = omega * omega;
gamma = 0.5 * omega2;

D = sqrt(beta .* beta - 4.0 * alfa .* gamma);

bD = beta - D;
eDt = exp(- D * T);

G = bD ./ (beta + D);
B = (bD ./ omega2) .* ((1.0 - eDt) ./ (1.0 - G .* eDt));
psi = (G .* eDt - 1.0) ./(G - 1.0);
A = ((kappa * theta) / (omega2)) * (bD * T - 2.0 * log(psi));

phi = A + B*V0 + 1i*u*(lnS+(r-d)*T);

end

% Bates
function phi = Bates_characteristicFn(u,lnS,T,r,d,V0,theta,kappa,omega,rho,a,b,lambda)
    phiHes = Heston_characteristicFn(u,lnS,T,r,d,V0,theta,kappa,omega,rho);
    phi = phiHes + LogNormalJump_characteristicFn(u,a,b,lambda,T);
end

% LogNormalJump for Merton and Bates
function phiJump = LogNormalJump_characteristicFn(u,a,b,lambda,T)
    %phiJump = exp(lambda*T*(-a*u*i + (exp(u*i*log(1.0+a)+0.5*b*b*u*i.*(u*i-1.0))-1.0)));
    phiJump = lambda*T*(-a*u*1i + (exp(u*1i*log(1.0+a)+0.5*b*b*u*1i.*(u*1i-1.0))-1.0));
end

% Variance Gamma
function phi = VG_characteristicFn(u,lnS,T,r,d,sigma,nu,theta)
    omega = (1/nu)*( log(1-theta*nu-sigma*sigma*nu/2) );
    tmp = 1 - 1i * theta * nu * u + 0.5 * sigma * sigma * u .* u * nu;
    %tmp = tmp.^(-T / nu);
    %phi = exp( i * u * (lnS + (r + omega - d) * T )) .* tmp;
    phi = 1i * u * (lnS + (r + omega - d) * T ) - T*log(tmp)/nu;

end

% Normal Inverse Gaussian
function phi = NIG_characteristicFn(u,lnS,T,r,d,alfa,beta,mu,delta)
    m = delta*(sqrt(alfa*alfa-(beta+1)^2)-sqrt(alfa*alfa-beta*beta));
    %tmp = exp(i*u*mu*T-delta*T*(sqrt(alfa*alfa-(beta+i*u).^2)-sqrt(alfa*alfa-beta*beta)));
    %phi = exp( i*u*(lnS + (r-d+m)*T)).*tmp;
    tmp = 1i*u*mu*T-delta*T*(sqrt(alfa*alfa-(beta+1i*u).^2)-sqrt(alfa*alfa-beta*beta));
    phi = 1i*u*(lnS + (r-d+m)*T) + tmp;
end

% Meixner
function phi = Meixner_characteristicFn(u,lnS,T,r,d,alfa,beta,delta)
    m = -2*delta*(log(cos(0.5*beta)) - log(cos((alfa+beta)/2)));
    tmp = (cos(0.5*beta)./cosh(0.5*(alfa*u-1i*beta))).^(2*T*delta);
    %phi = exp( i*u*(lnS + (r-d+m)*T)).*tmp;
    phi = 1i*u*(lnS + (r-d+m)*T) + log(tmp);
end

% Generalized Hyperbolic
function phi = GH_characteristicFn(u,lnS,T,r,d,alfa,beta,delta,nu)
    arg1 = alfa*alfa-beta*beta;
    arg2 = arg1-2*1i*u*beta + u.*u;
    argm = arg1-2*beta-1;
    m = -log((arg1./argm).^(0.5*nu).*besselk(nu,delta*sqrt(argm))./besselk(nu,delta*sqrt(arg1)));
    tmp = (arg1./arg2).^(0.5*nu).*besselk(nu,delta*sqrt(arg2))./besselk(nu,delta*sqrt(arg1));
    %phi = exp( i*u*(lnS + (r-d+m)*T)).*tmp.^T;
    phi = 1i*u*(lnS + (r-d+m)*T) + log(tmp).*T;
end

% CGMY
function phi = CGMY_characteristicFn(u,lnS,T,r,d,C,G,M,Y)
    m = -C*gamma(-Y)*((M-1)^Y-M^Y+(G+1)^Y-G^Y);
    %tmp = exp(C*T*gamma(-Y)*((M-i*u).^Y-M^Y+(G+i*u).^Y-G^Y));
    %phi = exp( i*u*(lnS + (r-d+m)*T)).*tmp;
    tmp = C*T*gamma(-Y)*((M-1i*u).^Y-M^Y+(G+1i*u).^Y-G^Y);
    phi = 1i*u*(lnS + (r-d+m)*T) + tmp;
end

%function phi = IntegratedCIR_characteristicFn(u,lnS,T,r,d,sigma,nu,theta,kappa,eta,lambda,y0)

%v1 = i*log(1 - i * theta * nu * u + 0.5 * sigma * sigma * u .* u * nu)/nu;
%v2 = i*log(1 - i * theta * nu *(-i) + 0.5 * sigma * sigma * (-i) .* (-i) * nu)/nu;

function phi = VarianceGammaCIR_characteristicFn(u,lnS,T,r,d,C,G,M,kappa,eta,lambda,y0)

v1 = -1i*C*(log(G*M)-log(G*M+(M-G)*1i*u + u.*u));
v2 = -1i*C*(log(G*M)-log(G*M+(M-G)*1i*(-1i) + (-1i).*(-1i)));

gamma1 = sqrt(kappa^2 - 2*lambda^2*1i*v1);
gamma2 = sqrt(kappa^2 - 2*lambda^2*1i*v2);
phi1 = kappa^2*eta*T/lambda^2 + 2*y0*1i*v1 ./ (kappa + gamma1.*coth(0.5*gamma1*T))...
    - 2*kappa*eta/lambda^2*log(cosh(0.5*gamma1*T) + kappa*sinh(0.5*gamma1*T)./gamma1);
phi2 = kappa^2*eta*T/lambda^2 + 2*y0*1i*v2 / (kappa + gamma2*coth(0.5*gamma2*T))...
    - 2*kappa*eta/lambda^2*log(cosh(0.5*gamma2*T) + kappa*sinh(0.5*gamma2*T)/gamma2);

%gam = sqrt(kappa^2-2*lambda^2);
m = 0;%- (kappa^2*eta*T/lambda^2 + 2*y0/(kappa+gam*coth(gam*T/2))) + 2*kappa*eta/lambda^2*log(cosh(gam*T/2)+kappa*sinh(gam*T/2)/gam);
phi = 1i*u*(lnS + (r-d+m)*T) + phi1 - 1i*u*phi2;%0.5*(log(phi1.^2) - i*u*log(phi2.^2));

end

function phi = VarianceGammaOU_characteristicFn(u,lnS,T,r,d,C,G,M,lambda,a,b)
    psiX1 = (-1i)*log((G*M./(G*M+(M-G)*1i*u+u.*u)).^C);
    psiX2 = (-1i)*log((G*M/(G*M+(M-G)-1)).^C);
    phiCIR1 = 1i*psiX1*lambda^(-1)*(1-exp(-lambda*T)) + lambda*a./(1i*psiX1-lambda*b).*(b*log(b./(b-1i*psiX1*lambda^(-1)*(1-exp(-lambda*T))))-1i*psiX1*T);
    phiCIR2 = 1i*psiX2*lambda^(-1)*(1-exp(-lambda*T)) + lambda*a./(1i*psiX2-lambda*b).*(b*log(b./(b-1i*psiX2*lambda^(-1)*(1-exp(-lambda*T))))-1i*psiX2*T);
    phi = 1i*u*(lnS + (r-d)*T)+phiCIR1 - 1i*u.*phiCIR2;
end


function [ y , ysup ] = exp_rnd(x,rnd)
%EXP_RND      Rigorous bounds for exp(x) and input vector x according to rnd
%
%   [ y , ysup ] = exp_rnd(x,rnd)
%
%If specified with two output arguments, lower and upper bound is computed
%independent of rnd, otherwise y is rounded according to rnd.
%Rounding need not be to nearest after leaving exp_rnd
%

% written  12/30/98     S.M. Rump
% modified 08/31/99     S.M. Rump  extreme input, improved accuracy,
%                                  major revision
% modified 02/14/01     S.M. Rump  improved accuracy
% modified 08/26/12     S.M. Rump  global variables removed
% modified 10/13/12     S.M. Rump  INTLAB_INTVAL_STDFCTS
%

  INTLAB_STDFCTS_EXP = getappdata(0,'INTLAB_STDFCTS_EXP');

  infsup = ( nargout==2 );
  if infsup
    rnd = -1;
  end

  setround(0)
  xint = fix(x);                            % integer part of x, chopped
  xfrac = x - xint;                         % fractional part, -1 < xfrac < 1

  indexlarge = ( xint>709 );                % care for exceptions
  indexsmall = ( xint<-744 );
  index = indexlarge | indexsmall | isnan(x);
  xint(index) = 0;
  xfrac(index) = 0;

  xs = pow2( floor(pow2(xfrac,14)) , -14 );  % max. 14 bits of mantissa of xfrac,
                                             % no bit below 2^-14
  d = xfrac - xs;                            % 0 <= d < 2^-14, exactly repr.
  expxs = exp(xs);
  factor = INTLAB_STDFCTS_EXP.EPS;
  Exint = INTLAB_STDFCTS_EXP.POW(745+xint);
  Exinteps = INTLAB_STDFCTS_EXP.POWSUP(745+xint);

  % general case, exp(xfrac) = exp(xs)*exp(d)
  if infsup          % 0 <= err <= exp(d)*d^4/4! < 0.2501*d*d^3/3!

    % calculate upper bound
    setround(1)
    % exp(d)*expxs <= corr + expxs
    corr = (( ( 1+0.2501*d ) .* expxs.*d/3 + expxs ).*d/2 + expxs ).*d;

    % exp(xs) <= expxs*(1+EPS)
    % exp(xfrac) = exp(d)*exp(xs) <= (corr+expxs)*(1+EPS)
    ysup = ( corr + corr*factor ) + expxs*factor ;

    % exp(xfrac) <= expxs+ysup,  exp(x) = exp(xfrac)*exp(xint)
    ysup = expxs.*Exint + ( (expxs+ysup).*Exinteps + ysup.*Exint );
    ysup(x==0) = 1;

  end

  setround(rnd)
  if rnd==-1
    Exinteps = INTLAB_STDFCTS_EXP.POWINF(745+xint);
    corr1 = 1;
  else
    corr1 = 1 + 0.2501*d;
  end

  % exp(d)*expxs ~ corr + expxs    subject to rounding
  corr = (( corr1 .* expxs.*d/3 + expxs ).*d/2 + expxs ).*d;

  % exp(xs)  in  expxs*(1+/-EPS)
  % exp(xfrac) = exp(d)*exp(xs)  in  (corr+expxs)*(1+rnd*EPS)
  y = ( corr + (corr*rnd)*factor ) + (expxs*rnd)*factor;

  % exp(xfrac) ~ expxs+y,  exp(x) = exp(xfrac)*exp(xint)
  y = expxs.*Exint + ( (expxs+y).*Exinteps + y.*Exint );
  y(x==0) = 1;

  % large or small input, exceptions
  if any(index)

    if any(indexlarge)
      if infsup
        y(indexlarge) = realmax;
        ysup(indexlarge) = inf;
      else
        if rnd==-1
          y(indexlarge) = realmax;
        else
          y(indexlarge) = inf;
        end
      end
    end

    if any(indexsmall)
      INTLAB_INTVAL_ETA = realmin*eps;  % smallest positive denormalized fl-pt
      if infsup
        y(indexsmall) = 0;
        ysup(indexsmall) = INTLAB_INTVAL_ETA;
      else
        if rnd==-1
          y(indexsmall) = 0;
        else
          y(indexsmall) = INTLAB_INTVAL_ETA;
        end
      end
    end

    index = isnan(x);
    if any(index)
      y(index) = NaN;
      if infsup
        ysup(index) = NaN;
      end
    end

  end

  index = ( xint<-720 );
  if any(index)
    y(index) = max( y(index) , 0 );
  end


function cc=lpcar2cc(ar,np)
%LPCAR2CC LPC: Convert ar filter to complex cepstrum CC=(AR,NP)
% the "real" cepstrum is half the complex cepstrum
% cc() does not include c0 whose value can be calculated
% from the prediction residual energy, e, as ln(e)/2
% for both real and complex cepstrum.

%      Copyright (C) Mike Brookes 1998
%      Version: $Id: lpcar2cc.m,v 1.4 2007/05/04 07:01:38 dmb Exp $
%
%   VOICEBOX is a MATLAB toolbox for speech processing.
%   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   This program is free software; you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation; either version 2 of the License, or
%   (at your option) any later version.
%
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You can obtain a copy of the GNU General Public License from
%   http://www.gnu.org/copyleft/gpl.html or by writing to
%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[nf,p1]=size(ar);
p=p1-1;
if (nargin<2) np=p; end
cc=zeros(nf,np);
cm=(1:np).^(-1);
if np>p
  xm=-(1:p);
  nz=np-p;
  for k=1:nf
    cc(k,:)=filter(1,ar(k,:),[ar(k,2:p1).*xm zeros(1,nz)]).*cm;
  end
else
  p1=np+1;
  xm=-(1:np);
  for k=1:nf
    cc(k,:)=filter(1,ar(k,:),ar(k,2:p1).*xm).*cm;
  end
end


function output = SHA1 ()

fname=input('Input File (in ASCII format)? ','s');
hash_foutname=input('Output File for SHA Hash? ','s');
time1=clock;
%Open the input file and get the first line of data
fid=fopen(fname);
M = fread(fid);
fclose(fid);
ini=dec2bin(M(1),8);

for ii = 2:length(M)
    ini=cat(2,ini,dec2bin(M(ii),8));
end

s2=length(ini)/8;

    block_temp = [ ini, ...
                 '1', ...
                 num2str(zeros(mod(448-1-s2*8,512),1))' ...
                dec2bin(s2*8,64) ];
           nb=length(block_temp)/512;

block = reshape(block_temp,512,nb)';

% H(0) initialization
H = [ '67','45','23','01';...
      'ef','cd','ab','89';...
      '98','ba','dc','fe';...
      '10','32','54','76';...
      'c3','d2','e1','f0'] ;

for N = 1:length(block_temp)/512

	% Generate Wt
	Wt = WtgenSHA1( block(N,:) );

	%use previous last H's
	a_hex = H(1,:); a = hex2bin(a_hex);
	b_hex = H(2,:); b = hex2bin(b_hex);
	c_hex = H(3,:); c = hex2bin(c_hex);
	d_hex = H(4,:); d = hex2bin(d_hex);
	e_hex = H(5,:); e = hex2bin(e_hex);

	% Kt initialization

	for t = 1:80
        T1 = bin2dec2(cls(a,5) );
        %Number to Char
        if t <= 20
   f = xor(b&c, ~b&d);
elseif t <= 40
   f = xor(xor(b,c),d);
elseif t <= 60
    f = xor(xor(b&c,b&d),c&d);
elseif t <= 80
    f = xor(xor(b,c),d);
else
    error ('t must be in the range 1 to 80')
end

        T2 = bin2dec2(f);
        T3 = bin2dec2(e);
        if t>=60
            T4=floor(2^32*sqrt(10));
        elseif t>=40
            T4=floor(2^32*sqrt(5));
        elseif t>=20
            T4=floor(2^32*sqrt(3));
        elseif t>0
            T4=floor(2^32*sqrt(2));
        end
%        T4=bin2dec2(Kt(t,:));
        T5 = bin2dec2(Wt(t,:) );
        T = mod(T1+T2+T3+T4+T5,2^32);

        e = d;
        d = c;
        c = cls(b,30);
        b = a;
        a = dec2bin(T,32);
        %display_resultsSHA1(t,a,b,c,d,e)         %receives column bits
	end

	H = calculate_new_HSHA1(H,a,b,c,d,e);

end
output=H;

time2=clock;
disp(etime(time2,time1));


% HEALPIX Border

clear

n = 2;
n = 4;
n = 4;

% sampling interval on the unit sphere
interval = pi / 90;

hold on
axis equal

% polar cap area

for k = 1:n
    start_phi = pi * k / (2 * n);
    end_phi = pi / 2;
    S = HealpixBorderLinePC(n, k, interval, start_phi, end_phi, 0);
    for m = 0:3
        % Northern Hemisphere
        C = SphToCart([S(:, 1), S(:, 2) + pi * m / 2]);
        plot3(C(:,1),C(:,2),C(:,3), 'k-')
        % Southern Hemisphere
        C = SphToCart([pi - S(:, 1), S(:, 2) + pi * m / 2]);
        plot3(C(:,1),C(:,2),C(:,3), 'k-')
    end

    start_phi = 0;
    end_phi = pi / 2 - pi * k / (2 * n);
    S = HealpixBorderLinePC(n, k, interval, start_phi, end_phi, 1);
    for m = 0:3
        % Northern Hemisphere
        C = SphToCart([S(:, 1), S(:, 2) + pi * m / 2]);
        plot3(C(:,1),C(:,2),C(:,3), 'k-')
        % Southern Hemisphere
        C = SphToCart([pi - S(:, 1), S(:, 2) + pi * m / 2]);
        plot3(C(:,1),C(:,2),C(:,3), 'k-')
    end
end

for k = 0:3
    % Northern Hemisphere
    PHI = 0:interval:acos(2 / 3);
    if PHI(end) ~= acos(2 / 3)  % if the end edge point was not included
        PHI = [PHI acos(2 / 3)];    % add the end edge
    end
    S = [PHI.', ones(size(PHI, 2), 1) * k * pi / 2];
    C = SphToCart(S);
    plot3(C(:,1),C(:,2),C(:,3), 'k-')

    % Southern Hemisphere
    PHI = acos(-2 / 3):interval:pi;
    if PHI(end) ~= pi  % if the end edge point was not included
        PHI = [PHI pi];    % add the end edge
    end
    S = [PHI.', ones(size(PHI, 2), 1) * k * pi / 2];
    C = SphToCart(S);
    plot3(C(:,1),C(:,2),C(:,3), 'k-')
end

% equatorial belt area

for k = (-3 * n):(n - 1)
    start_theta = acos(-2 / 3);
    start_phi = (-4 / 3 + 4 * k / (3 * n)) * 3 * pi / 8;
    end_phi = 4 * k / (3 * n) * 3 * pi / 8;
    S = HealpixBorderLineEB(n, k, interval, start_phi, end_phi, start_theta);
    C = SphToCart(S);
    plot3(C(:,1),C(:,2),C(:,3), 'k-')

    start_theta = acos(2 / 3);
    temp = -start_phi;
    start_phi = -end_phi;
    end_phi = temp;
    S = HealpixBorderLineEB(n, k, interval, start_phi, end_phi, start_theta);
    C = SphToCart(S);
    plot3(C(:,1),C(:,2),C(:,3), 'k-')
end

k = 5;
n = 2^k-1;
[x,y,z] = sphere(n);
c = zeros(32);
scale = 0.995;
surf(x*scale,y*scale,z*scale,c);
colormap([1  1  1])
shading flat
view(20,30);


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

% We test the performance of the inverse method using numerical
% algorithms based on the Kienitz extrapolation methodology
% for generating MC densities and we compare against analytic values

% Generate random numbers from a SABR density using numerical inversion
% of the cumulated probability and the density truncation method

clear; clc;
NSim = 100000;          % number of simulations
U = rand(1,NSim);       % uniforms

% sabr parameters
t =1;
% a = 0.25; b = 0.5; r = -.5;  f = 0.03;  n = 0.2;
% b= 0.5; r=-0.1595; f=0.0495;  n=0.3843;  a=0.1339 * f^(1-b);
b = 0.5;n=0.2;r=-0.2;f=0.03; a=0.9*f^(1-b);
% calibrate the parameters
[kl, mu, cl, bl, al, ku, nu, cu, bu, au] = ...
    psabr_param(a, b, r, n, f, 0.0001:0.0001:0.2, t,4);

% apply the calibrated density
d = @(x) psabr_5(a, b, r, n, f, x, t, ...
    kl, ku, mu, cl, bl, al, nu, cu, bu, au);

x_sabr = 0.001:0.0001:1;                % x_values for table
tic;
y_sabr = FSABR2_1(x_sabr,d);            % values for the table
US = FInvSABR4_2(U,x_sabr, y_sabr);     % inversion using table
toc

nbins = 150;
Nzero = sum(US==1);
Pzero = Nzero / NSim;
[n,xout] = hist(US,nbins);                % calc histogram
n(end) = 0;
pdensity = n/NSim*nbins; cdensity = cumsum(n) / NSim;

n(end) = 0;                             % remove artefact
figure;bar(n/nbins);                    % plot histogram
x = 0:.0001:1;                          % x values for plot
y = d(x);                               % calculate the density
Y = sum(y)*0.0001;
y(1) = 1-Y;
figure('Color', [1 1 1]);
hold on; plot([0 xout],[Pzero pdensity],'ro-'); plot(x,y); xlim([0,.2]); hold off; % plot sim against value
xlabel('Strike'); ylabel('Density p(x)');
x = [0 xout];                          % x values for plot
y = d(x);

figure('Color', [1 1 1]);
hold on; plot(x,[Pzero pdensity],'ro-'); plot(x,y,'gx-'); xlim([0,.25]); hold off; % plot sim against value

figure('Color', [1 1 1]);
plot(x,([Pzero pdensity] - y)./y); xlim([0,.25]); hold off; % plot sim against value


function r = cos(a)
%COS          Hessian (elementwise) cosine
%

% written  04/04/04     S.M. Rump
% 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

  K = prod(size(a.x));
  if K==1                   % scalar hessian

    r.x = cos(a.x);
    msinax = -sin(a.x);
    r.dx = msinax * a.dx;
    r.hx = msinax * a.hx - reshape( ((0.5*r.x)*a.dx) * a.dx.',size(a.hx));

  else                      % matrix hessian

    N = getappdata(0,'INTLAB_HESSIAN_NUMVAR');
    N2 = N^2;

    r.x = cos(full(a.x));
    if issparse(a.hx)               % input sparse

      ax = -sin(a.x(:));
      sizeax = length(ax);
      [ia,ja,sa] = find(a.dx);
      % check for emptyness: cures Matlab bug
      % a=sparse([],[],[],2,1), [i,j,s]=find(a), s(i).*s(:)  yields error
      if isempty(ia)
        r.dx = sparse([],[],[],N,sizeax);
        r.hx = sparse([],[],[],N2,sizeax);
      else
        adx1 = (-0.5)*r.x(:);
        if isa(a.x,'intval')          % sparse intval
          rdx = times(ax(ja),sa(:),0);
          adx1 = times(adx1(ja),sa(:),0);
          if rdx.complex
            r.dx = intval( sparse(ia,ja,rdx.mid,N,sizeax) , sparse(ia,ja,rdx.rad,N,sizeax) , 'midrad' );
          else
            r.dx = intval( sparse(ia,ja,rdx.inf,N,sizeax) , sparse(ia,ja,rdx.sup,N,sizeax) , 'infsup' );
          end
          if adx1.complex
            adx1 = intval( sparse(ia,ja,adx1.mid,N,sizeax) , sparse(ia,ja,adx1.rad,N,sizeax) , 'midrad' );
          else
            adx1 = intval( sparse(ia,ja,adx1.inf,N,sizeax) , sparse(ia,ja,adx1.sup,N,sizeax) , 'infsup' );
          end
        else                          % sparse point
          r.dx = sparse(ia,ja,ax(ja).*sa(:),N,sizeax);
          adx1 = sparse(ia,ja,adx1(ja).*sa(:),N,sizeax);
        end
        r.hx = adx2rhx(N,sizeax,adx1,a.dx);
      end
      [ia,ja,sa] = find(a.hx);        % sparse point or intval
      % check for emptyness: cures Matlab bug
      % a=sparse([],[],[],2,1), [i,j,s]=find(a), s(i).*s(:)  yields error
      if ~isempty(ia)
        if isa(a.x,'intval')
          rhx = times(ax(ja),sa(:),0);
          if rhx.complex
            r.hx = r.hx + intval( sparse(ia,ja,rhx.mid,N2,sizeax) , sparse(ia,ja,rhx.rad,N2,sizeax) , 'midrad' );
          else
            r.hx = r.hx + intval( sparse(ia,ja,rhx.inf,N2,sizeax) , sparse(ia,ja,rhx.sup,N2,sizeax) , 'infsup' );
          end
        else
          r.hx = r.hx + sparse(ia,ja,ax(ja).*sa(:),N2,sizeax);
        end
      end

    else                            % input full

      r.x = cos(a.x);
      rx = r.x(:).';
      msinax = -sin(a.x(:).');
      msinax = msinax(ones(N*N,1),:);
      r.dx = a.dx .* msinax(1:N,:);
      adx = repmat(0.5*rx,N,1) .* a.dx;
      r.hx = a.hx .* msinax - adx(repmat(1:N,N,1),:) .* a.dx(repmat(1:N,1,N),:);

    end

  end

  r = class(r,'hessian');

  if rndold
    setround(rndold)
  end


%% State Space MPC Tutorial
% This document explains how to use the setup function and online
% controller returned by ssmpcsetup.

%% State-space MPC set-up
% The online controller has to be set-up before use. To set-up the state
% space MPC controller, the user has to supply the state-space model,
% represented by A, B, C and D matrices (Note: it should be in
% discrete-time), the predication horizon, P, moving horizon, M and
% performance weights, Q and R. The default initial state and input are set
% to zero.
%
% SSMPC=MPCSETUP(A,B,C,D,P,M,Q,R,X0,U0);

%% Online controller
% The returned function handle from the MPC setup program is an online
% controller, SSMPC. The controller is called by proving two inputs:
% current measurement, Y and future reference, Ref. On return, it produces
% the optimal input, U for next step:
%
% U = SSMPC(Y,Ref);

%% A two-CSTR example
% A two-CSTR (Continuous Stired Reaction Tank) process is shown as follows.
%
% <html>
% <img src="2cstrPlant.png" width="600" height="400">
% </html>
%
% A linear state space of the model is developed for the plant. The model
% has six states, two inputs (two cooling water flow rates) and two
% disturbances (cooling water temperatures). The measured outputs are two
% tank temperatures. Further details of the process can be find in
% 1. Cao, Y and Yang, ZJ, "Multiobjective process controllability
% analysis", _Computers and Chemical Engineering_ , 28(2004), 83--90.
% 2. Al Seyab, RK and Cao, Y, "Differential recurrent neural network based
% predictive control", _Computers and Chemical Engineering_ , to appear.
%
% The discrete model with sampling rate 0.1 s is as follows:
A=[ 0.1555  -13.7665   -0.0604         0         0         0
    0.0010    1.0008    0.0068         0         0         0
         0    0.0374    0.9232         0         0         0
    0.0015   -0.1024   -0.0003    0.1587  -13.6705   -0.0506
         0    0.0061         0    0.0006    0.9929    0.0057
         0    0.0001         0         0    0.0366    0.9398];
Bu=[0.0001       0
         0       0
   -0.0036       0
         0  0.0001
         0       0
         0 -0.0028];
Bd=[      0         0
          0         0
     0.0013         0
          0         0
          0         0
          0    0.0008];
C=[0 362.995 0 0 0 0
   0 0 0 0 362.995 0];
D=zeros(2,2);

%% MPC parameters
% The MPC controller is configured with following parameters.
% Prediction horizon and moving horizon
p=10;
m=3;
% Performance wights
Q=1.5*eye(2*p);
R=eye(2*m);

%% MPC set-up
% The MPC controller is set-up by calling SSMPCSETUP:
ssmpc=mpcsetup(A,Bu,C,D,p,m,Q,R);

%% Simulation
% 150 seconds (1500 sampling intervals) simulation is conducted with
% several setpoint changes and random cooling water temperature changes
% within positive and negative 1 degree.
% Simulation length and variables for results
N=1500;
x0=zeros(6,1);
Y=zeros(N,2);
U=zeros(N,2);
% Predefined reference
T=zeros(N,2);
T(10:N,1)=1;
T(351:N,1)=3;
T(600:N,1)=5;
T(1100:N,1)=3;
T(100:N,2)=2;
T(451:N,2)=1;
T(700:N,2)=3;
T(1200:N,2)=4;
% Simulation
%%
for k=1:N
    % Process disturbances
    w=Bd*(rand(2,1)-0.5)*2;
    % Measurements noise
    v=0.01*randn(2,1);
    % actual measurement
    y=C*x0+v;
    % online controller
    u=ssmpc(y,T(k:end,:)');
    % plant update
    x0=A*x0+Bu*u+w;
    % save results
    Y(k,:)=y';
    U(k,:)=u';
end

%% Results
% The simulation results are summarized in two sub-plots.
t=(0:N-1)*0.1;
subplot(211)
plot(t,Y,t,T,'r--','linewidth',2)
title('output and setpoint')
ylabel('temp, C^\circ')
legend('T_1','T_2','Ref','location','southeast')
subplot(212)
stairs(t,U,'linewidth',2)
legend('u_1','u_2','location','southeast')
title('input')
ylabel('flow rate, m^3/s')
xlabel('time, s')


function C = coeffs3(f, m, n, p)
% COEFFS3   Trivariate Cheybshev-Fourier-Fourier expansion coefficients of F.
%   C = COEFFS3(F) returns the tensor of trivariate coefficients.  The
%   coefficients are arranged so they correspond the spherical coordinates
%   radial-azimuthal-polar.
%
%   X = COEFFS3(F, M, N, P) is the same as above but it returns
%   coefficients as an M x N x P tensor.

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

if ( nargin == 1 )
    % Return the coefficients
    C = f.coeffs;
else
    if ( nargin == 2 )
        n = m;
        p = m;
    elseif (nargin == 3 )
        p = n;
    end

    %% Copy the diff alias when we solve it below

    [mf, nf, pf] = size(f);
    F = f.coeffs;

    G = zeros(m,n,pf);

    for k = 1:pf
        G(:,:,k) = chebtech2.alias(trigtech.alias(F(:,:,k).',n).',m);
    end

    G = permute(G,[3,2,1]);
    C = zeros(p,n,m);

    for k = 1:m
       C(:,:,k) = trigtech.alias(G(:,:,k),p);
    end

    C = permute(C,[3,2,1]);
end


function r = acoth(a)
%ACOTH        Hessian (elementwise) inverse hyperbolic cotangent
%

% written  04/04/04     S.M. Rump
% 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

  K = prod(size(a.x));
  if K==1                   % scalar hessian

    r.x = acoth(a.x);
    f = 1 / ( 1 - sqr(a.x) );
    r.dx = a.dx * f;
    r.hx = ( a.hx + reshape( (a.x*r.dx) * a.dx.' , size(a.hx) ) ) * f;

  else                      % matrix hessian

    N = getappdata(0,'INTLAB_HESSIAN_NUMVAR');
    N2 = N^2;

    r.x = acoth(a.x);
    if issparse(a.hx)               % input sparse

      ax = 1 ./ ( 1 - sqr(full(a.x(:))) );
      sizeax = length(ax);
      [ia,ja,sa] = find(a.dx);
      % check for emptyness: cures Matlab bug
      % a=sparse([],[],[],2,1), [i,j,s]=find(a), s(i).*s(:)  yields error
      if isempty(ia)
        r.dx = sparse([],[],[],N,sizeax);
        r.hx = sparse([],[],[],N2,sizeax);
      else
        adx1 = a.x(:).*ax;
        if isa(a.x,'intval')          % sparse intval
          rdx = times(ax(ja),sa(:),0);
          adx1 = times(adx1(ja),sa(:),0);
          if rdx.complex
            r.dx = intval( sparse(ia,ja,rdx.mid,N,sizeax) , sparse(ia,ja,rdx.rad,N,sizeax) , 'midrad' );
          else
            r.dx = intval( sparse(ia,ja,rdx.inf,N,sizeax) , sparse(ia,ja,rdx.sup,N,sizeax) , 'infsup' );
          end
          if adx1.complex
            adx1 = intval( sparse(ia,ja,adx1.mid,N,sizeax) , sparse(ia,ja,adx1.rad,N,sizeax) , 'midrad' );
          else
            adx1 = intval( sparse(ia,ja,adx1.inf,N,sizeax) , sparse(ia,ja,adx1.sup,N,sizeax) , 'infsup' );
          end
        else                          % sparse point
          r.dx = sparse(ia,ja,ax(ja).*sa(:),N,sizeax);
          adx1 = sparse(ia,ja,adx1(ja).*sa(:),N,sizeax);
        end
        r.hx = adx2rhx(N,sizeax,adx1,r.dx);
      end
      [ia,ja,sa] = find(a.hx);      % sparse point or intval
      % check for emptyness: cures Matlab bug
      % a=sparse([],[],[],2,1), [i,j,s]=find(a), s(i).*s(:)  yields error
      if ~isempty(ia)
        if isa(a.x,'intval')
          rhx = times(ax(ja),sa(:),0);
          if rhx.complex
            r.hx = r.hx + intval( sparse(ia,ja,rhx.mid,N2,sizeax) , sparse(ia,ja,rhx.rad,N2,sizeax) , 'midrad' );
          else
            r.hx = r.hx + intval( sparse(ia,ja,rhx.inf,N2,sizeax) , sparse(ia,ja,rhx.sup,N2,sizeax) , 'infsup' );
          end
        else
          r.hx = r.hx + sparse(ia,ja,ax(ja).*sa(:),N2,sizeax);
        end
      end

    else                            % input full

      r.x = acoth(a.x);
      ax = a.x(:).';
      f = 1 ./ ( 1 - sqr(ax) );
      f = f(ones(N*N,1),:);
      r.dx = a.dx .* f(1:N,:);
      adx = repmat(ax,N,1) .* r.dx;
      r.hx = ( a.hx + adx(repmat(1:N,N,1),:) .* a.dx(repmat(1:N,1,N),:) ) .* f;

    end

  end

  r = class(r,'hessian');

  if rndold
    setround(rndold)
  end


function [Y, optinf] = celnet_gpu(D, S, lambda, mu, opt)

% celnet_gpu -- Convolutional Elastic Net (GPU version)
%
%         argmin_{x_m} (1/2)||\sum_m d_m * x_m - s||_2^2 +
%                      lambda \sum_m ||x_m||_1 + (mu/2) \sum_m ||x_m||_2^2
%
%         The solution is computed using an ADMM approach (see
%         boyd-2010-distributed) with efficient solution of the main
%         linear systems (see wohlberg-2016-efficient).
%
% Usage:
%       [Y, optinf] = celnet_gpu(D, S, lambda, mu, opt)
%
% Input:
%       D           Dictionary filter set (3D array)
%       s           Input image
%       lambda      Regularization parameter (l1)
%       mu          Regularization parameter (l2)
%       opt         Algorithm parameters structure
%
% Output:
%       Y           Dictionary coefficient map set (3D array)
%       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, l2
%                    regularisation term, and primal and dual residuals
%                    (see Sec. 3.3 of boyd-2010-distributed). The value of
%                    rho is also displayed if options request that it is
%                    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         Weighting array for coefficients in l1 norm of X.
%                    Array should have the same dimensions as X, but the
%                    first two dimensions may be of unit size, corresponding
%                    to a weighting that varies with filter index but is
%                    spatially constant.
%   L2Weight         Weighting array for l2 norm of X. Array should have
%                    dimensions corresponding to the non-spatial dimensions
%                    of X since spatial weighting is no possible (i.e.
%                    weighting varies only with filter and sample index).
%   Y0               Initial value for Y
%   U0               Initial value for U
%   rho              ADMM 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.
%   RhoRsdlTarget    Residual ratio targeted by auto rho update policy.
%   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)
%   RelaxParam       Relaxation parameter (see Sec. 3.4.3 of
%                    boyd-2010-distributed)
%   NoBndryCross     Flag indicating whether all solution coefficients
%                    corresponding to filters crossing the image boundary
%                    should be forced to zero.
%   AuxVarObj        Flag determining whether objective function is computed
%                    using the auxiliary (split) variable
%   HighMemSolve     Use more memory for a slightly faster solution
%
%
% Authors: Brendt Wohlberg <brendt@lanl.gov>
%          Ping-Keng Jao <jpk7656@gmail.com>
% Modified: 2015-12-18
%
% 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.

gS = gpuArray(S);
gD = gpuArray(D);
glambda = gpuArray(lambda);

if nargin < 5,
  opt = [];
end
if nargin < 4,
  gmu = gpuArray(0);
else
  gmu = gpuArray(mu);
end
checkopt(opt, defaultopts([]));
opt = defaultopts(opt);

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

% Start timer
tstart = tic;

% Collapsing of trailing singleton dimensions greatly complicates
% handling of both SMV and MMV cases. The simplest approach would be
% if S could always be reshaped to 4d, with dimensions consisting of
% image rows, image cols, a single dimensional placeholder for number
% of filters, and number of measurements, but in the single
% measurement case the third dimension is collapsed so that the array
% is only 3d.
if size(S,3) > 1,
  xsz = [size(S,1) size(S,2) size(D,3) size(S,3)];
  % Insert singleton 3rd dimension (for number of filters) so that
  % 4th dimension is number of images in input s volume
  S = reshape(S, [size(S,1) size(S,2) 1 size(S,3)]);
else
  xsz = [size(S,1) size(S,2) size(D,3) 1];
end
% Compute filters in DFT domain
gDf = fft2(gD, size(S,1), size(S,2));
% Convolve-sum and its Hermitian transpose
gDop = @(x) sum(bsxfun(@times, gDf, x), 3);
gDHop = @(x) bsxfun(@times, conj(gDf), x);
% Compute signal in DFT domain
gSf = fft2(gS);
% S convolved with all filters in DFT domain
gDSf = gDHop(gSf);

% Set up l2 weight array
if isscalar(opt.L2Weight),
  gwl2 = gpuArray(opt.L2Weight);
else
  gwl2 = gpuArray(reshape(opt.L2Weight, [1 1 size(opt.L2Weight,1) ...
                      size(opt.L2Weight,2)]));
end

% Default lambda is 1/10 times the lambda value beyond which the
% solution is a zero vector
if nargin < 3 | isempty(glambda),
  gb = ifft2(gDHop(gSf), 'symmetric');
  glambda = 0.1*max(vec(abs(gb)));
end
% Set up algorithm parameters and initialise variables
grho = gpuArray(opt.rho);
if isempty(grho), grho = 50*glambda+1; end;
gmwr = gmu*gwl2 + grho;
if isempty(opt.RhoRsdlTarget),
  if opt.StdResiduals,
    opt.RhoRsdlTarget = 1;
  else
    opt.RhoRsdlTarget = 1 + (18.3).^(log10(glambda) + 1);
  end
end
if opt.HighMemSolve,
  gcn = bsxfun(@rdivide, gDf, gmwr);
  gcd = sum(gDf.*bsxfun(@rdivide, conj(gDf), gmu*gwl2 + grho), 3) + 1.0;
  gC = bsxfun(@rdivide, gcn, gcd);
  clear cn cd;
else
  C = [];
end
gNx = prod(gpuArray(xsz));
optinf = struct('itstat', [], 'opt', opt);
gr = gpuArray(Inf);
gs = gpuArray(Inf);
gepri = gpuArray(0);
gedua = gpuArray(0);

% Initialise main working variables
% X = [];
if isempty(opt.Y0),
  gY = gpuArray.zeros(xsz);
else
  gY = gpuArray(opt.Y0);
end
gYprv = gY;
if isempty(opt.U0),
  if isempty(opt.Y0),
    gU = gpuArray.zeros(xsz);
  else
    gU = (glambda/grho)*sign(gY);
  end
else
  gU = gpuArray(opt.U0);
end

% Main loop
k = 1;
while k <= opt.MaxMainIter & (gr > gepri | gs > gedua),

  % Solve X subproblem
  gXf = solvedbd_sm(gDf, gmwr, gDSf + grho*fft2(gY - gU), gC);
  gX = ifft2(gXf, 'symmetric');

  % See pg. 21 of boyd-2010-distributed
  if opt.RelaxParam == 1,
    gXr = gX;
  else
    gXr = opt.RelaxParam*gX + (1-opt.RelaxParam)*gY;
  end

  % Solve Y subproblem
  gY = shrink(gXr + gU, (glambda/grho)*opt.L1Weight);
  if opt.NoBndryCross,
    gY((end-size(gD,1)+2):end,:,:,:) = 0;
    gY(:,(end-size(gD,1)+2):end,:,:) = 0;
  end

  % Update dual variable
  gU = gU + gXr - gY;

  % Compute data fidelity term in Fourier domain (note normalisation)
  if opt.AuxVarObj,
    gYf = fft2(gY); % This represents unnecessary computational cost
    gJdf = sum(vec(abs(sum(bsxfun(@times,gDf,gYf),3)-gSf).^2)) / ...
           (2*xsz(1)*xsz(2));
    gJl1 = sum(abs(vec(bsxfun(@times, opt.L1Weight, gY))));
    gJl2 = sum(vec(gwl2.*sum(sum(gY.^2, 1),2)))/2;
  else
    gJdf = sum(vec(abs(sum(bsxfun(@times,gDf,gXf),3)-gSf).^2)) / ...
           (2*xsz(1)*xsz(2));
    gJl1 = sum(abs(vec(bsxfun(@times, opt.L1Weight, gX))));
    gJl2 = sum(vec(gwl2.*sum(sum(gX.^2, 1),2)))/2;
  end
  gJfn = gJdf + glambda*gJl1 + gmu*gJl2;

  gnX = norm(gX(:)); gnY = norm(gY(:)); gnU = norm(gU(:));
  if opt.StdResiduals,
    % See pp. 19-20 of boyd-2010-distributed
    gr = norm(vec(gX - gY));
    gs = norm(vec(grho*(gYprv - gY)));
    gepri = sqrt(gNx)*opt.AbsStopTol+max(gnX,gnY)*opt.RelStopTol;
    gedua = sqrt(gNx)*opt.AbsStopTol+grho*gnU*opt.RelStopTol;
  else
    % See wohlberg-2015-adaptive
    gr = norm(vec(gX - gY))/max(gnX,gnY);
    gs = norm(vec(gYprv - gY))/gnU;
    gepri = sqrt(gNx)*opt.AbsStopTol/max(gnX,gnY)+opt.RelStopTol;
    gedua = sqrt(gNx)*opt.AbsStopTol/(grho*gnU)+opt.RelStopTol;
  end

  % Record and display iteration details
  tk = toc(tstart);
  optinf.itstat = [optinf.itstat; [k gather(gJfn) gather(gJdf) gather(gJl1) ...
                   gather(gJl2) gather(gr) gather(gs) gather(gepri) ...
                      gather(gedua) gather(grho) tk]];
  if opt.Verbose,
    if opt.AutoRho,
      disp(sprintf(sfms, k, gather(gJfn), gather(gJdf), gather(gJl1), ...
                   gather(gJl2), gather(gr), gather(gs), gather(grho)));
    else
      disp(sprintf(sfms, k, gather(gJfn), gather(gJdf), gather(gJl1), ...
                   gather(gJl2), gather(gr), gather(gs)));
    end
  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,
        grhomlt = sqrt(gr/(gs*opt.RhoRsdlTarget));
        if grhomlt < 1, grhomlt = 1/grhomlt; end
        if grhomlt > opt.RhoScaling, grhomlt = opt.RhoScaling; end
      else
        rhomlt = opt.RhoScaling;
      end
      grsf = 1;
      if gr > opt.RhoRsdlTarget*opt.RhoRsdlRatio*gs, grsf = grhomlt; end
      if gs > (opt.RhoRsdlRatio/opt.RhoRsdlTarget)*gr, grsf = 1/grhomlt; end
      grho = grsf*grho;
      gU = gU/grsf;
      if opt.HighMemSolve && grsf ~= 1,
        gmwr = gmu*gwl2 + grho;
        gcn = bsxfun(@rdivide, gDf, gmwr);
        gcd = sum(gDf.*bsxfun(@rdivide, conj(gDf), gmwr), 3) + 1.0;
        gC = bsxfun(@rdivide, gcn, gcd);
        clear gcn gcd;
      end
    end
  end

  gYprv = gY;
  k = k + 1;

end

% Record run time and working variables
optinf.runtime = toc(tstart);
optinf.X = gather(gX);
optinf.Xf = gather(gXf);
optinf.Y = gather(gY);
optinf.U = gather(gU);
optinf.lambda = gather(glambda);
optinf.mu = gather(mu);
optinf.rho = gather(grho);
Y = gather(gY);
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)

  if isscalar(lambda),
    u = sign(v).*max(0, abs(v) - lambda);
  else
    u = sign(v).*max(0, bsxfun(@minus, abs(v), lambda));
  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 = 0;
  end
  if ~isfield(opt,'RelStopTol'),
    opt.RelStopTol = 1e-4;
  end
  if ~isfield(opt,'L1Weight'),
    opt.L1Weight = 1;
  end
  if ~isfield(opt,'L2Weight'),
    opt.L2Weight = 1;
  end
  if ~isfield(opt,'Y0'),
    opt.Y0 = [];
  end
  if ~isfield(opt,'U0'),
    opt.U0 = [];
  end
  if ~isfield(opt,'rho'),
    opt.rho = [];
  end
  if ~isfield(opt,'AutoRho'),
    opt.AutoRho = 1;
  end
  if ~isfield(opt,'AutoRhoPeriod'),
    opt.AutoRhoPeriod = 1;
  end
  if ~isfield(opt,'RhoRsdlRatio'),
    opt.RhoRsdlRatio = 1.2;
  end
  if ~isfield(opt,'RhoScaling'),
    opt.RhoScaling = 100;
  end
  if ~isfield(opt,'AutoRhoScaling'),
    opt.AutoRhoScaling = 1;
  end
  if ~isfield(opt,'RhoRsdlTarget'),
    opt.RhoRsdlTarget = [];
  end
  if ~isfield(opt,'StdResiduals'),
    opt.StdResiduals = 0;
  end
  if ~isfield(opt,'RelaxParam'),
    opt.RelaxParam = 1.8;
  end
  if ~isfield(opt,'NoBndryCross'),
    opt.NoBndryCross = 0;
  end
  if ~isfield(opt,'AuxVarObj'),
    opt.AuxVarObj = 0;
  end
  if ~isfield(opt,'HighMemSolve'),
    opt.HighMemSolve = 0;
  end

return


function c=ref_edgtii_1(f,g,a,M)
%REF_EDGTII_1   Reference Even Discrete Gabor transform type II by DGT
%   Usage  c=ref_edgt(f,g,a,M);
%
%   If a is even, then the input window must be odd-centered of length 2L.
%
%   If a is odd, then the input window must be even-centered of length 2L.
%

L=size(f,1);
W=size(f,2);

N=L/a;

clong=ref_gdgt([f;conj(flipud(f))],g,a,M,.5,0,floor(a/2));

c=clong(1:M*N,:);


% Partially reproduces figure 1 from "Online Prediction of Time Series Data
% With Kernels". (3 algorithms, 25 MC simulations.)
%
% Learning curves for KNLMS, NORMA, and KRLS on a nonlinear system.
% Execution time: 2.5 minutes (Intel Pentium Core2 Duo).
%
% C. Richard, J.C.M. Bermudez, and P. Honeine, "Online Prediction of Time
% Series Data With Kernels," IEEE Transactions on Signal Processing,
% vol. 57, no. 3, pp. 1058-1067, March 2009,
% http://dx.doi.org/10.1109/TSP.2008.2009895
%
% This file is part of the Kernel Adaptive Filtering Toolbox for Matlab
% https://github.com/steven2358/kafbox/

clear
close all

%% PARAMETERS

N = 3000; % number of training data points
ktype = 'gauss';
kpar = 1/sqrt(2*3.73);

setups{1} = norma(struct('lambda',0.98,'tau',38,'eta',1,'tcoeff',-1/2,'kerneltype',ktype,'kernelpar',kpar));
setups{2} = knlms(struct('eta',.09,'eps',0.03,'mu0',0.5,'kerneltype',ktype,'kernelpar',kpar));
setups{3} = krls(struct('nu',.6,'kerneltype',ktype,'kernelpar',kpar));

numsim = 25;

%% RUN ALGORITHMS
t1 = tic;
fprintf('Fig. 1 from "Online Prediction of Time Series Data With Kernels".\n');

num_setup = length(setups);
MSE = zeros(N,num_setup);
titles = cell(num_setup,1);

for sim_ind = 1:numsim
    fprintf('SIM %d:\n',sim_ind)

    % Generate the data
    [X,y,yref] = generate_doddbench(N);

    for setup_ind = 1:num_setup
        kaf = setups{setup_ind};
        titles{setup_ind} = upper(class(kaf));

        for n=1:N
            if ~mod(n,floor(N/10)), fprintf('.'); end % progress indicator, 10 dots

            y_est = kaf.evaluate(X(n,:)); % test on test set
            err = yref(n) - y_est;
            MSE(n,setup_ind) = MSE(n,setup_ind) + err.^2/numsim;

            kaf.train(X(n,:),y(n)); % train with one input-output pair
        end
        fprintf('\n');
    end
end

toc(t1)
%% OUTPUT

% MSE smoothing by moving average for visualization
MSE_smooth = filter(1/20*ones(20,1),1,MSE);

figure
plot(10*log10(MSE_smooth));
title('Learning curves')
grid on

xlabel('iteration')
ylabel('MSE (dB)')
legend(titles)


function pass = test_eulerTricomi( prefs )
% Check that Euler--Tricomi equation is working.
% Alex Townsend, August 2013.

% First, check that all the particular solutions are being
% calculated correctly.

if ( nargin < 1 )
    prefs = chebfunpref();
end
tol = 100*prefs.techPrefs.chebfuneps;

exact = chebfun2(@(x,y) 1+0*x);
N = chebop2(@(x,y,u) diff(u,2,2) - x.*diff(u,2,1));
N.lbc = exact(-1,:); N.rbc = exact(1,:);
N.ubc = exact(:,1); N.dbc = exact(:,-1);
u = N \ 0 ;
pass(1) = ( norm( u - exact ) < tol );

exact = chebfun2(@(x,y) y);
N = chebop2(@(x,y,u) diff(u,2,2) - x.*diff(u,2,1));
N.lbc = exact(-1,:); N.rbc = exact(1,:);
N.ubc = exact(:,1); N.dbc = exact(:,-1);
u = N \ 0 ;
pass(2) = ( norm( u - exact ) < tol );

exact = chebfun2(@(x,y) x);
N = chebop2(@(x,y,u) diff(u,2,2) - x.*diff(u,2,1));
N.lbc = exact(-1,:); N.rbc = exact(1,:);
N.ubc = exact(:,1); N.dbc = exact(:,-1);
u = N \ 0 ;
pass(3) = ( norm( u - exact ) < tol );

exact = chebfun2(@(x,y) x.*y);
N = chebop2(@(x,y,u) diff(u,2,2) - x.*diff(u,2,1));
N.lbc = exact(-1,:); N.rbc = exact(1,:);
N.ubc = exact(:,1); N.dbc = exact(:,-1);
u = N \ 0 ;
pass(4) = ( norm( u - exact ) < tol );

exact = chebfun2(@(x,y) 3*y.^2+x.^3);
%exact = chebfun2(@(x,y) y.^2-x.^2);
N = chebop2(@(x,y,u) diff(u,2,2) - x.*diff(u,2,1));
N.lbc = exact(-1,:); N.rbc = exact(1,:);
N.ubc = exact(:,1); N.dbc = exact(:,-1);
u = N \ 0;
pass(5) = ( norm( u - exact ) < tol );

exact = chebfun2(@(x,y) 3*x.^2+y.^3);
% exact = chebfun2(@(x,y) 3*x.^2+y.^3);
N = chebop2(@(x,y,u) y.*diff(u,2,2) - diff(u,2,1));
N.lbc = exact(-1,:); N.rbc = exact(1,:);
N.ubc = exact(:,1); N.dbc = exact(:,-1);
u = N \ 0 ;
pass(6) = ( norm( u - exact ) < tol );

exact = chebfun2(@(x,y) 3*x.^2+y.^3);
% exact = chebfun2(@(x,y) 3*x.^2+y.^3);
N = chebop2(@(x,y,u) -y.*diff(u,2,2) + diff(u,2,1));
N.lbc = exact(-1,:); N.rbc = exact(1,:);
N.ubc = exact(:,1); N.dbc = exact(:,-1);
u = N \ 0 ;
pass(7) = ( norm( u - exact ) < tol );

exact = chebfun2(@(x,y) y.^3+x.^3.*y);
N = chebop2(@(x,y,u) diff(u,2,2) - x.*diff(u,2,1));
N.lbc = exact(-1,:); N.rbc = exact(1,:);
N.ubc = exact(:,1); N.dbc = exact(:,-1);
u = N \ 0 ;
pass(8) = ( norm( u - exact ) < tol );

exact = chebfun2(@(x,y) 6*x.*y.^2+x.^4);
N = chebop2(@(x,y,u) diff(u,2,2) - x.*diff(u,2,1));
N.lbc = exact(-1,:); N.rbc = exact(1,:);
N.ubc = exact(:,1); N.dbc = exact(:,-1);
u = N \ 0 ;
pass(9) = ( norm( u - exact ) < tol );

end


function t = spm_convmtx(v,n,OPT)
% as for convmtx but with boundary conditions
% FORMAT t = spm_convmtx(C,N,OPT)
%
% OPT  - 'circular' boundary conditions
%      - 'square'   top and tail convolution matrix
%
%--------------------------------------------------------------------------
%   CONVMTX(C,N) returns the convolution matrix for vector C.
%   If C is a column vector and X is a column vector of length N,
%   then CONVMTX(C,N)*X is the same as CONV(C,X).
%   If R is a row vector and X is a row vector of length N,
%   then X*CONVMTX(R,N) is the same as CONV(R,X).
%   See also CONV.%
%   With the circular option the convolution matrix is reduced to N X N
%__________________________________________________________________________
% Copyright (C) 1988-2004 The MathWorks, Inc.

% L. Shure and T. Krauss
% $Id: spm_convmtx.m 6122 2014-07-25 13:48:47Z karl $

if nargin < 3;
    OPT = 'none';
end

% create Toeplitz matrix
%--------------------------------------------------------------------------
[mv,nv] = size(v);
v    = full(v(:));                              % make v a column vector
c    = [v; zeros(n-1,1)];
r    = zeros(n,1);
m    = length(c);
x    = [r(n:-1:2) ; c(:)];                      % build vector of user data
cidx = (0:m-1)';
ridx = n:-1:1;
t    = cidx(:,ones(n,1)) + ridx(ones(m,1),:);   % Toeplitz subscripts
t(:) = x(t);                                    % actual data

% transpose if necessary
%--------------------------------------------------------------------------
if mv < nv
    t = t.';
end

% apply optional boundary conditions
%--------------------------------------------------------------------------
switch OPT

    case('circular')
        m      = fix((size(t,1) - n)/2);
        j      = (1:m) + m;
        t(j,:) = t(j,:) + t(j + n,:);
        j      = (1:m) + n;
        t(j,:) = t(j,:) + t(j - n,:);
        j      = 1:n;
        t      = t(j + m,:);

    case('square')
        m      = fix((size(t,1) - n)/2);
        j      = 1:n;
        t      = t(j + m,:);

    otherwise
end


function u = forward ( e, r, sigma, t1, Nx, Nt, L )

%*****************************************************************************80
%
%% FORWARD uses the forward difference method to value a European call option.
%
%  Modified:
%
%    28 March 2005
%
%  Author:
%
%    Original MATLAB version by Desmond Higham
%
%  Reference:
%
%    Desmond Higham,
%    Black-Scholes for Scientific Computing Students,
%    Computing in Science and Engineering,
%    November/December 2004, Volume 6, Number 6, pages 72-79.
%
%  Parameters:
%
%    Input, real E, the exercise price.
%
%    Input, real R, the interest rate.
%
%    Input, real SIGMA, the volatility of the asset.
%
%    Input, real T1, the expiry date.
%
%    Input, integer NX, the number of "space" steps used to divide the
%    interval [0,L].
%
%    Input, integer NT, the number of time steps.
%
%    Input, real L, the maximum value of S to consider.
%
%    Output, real U(NX-1,NT+1), the value of the European call option.
%
  k = t1 / Nt;
  h = L / Nx;
  TR1 = diag ( ones ( Nx-2,1),1) - diag ( ones(Nx-2,1), -1 );
  TR2 = -2 * eye(Nx-1,Nx-1) + diag(ones(Nx-2,1),1) + diag(ones(Nx-2,1),-1);
  mvec = [1:Nx-1];
  D1 = diag ( mvec );
  D2 = diag ( mvec.^2 );
  Aftcs = ( 1.0 - r * k ) * eye ( Nx-1,Nx-1 ) ...
        + 0.5 * k * sigma^2 * D2 * TR2 ...
        + 0.5 * k * r * D1 * TR1;

  u = zeros ( Nx-1,Nt+1);
  uzero = max ( [h:h:L-h]'-e, 0.0 );
  u(:,1) = uzero;
  p = zeros(Nx-1,1);

  for i = 1 : Nt
    tau = ( i - 1 ) * k;
    p(end) = 0.5 * k * (Nx-1) * ((sigma^2)*(Nx-1)+r) * ( L - e * exp ( - r * tau ) );
    u(:,i+1) = Aftcs * u(:,i) + p;
  end

  return
end


function [f,fp] = stft( x, sz, hp, pd, w)

if isreal( x)

	% Defaults
	if nargin < 5
		w = 1;
	end
	if nargin < 4
		pd = 0;
	end
	if nargin < 3
		hp = sz/2;
	end

        extra = (length(x)-sz)/hp;
        padding = ceil(extra)*hp + sz - length(x);
	x = [x zeros( 1, padding)];
%	x = [zeros( 1, sz+pd) x zeros( 1, sz+pd)];

	% Pack frames into matrix
	s = zeros( sz, (length(x)-sz)/hp);
	j = 1;
	for i = sz:hp:length( x)
		s(:,j) = w .* x((i-sz+1):i).';
		j = j + 1;
	end

	% FFT it
	f = fft( s, sz+pd);

	% Chop redundant part
	f = f(1:end/2+1,:);

	% Return phase component if asked to
	if nargout == 2
		fp = angle( f);
		fp = cos( fp) + sqrt(-1)*sin( fp);
	end

% Inverse transform
else

	% Defaults
	if nargin < 5
		w = 1;
	end
	if nargin < 4
		pd = 0;
	end
	if nargin < 3
		hp = sz/2;
	end

	% Ignore padded part
	if length( w) == sz
		w = [w; zeros( pd, 1)];
	end

	% Overlap add/window/replace conjugate part
	f = zeros( 1, (size(x,2)-1)*hp+sz+pd);
	v = 1:sz+pd;
	for i = 1:size( x,2)
		f((i-1)*hp+v) = f((i-1)*hp+v) + ...
			(w .* real( ifft( [x(:,i); conj( x(end-1:-1:2,i))])))';
	end

	% Norm for overlap
	f = f / (sz/hp);
	f = f(sz+pd+1:end-sz-2*pd);
end


function [decomp] = Decomposite_eig_new(M)

% input:  X is a cell structure, each containing a PSD matrix;
%         Y is a cell structure, each containing a PSD matrix;
%         index decides the set of eigenvalues to be included;
%
dim = size(M.X_cov,1);
n_X = size(M.X_cov,3);
if(n_X == 0)
    disp('X is empty, error!');
    return;
end

% extract eigenvalues and check PSD for input;

V_x = zeros(dim,dim,n_X);
D_x = zeros(dim,dim,n_X);

for i = 1:n_X
    [V,D] = eig(M.X_cov(:,:,i));
    Sorted_D = sort(diag(D),'descend');

    V_x(:,:,i) = fliplr(V(:,:));
    D_x(:,:,i) = abs(diag(Sorted_D));
end

decomp.V = V_x;
decomp.D = D_x;

end


function [ p, rank ] = perm_tj_successor ( n, p, rank )

%*****************************************************************************80
%
%% PERM_TJ_SUCCESSOR computes the Trotter-Johnson permutation successor.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 January 2011
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Donald Kreher, Douglas Simpson,
%    Combinatorial Algorithms,
%    CRC Press, 1998,
%    ISBN: 0-8493-3988-X,
%    LC: QA164.K73.
%
%  Parameters:
%
%    Input, integer N, the number of values being permuted.
%    N must be positive.
%
%    Input/output, integer P(N), describes the permutation.
%    P(I) is the item which is permuted into the I-th place
%    by the permutation.
%
%    Input/output, integer RANK, the rank.
%    If RANK = -1 on input, then the routine understands that this is
%    the first call, and that the user wishes the routine to supply
%    the first element in the ordering, which has RANK = 0.
%    In general, the input value of RANK is increased by 1 for output,
%    unless the very last element of the ordering was input, in which
%    case the output value of RANK is 0.
%

%
%  Return the first element.
%
  if ( rank == -1 )
    p = 1 : n;
    rank = 0;
    return
  end
%
%  Check.
%
  missing = perm_check ( n, p );

  if ( missing ~= 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'PERM_TJ_SUCCESSOR - Fatal error!\n' );
    fprintf ( 1, '  The input array is illegal.\n' );
    fprintf ( 1, '  Missing element = ', missing );
    error ( 'PERM_TJ_SUCCESSOR - Fatal error!' );
  end

  st = 0;
  q(1:n) = p(1:n);
  done = 0;
  m = n;

  while ( 1 < m && ~done )

    d = 1;
    while ( q(d) ~= m )
      d = d + 1;
    end

    for i = d : m - 1
      q(i) = q(i+1);
    end

    par = perm_parity ( m - 1, q );

    if ( par == 1 )

      if ( d == m )
        m = m - 1;
      else
        t         = p(st+d);
        p(st+d)   = p(st+d+1);
        p(st+d+1) = t;
        done = 1;
      end

    else

      if ( d == 1 )
        m = m - 1;
        st = st + 1;
      else
        t         = p(st+d);
        p(st+d)   = p(st+d-1);
        p(st+d-1) = t;
        done = 1;
      end

    end

  end
%
%  Last element was input.  Return first one.
%
  if ( m == 1 )
    p = 1 : n;
    rank = 0;
    return
  end

  rank = rank + 1;

  return
end


function [classMeans,clusterIndex,maxIterReached] = prtUtilKmeans(data,nClusters,varargin)
%[classMeans,clusterIndex] = prtUtilKmeans(data,nClusters)
%   Perform k-means clustering on the nObservations x nFeatures matrix data
%   using nClusters.  classMeans is a matrix of size nClusters (or less) x
%   nFeatures representing the classMeans, and clusterIndex is a
%   nObservations x 1 vector indicating the closest mean to each
%   observation in data.
%
%[classMeans,clusterIndex] = prtUtilKmeans(data,nClusters,param1,value1,...)
%   Enables inputs of parameter/value pairs as described below:
%
%   Parameters:
%       initialMeans - string or double matrix of size nClusters x
%       nFeatures.  If initialMeans is a string, it can be 'random' or
%       'plusplus'. random  which uses random samples from the data to
%       initialize the classMeans. plusplus uses the kMeans++ algorithm
%           Arthur, D. and Vassilvitskii, S. (2007).
%               k-means++: The advantages of careful seeding.
%               Proceedings of the eighteenth annual ACM-SIAM
%               symposium on Discrete algorithms. 1027?1035.
%       If initialMeans is a double matrix, the rows of the
%       matrix represetnt the initial class means, and nClusters is
%       ignored.  Default is 'plusplus'.
%
%       distanceMetricFn - prtDistance* function specifying the distance
%       metric to use.  distanceMetricFn(x,x) must return 0.  Default value
%       is @(data,centers)prtDistanceEuclidean(data,centers));
%
%       handleEmptyClusters - string specifying how to handle empty
%       clusters.  Allowed values are 'remove' and 'random'.  Default value
%       is 'remove'.
%
%       plotVisualization - bool value specifying whether to display a plot
%       of the current class centers and the corresponding data on every
%       iteration.  plotVisualization can also be a counting number, in
%       which case it specifies how often to update the plot.  Default
%       value is 'false'.
%
%   Example usage:
%
%       ds = prtDataGenBimodal(100);
%       data = ds.getObservations;
%       close all;
%       [classMeans,clusterIndex] = prtUtilKmeans(data,4,'plotVisualization',4);
%
%       close all;
%       [classMeans,clusterIndex] = prtUtilKmeans(data,4,'plotVisualization',4,'distanceMetricFn',@prtDistanceCityBlock);
%

p = inputParser;

%p.addParamValue('initialMeans',randn(50,2)/10);
p.addParamValue('initialMeans','random');
p.addParamValue('distanceMetricFn',@(data,centers)prtDistanceEuclidean(data,centers));
p.addParamValue('handleEmptyClusters','remove');
p.addParamValue('maxIterations',1000);
p.addParamValue('plotVisualization',false);
p.addParamValue('logicalMeans',false);

p.parse(varargin{:});
inputStructure = p.Results;

[nSamples,nDimensions] = size(data); %#ok<NASGU>
clusterIndexOld = nan(nSamples,1);
clusterIndex = [];

for iter = 1:inputStructure.maxIterations

    if iter == 1; %initialize
        if isa(inputStructure.initialMeans,'char')
            switch lower(inputStructure.initialMeans)
                case 'random'
                    randInds = max(1,ceil(rand(1,nClusters)*nSamples));
                    classMeans = data(randInds,:);
                case 'plusplus'

                    classMeans = nan(nClusters, size(data,2));
                    classMeans(1,:) = data(max(1,ceil(rand*nSamples)),:);
                    initDistanceMat = nan(nSamples,nClusters);
                    for iCluster = 2:nClusters
                        initDistanceMat(:,iCluster-1) = sum(bsxfun(@minus,data,classMeans(iCluster-1,:)).^2,2); % KMeans++ uses a squared euclidean distance.

                        minDistances = min(initDistanceMat,[],2);
                        drawProbabilities = minDistances./sum(minDistances);

                        newClusterMeanIndex = prtRvUtilRandomSample(drawProbabilities, 1);

                        classMeans(iCluster,:) = data(newClusterMeanIndex,:);
                    end

                otherwise
                    error('invalid');
            end
        elseif isnumeric(inputStructure.initialMeans)
            classMeans = inputStructure.initialMeans;
            nClusters = size(classMeans,1);
        else
            error('invalid');
        end
    else
        for clusterInd = 1:nClusters
            classMeans(clusterInd,:) = mean(data(clusterIndex == clusterInd,:),1);
        end
        if inputStructure.logicalMeans
            classMeans = classMeans>0.5;
        end
    end

    if ~mod(iter,inputStructure.plotVisualization);
        prtUtilKmeansPlotVisualization(data,classMeans,clusterIndex,inputStructure,iter);
    end

    distanceMat = inputStructure.distanceMetricFn(data,classMeans);
    [twiddle,clusterIndex] = min(distanceMat,[],2); %#ok<ASGLU>

    %Handle empty clusters:
    nMaxFixSteps = 10;
    for iFix = 1:nMaxFixSteps
        if length(unique(clusterIndex)) ~= nClusters
            invalidClusters = setdiff(1:nClusters,clusterIndex);
            validClusters = intersect(1:nClusters,clusterIndex);
            switch lower(inputStructure.handleEmptyClusters)
                case 'remove'
                    classMeans = classMeans(validClusters,:);
                    nClusters = nClusters - length(invalidClusters);
                    distanceMat = distanceMat(:,validClusters);
                    [twiddle,clusterIndex] = min(distanceMat,[],2); %#ok<ASGLU>
                case 'random'
                    randInds = max(1,ceil(rand(1,length(invalidClusters))*nSamples));
                    classMeans(invalidClusters,:) = data(randInds,:);
                    distanceMat =  inputStructure.distanceMetricFn(data,classMeans);
                    [twiddle,clusterIndex] = min(distanceMat,[],2); %#ok<ASGLU>
                otherwise
                    error('invalid');
            end
        else
            break
        end
    end
    if iFix == nMaxFixSteps
        maxIterReached = true;
        return
    end
    %Check convergence:
    if all(clusterIndexOld == clusterIndex)
        maxIterReached = false;
        return;
    else
        clusterIndexOld = clusterIndex;
    end

end
maxIterReached = true;

function prtUtilKmeansPlotVisualization(data,classMeans,clusterIndex,inputStructure,iter)

[nSamples,nDimensions] = size(data); %#ok<ASGLU>
if iter == 1
    distanceMat =  inputStructure.distanceMetricFn(data,classMeans);
    [twiddle,clusterIndex] = min(distanceMat,[],2); %#ok<ASGLU>
end
if nDimensions > 3
    warning('prt:prtUtilKmeans','plotVisualization is true, but dimensionality of data (%d) is > 3',nDimensions);
    return;
end
ds = prtDataSetClass(data,clusterIndex);

plot(ds);
hold on;
switch nDimensions
    case 1
        plot(classMeans,'b.');
    case 2
        plot(classMeans(:,1),classMeans(:,2),'b.');
    case 3
        plot3(classMeans(:,1),classMeans(:,2),classMeans(:,3),'b.');
end
hold off;
title(sprintf('Iteration %d',iter));
drawnow; %pause;


function bm=EWT_beta(x)

% function used in the construction of Meyer's wavelet
if x<0
    bm=0;
elseif x>1
    bm=1;
else
    bm=x^4*(35-84*x+70*x^2-20*x^3);
end


function imgOut = GammaDrago(img, drago_gamma, drago_slope, drago_start)
%
%        imgOut = GammaDrago(img, drago_gamma, drago_slope, drago_start)
%
%        This function applies gamma correction for the Drago et al.'s TMO,
%        please see DragoTMO.m
%
%        Input:
%           -img: an LDR image tone mapped with DragoTMO.m
%           -drago_gamma: is the elevation ratio of the line passing by the
%            origin and tangent to the curve
%           -drago_slope: f-stop value
%           -drago_start: is the abscissa at the point of tangency
%
%        Output:
%           -imgOut: gamma corrected img version
%
%     Copyright (C) 2013  Francesco Banterle
%
%     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/>.
%

if(~exist('drago_gamma','var'))
    drago_gamma = 2.2;
end

if(~exist('drago_slope','var'))
    drago_slope = 4.5;
end

if(~exist('drago_start','var'))
    drago_start = 0.018;
end

%applying gamma correction as in Drago et al. 2003
indx1 = find(img<=drago_start);
indx2 = find(img> drago_start);
img(indx1) =  img(indx1)*drago_slope;
img(indx2) = (img(indx2).^(0.9/drago_gamma))*1.099-0.099;

%clamping values out of the range [0.0,1.0]
imgOut = ClampImg(img, 0.0, 1.0);

end


function [yi, ypi, yppi] = qhermite(x, y, yp, ypp, xi, v)

% QHERMITE 1-D piecewise quintic Hermite spline
%    QHERMITE(X,Y,YP,YPP,XI,M) interpolates to find YI, the values of
%    the underlying function Y at the points in the array XI, using
%    piecewise quintic Hermite splines.  X and Y must be vectors
%    of length N.
%
%    V specifies how tangents are calculated when derivatives are not
%    specified.  V can be:
%       0 : Finite difference (default)
%       1 : Catmull-Rom spline
%
%    [YI,YPI,YPPI] = QHERMITE() also returns the interpolated
%    quartic derivative and cubic second derivative of the underlying
%    function Y at points XI.

% Joe Henning - Fall 2011

if (nargin < 6)
   v = 0;
end

if (v == 0)
   % precompute finite difference derivatives
   if (isempty(yp) && isempty(ypp))
      m = 0;
      yp = lfindiff (x, y);
      ypp = lfindiff (x, yp);
   elseif (isempty(yp))
      m = 1;
      yp = lfindiff (x, y);
   elseif (isempty(ypp))
      m = 2;
      ypp = lfindiff (x, yp);
   else
      m = -1;
   end
else
   if (isempty(yp) && isempty(ypp))
      m = 0;
   elseif (isempty(yp))
      m = 1;
   elseif (isempty(ypp))
      m = 2;
   else
      m = -1;
   end
end

n = length(x);

for i = 1:length(xi)
   % Find the right place in the table by means of a bisection.
   klo = 1;
   khi = n;
   while (khi-klo > 1)
      k = fix((khi+klo)/2.0);
      if (x(k) > xi(i))
         khi = k;
      else
         klo = k;
      end
   end

   h = x(khi) - x(klo);
   if (h == 0.0)
      fprintf('??? Bad x input to qhermite ==> x values must be distinct\n');
      yi(i) = NaN;
      ypi(i) = NaN;
      yppi(i) = NaN;
      continue;
   end

   if (m == -1)
      a = yp(klo);
      b = yp(khi);
      c = ypp(klo);
      d = ypp(khi);
   elseif (v == 0)
      % Finite difference
      a = yp(klo);
      b = yp(khi);
      c = ypp(klo);
      d = ypp(khi);
   elseif (m == 0)
      if (klo == 1)
         a = (y(khi) - y(klo))/h;
         b = (y(khi+1) - y(klo))/(x(khi+1) - x(klo));
         c = ((y(khi+1) - y(khi))/(x(khi+1) - x(khi)) - (y(khi) - y(klo))/h)/...
             (x(khi+1) - x(klo));
         d = 2*(y(khi+1) - 2*y(khi) + y(klo) - (x(khi+1) - 2*x(khi) + x(klo))*b)/...
             ((x(khi+1) - x(khi))*(x(khi+1) - x(khi)) + h*h);
      elseif (khi == n)
         a = (y(khi) - y(klo-1))/(x(khi) - x(klo-1));
         b = (y(khi) - y(klo))/h;
         c = 2*(y(khi) - 2*y(klo) + y(klo-1) - (x(khi) - 2*x(klo) + x(klo-1))*a)/...
             (h*h + (x(klo) - x(klo-1))*(x(klo) - x(klo-1)));
         d = ((y(khi) - y(klo))/h - (y(klo) - y(klo-1))/(x(klo) - x(klo-1)))/...
             (x(khi) - x(klo-1));
      else
         a = (y(khi) - y(klo-1))/(x(khi) - x(klo-1));
         b = (y(khi+1) - y(klo))/(x(khi+1) - x(klo));
         c = 2*(y(khi) - 2*y(klo) + y(klo-1) - (x(khi) - 2*x(klo) + x(klo-1))*a)/...
             (h*h + (x(klo) - x(klo-1))*(x(klo) - x(klo-1)));
         d = 2*(y(khi+1) - 2*y(khi) + y(klo) - (x(khi+1) - 2*x(khi) + x(klo))*b)/...
             ((x(khi+1) - x(khi))*(x(khi+1) - x(khi)) + h*h);
      end
   elseif (m == 1)
      c = ypp(klo);
      d = ypp(khi);
      if (klo == 1)
         a = (y(khi) - y(klo))/h;
         b = (y(khi+1) - y(klo))/(x(khi+1) - x(klo));
      elseif (khi == n)
         a = (y(khi) - y(klo-1))/(x(khi) - x(klo-1));
         b = (y(khi) - y(klo))/h;
      else
         a = (y(khi) - y(klo-1))/(x(khi) - x(klo-1));
         b = (y(khi+1) - y(klo))/(x(khi+1) - x(klo));
      end
   else
      a = yp(klo);
      b = yp(khi);
      if (klo == 1)
         c = ((y(khi+1) - y(khi))/(x(khi+1) - x(khi)) - (y(khi) - y(klo))/h)/...
             (x(khi+1) - x(klo));
         d = 2*(y(khi+1) - 2*y(khi) + y(klo) - (x(khi+1) - 2*x(khi) + x(klo))*b)/...
             ((x(khi+1) - x(khi))*(x(khi+1) - x(khi)) + h*h);
      elseif (khi == n)
         c = 2*(y(khi) - 2*y(klo) + y(klo-1) - (x(khi) - 2*x(klo) + x(klo-1))*a)/...
             (h*h + (x(klo) - x(klo-1))*(x(klo) - x(klo-1)));
         d = ((y(khi) - y(klo))/h - (y(klo) - y(klo-1))/(x(klo) - x(klo-1)))/...
             (x(khi) - x(klo-1));
      else
         c = 2*(y(khi) - 2*y(klo) + y(klo-1) - (x(khi) - 2*x(klo) + x(klo-1))*a)/...
             (h*h + (x(klo) - x(klo-1))*(x(klo) - x(klo-1)));
         d = 2*(y(khi+1) - 2*y(khi) + y(klo) - (x(khi+1) - 2*x(khi) + x(klo))*b)/...
             ((x(khi+1) - x(khi))*(x(khi+1) - x(khi)) + h*h);
      end
   end

   % Evaluate quintic Hermite polynomial
   t = (xi(i) - x(klo))/h;
   t2 = t*t;
   t3 = t2*t;
   t4 = t3*t;
   t5 = t4*t;
   h2 = h*h;
   z0 = -6*t5 + 15*t4 - 10*t3 + 1;
   z1 = -3*t5 + 8*t4 - 6*t3 + t;
   z2 = 0.5*(-t5 + 3*t4 - 3*t3 + t2);
   z3 = 1 - z0;
   z4 = -3*t5 + 7*t4 - 4*t3;
   z5 = 0.5*(t5 - 2*t4 + t3);

   yi(i) = z0*y(klo) + z1*h*a + z2*h2*c + z3*y(khi) + z4*h*b + z5*h2*d;

   % Differentiate to find the fourth-order interpolant
   z0 = -30*t4 + 60*t3 - 30*t2;
   z1 = -15*t4 + 32*t3 - 18*t2 + 1;
   z2 = 0.5*(-5*t4 + 12*t3 - 9*t2 + 2*t);
   z3 = -z0;
   z4 = -15*t4 + 28*t3 - 12*t2;
   z5 = 0.5*(5*t4 - 8*t3 + 3*t2);

   ypi(i) = z0*y(klo)/h + z1*a + z2*h*c + z3*y(khi)/h + z4*b + z5*h*d;

   % Differentiate to find the third-order interpolant
   z0 = -120*t3 + 180*t2 - 60*t;
   z1 = -60*t3 + 96*t2 - 36*t;
   z2 = 0.5*(-20*t3 + 36*t2 - 18*t + 2);
   z3 = -z0;
   z4 = -60*t3 + 84*t2 - 24*t;
   z5 = 0.5*(20*t3 - 24*t2 + 6*t);

   yppi(i) = z0*y(klo)/h2 + z1*a/h + z2*c + z3*y(khi)/h2 + z4*b/h + z5*d;
end

% 3-pt finite difference
function [yp] = lfindiff(x, y)
% Finite Difference Formulae for Unequal Sub-Intervals Using Lagrange's Interpolation Formula
% Singh, Ashok K. and B. S. Bhadauria
% Int. Journal of Math. Analysis, Vol. 3, 2009, no. 17, 815-827

n = length(x);

if (n ~= length(y))
   fprintf('Error, len(x) != len(y), returning\n');
   yp = NaN;
   return;
end

for k = 1:n
   if (k == 1)
      h1 = x(k+1) - x(k);
      h2 = x(k+2) - x(k+1);
      yp(k) = -(2*h1+h2)/(h1*(h1+h2))*y(k) + (h1+h2)/(h1*h2)*y(k+1) - h1/(h2*(h1+h2))*y(k+2);
   elseif (k == n)
      h1 = x(k-1) - x(k-2);
      h2 = x(k) - x(k-1);
      yp(k) = h2/(h1*(h1+h2))*y(k-2) - (h1+h2)/(h1*h2)*y(k-1) + (h1+2*h2)/(h2*(h1+h2))*y(k);
   else
      h1 = x(k) - x(k-1);
      h2 = x(k+1) - x(k);
      yp(k) = -h2/(h1*(h1+h2))*y(k-1) - (h1-h2)/(h1*h2)*y(k) + h1/(h2*(h1+h2))*y(k+1);
   end
end