even_permutation
#
Even permutations
We call even permutation, a permutation on the set of even size X_n = {-n, -n+1, ldots, n-1}. The set X_n comes with a canonical involution without fixed points i mapsto -i-1 (note that -i-1 is the bit complement to i). The commutator of this canonical involution are the signed permutations.
- surface_dynamics.misc.even_permutation.even_perm_canonical_label(p)#
Canonical label for the permutation
p
assuming that together with the canonical involution it acts transitively on X_n = {-n, -n+1, ldots, n-1}.For fatgraphs, we use canonical labelings for the faces, so that canonical labels detect the orientable fatgraphs.
For the possible starting points, we only need to consider the ones that have one side in the largest and the other side in the smallest possible. For now, we run through all possibilities.
OUTPUT: a pair
(canonical_p, map)
EXAMPLES:
sage: from surface_dynamics.misc.even_permutation import (even_perm_check, ....: even_perm_canonical_label, even_perm_is_transitive, even_perm_relabel, ....: signed_permutations, even_perm_tilde) sage: from array import array sage: def test_perm(p): ....: p = array('l', p) ....: even_perm_check(p) ....: n = len(p) // 2 ....: assert even_perm_is_transitive(p) ....: c = even_perm_canonical_label(p)[0] ....: q = even_perm_tilde(p) ....: cc = even_perm_canonical_label(q)[0] ....: assert c == cc, (c, cc) ....: for q in signed_permutations(n): ....: pp = even_perm_relabel(p, q) ....: cc, mm = even_perm_canonical_label(pp) ....: assert cc == even_perm_relabel(pp, mm) ....: assert c == cc, (q, pp, cc) sage: test_perm([-2,0,1,-1,2,-3]) sage: test_perm([-2,0,1,2,-1,-3]) sage: test_perm([2,1,0,-1,-3,-2]) sage: test_perm([2,0,1,-1,-3,-2]) sage: test_perm([2,0,-4,1,-1,-3,-2,3]) sage: test_perm([0,2,1,3,-2,-1,-4,-3])
- surface_dynamics.misc.even_permutation.even_perm_canonical_label_from(p, i)#
Return canonical labels for
p
that starts ati
.INPUT:
p
– even permutationi
– integer in X_n = {-n, -n+1, ldots, n-1}
OUTPUT: a signed permutation that specifies the new labels
EXAMPLES:
sage: from array import array sage: from surface_dynamics.misc.even_permutation import (even_perm_canonical_label_from, ....: is_signed_perm) sage: p = array('l', [-1, 2, 0, 1, -3, -2]) sage: even_perm_canonical_label_from(p, 0) array('l', [0, -2, -3, 2, 1, -1]) sage: p = array('l', [1, 2, 0, -2, -1, -3]) sage: is_signed_perm(even_perm_canonical_label_from(p, 0)) True sage: p = array('l', [2,1,0,-1,-3,-2]) sage: even_perm_canonical_label_from(p, 1) array('l', [2, 0, 1, -2, -1, -3])
- surface_dynamics.misc.even_permutation.even_perm_check(p)#
EXAMPLES:
sage: from surface_dynamics.misc.even_permutation import even_perm_check sage: even_perm_check([0, 1, 2, -3, -2, -1]) sage: even_perm_check([0]) Traceback (most recent call last): ... ValueError: odd length sage: even_perm_check([-2,0]) Traceback (most recent call last): ... ValueError: element -2 at position 0 out of range sage: even_perm_check([0,1,-2,0]) Traceback (most recent call last): ... ValueError: element 0 repeated
- surface_dynamics.misc.even_permutation.even_perm_compose(p1, p2)#
Return the composition of
p1
andp2
EXAMPLES:
sage: from surface_dynamics.misc.even_permutation import even_perm_compose sage: p1 = [0, -1, 2, -3, 1, -2] sage: p2 = [-1, 0, -2, 1, -3, 2] sage: q = even_perm_compose(p1, p2) sage: q array('l', [-1, 2, -2, 1, 0, -3]) sage: p2[p1[3]] == q[3] True
- surface_dynamics.misc.even_permutation.even_perm_compose_i(p1, p2)#
Return the compositions of the inverses of
p1
andp2
EXAMPLES:
sage: from surface_dynamics.misc.even_permutation import (even_perm_compose, ....: even_perm_invert, even_perm_compose_i) sage: p1 = [0, -2, 2, 1, -1, -3] sage: p2 = [1, -1, -2, -3, 2, 0] sage: even_perm_compose_i(p1, p2) array('l', [-1, -3, -2, 1, 0, 2]) sage: even_perm_compose(even_perm_invert(p1), even_perm_invert(p2)) array('l', [-1, -3, -2, 1, 0, 2])
- surface_dynamics.misc.even_permutation.even_perm_cycles(p)#
EXAMPLES:
sage: from surface_dynamics.misc.even_permutation import even_perm_cycles sage: even_perm_cycles([-1,0]) ([(-1, 0)], [0, 0]) sage: even_perm_cycles([-1,0,-2,1]) ([(-2,), (-1, 1, 0)], [1, 1, 0, 1])
- surface_dynamics.misc.even_permutation.even_perm_identity(n)#
Return the identity
EXAMPLES:
sage: from surface_dynamics.misc.even_permutation import even_perm_identity sage: even_perm_identity(3) array('l', [0, 1, 2, -3, -2, -1]) sage: even_perm_identity(0) array('l')
- surface_dynamics.misc.even_permutation.even_perm_init(data)#
- surface_dynamics.misc.even_permutation.even_perm_invert(p)#
Return the inverse of
p
.EXAMPLES:
sage: from surface_dynamics.misc.even_permutation import (even_perm_invert, ....: even_perm_compose, even_perm_identity) sage: p = [-2,0,-1,1] sage: q = even_perm_invert(p) sage: q array('l', [1, -1, 0, -2]) sage: even_perm_compose(p,q) array('l', [0, 1, -2, -1]) sage: even_perm_compose(q,p) array('l', [0, 1, -2, -1]) sage: for _ in range(10): ....: n = randint(1, 20) ....: p = list(range(-n, n)) ....: shuffle(p) ....: q = even_perm_invert(p) ....: assert even_perm_compose(p, q) == even_perm_compose(q, p) == even_perm_identity(n)
- surface_dynamics.misc.even_permutation.even_perm_is_orientable(p)#
Test whether the permutation is orientable (that is do not mix non-negatives with negatives)
EXAMPLES:
sage: from surface_dynamics.misc.even_permutation import even_perm_is_orientable sage: even_perm_is_orientable([1,0,-1,-2]) True sage: even_perm_is_orientable([0,1,-2,-1]) True sage: even_perm_is_orientable([1,-1,0,-2]) False
- surface_dynamics.misc.even_permutation.even_perm_is_transitive(p)#
EXAMPLES:
sage: from array import array sage: from surface_dynamics.misc.even_permutation import even_perm_is_transitive sage: p = array('l', [0, 1, -2, -1]) sage: even_perm_is_transitive(p) False sage: p = array('l', [0, 1, -1, -2]) sage: even_perm_is_transitive(p) True sage: from itertools import permutations sage: for p in permutations((-2,-1,0,1)): ....: print("%s %s" % (p, even_perm_is_transitive(array('l',p)))) (-2, -1, 0, 1) True (-2, -1, 1, 0) True (-2, 0, -1, 1) True (-2, 0, 1, -1) True (-2, 1, -1, 0) True (-2, 1, 0, -1) True (-1, -2, 0, 1) True (-1, -2, 1, 0) False (-1, 0, -2, 1) True (-1, 0, 1, -2) True (-1, 1, -2, 0) False (-1, 1, 0, -2) True (0, -2, -1, 1) True (0, -2, 1, -1) False (0, -1, -2, 1) True (0, -1, 1, -2) True (0, 1, -2, -1) False (0, 1, -1, -2) True (1, -2, -1, 0) True (1, -2, 0, -1) True (1, -1, -2, 0) True (1, -1, 0, -2) True (1, 0, -2, -1) True (1, 0, -1, -2) True
- surface_dynamics.misc.even_permutation.even_perm_minus(n)#
EXAMPLES:
sage: from surface_dynamics.misc.even_permutation import even_perm_minus sage: even_perm_minus(2) array('l', [-1, -2, 1, 0])
- surface_dynamics.misc.even_permutation.even_perm_relabel(p, m)#
Relabel (= conjugate) the permutation
p
according tom
.INPUT:
p
- a list of even permutationsm
- a permutation
EXAMPLES:
sage: from surface_dynamics.misc.even_permutation import (even_perm_relabel, ....: even_perm_identity, even_perm_tilde) sage: even_perm_relabel([-1, 0, -2, 1], [1, 0, -2, -1]) array('l', [1, -1, -2, 0]) sage: from array import array sage: p = array('l', [1, -2, 0, -1]) sage: even_perm_relabel(p, even_perm_identity(2)) == p True sage: from surface_dynamics.misc.even_permutation import signed_permutations sage: p = array('l', [-2,0,1,2,-1,-3]) sage: for s in signed_permutations(3): ....: p1 = even_perm_relabel(even_perm_tilde(p), s) ....: p2 = even_perm_tilde(even_perm_relabel(p, s)) ....: assert p1 == p2
- surface_dynamics.misc.even_permutation.even_perm_tilde(p)#
EXAMPLES:
sage: from surface_dynamics.misc.even_permutation import even_perm_tilde sage: even_perm_tilde([1r, 0r, -1r, -2r]) array('l', [1, 0, -1, -2]) sage: even_perm_tilde([1r, -1r, -2r, 0r]) array('l', [-1, 1, 0, -2]) sage: from surface_dynamics.misc.even_permutation import even_permutations, is_signed_perm sage: all((p == even_perm_tilde(p)) == is_signed_perm(p) for p in even_permutations(3)) True
- surface_dynamics.misc.even_permutation.even_permutations(n)#
- surface_dynamics.misc.even_permutation.is_signed_perm(p)#
- surface_dynamics.misc.even_permutation.signed_permutations(n)#
EXAMPLES:
sage: from surface_dynamics.misc.even_permutation import signed_permutations sage: for p in signed_permutations(2): ....: assert p[0r] == ~p[~0r] ....: assert p[1r] == ~p[~1r]