function r8mat_exp_story ( test )

%*****************************************************************************80
%
%% R8MAT_EXP_STORY prints explanatory text for each problem.
%
%  Discussion:
%
%     1) Diagonal example
%     2) Symmetric example
%     3) Laub
%     4) Moler and Van Loan
%     5) Moler and Van Loan
%     6) Moler and Van Loan
%     7) Moler and Van Loan
%     8) Wikipedia example
%     9) NAG F01ECF
%    10) Ward #1
%    11) Ward #2
%    12) Ward #3
%    13) Ward #4
%    14) Moler example
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 October 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Alan Laub,
%    Review of "Linear System Theory" by Joao Hespanha,
%    SIAM Review,
%    Volume 52, Number 4, December 2010, page 779-781.
%
%    Cleve Moler, Charles VanLoan,
%    Nineteen Dubious Ways to Compute the Exponential of a Matrix,
%    Twenty-Five Years Later,
%    SIAM Review,
%    Volume 45, Number 1, March 2003, pages 3-49.
%
%    Cleve Moler,
%    Cleve's Corner: A Balancing Act for the Matrix Exponential,
%    July 23rd, 2012.
%
%    Robert Ward,
%    Numerical computation of the matrix exponential with accuracy estimate,
%    SIAM Journal on Numerical Analysis,
%    Volume 14, Number 4, September 1977, pages 600-610.
%
%  Parameters:
%
%    Input, integer TEST, the index of the test case.
%
  if ( test == 1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  This matrix is diagonal.\n' );
    fprintf ( 1, '  The calculation of the matrix exponential is simple.\n' );
  elseif ( test == 2 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  This matrix is symmetric.\n' );
    fprintf ( 1, '  The calculation of the matrix exponential is straightforward.\n' );
  elseif ( test == 3 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  This example is due to Laub.\n' );
    fprintf ( 1, '  This matrix is ill-suited for the Taylor series approach.\n' );
    fprintf ( 1, '  As powers of A are computed, the entries blow up too quickly.\n' );
  elseif ( test == 4 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  This example is due to Moler and Van Loan.\n' );
    fprintf ( 1, '  The example will cause problems for the series summation approach,\n' );
    fprintf ( 1, '  as well as for diagonal Pade approximations.\n' );
  elseif ( test == 5 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  This example is due to Moler and Van Loan.\n' );
    fprintf ( 1, '  This matrix is strictly upper triangular\n' );
    fprintf ( 1, '  All powers of A are zero beyond some (low) limit.\n' );
    fprintf ( 1, '  This example will cause problems for Pade approximations.\n' );
  elseif ( test == 6 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  This example is due to Moler and Van Loan.\n' );
    fprintf ( 1, '  This matrix does not have a complete set of eigenvectors.\n' );
    fprintf ( 1, '  That means the eigenvector approach will fail.\n' );
  elseif ( test == 7 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  This example is due to Moler and Van Loan.\n' );
    fprintf ( 1, '  This matrix is very close to example 5.\n' );
    fprintf ( 1, '  Mathematically, it has a complete set of eigenvectors.\n' );
    fprintf ( 1, '  Numerically, however, the calculation will be suspect.\n' );
  elseif ( test == 8 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  This matrix was an example in Wikipedia.\n' );
  elseif ( test == 9 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  This example is due to the NAG Library.\n' );
    fprintf ( 1, '  It is an example for function F01ECF.\n' );
  elseif ( test == 10 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  This is Ward''s example #1.\n' );
    fprintf ( 1, '  It is defective and nonderogatory.\n' );
    fprintf ( 1, '  The eigenvalues are 3, 3 and 6.\n' );
  elseif ( test == 11 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  This is Ward''s example #2.\n' );
    fprintf ( 1, '  It is a symmetric matrix.\n' );
    fprintf ( 1, '  The eigenvalues are 20, 30, 40.\n' );
  elseif ( test == 12 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  This is Ward''s example #3.\n' );
    fprintf ( 1, '  Ward''s algorithm has difficulty estimating the accuracy\n' );
    fprintf ( 1, '  of its results.  The eigenvalues are -1, -2, -20.\n' );
  elseif ( test == 13 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  This is Ward''s example #4.\n' );
    fprintf ( 1, '  This is a version of the Forsythe matrix.\n' );
    fprintf ( 1, '  The eigenvector problem is badly conditioned.\n' );
    fprintf ( 1, '  Ward''s algorithm has difficulty estimating the accuracy\n' );
    fprintf ( 1, '  of its results for this problem.\n' );
  elseif ( test == 14 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  This is Moler''s example.\n' );
    fprintf ( 1, '  This badly scaled matrix caused problems for MATLAB''s expm().\n' );
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, 'R8MAT_EXP_STORY - Fatal error!\n' );
    fprintf ( 1, '  Illegal value of TEST = %d\n', test );
    error ( 'R8MAT_EXP_STORY - Fatal error!' );
  end

  return
end


function [params, names] = simwhiteKernExtractParam(kern)

% SIMWHITEKERNEXTRACTPARAM Extract parameters from the SIM-WHITE kernel
% structure.
% FORMAT
% DESC extracts parameters from the SIM-White (Single Input Motif - White)
% kernel structure into a vector of parameters for optimisation.
% ARG kern : the kernel structure containing the parameters to be
% extracted.
% RETURN param : vector of parameters extracted from the kernel. If
% the field 'transforms' is not empty in the kernel structure, the
% parameters will be transformed before optimisation (for example
% positive only parameters could be logged before being returned).
%
% FORMAT
% DESC extracts parameters and parameter names from the SIM-White (Single
% Input Motif - White) kernel structure.
% ARG kern : the kernel structure containing the parameters to be
% extracted.
% RETURN param : vector of parameters extracted from the kernel. If the
% field 'transforms' is not empty in the kernel structure, the parameters
% will be transformed before optimisation (for example positive only
% parameters could be logged before being returned).
% RETURN names : cell array of strings containing names for each
% parameter.
%
% SEEALSO simwhiteKernParamInit, simwhiteKernExpandParam, kernExtractParam,
% scg, conjgrad
%
% COPYRIGHT : David Luengo, 2009
%
% KERN

params = [kern.decay kern.variance kern.sensitivity];
if nargout > 1
  names = {'decay', 'variance', 'sensitivity'};
end


% Here the training data is adapted from UCI ML repository, 'zoo' data

dtreeCPD=tree_CPD;

% load data
fname = fullfile(BNT_HOME, 'examples', 'static', 'uci_data', 'zoo', 'zoo1.data')
data=load(fname);
data=data';

data=transform_data_into_bnt_format(data, []);

% learn decision tree from data
ns=2*ones(1,17);
ns(13)=6;
ns(17)=7;
dtreeCPD1=learn_params(dtreeCPD,1:17,data,ns,[],'stop_cases',5); % a node with less than 5 cases will not be splitted

% evaluate on data
[score,outputs]=evaluate_tree_performance(dtreeCPD1,1:17,data,ns,[]);
fprintf('Accuracy in old training data %6.3f\n',score);


% dbm_get_hidden
% Copyright (C) 2011 KyungHyun Cho, Tapani Raiko, Alexander Ilin
%
%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, write to the Free Software
%Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
%
function [h_mf] = dbm_get_hidden(x0, D, max_iter, tol, reg)

if nargin < 3
    max_iter = 10;
end

if nargin < 4
    tol = 1e-6;
end

if nargin < 5
    reg = 0;
end

h_mf = dbm_get_hidden_raw(x0, D.data.binary, D.structure.layers, ...
    D.W, D.biases, D.sigmas, max_iter, tol, reg, D.centering.use, D.centering.centers);


function T = qq(q,varargin)
% returns w * q' * q
%
% Input
%  q - list of quaternions
%  w - list of weights

notNaN = ~isnan(q.a);
ql = [q.a(:), q.b(:), q.c(:), q.d(:)];
ql = ql(notNaN,:);

% weigths
w = get_option(varargin,'weights');

if ~isempty(w)
  w = w(notNaN);
  w = w./sum(w);
  w = repmat(w(:).',4,1);
  T = (w .* ql.') * ql;
else
  T = ql.'*ql;
  T = T ./ size(ql,1);
end


function obj = Infill_Maximal_Distance(x, sample_x)
obj = - min(pdist2(x, sample_x),[],2);
end


% Generate some shark data
animGT=generateToyAnimation( 4.2,'noise', 0.0, 'fixT', true );
dimSSpace = 2;
anim = computeNRSFM( 2, animGT.W);
[ err ] = computeNRSFMError( animGT, anim );
fprintf( 'Error with Xiao-Kanade: %e \n', sum(sum(err(1:2,:))) );
fprintf( 'Reprojection error: %e \n', computeSFMError( 'reproj', 0, 'anim', anim ) );

% Force some constraints
anim.SBasis(:,:,1)=-anim.SBasis(:,:,1);

anim.l(1,:)=1; anim.t(:)=0;
anim=anim.setFirstPRtToId();
anim = bundleAdjustment( anim, 'nItr', 100 );
anim=anim.setFirstPRtToId();

[ err ] = computeNRSFMError( animGT, anim );
fprintf( 'Error with Xiao-Kanade: %e \n', sum(sum(err(1:2,:))) );
fprintf( 'Reprojection error: %e \n', computeSFMError( 'reproj', 0, 'anim', anim ) );

% Set back to the original camera
for t=1:anim.nFrame
  anim.R(:,:,t)=animGT.R(:,:,t)'*anim.R(:,:,t);
end

animGT=generateToyAnimation( 4,'noise', 0.0, 'fixT', true );

anim.W=animGT.W;

[ err ] = computeNRSFMError( animGT, anim );
fprintf( 'Error with Xiao-Kanade: %e \n', sum(sum(err(1:2,:))) );
fprintf( 'Reprojection error: %e \n', computeSFMError( 'reproj', 0, 'anim', anim ) );

% Normalize the whole thingy
%  anim.SBasis(:,:,i)/mean(anim.l(1,:)); anim.l(1,:)=1;
for i=2:3
  anim.l(i,:)=norm(anim.SBasis(:,:,i),'fro')*anim.l(i,:);
  anim.SBasis(:,:,i)=anim.SBasis(:,:,i)/norm(anim.SBasis(:,:,i),'fro');
  anim.SBasis(:,:,1)=anim.SBasis(:,:,1)+mean(anim.l(i,:))*...
    anim.SBasis(:,:,i);
  anim.l(i,:)=anim.l(i,:)-mean(anim.l(i,:));
end

save('jawSource.mat','anim');


function [minconpos, mincon]=API(fun1,LB,UB,NumAnts,Nmoves,LocalMoves,nonlinfun,rpmax,RES,varargin)
%
% APA, 2003

warning off
%  API Finds a unconstrained or constrained minimum of a function of several variables.
%     API solves problems of the form:
%         min F(X)  subject to:  g(x) <= 0,  h(x) = Beq (inequality & equality constraints)
%          X                     LB <= X <= UB (boundary constraints)
%
%     X=API(FUN,LB,UB,NumAnts,Nmoves,LocalMoves,NONLNCON,rpmax) minimizes FUN
%     subject to inequality and equality constraints in NONLINCON. (Set NONLINCON=[]
%     and rpmax=[] if no inequality and equality constraints exist).
%     NumAnts = Number of API Ants to be used.
%     Nmoves = Number of Nest Moves.
%     LocalMoves = Number of Local Moves for API Ants.
%     rpmax = Augmented Lagrangian parameter.
%
%     X=API(FUN,LB,UB,NumAnts,Nmoves,LocalMoves,NONLNCON,rpmax,P1,P2,...) passes the
%     problem-dependent parameters P1,P2,... directly to the functions FUN
%     and NONLCON: feval(FUN,X,P1,P2,...) and feval(NONLCON,X,P1,P2,...).
%
% Example:
% FUN='testbanana';LB=[-5 -5];UB=[3 3];NumAnts=20;Nmoves=15;LocalMoves=25;
% NONLNCON='nonlinbanana';rpmax=5;
% X=API(FUN,LB,UB,NumAnts,Nmoves,LocalMoves,NONLNCON,rpmax)
%
% Listing of Objective and Constraint for the above exxample
%
% function f=testbanana(x)
% f=100*(x(1)^2-x(2))^2 + (1-x(1))^2;
%
% function [g,h]=nonlinbanana(x)
% x1=x(1); x2=x(2);
% %%% Equality Constraints %%%%%%%%
% h=0;
% %%% Inequality Constraints %%%%%%
% g(1,:)=-(x1.^2+x2.^2-1.2);
% g(2,:)=-(1.5-(x1-.2)^2-x2.^2);

if isempty(nonlinfun)

    xb=[LB(:) UB(:)];

    % Specify the starting point
    Ninit = (LB+UB)/2;

    n=length(Ninit);

    %%% **************--- Unconstrained Loop ---****************

    N=Ninit;% Initial Nest Location
    min1=inf;
    disp('Nest Move    Objective')
    for ii=1:Nmoves   % Number of Nest Moves

        Smem=[];
        for num=1:NumAnts
            if(num==1)
                Asite=0.01;
            else
                Asite=0.01*(1/0.01)^(num/NumAnts);
            end
            for i=1:2
                for j=1:n
                    r=rand;
                    S(j)=N(j)+((-0.5+r)*Asite*(xb(j,2)-xb(j,1)));
                    while(~((xb(j,1)<=S(j))&(xb(j,2)>=S(j))))
                        r=rand;
                        S(j)=N(j)+((-0.5+r)*Asite*(xb(j,2)-xb(j,1)));
                    end
                end
                Smem=[Smem;S];
            end
        end
        % Fun1='fun';
        %%%%%%%%%%%% Tandem Running %%%%%%%%%%%%%%%
        a1=1+floor(NumAnts*rand);
        a2=1+floor(NumAnts*rand);
        f1=feval(fun1,Smem(2*a1-1,:),varargin{:});
        f2=feval(fun1,Smem(2*a1,:),varargin{:});
        f3=feval(fun1,Smem(2*a2-1,:),varargin{:});
        f4=feval(fun1,Smem(2*a2,:),varargin{:});

        if(f1<f2)
            fpos1=2*a1-1;
            fmin1=f1;
        else
            fpos1=2*a1;
            fmin1=f2;
        end
        if(f3<f4)
            fpos2=2*a2-1;
            fmin2=f3;
        else
            fpos2=2*a2;
            fmin2=f4;
        end
        if(fmin1<fmin2)
            Smem(fpos2,:)=Smem(fpos1,:);
        else
            Smem(fpos1,:)=Smem(fpos2,:);
        end
        %%%%%%%%%%%%%%tandem running loop ends%%%%%%%%%%%%%%%%%%

        for num=1:2:(2*NumAnts-1)

            if(num==1)
                Alocal=0.1*0.01;
            else
                Alocal=(1/10)*0.01*(1/0.01)^(((num+1)/2)/NumAnts);
            end
            pos1=num;
            pos2=num+1;

            for i=1:LocalMoves   % Number of Local Sites % Local Search Loop Starts here

                Spos=Smem(num,:);
                for j=1:n
                    r=rand;
                    Sloc(j)=Spos(j)+(-0.5+r)*Alocal*(xb(j,2)-xb(j,1));
                    while(~((xb(j,1)<=Sloc(j))&(xb(j,2)>=Sloc(j))))
                        r=rand;
                        Sloc(j)=Spos(j)+(-0.5+r)*Alocal*(xb(j,2)-xb(j,1));
                    end
                end

                V1=feval(fun1,Spos,varargin{:});
                V2=feval(fun1,Sloc,varargin{:});
                if(V1>V2)
                    Smem(pos1,:)=Sloc;
                    if(min1>V2)
                        minpos=Sloc;
                        min1=V2;
                    end
                else
                    temppos=Smem(pos1,:);
                    Smem(pos1,:)=Smem(pos2,:);
                    Smem(pos2,:)=temppos;
                    if(min1>V1)
                        minpos=Spos;
                        min1=V1;
                    end
                end

            end

        end
        %! Put-in the residue
        if min1<RES
            return
        end
        N=minpos;
        % disp('[Nest Move    Objective]')
        disp(['    ',num2str(ii),'        ',num2str(min1)])

    end

    %%%***********--- Unconstrained Loop Ends ---***************
    minconpos=minpos;
    mincon=min1;

else

    %API1Gen.m
    ftemp=fun1;nonlinfuntemp=nonlinfun;
    global rp mu1 si1 fun1 nonlinfun
    fun1=ftemp;nonlinfun=nonlinfuntemp;
    xb=[LB(:) UB(:)];

    % Specify the starting point
    Ninit = (LB+UB)/2;

    n=length(Ninit);
    rp=1;
    [g1, h1]=feval('nonlinAPI',Ninit,varargin{:});
    mu1=zeros(length(g1),1);
    si1=zeros(length(h1),1);

    mincon=inf;
    NITER=0;
    while(rp<rpmax)

        NITER=NITER+1;

        %%% **************--- Unconstrained Loop ---****************

        N=Ninit;% Initial Nest Location
        min1=inf;

        for ii=1:Nmoves   % Number of Nest Moves

            Smem=[];
            for num=1:NumAnts
                if(num==1)
                    Asite=0.01;
                else
                    Asite=0.01*(1/0.01)^(num/NumAnts);
                end
                for i=1:2
                    for j=1:n
                        r=rand;
                        S(j)=N(j)+((-0.5+r)*Asite*(xb(j,2)-xb(j,1)));
                        while(~((xb(j,1)<=S(j))&(xb(j,2)>=S(j))))
                            r=rand;
                            S(j)=N(j)+((-0.5+r)*Asite*(xb(j,2)-xb(j,1)));
                        end
                    end
                    Smem=[Smem;S];
                end
            end
            %%%%%%%%%%%% Tandem Running %%%%%%%%%%%%%%%
            a1=1+floor(NumAnts*rand);
            a2=1+floor(NumAnts*rand);
            f1=feval(@funAPI,Smem(2*a1-1,:),varargin{:});
            f2=feval(@funAPI,Smem(2*a1,:),varargin{:});
            f3=feval(@funAPI,Smem(2*a2-1,:),varargin{:});
            f4=feval(@funAPI,Smem(2*a2,:),varargin{:});

            if(f1<f2)
                fpos1=2*a1-1;
                fmin1=f1;
            else
                fpos1=2*a1;
                fmin1=f2;
            end
            if(f3<f4)
                fpos2=2*a2-1;
                fmin2=f3;
            else
                fpos2=2*a2;
                fmin2=f4;
            end
            if(fmin1<fmin2)
                Smem(fpos2,:)=Smem(fpos1,:);
            else
                Smem(fpos1,:)=Smem(fpos2,:);
            end
            %%%%%%%%%%%%%%tandem running loop ends%%%%%%%%%%%%%%%%%%

            for num=1:2:(2*NumAnts-1)

                if(num==1)
                    Alocal=0.1*0.01;
                else
                    Alocal=(1/10)*0.01*(1/0.01)^(((num+1)/2)/NumAnts);
                end
                pos1=num;
                pos2=num+1;

                for i=1:LocalMoves   % Number of Local Sites % Local Search Loop Starts here

                    Spos=Smem(num,:);
                    for j=1:n
                        r=rand;
                        Sloc(j)=Spos(j)+(-0.5+r)*Alocal*(xb(j,2)-xb(j,1));
                        while(~((xb(j,1)<=Sloc(j))&(xb(j,2)>=Sloc(j))))
                            r=rand;
                            Sloc(j)=Spos(j)+(-0.5+r)*Alocal*(xb(j,2)-xb(j,1));
                        end
                    end

                    V1=feval(@funAPI,Spos,varargin{:});
                    V2=feval(@funAPI,Sloc,varargin{:});
                    if(V1>V2)
                        Smem(pos1,:)=Sloc;
                        if(min1>V2)
                            minpos=Sloc;
                            min1=V2;
                        end
                    else
                        temppos=Smem(pos1,:);
                        Smem(pos1,:)=Smem(pos2,:);
                        Smem(pos2,:)=temppos;
                        if(min1>V1)
                            minpos=Spos;
                            min1=V1;
                        end
                    end

                end

            end

            N=minpos;

        end

        %%%***********--- Unconstrained Loop Ends ---***************

        %%% --- Augmented Lagrangian Method ---
        if(rp>1)
            mincon=feval(@funAPI,minconpos,varargin{:});
        end
        if(min1<mincon)
            minconpos=minpos;
            mincon=min1;
        end

        [temp1, temp2]=feval(nonlinfun, minconpos,varargin{:});
        mu1 = mu1 + rp.*temp1(:);
        si1 = si1 + rp.*temp2(:);
        %%% ------ End of Augmented Lagrangian -----

        rp=rp*1.15;
        if NITER==1
            disp('Iteration     Objective    Maximum Constraint')
            disp(['     ',num2str(NITER),'         ',num2str(mincon),'         ',num2str(max(temp1))])
        else
            disp(['     ',num2str(NITER),'         ',num2str(mincon),'         ',num2str(max(temp1))])
        end

    end %%% End of Constrained Loop (i.e. rp)

    %%%% function API1gen(fun1,nonlinAPI) ends

end

function Faug=funAPI(x,varargin)

global mu1 si1 rp nonlinfun fun1
if ~isempty(varargin)
    f=feval(fun1,x,varargin{:});
else
    f=feval(fun1,x);
end
if ~isempty(varargin)
    [zeta1, h1]=feval(nonlinfun,x,varargin{:});
else
    [zeta1, h1]=feval(nonlinfun,x);
end
Fp = f + rp/2*(sum(zeta1.^2) + sum(h1.^2));
Faug = Fp + sum(mu1.*zeta1) + sum(si1.*h1);

%%%%% fun1(x) ends %%%%

function [zeta1, h1]=nonlinAPI(x,varargin)
global mu1 si1 rp h1 nonlinfun

if ~isempty(varargin)
    [g1, h1]=feval(nonlinfun,x,varargin{:});
else
    [g1, h1]=feval(nonlinfun,x);
end
if(rp==1)
    zeta1=g1;
else
    zeta1=max(g1,-mu1/rp);
end

%%%%% function nonlinAPI(x) ends


filename='Bridge_triangle_fine';
 ptype = 'MACRO';
method = 'SIMPALL';
materialType = 'ISOTROPIC';
initial_case = 'full';
cost = {'compliance';'perimeter'};
weights = [1, 0.1];
constraint = {'volumeConstraint'};
optimizer = 'PROJECTED GRADIENT'; incrementFactor = 1;
filterType = 'P1';

nsteps = 5;
Vfrac_final = 0.2;
Perimeter_target = 1;
optimality_final = 1e-3;
constr_final =1e-3;

Vfrac_initial = 1;
optimality_initial = 1e-2;
constr_initial = 1e-3;
TOL.rho_plus = 1;
TOL.rho_minus = 0;
TOL.E_plus = 1;
TOL.E_minus = 1e-3;
TOL.nu_plus = 1/3;
TOL.nu_minus = 1/3;


function out=spm_api_bmc(F,N,exp_r,xp,family)
% API to select and compare DCMs using Bayesian model comparison
% FORMAT out=spm_api_bmc(F,N,alpha,exp_r,xp)
%
% INPUT:
% F      - Matrix/Vector of log model evidences
% N      - vector of model names
% alpha  - vector of model probabilities
% exp_r  - expectation of the posterior p(r|y)
% xp     - exceedance probabilities
%
% OUTPUT:
% out    - conditional probability of DCMs (when using fixed effect method)
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_api_bmc.m 4832 2012-08-08 14:28:00Z will $

if nargin < 4 || isempty(xp)
    inf_method = 'FFX';
else
    inf_method = 'RFX';
end

if nargin>4
    plot_family = 1;
else
    plot_family = 0;
end

nm = length(N);

Fgraph  = spm_figure('GetWin','Graphics');
spm_clf(Fgraph);

switch inf_method

    %======================================================================
    % Fixed Effect
    %======================================================================
    case ('FFX')

        figure(Fgraph);

        %-Compute conditional probability of DCMs under flat priors.
        %------------------------------------------------------------------
        F    = F - min(F);
        i    = F < (max(F) - 32);
        P    = F;
        P(i) = max(F) - 32;
        P    = P - min(P);
        P    = exp(P);
        P    = P/sum(P);

        %-Display results
        %------------------------------------------------------------------
        subplot(2,1,1)
        bar(1:nm,F)
        set(gca,'XTick',1:nm)
        set(gca,'XTickLabel',1:nm)
        ylabel('Log-evidence (relative)','Fontsize',14)
        xlabel('Models','Fontsize',14)
        title(['Bayesian Model Selection: ',inf_method],'Fontsize',14)
        axis square
        grid on

        subplot(2,1,2)
        bar(1:nm,P)
        set(gca,'XTick',1:nm)
        set(gca,'XTickLabel',1:nm)
        ylabel('Model Posterior Probability','Fontsize',14)
        title(['Bayesian Model Selection: ',inf_method],'Fontsize',14)
        xlabel('Models','Fontsize',14)
        axis square
        grid on

        out = P;

        if plot_family

            %-Display results - families
            %--------------------------------------------------------------
            F  = spm_figure('Create','Graphics','BMS: results');
            figure(F);

            Nfam = length(family.post);
            bar(1:Nfam,family.post)
            set(gca,'XTick',1:Nfam)
            set(gca,'XTickLabel',family.names)
            ylabel('Family Posterior Probability','Fontsize',14)
            xlabel('Families','Fontsize',14)
            title(['Bayesian Model Selection: ',inf_method],'Fontsize',14)
            axis square
            grid on

            out = [];

        end

    %======================================================================
    % Random Effect
    %======================================================================
    case ('RFX')

        figure(Fgraph);

        %-Display results
        %------------------------------------------------------------------
        subplot(2,1,1)
        bar(1:length(N),exp_r)
        set(gca,'XTick',1:length(N))
        set(gca,'XTickLabel',1:nm)
        ylabel('Model Expected Probability','Fontsize',14)
        xlabel('Models','Fontsize',14)
        title(['Bayesian Model Selection: ',inf_method],'Fontsize',14)
        axis square
        grid on

        subplot(2,1,2)
        bar(1:length(N),xp')
        set(gca,'XTick',1:length(N))
        set(gca,'XTickLabel',1:nm)
        ylabel('Model Exceedance Probability','Fontsize',14)
        xlabel('Models','Fontsize',14)
        title(['Bayesian Model Selection: ',inf_method],'Fontsize',14)
        axis square
        grid on

        out = [];

        if plot_family

            %-Display results - families
            %--------------------------------------------------------------
            F  = spm_figure('Create','Graphics','BMS: results');
            figure(F);

            %-Display results - families
            %--------------------------------------------------------------
            subplot(2,1,1)
            Nfam = length(family.exp_r);
            bar(1:Nfam,family.exp_r)
            set(gca,'XTick',1:Nfam)
            set(gca,'XTickLabel',family.names)
            ylabel('Family Expected Probability','Fontsize',14)
            xlabel('Families','Fontsize',14)
            title(['Bayesian Model Selection: ',inf_method],'Fontsize',14)
            axis square
            grid on

            subplot(2,1,2)
            bar(1:Nfam,family.xp')
            set(gca,'XTick',1:Nfam)
            set(gca,'XTickLabel',family.names)
            ylabel('Family Exceedance Probability','Fontsize',14)
            xlabel('Families','Fontsize',14)
            title(['Bayesian Model Selection: ',inf_method],'Fontsize',14)
            axis square
            grid on

            out = [];

        end
end


% This script depends on
% - ex_run_rpca.m
% Please execute the dependencies before
% running this script.

close all; clear all; clc;
fprintf('Loading RPCA images.\n');
load bin/yale_rpca_cache.mat;
fprintf('Loaded RPCA images.\n');
full_width = 168;
full_height = 192;
full_image_size = full_width * full_height;
num_subjects = 38;
images_per_subject  = 50;
orig_images = rpca_images;
[s, n]  = size(orig_images);
width = 42;
height = 48;
sz = width * height;
Y = zeros(sz, n);
for i=1:n
    fprintf('Resizing: %d\n',  i);
    image = reshape(orig_images(:, i), full_height, full_width);
    resized_image = imresize(image, [height, width]);
    Y(:, i) = reshape(resized_image, sz, 1);
end
fprintf('Saving resized RPCA images.\n');
save('bin/yale_rpca_downsampled_images', 'Y');
fprintf('Saved resized RPCA images.\n');


function FrontNo = UpdateFront(PopObj,FrontNo,x)
% Update the front number of each solution when a solution is added or
% deleted

%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

    [N,M] = size(PopObj);
    if nargin < 3
        %% Add a new solution (has been stored in the last of PopObj)
        FrontNo  = [FrontNo,0];
        Move     = false(1,N);
        Move(N)  = true;
        CurrentF = 1;
        % Locate the front No. of the new solution
        while true
            Dominated = false;
            for i = 1 : N-1
                if FrontNo(i) == CurrentF
                    m = 1;
                    while m <= M && PopObj(i,m) <= PopObj(end,m)
                        m = m + 1;
                    end
                    Dominated = m > M;
                    if Dominated
                        break;
                    end
                end
            end
            if ~Dominated
                break;
            else
                CurrentF = CurrentF + 1;
            end
        end
        % Move down the dominated solutions front by front
        while any(Move)
            NextMove = false(1,N);
            for i = 1 : N
                if FrontNo(i) == CurrentF
                    Dominated = false;
                    for j = 1 : N
                        if Move(j)
                            m = 1;
                            while m <= M && PopObj(j,m) <= PopObj(i,m)
                                m = m + 1;
                            end
                            Dominated = m > M;
                            if Dominated
                                break;
                            end
                        end
                    end
                    NextMove(i) = Dominated;
                end
            end
            FrontNo(Move) = CurrentF;
            CurrentF      = CurrentF + 1;
            Move          = NextMove;
        end
    else
        %% Delete the x-th solution
        Move     = false(1,N);
        Move(x)  = true;
        CurrentF = FrontNo(x) + 1;
        while any(Move)
            NextMove = false(1,N);
            for i = 1 : N
                if FrontNo(i) == CurrentF
                    Dominated = false;
                    for j = 1 : N
                        if Move(j)
                            m = 1;
                            while m <= M && PopObj(j,m) <= PopObj(i,m)
                                m = m + 1;
                            end
                            Dominated = m > M;
                            if Dominated
                                break;
                            end
                        end
                    end
                    NextMove(i) = Dominated;
                end
            end
            for i = 1 : N
                if NextMove(i)
                    Dominated = false;
                    for j = 1 : N
                        if FrontNo(j) == CurrentF-1 && ~Move(j)
                            m = 1;
                            while m <= M && PopObj(j,m) <= PopObj(i,m)
                                m = m + 1;
                            end
                            Dominated = m > M;
                            if Dominated
                                break;
                            end
                        end
                    end
                    NextMove(i) = ~Dominated;
                end
            end
            FrontNo(Move) = CurrentF - 2;
            CurrentF      = CurrentF + 1;
            Move          = NextMove;
        end
        FrontNo(x) = [];
    end
end


% Loading External Image Maps Example
%
% This example demonstrates how to assign an external image to the initial
% pressure distribution for the simulation of an initial value problem
% within a two-dimensional homogeneous propagation medium. It builds on the
% Homogeneous Propagation Medium Example.
%
% author: Bradley Treeby
% date: 30th June 2009
% last update: 19th July 2011
%
% This function is part of the k-Wave Toolbox (http://www.k-wave.org)
% Copyright (C) 2009-2014 Bradley Treeby and Ben Cox

% This file is part of k-Wave. k-Wave is free software: you can
% redistribute it and/or modify it under the terms of the GNU Lesser
% General Public License as published by the Free Software Foundation,
% either version 3 of the License, or (at your option) any later version.
%
% k-Wave is distributed in the hope that it will be useful, but WITHOUT ANY
% WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
% FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
% more details.
%
% You should have received a copy of the GNU Lesser General Public License
% along with k-Wave. If not, see <http://www.gnu.org/licenses/>.

clear all;

% =========================================================================
% SIMULATION
% =========================================================================

% load the initial pressure distribution from an image and scale the
% magnitude
p0_magnitude = 3;
p0 = p0_magnitude*loadImage('EXAMPLE_source_one.png');

% create the computational grid
Nx = 128;           % number of grid points in the x (row) direction
Ny = 128;           % number of grid points in the y (column) direction
dx = 0.1e-3;        % grid point spacing in the x direction  [m]
dy = 0.1e-3;        % grid point spacing in the y direction  [m]
kgrid = makeGrid(Nx, dx, Ny, dy);

% resize the image to match the size of the computational grid and assign
% to the source input structure
source.p0 = resize(p0, [Nx, Ny]);

% define the properties of the propagation medium
medium.sound_speed = 1500;  % [m/s]
medium.alpha_coeff = 0.75;  % [dB/(MHz^y cm)]
medium.alpha_power = 1.5;

% define a centered circular sensor
sensor_radius = 4e-3;   % [m]
num_sensor_points = 50;
sensor.mask = makeCartCircle(sensor_radius, num_sensor_points);

% run the simulation
sensor_data = kspaceFirstOrder2D(kgrid, medium, source, sensor);

% =========================================================================
% VISUALISATION
% =========================================================================

% plot the initial pressure and sensor distribution
figure;
imagesc(kgrid.y_vec*1e3, kgrid.x_vec*1e3, source.p0 + cart2grid(kgrid, sensor.mask), [-1 1]);
colormap(getColorMap);
ylabel('x-position [mm]');
xlabel('y-position [mm]');
axis image;

% plot the simulated sensor data
figure;
imagesc(sensor_data, [-1, 1]);
colormap(getColorMap);
ylabel('Sensor Position');
xlabel('Time Step');
colorbar;


classdef Grid1d < handle
    % Grid has all the information related to the staggered grid in a single
    % Cartesian axis.  It does not have physical quantities dependent on
    % frequencies, e.g., omega, eps, mu, and PML s-factors.

    properties (SetAccess = immutable)
		axis  % axis of this grid; one of Axis.x, Axis.y, Axis.z
		unit  % instance of PhysUnit
		unitvalue  %  unit value of length
        l  % {locations for primary vertices, locations for dual vertices}
        dl  % {dl at primary vertex, dl at dual vertex} == { diff( l{GT.dual} ), diff( l{GT.prim} ) }
        bc  % instance of BC
        N  % number of grid cells
		L  % length of the grid (domain)
        Npml  % [Npml at (-) end, Npml at (+) end]
		lpml  % [location of PML interface at (-) end, location of PML interface at (+) end]
		Lpml  % [thickness of PML interface at (-) end, thickness of PML interface at (+) end]
		center  % center of grid without PML
	end

	properties (Access = private)
		lghost  % [location of ghost primary vertex (after the last one), location of ghost dual vertex (before the first one)]
		ldual_ext  % location of dual vertex after the last one
	end

	properties (Dependent, SetAccess = immutable)
		lg  % {l_prim with ghost, l_dual with ghost}: l with ghost vertex (beyond boundary)
		lall  % {l_prim with ghost, l_dual with extra vertices}: l with vertices to interpolate fields at corners of simulation domain
		bound  % [lall_prim(1), lall_prim(end)]
	end

	properties (SetAccess = private)
		kBloch
	end

    methods
        function this = Grid1d(axis, unit, lprim_array, Npml_array, bc)
			chkarg(istypesizeof(axis, 'Axis'), '"axis" should be instance of Axis.');
			this.axis = axis;

			chkarg(istypesizeof(unit, 'PhysUnit'), '"unit" should be instance of PhysUnit.');
			this.unit = unit;
			this.unitvalue = unit.value(PhysQ.L);

			chkarg(istypesizeof(Npml_array, 'int', [1, Sign.count]), ...
				'"Npml" should be length-%d row vector with integer elements.', Sign.count);
			this.Npml = Npml_array;

			chkarg(istypesizeof(bc, 'BC'), '"bc" should be instance of BC.');
			this.bc = bc;

			chkarg(istypesizeof(lprim_array, 'real', [1 0]), ...
				'"lprim_array" should be row vector with real elements.');

			% Set N and L.
			lprim = lprim_array;
			this.N = length(lprim)-1;  % # of grid cells in the axis
			this.L = lprim(end) - lprim(1);

			% Set loc and dl.
			ldual = NaN(1, this.N+1);
			ldual(2:(this.N+1)) = (lprim(1:end-1) + lprim(2:end)) / 2;

			if this.bc == BC.p
				ldual(1) = ldual(end) - (lprim(end)-lprim(1));  % lprim(end) - lprim(1) == ldual(end) - ldual(1)
				this.ldual_ext = ldual(2) + (lprim(end)-lprim(1));  % lprim(end) - lprim(1) = ldual_ext - ldual(2)
			else
				ldual(1) = lprim(1) - (ldual(2)-lprim(1));  % lprim(1) - ldual(1) == ldual(2) - lprim(1)
				this.ldual_ext = lprim(end) + (lprim(end) - ldual(end));  % ldual_ext - lprim(end) = lprim(end) - ldual(end)
			end

			this.l = {lprim(1:end-1), ldual(2:end)};
			this.lghost = [lprim(end), ldual(1)];
			this.dl = {diff(ldual), diff(lprim)};  % not {diff(lprim), diff(ldual)}

			% Set lpml, Lpml, and center.
			this.lpml = [lprim(1 + this.Npml(Sign.n)), lprim(end - this.Npml(Sign.p))];
			this.Lpml = [this.lpml(Sign.n) - lprim(1), lprim(end) - this.lpml(Sign.p)];
			this.center = mean(this.lpml);

			% Initialize kBloch
			this.kBloch = 0;
		end

		function lg = get.lg(this)
			lg = {[this.l{GT.prim}, this.lghost(GT.prim)], [this.lghost(GT.dual), this.l{GT.dual}]};
		end

		function lall = get.lall(this)
			lall = {this.lg{GT.prim}, [this.lg{GT.dual}, this.ldual_ext]};
		end

		function bound = get.bound(this)
			bound = this.lall{GT.prim}([1 end]);
		end

		function set_kBloch(this, blochSrc)
			chkarg(istypesizeof(blochSrc, 'WithBloch'), '"blochSrc" should be instance of WithBloch.');
			this.kBloch = blochSrc.kBloch(this.axis);
		end

		function truth = contains(this, l)
			% This function can handle "l" as an array.
			chkarg(istypeof(l, 'real'), '"l" should be array with real elements.');
			truth = (l >= this.lall{GT.prim}(1)) & (l <= this.lall{GT.prim}(end));  % &: elementwise AND operator
		end

		function bound_plot = bound_plot(this, withpml)
			if withpml
				bound_plot = this.bound;
			else
				bound_plot = this.lpml;
			end
		end

		function lplot = lplot(this, g, withinterp, withpml)
			% Return the locations where data are evaluated for plotting.  If
			% the data do not include the boundaries of the simulation domain (or
			% the PML interfaces for "withpml == false"), the boundary points
			% are added to ensure that the plot is drawn from boundary to
			% boundary.
			chkarg(istypesizeof(g, 'GT') , '"g" should be instance of GT');
			chkarg(istypesizeof(withinterp, 'logical'), '"withinterp" should be logical.');
			chkarg(istypesizeof(withpml, 'logical'), '"withpml" should be logical.');

			if g == GT.prim
				lplot = this.lall{g};
			else  % g == GT.dual
				lplot = this.l{g};
			end

			if ~withpml
				lplot = lplot(1+this.Npml(Sign.n):end-this.Npml(Sign.p));
			end

			if g == GT.dual && withinterp
				lbound = this.bound_plot(withpml);
				lplot = [lbound(1), lplot, lbound(end)];
			end
		end

		function lvoxelbound = lvoxelbound(this, g, withpml)
			% Return the locations of boundaries of voxels drawn.  For data
			% at primary grid points, the voxel centers are within the
			% simulation domain including the boundary.  For data at dual
			% grid points, the voxel centers are within the simulation
			% domain excluding the boundary.
			chkarg(istypesizeof(g, 'GT') , '"g" should be instance of GT');
			chkarg(istypesizeof(withpml, 'logical'), '"withpml" should be logical.');

			lvoxelbound = this.lall{alter(g)};
			if ~withpml
				lvoxelbound = lvoxelbound(1+this.Npml(Sign.n):end-this.Npml(Sign.p));
			end

		end
	end
end


function rec=iEWT1D(ewt,mfb)

% ======================================================================
% function rec=iEWT1D(ewt,mfb)
%
% Perform the Inverse Empirical Wavelet Transform of ewt accordingly to
% the filter bank mfb
%
% Inputs:
%   -ewt: cell containing the EWT components
%   -mfb: filter bank used during the EWT
%
% Outputs:
%   -rec: reconstructed signal
%
% Author: Jerome Gilles
% Institution: UCLA - Department of Mathematics
% Year: 2012
% Version: 1.0
% ======================================================================

l=round(length(ewt{1})/2);

%We perform the adjoint operator to get the reconstruction
for k=1:length(ewt)
    ewt{k}=[ewt{k}(l-1:-1:1);ewt{k};ewt{k}(end:-1:end-l+1)];
    if k==1
        rec=zeros(length(ewt{1}),1);
    end
    rec=rec+real(ifft(fft(ewt{k}).*mfb{k}));
end
rec=rec(l:end-l);


%% POS conversion

posfile = dir('*pos');
pos = importdata(posfile.name);

% determine if timestamps are first or last column
[a b] = min(nanstd(diff(pos))); % find the column with smallest variability..

behav.timestamps = pos(:,b);
pos(:,b) = []; % remove timestamps from pos mat

if size(pos,2) > 5  % if optitrack
    columns = [7 9 8 3 5 4 6 10 1 2];
    pos = pos(:,columns);
    behav.position.x = pos(:,2);
    behav.position.y = pos(:,3);
    behav.position.z = pos(:,4);
    behav.orientation.rx = pos(:,5);
    behav.orientation.ry = pos(:,6);
    behav.orientation.rz = pos(:,7);
    behav.orientation.rw = pos(:,8);
    behav.timestamps = pos(:,1);
    behav.errorPerMarker = pos(:,9);
    behav.frameCount = pos(:,10);

elseif size(pos,2) < 5  % if LED tracking
    behav.position.x = nanmean(pos(:,[2 4]));
    behav.position.y = nanmean(pos(:,[1 3]));
    dx = pos(:,3) - pos(:,5);
    dy = pos(:,2) - pos(:,4);
	ang = atan2(dy,dx)-angOffset;
	ang = mod(ang,2*pi);
    behav.orientation.z = ang;
    warning('come up with a better head dir calculation...')
end

%% LFP conversion

%% SPIKE conversion

% times

spktimes.timestamps = ;

save('spktimes.cellinfo.mat')

% waveforms

save('waveforms.cellinfo.mat')

% features

save('features.cellinfo.mat')

% metadata

save('metadata.cellinfo.mat')

%% METADATA conversion

%% EVENT conversion

%% move old files to FMAT_format folder


filename='Cantilever_tetrahedra';
ptype = 'MACRO';
method = 'SIMPALL';
materialType = 'ISOTROPIC';
initial_case = 'full';
cost = {'compliance'};
weights = [1 0.1];
constraint = {'volumeConstraint'};
optimizer = 'MMA';
incrementFactor = 1;
designVariable = 'Density';
filterType = 'P1';

nsteps = 1;
Vfrac_final = 0.15;
optimality_final =1e-3;
constr_final =1e-3;

Vfrac_initial = 1;
optimality_initial = 1e-3;
constr_initial = 1e-3;

TOL.rho_plus = 1;
TOL.rho_minus = 0;
TOL.E_plus = 1;
TOL.E_minus = 1e-3;
TOL.nu_plus = 1/3;
TOL.nu_minus = 1/3;


function Ath = threshold_components(A,options)

% post processing of spatial components
% for each component perform the following:
%   (i)     perform median filtering
%   (ii)    threshold components
%   (iii)   perform morphological closing
%   (iv)    extract largest connected component

% The thresholding can be determined in two ways:
% options.thr_method = 'max': For every component pixel values below
%       options.thr_method are discarded
% options.thr_method = 'nrg': The boundary is drawn around the value above
%        which a specified fraction of energy is explained (default 99%)

% Written by:
% Eftychios A. Pnevmatikakis, Simons Foundation, 2015

    defoptions = CNMFSetParms;
    if nargin < 2 || isempty(options); options = defoptions; end
%     defoptions.nrgthr = 0.9999;              % energy threshold
%     defoptions.clos_op = strel('square',3);  % morphological operator for closing
%     defoptions.medw = [3,3];                 % size of median filter

    if ~isfield(options,'thr_method') || isempty(options.thr_method); options.thr_method = defoptions.thr_method; end
    if ~isfield(options,'nrgthr') || isempty(options.nrgthr); options.nrgthr = defoptions.nrgthr; end
    if ~isfield(options,'maxthr') || isempty(options.maxthr); options.maxthr = defoptions.maxthr; end
    if ~isfield(options,'clos_op') || isempty(options.clos_op); options.clos_op = defoptions.clos_op; end
    if ~isfield(options,'conn_comp') || isempty(options.conn_comp); options.conn_comp = defoptions.conn_comp; end % extract largest connected component
    if ~isfield(options,'medw') || isempty(options.medw); options.medw = defoptions.medw; end
    if ~isfield(options,'d3') || isempty(options.d3); options.d3 = 1; end

    if options.d3 > 1; options.thr_method = 'nrg'; end
    [d,nr] = size(A);
    Ath = spalloc(d,nr,nnz(A));
    Ath(:,nr-options.nb+1:nr) = A(:,nr-options.nb+1:nr);
    indf = cell(nr,1);
    valf = cell(nr,1);
    parfor i = 1:nr-options.nb
        A_temp = reshape(full(A(:,i)),options.d1,options.d2,options.d3);
        for z = 1:options.d3
            A_temp(:,:,z) = medfilt2(A_temp(:,:,z),options.medw);
        end
        if strcmpi(options.thr_method,'nrg')
            A_temp = A_temp(:);
            [temp,ind] = sort(A_temp(:).^2,'ascend');
            temp =  cumsum(temp);
            ff = find(temp > (1-options.nrgthr)*temp(end),1,'first');
            BW = zeros(options.d1,options.d2,options.d3);
            BW(ind(ff:d)) = 1;
            for z = 1:options.d3
                BW(:,:,z) = imclose(BW(:,:,z),options.clos_op);
            end
            [L,NUM] = bwlabeln(BW,8*(options.d3==1) + 6*(options.d3~=1));
            if NUM > 0
                nrg = zeros(NUM,1);
                for l = 1:NUM
                    ff = (L==l);
                    nrg(l) = sum(A_temp(ff).^2);
                end
                [~,indm] = max(nrg);
                ff = find(L==indm);
                indf{i} = ff;
                valf{i} = A_temp(ff);
            else
                valf{i} = 0;
            end
        else
            if ~strcmpi(options.thr_method,'max')
                fprintf('Unknown thresholding method, using thresholding based on max value. \n');
            end
            A_temp(A_temp<options.maxthr*max(A_temp(:))) = 0;
            BW = imclose(A_temp>0,options.clos_op);
            if options.conn_comp;
                BW = bwareafilt(BW,1);
            end
            ff = find(BW>0);
            indf{i} = ff;
            if ~isempty(ff)
                valf{i} = A_temp(ff);
            else
                valf{i} = 0;
            end
        end
    end
    for i = 1:nr-options.nb
        if ~isempty(indf{i})
            Ath(indf{i},i) = valf{i};
        end
    end
end


function out = NL_TSTL_dimensions(y,numBins,embedParams)
% NL_TSTL_dimensions Box counting, information, and correlation dimension of a time series.
%
% Computes the box counting, information, and correlation dimension of a
% time-delay embedded time series using the TSTOOL code 'dimensions'.
% This function contains extensive code for estimating the best scaling range to
% estimate the dimension using a penalized regression procedure.
%
% cf. TSTOOL, http://www.physik3.gwdg.de/tstool/
%
%---INPUTS:
% y, column vector of time series data
% numBins, maximum number of partitions per axis
% embedParams, embedding parameters to feed BF_Embed() for embedding the
%              signal in the form {tau,m}
%
%---OUTPUTS:
% A range of statistics are returned about how each dimension estimate changes
% with m, the scaling range in r, and the embedding dimension at which the best
% fit is obtained.

% ------------------------------------------------------------------------------
% Copyright (C) 2020, Ben D. Fulcher <ben.d.fulcher@gmail.com>,
% <http://www.benfulcher.com>
%
% If you use this code for your research, please cite the following two papers:
%
% (1) B.D. Fulcher and N.S. Jones, "hctsa: A Computational Framework for Automated
% Time-Series Phenotyping Using Massive Feature Extraction, Cell Systems 5: 527 (2017).
% DOI: 10.1016/j.cels.2017.10.001
%
% (2) B.D. Fulcher, M.A. Little, N.S. Jones, "Highly comparative time-series
% analysis: the empirical structure of time series and their methods",
% J. Roy. Soc. Interface 10(83) 20130048 (2013).
% DOI: 10.1098/rsif.2013.0048
%
% This function 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/>.
% ------------------------------------------------------------------------------

% ------------------------------------------------------------------------------
%% Preliminaries, check inputs
% ------------------------------------------------------------------------------
doPlot = false; % plot outputs to screen

% (1) Maximum number of bins, numBins
if nargin < 2 || isempty(numBins)
    numBins = 50; % 50 points
    fprintf(1,'Using a default of 50 bins per axis\n');
end

% (2) Set embedding parameters to defaults
if nargin < 3 || isempty(embedParams)
    embedParams = {'ac','fnnmar'};
    fprintf(1,'Using default time-delay embedding parameters: autocorrelation and cao');
else
    if length(embedParams) ~= 2
        error('Embedding parameters are incorrectly formatted -- need {tau,m}')
    end
end

% ------------------------------------------------------------------------------
%% Embed the signal
% ------------------------------------------------------------------------------
% Convert to embedded signal object for TSTOOL
s = BF_Embed(y,embedParams{1},embedParams{2},1);

if ~isa(s,'signal') && isnan(s); % embedding failed
    error('Time-delay embedding for TSTOOL failed')
end

if size(data(s),2) < 3 % embedded with dimension < 3
    % note the 'true' predicted embedding dimension
    mopt = size(data(s),2);
    % embed with dimension m = 3
    s = BF_Embed(y,embedParams{1},3,1);
    fprintf(1,'Re-embedded with embedding dimension 3\n');
else
	mopt = size(data(s),2);
end

% ------------------------------------------------------------------------------
%% Run the TSTOOL function:
% ------------------------------------------------------------------------------
% This looks for the dimensions file in the tstoolbox/@signal/dimensions directory
if ~exist(fullfile('tstoolbox','@signal','dimensions'),'file')
    error('Cannot find the code ''dimensions'' from the TSTOOL package. Is it installed and in the Matlab path?');
end
try
    [bc, ~, co] = dimensions(s,numBins);
catch me
    error('Error running TSTOOL code dimensions: %s',me.message);
end

% We now have the scaling of the boxcounting dimension, D0, the information
% dimension D1, and the correlation dimension D2.

% It seems like there's not extra information in the in dimension, D1, by these
% estimates -- focus on the bc, D0 and correlation, D2.
% Can switch this here:
compute_in = 0;

% ------------------------------------------------------------------------------
%% Convert output to vectors
% ------------------------------------------------------------------------------
% calculations for each dimension up to the maximum:
% Seems to be in units of log_2 -- log2, so actually doesn't span a very wide
% range of length scales... -- although I think the maximum length is at 1,
% so I think it might be referring to fractions of the 'attractor size'...

% (1) Boxcounting dimension (BC)
bc_logN = data(bc); % this is log(N(r)) -- number within radius (look for this to scale linearly)
bc_logr = spacing(bc); % this is log(r) -- length scale
bc_logNlogr = bc_logN./(ones(size(bc_logN,2),1)*bc_logr)'; % look for this to be constant

% (2) Information dimension (IN)
if compute_in
    in_logl = data(in); % I think this is log(l(r)), look for this to scale linearly
    in_logr = spacing(in);
    in_logllogr = in_logl./(ones(size(in_logl,2),1)*in_logr)'; % look for this to be constant
end

% (3) Correlation dimension (CO)
co_logC = data(co); % look for this to scale linearly
co_logr = spacing(co);
co_logClogr = co_logC./(ones(size(co_logC,2),1)*co_logr)'; % look for this to be constant

if doPlot
    plot(bc_logr,bc_logNlogr,'o-')
    plot(bc_logr,bc_logN,'o-')
    input('BC')
    if compute_in
        plot(in_logr,in_logllogr,'o-')
        plot(in_logr,in_logl,'o-')
        input('IN')
    end
    plot(co_logr,co_logClogr,'o-')
    plot(co_logr,co_logC,'o-')
    input('CO')
end

% *** We now have to look for scaling regimes in each of these dimensions

% ------------------------------------------------------------------------------
%% Basic statistics on curves
% ------------------------------------------------------------------------------
out = struct;

%-------------------------------------------------------------------------------
%% How do curves change with m?
%-------------------------------------------------------------------------------
% Use SUB_mch

% Box counting dimension:
out = SUB_mch(bc_logr,bc_logN,'bc',out);

% Information dimension:
if compute_in
    out = SUB_mch(bc_logr,bc_logN,'in',out);
end

% Correlation dimension:
out = SUB_mch(co_logr,co_logC,'co',out);

% ------------------------------------------------------------------------------
%% What is the scaling range in r?
% ------------------------------------------------------------------------------
% ... and how good is the fit over this range?
% Use SUB_ScalingRange

% Box counting dimension, m = 1
out = SUB_ScalingRange(bc_logr,bc_logN(:,1),'scr_bc_m1',out);

% Box counting dimension m = 2
out = SUB_ScalingRange(bc_logr,bc_logN(:,2),'scr_bc_m2',out);

% Box counting dimension m = 3
out = SUB_ScalingRange(bc_logr,bc_logN(:,3),'scr_bc_m3',out);

% Box counting dimension m = chosen/given
out = SUB_ScalingRange(bc_logr,bc_logN(:,mopt),'scr_bc_mopt',out);

if compute_in
    % Information dimension, m = 1
    out = SUB_ScalingRange(in_logr,in_logl(:,1),'scr_in_m1',out);

    % Information dimension m = 2
    out = SUB_ScalingRange(in_logr,in_logl(:,2),'scr_in_m2',out);

    % Information dimension m = 3
    out = SUB_ScalingRange(in_logr,in_logl(:,3),'scr_in_m3',out);

    % Information dimension m = chosen/given
    out = SUB_ScalingRange(in_logr,in_logl(:,mopt),'scr_in_mopt',out);
end

% Correlation dimension, m = 1
out = SUB_ScalingRange(co_logr,co_logC(:,1),'scr_co_m1',out);

% Correlation dimension m = 2
out = SUB_ScalingRange(co_logr,co_logC(:,2),'scr_co_m2',out);

% Correlation dimension m = 3
out = SUB_ScalingRange(co_logr,co_logC(:,3),'scr_co_m3',out);

% Correlation dimension m = chosen/given
out = SUB_ScalingRange(co_logr,co_logC(:,mopt),'scr_co_mopt',out);

% ------------------------------------------------------------------------------
%% What m gives best fit?
% ------------------------------------------------------------------------------
% Use SUB_bestm

% Box counting dimension
out = SUB_bestm(bc_logr,bc_logN,'bc',out);

if compute_in
    % Information dimension
    out = SUB_bestm(in_logr,in_logl,'in',out);
end

% Correlation dimension
out = SUB_bestm(co_logr,co_logC,'co',out);

% ------------------------------------------------------------------------------
% ------------------------------------------------------------------------------
function out = SUB_mch(logr,logN,prefix,out)
    % looks at how changes with m. Since m will in general be different for each
    % different time series (i.e., if choosing an automatic method for
    % determining the embedding parameters), we have that m is at least
    % 3 here so that we can do statistics on at least these ones...

    % (i) on average the raw means at each m up to m = 3
    out.([prefix,'_meanm1']) = mean(logN(:,1));
    out.([prefix,'_meanm2']) = mean(logN(:,2));
    out.([prefix,'_meanm3']) = mean(logN(:,3));
    out.([prefix,'_meanmmax']) = mean(logN(:,end));

    % (ii) raw minimum at each m up to m = 3
    out.([prefix,'_minm1']) = min(logN(:,1));
    out.([prefix,'_minm2']) = min(logN(:,2));
    out.([prefix,'_minm3']) = min(logN(:,3));
    out.([prefix,'_minmmax']) = min(logN(:,end));

    % (iii) range at each m up to m = 3
    out.([prefix,'_range1']) = range(logN(:,1));
    out.([prefix,'_range2']) = range(logN(:,2));
    out.([prefix,'_range3']) = range(logN(:,3));
    out.([prefix,'_rangemmax']) = range(logN(:,end));

    % (iv) increments with m
    out.([prefix,'_mindiff']) = mean([min(logN(:,2))-min(logN(:,1)),min(logN(:,3))-min(logN(:,2))]);
    out.([prefix,'_meandiff']) = mean([mean(logN(:,2))-mean(logN(:,1)),mean(logN(:,3))-mean(logN(:,2))]);

    % (v) slopes and goodness of fit across whole r range
    [out.([prefix,'_lfitm1']), out.([prefix,'_lfitb1']), out.([prefix,'_lfitmeansqdev1'])] = subsublinfit(logr,logN(:,1)');
    [out.([prefix,'_lfitm2']), out.([prefix,'_lfitb2']), out.([prefix,'_lfitmeansqdev2'])] = subsublinfit(logr,logN(:,2)');
    [out.([prefix,'_lfitm3']), out.([prefix,'_lfitb3']), out.([prefix,'_lfitmeansqdev3'])] = subsublinfit(logr,logN(:,3)');
    [out.([prefix,'_lfitmmax']), out.([prefix,'_lfitbmax']), out.([prefix,'_lfitmeansqdevmax'])] = subsublinfit(logr,logN(:,end)');

    function [m, b, meansqdev] = subsublinfit(x,y)
        p1 = polyfit(x,y,1);
        pfit = p1(1)*x + p1(2);
        res = y-pfit;
        m = p1(1); % gradient
        b = p1(2); % intercept
        meansqdev = mean(res.^2);
    end
end

% ------------------------------------------------------------------------------
function out = SUB_ScalingRange(logr,logN,prefix,out)
    % determines the scaling range in r for some m
    % we remove points from either extreme in r until minimize some
    % error measure
    % two dimensional optimization: over starting point and ending
    % point.

    l = length(logr);
    stptr = 1:floor(l/2)-1; % must be in the first half (not necessarily, but for here)
    endptr = ceil(l/2)+1:l; % must be in second half (not necessarily, but for here)
    mybad = zeros(length(stptr),length(endptr));
    for i = 1:length(stptr)
        for j = 1:length(endptr)
            mybad(i,j) = lfitbadness(logr(stptr(i):endptr(j)),logN(stptr(i):endptr(j))');
        end
    end
    [a,b] = find(mybad == min(min(mybad))); % this defines the 'best' scaling range
%         plot(logr,logN,'o-b'); hold on; plot(logr(stptr(a):endptr(b)),logN(stptr(a):endptr(b)),'o-r');
%         hold off
%         disp(['keep from ' num2str(stptr(a)) ' to ' num2str(endptr(b))])

    out.([prefix,'_logrmin']) = logr(stptr(a)); % minimum of scaling range
    out.([prefix,'_logrmax']) = logr(endptr(b)); % maximum of scaling range
    out.([prefix,'_logrrange']) = logr(endptr(b)) - logr(stptr(a)); % range of scaling... range
    out.([prefix,'_pgone']) = (stptr(a)-1 + l - endptr(b))/length(logr); % number of points removed in process
                                               				  % of choosing the optimum scaling range

	% Do the optimum fit again
	x = logr(stptr(a):endptr(b));
	y = logN(stptr(a):endptr(b))';
    p = polyfit(x,y,1);
    pfit = p(1)*x + p(2);
    res = pfit - y;
    out.([prefix,'_meanabsres']) = mean(abs(res));
	out.([prefix,'_meansqres']) = mean(res.^2);
    out.([prefix,'_scaling_exp']) = p(1);
	out.([prefix,'_scaling_int']) = p(2);
	out.([prefix,'_minbad']) = min(min(mybad));

    function badness = lfitbadness(x,y)
        gamma = 0.02; % reguralization parameter gamma selected empirically, could be tweaked in future work
        p = polyfit(x,y,1);
        pfit = p(1)*x+p(2);
        res = pfit - y;
        badness = mean(abs(res)) - gamma*length(x); % want to still maximize length(x)
    end
end

% ------------------------------------------------------------------------------
function out = SUB_bestm(logr,logNN,prefix,out)
    % logNN is a matrix... logN is a vector for a given m
	% determines the scaling range in r for some m
    % we remove points from either extreme in r until minimize some
    % error measure
    % two dimensional optimization: over starting point and ending
    % point.

	store_scalingexps = zeros(size(logNN,2),1);
	store_meansqres = zeros(size(logNN,2),1);
	for k = 1:size(logNN,2);
		logN = logNN(:,k); % take this element

        l = length(logr);
        stptr = 1:floor(l/2)-1; % must be in the first half (not necessarily, but for here)
        endptr = ceil(l/2)+1:l; % must be in second half (not necessarily, but for here)
        mybad = zeros(length(stptr),length(endptr));
        for i = 1:length(stptr)
            for j = 1:length(endptr)
                mybad(i,j) = lfitbadness(logr(stptr(i):endptr(j)),logN(stptr(i):endptr(j))');
            end
        end
        [a, b] = find(mybad == min(min(mybad))); % this defines the 'best' scaling range

		% Do the optimum fit again
		x = logr(stptr(a):endptr(b));
		y = logN(stptr(a):endptr(b))';
        p = polyfit(x,y,1);
        pfit = p(1)*x+p(2);
        res = pfit - y;
		% subout.meanabsres = mean(abs(res));
		% subout.meansqres = mean(res.^2);
		% subout.scaling_exp = p(1);
		% subout.scaling_int = p(2);
		% subout.minbad = min(min(mybad));

		store_scalingexps(k) = p(1);
		store_meansqres(k) = mean(res.^2);
	end

	out.([prefix,'_minscalingexp']) = min(store_scalingexps);
	out.([prefix,'_meanscalingexp']) = mean(store_scalingexps);
	out.([prefix,'_maxscalingexp']) = max(store_scalingexps);
	out.([prefix,'_mbestfit']) = find(store_meansqres == min(store_meansqres),1,'first');

    function badness = lfitbadness(x,y)
        gamma = 0.02; % reguralization parameter gamma selected empirically, could be tweaked in future work
        p = polyfit(x,y,1);
        pfit = p(1)*x + p(2);
        res = pfit - y;
        badness = mean(abs(res)) - gamma*length(x); % want to still maximize length(x)
    end
end

end


% Copyright (C) 1993-2017, by Peter I. Corke
%
% This file is part of The Machine Vision Toolbox for Matlab (MVTB).
%
% MVTB is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% MVTB is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with MVTB.  If not, see <http://www.gnu.org/licenses/>.
%
% http://www.petercorke.com
classdef scamera
    properties
        name
        Tcam
    end

    methods
        function c = scamera
            c.Tcam = eye(4,4);
        end

        function f = plot(c, points, varargin)
            f = c.project(points, varargin{:});
            plot(f(2,:), f(1,:), 'o');
            xlabel('phi (rad)');
            ylabel('theta (rad)');
            grid on
            axis([-pi pi 0 pi]);
        end

        function f = project(c, P, Tcam)
            if nargin < 3
                Tcam = c.Tcam;
            end
            P = transformp(inv(Tcam), P);

            R = sqrt( sum(P.^2) );
            x = P(1,:) ./ R;
            y = P(2,:) ./ R;
            z = P(3,:) ./ R;
            r = sqrt( x.^2 + y.^2);
            theta = atan2(r, z);
            phi = atan2(y, x);
            f = [theta; phi];
        end
    end
end


% test_itk_imfilter.m
%
% Script to test the filters provided by itk_imfilter.

% Author: Ramon Casero <rcasero@gmail.com>
% Copyright © 2011-2014 University of Oxford
% Version: 0.4.5
%
% University of Oxford means the Chancellor, Masters and Scholars of
% the University of Oxford, having an administrative office at
% Wellington Square, Oxford OX1 2JD, UK.
%
% This file is part of Gerardus.
%
% 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. The offer of this
% program under the terms of the License is subject to the License
% being interpreted in accordance with English Law and subject to any
% action against the University of Oxford being under the jurisdiction
% of the English Courts.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see
% <http://www.gnu.org/licenses/>.

%% itk::BinaryThinningImageFilter3D (skel) filter

% load test data
nrrd = scimat_load('../../cpp/src/third-party/IJ-Vessel_Enhancement_Diffusion.1/CroppedWholeLungCTScan.mhd');
nrrd.data = nrrd.data > 150;

% plot data
close all
imagesc(nrrd.data(:, :, 3))

% skeletonise (0.04 s)
tic
im = itk_imfilter('skel', nrrd);
toc

figure
imagesc(im(:, :, 3))

%% itk::DanielssonDistanceMapImageFilter (dandist) filter

% very simple 3x3 matrix with only central pixel = 1
im = zeros(3);
im(2, 2) = 1;
nrrd = scimat_im2scimat(im, [.5 .5 .5], [0 0 0]);
[im2, v, w] = itk_imfilter('dandist', nrrd);

% vector is given in voxel coordinates as (r, c, s) instead of (x, y, z)
w()

% load test data
nrrd = scimat_load('../../cpp/src/third-party/IJ-Vessel_Enhancement_Diffusion.1/CroppedWholeLungCTScan.mhd');
nrrd2 = nrrd;
nrrd2.data(:) = 0;
nrrd2.data(:, 20, :) = 1;
nrrd2.data(:, 45, :) = 2;

% plot data
close all
imagesc(nrrd2.data(:, :, 3))

% compute distance (0.11 s)
tic
[im, v, w] = itk_imfilter('dandist', nrrd2);
toc

% distance map
figure
imagesc(im(:, :, 3))

% voronoi diagram
figure
imagesc(v(:, :, 3))

%% itk::SignedMaurerDistanceMapImageFilter (maudist) filter

% load test data
nrrd = scimat_load('../../cpp/src/third-party/IJ-Vessel_Enhancement_Diffusion.1/CroppedWholeLungCTScan.mhd');
nrrd2 = nrrd;
nrrd2.data(:) = 0;
nrrd2.data(:, 20:23, :) = 1;
nrrd2.data = uint16(nrrd2.data);

% plot data
close all
imagesc(nrrd2.data(:, :, 3))

% compute distance (0.11 s)
tic
im = itk_imfilter('maudist', nrrd2.data);
toc

% distance map
figure
imagesc(im(:, :, 3))

%% itk:::BinaryDilateImageFilter (bwdilate) filter

% load test data
nrrd = scimat_load('../../cpp/src/third-party/IJ-Vessel_Enhancement_Diffusion.1/CroppedWholeLungCTScan.mhd');
nrrd.data = nrrd.data > 150;

% plot data
close all
imagesc(nrrd.data(:, :, 3))

% dilate (0.02 s)
tic
im = itk_imfilter('bwdilate', nrrd, 4);
toc

figure
imagesc(im(:, :, 3))

%% itk:::BinaryErodeImageFilter (bwerode) filter

% load test data
nrrd = scimat_load('../../cpp/src/third-party/IJ-Vessel_Enhancement_Diffusion.1/CroppedWholeLungCTScan.mhd');
nrrd.data = nrrd.data > 150;

% plot data
close all
imagesc(nrrd.data(:, :, 3))

% erode (0.02 s)
tic
im = itk_imfilter('bwerode', nrrd, 1);
toc

figure
imagesc(im(:, :, 3))

%% itk::AnisotropicDiffusionVesselEnhancementImageFilter (advess) filter

% load test data
nrrd = scimat_load('../../cpp/src/third-party/IJ-Vessel_Enhancement_Diffusion.1/CroppedWholeLungCTScan.mhd');
nrrd.data = single(nrrd.data);

% plot data
close all
imagesc(nrrd.data(:, :, 3))

% user-provided parameters
sigmaMin = nrrd.axis(1).spacing * 5;
sigmaMax = nrrd.axis(1).spacing * 10;
sigmaSteps = 15;
isSigmaStepLog = false;
iterations = 30;
wStrength = 24;
sensitivity = 4.0;
timeStep = 1e-3;
epsilon = 1e-2;

% smooth along vessels (11.4 s)
tic
im = itk_imfilter('advess', nrrd, sigmaMin, sigmaMax, sigmaSteps, ...
    isSigmaStepLog, iterations, wStrength, sensitivity, timeStep, epsilon);
toc

figure
imagesc(im(:, :, 3))

figure
imagesc(nrrd.data(:, 2:end, 3) - im(:, 2:end, 3))

%% itk::MultiScaleHessianSmoothed3DToVesselnessMeasureImageFilter (hesves)

% load test data
nrrd = scimat_load('../../cpp/src/third-party/IJ-Vessel_Enhancement_Diffusion.1/CroppedWholeLungCTScan.mhd');
nrrd.data = single(nrrd.data);

% plot data
close all
imagesc(nrrd.data(:, :, 5))

% user-provided parameters
sigmaMin = 1;
sigmaMax = 8;
sigmaSteps = 4;
isSigmaStepLog = false;

% compute vesselness measure
tic
im = itk_imfilter('hesves', nrrd.data, sigmaMin, sigmaMax, sigmaSteps, ...
    isSigmaStepLog);
toc

figure
imagesc(im(:, :, 5))

%% itk::MedianImageFilter (median)

% load test data
nrrd = scimat_load('../../cpp/src/third-party/IJ-Vessel_Enhancement_Diffusion.1/CroppedWholeLungCTScan.mhd');

% default median filtering (no filtering)
im2 = itk_imfilter('median', nrrd);

err = im2 - nrrd.data;
% expected result = 0
any(err(:) ~= 0)

% median filtering only along rows, line of length 5+1+5=11
im2 = itk_imfilter('median', nrrd, [5 0 0]);

% plot difference
subplot(2, 1, 1)
imagesc(nrrd.data(:, :, 4))
subplot(2, 1, 2)
imagesc(im2(:, :, 4))

% median filtering only along columns, line of length 20+1+20=41
im2 = itk_imfilter('median', nrrd, [0, 20, 0]);

% plot difference
subplot(2, 1, 1)
imagesc(nrrd.data(:, :, 4))
subplot(2, 1, 2)
imagesc(im2(:, :, 4))

% compare speed and results with Matlab's implementation
tic
im2 = itk_imfilter('median', nrrd, [10, 10, 10]); % 5.9 sec
toc
tic
im3 = medfilt3(nrrd.data, [21, 21, 21]); % 36.5 sec
toc

% difference: expected result = 0
any(double(im2(:)) - double(im3(:)))

% plot both results
subplot(2, 1, 1)
imagesc(im2(:, :, 4))
subplot(2, 1, 2)
imagesc(im3(:, :, 4))

%% itk::MRFImageFilter (mrf)

% load test data
scimat = scimat_load('../../cpp/src/third-party/IJ-Vessel_Enhancement_Diffusion.1/CroppedWholeLungCTScan.mhd');

% plot image
hold off
subplot(2, 2, 1)
imagesc(scimat.data(:,:,4))

% initial segmentation
[thr, q, obj, seg] = gmthr_seg(double(scimat.data), 2);

% quality of the separation between classes (expected: q = 0.9020)
q

% plot segmented image using the Gaussian mixture model
subplot(2, 2, 2)
imagesc(seg(:,:,4))

% compute neighbourhood weights that decrease with Euclidean distance
[gr, gc, gs] = ndgrid(-3:3, -3:3, -2:2);
weights = 1./sqrt(gr.^2 + gc.^2 + gs.^2);
weights(isinf(weights)) = 0.0;

% segment the image using the Markov Random Filter algorithm
seg = itk_imfilter('mrf', scimat.data, obj.mu', weights);

% plot segmented image using the Gaussian mixture model
subplot(2, 2, 3)
imagesc(seg(:,:,4))

% repeat segmentation, now with significant smoothing
seg = itk_imfilter('mrf', scimat.data, obj.mu', weights, 2);

% plot segmented image using the Gaussian mixture model
subplot(2, 2, 4)
imagesc(seg(:,:,4))

%% itk::VotingBinaryIterativeHoleFillingImageFilter (voteholefill)

% create small toy image with a small hole
im = zeros(15, 15, 'uint8');
im(3:13, 3:13) = 1;
im(7:8, 7) = 0;

% plot input image
hold off
imagesc(im)

% run filter to fill in holes
RAD = [2 2];
THR = 2;
im2 = itk_imfilter('voteholefill', im, RAD, THR);

% plot output image
imagesc(im2)

%% itk::CannyEdgeDetectionImageFilter

% load rat heart MRI
scimat = scimat_load('data/008-mri-downsampled-4.mha');

% normalise the spacing, otherwise the filter produces NaN voxels
inc = min([scimat.axis.spacing]);
scimat.axis(1).spacing = scimat.axis(1).spacing / inc;
scimat.axis(2).spacing = scimat.axis(2).spacing / inc;
scimat.axis(3).spacing = scimat.axis(3).spacing / inc;

% plot one of the intermediate slices
subplot(2, 2, 1)
hold off
imagesc(scimat.data(:, :, 112));
colormap(gray)

% filter parameters

% standard deviation of the Gaussian filtering is roughly 5 times the
% the voxel size in each dimension
sigma = [scimat.axis.spacing] * 2;

% upper threshold
uppthr = 450;

% lower threshold
lowthr = uppthr/2;

% maximum error
maxerr = 0.01*ones(1, 3);

% run Canny edge filter
[im, im2] = itk_imfilter('canny', scimat, sigma.^2, uppthr, lowthr, maxerr);

% plot edge detection result
subplot(2, 2, 2)
imagesc(im2(:, :, 112))
subplot(2, 2, 3)
imagesc(im(:, :, 112))


function value = r8_huge ( )

%*****************************************************************************80
%
%% R8_HUGE returns a "huge" real number.
%
%  Discussion:
%
%    MATLAB provides a built-in symbolic function realmax ( ) that returns
%    the largest real number.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 September 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, real VALUE, a huge number.
%
  value = 1.79769313486231571E+308;

  return
end


function y = relu(x,dzdy)

  if nargin <= 1 || isempty(dzdy)
    y = max(x, single(0)) ;
  else
    y = dzdy .* (x > single(0)) ;
  end

end


function y=nsct_fuse(I1,I2,nlevels)
%    NSCT
%    Input:
%    I1 - input image A
%    I2 - input image B
%    nlevels - number of directions in each decomposition level
%    Output:
%    y  - fused image
%
%    The code is edited by Yu Liu, 01-09-2014.

%nlevels = [2,3,3,4] ;
pfilter = 'pyrexc' ;
dfilter = 'vk' ;

I1=double(I1);
I2=double(I2);
coeffs_1 = nsctdec( I1, nlevels, dfilter, pfilter );
coeffs_2 = nsctdec( I2, nlevels, dfilter, pfilter );

[m,n]=size(I1);
coeffs=coeffs_2;
for i=2:numel(nlevels)+1

    if nlevels(i-1)==0
        E1=abs(coeffs_1{i});
        E2=abs(coeffs_2{i});
        %             map=E1>E2;
         um=3;
    A1 = ordfilt2(abs(es2(E1,floor(um/2))), um*um, ones(um));
  	A2 = ordfilt2(abs(es2(E2,floor(um/2))), um*um, ones(um));
    % second step
  	map= (conv2(double(A1 > A2), ones(um), 'valid')) > floor(um*um/2);
        coeffs{i}(map)=coeffs_1{i}(map);
    else
        for j=1:(2^nlevels(i-1))
            E1=abs(coeffs_1{i}{j});
            E2=abs(coeffs_2{i}{j});
%             map=E1>E2;
    um=3;
    A1 = ordfilt2(abs(es2(E1,floor(um/2))), um*um, ones(um));
  	A2 = ordfilt2(abs(es2(E2,floor(um/2))), um*um, ones(um));
    % second step
  	map= (conv2(double(A1 > A2), ones(um), 'valid')) > floor(um*um/2);
            coeffs{i}{j}(map)=coeffs_1{i}{j}(map);
        end
    end
end

% energy based method

coeffs{1}=(coeffs_1{1}+coeffs_2{1})/2;

y= nsctrec( coeffs, dfilter, pfilter ) ;


function [ new_images ] = nxel( n, old_image )
%Nxel - takes image and pixelizes into n * n array
    [a,b,~] = size(old_image);
    new_images = cell(n,n);
    for i = 1:n
        for j = 1:n
            new_images{i,j} = old_image((1+(i-1)*floor(a/n)):(floor(i*a/n)-1),...
                                        (1+(j-1)*floor(b/n)):(floor(j*b/n)-1),...
                                   :);
        end
    end
end


function [xVals, yVals, zVals] = getDeformXYZVals(deformStruct)
%"getDeformXYZVals"
%   Returns the x, y, and z values of the cols, rows, and slices of the
%   passed deformStruct.
%
%   REMINDER: These x,y,z values are the coordinates of the MIDDLE of the
%   voxels of the scan.  They are not the coordinates of the dividers
%   between the voxels.
%
%
% xVals yVals zVals : x,y,z Values for scan deformation grid.
%
% Usage:
%   function [xVals, yVals, zVals] = getDeformXYZVals(deformStruct)
%
% Copyright 2010, Joseph O. Deasy, on behalf of the CERR development team.
%
% This file is part of The Computational Environment for Radiotherapy Research (CERR).
%
% CERR development has been led by:  Aditya Apte, Divya Khullar, James Alaly, and Joseph O. Deasy.
%
% CERR has been financially supported by the US National Institutes of Health under multiple grants.
%
% CERR is distributed under the terms of the Lesser GNU Public License.
%
%     This version of CERR 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.
%
% CERR 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 CERR.  If not, see <http://www.gnu.org/licenses/>.

sizeDim1 = double(deformStruct.gridDimensions(2))-1;
sizeDim2 = double(deformStruct.gridDimensions(1))-1;
sizeDim3 = double(deformStruct.gridDimensions(3));
zStart = deformStruct.imagePositionPatient(3);
zRes = deformStruct.gridResolution(3);
deformStruct.xOffset = double(deformStruct.xOffset);
deformStruct.yOffset = double(deformStruct.yOffset);

xVals = deformStruct.xOffset - (sizeDim2*deformStruct.gridResolution(1))/2 : deformStruct.gridResolution(1) : deformStruct.xOffset + (sizeDim2*deformStruct.gridResolution(1))/2;
yVals = fliplr(deformStruct.yOffset - (sizeDim1*deformStruct.gridResolution(2))/2 : deformStruct.gridResolution(2) : deformStruct.yOffset + (sizeDim1*deformStruct.gridResolution(2))/2);
zVals = linspace(zStart, zStart + zRes * sizeDim3, sizeDim3);
zVals = -fliplr(zVals);


function [Psamp,noise,M] = spm_mci_fixed (mcmc,w,fixed,noise,M,U,Y)
% Group fixed effects estimation
% FORMAT [Psamp,noise,M] = spm_mci_fixed (mcmc,w,fixed,noise,M,U,Y)
%
% mcmc      Sampling parameters
% w(:,n)    Random effects for nth subject
% fixed     [fixed.pE, fixed.pC] prior over fixed effects
% noise     noise structure
% M,U,Y     Model, input, data structures
%
% Psamp     Samples, [maxits x M{1}.Np]
% noise     updated noise model
% M         updated model structures
%
% Uses Langevin Monte Carlo
%__________________________________________________________________________
% Copyright (C) 2015 Wellcome Trust Centre for Neuroimaging

% Will Penny
% $Id: spm_mci_fixed.m 6697 2016-01-27 14:57:28Z spm $

try, verbose=mcmc.verbose; catch, verbose=0; end
try, maxits=mcmc.maxits; catch, maxits=64; end
try, plot_int=mcmc.plot_int; catch, plot_int=1; end
try, update_obs_step=mcmc.update_obs_step; catch, update_obs_step=64; end
try, h=mcmc.h; catch, h=0.5; end

assign=mcmc.assign;

% Prior over fixed effects
pE=fixed.pE;
Np=length(pE);
V=eye(Np);
ipC=inv(fixed.pC);
log_prior_t2=spm_logdet(ipC)/2-0.5*Np*log(2*pi);

N=length(M);
for n=1:N
    M{n}.logdet_Ce=spm_logdet(M{n}.Ce);
    M{n}.iCe = inv(M{n}.Ce);
end

try, init=mcmc.init; catch, init=fixed.vpE; end
xinit = init;
x = zeros(maxits,Np);
x(1,:) = xinit';

if verbose figure; end

% Tune h by monitoring acceptance rate
tune_h=1;
acc_block=32;
acc_low=0.3;
acc_high=0.7;
total_acc_target=64; % Number of accepted samples to get
acc=zeros(maxits,1);

i=1;
while (i < maxits) && (sum(acc) < total_acc_target),

    if verbose
        if mod(i,plot_int) == 0 && i > 2
            spm_mci_progress (x,E,i);
        end
    end

    if mod(i,acc_block)==0 && tune_h
        % Change step size h ?
        Nacc=sum(acc(i-acc_block+1:i-1));
        prop_acc=Nacc/acc_block;
        if prop_acc < acc_low
            if verbose, disp('Decreasing step size ...'); end
            h=h/2;
        elseif prop_acc > acc_high
            if verbose, disp('Increasing step size ...'); end
            h=h*2;
        end
    end

    % Proposal (first proposal always accepted)
    if i==1
        pos=x(1,:)';
        curr=[];
    else
        pos=spm_normrnd(curr.mu,curr.Cp,1);
    end

    % Quantities re proposal
    prop.pos=pos;

    % Get gradient and curvature of log like
    dLdp=zeros(1,Np);
    iCpY=zeros(Np,Np);

    for n=1:N,
        if ~isempty(w), wsub=w(:,n); else, wsub=[]; end
        [dLdp_n,iCpY_n,st] = spm_mci_grad_curve (assign,wsub,pos,M{n},U{n},Y{n},'fixed');

        dLdp = dLdp + dLdp_n;
        iCpY = iCpY + iCpY_n;
    end
    dlogprior = - (pos-pE)'*ipC;
    j=dLdp+dlogprior;

    % Log like
    log_like=0;
    for n=1:N,
        if ~isempty(w), wsub=w(:,n); else, wsub=[]; end
        [Pinit,Pflow] = spm_mci_init_flow (assign,wsub,pos,M{n});
        like_n = spm_mci_like_ind (Pflow,Pinit,M{n},U{n},Y{n});
        log_like = log_like + like_n;
    end
    e=pos-pE;
    log_prior = - e'*ipC*e/2 + log_prior_t2;
    prop.L=log_like+log_prior;

    if st==-1
        disp('Integration problem in spm_mci_random.m');
        keyboard
    end

    % Posterior covariance under local linear approximation
    prop.Cp = h*inv(iCpY+ipC);
    prop.mu = pos+0.5*h*prop.Cp*j(:);

    prop.iCp = inv(prop.Cp);
    prop.logdetCp = spm_logdet(prop.Cp);

    % Accept proposal ?
    [curr,accepted,bayes_fb(i),dL(i)] = spm_mci_mh_update(curr,prop,verbose);
    acc(i)=accepted;
    E(i) = -curr.L;
    if i > 1
        dEdit(i-1)=100*(E(i)-E(i-1))/E(i-1);
    end
    x(i,:)=curr.pos;

    i=i+1;
end

Psamp=x(1:i-1,:);


function [ a, b ] = p20_lim ( )

%*****************************************************************************80
%
%% P20_LIM returns the integration limits for problem 20.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 November 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, real A, B, the limits of integration.
%
  a = -1.0;
  b = 1.0;

  return
end


function value = i4_min ( a, b )

%*****************************************************************************80
%
%% I4_MIN returns the minimum of two I4's.
%
%  Discussion:
%
%    An I4 is an integer value.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 March 2015
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer A, B, values to compare.
%
%    Output, integer VALUE, the minimum of A and B.
%
  a = floor ( a );
  b = floor ( b );

  if ( a < b )
    value = a;
  else
    value = b;
  end

  return
end


function [irf_record,D_record,gamma_record,struct_irf_record,irf_estimates,D_estimates,gamma_estimates,strshocks_record,strshocks_estimates]=...
    panel6irf(y,Xtilde,theta_gibbs,sigma_gibbs,B_gibbs,Xi,It,Bu,IRFperiods,IRFband,IRFt,rho,thetabar,N,n,m,p,T,d,favar)

% create first the cells storing the results
irf_record={};
irf_estimates={};

% deal with shocks in turn (there are N*n shocks with this model)
for ii=1:N*n

   % start iterating
   for jj=1:It-Bu

   % draw theta from its posterior distribution
   theta=theta_gibbs(:,jj,T);

   % draw B from its posterior distribution
   B=reshape(B_gibbs(:,jj),d,d);
   % obtain its Choleski factor: as B is diagonal, it is simply the square roots of its diagonal entries
   cholB=sparse(diag((diag(B).^0.5)));

   % create a matrix of zeros of dimension p*(N*n)
   Ysim=zeros(p,N*n);
   %  step 2: set the value of the last row, column i, equal to 1
   Ysim(p,ii)=1;

      % step 4: for each iteration kk, repeat the algorithm for periods T+1 to T+h
      for kk=1:IRFperiods-1

      % recover theta for period T+kk
      theta=(1-rho)*thetabar+rho*theta+cholB*mvnrnd(zeros(d,1),eye(d))';

      % use the function lagx to obtain a matrix temp, containing the endogenous regressors
      temp=bear.lagx(Ysim,p-1);

      % define the vector X for the period
      Xsim_t=[temp(end,:) zeros(1,m)];

      % obtain Xbar_t et Xtilde_t
      Xbar_t=kron(speye(N*n),Xsim_t);
      Xtilde_t=Xbar_t*Xi;

      % obtain the predicted value for T+kk
      yp=Xtilde_t*theta;

      % concatenate yp at the top of Y
      Ysim=[Ysim;yp'];

      % repeat until values are obtained for T+h
      end

      % record the results from current iteration in cell irf_record
      % loop over variables
      for kk=1:N*n
      % consider column kk of matrix Ysim and trim the (p-1) initial periods: what remains is the series of IRFs for period T to period T+h-1, for variable kk
      temp=Ysim(p:end,kk);
      % record these values in the corresponding matrix of irf_record
      irf_record{kk,ii}(jj,:)=temp';
      end

   % then go for next iteration
   end

% conduct the same process with shocks in other variables
end

% then apply the structural decomposition (if applicable)
% if IRFs have been set to an unrestricted VAR (IRFt=1):
if IRFt==1
% generate empty structural IRFs (just to be consistent with subsequent parts of the code
struct_irf_record=[];
% compute posterior estimates
[irf_estimates,D_estimates,gamma_estimates]=bear.irfestimates(irf_record,N*n,IRFperiods,IRFband,IRFt,[],[],favar);
% if IRFs have been set to an SVAR with Choleski identification (IRFt=2):
elseif IRFt==2
% run the Gibbs sampler to transform unrestricted draws into orthogonalised draws
[struct_irf_record,D_record,gamma_record]=bear.irfchol(sigma_gibbs(:,:,T),irf_record,It,Bu,IRFperiods,N*n,favar);
% compute posterior estimates
[irf_estimates,D_estimates,gamma_estimates]=bear.irfestimates(struct_irf_record,N*n,IRFperiods,IRFband,IRFt,D_record,gamma_record,favar);
% if IRFs have been set to an SVAR with triangular factorisation (IRFt=3):
elseif IRFt==3
% run the Gibbs sampler to transform unrestricted draws into orthogonalised draws
[struct_irf_record,D_record,gamma_record]=bear.irftrig(sigma_gibbs(:,:,T),irf_record,It,Bu,IRFperiods,N*n,favar);
% compute posterior estimates
[irf_estimates,D_estimates,gamma_estimates]=bear.irfestimates(struct_irf_record,N*n,IRFperiods,IRFband,IRFt,D_record,gamma_record,favar);
end

% record the structural decomposition matrices (the ones obtained from the structural decomposition function only apply to the final period, but incoming functions will require records for all the periods)
% also, if a structural identification was implemented, compute structural shocks
strshocks_record={};
strshocks_estimates={};
% in the case of no structural decomposition
if IRFt==1
% run a pseudo Gibbs sampler to obtain records for D and gamma (for the trivial SVAR)
D_record=repmat(reshape(eye(N*n),(N*n)^2,1),[1 It-Bu T]);
gamma_record=sigma_gibbs;
% obtain estimates
D_estimates=repmat(reshape(eye(N*n),(N*n)^2,1),[1 1 T]);
   for ii=1:T
   gamma_estimates(:,1,ii)=quantile(gamma_record(:,:,ii),0.5,2);
   end
elseif IRFt==2
% run the Gibbs sampler
[strshocks_record,D_record,gamma_record]=bear.strshockspan6(theta_gibbs,sigma_gibbs,y,Xtilde,N,n,T,It,Bu,IRFt);
% obtain point estimates and credibility intervals
[strshocks_estimates]=bear.strsestimates(strshocks_record,N*n,T,IRFband);
% reshape
strshocks_estimates=reshape(strshocks_estimates,[n 1 N]);
% obtain estimates
   for ii=1:T
   D_estimates(:,1,ii)=quantile(D_record(:,:,ii),0.5,2);
   end
gamma_estimates=repmat(reshape(eye(N*n),(N*n)^2,1),[1 1 T]);
elseif IRFt==3
% run the Gibbs sampler
[strshocks_record,D_record,gamma_record]=bear.strshockspan6(theta_gibbs,sigma_gibbs,y,Xtilde,N,n,T,It,Bu,IRFt);
% obtain point estimates and credibility intervals
[strshocks_estimates]=bear.strsestimates(strshocks_record,N*n,T,IRFband);
% reshape
strshocks_estimates=reshape(strshocks_estimates,[n 1 N]);
% obtain estimates
   for ii=1:T
   D_estimates(:,1,ii)=quantile(D_record(:,:,ii),0.5,2);
   gamma_estimates(:,1,ii)=quantile(gamma_record(:,:,ii),0.5,2);
   end
end


function test_bug1571

% MEM 5gb
% WALLTIME 00:10:00
% DEPENDENCY ft_preprocessing ft_preproc_dftfilter dftfilter ft_freqanalysis ft_singleplotER

% Philipp Hintze wrote:
% The issue with the continuous data is the following: I tried using
% [this script]
% but looking at averaged timelocked data for the subject, the data looks
% identical to the result I get using no filter at all, i.e., contaminated by
% strong line noise. Including padding makes no difference either, therefore
% the brackets.

dataset = dccnpath('/home/common/matlab/fieldtrip/data/test/bug1571/20101230_1010.cnt');

cfg                     = [];
cfg.channel      = {'EEG'};
cfg.datafile     = dataset;
cfg.headerfile   = dataset;
cfg.dataset      = dataset;
cfg.continuous   = 'yes';

unfilteredContinuousData  = ft_preprocessing(cfg);

cfg.dftfilter           = 'yes';
filteredContinuousData  = ft_preprocessing(cfg);

assert(~isequal(filteredContinuousData.trial{1}(:), unfilteredContinuousData.trial{1}(:)))

cfg = [];
cfg.channel = {'Fp1'};
cfg.method = 'mtmfft';
cfg.taper = 'hanning';
cfg.foi = 1:100;
fftFilt = ft_freqanalysis(cfg, filteredContinuousData);
figure;
subplot(2,1,1)
ft_singleplotER(cfg, fftFilt)

cfg = [];
cfg.channel = {'Fp1'};
cfg.method = 'mtmfft';
cfg.taper = 'hanning';
cfg.foi = 1:100;
fftUnfilt = ft_freqanalysis(cfg, unfilteredContinuousData);
subplot(2,1,2)
ft_singleplotER(cfg, fftUnfilt)

%% synthetic signal with wrong sampling rate

fsample = 512;

data = {};
data.fsample = fsample;
data.label = {'1', '2', '3'};
nchans = numel(data.label);
real_fsample = 512.01;
data.time{1} = 0:1/real_fsample:100;
data.trial{1} = rand(nchans, numel(data.time{1}));

cfg                     = [];
cfg.continuous          = 'yes';
cfg.dftfilter           = 'yes';
filteredData  = ft_preprocessing(cfg, data);

assert(~isequal(data.trial{1}, filteredData.trial{1}(:)))

fprintf('done.\n');


function results = vl_test_imarray(varargin)
% VL_TEST_IMARRAY
vl_test_init ;

function test_movie_rgb(s)
A = rand(23,15,3,4) ;
B = vl_imarray(A,'movie',true) ;

function test_movie_indexed(s)
cmap = get(0,'DefaultFigureColormap') ;
A = uint8(size(cmap,1)*rand(23,15,4)) ;
A = min(A,size(cmap,1)-1) ;
B = vl_imarray(A,'movie',true) ;

function test_movie_gray_indexed(s)
A = uint8(255*rand(23,15,4)) ;
B = vl_imarray(A,'movie',true,'cmap',gray(256)) ;

for k=1:size(A,3)
  vl_assert_equal(squeeze(A(:,:,k)), ...
                  frame2im(B(k))) ;
end

function test_basic(s)
M = 3 ;
N = 4 ;
width = 32 ;
height = 15 ;
for i=1:M
  for j=1:N
    A{i,j} = rand(width,height) ;
  end
end
A1 = A';
A1 = cat(3,A1{:}) ;
A2 = cell2mat(A) ;
B = vl_imarray(A1, 'layout', [M N]) ;
vl_assert_equal(A2,B) ;


function A = sup(A)
%SUP          Supremum of long (only with error term)
%
%  C = sup(A)
%
%For A being a long scalar or column vector with error term (see long),
%  output C is the long upper bound
%

% written  11/06/99     S.M. Rump
% modified 04/04/04     S.M. Rump  set round to nearest for safety
% modified 09/20/04     S.M. Rump  E.sign fixed
% modified 11/19/04     S.M. Rump  exponent update for error
% modified 04/06/05     S.M. Rump  rounding unchanged
% modified 07/25/05     S.M. Rump  result improved, thanks to
%                                      Nozomu Matsuda and Nobito Yamamoto
% modified 09/28/08     S.M. Rump  check for rounding to nearest improved
% modified 08/26/12     S.M. Rump  global variables removed
%

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

  INTLAB_LONG_ERROR = getappdata(0,'INTLAB_LONG_ERROR');

  if ~INTLAB_LONG_ERROR
    error('sup called for long without error term')
  end

  n = length(A.sign);
  E = long(A.error.mant);
  E.exponent = E.exponent + A.error.exp;

  A.error.mant = 0;
  A.error.exp = 0;

  A = A + E;
  index = ( A.error.mant~=0 );
  if any(index)
    %VVVV  A(index) = sup(A(index));
    s.type = '()'; s.subs = {index}; A = subsasgn(A,s,sup(subsref(A,s)));
    %AAAA  Matlab bug fix
  end

  if rndold
    setround(rndold)
  end


function op = tfocs_prox( f, prox_f, VECTOR_SCALAR )
% OP = TFOCS_PROX( F, PROX_F )
%   combines F and PROX_F into the appropriate TFOCS-compatible object.
%
%   F is any function (with known proximity operator),
%   and PROX_F is its proximity operator, defined as:
%
%   PROX_F( Y, t ) = argmin_X  F(X) + 1/(2*t)*|| X - Y ||^2
%
%   To use this, please see the file PROX_L1 as an example
%
%   The basic layout of a file like PROX_L1 is as follows:
%   ( for the function F(X) = q*||X||_1 )
%
%       function op = prox_l1(q)
%       op = tfocs_prox( @f, @prox_f )
%
%         function v = f(x)
%           ... this function calculates the function f ...
%         end
%         function v = prox_f(y,t)
%           ... this function calculates the prox-function to f ...
%         end
%       end
%
%   Note: in the above template, the "end" statements are very important.
%
% OP = TFOCS_PROX( F, PROX_F, 'vector')
%   will signal the routine that it is OK to allow "vector" stepsizes
%   (this corresponds to solving
%       PROX_F( Y, T ) = argmin_X F(X) + 1/2( X-Y )'*diag(1./T)*( X-Y )
%    where T is a vector of the same size as X ).
% ... = TFOCS_PROX( F, PROX_F, 'scalar' )
%   will throw an error if a vector stepsize is attempted. This is the default.
%
%   Also, users may wish to test their smooth function
%   with the script TEST_NONSMOOTH
%
%   See also prox_l1, test_nonsmooth

if nargin < 3 || isempty(VECTOR_SCALAR)
    VECTOR_SCALAR = 'scalar';
end

if strcmpi(VECTOR_SCALAR,'scalar')
    op = @fcn_impl;
elseif strcmpi(VECTOR_SCALAR,'vector')
    op = @fcn_impl_vector;
else
    error('bad option for VECTOR_SCALAR parameter');
end

function [ v, x ] = fcn_impl(x, t )
    if nargin < 1,
        error( 'Not enough arguments.' );
    end
    if nargin == 2,
        if numel(t) ~= 1, error('The stepsize must be a scalar'); end
        x  = prox_f(x,t);
    elseif nargout == 2,
        error( 'This function is not differentiable.' );
    end
    v = f(x);
end

function [ v, x ] = fcn_impl_vector(x, t )
    if nargin < 1,
        error( 'Not enough arguments.' );
    end
    if nargin == 2,
        x  = prox_f(x,t);
    elseif nargout == 2,
        error( 'This function is not differentiable.' );
    end
    v = f(x);
end

end

% TFOCS v1.2 by Stephen Becker, Emmanuel Candes, and Michael Grant.
% Copyright 2012 California Institute of Technology and CVX Research.
% See the file TFOCS/license.{txt,pdf} for full license information.


% SP_H1_ERROR: Evaluate the error in H^1 norm.
%
%   [errh1, errl2, errh1s] = sp_h1_error (space, msh, u, uex, graduex)
%
% INPUT:
%
%    space:   object defining the space of discrete functions (see sp_multipatch)
%    msh:     object defining the domain partition and the quadrature rule (see msh_multipatch)
%    u:       vector of dof weights
%    uex:     function handle to evaluate the exact solution
%    graduex: function handle to evaluate the gradient of the exact solution
%
% OUTPUT:
%
%     errh1:  error in H^1 norm
%     errl2:  error in L^2 norm
%     errh1s: error in H^1 seminorm
%
% Copyright (C) 2015 Rafael Vazquez
%
% 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 Octave; see the file COPYING.  If not, see
% <http://www.gnu.org/licenses/>.

function [errh1, errl2, errh1s] = sp_h1_error (space, msh, u, uex, graduex)

  if (space.npatch ~= msh.npatch)
    error ('The number of patches does not coincide')
  end

  if (numel(u) ~= space.ndof)
    error ('Wrong size of the vector of degrees of freedom')
  end

  for iptc = 1:msh.npatch
    if (isempty (space.dofs_ornt))
      u_ptc = u(space.gnum{iptc});
    else
      u_ptc = u(space.gnum{iptc}) .* space.dofs_ornt{iptc}.';
    end
    [error_h1(iptc), error_l2(iptc), error_h1s(iptc)] = ...
        sp_h1_error (space.sp_patch{iptc}, msh.msh_patch{iptc}, u_ptc, uex, graduex);
  end
  errl2 = sqrt (sum (error_l2 .* error_l2));
  errh1 = sqrt (sum (error_h1 .* error_h1));
  errh1s = sqrt (sum (error_h1s .* error_h1s));
end


function error_msg = mdp_check_square_stochastic( Z )

% mdp_check_square_stochastic     Check if Z is a square stochastic matrix
% Arguments ---------------------------------------------------------------
%   Z(SxS) = a matrix
% Evaluation --------------------------------------------------------------
%   error_msg = error message or '' if correct

% MDPtoolbox: Markov Decision Processes Toolbox
% Copyright (C) 2009  INRA
% Redistribution and use in source and binary forms, with or without modification,
% are permitted provided that the following conditions are met:
%    * Redistributions of source code must retain the above copyright notice,
%      this list of conditions and the following disclaimer.
%    * Redistributions in binary form must reproduce the above copyright notice,
%      this list of conditions and the following disclaimer in the documentation
%      and/or other materials provided with the distribution.
%    * Neither the name of the <ORGANIZATION> nor the names of its contributors
%      may be used to endorse or promote products derived from this software
%      without specific prior written permission.
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
% ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
% IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
% INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
% BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
% DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
% LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
% OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
% OF THE POSSIBILITY OF SUCH DAMAGE.

error_msg = '';

[s1 s2] = size(Z);
if s1 ~=s2
   error_msg = 'MDP Toolbox ERROR: Matrix must be square';
elseif max(abs(sum(Z,2)-ones(s2,1))) > 10^(-12)
   error_msg = 'MDP Toolbox ERROR: Row sums of the matrix must be 1';
elseif ~isempty(find (Z < 0))
   error_msg = 'MDP Toolbox ERROR: Probabilities must be non-negative';
end;


function f = simplify(f, tol)
%SIMPLIFY  Simplifies the smoothPart of a SINGFUN object.
%  F = SIMPLIFY(F) returns a SINGFUN which has a simplified smoothPart by
%  calling SIMPLIFY in SMOOTHFUN and has exponents less than 1 by absorbing
%  boundary roots with integer multiplicity into the smoothPart.
%
%  F = SIMPLIFY(F, TOL) does the same thing but uses TOL supplied by the user
%  and pass it to SIMPLIFY in SMOOTHFUN.

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

if ( nargin == 2 )
    f.smoothPart = simplify(f.smoothPart, tol);
elseif ( nargin == 1 )
    f.smoothPart = simplify(f.smoothPart);
end

% Replace the roots:
f = simplifyExponents(f);

end