function [significanceValue, permAUC] = permROC(Y, YPred, DMmeasure, nPerm)
%[significanceValue, permAUC] = permROC(Y, YPred, DMmeasure, nPerm);

%   permROC permutes the values in DM measure to determine the distribution
%   of AUC ROC values under the null hypothesis that the DM measure does
%   not carry any information.
%
%   Input
%   Y:                  Class labels ('0' for class 1, '1' for class 2)
%   YPred:              Predicted class labels
%   DMmeasure:          DM measure
%   nPerm:              Number of computed permutations
%
%   Output
%   significanceValue:  95th percentile of permutation distribution
%   permAUC:            AUC values for each permutation

% Initilaize random number generator with constant seed (for
% reproducibility)
seed = 0;
rng(seed, 'twister')

% Allocate variable for storing the permutation distribution
permAUC = zeros(nPerm, 1);

% Class predictions. Find indices for of objects for both classes. Used for
% generating the random permutations.
IdxClass1 = find(YPred == 0);
IdxClass2 = find(YPred == 1);

% Determine number of predicted objects for each class. Used for generating
% the random permutations.
n1Pred = length(IdxClass1);
n2Pred = length(IdxClass2);

% Determine the actual number of objects for each class. Needed for 
% computing AUC.
n1True = sum(Y == 0);
n2True = sum(Y == 1);
% Determine the indices (here through logical subscripting) to the actual
% objects of class 1. Needed for computing AUC.
IdxYTrueClass1 = (Y == 0);

% Allocate array for permuted DM measure
permDMmeas = zeros(size(DMmeasure));

for i = 1:nPerm
    % Randomly permute class indices based on predictions
    permIdxC1 = IdxClass1(randperm(n1Pred));
    permIdxC2 = IdxClass2(randperm(n2Pred));
    % Assign permuted DM measures 
    permDMmeas(IdxClass1) = DMmeasure(permIdxC1);
    permDMmeas(IdxClass2) = DMmeasure(permIdxC2);
    
    % Computation of AUC (see Till & Hand, Machine Learning, 45, 2001,
    % 171-186) for ranking list resulting from permuted DM measure. 
    
    % Determine ranks after permutation
    [Ranks] = tiedrank(permDMmeas);
    % Compute sum of ranks for objects of class 1
    S1 = sum(Ranks(IdxYTrueClass1));
    % Compute AUC from sum of ranks and class population
    auc = (S1 - (n1True * (n1True + 1) / 2)) / (n1True * n2True);
    % Store permutation distribution
    permAUC(i, 1) = auc;
    
end

% Significance value. 95% percentile of permutation distribution
significanceValue = prctile(permAUC, 95);

end

