Constellations¶
A constellation is a tuple \((g_0, g_1, \dots, g_k)\) of permutations such that the product \(g_0 g_1 ... g_k\) is the identity. One often assumes that the group generated by \(g_0, g_1, \dots, g_k\) acts transitively ([LZ2004] definition 1). Geometrically, it corresponds to a covering of the 2-sphere ramified over \(k\) points (the transitivity condition corresponds to the connectivity of the covering).
EXAMPLES:
sage: c = Constellation(['(1,2)', '(1,3)', None])
sage: c
Constellation of length 3 and degree 3
g0 (1,2)(3)
g1 (1,3)(2)
g2 (1,3,2)
sage: C = Constellations(3,4); C
Connected constellations of length 3 and degree 4 on {1, 2, 3, 4}
sage: C.cardinality() # long time
426
sage: C = Constellations(3, 4, domain=('a', 'b', 'c', 'd'))
sage: C
Connected constellations of length 3 and degree 4 on {'a', 'b', 'c', 'd'}
sage: c = C(('a','c'),(('b','c'),('a','d')), None)
sage: c
Constellation of length 3 and degree 4
g0 ('a','c')('b')('d')
g1 ('a','d')('b','c')
g2 ('a','d','c','b')
sage: c.is_connected()
True
sage: c.euler_characteristic()
2
sage: TestSuite(C).run()
- sage.combinat.constellation.Constellation(g=None, mutable=False, connected=True, check=True)¶
Constellation
INPUT:
g– a list of permutationsmutable– whether the result is mutable or not. Default isFalse.connected– whether the result should be connected. Default isTrue.check– whether or not to check. If it isTrue, then the listgmust contains noNone.
EXAMPLES:
Simple initialization:
sage: Constellation(['(0,1)','(0,3)(1,2)','(0,3,1,2)']) Constellation of length 3 and degree 4 g0 (0,1)(2)(3) g1 (0,3)(1,2) g2 (0,3,1,2)
One of the permutation can be omitted:
sage: Constellation(['(0,1)', None, '(0,4)(1,2,3)']) Constellation of length 3 and degree 5 g0 (0,1)(2)(3)(4) g1 (0,3,2,1,4) g2 (0,4)(1,2,3)
One can define mutable constellations:
sage: Constellation(([0,2,1], [2,1,0], [1,2,0]), mutable=True) Constellation of length 3 and degree 3 g0 (0)(1,2) g1 (0,2)(1) g2 (0,1,2)
- class sage.combinat.constellation.Constellation_class(parent, g, connected, mutable, check)¶
Bases:
sage.structure.element.ElementConstellation
A constellation or a tuple of permutations \((g_0,g_1,...,g_k)\) such that the product \(g_0 g_1 ... g_k\) is the identity.
- braid_group_action(i)¶
Act on
selfas the braid group generator that exchanges position \(i\) and \(i+1\).INPUT:
i– integer in \([0, n-1]\) where \(n\) is the length ofself
EXAMPLES:
sage: sigma = lambda c, i: c.braid_group_action(i) sage: c = Constellation(['(0,1)(2,3,4)','(1,4)',None]); c Constellation of length 3 and degree 5 g0 (0,1)(2,3,4) g1 (0)(1,4)(2)(3) g2 (0,1,3,2,4) sage: sigma(c, 1) Constellation of length 3 and degree 5 g0 (0,1)(2,3,4) g1 (0,1,3,2,4) g2 (0,3)(1)(2)(4)
Check the commutation relation:
sage: c = Constellation(['(0,1)(2,3,4)','(1,4)','(2,5)(0,4)',None]) sage: d = Constellation(['(0,1,3,5)','(2,3,4)','(0,3,5)',None]) sage: c13 = sigma(sigma(c, 0), 2) sage: c31 = sigma(sigma(c, 2), 0) sage: c13 == c31 True sage: d13 = sigma(sigma(d, 0), 2) sage: d31 = sigma(sigma(d, 2), 0) sage: d13 == d31 True
Check the braid relation:
sage: c121 = sigma(sigma(sigma(c, 1), 2), 1) sage: c212 = sigma(sigma(sigma(c, 2), 1), 2) sage: c121 == c212 True sage: d121 = sigma(sigma(sigma(d, 1), 2), 1) sage: d212 = sigma(sigma(sigma(d, 2), 1), 2) sage: d121 == d212 True
- braid_group_orbit()¶
Return the graph of the action of the braid group.
The action is considered up to isomorphism of constellation.
EXAMPLES:
sage: c = Constellation(['(0,1)(2,3,4)','(1,4)',None]); c Constellation of length 3 and degree 5 g0 (0,1)(2,3,4) g1 (0)(1,4)(2)(3) g2 (0,1,3,2,4) sage: G = c.braid_group_orbit() sage: G.num_verts() 4 sage: G.num_edges() 12
- connected_components()¶
Return the connected components.
OUTPUT:
A list of connected constellations.
EXAMPLES:
sage: c = Constellation(['(0,1)(2)', None, '(0,1)(2)'], connected=False) sage: cc = c.connected_components(); cc [Constellation of length 3 and degree 2 g0 (0,1) g1 (0)(1) g2 (0,1), Constellation of length 3 and degree 1 g0 (0) g1 (0) g2 (0)] sage: all(c2.is_connected() for c2 in cc) True sage: c = Constellation(['(0,1,2)', None], connected=False) sage: c.connected_components() [Constellation of length 2 and degree 3 g0 (0,1,2) g1 (0,2,1)]
- copy()¶
Return a copy of
self.
- degree()¶
Return the degree of the constellation.
The degree of a constellation is the number \(n\) that corresponds to the symmetric group \(S(n)\) in which the permutations of the constellation are defined.
EXAMPLES:
sage: c = Constellation([]) sage: c.degree() 0 sage: c = Constellation(['(0,1)',None]) sage: c.degree() 2 sage: c = Constellation(['(0,1)','(0,3,2)(1,5)',None,'(4,3,2,1)']) sage: c.degree() 6
- euler_characteristic()¶
Return the Euler characteristic of the surface.
ALGORITHM:
Hurwitz formula
EXAMPLES:
sage: c = Constellation(['(0,1)', '(0,2)', None]) sage: c.euler_characteristic() 2 sage: c = Constellation(['(0,1,2,3)','(1,3,0,2)', '(0,3,1,2)', None]) sage: c.euler_characteristic() -4
- g(i=None)¶
Return the permutation \(g_i\) of the constellation.
INPUT:
i – integer or
None(default)
If
None, return instead the list of all \(g_i\).EXAMPLES:
sage: c = Constellation(['(0,1,2)(3,4)','(0,3)',None]) sage: c.g(0) (0,1,2)(3,4) sage: c.g(1) (0,3) sage: c.g(2) (0,4,3,2,1) sage: c.g() [(0,1,2)(3,4), (0,3), (0,4,3,2,1)]
- genus()¶
Return the genus of the surface.
EXAMPLES:
sage: c = Constellation(['(0,1)', '(0,2)', None]) sage: c.genus() 0 sage: c = Constellation(['(0,1)(2,3,4)','(1,3,4)(2,0)', None]) sage: c.genus() 1
- is_connected()¶
Test of connectedness.
EXAMPLES:
sage: c = Constellation(['(0,1)(2)', None, '(0,1)(2)'], connected=False) sage: c.is_connected() False sage: c = Constellation(['(0,1,2)', None], connected=False) sage: c.is_connected() True
- is_isomorphic(other, return_map=False)¶
Test of isomorphism.
Return
Trueif the constellations are isomorphic (i.e. related by a common conjugacy) and return the permutation that conjugate the two permutations ifreturn_mapisTruein such a way thatself.relabel(m) == other.ALGORITHM:
uses canonical labels obtained from the method
relabel().EXAMPLES:
sage: c = Constellation([[1,0,2],[2,1,0],[0,2,1],None]) sage: d = Constellation([[2,1,0],[0,2,1],[1,0,2],None]) sage: answer, mapping = c.is_isomorphic(d,return_map=True) sage: answer True sage: c.relabel(mapping) == d True
- is_mutable()¶
Return
Falseasselfis immutable.EXAMPLES:
sage: c = Constellation(([0,2,1],[2,1,0],[1,2,0]), mutable=False) sage: c.is_mutable() False
- length()¶
Return the number of permutations.
EXAMPLES:
sage: c = Constellation(['(0,1)','(0,2)','(0,3)',None]) sage: c.length() 4 sage: c = Constellation(['(0,1,3)',None,'(1,2)']) sage: c.length() 3
- mutable_copy()¶
Return a mutable copy of
self.EXAMPLES:
sage: c = Constellation(([0,2,1],[2,1,0],[1,2,0]), mutable=False) sage: d = c.mutable_copy() sage: d.is_mutable() True
- passport(i=None)¶
Return the profile of
self.The profile of a constellation is the tuple of partitions associated to the conjugacy classes of the permutations of the constellation.
This is also called the passport.
EXAMPLES:
sage: c = Constellation(['(0,1,2)(3,4)','(0,3)',None]) sage: c.profile() ([3, 2], [2, 1, 1, 1], [5])
- profile(i=None)¶
Return the profile of
self.The profile of a constellation is the tuple of partitions associated to the conjugacy classes of the permutations of the constellation.
This is also called the passport.
EXAMPLES:
sage: c = Constellation(['(0,1,2)(3,4)','(0,3)',None]) sage: c.profile() ([3, 2], [2, 1, 1, 1], [5])
- relabel(perm=None, return_map=False)¶
Relabel
self.If
permis provided then relabel with respect toperm. Otherwise use canonical labels. In that case, ifreturn_mapis provided, the return also the map used for canonical labels.Algorithm:
the cycle for g(0) are adjacent and the cycle are joined with respect to the other permutations. The minimum is taken for all possible renumerotations.
EXAMPLES:
sage: c = Constellation(['(0,1)(2,3,4)','(1,4)',None]); c Constellation of length 3 and degree 5 g0 (0,1)(2,3,4) g1 (0)(1,4)(2)(3) g2 (0,1,3,2,4) sage: c2 = c.relabel(); c2 Constellation of length 3 and degree 5 g0 (0,1)(2,3,4) g1 (0)(1,2)(3)(4) g2 (0,1,4,3,2)
The map returned when the option
return_mapis set toTruecan be used to set the relabelling:sage: c3, perm = c.relabel(return_map=True) sage: c3 == c2 and c3 == c.relabel(perm=perm) True sage: S5 = SymmetricGroup(range(5)) sage: d = c.relabel(S5([4,3,1,0,2])); d Constellation of length 3 and degree 5 g0 (0,2,1)(3,4) g1 (0)(1)(2,3)(4) g2 (0,1,2,4,3) sage: d.is_isomorphic(c) True
We check that after a random relabelling the new constellation is isomorphic to the initial one:
sage: c = Constellation(['(0,1)(2,3,4)','(1,4)',None]) sage: p = S5.random_element() sage: cc = c.relabel(perm=p) sage: cc.is_isomorphic(c) True
Check that it works for “non standard” labels:
sage: c = Constellation([(('a','b'),('c','d','e')),('b','d'), None]) sage: c.relabel() Constellation of length 3 and degree 5 g0 ('a','b')('c','d','e') g1 ('a')('b','c')('d')('e') g2 ('a','b','e','d','c')
- set_immutable()¶
Do nothing, as
selfis already immutable.EXAMPLES:
sage: c = Constellation(([0,2,1],[2,1,0],[1,2,0]), mutable=False) sage: c.set_immutable() sage: c.is_mutable() False
- switch(i, j0, j1)¶
Perform the multiplication by the transposition \((j0, j1)\) between the permutations \(g_i\) and \(g_{i+1}\).
The modification is local in the sense that it modifies \(g_i\) and \(g_{i+1}\) but does not modify the product \(g_i g_{i+1}\). The new constellation is
\[(g_0, \ldots, g_{i-1}, g_{i} (j0 j1), (j0 j1) g_{i+1}, g_{i+2}, \ldots, g_k)\]EXAMPLES:
sage: c = Constellation(['(0,1)(2,3,4)','(1,4)',None], mutable=True); c Constellation of length 3 and degree 5 g0 (0,1)(2,3,4) g1 (0)(1,4)(2)(3) g2 (0,1,3,2,4) sage: c.is_mutable() True sage: c.switch(1,2,3); c Constellation of length 3 and degree 5 g0 (0,1)(2,3,4) g1 (0)(1,4)(2,3) g2 (0,1,3,4)(2) sage: c._check() sage: c.switch(2,1,3); c Constellation of length 3 and degree 5 g0 (0,1,4,2,3) g1 (0)(1,4)(2,3) g2 (0,3,4)(1)(2) sage: c._check() sage: c.switch(0,0,1); c Constellation of length 3 and degree 5 g0 (0)(1,4,2,3) g1 (0,4,1)(2,3) g2 (0,3,4)(1)(2) sage: c._check()
- sage.combinat.constellation.Constellations(*data, **options)¶
Build a set of constellations.
INPUT:
profile– an optional profilelength– an optional lengthdegree– an optional degreeconnected– an optional boolean
EXAMPLES:
sage: Constellations(4,2) Connected constellations of length 4 and degree 2 on {1, 2} sage: Constellations([[3,2,1],[3,3],[3,3]]) Connected constellations with profile ([3, 2, 1], [3, 3], [3, 3]) on {1, 2, 3, 4, 5, 6}
- class sage.combinat.constellation.Constellations_ld(length, degree, sym=None, connected=True)¶
Bases:
sage.structure.unique_representation.UniqueRepresentation,sage.structure.parent.ParentConstellations of given length and degree.
EXAMPLES:
sage: C = Constellations(2,3); C Connected constellations of length 2 and degree 3 on {1, 2, 3} sage: C([[2,3,1],[3,1,2]]) Constellation of length 2 and degree 3 g0 (1,2,3) g1 (1,3,2) sage: C.cardinality() 2 sage: Constellations(2,3,connected=False).cardinality() 6
- Element¶
alias of
Constellation_class
- braid_group_action()¶
Return a list of graphs that corresponds to the braid group action on
selfup to isomorphism.OUTPUT:
list of graphs
EXAMPLES:
sage: C = Constellations(3,3) sage: C.braid_group_action() [Looped multi-digraph on 3 vertices, Looped multi-digraph on 1 vertex, Looped multi-digraph on 3 vertices]
- braid_group_orbits()¶
Return the orbits under the action of braid group.
EXAMPLES:
sage: C = Constellations(3,3) sage: O = C.braid_group_orbits() sage: len(O) 3 sage: [x.profile() for x in O[0]] [([1, 1, 1], [3], [3]), ([3], [1, 1, 1], [3]), ([3], [3], [1, 1, 1])] sage: [x.profile() for x in O[1]] [([3], [3], [3])] sage: [x.profile() for x in O[2]] [([2, 1], [2, 1], [3]), ([2, 1], [3], [2, 1]), ([3], [2, 1], [2, 1])]
- is_empty()¶
Return whether this set of constellations is empty.
EXAMPLES:
sage: Constellations(2, 3).is_empty() False sage: Constellations(1, 2).is_empty() True sage: Constellations(1, 2, connected=False).is_empty() False
- random_element(mutable=False)¶
Return a random element.
This is found by trial and rejection, starting from a random list of permutations.
EXAMPLES:
sage: const = Constellations(3,3) sage: const.random_element() Constellation of length 3 and degree 3 ... ... ... sage: c = const.random_element() sage: c.degree() == 3 and c.length() == 3 True
- class sage.combinat.constellation.Constellations_p(profile, domain=None, connected=True)¶
Bases:
sage.structure.unique_representation.UniqueRepresentation,sage.structure.parent.ParentConstellations with fixed profile.
EXAMPLES:
sage: C = Constellations([[3,1],[3,1],[2,2]]); C Connected constellations with profile ([3, 1], [3, 1], [2, 2]) on {1, 2, 3, 4} sage: C.cardinality() 24 sage: C.first() Constellation of length 3 and degree 4 g0 (1)(2,3,4) g1 (1,2,3)(4) g2 (1,2)(3,4) sage: C.last() Constellation of length 3 and degree 4 g0 (1,4,3)(2) g1 (1,4,2)(3) g2 (1,2)(3,4)
Note that the cardinality can also be computed using characters of the symmetric group (Frobenius formula):
sage: P = Partitions(4) sage: p1 = Partition([3,1]) sage: p2 = Partition([3,1]) sage: p3 = Partition([2,2]) sage: i1 = P.cardinality() - P.rank(p1) - 1 sage: i2 = P.cardinality() - P.rank(p2) - 1 sage: i3 = P.cardinality() - P.rank(p3) - 1 sage: s = 0 sage: for c in SymmetricGroup(4).irreducible_characters(): ....: v = c.values() ....: s += v[i1] * v[i2] * v[i3] / v[0] sage: c1 = p1.conjugacy_class_size() sage: c2 = p2.conjugacy_class_size() sage: c3 = p3.conjugacy_class_size() sage: c1 * c2 * c3 / factorial(4)**2 * s 1
The number obtained above is up to isomorphism. And we can check:
sage: len(C.isomorphism_representatives()) 1
- isomorphism_representatives()¶
Return a set of isomorphism representative of
self.EXAMPLES:
sage: C = Constellations([[5], [4,1], [3,2]]) sage: C.cardinality() 240 sage: ir = sorted(C.isomorphism_representatives()) sage: len(ir) 2 sage: ir[0] Constellation of length 3 and degree 5 g0 (1,2,3,4,5) g1 (1)(2,3,4,5) g2 (1,5,3)(2,4) sage: ir[1] Constellation of length 3 and degree 5 g0 (1,2,3,4,5) g1 (1)(2,5,3,4) g2 (1,5)(2,3,4)
- sage.combinat.constellation.perm_conjugate(p, s)¶
Return the conjugate of the permutation \(p\) by the permutation \(s\).
INPUT:
two permutations of {0,..,n-1} given by lists of values
OUTPUT:
a permutation of {0,..,n-1} given by a list of values
EXAMPLES:
sage: from sage.combinat.constellation import perm_conjugate sage: perm_conjugate([3,1,2,0], [3,2,0,1]) [0, 3, 2, 1]
- sage.combinat.constellation.perm_invert(p)¶
Return the inverse of the permutation \(p\).
INPUT:
a permutation of {0,..,n-1} given by a list of values
OUTPUT:
a permutation of {0,..,n-1} given by a list of values
EXAMPLES:
sage: from sage.combinat.constellation import perm_invert sage: perm_invert([3,2,0,1]) [2, 3, 1, 0]
- sage.combinat.constellation.perm_sym_domain(g)¶
Return the domain of a single permutation (before initialization).
EXAMPLES:
sage: from sage.combinat.constellation import perm_sym_domain sage: perm_sym_domain([1,2,3,4]) {1, 2, 3, 4} sage: perm_sym_domain(((1,2),(0,4))) {0, 1, 2, 4} sage: sorted(perm_sym_domain('(1,2,0,5)')) [0, 1, 2, 5]
- sage.combinat.constellation.perms_are_connected(g, n)¶
Checks that the action of the generated group is transitive
INPUT:
a list of permutations of \([0, n-1]\) (in a SymmetricGroup)
an integer \(n\)
EXAMPLES:
sage: from sage.combinat.constellation import perms_are_connected sage: S = SymmetricGroup(range(3)) sage: perms_are_connected([S([0,1,2]),S([0,2,1])],3) False sage: perms_are_connected([S([0,1,2]),S([1,2,0])],3) True
- sage.combinat.constellation.perms_canonical_labels(p, e=None)¶
Relabel a list with a common conjugation such that two conjugated lists are relabeled the same way.
INPUT:
pis a list of at least 2 permutationseis None or a list of integer in the domain of the permutations. If provided, then the renumbering algorithm is only performed from the elements ofe.
OUTPUT:
a pair made of a list of permutations (as a list of lists) and a list that corresponds to the conjugacy used.
EXAMPLES:
sage: from sage.combinat.constellation import perms_canonical_labels sage: l0 = [[2,0,3,1], [3,1,2,0], [0,2,1,3]] sage: l, m = perms_canonical_labels(l0); l [[1, 2, 3, 0], [0, 3, 2, 1], [2, 1, 0, 3]] sage: S = SymmetricGroup(range(4)) sage: [~S(m) * S(u) * S(m) for u in l0] == list(map(S, l)) True sage: perms_canonical_labels([]) Traceback (most recent call last): ... ValueError: input must have length >= 2
- sage.combinat.constellation.perms_canonical_labels_from(x, y, j0, verbose=False)¶
Return canonical labels for
x,ythat starts atj0Warning
The group generated by
xand the elements ofyshould be transitive.INPUT:
x– list - a permutation of \([0, ..., n]\) as a listy– list of permutations of \([0, ..., n]\) as a list of listsj0– an index in [0, …, n]
OUTPUT:
mapping: a permutation that specify the new labels
EXAMPLES:
sage: from sage.combinat.constellation import perms_canonical_labels_from sage: perms_canonical_labels_from([0,1,2],[[1,2,0]], 0) [0, 1, 2] sage: perms_canonical_labels_from([1,0,2], [[2,0,1]], 0) [0, 1, 2] sage: perms_canonical_labels_from([1,0,2], [[2,0,1]], 1) [1, 0, 2] sage: perms_canonical_labels_from([1,0,2], [[2,0,1]], 2) [2, 1, 0]
- sage.combinat.constellation.perms_sym_init(g, sym=None)¶
Initialize a list of permutations (in the same symmetric group).
OUTPUT:
sym– a symmetric groupgg– a list of permutations
EXAMPLES:
sage: from sage.combinat.constellation import perms_sym_init sage: S, g = perms_sym_init([[0,2,1,3], [1,3,2,0]]) sage: S.domain() {0, 1, 2, 3} sage: g [(1,2), (0,1,3)] sage: S, g = perms_sym_init(['(2,1)', '(0,3)']) sage: S.domain() {0, 1, 2, 3} sage: g [(1,2), (0,3)] sage: S, g = perms_sym_init([(1,0), (2,1)]) sage: S.domain() {0, 1, 2} sage: g [(0,1), (1,2)] sage: S, g = perms_sym_init([((1,0),(2,3)), '(0,1,4)']) sage: S.domain() {0, 1, 2, 3, 4} sage: g [(0,1)(2,3), (0,1,4)]