%% PS4: Problem 2(a)
% NOTE: You only need to edit the sections that have been marked in the
% following files:
%  this file (include liblinear training)
%  CompileBoW.m

%% Get filenames of descriptor files
input_folder = 'descriptors/';
output_file = ['dictionary_' num2str(dictionarySize) '.mat'];

classes = {'badminton', 'rowing', 'sailing', 'snowboarding'};
train_files = cell(0, 1);
train_labels = [];

test_files = cell(0, 1);
test_labels = [];

for i=1:length(classes)
    files = arrayfun(@(x) x.name, dir([input_folder classes{i} '/train/*.mat']), 'UniformOutput', false);
    train_files(end+1:end+length(files), 1) = cellfun(@(x) [input_folder classes{i} '/train/' x], files, 'UniformOutput', false);
    train_labels(end+1:end+length(files), 1) = i;
    
    files = arrayfun(@(x) x.name, dir([input_folder classes{i} '/test/*.mat']), 'UniformOutput', false);
    test_files(end+1:end+length(files), 1) = cellfun(@(x) [input_folder classes{i} '/test/' x], files, 'UniformOutput', false);
    test_labels(end+1:end+length(files), 1) = i;
end

%% Load the saved dictionary
load('dictionary_256.mat');


%% Compile BoW Features
Train_BoW_Features = CompileBoW(train_files, dictionary);
Test_BoW_Features = CompileBoW(test_files, dictionary);


%% Train a linear SVM using liblinear
addpath('liblinear-1.7/matlab/');
% Liblinear options to use:
% -s 2
% Set bias to 1
% Set C value to 10
svm_options = '-s 2 -B 1 -c 10';
model = train(train_labels, sparse(Train_BoW_Features), svm_options);
[predicted_labels, accuracy] = predict(test_labels, sparse(Test_BoW_Features), model);

expected_accuracy = 77.5;
disp(['Expected Accuracy: ' num2str(expected_accuracy) '%']);

if(abs(accuracy-expected_accuracy)>0.1)
    disp('Try again! Did you normalize each histogram to sum to 1? Did you use the correct SVM parameters?');
else
    disp('Good job! Move on to the next part!')
end