clear;
clc;
%PESQ_LQ.exe +8000 CH01M001.dat CH01M001-white+10dB.dat > test.txt
addpath('bin');
addpath('bin\obj_evaluation')
path = '.\EnhancedSpeech\';
[enhancedFiles]=find_wav(path);
numEnhancedFile=size(enhancedFiles,1);
fid=fopen('PESQ.txt','wt');

cleanFilePath='.\cleanSpeech\TIMIT_1_TEST.wav';
cleanSig = audioread(cleanFilePath);
for i=1:numEnhancedFile
    enhancedFilePath=enhancedFiles(i,:);

    k=0;
    enhancedSig = audioread(enhancedFilePath);
    short = min(length(enhancedSig),length(cleanSig));

    cleanSig = cleanSig(1:1:short);
    enhancedSig = enhancedSig(1:1:short);

    audiowrite('temp_clean.wav',cleanSig,8000,'BitsPerSample',16);
    audiowrite('temp_enhanced.wav',enhancedSig,8000,'BitsPerSample',16);
    PESQ_O=pesq('temp_clean.wav','temp_enhanced.wav');
    delete('temp_clean.wav');
    delete('temp_enhanced.wav');

    fprintf(fid,'%s\t\t',enhancedFilePath(length(path)+2:end));
    fprintf(fid,'%s\n',num2str(PESQ_O));
end
fclose(fid);


classdef nme_bus3p_acp < mp.nme_bus3p & mp.form_acp

%   MATPOWER
%   Copyright (c) 2021, Power Systems Engineering Research Center (PSERC)
%   by Ray Zimmerman, PSERC Cornell
%
%   This file is part of MATPOWER.
%   Covered by the 3-clause BSD License (see LICENSE file for details).
%   See https://matpower.org for more info.

%     properties
%         name = 'bus3p';
%     end

    methods
        function obj = add_vvars(obj, nm, dm, idx)
            dme = obj.data_model_element(dm);
            nb = obj.nk;
            p = idx{1};

            %% prepare angle bounds for ref buses
            ref = dme.type == mp.NODE_TYPE.REF;
            va_lb = -Inf(nb, 1);
            va_ub =  Inf(nb, 1);
            vm_start = dme.(sprintf('vm%d_start', p));
            va_start = dme.(sprintf('va%d_start', p));
            va1_lb(ref) = va_start(ref);
            va1_ub(ref) = va_start(ref);

            if p == 1
                nm.init_indexed_name('va', 'Va3', {obj.nn});
                nm.init_indexed_name('vm', 'Vm3', {obj.nn});
            end
            nm.add_var('va', 'Va3', {p}, nb, va_start, va_lb, va_ub);
            nm.add_var('vm', 'Vm3', {p}, nb, vm_start, 0, 2);
        end
    end     %% methods
end         %% classdef


function dist = getDistPeopleHist(expidx)

p = rcnn_exp_params(expidx);

[annolistAll, imgidxs, rectidxs, rectIgnore, groupidxs]= getAnnolist(expidx);

distAll = [];
nPeople = [];
imgidxsAll = [];

for i = 1:length(imgidxs)
    fprintf('.');
    rect = annolistAll(imgidxs(i)).annorect;
    for g = 1:length(groupidxs{imgidxs(i)})
        ridxs_group = intersect(rectidxs{imgidxs(i)},groupidxs{imgidxs(i)}{g});
        if (~isempty(ridxs_group))
            dist = inf(length(ridxs_group),length(ridxs_group));
            for ridx1 = 1:length(ridxs_group)
                for ridx2 = 1:length(ridxs_group)
                    if ((ridx1 == ridx2) || ...
                            ~isfield(rect(ridxs_group(ridx1)), 'annopoints') || isempty(rect(ridxs_group(ridx1)).annopoints) || ...
                            ~isfield(rect(ridxs_group(ridx2)), 'annopoints') || isempty(rect(ridxs_group(ridx2)).annopoints))
                        continue;
                    end
                    dist(ridx1,ridx2) = util_get_min_dist(rect(ridxs_group(ridx1)),rect(ridxs_group(ridx2)));
                end
            end
            md = min(dist,[],2);
            distAll = [distAll; mean(md)];
            nPeople = [nPeople; length(ridxs_group)];
            imgidxsAll = [imgidxsAll; i];
        end
    end

    if (~mod(i, 100))
        fprintf(' %d/%d\n',i,length(imgidxs));
    end
end
fprintf(' done\n');

edges = 0:4:40;
[~,bin] = histc(distAll,edges);
dist = zeros(max(nPeople),length(edges));

for i = 1:length(nPeople)
    dist(nPeople(i),bin(i)+1) = dist(nPeople(i),bin(i)+1) + 1;
end

nPeopleHist = zeros(max(nPeople),1);
for i = 1:length(nPeopleHist)
    nPeopleHist(i) = sum(nPeople(nPeople == i));
end

figure(100); clf;

set(0,'DefaultAxesFontSize', 16)
set(0,'DefaultTextFontSize', 16)

bar3(dist);
set(gca,'XLim',[0 max(distAll)],'XTickLabel',edges);
ylabel('# people');
xlabel('avg min dist, px');
print(gcf, '-dpng', [p.plotsDir '/distPeople-expidx' num2str(expidx) '.png']);

figure(100); clf;
bar(nPeopleHist);
set(gca,'XTickLabel',1:length(nPeopleHist));
ylabel('# people');
text(0.5:length(nPeopleHist)-0.5,nPeopleHist+max(nPeopleHist)/50,num2str(nPeopleHist/sum(nPeopleHist)*100,'%1.1f'))
print(gcf, '-dpng', [p.plotsDir '/nPeople-expidx' num2str(expidx) '.png']);

    function minDist = util_get_min_dist(rect1,rect2)

        points1 = rect1.annopoints.point;
        points2 = rect2.annopoints.point;
        minDist = Inf;
        for idx1 = 1:length(points1)
            for idx2 = 1:length(points2)
                d = 1/rect1.scale*norm([points1(idx1).x points1(idx1).y] - [points2(idx2).x points2(idx2).y]);
                if (minDist > d)
                    minDist = d;
                end
            end
        end

    end

end


classdef BoundaryConditions < handle

    properties (GetAccess = public)
        dirichlet
        dirichlet_values
        free
        freeFields
        masterSlave
        periodic_free
        periodic_constrained
        neumann
        neumann_values
    end

    properties (Access = private)
        ndimf
        ndofs
        scale
        dirichletInput
        pointloadInput
    end

    methods (Access = public)

        function obj = BoundaryConditions(cParams)
            obj.init(cParams);
        end

        function compute(obj)
            [dirID, dirVals]     = obj.formatInputData(obj.ndimf, obj.dirichletInput);
            [neuID, neuVals]     = obj.formatInputData(obj.ndimf, obj.pointloadInput);
            obj.dirichlet        = dirID;
            obj.dirichlet_values = dirVals;
            obj.neumann          = neuID;
            obj.neumann_values   = neuVals;
            obj.free             = obj.computeFreeDOF();
        end

        function red = fullToReducedMatrix(obj, mat)
            switch obj.scale
                case 'MACRO'
                    red = obj.reduceMatrixDirichlet(mat);
                case 'MICRO'
                    red = obj.reduceMatrixPeriodic(mat);
            end
        end

        function red = fullToReducedVector(obj, vec)
            switch obj.scale
                case 'MACRO'
                    red = obj.reduceVectorDirichlet(vec);
                case 'MICRO'
                    red = obj.reduceVectorPeriodic(vec);
            end
        end

        function full = reducedToFullVector(obj, vec)
            switch obj.scale
                case 'MACRO'
                    full = obj.expandVectorDirichlet(vec);
                case 'MICRO'
                    full = obj.expandVectorPeriodic(vec);
            end
        end

        function changeBoundaryConditions(obj,neumannDOFs,neumannValues)
            obj.neumann        = neumannDOFs;
            obj.neumann_values = neumannValues;
        end

    end

    methods (Access = private)

        function init(obj,cParams)
            obj.scale          = cParams.scale;
            obj.ndofs          = cParams.ndofs; % Stokes
            obj.ndimf          = cParams.bc{1}.ndimf; % Elastic
            obj.initPeriodicMasterSlave(cParams);
            obj.initDirichletInput(cParams);
        end

        function initDirichletInput(obj, s)
            nfields = numel(s.bc);
            dirich  = [];
            neumann    = [];
            dirichVals = [];
            neumnnVals = [];
            free       = [];
            globalNdof = 0;
            for i = 1:nfields
                bc = s.bc{i};
                obj.dirichletInput = bc.dirichlet;
                obj.pointloadInput = bc.pointload;

                inD = bc.dirichlet;
                inN = bc.pointload;
                [idxD, valD] = obj.formatInputData(bc.ndimf,inD);
                [idxN, valN] = obj.formatInputData(bc.ndimf,inN);
                idxD = idxD + globalNdof;
                idxN = idxN + globalNdof;

                dirich     = [dirich; idxD];
                dirichVals = [dirichVals; valD];
                neumann    = [neumann; idxN];
                neumnnVals = [neumnnVals; valN];

                firstDof = globalNdof + 1;
                lastDof  = firstDof + bc.ndofs - 1;
                obj.freeFields{i} = setdiff(firstDof:lastDof,idxD);
                globalNdof = globalNdof+ bc.ndofs;
            end
            obj.dirichlet        = dirich;
            obj.dirichlet_values = dirichVals;
            obj.neumann          = neumann;
            obj.neumann_values   = neumnnVals;
            obj.free             = obj.computeFreeDOF();
        end

        function initPeriodicMasterSlave(obj, cParams)
            switch obj.scale
                case 'MICRO'
                    if isfield(cParams.bc, 'masterSlave')
                        obj.masterSlave = cParams.bc.masterSlave;
                    end
                    MS = obj.masterSlave;
                    if isempty(MS)
                        mesh = cParams.mesh;
                        MS = obj.computeMasterSlave(mesh.coord);
                        obj.masterSlave = MS;
                    end
                    obj.periodic_free = obj.computePeriodicNodes(MS(:,1));
                    obj.periodic_constrained = obj.computePeriodicNodes(MS(:,2));
            end
        end

        function perDof = computePeriodicNodes(obj,perNodes)
            nunkn = obj.ndimf;
            nlib = size(perNodes,1);
            perDof = zeros(nlib*nunkn,1);
            for iunkn = 1:nunkn
                indDof = nlib*(iunkn - 1) + [1:nlib];
                perDof(indDof,1) = obj.nod2dof(obj.ndimf, perNodes,iunkn);
            end
        end

        function free = computeFieldFree(obj, ndofs, dirich)
            free  = setdiff(1:ndofs,dirich);
        end

        function free = computeFreeDOF(obj)
            ndof  = obj.ndofs;
            cnstr = [obj.periodic_constrained;obj.dirichlet];
            free  = setdiff(1:ndof,cnstr);
        end

        function [dofs, vals] = formatInputData(obj, ndimf, data)
            dofs = [];
            vals = [];
            if ~isempty(data)
                inod = data(:,1);
                iunk = data(:,2);
                vals = data(:,3);
                dofs = obj.nod2dof(ndimf, inod,iunk);
            end
        end

        function idof = nod2dof(obj, ndimf, inode, iunkn)
            idof(:,1)= ndimf*(inode - 1) + iunkn;
        end

        function Ared = reduceMatrixDirichlet(obj,A)
%             fr = obj.computeGlobalFree();
            fr = obj.free';
            Ared = A(fr,fr);
        end

        function b_red = reduceVectorDirichlet(obj,b)
            fr = obj.free';
            b_red = b(fr);
        end

        function Ared = reduceMatrixPeriodic(obj,A)
            MS = obj.masterSlave;
            vF = obj.free;
            vP = obj.computePeriodicNodes(MS(:,1));
            vQ = obj.computePeriodicNodes(MS(:,2));
            vI = setdiff(vF,vP);

            A_II = A(vI,vI);
            A_IP = A(vI,vP) + A(vI,vQ); %Grouping P and Q nodal values
            A_PI = A(vP,vI) + A(vQ,vI); % Adding P  and Q equation
            A_PP = A(vP,vP) + A(vP,vQ) + A(vQ,vP) + A(vQ,vQ); % Adding and grouping

            Ared = [A_II, A_IP; A_PI, A_PP];
        end

        function b_red = reduceVectorPeriodic(obj,b)
            vF = obj.free;
            vP = obj.periodic_free;
            vQ = obj.periodic_constrained;
            vI = setdiff(vF,vP);
            b_I = b(vI);
            b_P = b(vP) + b(vQ);
            b_red = [b_I; b_P];
        end

        function b = expandVectorDirichlet(obj,bfree)
            dir = obj.dirichlet;
            uD  = obj.dirichlet_values;
            fr  = obj.free;
            nsteps = length(bfree(1,:));
            ndof = sum(obj.ndofs);
            uD = repmat(uD,1,nsteps);

            b = zeros(ndof,nsteps);
            b(fr,:) = bfree;
            if ~isempty(dir)
                b(dir,:) = uD;
            end
        end

        function b = expandVectorPeriodic(obj,bfree)
            vF = obj.free;
            vP = obj.periodic_free;
            vC = obj.periodic_constrained;
            vI = setdiff(vF,vP);
            b = zeros(obj.ndofs,1);
            b(vI) = bfree(1:1:size(vI,2));
            b(vP) = bfree(size(vI,2)+1:1:size(bfree,1));
            b(vC) = b(vP);
        end

        function MS = computeMasterSlave(obj, coord)
           mR = MasterSlaveRelator(coord);
           MS = mR.getRelation();
        end

    end
end


function msm_to_mm_coordinate ( output_filename, a, type, symmetry )

%*****************************************************************************80
%
%% MSM_TO_MM_COORDINATE writes a MATLAB Sparse Matrix to a Matrix Market file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    31 October 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string OUTPUT_FILENAME, the name of the file to which the information
%    should be written.
%
%    Input, sparse matrix A, the NROW by NCOL matrix, stored in MATLAB sparse
%    matrix format, which is to be written to the file.
%
%    Input, string TYPE, describes the arithmetic data type, as
%    'REAL', 'INTEGER', 'COMPLEX', or 'PATTERN'.
%
%    Input, string SYMMETRY, describes the symmetry type, as 'GENERAL',
%    'SYMMETRIC', 'SKEW-SYMMETRIC' or 'HERMITIAN'.
%
  if ( s_eqi ( type, 'REAL' ) )
    msm_to_mm_coordinate_real ( output_filename, a, symmetry );
  elseif ( s_eqi ( type, 'INTEGER' ) )
    msm_to_mm_coordinate_integer ( output_filename, a, symmetry );
  elseif ( s_eqi ( type, 'COMPLEX' ) )
    msm_to_mm_coordinate_complex ( output_filename, a, symmetry );
  elseif ( s_eqi ( type, 'PATTERN' ) )
    msm_to_mm_coordinate_pattern ( output_filename, a, symmetry );
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, 'MSM_TO_MM_COORDINATE - Fatal error!\n' );
    fprintf ( 1, '  Illegal value of TYPE.\n' );
    error ( 'MSM_TO_MM_COORDINATE - Fatal error!' );
  end

  return
end


function [Phase_3, Phase_2, Phase_1, UPhase_3] = learn_struct_bnpc(data,node_sizes,epsilon,star)
% G = learn_struct_bnpc(Data,node_sizes,epsilon,star)
%
% Data(i,m) is node i in case m.
% node_sizes and epsilon are optionnals.
% star = 0 to use try_to_separate_B instead of try_to_separate_B_star
%
% see "Learning bayesian Networks from Data: A Efficient Approach Based on Information Theorie"
%     Jie Cheng, David Bell and Weird Liu.
%
% Things to do : rewrite function orient_edges !
%                ! sometimes it causes crashes !
%
% V0.91 : 18 sept 2003 (olivier.francois@insa-rouen.fr)

verbose=1;
%if nargin < 5, mwst=0; end
if nargin < 4, star=1; end
if nargin < 3, epsilon=0.05; end
if nargin < 2, node_sizes=max(data'); end

if verbose
  fprintf('================== phase I : \n');
end
tmp1=cputime;
[Phase_1 II JJ score_mat score_mat2] = phaseI(data, node_sizes, epsilon);
tmp1=cputime-tmp1;

if verbose
  fprintf('Execution time : %2.5f\n',tmp1);
  fprintf('\n================== phase II : \n');
end
tmp1=cputime;
Phase_2 = phaseII(Phase_1, data, node_sizes, epsilon, II, JJ, score_mat);
tmp1=cputime-tmp1;

if verbose
  fprintf('Execution time : %2.5f\n',tmp1);
  fprintf('\n================== phase III : \n');
end
tmp1=cputime;
[Phase_3 UPhase_3]  = phaseIII(Phase_2, data, node_sizes, epsilon, score_mat2, star);
tmp1=cputime-tmp1;
if verbose
  fprintf('Execution time : %2.5f\n',tmp1);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [G, II, JJ, score_mat, sc2] = phaseI(data,node_sizes,alpha)
% [G, II , JJ, score_mat, s2] = phaseI(data,node_sizes,epsilon)
%
% G is an acyclic graph
% [II JJ] is the list of important edges not processed in phase I (for phase II)
% score_mat is the mutual information score matrix
%
% data(i,m) is node i in case m.
% alpha is the significant level for CI tests ( default=0.05 ).
% node_sizes is the vector of sizes ( default=max(data') ).
%
% see "Learning bayesian Networks from Data: A Efficient Approach Based on Information Theorie"
%     Jie Cheng, David Bell and Weird Liu.

% 0.
if nargin < 3, alpha=0.05; end
if nargin < 2, node_sizes=max(data'); end
[N m] = size(data);
score_mat = zeros(N);
edges=0;

% 1.
G = zeros(N);
L=[];

% 2. Use of Chi2 instead of MI ... allow using a confidence level alpha instead of an arbitrary epsilon
for i=1:(N-1)
  for j=(i+1):N
    [I score_mat(i,j)] = cond_indep_chisquare(i,j,[],data,'LRT',alpha,node_sizes);
  end
end
sc2=score_mat;

[tmp ordre]=sort(-score_mat(:));
ordre2=ordre(find(-tmp>alpha));
[II JJ]=ind2sub([N N],ordre2);

pointer=1 ;
fini=length(II);

% 3.
edges=2;
for pointer=1:min(2,fini),
  %fprintf('%d-%d\n',II(pointer),JJ(pointer));
  G(II(pointer),JJ(pointer))=1;
  G(JJ(pointer),II(pointer))=1;
  score_mat(II(pointer),JJ(pointer))=-inf;
end

pointer=min(2,fini);
arret=0;

while pointer<fini & ~arret
  % 4.
  pointer=pointer+1;
  C = ~reachability_graph(G);
  if C(II(pointer),JJ(pointer))
    %fprintf('%d-%d\n',II(pointer),JJ(pointer));
    G(II(pointer),JJ(pointer))=1;
    G(JJ(pointer),II(pointer))=1;
    score_mat(II(pointer),JJ(pointer))=-inf;
    edges=edges+1;
    if edges==N-1
      arret=1;
    end
  end

  % 5.
end

[tmp ordre]=sort(-score_mat(:));
ordre2=ordre(find(-tmp>alpha));
[II JJ]=ind2sub([N N],ordre2);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function G = phaseII(G1,data,node_sizes,alpha,II, JJ, score_mat)
% G = phaseII(G1,data,node_sizes,epsilon,II,JJ, score_mat)
%
% G1, II, JJ,score_mat are given by phaseI.
% data(i,m) is node i in case m.
% node_sizes is the vector of sizes ( default=max(data') ).
% alpha is the significant level for CI tests ( default=0.05 ).
%
% see "Learning bayesian Networks from Data: A Efficient Approach Based on Information Theorie"
%     Jie Cheng, David Bell and Weird Liu.

st{1}='added';
st{2}='';
% 0.
[N m] = size(data);

G=G1;

% 6.
II=II(end:-1:1);
JJ=JJ(end:-1:1);

pointer=length(II);

while pointer>0
  % 7.
  trysep = try_to_separate_A(G,II(pointer),JJ(pointer),data,alpha,node_sizes);
  %fprintf('Try to separate %d and %d : %s\n',II(pointer),JJ(pointer),st{trysep+1});
  if ~trysep
    G(II(pointer),JJ(pointer))=1;
    G(JJ(pointer),II(pointer))=1;
    %fprintf('%d-%d\n',II(pointer),JJ(pointer));
  end
  % 8.
  pointer=pointer-1;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [G,U] = phaseIII(G1,data,node_sizes,alpha,s2,star)
% [G] = phaseIII(G1,data,node_sizes,alpha,s2,star)
%
% data(i,m) is node i in case m.
% if star~=0, use try_to_separate_B_star instead of try_to_separate_B (default star=1).
% G is the non-oriented graph and G1 the oriented result.
%
% see "Learning bayesian Networks from Data: A Efficient Approach Based on Information Theorie"
%     Jie Cheng, David Bell and Weird Liu.

% 0.
if nargin < 2, disp('Not enough arguments');return; end
if nargin < 3, node_sizes=max(data'); end
if nargin < 4, alpha = 0.05; end
if nargin < 5, star=1; end
G=G1;
N=length(G);
% reachability_matrix of G
M = expm(full(G)) - eye(length(G)); M = (M>0);

% 9.
fprintf('Thinning - separateA\n');

% Edges are examined in the inverse order of their Chi2 (or MI) score
s2(find(~G))=0;
[tmp ordre]=sort(s2(:));
ordre2=ordre(find(tmp>0));
[I J]=ind2sub([N N],ordre2);
ii=1:length(I);
for i=ii,
  %fprintf('%d-%d : ',I(i),J(i));
  G(I(i),J(i))=0;
  G(J(i),I(i))=0;
  trysep = try_to_separate_A(G,I(i),J(i),data,alpha,node_sizes);

  if ~trysep,
    G(I(i),J(i))=1;
    G(J(i),I(i))=1;
    %fprintf(' keep\n');
    %else
    %fprintf('delete\n');
  end
end

% 10.
fprintf('Thinning - separateB'); if star; fprintf('star'); end; fprintf('\n');
s2(find(~G))=0;
[tmp ordre]=sort(s2(:));
ordre2=ordre(find(tmp>0));
[I J]=ind2sub([N N],ordre2);
ii=1:length(I);
for i=ii,
  %fprintf('%d-%d : ',I(i),J(i));
  G(I(i),J(i))=0; G(J(i),I(i))=0;
  if star==0
    trysep = try_to_separate_B(G,I(i),J(i),data,node_sizes,alpha);
  else
    trysep = try_to_separate_B_star(G,I(i),J(i),data,node_sizes,alpha);
  end
  if ~trysep,
    G(I(i),J(i))=1; G(J(i),I(i))=1;
    %fprintf(' keep\n');
    %else
    %fprintf('delete\n');
  end
end

%11.
fprintf('Thinning - orient_edges\n');
U=G;
G=orient_edges(U,data,node_sizes,alpha);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [I, N1, N2] = try_to_separate_A(G,node1,node2,data,alpha,node_sizes)
% [I, N1, N2] = try_to_separate_A(G,node1,node2,data,alpha,node_sizess)
%
% G is the current partially directed graph.
% I is a boolean : I=1 <==> separated.
% N1 : neighbors of node1 that are on an adjacency path between node1 and node2 (ditto for N2).
%
% see "Learning bayesian Networks from Data: A Efficient Approach Based on Information Theorie"
%     Jie Cheng, David Bell and Weird Liu.

% 0.
if node1==node2 | length(G)<2
  disp('Error: Check your arguments in try_to_separate_A.');I=0; return
end
N=size(data,1);
if nargin==4, alpha=0.05; node_sizes=max(data'); end
if nargin==5, node_sizes=max(data'); end

% 1.
N1=find(G(node1,:)==1);N01=N1;
GG1=G(setdiff(1:N,node1),setdiff(1:N,node1));
node22=node2-(node2>node1);
% reachability_matrix of GG1
M = expm(full(GG1)) - eye(length(GG1)); M = (M>0);
% N1 is the neighbors of node1 that are on the adjacency between node1 and node2
for i=N1
  j=i-(i>node1);
  if M(j,node22)~=1, N01=setdiff(N01,i); N1=setdiff(N1,i); end
  % 2.
  if ~G(node1,i), N1=setdiff(N1,i); end
end

N2=find(G(node2,:)==1);N02=N2;
GG2=G(setdiff(1:N,node2),setdiff(1:N,node2));
node12=node1-(node2<node1);
% reachability_matrix of GG2
M = expm(full(GG2)) - eye(length(GG2)); M = (M>0);
% N2 is the neighbors of node2 that are on the adjacency between node1 and node2
for i=N2
  j=i-(i>node2);
  if M(node12,j)~=1, N02=setdiff(N02,i); N2=setdiff(N2,i); end
  % 2.
  if ~G(node2,i), N2=setdiff(N2,i); end
end

%fprintf('%d : N1=',node1); fprintf('%d',N1); fprintf('\n');
%fprintf('%d : N2=',node2); fprintf('%d',N2); fprintf('\n');
% 3.
if length(N1)>length(N2), tmp=N1; N1=N2; N2=tmp; clear tmp, end
% 4.
C=N1;
for test=1:2
  if test==2, C=N2; end
  % 5.
  [I v1] = cond_indep_chisquare(node1,node2,C,data,'LRT',alpha,node_sizes);
  if I, %fprintf('%d-%d separated (%2.5f) by C=',node1,node2,v1); fprintf('%d',C); fprintf('\n');
    return,
    %else
    %fprintf('%d-%d not separated (%2.5f) by C=',node1,node2,v1); fprintf('%d',C); fprintf('\n');
  end;

  % 6.
  step6=1;
  while step6
    step6=0;
    if length(C)>=1
      v=[];
      for i=C
	Ci = setdiff(C,i);
	[I(i) v(i)] = cond_indep_chisquare(node1,node2,Ci,data,'LRT',alpha,node_sizes);
      end
      [vm ind] = min(v);

      % 7.
      if I(ind)
	I = 1; return
      else
	if vm < v1
	  v1 = vm;
	  C = setdiff(C,ind);
	  % goto step 6.
	  step6 = 1;
	end
      end
    end

    % 8.
    if test==2, I=0; return, end
  end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function I = try_to_separate_B(G,node1,node2,data,node_sizes,alpha,N1,N2)
% I = try_to_separate_B(G,node1,node2,data,node_sizes,epsilon,N1,N2)
%
% G is the current partially directed graph.
% data(i,m), node i in case m.
% node_sizes is the vector of size of the attributs in data ( default max(data') )
% N1 (optionnal) is the neighbors of node1 that are on an adjacency path between node1 and node2 (ditto for N2).
% I is a boolean : I+1 <==> separated.
%
% see "Learning bayesian Networks from Data: A Efficient Approach Based on Information Theorie"
%     Jie Cheng, David Bell and Weird Liu.

% 0.
if node1==node2 | length(G)<2
  disp('Error: Verify your arguments in try_to_separate_B.');I=0; return
end
if nargin < 4,
  disp('Error : not enougth arguments'); I=0; return;
end
N=size(data,1);

% 1.
if nargin < 8
  N1=find(G(node1,:)==1);
  GG1=G(setdiff(1:N,node1),setdiff(1:N,node1));
  node22=node2-(node2>node1);
  M = expm(full(GG1)) - eye(length(GG1)); M = (M>0);
  for i=N1
    j=i-(i>node1);
    if M(j,node22)~=1, N1=setdiff(N1,i); end
  end
  N2=find(G(node2,:)==1);
  GG2=G(setdiff(1:N,node2),setdiff(1:N,node2));
  node12=node1-(node2<node1);
  M = expm(full(GG2)) - eye(length(GG2)); M = (M>0);
  for i=N2
    j=i-(i>node2);
    if M(node12,j)~=1, N2=setdiff(N2,i); end
  end
end
if nargin < 6, alpha=0.05; end
if nargin < 5, node_sizes=max(data'); end
M = expm(full(G)) - eye(length(G)); M = (M>0);

% 2.
N1b=[];
for i=N1
  NN1=find(G(i,:)==1);
  for j=NN1
    if M(i,j)~=1 & ~ismember(j,N1), N1b=union(N1b,j); end
  end
end

% 3.
N2b=[];
for i=N2
  NN2=find(G(i,:)==1);
  for j=NN2
    if M(i,j)~=1 & ~ismember(j,N2), N2b=union(N2b,j); end
  end
end

% 4.
if length(union(N1,N1b)) < length(union(N2,N2b))
  C=union(N1,N1b);
else
  C=union(N2,N2b);
end

% 5.
continu=1;
while continu
  l=length(C);
  %fprintf('%d',continu);
  [I v] = cond_indep_chisquare(node1,node2,C,data,'LRT',alpha,node_sizes);
  if I==1; return, elseif l<2, I=0; return, end

  % 6.
  Cb=C;
  for i=1:l
    Ci=setdiff(C,C(i));
    [I vi] = cond_indep_chisquare(node1,node2,Ci,data,'LRT',alpha,node_sizes);
    e = (v+1)/3;    % e is a small value...
	if I==1,return, elseif vi<v+e, Cb=setdiff(Cb,C(i)); end
  end

  % 7.
  if length(Cb) < l, C=Cb; else continu==0; I=0; return; end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function I = try_to_separate_B_star(G,node1,node2,data,node_sizes,alpha,N1,N2)
% I = try_to_separate_B_star(G,node1,node2,data,epsilon,node_sizess)
%
% G is the current partially directed graph.
% I is a boolean.
% N1 is the neighbors of node1 that are on an adjacency path between node1 and node2 (ditto for N2).
%
% see "Learning bayesian Networks from Data: A Efficient Approach Based on Information Theorie"
%     Jie Cheng, David Bell and Weird Liu.

% 0.
if node1==node2 | length(G)<2
  disp('Error: Verify your arguments in try_to_separate_B_star.');I=0; return
end
if nargin < 4,
  disp('Error : not enougth arguments');I=0; return;
end
N=size(data,1);

% 1.
if nargin < 8
  N1=find(G(node1,:)==1);
  GG1=G(setdiff(1:N,node1),setdiff(1:N,node1));
  node22=node2-(node2>node1);
  M = expm(full(GG1)) - eye(length(GG1)); M = (M>0);
  for i=N1
    j=i-(i>node1);
    if M(j,node22)~=1, N1=setdiff(N1,i); end
    % 2.
    if ~G(node1,i), N1=setdiff(N1,i); end
  end
  N2=find(G(node2,:)==1);
  GG2=G(setdiff(1:N,node2),setdiff(1:N,node2));
  node12=node1-(node2<node1);
  M = expm(full(GG2)) - eye(length(GG2)); M = (M>0);
  for i=N2
    j=i-(i>node2);
    if M(node12,j)~=1, N2=setdiff(N2,i); end
    % 2.
    if ~G(node2,i), N2=setdiff(N2,i); end
  end
end
if nargin < 6, alpha=0.05; end
if nargin < 5, node_sizes=max(data'); end

% 3.
if length(N1)>length(N2), tmp=N1; N1=N2; N2=tmp; end

% 4.
C=N1;
l=length(C);
I=0;

% 5.
for test=1:2
  continu=1;
  %test
  if test==2 & ~isempty(N2)
    C=N2; l=length(C); IsInCi=zeros(1,l); IsInCi(l)=1;
  else IsInCi=zeros(1,l);
  end
  s=ones(1,l);
  % Pour tous les sous-ensemble Ci de C :
  while continu & ~isempty(C)
    Ci = setdiff(C.*IsInCi,0);
    [I vi] = cond_indep_chisquare(node1,node2,Ci,data,'LRT',alpha,node_sizes);
    if I, %fprintf('%d-%d separated (%2.5f) by C=',node1,node2,vi); fprintf('%d',Ci); fprintf('\n');
      return,
      %else
      %fprintf('%d-%d not separated (%2.5f) by C=',node1,node2,vi); fprintf('%d',Ci); fprintf('\n');
    end;
    %    if I, return, end

    if IsInCi==s, continu=0;
    else
      IsInCi(l)=IsInCi(l)+1;

      notOK=1; i=l;
      while notOK & i>1
	if IsInCi(i)>s(i), IsInCi(i)=0; IsInCi(i-1)=IsInCi(i-1)+1; else notOK=0; end
	i=i-1;
      end
    end
  end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function G1 = orient_edges(G,data,node_sizes,alpha)
% G1 = orient_edges(G,data,node_sizes)
%
% G is the partially directed graph.
% data(i,m), node i in case m.
% node_sizes is the vector of size of the attributs in data ( default max(data') )
%
% see "Learning bayesian Networks from Data: A Efficient Approach Based on Information Theorie"
%     Jie Cheng, David Bell and Weird Liu.

% 0.
if nargin < 4, alpha=0.05; end
if nargin < 3, node_sizes=max(data'); end
if nargin < 2, disp(' Require at least two arguments.'); return, end
N=length(G);
G1=G;

% 1.
[Lnode1 Lnode2]=find(triu(1-triu(G),1)); %[Lnode1 Lnode2]=ind2sub([N N],find(triu(1-triu(G),1)));
for ii = 1:length(Lnode1),
  node1=Lnode1(ii);
  node2=Lnode2(ii);
  %fprintf('%d %d\n',node1,node2);
  N1 = find(G(node1,:)==1);
  N2 = find(G(node2,:)==1);
  if ~isempty(intersect(N1,N2))
    %fprintf('V1='); fprintf('%d ',N1); fprintf('\n');
    %fprintf('V2='); fprintf('%d ',N2); fprintf('\n');
    GG1 = G(setdiff(1:N,node1),setdiff(1:N,node1));
    node22 = node2-(node2>node1);
    % reachability_matrix of GG1
    M = expm(full(GG1)) - eye(length(GG1)); M = (M>0);
    % N1 is the neighbors of node1 that are on the adjacency between node1 and node2
    for i = N1
      j = i-(i>node1);
      if M(j,node22)~=1, N1=setdiff(N1,i);
      end
    end
    GG2 = G(setdiff(1:N,node2),setdiff(1:N,node2));
    node12 = node1-(node2<node1);
    % reachability_matrix of GG2
    M = expm(full(GG2)) - eye(length(GG2)); M = (M>0);
    % N2 is the neighbors of node2 that are on the adjacency between node1 and node2
    for i=N2
      j = i-(i>node2);
      if M(node12,j)~=1, N2=setdiff(N2,i); end
    end
    %fprintf('%d %d\n',node1,node2);
    %fprintf('N1='); fprintf('%d ',N1); fprintf('\n');
    %fprintf('N2='); fprintf('%d ',N2); fprintf('\n');

    % 2.
    M = expm(full(G)) - eye(length(G)); M = (M>0);
    N1b=N1;
    for i=N1
      NN1 = find(G(i,:)==1);
      for j=NN1
	if M(i,j)~=1 & ~ismember(j,N1), N1b=union(N1b,j); end
      end
    end
    %fprintf('N1''='); fprintf('%d ',N1b); fprintf('\n');

    % 3.
    N2b=N2;
    for i=N2
      NN2 = find(G(i,:)==1);
      for j=NN2
	if M(i,j)~=1 & ~ismember(j,N2), N2b=union(N2b,j); end
      end
    end
    %fprintf('N2''='); fprintf('%d ',N2b); fprintf('\n');

    % 4.
    if length(N1b) < length(N2b)
      C = N1b;
    else
      C = N2b;
    end
    %l=length(C);
    %fprintf('C='); fprintf('%d ',C); fprintf('\n');

    % 7.
    step5=1;
    while step5
      step5=0;
      %fprintf('.');
      % 5.
      l=length(C);
      [I v] = cond_indep_chisquare(node1,node2,C,data,'LRT',alpha,node_sizes);
      %fprintf('C='); fprintf('%d ',C);
      %fprintf(': %d %2.5f\n',I,v);

      step8=0;
      if I==1 & v~=0 % v < epsilon
	step8=1;
      else
	if  l==1
	  G1(C,node1)=0; G1(C,node2)=0;
	  fprintf('%d -> %d <- %d\n',node1,C,node2);
	  step8=1;
	end
      end
      %fprintf('%d\n',step8);

      % 6.
      if ~step8
	Cb=C;
	for i=1:l
	  Ci=setdiff(C,C(i));
	  [I vi] = cond_indep_chisquare(node1,node2,Ci,data,'LRT',alpha,node_sizes);
	  % e = (v+1)/3;    % e is a small value...
	  if I==1 % vi < v+e
	    Cb=setdiff(Cb,C(i));
	    if ismember(C(i),N1) & ismember(C(i),N2)
	      G1(C(i),node1)=0; G1(C(i),node2)=0;
	      fprintf('%d -> %d <- %d\n',node1,C(i),node2);
	    end
	    if I==1 % vi < epsilon
	      step8=1;
	    end
	  end
	end % for
      end % if

      % 7.
      if ~step8
	if length(Cb) < length(C), C=Cb; end
	if length(C) > 0, step5==1; end
      end
    end % while step5
    % step8 : passer � la paire de noeud suivant
    %fprintf('\n');
    %else
    %fprintf(' No common neighbor\n');
  end % if
end % for

% 11.
step9=0;
fprintf('Infering directions ');
test = pdag_to_dag(G1);
while ~isdag(test) %& step9<N
  step9=step9+1;
  %if ~isempty(test)
    %fprintf('.');
    % 9.
    for a=1:N, for b=1:N, for c=1:N,
	  if a~=b & b~=c & c~=a
	    if G1(a,b)==1 & G1(b,a)==0
	      %fprintf('%d -> %d ... \n',a,b);
	      if G1(b,c)==1 & G1(c,b)==1
		if G1(a,c)+G1(c,a)==0,
		  G1(c,b)=0;
		  fprintf('%d -> %d (9)\n',b,c);
		end
	      end
	    end
	  end
    end, end, end

    % 10.
    for a=1:N-1, for b=a+1:N
	if G1(a,b)==1 & G1(b,a)==1
	  GGG1=xor(G1,G1'); % matrice des arcs orient�s de G1
	  M = expm(full(GGG1)) - eye(length(GGG1)); M = (M>0);
	  if M(a,b)==1,
	    G1(b,a)=0;
	    fprintf('%d -> %d (10)\n',a,b);
	  end
	end
    end, end

      test = pdag_to_dag(G1);
      if isempty(test), G1=return_one_edge(G1); end
  %else
  %  G1, return,
  %end
end % while 11.
G1 = pdag_to_dag(G1);
fprintf('%d boucles\n',step9);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function b = isdag(G)
b = sum(sum(G.*G'));        % How many undirected arcs ? (x2)
b=~b & ~isempty(G);
if b
  M = expm(full(G)) - eye(length(G)); M = (M>0);
  b = b & find(sum(sum(eye(length(G)).*M))); % is there no cycle ?
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function G=return_one_edge(G)
N=length(G); fam=[]; node2=[];
permnode = randperm(5); i=0; %fprintf('rev\n');
while isempty(fam) | isempty(node2) | i==N
 i=i+1;
 node = permnode(i); %node = ceil(rand(1)*N);
 fam=find(G(node,:)==1);
 par=find(G(:,node)==1);
 fam = myunion(fam, par);
 if ~isempty(fam)
  node2 = fam(ceil(rand(1)*length(fam)));
  par2=find(G(:,node)==1);
  if ~isempty(intersect(par2, node)), node2=[]; end
 end
end
if isempty(myintersect(node, par2)),
 G(node, node2)=0;
 G(node2, node)=1;
 fprintf('%d -> %d (Rev)\n',node, node2);
else
 G(node, node2)=1;
 G(node2, node)=0;
 fprintf('%d -> %d (Rev)\n',node2, node);
end


alpha=1;
beta=0.5;
gamma=0.00001;
lambda=0.00001;
numK=10;
maxIter=100;
flag=1;
inputPath='D:/chengxh/matlab/TLLibrary64/CRA/data/img/inputData.mat';
% CRA_enterFunc(alpha,beta,gamma,lambda,numK,maxIter,flag,inputPath)

alpha=1;
beta=0.5;
gamma=0.00001;
numK=10;
numC=2;
maxIter=100;
flag=1;
TrainXPath='D:/chengxh/matlab/TLLibrary/TLDA/data/img/TrainData.mat';
TrainYPath='D:/chengxh/matlab/TLLibrary/TLDA/data/img/TrainLabel.mat';
TestXPath='D:/chengxh/matlab/TLLibrary/TLDA/data/img/TestData.mat';
TestYPath='D:/chengxh/matlab/TLLibrary/TLDA/data/img/TestLabel.mat';
InputPath='TLDA/data/img/inputData.mat'
% TLDA_enterFunc(alpha,beta,gamma,numK,maxIter,flag,InputPath)

alpha=1;
beta=0.5;
gamma=0.00001;
lambda=0.00001;
numK=10;
sourceSize='166 200 185';
maxIter=10;
flag=1;
TrainXPath='D:/chengxh/matlab/TLLibrary/CRA/data/img/TrainData.mat';
TrainYPath='D:/chengxh/matlab/TLLibrary/CRA/data/img/TrainLabel.mat';
TestXPath='D:/chengxh/matlab/TLLibrary/CRA/data/img/TestData.mat';
TestYPath='D:/chengxh/matlab/TLLibrary/CRA/data/img/TestLabel.mat';
%CRA_enterFunc(alpha,beta,gamma,lambda,numK,sourceSize,maxIter,flag,TrainXPath,TrainYPath,TestXPath,TestYPath)

alpha=2.4;
beta=2.4;
numCluster=15;
maxIter=200;
TrainXPath='MTrick/data/TrainData.mat';
TrainYPath='MTrick/data/TrainLabel.mat';
TestXPath='MTrick/data/TestData.mat';
TestYPath='MTrick/data/TestLabel.mat';
inputPath='data.mat';
% result = MTrick_enterFunc(alpha,beta,numCluster,maxIter,inputPath);

numIdentical=20;
numAlike=20;
numDistinct=10;
numIter=10;
inputPath='data.mat';
HIDC_enterFunc(numIdentical,numAlike,numDistinct,numIter,inputPath)

numIdentical=20;
numAlike=20;
numDistinct=10;
numIter=100;
sourceSize = '1976';
targetSize = '1977';
TrainXPath='TriTL/data/TrainData.mat';
TrainYPath='TriTL/data/TrainLabel.mat';
TestXPath='TriTL/data/TestData.mat';
TestYPath='TriTL/data/TestLabel.mat';
InputPath='data.mat';
% TriTL_enterFunc(numIdentical,numAlike,numDistinct,numIter,InputPath)

numCluster=64;
maxIter=10;
inputPath='data.mat';
% CDPLSA_enterFunc(numCluster,maxIter,inputPath)

numIdentical=20;
numAlike=20;
numDistinct=10;
numIter=500;
inputPath='data.mat';
% HIDC_enterFunc(numIdentical,numAlike,numDistinct,numIter,inputPath)

alpha=0.4;
beta=15;
gamma=0.12;
threshold=0.1;
inputPath='D:/chengxh/matlab/TLLibrary64/IHR/data/inputData.mat';
neighborPath='D:/chengxh/matlab/TLLibrary64/IHR/data/KneighborFile.txt';
%IHR_enterFunc(alpha,beta,gamma,threshold,inputPath,neighborPath)

inputPath='D:/chengxh/matlab/TLLibrary64/MAMUDA/data/inputData.mat';
ite1=4;
ite2=4;
itermediateD=50;
reducedD=50;
sharedD=50;
% meanF1=MAMUDA_enterFunc(inputPath,ite1,ite2,itermediateD,reducedD,sharedD);

inputPath='D:/chengxh/matlab/TLLibrary64/CSL_MTMV/data/inputData.mat';
ite=20;
h=15;
alpha=0.0039;
beta=0.0078;
gamma=0.0039;
% meanF1=CASO_MVMT_enterFunc(inputPath,ite,h,alpha,beta,gamma);

inputPath='CCR3/data/inputData.mat';
gamma=150;
%results=CCR3_enterFunc(gamma, inputPath);


close all; clear all; clc;

audio = audioload();

file = 'text.txt';
fid  = fopen(file, 'r');
text = fread(fid,'*char')';
fclose(fid);

msg = dsss_dec(audio.data, 8*length(text));
err = BER(text,msg);
nc  = NC(text, msg);

fprintf('Text: %s\n', msg);
fprintf('BER : %d\n', err);
fprintf('NC  : %d\n', nc);


%-------------------------------------------------------------------------------------------------------------------%
%
% IB2d is an Immersed Boundary Code (IB) for solving fully coupled non-linear
% 	fluid-structure interaction models. This version of the code is based off of
%	Peskin's Immersed Boundary Method Paper in Acta Numerica, 2002.
%
% Author: Nicholas A. Battista
% Email:  nick.battista@unc.edu
% Date Created: May 27th, 2015
% Institution: UNC-CH
%
% This code is capable of creating Lagrangian Structures using:
% 	1. Springs
% 	2. Beams (*torsional springs)
% 	3. Target Points
%	4. Muscle-Model (combined Force-Length-Velocity model, "HIll+(Length-Tension)")
%
% One is able to update those Lagrangian Structure parameters, e.g., spring constants, resting %%	lengths, etc
%
% There are a number of built in Examples, mostly used for teaching purposes.
%
% If you would like us to add a specific muscle model, please let Nick (nick.battista@unc.edu) know.
%
%--------------------------------------------------------------------------------------------------------------------%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: Plots the Lagrangian structure with:
%           (1): the background velocity field
%           (2): the Lagrangian structure itself
%           (3): the vorticity field in a colormap
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [loc, diffy] =  please_Plot_Results(ds,X,Y,U,V,vort,uMag,p,C,chiX,chiY,lagPlot,velPlot,vortPlot,pressPlot,uMagPlot,conPlot,firstPrint,loc,diffy,spacing)

%X,Y:  (x,y) values
%U,V:  x-directed, y-directed velocities respectively
%vort: vorticity
%uMag: magnitude of velocity
%p:    pressure

%FLAGS FOR PLOTTING:
%pressPlot - if you want pressure plot = 1
%uMagPlot  - if you want mag. velocity plot = 1
%vortPlot  - if you want vorticity plot = 1
%velPlot   - if you want velocity plot = 1
%lagPlot   - if you want lag. point ONLY plot = 1
%conPlot   - if you want concentration plot =1
%
% Assumption: Assuming chiX and chiY are column vectors
% Assumption: Assuming chiX(i+1)-chiX(i) < .5 and chiY(i+1)-chiY(i) < .5, for all points that don't cross the boundary
%
% This script has been adapted from the Mat-IB code by Hiens and Stockie, 2014.
%

Lx = X(1,end)+X(1,2);
Ly = Y(end,1)+Y(2,1);

%Shift so inside of interval [0,Lx] or [0,Ly]
chiX = mod(chiX,Lx);
chiY = mod(chiY,Ly);

%Connect Geometry Appropriately At Beginning Of Simulation then Store it!
if firstPrint == 1
    diffX = abs([chiX(2:end);chiX(1)]-chiX);
    diffY = abs([chiY(2:end);chiY(1)]-chiY);

    locX = find(diffX > spacing ); % assuming x value can't change more than Lx/2 (without crossing boundary)
    locY = find(diffY > spacing ); % assuming y value can't change more than Ly/2 (without crossing boundary)
    loc =  sort(unique([locX;locY]));

    diffy = sqrt( (chiX(end)-chiX(1) )^2 + ( chiY(end)-chiY(1) )^2 );
end

clf; %Clear previous plots :)

[N1,N2,num_con]=size(C);
figure(1)
numPlots = lagPlot+velPlot+vortPlot+pressPlot+uMagPlot+conPlot+(num_con-1);

ct = 1;

% % % % % PLOTS LAGRANGIAN POINTS ONLY (if selected) % % % % %

if lagPlot == 1
    subplot(1,numPlots,ct)
    axis([0 Lx 0 Ly]);
    title('LAGRANGIAN PTS');
    xlabel('x'); ylabel('y');
    hold all;

    loc = [0;loc;length(chiX)];
    for i=2:length(loc)
       plot(chiX(loc(i-1)+1:loc(i)),chiY(loc(i-1)+1:loc(i)),'m','LineWidth',3);
    end
    if diffy < 5*ds
        xTemp = [chiX(1) chiX(end)];
        yTemp = [chiY(1) chiY(end)];
        plot(xTemp(1:2),yTemp(1:2),'m','LineWidth',3);
    end

    axis square;

    ct=ct+1;
end

% % % % % PLOTS VORTICITY + LAG Pts. (if selected) % % % % %

if vortPlot == 1

    subplot(1,numPlots,ct)
    %
    axis([0 Lx 0 Ly]);
    title('VORTICITY');
    xlabel('x'); ylabel('y');
    hold all;

    %Compute Vorticity and Plot It against Lagrangian Grid!
    x = X(1,:); y = Y(:,1);
    contourf(x,y,flipud(rot90(vort)),10); hold on;

    loc = [0;loc;length(chiX)];
    for i=2:length(loc)
        plot(chiX(loc(i-1)+1:loc(i)),chiY(loc(i-1)+1:loc(i)),'m','LineWidth',3);
    end
    if diffy < 5*ds
        xTemp = [chiX(1) chiX(end)];
        yTemp = [chiY(1) chiY(end)];
        plot(xTemp(1:2),yTemp(1:2),'m','LineWidth',3);
    end

    axis square;

    ct=ct+1;
end

% % % % % PLOTS PRESSURE + LAG Pts. (if selected) % % % % %

if pressPlot == 1

    subplot(1,numPlots,ct)
    %
    axis([0 Lx 0 Ly]);
    title('PRESSURE');
    xlabel('x'); ylabel('y');
    hold all;

    %Use Pressure and Plot It against Lagrangian Grid!
    x = X(1,:); y = Y(:,1);
    contourf(x,y,p,6); hold on;

    loc = [0;loc;length(chiX)];
    for i=2:length(loc)
        plot(chiX(loc(i-1)+1:loc(i)),chiY(loc(i-1)+1:loc(i)),'m','LineWidth',3);
    end
    if diffy < 5*ds
        xTemp = [chiX(1) chiX(end)];
        yTemp = [chiY(1) chiY(end)];
        plot(xTemp(1:2),yTemp(1:2),'m','LineWidth',3);
    end

    axis square;

    ct=ct+1;
end

% % % % % PLOTS MAGNITUDE OF VELOCITY + LAG Pts. (if selected) % % % % %

if uMagPlot == 1

    subplot(1,numPlots,ct)
    %
    axis([0 Lx 0 Ly]);
    title('MAGNITUDE OF VELOCITY');
    xlabel('x'); ylabel('y');
    hold all;

    %Use Mag. Velocity and Plot It against Lagrangian Grid!
    x = X(1,:); y = Y(:,1);
    contourf(x,y,uMag,6); hold on;

    loc = [0;loc;length(chiX)];
    for i=2:length(loc)
        plot(chiX(loc(i-1)+1:loc(i)),chiY(loc(i-1)+1:loc(i)),'m','LineWidth',3);
    end
    if diffy < 5*ds
        xTemp = [chiX(1) chiX(end)];
        yTemp = [chiY(1) chiY(end)];
        plot(xTemp(1:2),yTemp(1:2),'m','LineWidth',3);
    end

    axis square;

    ct=ct+1;
end

% % % % % PLOTS VELOCITY FIELD + LAG Pts. (if selected) % % % % %

if velPlot == 1

    subplot(1,numPlots,ct)
    %
    axis([0 Lx 0 Ly]);
    title('VELOCITY');
    xlabel('x'); ylabel('y');
    hold all;

    quiver(X,Y,U,V); %Print Velocity Field

    loc = [0;loc;length(chiX)];
    for i=2:length(loc)
       plot(chiX(loc(i-1)+1:loc(i)),chiY(loc(i-1)+1:loc(i)),'m','LineWidth',3);
    end
    if diffy < 5*ds
        xTemp = [chiX(1) chiX(end)];
        yTemp = [chiY(1) chiY(end)];
        plot(xTemp(1:2),yTemp(1:2),'m','LineWidth',3);
    end

    axis square;

    ct=ct+1;
end

if conPlot == 1
    % plotting all concentrations
    for ic=1:num_con
        subplot(1,numPlots,ct)
    %
        axis([0 Lx 0 Ly]);
        title(sprintf('Concentration%g',ic));
        xlabel('x'); ylabel('y');
        hold all;

        x = X(1,:); y = Y(:,1);
        pcolor(X,Y,C(:,:,ic));
        shading interp;

        loc = [0;loc;length(chiX)];
        for i=2:length(loc)
            plot(chiX(loc(i-1)+1:loc(i)),chiY(loc(i-1)+1:loc(i)),'m','LineWidth',3);
        end
        if diffy < 5*ds
            xTemp = [chiX(1) chiX(end)];
            yTemp = [chiY(1) chiY(end)];
            plot(xTemp(1:2),yTemp(1:2),'m','LineWidth',3);
        end

        axis square;

        ct=ct+1;
    end
end

drawnow;

hold off;
set(gca,'Box','on');


function [pyFiltS,cerrFiltS] = comparePyradFilters
% Function to compare filtered images computed using CERR vs. Pyradiomics.
% Supported filer types: LoG, Wavelets.
%------------------------------------------------------------------------
% AI 07/02/2020

%% Load sample data
fpath = fullfile(fileparts(fileparts(getCERRPath)),...
    'Unit_Testing/data_for_cerr_tests/IBSI1_CT_phantom/IBSILungCancerCTImage.mat.bz2');
planC = loadPlanC(fpath,tempdir);
planC = updatePlanFields(planC);
planC = quality_assure_planC(fpath,planC);
indexS = planC{end};
scanNum=1;

%% Apply filters using pyradiomics

% 1. LoG
filtName = 'LoG';
testSigmaV = [3.0,4.0];
pyFiltParam1S.sigma = testSigmaV;
pyFiltS = processImageUsingPyradiomics(planC,'',filtName,pyFiltParam1S);
pyFieldLoGC = fieldnames(pyFiltS);

%2. Wavelets
filtName = 'wavelet';
pyFiltParam2S.wavetype = 'coif1';
pyFilt2S = processImageUsingPyradiomics(planC,'',filtName,pyFiltParam2S);
pyFieldWavC = fieldnames(pyFilt2S);
for n = 1:length(pyFieldWavC)
    pyFiltS.(pyFieldWavC{n}) = pyFilt2S.(pyFieldWavC{n});
end

%% Apply filters using CERR

%Get scan array
scan3M = getScanArray(scanNum,planC);
CToffset = planC{indexS.scan}(scanNum).scanInfo(1).CTOffset;
scan3M = double(scan3M)-CToffset;
wholeScanMask3M = ones(size(scan3M));

% 1. LoG
filtName = 'LoG';
cerrFiltS = struct();
scanS = planC{indexS.scan}(scanNum);
[xV,yV,zV] = getScanXYZVals(scanS);
dx = median(abs(diff(xV)));
dy = median(abs(diff(yV)));
dz = median(diff(zV));
voxelSizeV = [dx,dy,dz];
cerrFiltParam1S.VoxelSize_mm.val = voxelSizeV*10;%convert to mm
for n = 1:length(testSigmaV)
        cerrFiltParam1S.Sigma_mm.val = testSigmaV(n);
        outFieldname = pyFieldLoGC{n};
        outS = processImage(filtName,scan3M,wholeScanMask3M,cerrFiltParam1S);
        fieldsC = fieldnames(outS);
        cerrFiltS.(outFieldname) = outS.(fieldsC{1});
end

% 2. Wavelets
cerrFiltParam2S = struct();
cerrFiltParam2S.Wavelets.val='coif';
cerrFiltParam2S.Index.val='1';
cerrFiltParam2S.NormFlag.val=0;
dirC = {'LLH','LHL','LHH','HLL','HLH','HHL','HHH','LLL'};
filtName = 'Wavelets';
for n = 1:length(dirC)
    %Convert python dictionary to matlab struct
    cerrFiltParam2S.Direction.val = dirC{n};
    outS = processImage(filtName,scan3M,wholeScanMask3M,cerrFiltParam2S);
    outFieldname = pyFieldWavC{n};
    fieldsC = fieldnames(outS);
    cerrFiltS.(outFieldname) = outS.(fieldsC{1});
end

end


function fig2simulinkmaskicon(hFig,colors)
% Creates a mask for simulink subsystem from a given figure. This subsystem is
% masked with a ICON correspoding to lines on the figure. This is useful to illustrate
% the behaviour of the subsystem by a icon.
%
% You can use the simplot command to create it from the actual output. See the
% documentation of simplot (doc simplot) for further info.
%
% INPUTS:   hFig      - handle to a figure to be used (e.g. gcf)
%           colors    - (OPTIONAL) colors for different lines.
%                       Supported (default) colors: blue, red, green, magenta, yellow, cyan, black
%
% OUTPUTS:  Creates a simulink subsystem with a given mask
%           Prints out the Mask/Icon string
%
% Author: Paul Proteus (e-mail: proteus.paul (at) yahoo (dot) com)
% Version: 1.0
% Changes tracker:  13.07.2010  - First version
%
% Example:  h = figure; hold on;
%           plot([0:0.1:10],sin([0:0.1:10]));
%           plot([0:0.5:12],cos([0:0.5:12]));
%           fig2simulinkmaskicon(gcf);
%           fig2simulinkmaskicon(gcf,'yellow');
%           fig2simulinkmaskicon(gcf,{'red','magenta'});

%% Check required inputs
if ~strcmp(get(hFig,'Type'),'figure'),
    % Checking the validity of the figure handle
    error('hFig argument is not a valid figure handle');
end

% Find the lines
hLine = findall(hFig,'type','line');

% Check if there is at least one line
if isempty(hLine),
    % There is no line to be used. Figure has to have at least one.
    error('There are no lines in this figure. Cannot create subsystem mask.');
end

% If the colors are not provided, use the default
if ~exist('colors','var'),
    % define the default colors
    colors = { ...
        'blue',    ...
        'red',     ...
        'green',   ...
        'magenta', ...
        'yellow',  ...
        'cyan',    ...
        'black',   ...
        };
end

% Check if the colors where not provided as a string
if ischar(colors),
    % Make it cell-array for further use
    colors = {colors};
end

%% Initialization
XData = get(hLine,'XData');
YData = get(hLine,'YData');

if ~iscell(XData),
    % In case there is only one line specified in this hLine
    XData  = {XData};
    YData  = {YData};
end

nGraphs = length(XData);

%% Prepare and print out the MASK/ICON string
disp('Copy following lines to the Mask/Icon of the selected subsystem:');
disp('------- START OF COPY SECTION');

allPreparedString = [];
% Loop through all lines in the figure
for idx=1:nGraphs,
    % Color selection
    colorIdx = min(idx,length(colors)); % if too many lines - used the last color
    preparedString = ['color(''' colors{colorIdx} ''');'];
    disp(preparedString);

    allPreparedString = [allPreparedString preparedString];

    % Plot the line
    preparedString = 'plot(';
    preparedString = [preparedString ...
                      '[' num2str(XData{idx}) '],' ...
                      '[' num2str(YData{idx}) '],'];
    preparedString = [preparedString(1:end-1) ');'];
    % get rid of the too many spaces
    preparedString = regexprep(preparedString, '\s*', ' ');

    disp(preparedString);
    allPreparedString = [allPreparedString preparedString];
end

disp('------- END');

%% Create a new simulink subsystem block and set it up
systemName = ['model_fig2simulinkmaskicon_' num2str(round(rand*100000))];
new_system(systemName);
open_system(systemName);

add_block('built-in/SubSystem',[systemName '/SS_Masked']);

% Enlarge it and mask it
hBlock = get_param([systemName '/SS_Masked'],'handle');
set(hBlock,'Position',[45 35 181 113]);
set(hBlock,'Mask','on');
set(hBlock,'MaskDisplay',allPreparedString);


function [audio_obj, features] = get_files_and_mfcc_features(input_dir, l, fn_filter)
    current_dir = cd();
    cd(input_dir);
    files = get_files_by_filter(fn_filter);
    % label according to l-th character in file name
    audio_obj = miraudio(files, 'Label', l, 'Normal');
    features = struct();
    mfcc = mirmfcc(audio_obj, 'Frame');
    features.mfcc = mirstat(mfcc);
    mfcc_delta = mirmfcc(audio_obj, 'Frame', 'Delta');
    features.mfcc_delta = mirstat(mfcc_delta);
    centroid = mircentroid(audio_obj, 'Frame');
    features.centroid = mirstat(centroid);
    rms = mirrms(audio_obj, 'Frame');
    features.rms = mirstat(rms);
    cd(current_dir);
end


function [new_nbrs, new_ops, new_nodes, new_topos] = mk_nbrs_of_dag_topo(G0)
% MK_NBRS_OF_DAG_TOPO Make all DAGs that differ from G0 by a single edge deletion, addition or reversal
% [new_nbrs, new_ops, new_nodes, new_topos] = mk_nbrs_of_dag_topo(G0)
%
% new_nbrs{i} is the i'th neighbor of G0.
% new_ops{i} = 'add', 'del', or 'rev' is the operation used to create the i'th neighbor.
% new_nodes(i,1:2) are the head and tail of the operated-on arc.
% new_topos are topological orders of the neighbours.
%
% We implement the fast acyclicity check described by P. Giudici and R. Castelo,
% "Improving MCMC model search for data mining", submitted to J. Machine Learning, 2001.
%
% Written by Qian Diao <qian.diao@intel.com> on 19 Nov 01
% Reference are ..\BNT\graph\mk_nbrs_of_dag.m, ..\BNT\learning\learn_struct_mcmc.m and
% ..\BNT\graph\topological_sort.m
% Copyright Intel 2001
%
new_nbrs = {};
new_ops = {};
new_nodes = [];
new_topos = {};
cs = {};

n = length(G0);
indeg = zeros(1,n);
zero_indeg = []; % a stack of nodes with no parents
for i=1:n
  indeg(i) = length(parents(G0,i));
  cs{i} = children(G0, i);
  if indeg(i)==0
    zero_indeg = [i zero_indeg];
  end
end

dag = G0;
[nbrs, ops, nodes] = mk_nbrs_of_digraph(dag);
A = init_ancestor_matrix(dag);
%assert(acyclic(new_dag));

d1 = 1;
for d = 1:length(ops)
  i = nodes(d, 1); j = nodes(d, 2);
  legal = 0;
  switch ops{d}
   case 'add',
    if A(i,j)==0
      legal = 1;
    end
   case 'del',
    legal = 1;
   case 'rev',
    ps = mysetdiff(parents(dag, j), i);
    % if any(A(ps,i)) then there is a path i -> parent of j -> j
    % so reversing i->j would create a cycle
    legal = ~any(A(ps, i));
  end

  if legal
    tmp = nbrs(:,:,d);
    new_nbrs{d1} = tmp;
    new_ops{d1} =  ops{d};
    new_nodes(d1,1:2) = nodes(d,1:2);

    % obtain the topological orders of neighbour dags
    zero_indeg_nbr = [];
    indeg_nbr = [];
    cs_nbr = [];

    switch ops{d}
     case 'add' % i is a new parent of j
      zero_indeg_nbr = zero_indeg;
      indeg_nbr = indeg;
      if ~isempty(find(zero_indeg == j)) % j is not a root anymore
        zero_indeg_nbr = mysetdiff(zero_indeg, j);
      end
      indeg_nbr(j) = indeg(j)+1;

      t_nbr=1;
      order_nbr = zeros(1,n);
      while ~isempty(zero_indeg_nbr)
        v_nbr = zero_indeg_nbr(1); % pop v
        zero_indeg_nbr = zero_indeg_nbr(2:end);
        order_nbr(t_nbr) = v_nbr;
        t_nbr = t_nbr + 1;
        if v_nbr == i % j is a new child of i
          cs_nbr = sort([j cs{i}]);
        else
          cs_nbr = cs{v_nbr};
        end
        for k = 1:length(cs_nbr)
          c_nbr = cs_nbr(k);
          indeg_nbr(c_nbr) = indeg_nbr(c_nbr) - 1;
          if indeg_nbr(c_nbr) == 0
            zero_indeg_nbr = [c_nbr zero_indeg_nbr]; % push c
          end
        end
      end

     case 'del' % i is not a parent of j anymore
      zero_indeg_nbr = zero_indeg;
      indeg_nbr = indeg;
      if length(parents(tmp, j))==0
        zero_indeg_nbr = -sort(-[zero_indeg, j]); % descending order
      end
      indeg_nbr(j) = indeg(j) - 1;

      t_nbr=1;
      order_nbr = zeros(1,n);
      while ~isempty(zero_indeg_nbr)
        v_nbr = zero_indeg_nbr(1); % pop v
        zero_indeg_nbr = zero_indeg_nbr(2:end);
        order_nbr(t_nbr) = v_nbr;
        t_nbr = t_nbr + 1;
        if v_nbr == i % j is not a child of i anymore
          cs_nbr = mysetdiff(cs{i}, j);
        else
          cs_nbr = cs{v_nbr};
        end
        for k = 1:length(cs_nbr)
          c_nbr = cs_nbr(k);
          indeg_nbr(c_nbr) = indeg_nbr(c_nbr) - 1;
          if indeg_nbr(c_nbr) == 0
            zero_indeg_nbr = [c_nbr zero_indeg_nbr]; % push c
          end
        end
      end

     case 'rev' %i is a new child of j and j is a new parent of i
      zero_indeg_nbr = zero_indeg;
      indeg_nbr = indeg;
      if ~isempty(find(zero_indeg == i))
        zero_indeg_nbr = mysetdiff(zero_indeg_nbr, i);
      end
      if length(parents(tmp, j))==0
        zero_indeg_nbr = -sort(-[zero_indeg_nbr, j]); % decending order
      end
      indeg_nbr(i) = indeg(i)+1;
      indeg_nbr(j) = indeg(j)-1;

      t_nbr=1;
      order_nbr = zeros(1,n);
      while ~isempty(zero_indeg_nbr)
        v_nbr = zero_indeg_nbr(1); % pop v
        zero_indeg_nbr = zero_indeg_nbr(2:end);
        order_nbr(t_nbr) = v_nbr;
        t_nbr = t_nbr + 1;
        cs_nbr = cs{v_nbr};
        if v_nbr == i % j is not a child of i anymore
          cs_nbr = mysetdiff(cs{i}, j);
        end
        if v_nbr == j % i is a new child of j
          cs_nbr = sort([i cs{j}]);
        end
        for k = 1:length(cs_nbr)
          c_nbr = cs_nbr(k);
          indeg_nbr(c_nbr) = indeg_nbr(c_nbr) - 1;
          if indeg_nbr(c_nbr) == 0
            zero_indeg_nbr = [c_nbr zero_indeg_nbr]; % push c
          end
        end
      end
     end

    new_topos{d1} = order_nbr;
    d1 = d1+1;
  end
end

clear nbrs ops nodes;

%%%%%%%%%
function A = update_row(A, j, dag)
% We compute row j of A
A(j, :) = 0;
ps = parents(dag, j);
if ~isempty(ps)
  A(j, ps) = 1;
end
for k=ps(:)'
  anck = find(A(k,:));
  if ~isempty(anck)
    A(j, anck) = 1;
  end
end

%%%%%%%%
function A = init_ancestor_matrix(dag)
order = topological_sort(dag);
A = zeros(length(dag));
for j=order(:)'
  A = update_row(A, j, dag);
end


% testRadiomicsFeaturesWithPyRadiomics.m
%
% Script to compare CERR and pyRadiomics features
%
% APA, 2/22/2018

global planC
indexS = planC{end};

% Wavelet decomposition flag
wavDecompFlg = 1; % 0: original image, 1: wavelet pre-processing

% Specify discretization
fixedMinMaxGrLevFlag = 0; % 1: to input fixed min/max/grLevels, 0: min/max
                          % calculated for the structure and bin width of binWidth.
binWidth = 25;
structNum = 1;
scanNum = 1;
pyradScanType = 'original';

paramS.firstOrderParamS.offsetForEnergy = planC{indexS.scan}(scanNum).scanInfo(1).CTOffset;
paramS.firstOrderParamS.binWidth = binWidth;

% Get structure
[rasterSegments, planC, isError] = getRasterSegments(structNum,planC);
[mask3M, uniqueSlices] = rasterToMask(rasterSegments, scanNum, planC);
scanArray3M = getScanArray(planC{indexS.scan}(scanNum));
scanArray3M = double(scanArray3M) - ...
    planC{indexS.scan}(scanNum).scanInfo(1).CTOffset;
% Wavelet decomposition
if wavDecompFlg == 1
    dirString = 'HHL';
    wavType = 'coif1';
    scanArray3M = flip(scanArray3M,3);
    if mod(size(scanArray3M,3),2) > 0
        scanArray3M(:,:,end+1) = 0*scanArray3M(:,:,1);
    end
    scanArray3M = wavDecom3D(double(scanArray3M),dirString,wavType);
    if mod(size(scanArray3M,3),2) > 0
        scanArray3M = scanArray3M(:,:,1:end-1);
    end
    scanArray3M = flip(scanArray3M,3);
end

SUVvals3M = mask3M.*double(scanArray3M(:,:,uniqueSlices));
[minr, maxr, minc, maxc, mins, maxs] = compute_boundingbox(mask3M);
maskBoundingBox3M = mask3M(minr:maxr,minc:maxc,mins:maxs);

% Assign NaN to image outside mask
volToEval = SUVvals3M(minr:maxr,minc:maxc,mins:maxs);
volToEval(~maskBoundingBox3M) = NaN;

% Get x,y,z grid for the shape features (flip y to make it monotically
% increasing)
[xValsV, yValsV, zValsV] = getUniformScanXYZVals(planC{indexS.scan}(scanNum));
yValsV = fliplr(yValsV);
xValsV = xValsV(minc:maxc);
yValsV = yValsV(minr:maxr);
zValsV = zValsV(mins:maxs);
PixelSpacingX = abs(xValsV(2)-xValsV(1));
PixelSpacingY = abs(yValsV(2)-yValsV(1));
PixelSpacingZ = abs(zValsV(2)-zValsV(1));
VoxelVol = PixelSpacingX*PixelSpacingY*PixelSpacingZ*1000; % convert cm to mm

if fixedMinMaxGrLevFlag
    numGrLevels = paramS.higherOrderParamS.numGrLevels;
    minIntensity = paramS.higherOrderParamS.minIntensity;
    maxIntensity = paramS.higherOrderParamS.maxIntensity;
    % Quantize using the number of bins
    quantizedM = imquantize_cerr(volToEval,numGrLevels,...
        minIntensity,maxIntensity);

else % Quantize using the binwidth
    minIntensity = [];
    maxIntensity = [];
    numGrLevels = [];
    quantizedM = imquantize_cerr(volToEval,numGrLevels,...
        minIntensity,maxIntensity,binwidth);
    numGrLevels = max(quantizedM(:));
    paramS.higherOrderParamS.numGrLevels = numGrLevels;
end

paramS.higherOrderParamS.numGrLevels = numGrLevels;
paramS.higherOrderParamS.patchRadius3dV = [1 1 1];
paramS.higherOrderParamS.imgDiffThresh = 0;

% Number of voxels (used in run percentage calculation)
numVoxels = sum(~isnan(quantizedM(:)));

%% First order features
featureS.firstOrderS = radiomics_first_order_stats...
    (volToEval(logical(maskBoundingBox3M)), VoxelVol, ...
    paramS.firstOrderParamS.offsetForEnergy, paramS.firstOrderParamS.binWidth);
firstOrderS = featureS.firstOrderS;
cerrFirstOrderV = [firstOrderS.energy, firstOrderS.totalEnergy, firstOrderS.interQuartileRange, ...
    firstOrderS.kurtosis+3, firstOrderS.max, firstOrderS.mean, firstOrderS.meanAbsDev, ...
    firstOrderS.median, firstOrderS.medianAbsDev, firstOrderS.min, ...
    firstOrderS.P10, firstOrderS.P90, firstOrderS.interQuartileRange, ...
    firstOrderS.robustMeanAbsDev, firstOrderS.rms, firstOrderS.skewness, ...
    firstOrderS.std, firstOrderS.var, firstOrderS.entropy];
pyradFirstorderNamC = {'Energy', 'TotalEnergy','InterquartileRange','Kurtosis',...
    'Maximum', 'Mean','MeanAbsoluteDeviation','Median','medianAbsDev',...
    'Minimum','10Percentile','90Percentile','InterquartileRange',...
    'RobustMeanAbsoluteDeviation','RootMeanSquared','Skewness',...
    'StandardDeviation','Variance','Entropy'};
pyradFirstorderNamC = strcat([pyradScanType,'_firstorder_'],pyradFirstorderNamC);
pyRadFirstOrderV = [];
for i = 1:length(pyradFirstorderNamC)
    if isfield(teststruct,pyradFirstorderNamC{i})
        pyRadFirstOrderV(i) = teststruct.(pyradFirstorderNamC{i});
    else
        pyRadFirstOrderV(i) = NaN;
    end
end

diffFirstOrderV = (cerrFirstOrderV - pyRadFirstOrderV) ./ cerrFirstOrderV * 100

%% Shape features
featureS.shapeS = getShapeParams(maskBoundingBox3M, ...
        {xValsV, yValsV, zValsV});
shapeS = featureS.shapeS;
cerrShapeV = [shapeS.majorAxis, shapeS.minorAxis, shapeS.leastAxis, ...
    shapeS.flatness, shapeS.elongation, shapeS.max3dDiameter, shapeS.max2dDiameterAxialPlane,...
    shapeS.max2dDiameterSagittalPlane', shapeS.max2dDiameterCoronalPlane, ...
    shapeS.Compactness1, shapeS.Compactness2, shapeS.spherDisprop, ...
    shapeS.sphericity, shapeS.surfToVolRatio/10,...
    shapeS.surfArea*100, shapeS.volume*1000];
pyradShapeNamC = {'MajorAxis', 'MinorAxis', 'LeastAxis', 'Flatness',  'Elongation', ...
    'Maximum3DDiameter', 'Maximum2DDiameterSlice', 'Maximum2DDiameterRow', ...
    'Maximum2DDiameterColumn', 'Compactness1','Compactness2','spherDisprop','Sphericity', ...
    'SurfaceVolumeRatio','SurfaceArea','Volume'};
pyradShapeNamC = strcat([pyradScanType,'_shape_'],pyradShapeNamC);
pyRadShapeV = [];
for i = 1:length(pyradShapeNamC)
    if isfield(teststruct,pyradShapeNamC{i})
        pyRadShapeV(i) = teststruct.(pyradShapeNamC{i});
    else
        pyRadShapeV(i) = NaN;
    end
end
shapeDiffV = (cerrShapeV - pyRadShapeV) ./ cerrShapeV * 100

%% GLCM features

% Define flags
glcmFlagS.energy = 1;
glcmFlagS.jointEntropy = 1;
glcmFlagS.jointMax = 1;
glcmFlagS.jointAvg = 1;
glcmFlagS.jointVar = 1;
glcmFlagS.contrast = 1;
glcmFlagS.invDiffMoment = 1;
glcmFlagS.sumAvg = 1;
glcmFlagS.corr = 1;
glcmFlagS.clustShade = 1;
glcmFlagS.clustProm = 1;
glcmFlagS.haralickCorr = 1;
glcmFlagS.invDiffMomNorm = 1;
glcmFlagS.invDiff = 1;
glcmFlagS.invDiffNorm = 1;
glcmFlagS.invVar = 1;
glcmFlagS.dissimilarity = 1;
glcmFlagS.diffEntropy = 1;
glcmFlagS.diffVar = 1;
glcmFlagS.diffAvg = 1;
glcmFlagS.sumVar = 1;
glcmFlagS.sumEntropy = 1;
glcmFlagS.clustTendency = 1;
glcmFlagS.autoCorr = 1;
glcmFlagS.invDiffMomNorm = 1;
glcmFlagS.firstInfCorr = 1;
glcmFlagS.secondInfCorr = 1;

dirctn      = 1;
cooccurType = 2;
featureS.harFeat3DdirS = get_haralick(dirctn, cooccurType, quantizedM, ...
numGrLevels, glcmFlagS);

% harlCombS = featureS.harFeat3DcombS.CombS;
harlCombS = featureS.harFeat3DdirS.AvgS;
cerrGlcmV = [harlCombS.autoCorr, harlCombS.jointAvg, harlCombS.clustPromin, harlCombS.clustShade, harlCombS.clustTendency, ...
harlCombS.contrast, harlCombS.corr, harlCombS.diffAvg, harlCombS.diffEntropy, harlCombS.diffVar, harlCombS.dissimilarity, ...
harlCombS.energy, harlCombS.jointEntropy, harlCombS.invDiff, harlCombS.invDiffMom, harlCombS.firstInfCorr, ...
harlCombS.secondInfCorr, harlCombS.invDiffMomNorm, harlCombS.invDiffNorm, harlCombS.invVar, ...
harlCombS.sumAvg, harlCombS.sumEntropy, harlCombS.sumVar];

pyradGlcmNamC = {'Autocorrelation', 'JointAverage', 'ClusterProminence', 'ClusterShade',  'ClusterTendency', ...
    'Contrast', 'Correlation', 'DifferenceAverage', 'DifferenceEntropy', 'DifferenceVariance', 'Dissimilarity', ...
    'JointEnergy', 'JointEntropy','Id','Idm', 'Imc1' , ...
    'Imc2', 'Idmn','Idn','InverseVariance', 'sumAverage', 'SumEntropy', 'sumVariance'};

pyradGlcmNamC = strcat([pyradScanType,'_glcm_'],pyradGlcmNamC);
pyRadGlcmV = [];
for i = 1:length(pyradGlcmNamC)
    if isfield(teststruct,pyradGlcmNamC{i})
        pyRadGlcmV(i) = teststruct.(pyradGlcmNamC{i});
    else
        pyRadGlcmV(i) = NaN;
    end
end

glcmDiffV = (cerrGlcmV - pyRadGlcmV) ./ cerrGlcmV * 100

%% RLM features

rlmFlagS.sre = 1;
rlmFlagS.lre = 1;
rlmFlagS.gln = 1;
rlmFlagS.glnNorm = 1;
rlmFlagS.rln = 1;
rlmFlagS.rlnNorm = 1;
rlmFlagS.rp = 1;
rlmFlagS.lglre = 1;
rlmFlagS.hglre = 1;
rlmFlagS.srlgle = 1;
rlmFlagS.srhgle = 1;
rlmFlagS.lrlgle = 1;
rlmFlagS.lrhgle = 1;
rlmFlagS.glv = 1;
rlmFlagS.rlv = 1;
rlmFlagS.re = 1;

numGrLevels = paramS.higherOrderParamS.numGrLevels;

% 3D Run-Length features from combined run length matrix
dirctn      = 1;
rlmType     = 2;
featureS.rlmFeat3DdirS = get_rlm(dirctn, rlmType, quantizedM, ...
    numGrLevels, numVoxels, rlmFlagS);

rlmCombS = featureS.rlmFeat3DdirS.AvgS;
cerrRlmV = [rlmCombS.gln, rlmCombS.glnNorm, rlmCombS.glv, rlmCombS.hglre, rlmCombS.lglre, rlmCombS.lre, rlmCombS.lrhgle, ...
    rlmCombS.lrlgle, rlmCombS.rln, rlmCombS.rlnNorm, rlmCombS.rlv, rlmCombS.rp, ...
    rlmCombS.sre, rlmCombS.srhgle, rlmCombS.srlgle, rlmCombS.re];

pyradRlmNamC = {'GrayLevelNonUniformity', 'GrayLevelNonUniformityNormalized',...
    'GrayLevelVariance', 'HighGrayLevelRunEmphasis',  'LowGrayLevelRunEmphasis', ...
    'LongRunEmphasis', 'LongRunHighGrayLevelEmphasis', 'LongRunLowGrayLevelEmphasis',...
    'RunLengthNonUniformity', 'RunLengthNonUniformityNormalized', 'RunVariance', ...
    'RunPercentage', 'ShortRunEmphasis','ShortRunHighGrayLevelEmphasis', ...
    'ShortRunLowGrayLevelEmphasis','RunEntropy'};

pyradRlmNamC = strcat([pyradScanType,'_glrlm_'],pyradRlmNamC);
pyRadRlmV = [];
for i = 1:length(pyradRlmNamC)
    if isfield(teststruct,pyradRlmNamC{i})
        pyRadRlmV(i) = teststruct.(pyradRlmNamC{i});
    else
        pyRadRlmV(i) = NaN;
    end
end

rlmDiffV = (cerrRlmV - pyRadRlmV) ./ cerrRlmV * 100

%% Size Zone features in 3d

flagS.sae = 1;
flagS.lae = 1;
flagS.gln = 1;
flagS.glv = 1;
flagS.szv = 1;
flagS.glnNorm = 1;
flagS.szn = 1;
flagS.sznNorm = 1;
flagS.zp = 1;
flagS.lglze = 1;
flagS.hglze = 1;
flagS.salgle = 1;
flagS.sahgle = 1;
flagS.lalgle = 1;
flagS.larhgle = 1;
flagS.ze = 1;

szmType = 1; % 1: 3d, 2: 2d
szmM = calcSZM(quantizedM, numGrLevels, szmType);
numVoxels = sum(~isnan(quantizedM(:)));
featureS.szmFeature3dS = szmToScalarFeatures(szmM,numVoxels, szmFlagS);
szmS = featureS.szmFeature3dS;
% cerrSzmV = [szmS.gln, szmS.glnNorm, szmS.glv, szmS.hglre, szmS.lglre, szmS.lre, szmS.lrhgle, ...
%     szmS.lrlgle, szmS.rln, szmS.rlnNorm, szmS.rlv, szmS.rp, ...
%     szmS.sre, szmS.srhgle, szmS.srlgle];
cerrSzmV = [szmS.gln, szmS.glnNorm, szmS.glv, szmS.hglze, szmS.lglze, szmS.lae, szmS.lahgle, ...
    szmS.lalgle, szmS.szn, szmS.sznNorm, szmS.szv, szmS.zp, ...
    szmS.sae, szmS.sahgle, szmS.salgle, szmS.ze];

pyradSzmNamC = {'GrayLevelNonUniformity', 'GrayLevelNonUniformityNormalized',...
    'GrayLevelVariance', 'HighGrayLevelZoneEmphasis',  'LowGrayLevelZoneEmphasis', ...
    'LargeAreaEmphasis', 'LargeAreaHighGrayLevelEmphasis', 'LargeAreaLowGrayLevelEmphasis',...
    'SizeZoneNonUniformity', 'SizeZoneNonUniformityNormalized', 'ZoneVariance', ...
    'ZonePercentage', 'SmallAreaEmphasis','SmallAreaHighGrayLevelEmphasis', ...
    'SmallAreaLowGrayLevelEmphasis','ZoneEntropy'};

pyradSzmNamC = strcat([pyradScanType,'_glszm_'],pyradSzmNamC);
pyRadSzmV = [];
for i = 1:length(pyradSzmNamC)
    if isfield(teststruct,pyradSzmNamC{i})
        pyRadSzmV(i) = teststruct.(pyradSzmNamC{i});
    else
        pyRadSzmV(i) = NaN;
    end
end
szmDiffV = (cerrSzmV - pyRadSzmV) ./ cerrSzmV * 100

%% NGLDM features

patchRadius3dV = paramS.higherOrderParamS.patchRadius3dV;
imgDiffThresh = paramS.higherOrderParamS.imgDiffThresh;
% 3d
ngldmM = calcNGLDM(quantizedM, patchRadius3dV, ...
    numGrLevels, imgDiffThresh);
featureS.ngldmFeatures3dS = ngldmToScalarFeatures(ngldmM,numVoxels);

ngldmS = featureS.ngldmFeatures3dS;
cerrNgldmV = [ngldmS.lde, ngldmS.hde, ngldmS.lgce, ngldmS.hgce, ...
    ngldmS.ldlge, ngldmS.ldhge, ngldmS.hdlge, ngldmS.hdhge, ...
    ngldmS.gln, ngldmS.glnNorm, ngldmS.dcn, ngldmS.dcnNorm,...
    ngldmS.dcp, ngldmS.glv, ngldmS.dcv, ngldmS.entropy, ngldmS.energy];

pyradNgldmNamC = {'SmallDependenceEmphasis', 'LargeDependenceEmphasis',...
    'LowGrayLevelCountEmphasis', 'HighGrayLevelCountEmphasis',  'SmallDependenceLowGrayLevelEmphasis', ...
    'SmallDependenceHighGrayLevelEmphasis', 'LargeDependenceLowGrayLevelEmphasis', ...
    'LargeDependenceHighGrayLevelEmphasis', 'GrayLevelNonUniformity', 'GrayLevelNonUniformityNorm', ...
    'DependenceNonUniformity', 'DependenceNonUniformityNormalized', ...
    'DependencePercentage', 'GrayLevelVariance', 'DependenceVariance', ...
    'DependenceEntropy', 'DependenceEnergy'};

pyradNgldmNamC = strcat([pyradScanType,'_gldm_'],pyradNgldmNamC);
pyRadNgldmV = [];
for i = 1:length(pyradNgldmNamC)
    if isfield(teststruct,pyradNgldmNamC{i})
        pyRadNgldmV(i) = teststruct.(pyradNgldmNamC{i});
    else
        pyRadNgldmV(i) = NaN;
    end
end

ngldmDiffV = (cerrNgldmV - pyRadNgldmV) ./ cerrNgldmV * 100

%% NGTDM features
numGrLevels = paramS.higherOrderParamS.numGrLevels;
patchRadius3dV = paramS.higherOrderParamS.patchRadius3dV;
% 3d
[s,p] = calcNGTDM(quantizedM, patchRadius3dV, numGrLevels);
featureS.ngtdmFeatures3dS = ngtdmToScalarFeatures(s,p,numVoxels);

ngtdmS = featureS.ngtdmFeatures3dS;
cerrNgtdmV = [ngtdmS.busyness ngtdmS.coarseness ngtdmS.complexity ngtdmS.contrast ngtdmS.strength];


function model = ivmOptimiseIvm(model, display)

% IVMOPTIMISEIVM Selects the points for an IVM model.
% FORMAT
% DESC selects points in an IVM model for inclusion in the active
% set.
% ARG model : the model for which the points are to be selected.
% ARG display : the display level, should be 0, 1 or 2. The higher
% the display, the more verbose.
% RETURN model : the model with the active set selected.
%
% SEEALSO : ivmInit, ivmSelectVisualise, ivmAddPoint,
% ivmSelectPoint, ivmEpUpdatePoint
%
% COPYRIGHT : Neil D. Lawrence, 2003, 2004, 2005

% IVM

if nargin < 2
  display = 1;
end
tol = 1e-4;
model = ivmInit(model);
numData = size(model.X, 1);

if model.d > numData
  warning('Active set size is larger than data-set, resetting to data-set size');
  model.d = numData;
end

% Start with all data-points inactive.
model.J = 1:numData;

% Set first infoChange to NaN
infoChange(1) = NaN;
dVal = model.d;
for k = 1:dVal

  [indexSelect, infoChange(k)] = ivmSelectPoint(model);
  dataIndexSelect = model.J(indexSelect);
  model = ivmAddPoint(model, dataIndexSelect);
  if display
    ivmSelectVisualise(model, display, k, dataIndexSelect);
  end
end
if model.epUpdate
  lengthIndex = length(model.I);
  betaChange = 1;
  oldBeta = model.beta;
  counter = 0;
  while betaChange > tol
    I = model.I';
    counter = counter + 1;
    for i = I;
      model = ivmEpUpdatePoint(model, i);
    end
    betaChange = full(max(abs(model.beta - oldBeta)));
    fprintf('EP Update %d, beta change %2.4f\n', counter, betaChange)
    oldBeta =  model.beta;
  end
end


% This demo compares dynamic Bayesian GPLVM with and without image pyramids
% to see if we get a better reconstruction of the dog tail motion using
% pyramids.
%
% Created by Andreas and Teo on 31 July 2013, based on demosDynamics.m

%------------ GENERATION -------
% Train

%% Setting paths
addpath(genpath('../../../GPmat/matlab/')); % GPmat
% addpath(genpath('../../../vargplvm/vargplvm/matlab/')); % Bayesian GPLVM
addpath('../../../GPmatlab/netlab3_3/'); % NetLab, which is not included in gitHub

%% Preparing pyramid dataset:
% This only needs to be done once.
load dog
% To view it:
% for f=1:600, image(reshape(Y(mod(f-1,61)+1,:),[360 640])); colormap gray(256); pause(0.033); end
levels = 5;
Y = im2pyramid(Y, height, width, levels);
save('dogPyramid', 'Y', 'height', 'width', 'levels');
clear

%% Selecting dataset -- To run experiments, change the dataset below and run the test again:
% function doAll(dataSetName)
dataSetName = 'dog';
% Running the rest for each dataset.
fprintf(1,'\n\n#-----  DOG DEMO: Generation ----#\n');
experimentNo=61;
indPoints=-1;
latentDim=35;
fixedBetaIters= 0;
initVardistIters = 800;
mappingKern = 'rbfardjit';
reconstrIters = 1; % no reconstruction needed here
itNo=repmat(1000, 1, 16); %16000
periodicPeriod = 4.3983; % Recalculated for dataToKeep=60
dynamicKern={'rbfperiodic','whitefixed','bias','rbf'};
vardistCovarsMult=0.8;
whiteVar = 1e-6;
dataToKeep = 60;
dataSetSplit = 'custom';
indTr = [1:60];
indTs = 60; % We don't really reconstruct in this experiment
learnSecondVariance = 0;
DgtN = 1; % Uncomment for the faster version
predWithMs = 0;
%%
demHighDimVargplvm3

%%
%-- Then generate:
% experimentNo=61;
% dataToKeep = 60;
% dataSetSplit = 'custom';
% indTr = [1:60];
% indTs = 60;
futurePred = 40;
doSampling = 0;
demHighDimVargplvmTrained
%clear Yts; clear YtsOriginal; clear Testmeans2; clear Testcovars2;
%playMov(height, width, [], [Ytr(end-5:end,:); Varmu2]);

%%

% Produce plots
bar(prunedModelInit.kern.comp{1}.inputScales)
print -depsc ../diagrams/dog_scalesInit.eps; system('epstopdf ../diagrams/dog_scalesInit.eps');
bar(model.kern.comp{1}.inputScales)
print -depsc ../diagrams/dog_scalesOpt.eps; system('epstopdf ../diagrams/dog_scalesOpt.eps');

nPixels = height*width; % This will be used in case Y was built using pyramids.
fr=reshape(Ytr(end,1:nPixels),height,width); imagesc(fr); colormap('gray'); % Last training image
print -depsc ../diagrams/dogGeneration_lastOfTraining.eps; system('epstopdf ../diagrams/dogGeneration_lastOfTraining.eps');
fr=reshape(Varmu2(1,1:nPixels),height,width); imagesc(fr); colormap('gray');  % First predicted
print -depsc ../diagrams/dogGeneration_firstOfTest.eps; system('epstopdf ../diagrams/dogGeneration_firstOfTest.eps');
fr=reshape(Varmu2(13,1:nPixels),height,width); imagesc(fr); colormap('gray'); % A subsequent frame
print -depsc ../diagrams/dogGeneration_frame14.eps; system('epstopdf ../diagrams/dogGeneration_frame14.eps');

for i=1:size(Varmu2,1)
    img = reshape(Varmu2(i,1:nPixels), height, width);
    % imagesc(img); colormap('gray');
    imwrite(uint8(img), sprintf('../diagrams/%s_%02d.png',dataSetName, i))
    % pause(0.1);
end

%% Compare the dogs
diffs = zeros(40,2);
for f=1:40,
    imgFlat = imread(sprintf('../diagrams/dog_%02d.png',f));
    imgPyramid = imread(sprintf('../diagrams/dogPyramid_%02d.png',f));
    diffImg = abs(imgFlat - imgPyramid);
    imagesc(diffImg);
    colorbar
    diffs(f,1) = mean(diffImg(:));
    diffs(f,2) = max(diffImg(:));
    fprintf('f=%d, mean_difference=%f, max_difference=%f\n', f, diffs(f,1), diffs(f,2));
    pause(0.1);
end


function [superPixSeg,superPixInd,superPixBounds]=mvg_FelzenswalbSuperpixelWrapper(img,sigma,min_area,k)
% The funtion [superPixSeg,superPixInd,superPixBounds]=FelzenswalbSuperpixels(img,sigma,min_area,k)
% is a wrapper funtion to superpixel segmentation algorithm from
% Pedro F. Felzenszwalb and Daniel P. Huttenlocher, described in
% "Efficient Graph-Based Image Segmentation"
% Pedro F. Felzenszwalb and Daniel P. Huttenlocher
% International Journal of Computer Vision, 59(2) September 2004.
% The executables are available online in
% See http://www.cs.brown.edu/~pff/segment/
%

%% Path to executables of Felzenszwalb superpixel algorithm (see above)
global configjson
soft_dir=fullfile(configjson.rahtu.rahtuPath,'/segment/'); % Change here the path to the executables

%% Default parameters
% Default parameters proposed by Felzenszwalb et al.  sigma = 0.5, k = 500, min_area = 20. (Larger values for k result in larger components in the result.)
if nargin<2
    sigma=0.5;
end
if nargin<3
    min_area=20;
end
if nargin<4
    k=500;
end

%% Initialize path
tmp_dir=soft_dir;
%tmp_dir=[soft_dir,'tmp',filesep];

%% Initialize files
tempFile=tempname(tmp_dir);
imgFile=[tempFile,'.ppm'];
segFile=[tempFile,'_superpix.ppm'];

% Make image file (in ppm format) if it does not exist already
if ~ischar(img)
    % Image matrix given, make ppm file
    imwrite(img,imgFile,'ppm');
    tempImage=1;
else
    % Image file name given (image has to be in ppm format, check)
    if ~strcmp(img(end-2:end),'ppm')
        error('If image file is given, it must be in ppm format');
    end
    imgFile=img;
    tempImage=0;
end

%% Run segmentation algorithm by Pedro F. Felzenszwalb and Daniel P. Huttenlocher
if isunix
    cmd = ['sh -c "unset LD_LIBRARY_PATH;' soft_dir 'segment ' num2str(sigma) ' ' num2str(k) ' ' num2str(min_area) ' "' imgFile '" "' segFile '""' ];
else
    cmd = [soft_dir 'segment ' num2str(sigma) ' ' num2str(k) ' ' num2str(min_area) ' ' imgFile ' ' segFile ];
end
system(cmd);

%% Read in segmentation result
superPixSeg=imread(segFile);

%% Return also index image if needed
if nargout>1
    superPixInd=mvg_numerizeLabels(superPixSeg);
end

%% Return also superpixel boundaries if needed
if nargout>2
    superPixBounds=superpixels2boundaries(superPixInd);
end

%% Delete temporary all created temporary files
if exist(imgFile,'file') && tempImage==1
    delete(imgFile);
end
if exist(segFile,'file')
    delete(segFile);
end


%--- help for ts/chebyshev_box ---
%
%  Constructs chebyshev boxes for multivariate-multiperiods densities
%
%  ::
%
%    mvcb=chebyshev_box(this,gam)
%
%  Args:
%
%     this (ts | rts) : time series with many pages (number of simulations)
%       and potentially many columns (number of variables)
%
%     gam (scalar | vector) : percentile(s)
%
%  Returns:
%     :
%
%     - **mvcb** [struct] : structure with time series in its fields. Each
%       field represents a particular variable
%
%     - **gam_** [scalar|vector] : sorted percentile(s)
%
%     - **my** [ts] : mean across simulations
%
%


%DECODER PORTION

function synth_speech = f_DECODER (aCoeff, pitch_plot, voiced, gain);

%re-calculating frame_length for this decoder,
frame_length=1;
for i=2:length(gain)
    if gain(i) == 0,
        frame_length = frame_length + 1;
    else break;
    end
end

%decoding starts here,
for b=1 : frame_length : (length(gain)),    %length(gain) should be very close
                                            %(i.e less than a frame_length error) to length(x)

    %FRAME IS VOICED OR UNVOICED
    if voiced(b) == 1,   %voiced frame
            pitch_plot_b = pitch_plot(b);
        syn_y1 = f_SYN_V (aCoeff, gain, frame_length, pitch_plot_b, b);
    else syn_y1 = f_SYN_UV (aCoeff, gain, frame_length, b); %unvoiced frame
    end

    synth_speech(b:b+frame_length-1) = syn_y1;
end


function [bootSam,testSets] = buildBootSet(Y,nBoot,IABR)
% -------------------------------------------------------------------------
% function [bootSam] = buildBootSet(outcome,nBoot,IABR)
% -------------------------------------------------------------------------
% DESCRIPTION:
% This function creates a matrix of 'nBoot' bootstrap samples. The matrix
% is composed of instance indexes for each bootstrap sample. In addition,
% if specified by the user, the function implements the 'imbalance-adjusted
% bootstrap resampling'method: it duplicates the number of positive instance
% by a factor equal to the number of negative instances, and it duplicates
% the number of negative instance by a factor equal to the number of
% positive instances, such that the probability of picking a positive and a
% negative instance in the bootstrap sample is equal. See ref. [1] for more
% details.
% -------------------------------------------------------------------------
% REFERENCE:
% [1] Vallieres, M. et al. (2015). A radiomics model from joint FDG-PET and
%     MRI texture features for the prediction of lung metastases in soft-tissue
%     sarcomas of the extremities. Physics in Medicine and Biology, 60(14),
%     5471-5496. doi:10.1088/0031-9155/60/14/5471
% -------------------------------------------------------------------------
% INPUTS:
% - Y: Column vector of size [nInst X 1] specifying the outcome status
%      (1 or 0) for all instances.
% - nBoot: Number of bootstrap samples.
% - IABR: (optional argument). Use 'adjust' to perform imbalance-adjusted
%         bootstrap resampling (IABR), and use no argument for regular
%         resampling.
% -------------------------------------------------------------------------
% OUTPUTS:
% - bootSam: Matrix of size [nInst X nBoot], where 'nInst' is the number of
%            instance in Y.
% - testSets: Cell of size [1 X nBoot], where each entry is a testing set
%             vector (Testing sets for different bootstrap samples may not
%             be of the same length).
% -------------------------------------------------------------------------
% AUTHOR(S): Martin Vallieres <mart.vallieres@gmail.com>
% -------------------------------------------------------------------------
% HISTORY:
% - Creation: May 2015
%--------------------------------------------------------------------------
% STATEMENT:
% This file is part of <https://github.com/mvallieres/radiomics/>,
% a package providing MATLAB programming tools for radiomics analysis.
% --> Copyright (C) 2015  Martin Vallieres
%
%    This package is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    This package is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with this package.  If not, see <http://www.gnu.org/licenses/>.
% -------------------------------------------------------------------------

% RANDOM NUMBER GENERATOR SEED
if ~RandStream.getGlobalStream.Seed
    rng('shuffle')
end

indPos = find(Y); % indexes of postivie instances
indNeg = find(~Y); % indexes of negative instances
nNeg = length(indNeg); % Number of negative instances
nPos = length(indPos); % Number of positive instances
nInst = length(indPos) + length(indNeg); % Total number of instances

if nargin == 3 && strcmp(IABR,'adjust') % Adjust probability of picking positive and negative instances
    indPos = repmat(indPos,nNeg,1);
    indNeg = repmat(indNeg,nPos,1);
end
ind = [indPos;indNeg];
ind = shufflePartition(ind);
ind = shufflePartition(ind);

% Obtaining the bootstrap samples
nSize = length(ind);
bootSam = ind(ceil(nSize .* rand(nInst,nBoot)));
testSets = findBootTestSet(bootSam);

% Verification for each bootstrap sample: Both training and testing sets
% must have at least 2 instances of each class, and these instances must be
% different.
for n = 1:nBoot
    training = bootSam(:,n);
    testing = testSets{n};
    while ( sum(Y(testing))<2 || sum(Y(testing))>(length(Y(testing))-2) || sum(Y(training))<2 || sum(Y(training))>(length(Y(training))-2) || length(unique(training))==1 || length(unique(testing))==1 )
        bootSam(:,n) = ind(ceil(nSize .* rand(nInst,1)));
        testSets(n) = findBootTestSet(bootSam(:,n));
        training = bootSam(:,n);
        testing = testSets{n};
    end
end

end


function outputImage = shear(this, shear_dr)
% Geometric shear of MrImage
%
%   Y = MrImage()
%   Y.shear(inputs)
%
% This is a method of class MrImage.
%
% NOTE: This is a method of MrImage rather than MrImageGeometry, because
%       the latter is composed on the fly from affineTransformation and
%       dimInfo to integrate both information and sustain consistency.
%       Thus, the effect will only be visible using the world space plot
%       options, i.e. Y.plot('plotType', 'spmi').
% NOTE: The rotation is *added* to the rotation already defined in the
%       affine transformation matrix, equivalent to the rotation in SPM
%       Display.
% IN
%   shear_dr            [1,3] shear components, i.e., [sx, sy, sz]
%
% OUT
%
% EXAMPLE
%   shear
%
%   See also MrImage

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

outputImage = this.copyobj();

[outputImage.dimInfo, outputImage.affineTransformation] = ...
    this.geometry.perform_world_space_operation('shear', shear_dr, this.dimInfo);

end


%SerialLink.fkine Forward kinematics
%
% T = R.fkine(Q, OPTIONS) is the pose of the robot end-effector as an SE3
% object for the joint configuration Q (1xN).
%
% If Q is a matrix (KxN) the rows are interpreted as the generalized joint
% coordinates for a sequence of points along a trajectory.  Q(i,j) is the
% j'th joint parameter for the i'th trajectory point.  In this case T is a
% an array of SE3 objects (K) where the subscript is the index along the path.
%
% [T,ALL] = R.fkine(Q) as above but ALL (N) is a vector of SE3 objects describing
% the pose of the link frames 1 to N.
%
% Options::
%  'deg'    Assume that revolute joint coordinates are in degrees not
%           radians
%
% Note::
% - The robot's base or tool transform, if present, are incorporated into the
%   result.
% - Joint offsets, if defined, are added to Q before the forward kinematics are
%   computed.
% - If the result is symbolic then each element is simplified.
%
% See also SerialLink.ikine, SerialLink.ikine6s.

% Copyright (C) 1993-2017, by Peter I. Corke
%
% This file is part of The Robotics Toolbox for MATLAB (RTB).
%
% RTB 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.
%
% RTB 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 RTB.  If not, see <http://www.gnu.org/licenses/>.
%
% http://www.petercorke.com

function [t,allt] = fkine(robot, q, varargin)

%
% evaluate fkine for each point on a trajectory of
% theta_i or q_i data
%

n = robot.n;

opt.deg = false;

opt = tb_optparse(opt, varargin);

if opt.deg
    % in degrees mode, scale the columns corresponding to revolute axes
    q = robot.todegrees(q);
end

if nargout > 1
    allt(n) = SE3;
end

L = robot.links;
if numel(q) == n
    % single configuration
    t = SE3(robot.base);
    for i=1:n
        t = t * L(i).A(q(i));

        if nargout > 1
            allt(i) = t; % intermediate transformations
        end
    end
    t = t * SE3(robot.tool);
else
    if numcols(q) ~= n
        error('q must have %d columns', n)
    end
    t(numrows(q)) = SE3;  % preallocate storage
    for k=1:numrows(q)		% for each trajectory point
        qk = q(k,:);
        tt = SE3(robot.base);
        for i=1:n
            tt = tt * L(i).A(qk(i));
        end
        t(k) = tt * SE3(robot.tool);
    end
end

if issym(t)
    t = simplify(t);
else
    t = trnorm(t);
end

%robot.T = t;
%robot.notify('Moved');


function x = zero_null_right ( m, n )

%*****************************************************************************80
%
%% ZERO_NULL_RIGHT returns a right null vector of the ZERO matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 November 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, N, the order of A.
%
%    Output, real X(N,1), the null vector.
%
  x = ones ( n, 1 );

  return
end


function [c1,c2] = simpleXover(p1,p2,bounds,Ops)
% Simple crossover takes two parents P1,P2 and performs simple single point
% crossover.
%
% function [c1,c2] = simpleXover(p1,p2,bounds,Ops)
% p1      - the first parent ( [solution string function value] )
% p2      - the second parent ( [solution string function value] )
% bounds  - the bounds matrix for the solution space
% Ops     - Options matrix for simple crossover [gen #SimpXovers].

% Binary and Real-Valued Simulation Evolution for Matlab
% Copyright (C) 1996 C.R. Houck, J.A. Joines, M.G. Kay
%
% C.R. Houck, J.Joines, and M.Kay. A genetic algorithm for function
% optimization: A Matlab implementation. ACM Transactions on Mathmatical
% Software, Submitted 1996.
%
% 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 1, 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. A copy of the GNU
% General Public License can be obtained from the
% Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

numVar = size(p1,2)-1; 			% Get the number of variables
% Pick a cut point randomly from 1-number of vars
cPoint = round(rand * (numVar-2)) + 1;

c1 = [p1(1:cPoint) p2(cPoint+1:numVar+1)]; % Create the children
c2 = [p2(1:cPoint) p1(cPoint+1:numVar+1)];


function options = defaultOptions;

% DEFAULTOPTIONS The default options for optimisation.
% FORMAT
% DESC returns a default options vector for optimisation.
% RETURN options : the default options vector.
%
% COPYRIGHT : Neil D. Lawrence, 2005, 2006
%
% SEEALSO : scg, conjgrad, quasinew

% NDLUTIL

options = [0,  1e-4, 1e-4, 1e-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1e-8, 0.1, 0];


function [param, names] = gpsimMapExtractParam(model)

% GPSIMMAPEXTRACTPARAM Extract the parameters of a GPSIMMAP model.
% FORMAT
% DESC extracts the model parameters from a structure containing
% the information about a Gaussian process for single input motif
% modelling.
% ARG model : the model structure containing the information about
% the model.
% RETURN params : a vector of parameters from the model.
%
% SEEALSO : gpsimMapCreate, gpsimMapExpandParam, modelExtractParam
%
% COPYRIGHT : Neil D. Lawrence, 2006
%
% MODIFIED : Pei Gao, 2008

% SHEFFIELDML

if nargout>1
  [param, names] = kernExtractParam(model.kern);
else
  param = kernExtractParam(model.kern);
end

fhandle = str2func([model.Transform 'Transform']);

for i = 1:model.numGenes
  if isfield(model,'bTransform') && isempty(model.bTransform);
    param = [param model.B(i)];
  else
    param = [param fhandle(model.B(i), 'xtoa')];
  end

  param = [param fhandle(model.S(i), 'xtoa') fhandle(model.D(i), ...
                                                    'xtoa')];

  if  isfield(model, 'includeRepression') && model.includeRepression
    if isfield(model,'alphaTransform') && isempty(model.alphaTransform);
      param = [param model.alpha(i)];
    else
      param = [param fhandle(model.alpha(i), 'xtoa')];
    end
  end

  if model.ngParam > 0
    param = [param (fhandle(model.gParam(:,i), 'xtoa'))'];
  end

  if nargout >1
    names{end+1} = ['Basal' num2str(i)];
    names{end+1} = ['Sensitivity' num2str(i)];
    names{end+1} = ['Decay' num2str(i)];

    if isfield(model, 'isGroupNonlinearity') && model.isGroupNonlinearity
      if strcmp(model.nonLinearity{i}, 'repression')
        names{end+1} = ['alpha' num2str(i)];
      end
    else
      names{end+1} = ['alpha' num2str(i)];
    end

    if model.ngParam > 0
      ngParamk = model.ngParam/model.numGenes;
      names{(end+1):(end+ngParamk)} = ['Parameters for g' num2str(i)];
    end
  end
end

if isfield(model,'includeNoise') && model.includeNoise
  param = [param fhandle(sqrt(model.noiseVar), 'xtoa')];
  if nargout > 1
    for i=1:model.numGenes
      names = {names{:} ['noiseSd' num2str(i)]};
    end
  end
end

if isfield(model, 'fix')
  for i = 1:length(model.fix)
    param(model.fix(i).index) = model.fix(i).value;
  end
end

param = real(param);

% Check if there is a mean function.
if isfield(model, 'meanFunction') & ~isempty(model.meanFunction)
  if nargout>1
    [meanFuncParams, meanFuncNames] = modelExtractParam(model.meanFunction);
  else
    meanFuncParams = modelExtractParam(model.meanFunction);
  end
else
  meanFuncParams =[];
  meanFuncNames = {};
end

param = [param meanFuncParams];
if nargout > 1
  names = {names{:} meanFuncNames{:}};
end


function th=thresh(X)
count=imhist(X);
[M, N]=size(X);

th=M/5;
end