I define even permutations as following, but there may be some error. I use it in two different way and get different output.
evenper[x_] := Select[Permutations[x], Signature[#] == 1 &]
Way 1:
evenper[x_] := Select[Permutations[x], Signature[#] == 1 &]
manual=evenper[{a, b, c, d}]
phi = 1.61803398875;
p1 = manual /. {a -> phi, b -> 1, c -> 1/phi, d -> 0};
p2 = manual /. {a -> phi, b -> 1, c -> -1/phi, d -> 0};
p3 = manual /. {a -> phi, b -> -1, c -> 1/phi, d -> 0};
p4 = manual /. {a -> phi, b -> -1, c -> -1/phi, d -> 0};
p5 = manual /. {a -> -phi, b -> 1, c -> 1/phi, d -> 0};
p6 = manual /. {a -> -phi, b -> 1, c -> -1/phi, d -> 0};
p7 = manual /. {a -> -phi, b -> -1, c -> 1/phi, d -> 0};
p8 = manual /. {a -> -phi, b -> -1, c -> -1/phi, d -> 0};
list1=Union[p1, p2, p3, p4, p5, p6, p7, p8]//Sort;
This result is what I want.
Way 2:
evenper[x_] := Select[Permutations[x], Signature[#] == 1 &]
phi = 1.61803398875;
list20 = #*{phi, 1, 1/phi, 0} & /@ (Tuples[{{1, -1}, {1, -1}, {1, -1}, {1}}]);
list2 = Flatten[evenper[#] & /@ list20, 1] // Sort;
But you will find list1 != list2
as following
Position[list1, {-1.618033988749895`, 0, 0.6180339887498948`, -1}]
Position[list2, {-1.618033988749895`, 0, 0.6180339887498948`, -1}]
(*{}*)
(*{{6}}*)
Answer
Thanks for updating your Question. With the new, clearer example I believe I can see the issue.
Analysis
The first method uses evenper
on Symbolic values that are in canonical order:
r1 = evenper[{a, b, c, d}]
{{a, b, c, d}, {a, c, d, b}, {a, d, b, c}, {b, a, d, c}, {b, c, a, d}, {b, d, c, a},
{c, a, b, d}, {c, b, d, a}, {c, d, a, b}, {d, a, c, b}, {d, b, a, c}, {d, c, b, a}}
Recalling the definition of Signature
Signature[list]
gives the signature of the permutation needed to place the elements oflist
in canonical order.
We cannot therefore expect the same permutations to be selected if evenper
is used on on elements that are not in canonical order:
rls = {a -> 2, b -> 1, c -> 3, d -> 4};
r2 = evenper[{a, b, c, d} /. rls]
r2 /. Reverse[rls, 2]
% === r1
{{2, 1, 4, 3}, {2, 3, 1, 4}, {2, 4, 3, 1}, {1, 2, 3, 4}, {1, 3, 4, 2}, {1, 4, 2, 3},
{3, 2, 4, 1}, {3, 1, 2, 4}, {3, 4, 1, 2}, {4, 2, 1, 3}, {4, 1, 3, 2}, {4, 3, 2, 1}}
{{a, b, d, c}, {a, c, b, d}, {a, d, c, b}, {b, a, c, d}, {b, c, d, a}, {b, d, a, c},
{c, a, d, b}, {c, b, a, d}, {c, d, b, a}, {d, a, b, c}, {d, b, c, a}, {d, c, a, b}}
False
Solution
If you wish to apply a certain set of permutations to arbitrary expressions, regardless of their canonical ordering, you can first permute a list of indices (natural numbers) and then use Part
to extract them from the expression list:
Select[Permutations @ Range @ 3, Signature[#] == 1 &]
{z, a, p}[[#]] & /@ %
{{1, 2, 3}, {2, 3, 1}, {3, 1, 2}}
{{z, a, p}, {a, p, z}, {p, z, a}}
Applied to your problem:
perms = Select[Permutations @ Range @ 4, Signature[#] == 1 &];
phi = 1.61803398875;
tup = # {phi, 1, 1/phi, 0} & /@ Tuples[{1, -1}, 4];
result = Union @@ Outer[Part, tup, perms, 1];
result == list1
True
As rasher informed me in a comment a greatly improved method for Mathematica 8 or later is to use AlternatingGroup
and Permute
as follows:
fn = # ~Permute~ AlternatingGroup[Length @ #] &;
fn @ {z, a, p}
{{z, a, p}, {a, p, z}, {p, z, a}}
perms === fn @ Range @ 4
True
Comments
Post a Comment