% below are the load commands for different databases
% depending on which database you would like to be processed
% just uncomment the related lines

load coc81_1_1.csv;
dataset = coc81_1_1;
clear coc81_1_1;

% load coc81_1_1_organic.csv;
% dataset = coc81_1_1_organic;
% clear coc81_1_1_organic;

% load coc81_1_1_embedded.csv;
% dataset = coc81_1_1_embedded;
% clear coc81_1_1_embedded;

% load ISBSG_Banking_Applications.csv;
% dataset = ISBSG_Banking_Applications;
% clear ISBSG_Banking_Applications;

% load SDR_Banking.csv;
% dataset = SDR_Banking;
% clear SDR_Banking;

% load COCOMO_NASA93.csv;
% dataset = COCOMO_NASA93;
% clear COCOMO_NASA93;

% load nasa93_center_5.csv;
% dataset = nasa93_center_5;
% clear nasa93_center_5;

% load nasa93_center_2.csv;
% dataset = nasa93_center_2;
% clear nasa93_center_2;

% load nasa93_between70_80.csv;
% dataset = nasa93_between70_80;
% clear nasa93_between70_80;

% load nasa93_between81_90.csv;
% dataset = nasa93_between81_90;
% clear nasa93_between81_90;

% load albrecht.csv;
% dataset = albrecht;
% clear albrecht;

% load COCOMOII_SDR.csv;
% dataset = COCOMOII_SDR;
% clear COCOMOII_SDR;

% load desharnais.csv;
% dataset = desharnais;
% clear desharnais;

% kernelType = ['uniform']; % kernel type
% kernelType = ['triangular']; % kernel type
% kernelType = ['epanechnikov']; % kernel type
% kernelType = ['quartic']; % kernel type
% kernelType = ['triweight']; % kernel type
% kernelType = ['gaussian']; % kernel type
% kernelType = ['cosine']; % kernel type

actuals = -1 * ones(20,size(dataset,1));
actualsWithFeatures = [];

pred1 = -1 * ones(20,size(dataset,1));
mre1 = -1 * ones(20,size(dataset,1));
pred1 = -1 * ones(20,size(dataset,1));
mre1Kernel = -1 * ones(20,size(dataset,1));

pred3 = -1 * ones(20,size(dataset,1));
mre3 = -1 * ones(20,size(dataset,1));
pred3Kernel = -1 * ones(20,size(dataset,1));
mre3Kernel = -1 * ones(20,size(dataset,1));

pred5 = -1 * ones(20,size(dataset,1));
mre5 = -1 * ones(20,size(dataset,1));
pred5Kernel = -1 * ones(20,size(dataset,1));
mre5Kernel = -1 * ones(20,size(dataset,1));

pred7 = -1 * ones(20,size(dataset,1));
mre7 = -1 * ones(20,size(dataset,1));
pred7Kernel = -1 * ones(20,size(dataset,1));
mre7Kernel = -1 * ones(20,size(dataset,1));

pred9 = -1 * ones(20,size(dataset,1));
mre9 = -1 * ones(20,size(dataset,1));
pred9Kernel = -1 * ones(20,size(dataset,1));
mre9Kernel = -1 * ones(20,size(dataset,1));

predBestK = -1 * ones(20,size(dataset,1));
mreBestK = -1 * ones(20,size(dataset,1));
predBestKKernel = -1 * ones(20,size(dataset,1));
mreBestKKernel = -1 * ones(20,size(dataset,1));

% a dummy to keep track of whether the best k value was found
bestKFound = 0;
% find the best k value for the train data
if bestKFound == 0
    myBestK = bestk(dataset);
end

% repeat 20 times
for counter = 1:20
    
    % randomize dataset
    dataset = randomizeDataset(dataset);
      
    % for each row in the randomized dataset do the following
    i = 0;
    while i < size(dataset,1)
        % increment i by 1
        i = i + 1;
        
        % pick up the row
        myRow = dataset(i,:);
        
        % record it into actuals
        actuals(counter,i) = myRow(1,size(myRow,2));
        % record also the features of that instance (since a lot of instances
        % have the same effort value, I needed to record the features too)
        actualsWithFeatures = [actualsWithFeatures;myRow(1,:)];
        
        
        % train is the dataset minus the selected row
        train = dataset;
        train(i,:) = [];
                        
        % now start predictions
        % below are the ones for various k values
        [pred1(counter,i), mre1(counter,i), sortedEffortValues] = nnkForKernel(myRow,train,1);
        [pred1Kernel(counter,i), mre1Kernel(counter,i)] = myKernelEstimator(myRow, train, kernelType, sortedEffortValues);
        
        [pred3(counter,i), mre3(counter,i), sortedEffortValues] = nnkForKernel(myRow,train,3);
        [pred3Kernel(counter,i), mre3Kernel(counter,i)] = myKernelEstimator(myRow, train, kernelType, sortedEffortValues);
        
        [pred5(counter,i), mre5(counter,i), sortedEffortValues] = nnkForKernel(myRow,train,5);
        [pred5Kernel(counter,i), mre5Kernel(counter,i)] = myKernelEstimator(myRow, train, kernelType, sortedEffortValues);
        
        [pred7(counter,i), mre7(counter,i), sortedEffortValues] = nnkForKernel(myRow,train,7);
        [pred7Kernel(counter,i), mre7Kernel(counter,i)] = myKernelEstimator(myRow, train, kernelType, sortedEffortValues);
        
        [pred9(counter,i), mre9(counter,i), sortedEffortValues] = nnkForKernel(myRow,train,9);
        [pred9Kernel(counter,i), mre9Kernel(counter,i)] = myKernelEstimator(myRow, train, kernelType, sortedEffortValues);
        
        [predBestK(counter,i), mreBest(counter,i), sortedEffortValues] = nnkForKernelnnk(myRow,train,myBestK);
        [predBestKKernel(counter,i), mreBestKKernel(counter,i)] = myKernelEstimator(myRow, train, kernelType, sortedEffortValues);
        
    end
    counter
end