|
The function below also avoids the find() function, which is expensive, especially as n becomes large. For the output of perms it really doesn't matter what you use because n is small.
------------------------------------------------------
function s = SignCycs(p);
% p(1,n) is a permutation of {1,2,...,n}
% One of many definitions: Sign(p) = (-1)^(No. of even-length cycles)
% Complexity : O(n + ncycles) ~ O(n + Hn) ~~ O(n+log(n)) steps.
%
% USE :>> n = 10^8; p = GRPfys(n); s = SignCycs(p);
%
% Derek O'Connor 20 March 2011. derekroconnor@eircom.net
%
n = length(p);
visited = p<0;
% Logical array visited(1:n) = false which marks all p(k) not visited.
% Not needed if sign bit of p(k) is used. Messy.
s = 1;
for k = 1:n
if ~visited(k) % k not visited, start of new cycle
next = k;
L = 0;
while ~visited(next) % Traverse the current cycle k
L = L+1; % and find its length L
visited(next) = true;
next = p(next);
end
if rem(L,2) == 0 % If L is even, change sign.
s = -s;
end
end % if ~visited
end % for k
return % SignCycs
-----------------------------------------------------
The only extra memory used is the logical array visited(1,n). This may be eliminated if the sign-bit of p(k) is used to mark each 'node' of p, but the code is messier and error-prone.
With n = 10^6, time to generate p = 0.22 secs, time sign p = 0.13 secs
With n = 10^8, time to generate p = 31 secs, time sign p = 26 secs
Dell Precision 690, Intel 2xQuad-Core E5345 @ 2.33GHz 16GB RAM,
Windows7 64-bit Professional. MATLAB Version 7.6.0.324 (R2008a)
Derek O'Connor
|