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;