% the difference between myMainFile2 and myMainFile
% is that this version has a stopping criterion

% clearn workspace and command window
clear;clc;

% define how many times the experiments are to be repeated
maxExperimentCount = 10;
minManyLabels = 3;

% define datasets of experiment
myDatasets = {
    'cocomo81',...
    'cocomo81e',...
    'cocomo81o',...
    'cocomo81s',...
    'desharnais',...
    'desharnaisL1',...
    'desharnaisL2',...
    'desharnaisL3',...
    'nasa93',...
    'nasa93_center_1',...
    'nasa93_center_2',...
    'nasa93_center_5',...
    'sdr',...
    'albrecht',...
    'finnish',...
    'kemerer',...
    'maxwell',...
    'miyazaki94',...
    'telecom1',...
    'china',...
    'chinaResource1',...
    'chinaResource2',...
    'chinaResource3',...
    'chinaResource4',...
    };

% for each dataset in the study
datasetSize = size(myDatasets,2);
for datasetCounter = 1:datasetSize
    
    eval(['load ',char(myDatasets(datasetCounter)),'.csv;']);
    eval(['nowDataset = ',char(myDatasets(datasetCounter)),';']);
    eval(['clear ',char(myDatasets(datasetCounter)),';']);
    clc;
    myDatasets(datasetCounter)  % print out the dataset name
    
    % get the row and column number (without dependent variable)
    n = size(nowDataset,1);
    p = size(nowDataset,2) - 1; % exclude the effort value, i.e. dependent var.
    
    % log the dataset
    logNowDataset = [log(nowDataset(:,1:p)), nowDataset(:,(p+1))];
    
    % also keep a normalized version of the dataset
    normNowDataset = myNormalizer(nowDataset);
    
    % define test set size; the remaining instances will be the train
    testSize = ceil(n/10);
    
    % define overall actuals and predictions
    myOverallTestActuals = [];
    myOverallPassivePredictions = [];
    myOverallActivePredictions = [];
    myOverallRandomPredictions = [];
    myOverallCartPredictions = [];
    datasetActuals = logNowDataset(:,p+1);
    
    % calculate the index matrix that is the sorted distance matrix
    [tmpMatrix myDistMatrix] = calculateMyDistanceMatrix(logNowDataset);
        
    for experimentCounter = 1:maxExperimentCount
        
        % pick up testSize-many instances at random
        trainIndices = 1:n;
        testIndices = [];
        for testPicker = 1:testSize
            tmpRnd = randi([1 size(trainIndices,2)],1,1);
            testIndices = [testIndices,trainIndices(tmpRnd)];
            trainIndices(tmpRnd) = [];
        end
        
        testActuals = logNowDataset(testIndices,p+1)'; % store actual effort values
        myOverallTestActuals = [myOverallTestActuals,testActuals];
        trainActuals = logNowDataset(trainIndices,p+1)';
        
        % now start getting the predictions from active and normal k
        % first get the predictions of k=1 with all effort known
        predictionsPassive = -1 * ones(1,testSize);
        predictionsRandom = -1 * ones(1,testSize);
        predictionsCart = -1 * ones(1,testSize);
        for i = 1:testSize
            relatedIndices = tmpMatrix(:,testIndices(i));
            relatedIndices = relatedIndices(trainIndices);
            [C closestGuyIndex] = min(relatedIndices);
            predictionsPassive(i) = trainActuals(closestGuyIndex);
            predictionsRandom(i) = trainActuals(randi([1 size(trainActuals,2)],1,1));
        end
        % store passive prediction
        myOverallPassivePredictions = [myOverallPassivePredictions,predictionsPassive];
        % store random precitons. random predictions will form the baseline
        myOverallRandomPredictions = [myOverallRandomPredictions,predictionsRandom];
        
        % now get the predictions for k=1, with different numbers of labeled
        % instances from 1 to n-1
        [popIndex maxLabelsToAsk] = findPopularity(tmpMatrix); % order instances w.r.t. popularity
        popIndex = popIndex(trainIndices);    % get pop indices of train instances
        predictionsActive = [];
        
        % if it is the first experiment, then find how many labels to ask
        if experimentCounter == 1
            askMore = 1;    % a control variable saying if we need to ask more labels
            howManyLabels = 0;  % tells how many labels to ask for
            while(((askMore == 1) && (howManyLabels <= maxLabelsToAsk)) || (howManyLabels < minManyLabels))
                tmpPredictionsActive = [];
                howManyLabels = howManyLabels + 1;  % increment labels to ask by one
                tmpPredictionsActive = activePredict(datasetActuals,tmpMatrix,popIndex,howManyLabels,testIndices,myDistMatrix);
                askMore = decideMoreLabels(tmpPredictionsActive, predictionsActive, testActuals);
                predictionsActive = [predictionsActive;tmpPredictionsActive];   % save new predictions
            end
        else
            for i = 1:howManyLabels
                tmpPredictionsActive = activePredict(datasetActuals,tmpMatrix,popIndex,i,testIndices,trainIndices);
                predictionsActive = [predictionsActive;tmpPredictionsActive];
            end
        end
        myOverallActivePredictions = [myOverallActivePredictions,predictionsActive];
        
        % and now apply the CART algorithm and get its predictions
        tmpCartPredictions = myCARTOn(normNowDataset(testIndices,:),normNowDataset(trainIndices,:));
        myOverallCartPredictions = [myOverallCartPredictions,tmpCartPredictions];
    end
    
    
    % now we will plot the results w.r.t. different error measures
    mdmrePassive = ones(1,howManyLabels) * median(abs(myOverallTestActuals - myOverallPassivePredictions)./myOverallTestActuals);
    mdmreActive = -1 * ones(1,howManyLabels);
    mdmreRandom = ones(1,howManyLabels) * median(abs(myOverallTestActuals - myOverallRandomPredictions)./myOverallTestActuals);
    mdmreCart = ones(1,howManyLabels) * median(abs(myOverallTestActuals - myOverallCartPredictions)./myOverallTestActuals);
   
    for i = 1:howManyLabels
        mdmreActive(i) = median(abs(myOverallTestActuals - myOverallActivePredictions(i,:))./myOverallTestActuals);
    end
     % check statistical difference and see if active and passive mre's are
    % statistically different
    passiveMREs = (abs(myOverallTestActuals - myOverallPassivePredictions)./myOverallTestActuals);
    activeMREs = (abs(myOverallTestActuals - myOverallActivePredictions(i,:))./myOverallTestActuals);
    [p h] = ranksum(passiveMREs, activeMREs);
    close all;
    h = figure;
%     hold on;
%     axis([1 howManyLabels ...
%         (min([log(mdmrePassive) log(mdmreActive) log(mdmreRandom) log(mdmreCart)])-0.2) ...
%         (max([log(mdmrePassive) log(mdmreActive) log(mdmreRandom) log(mdmreCart)])+0.2) ]);
%     semilogy(1:howManyLabels,(mdmrePassive),'o-'...
%         ,1:howManyLabels,(mdmreActive),'p-'...
%         ,1:howManyLabels,(mdmreRandom),'s-'...
%         ,1:howManyLabels,(mdmreCart),'d-'...
%         ,'LineWidth',1.5...
%         ,'MarkerSize',8);
    axis([1 howManyLabels ...
        (min([(mdmrePassive) (mdmreActive) (mdmreRandom) (mdmreCart)])-0.2) ...
        (max([(mdmrePassive) (mdmreActive) (mdmreRandom) (mdmreCart)])+0.2) ]);

    plot(1:howManyLabels,log10(mdmrePassive),'o-'...
        ,1:howManyLabels,log10(mdmreActive),'p-'...
        ,1:howManyLabels,log10(mdmreRandom),'s-'...
        ,1:howManyLabels,log10(mdmreCart),'d-'...
        ,'LineWidth',1.5...
        ,'MarkerSize',8);
    legend('Passive 1NN','Active 1NN','Random 1NN','Norm-Cart/On');
    xlabel('Number of labeled instances');ylabel('MdMRE');
    title([char(myDatasets(datasetCounter)) ', Significance = ' num2str(h)]);
    hold off;
    eval(['print(h,''-dpng'', ''plots\',char(myDatasets(datasetCounter)),'.png'');']);
%     hold off;
    close all;
end