% Demo for incremental accelerated kernel discriminant analysis (IAKDA)
%
% Description:
%  Demostration of using IAKDA. For more details see the paper:
%  "N. Gkalelis, V. Mezaris, "Incremental accelerated kernel discriminant
%  analysis", Proc. ACM Multimedia 2017, Mountain View, CA, USA, October
%  2017."
%
% Author: Nikolaos Gkalelis - CERTH-ITI
% Email: gkalelis@iti.gr
%
% First creation (Version 0.0) 19 Jul 2017.
%

clear all; close all

trgLbl = 8; % target label
noDatPrt = 10; % number of data partitions

%% training
for k = 1:noDatPrt

load(strcat('ayahoo_train_', num2str(k), '.mat'));

% ground truth labels - 1: target event 2: rest-of-world, 
gnd = gnd_ev == trgLbl;
gnd = double(gnd);
gnd(gnd == 0) = 2;

[fea_Train, gnd_Train] = sortFeaLabels(fea, gnd);
clear fea gnd;
fea_Train = normFea(fea_Train, 'unityNorm');

opts.kerntype = 'gaussian';
opts.r = 33e-02;
optsda.regAlpha = 0.001;

if k == 1
    K11 = kernelize(fea_Train, opts);
    fea_Train_Prev = fea_Train;
    gnd_Train_Prev = gnd_Train;
    [V, L11, ~] = iakdaInit(K11, gnd_Train, optsda);
else
    K22 = kernelize(fea_Train, opts);
    K21 = kernelize(fea_Train, opts, fea_Train_Prev);
    gnd_Train = [gnd_Train_Prev; gnd_Train];
    fea_Train = [fea_Train_Prev; fea_Train];
    [V, ~, L11, K11]  = iakdaUpdate(K11, L11, K21, K22, gnd_Train, optsda);
    %K11 = [ K11, K21'; K21, K22 ];
    gnd_Train_Prev = gnd_Train;
    fea_Train_Prev = fea_Train;
end

fea_Train_Proj = K11 * V;
Mdl = fitcsvm(fea_Train_Proj, gnd_Train, 'ScoreTransform', 'logit'); % svm model

%% testing
load('ayahoo_test.mat');

gnd = gnd_ev == trgLbl;
gnd = double(gnd);
gnd(gnd ==0) = 2;
gnd_Test = gnd;
fea_Test = fea;
clear fea gnd gnd_ev;

fea_Test = normFea(fea_Test, 'unityNorm');
fea_Test_kernelSpace = kernelize(fea_Test, opts, fea_Train);

fea_Test_Proj = fea_Test_kernelSpace * V;

%% evaluation
[predictLabel, predictScore, predictCost] = predict(Mdl, fea_Test_Proj);

gnd_ap = gnd_Test;
ap = cmpAp(predictScore(:,1), gnd_ap);
fprintf(1,'Target (%i), Data partion (%i), Kernel Type (%s), Kernel value (%d) - AP (%d)\n', trgLbl, k, opts.kerntype, opts.r, ap);

end
