% Compute a precision-recall curve from a similaritiy matrix and
% ground-truth information.
% 
% S ... pairwise similarity matrix
% GThard ... ground truth matching matrix: places that MUST be matched
% GTsoft ... ground truth matching matrix: places that CAN be matched, but
%            not are not necessary (to deal with ambiguous matchings), optional
%
%   =====================================================================
%   Copyright (C) 2021  Stefan Schubert, stefan.schubert@etit.tu-chemnitz.de
%   
%   This program is free software: you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation, either version 3 of the License, or
%   (at your option) any later version.
%   
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%   
%   You should have received a copy of the GNU General Public License
%   along with this program.  If not, see <http://www.gnu.org/licenses/>.
%   =====================================================================
% 
function [P, R] = createPR(S, GThard, GTsoft)

    GT = logical(GThard); % ensure logical-datatype
        
    % remove soft-but-not-hard-entries
    if ~isempty(GTsoft)
        S(logical(GTsoft) & ~GT) = min(S(:));
    end
    
    % init precision and recall vectors
    R = 0;
    P = 1;
    
    % select start and end treshold
    startV = max(S(:)); % start-value for treshold
    endV = min(S(:)); % end-value for treshold
    
    % iterate over different thresholds
    for i=linspace(startV, endV, 100) 
        B = S>=i; % apply threshold
        
        TP = nnz( GT & B ); % true positives
        FN = nnz( GT & (~B) ); % false negatives
        FP = nnz( (~GT) & B ); % false positives
        
        P(end+1) = TP/(TP + FP); % precision
        R(end+1) = TP/(TP + FN); % recall
    end
end
