% [y,i] = compsort( list, comparefun )
% Sorts a cell array according to <comparefun>
% y -- a cell array in sorted order
% i -- the indices to turn the original into sorted order
function [res,inds] = compsort(list,comparefun)
[res,inds] = helper(list(:), comparefun, 1:prod(size(list)));
res  = reshape(res, size(list));
inds = reshape(inds, size(list));

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [res, inds] = helper(list, comparefun, inds);
if ~iscell(list)
   error('compsort: expects a cell array');
end

n = length(list);

if n==0 | n == 1
   res = list;
else
   smaller = {}; smalleri = [];
   bigger = {}; biggeri = [];
   same = {}; samei = [];
   pivot = ceil(rand(1)*n);
   pivotitem = list{pivot};
   for k=1:n
      switch feval(comparefun,list{k},pivotitem)
      case 1
         same{end+1} = list{k};
         samei(end+1) = inds(k);
      case 2
         smaller{end+1} = list{k};
         smalleri(end+1) = inds(k);
      case 3
         bigger{end+1} = list{k};
         biggeri(end+1) = inds(k);
      otherwise
         error('compsort: illegal return value from comparefun.');
      end
   end
   [smaller, smalleri] = helper(smaller, comparefun, smalleri);
   [bigger, biggeri] = helper(bigger, comparefun,biggeri);
   res = [smaller; same; bigger];
   inds = [smalleri, samei, biggeri];
end
