function [rawindex,expectation,variance,upvalue,sortvalues] = linassign_exact(prox)
% LINASSIGN_EXACT evaluates the salience of the sum of main diagonal entries (the
% trace) in an $n \times n$ square (but not necessarily
% symmetric) input matrix PROX using a (linear assignment) permutation
% strategy. The columns of PROX are permutated in all $n!$ possible ways with the
% matrix trace repeatedly computed. The original trace of PROX is RAWINDEX; the
% $n!$ index values are given (sorted in increasing order)
% in the vector SORTVALUES; EXPECTATION and VARIANCE are the exact mean and
% variance of the permutation distribution assuming that all $n!$ permutations
% are equally-likely; UPVALUE is the proportion of the NSTARTS indices that
% are as large or larger than RAWINDEX (i.e., UPVALUE is the upper-tail p-value for
% the observed index RAWINDEX). Given the type of computational storage
% required, $n!$ should be restricted to being less than or equal to, say,
% nine.
n= size(prox,1);
aone = (sum(sum(prox)))^2;
atwo = sum((sum(prox')).^2);
athree = sum((sum(prox)).^2);
afour = sum(sum(prox.^2));
expectation = (sum(sum(prox)))/n;
variance = ((aone/n) - (atwo + athree) + (n*afour))/(n*(n-1));
rawindex = sum(diag(prox));
upval = 0;
permutations = perms(1:n);
nfactorial = size(permutations,1);
indexvals = zeros(nfactorial,1);
for i = 1:nfactorial
iden = 1:n;
perm = permutations(i,:);
indexvals(i) = sum(diag(prox(iden,perm)));
if (indexvals(i) >= rawindex)
upval = upval + 1;
end
end
sortvalues = sort(indexvals)';
upvalue = upval/nfactorial;