def automorphism_group(self): """ Returns the group of permutations whose action on this structure leave it fixed. EXAMPLES:: sage: p = PermutationGroupElement((2,3,4)) sage: P = species.PermutationSpecies() sage: a = P.structures(["a", "b", "c", "d"]).random_element(); a ['a', 'c', 'b', 'd'] sage: a.automorphism_group() Permutation Group with generators [(2,3), (1,4)] :: sage: [a.transport(perm) for perm in a.automorphism_group()] [['a', 'c', 'b', 'd'], ['a', 'c', 'b', 'd'], ['a', 'c', 'b', 'd'], ['a', 'c', 'b', 'd']] """ from sage.groups.all import SymmetricGroup, PermutationGroup S = SymmetricGroup(len(self._labels)) p = self.permutation_group_element() return PermutationGroup(S.centralizer(p).gens())
def automorphism_group(self): """ Returns the group of permutations whose action on this subset leave it fixed. EXAMPLES:: sage: F = species.SubsetSpecies() sage: a = F.structures([1,2,3,4])[6]; a {1, 3} sage: a.automorphism_group() Permutation Group with generators [(2,4), (1,3)] :: sage: [a.transport(g) for g in a.automorphism_group()] [{1, 3}, {1, 3}, {1, 3}, {1, 3}] """ from sage.groups.all import SymmetricGroup, PermutationGroup a = SymmetricGroup(self._list) b = SymmetricGroup(self.complement()._list) return PermutationGroup(a.gens() + b.gens())
def automorphism_group(self): """ Returns the group of permutations whose action on this structure leave it fixed. EXAMPLES:: sage: P = species.CycleSpecies() sage: a = P.structures([1, 2, 3, 4]).random_element(); a (1, 2, 3, 4) sage: a.automorphism_group() Permutation Group with generators [(1,2,3,4)] :: sage: [a.transport(perm) for perm in a.automorphism_group()] [(1, 2, 3, 4), (1, 2, 3, 4), (1, 2, 3, 4), (1, 2, 3, 4)] """ from sage.groups.all import SymmetricGroup, PermutationGroup S = SymmetricGroup(len(self._labels)) p = self.permutation_group_element() return PermutationGroup(S.centralizer(p).gens())
def automorphism_group(self): """ Returns the group of permutations whose action on this structure leave it fixed. For the characteristic species, there is only one structure, so every permutation is in its automorphism group. EXAMPLES:: sage: F = species.CharacteristicSpecies(3) sage: a = F.structures(["a", "b", "c"]).random_element(); a {'a', 'b', 'c'} sage: a.automorphism_group() Symmetric group of order 3! as a permutation group """ from sage.groups.all import SymmetricGroup return SymmetricGroup(len(self._labels))
def automorphism_group(self): """ Returns the group of permutations whose action on this structure leave it fixed. For the species of linear orders, there is no non-trivial automorphism. EXAMPLES:: sage: F = species.LinearOrderSpecies() sage: a = F.structures(["a", "b", "c"])[0]; a ['a', 'b', 'c'] sage: a.automorphism_group() Symmetric group of order 1! as a permutation group """ from sage.groups.all import SymmetricGroup return SymmetricGroup(1)
def automorphism_group(self): """ Returns the group of permutations whose action on this set partition leave it fixed. EXAMPLES:: sage: p = PermutationGroupElement((2,3)) sage: from sage.combinat.species.partition_species import PartitionSpeciesStructure sage: a = PartitionSpeciesStructure(None, [2,3,4], [[1,2],[3]]); a {{2, 3}, {4}} sage: a.automorphism_group() Permutation Group with generators [(1,2)] """ from sage.groups.all import SymmetricGroup return reduce(lambda a, b: a.direct_product(b, maps=False), [SymmetricGroup(block._list) for block in self._list])
def change_support(perm, support, change_perm=None): """ Changes the support of a permutation defined on [1, ..., n] to support. EXAMPLES:: sage: from sage.combinat.species.misc import change_support sage: p = PermutationGroupElement((1,2,3)); p (1,2,3) sage: change_support(p, [3,4,5]) (3,4,5) """ if change_perm is None: change_perm = prod([ PermutationGroupElement((i + 1, support[i])) for i in range(len(support)) if i + 1 != support[i] ], PermutationGroupElement([], SymmetricGroup(support))) if isinstance(perm, PermutationGroup_generic): return PermutationGroup( [change_support(g, support, change_perm) for g in perm.gens()]) return change_perm * perm * ~change_perm
def has_irred_rep(self, n, gen_set=None, restrict=None, force=False): """ Returns `True` if there exists an `n`-dimensional irreducible representation of `self`, and `False` otherwise. Of course, this function runs `has_rep(n, restrict)` to verify there is a representation in the first place, and returns `False` if not. The argument `restrict` may be used equivalenty to its use in `has_rep()`. The argument `gen_set` may be set to `'PBW'` or `'pbw'`, if `self` has an algebra basis similar to that of a Poincaré-Birkhoff-Witt basis. Alternatively, an explicit generating set for the algorithm implemented by this function can be given, as a tuple or array of `FreeAlgebraElements`. This is only useful if the package cannot reduce the elements of `self`, but they can be reduced in theory. Use `force=True` if the function does not recognize the base field as computable, but the field is computable. """ if (not force and self.base_field() not in NumberFields and self.base_field() not in FiniteFields): raise TypeError( 'Base field must be computable. If %s is computable' % self.base_field() + ' then use force=True to bypass this.') if n not in ZZ or n < 1: raise ValueError('Dimension must be a positive integer.') if not self.has_rep(n, restrict): return False from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.groups.all import SymmetricGroup import math B = PolynomialRing(self.base_field(), (self.ngens() * n**2 + 1), 'x', order='deglex') M = MatrixSpace(B, n, sparse=True) gen_matrix = list() if not isinstance(restrict, (tuple, list)): restrict = [None for i in range(self.ngens())] if len(restrict) != self.ngens(): raise ValueError( 'Length of restrict does not match number of generators.') for i in range(self.ngens()): ith_gen_matrix = [] for j in range(n): for k in range(n): if restrict[i] == 'upper' and j > k: ith_gen_matrix.append(B.zero()) elif restrict[i] == 'lower' and j < k: ith_gen_matrix.append(B.zero()) elif restrict[i] == 'diagonal' and j != k: ith_gen_matrix.append(B.zero()) else: ith_gen_matrix.append(B.gen(j + (j + 1) * k + i * n**2)) gen_matrix.append(M(ith_gen_matrix)) relB = list() for i in range(self.nrels()): relB += self._to_matrix(self.rel(i), M, gen_matrix).list() Z = FreeAlgebra(ZZ, 2 * n - 2, 'Y') standard_poly = Z(0) for s in SymmetricGroup(2 * n - 2).list(): standard_poly += s.sign() * reduce( lambda x, y: x * y, [Z('Y%s' % (i - 1)) for i in s.tuple()]) if n <= 6 and is_NumberField(self.base_field()): p = 2 * n else: p = int( math.floor(n * math.sqrt(2 * n**2 / float(n - 1) + 1 / float(4)) + n / float(2) - 3)) if isinstance(gen_set, (tuple, list)): try: gen_set = [ self._to_matrix(elt, M, gen_matrix) for elt in gen_set ] except (NameError, TypeError) as error: print(error) if gen_set == None: word_gen_set = list(self._create_rep_gen_set(n, p)) gen_set = [ self._to_matrix(_to_element(self, [[word, self.one()]]), M, gen_matrix) for word in word_gen_set ] elif gen_set == 'pbw' or gen_set == 'PBW': word_gen_set = list(self._create_pbw_rep_gen_set(n, p)) gen_set = [ self._to_matrix(_to_element(self, [[word, self.one()]]), M, gen_matrix) for word in word_gen_set ] else: raise TypeError('Invalid generating set.') ordering = [i for i in range(2 * n - 2)] max_ordering = [ len(gen_set) - (2 * n - 2) + i for i in range(2 * n - 2) ] ordering.insert(0, 0) max_ordering.insert(0, len(gen_set)) rep_exists = False z = B.gen(B.ngens() - 1) while ordering[0] != max_ordering[0]: y = gen_set[ordering[0]].trace_of_product( standard_poly.subs({ Z('Y%s' % (j - 1)): gen_set[ordering[j]] for j in range(1, 2 * n - 1) })) radB_test = relB + [B(1) - z * y] if B.one() not in B.ideal(radB_test): rep_exists = True break for i in range(2 * n - 2, -1, -1): if i != 0 and ordering[i] != max_ordering[i]: ordering[i] += 1 break elif i == 0: ordering[i] += 1 if ordering[i] != max_ordering[i]: for j in range(1, 2 * n - 1): ordering[j] = j - 1 return rep_exists