function ap = cmpAp(scoreVal, lbl)
%
% ap = cmpAp(scoreVal,lbl)
%
% Computes the average precision 
% 
% IN:
%  scoreVal: confidence scores for target class in [0,1]
%  lbl: ground truth labels - 1: target class, 2: rest-of-world class
%
% OUT:
%  ap: average precision
%
% Author: Nikolaos Gkalelis - ITI/CERTH
% Email: gkalelis@iti.gr
%
% First creation (Version 0.0) 1 Jan 2014.
% Version 0.1, 19 Jul 2017.
%

fprintf('cmpAp>>> Entering\n');

trueLbls = unique(lbl);
C = length(trueLbls);
N = length(lbl);

if C ~= 2
    error('cmpAP>> Number of classes must be two!');
end

if sum(lbl == 1) + sum(lbl == 2) ~= N
    error('cmpAP>> Labels can be 1 (target class) or 0 (rest-of-world class) !');
end

% simulate worst case scenario
lblPos = lbl(lbl == 1);
lblNeg = lbl(lbl == 2);

scoreValPos = scoreVal(lbl == 1);
scoreValNeg = scoreVal(lbl == 2);

lbl = [lblNeg; lblPos];
scoreVal = [scoreValNeg; scoreValPos];

% Rank decision values (top = most likely to be given positive label):
[~,idx] = sort(scoreVal,'descend');

% Reorder labels to match sorted decision values:
sortedLbl = lbl(idx);

% Total number of positive labels:
Ntrg = sum(lbl == 1);

% At the level of each positive (=1) label, evaluate precision:
trgPst = find(sortedLbl == 1);
prec = zeros(Ntrg,1);
for i = 1:length(trgPst)
    % At this level, evaluate precision = (# true / total #)
    prec(i) = sum(sortedLbl(1:trgPst(i)) == 1) / trgPst(i);
end

% Average precision over total number of positive examples:
ap = sum(prec) / Ntrg;

fprintf('cmpAp>>> Exiting\n');

