
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%  Title: StatisCLAS: A Package of Classification Methods   %%%%
%%%%  Author: David Casado de Lucas                            %%%%
%%%%  Version: 29th May 2013                                   %%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% PURPOSE: This function applies different classification methods for functional data.

% INPUT VARIABLES:
%    numFDtoCLASSmethod: Number of the method to be applied.
%    infoFDtoCLASSmethod: Necessary information for the classification method.
%    groupFD1: Matrix with the training functions of group 1 as rows.
%    groupFD1test: Matrix with the testing functions of group 1 as rows.
%    groupFD2: Matrix with the training functions of group 2 as rows.
%    groupFD2test: Matrix with the testing functions of group 2 as rows.

% OUTPUT VARIABLES:
%    errorRatesGroup1: Vector with the misclassification error rates for sample 1.
%    errorRatesGroup2: Vector with the misclassification error rates for sample 2.
%    outputFDtoCLASSmethod: Cell array with possible additional output information of the method.

% COMMENTS:
%   (1) By default, out robust functional classification method is implemented, but
%       the user can easily add other transformations.

function [errorRatesGroup1 errorRatesGroup2 outputFDtoCLASSmethod] =...
    fromFDtoCLASS(numFDtoCLASSmethod, infoFDtoCLASSmethod, groupFD1, groupFD1test, groupFD2, groupFD2test)

n1 = size(groupFD1,1);
m1 = size(groupFD1test,1);
n2 = size(groupFD2,1);
m2 = size(groupFD2test,1);

switch numFDtoCLASSmethod
  case 1  % Our method DbC, with the mean
    numberFDdistance = infoFDtoCLASSmethod{1};
    numberFDreference = infoFDtoCLASSmethod{2};
    infoFDreference = infoFDtoCLASSmethod{3};
    contamination = false;  % To disable DbC-alpha
    alpha = [];
    [errorRatesGroup1 errorRatesGroup2 mean1 mean1alpha mean2 mean2alpha groupMV1 groupMV1test groupMV2 groupMV2test] =...
        functionRFC(groupFD1,groupFD1test,groupFD2,groupFD2test,contamination,alpha,numberFDdistance,numberFDreference,infoFDreference);
    errorRatesGroup1 = errorRatesGroup1(1); % Number of misclassified testing elements of group 1 (out of m1)
    errorRatesGroup2 = errorRatesGroup2(1); % Number of misclassified testing elements of group 2 (out of m2)
    equalDist = ([groupMV1test(:,1); groupMV2test(:,1)] == 0);
    if any(equalDist)    % The elements in the frontier are allocated at random
      groupMV1test(groupMV1test(:,1)==0, 1) = randi(2,sum(groupMV1test(:,1)==0),1)-1.5;
      groupMV2test(groupMV2test(:,1)==0, 1) = randi(2,sum(groupMV2test(:,1)==0),1)-1.5;
    end
    outputFDtoCLASSmethod{1} = groupMV1test(:,1)>0;  % Misclassified elements of testing sample 1
    outputFDtoCLASSmethod{2} = groupMV2test(:,1)<0;  % Misclassified elements of testing sample 2
    outputFDtoCLASSmethod{3} = equalDist;  % Frontier elements
  case 2  % Our robust method DbC-alpha, with the trimmed mean
    numberFDdistance = infoFDtoCLASSmethod{1};
    numberFDreference = infoFDtoCLASSmethod{2};
    infoFDreference = infoFDtoCLASSmethod{3};
    contamination = infoFDtoCLASSmethod{4};
    alpha = infoFDtoCLASSmethod{5};
    [errorRatesGroup1 errorRatesGroup2 mean1 mean1alpha mean2 mean2alpha groupMV1 groupMV1test groupMV2 groupMV2test] =...
        functionRFC(groupFD1,groupFD1test,groupFD2,groupFD2test,contamination,alpha,numberFDdistance,numberFDreference,infoFDreference);
    errorRatesGroup1 = errorRatesGroup1(2); % Number of misclassified testing elements of group 1 (out of m1)
    errorRatesGroup2 = errorRatesGroup2(2); % Number of misclassified testing elements of group 2 (out of m2)
    equalDist = ([groupMV1test(:,2); groupMV2test(:,2)] == 0);
    if any(equalDist)    % The elements in the frontier are allocated at random
      groupMV1test(groupMV1test(:,2)==0, 1) = randi(2,sum(groupMV1test(:,2)==0),1)-1.5;
      groupMV2test(groupMV2test(:,2)==0, 1) = randi(2,sum(groupMV2test(:,2)==0),1)-1.5;
    end
    outputFDtoCLASSmethod{1} = groupMV1test(:,2)>0;  % Misclassified elements of testing sample 1
    outputFDtoCLASSmethod{2} = groupMV2test(:,2)<0;  % Misclassified elements of testing sample 2
    outputFDtoCLASSmethod{3} = equalDist;  % Frontier elements
end

end
