function [FmG, Fm, outtr]=crossKlasifikace(ParamClass, OutClass, indices, ClassType, Opts, FS, Stand)
% Function for classification:
       % [meanAcc, meanSe, meanSp, TimeReq]=crossClassMulti(Input, Output, ClassType, Opts, FS), 
       % where:
       %       Input - features matrix
       %       Output - targets matrix
       %       ClassType - type of classification model: 2 - SVM
       %             for SVM: Opts represents type of model - 'linear' or 'rbf'
       %       FS - feature set
       %       Stand - use of non-standardized '0' or standardized '1' data
       
% Old version: function [meanAcc, meanSe, meanSp, TimeReq]=crossClassMulti(ParamClass, OutClass, typeLDA, knumber, typeSVM, ClassType, FS)

    AccTr=[];Acc=[];
    SeTr=[];Se=[];
    SpTr=[];Sp=[];
    FmTr=[];Fm=[];
    SeTrG=[];SeG=[];
    SpTrG=[];SpG=[];
    FmTrG=[];FmG=[];
    Accv=[];SeGv=[];SpGv=[];FmGv=[];Sev=[];Spv=[];Fmv=[];
    paramOutTeCV={};ClassTeCV={};ClassVCV={};
    C={}; Cv={}; MODELS={};
    tic
    nfold = max(indices);
    for i=1:nfold % for each fold
        i
            testIdx = (indices == i); trainIdx = ~testIdx;
        
            paramOutTr=OutClass(trainIdx); % train data
            ptr=ParamClass(trainIdx,:);

            paramOutTe=OutClass(testIdx); % test data
            paramOutTeCV(i,1)={paramOutTe};
            pte=ParamClass(testIdx,:);

            if Stand == 1 % for standardized features
                mitr=min(ptr); % train statistics measures for standardization
                matr=max(ptr);
                % scaling each feature to the range                
                ptrnorm=(ptr-repmat(mitr,size(ptr,1),1))./(repmat(matr,size(ptr,1),1)-repmat(mitr,size(ptr,1),1));
                ptenorm=(pte-repmat(mitr,size(pte,1),1))./(repmat(matr,size(pte,1),1)-repmat(mitr,size(pte,1),1));
                                                 
                ptr = ptrnorm;
                pte = ptenorm;
            end
                   
            if ClassType==0
                className ='DF';
                DF = fitcdiscr(ptr,paramOutTr,'DiscrimType',Opts);
                ClassTR = predict(DF,ptr);
                Class = predict(DF,pte);
                if strcmp(Opts, 'diaglinear')
                    listN=1;
                elseif strcmp(Opts, 'diagquadratic')
                    listN=2;
                end
                MODELS(i,1)={DF};
            elseif ClassType==1
                className ='kNN';
                KN = fitcknn(ptr,paramOutTr,'NumNeighbors',Opts);% euclidean is default metric
                ClassTR = predict(KN,ptr);
                Class = predict(KN,pte);
                if Opts == 5
                    listN=3;
                elseif Opts > 5
                    listN=4;
                end
                MODELS(i,1)={KN};
            elseif ClassType==2
                className ='NB';
                NB = NaiveBayes.fit(ptr, paramOutTr,'dist','kernel');  
                ClassTR = NB.predict(ptr);
                Class = NB.predict(pte);
                MODELS(i,1)={NB};
            elseif ClassType==3
                className ='SVM';              
                if strcmp(Opts, 'linear')
                    SV = fitcecoc(ptr,paramOutTr,'Coding','onevsone');
                    listN=5;
                elseif strcmp(Opts, 'rbf')
                    temp = templateSVM('KernelFunction',Opts);
                    SV = fitcecoc(ptr,paramOutTr,'Learners',temp,'Coding','onevsone');
                    listN=6;
                end
                ClassTR = predict(SV, ptr);
                Class = predict(SV, pte);
                MODELS(i,1)={SV};
            end
            
            ClassTeCV(i,1)={Class}; % output of classifier
                        
            % Calculate and save confusion matrix in each fold of validation:
            Cj = confusionmat(paramOutTe,Class); 
            C(i,1)={Cj};
            
            TargetV=[0 1 2 3 5]; % target vector: 0 - WAKE; 1 - N1; 2 - N2; 3 - N3; 5 - REM
            
            % Calculate performance indices, such as Se, Sp, F measure, etc.: 
            outtr=paramOutTr
            [SeTrT, SpTrT, SeOverallTrT, SpOverallTrT,AccOverallTrT]=AccuraciesMulti3(paramOutTr, ClassTR, TargetV);
            [SeT, SpT, SeOverallT, SpOverallT, AccOverallT]=AccuraciesMulti3(paramOutTe, Class, TargetV);      
                        
            % Separately for groups 0-3:
            SeTrG=[SeTrG; SeTrT];
            SeG=[SeG; SeT];
                       
            SpTrG=[SpTrG; SpTrT];
            SpG=[SpG; SpT];
                        
           
            % Overall (through all groups):
            AccTr=[AccTr; AccOverallTrT];
            Acc=[Acc; AccOverallT];
                            
            SeTr=[SeTr; SeOverallTrT];
            Se=[Se; SeOverallT];
           
            SpTr=[SpTr; SpOverallTrT];
            Sp=[Sp; SpOverallT];
            
    end
    tt=toc; TimeReq=toc/nfold; % time required for model training during 1 fold
    
    if Stand == 0
        tempStand = 'NonStand';        
    elseif Stand == 1
        tempStand = 'Stand';
    end
    
figure;
subplot(231);boxplot(AccTr,'Color',[0.5 0.5 0.5],'Boxstyle','filled','symbol','+','outliersize',3,'MedianStyle','target');ylim([0 100]);ylabel('Train ACC, %')
if ClassType==0
    xlabel(['LDA: ' Opts])
elseif ClassType==1
    xlabel(['kNN: ' num2str(Opts)])
elseif ClassType==2
    xlabel('Naive Bayes: kernel')
elseif ClassType==3
    xlabel(['SVM: ' Opts])
end
subplot(234);boxplot(Acc,'Color',[0.5 0.5 0.5],'Boxstyle','filled','symbol','+','outliersize',3,'MedianStyle','target');ylim([0 100]);xlabel(FS);ylabel('Test ACC, %')
subplot(232);boxplot(SeTrG,'Color',[0.5 0.5 0.5],'Boxstyle','filled','symbol','+','outliersize',3,'MedianStyle','target');ylim([0 100]);ylabel('Train Se, %')
subplot(235);boxplot(SeG,'Color',[0.5 0.5 0.5],'Boxstyle','filled','symbol','+','outliersize',3,'MedianStyle','target');ylim([0 100]);ylabel('Test Se, %')
subplot(233);boxplot(SpTrG,'Color',[0.5 0.5 0.5],'Boxstyle','filled','symbol','+','outliersize',3,'MedianStyle','target');ylim([0 100]);ylabel('Train Sp, %')
subplot(236);boxplot(SpG,'Color',[0.5 0.5 0.5],'Boxstyle','filled','symbol','+','outliersize',3,'MedianStyle','target');ylim([0 100]);ylabel('Test Sp, %')

set(gcf, 'PaperPositionMode', 'manual');
set(gcf, 'PaperUnits', 'inches');
set(gcf, 'PaperPosition', [2 1 12 6]);  
    
if ClassType==0
        saveas(gcf,['C:\Users\Tomáš Kříženecký\Desktop\fleška téééčko\DP\Nová složka\LDA' Opts '_' FS '_' tempStand '.emf']) % save figure with performance indices
        save(['C:\Users\Tomáš Kříženecký\Desktop\fleška téééčko\DP\Nová složka\LDA' Opts '_' FS '_' tempStand '.mat'],'MODELS') % save structure with classifier
        filename = ['C:\Users\Tomáš Kříženecký\Desktop\fleška téééčko\DP\Nová složka\LDA' Opts '_' FS '_' tempStand '.xlsx']; % definition of name of Excel file
    elseif ClassType==1
        saveas(gcf,['C:\Users\Tomáš Kříženecký\Desktop\fleška téééčko\DP\Nová složka\KNN' num2str(Opts) '_' FS '_' tempStand '.emf'])
        save(['C:\Users\Tomáš Kříženecký\Desktop\fleška téééčko\DP\Nová složka\KNN' num2str(Opts) '_' FS '_' tempStand '.mat'],'MODELS')
        filename = ['C:\Users\Tomáš Kříženecký\Desktop\fleška téééčko\DP\Nová složka\KNN' num2str(Opts) '_' FS '_' tempStand '.xlsx'];
    elseif ClassType==2
        saveas(gcf,['C:\Users\Tomáš Kříženecký\Desktop\fleška téééčko\DP\Nová složka\NB' Opts '_' FS '_' tempStand '.emf'])
        save(['C:\Users\Tomáš Kříženecký\Desktop\fleška téééčko\DP\Nová složka\NB' Opts '_' FS '_' tempStand '.mat'],'MODELS')
        filename = ['C:\Users\Tomáš Kříženecký\Desktop\fleška téééčko\DP\Nová složka\NB' Opts '_' FS '_' tempStand '.xlsx'];
    elseif ClassType==3
        saveas(gcf,['C:\Users\Tomáš Kříženecký\Desktop\fleška téééčko\DP\Nová složka\SVM' Opts '_' FS '_' tempStand '.emf'])
        save(['C:\Users\Tomáš Kříženecký\Desktop\fleška téééčko\DP\Nová složka\SVM' Opts '_' FS '_' tempStand '.mat'],'MODELS')
        filename = ['C:\Users\Tomáš Kříženecký\Desktop\fleška téééčko\DP\Nová složka\SVM' Opts '_' FS '_' tempStand '.xlsx'];
end
close all
    
 % Mean performance indices (from all 10 folds of validation), can be saved and used for analysis   
    meanAcc=[mean(AccTr(:)) mean(Acc(:)) ;...
            std(AccTr(:)) std(Acc(:)) ;...
            min(AccTr(:)) min(Acc(:)) ;...
            max(AccTr(:)) max(Acc(:)) ];
        
    meanSe=[mean(SeTr(:)) mean(Se(:)) ;...
            std(SeTr(:)) std(Se(:)) ;...
            min(SeTr(:)) min(Se(:)) ;...
            max(SeTr(:)) max(Se(:)) ];
        
    meanSp=[mean(SpTr(:)) mean(Sp(:)) ;...
            std(SpTr(:)) std(Sp(:)) ;...
            min(SpTr(:)) min(Sp(:)) ;...
            max(SpTr(:)) max(Sp(:)) ];
    
    Perform={};
    Perform(1,1)={'meanAcc'};
    Perform(2,1)={'meanSe'};
    Perform(3,1)={'meanSp'};
    Perform(4,1)={'TimeReq'};
    Perform(1,2)={meanAcc};
    Perform(2,2)={meanSe};
    Perform(3,2)={meanSp};
    Perform(4,2)={TimeReq};
    % save('...','Perform')
     