Path: blob/master/src/sage/groups/perm_gps/permgroup_morphism.py
8815 views
r"""1Permutation group homomorphisms23AUTHORS:45- David Joyner (2006-03-21): first version67- David Joyner (2008-06): fixed kernel and image to return a group,8instead of a string.910EXAMPLES::1112sage: G = CyclicPermutationGroup(4)13sage: H = DihedralGroup(4)14sage: g = G([(1,2,3,4)])15sage: phi = PermutationGroupMorphism_im_gens(G, H, map(H, G.gens()))16sage: phi.image(G)17Subgroup of (Dihedral group of order 8 as a permutation group) generated by [(1,2,3,4)]18sage: phi.kernel()19Subgroup of (Cyclic group of order 4 as a permutation group) generated by [()]20sage: phi.image(g)21(1,2,3,4)22sage: phi(g)23(1,2,3,4)24sage: phi.codomain()25Dihedral group of order 8 as a permutation group26sage: phi.codomain()27Dihedral group of order 8 as a permutation group28sage: phi.domain()29Cyclic group of order 4 as a permutation group30"""3132#*****************************************************************************33# Copyright (C) 2006 David Joyner and William Stein <[email protected]>34#35# Distributed under the terms of the GNU General Public License (GPL)36# http://www.gnu.org/licenses/37#*****************************************************************************3839from sage.misc.superseded import deprecation40from sage.categories.morphism import Morphism41from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic4243class PermutationGroupMorphism(Morphism):44"""45A set-theoretic map between PermutationGroups.46"""47def _repr_type(self):48"""49Returns the type of this morphism. This is used for printing50the morphism.5152EXAMPLES::5354sage: G = PSL(2,7)55sage: D, iota1, iota2, pr1, pr2 = G.direct_product(G)56sage: pr1._repr_type()57'Permutation group'58"""59return "Permutation group"6061def range(self):62"""63Returns the codomain of this morphism. This method is64deprecated. Please use :meth:`codomain` instead.6566EXAMPLES::6768sage: G = PSL(2,7)69sage: D, iota1, iota2, pr1, pr2 = G.direct_product(G)70sage: pr1.range()71doctest:...: DeprecationWarning: range is deprecated. Please use codomain instead.72See http://trac.sagemath.org/10334 for details.73Permutation Group with generators [(3,7,5)(4,8,6), (1,2,6)(3,4,8)]74"""75deprecation(10334, 'range is deprecated. Please use codomain instead.')76return self.codomain()7778def kernel(self):79"""80Returns the kernel of this homomorphism as a permutation group.8182EXAMPLES::8384sage: G = CyclicPermutationGroup(4)85sage: H = DihedralGroup(4)86sage: g = G([(1,2,3,4)])87sage: phi = PermutationGroupMorphism_im_gens(G, H, [1])88sage: phi.kernel()89Subgroup of (Cyclic group of order 4 as a permutation group) generated by [(1,2,3,4)]9091::9293sage: G = PSL(2,7)94sage: D = G.direct_product(G)95sage: H = D[0]96sage: pr1 = D[3]97sage: G.is_isomorphic(pr1.kernel())98True99"""100return self.domain().subgroup(gap_group=self._gap_().Kernel())101102def image(self, J):103"""104J must be a subgroup of G. Computes the subgroup of H which is the105image of J.106107EXAMPLES::108109sage: G = CyclicPermutationGroup(4)110sage: H = DihedralGroup(4)111sage: g = G([(1,2,3,4)])112sage: phi = PermutationGroupMorphism_im_gens(G, H, map(H, G.gens()))113sage: phi.image(G)114Subgroup of (Dihedral group of order 8 as a permutation group) generated by [(1,2,3,4)]115sage: phi.image(g)116(1,2,3,4)117118::119120sage: G = PSL(2,7)121sage: D = G.direct_product(G)122sage: H = D[0]123sage: pr1 = D[3]124sage: pr1.image(G)125Subgroup of (The projective special linear group of degree 2 over Finite Field of size 7) generated by [(3,7,5)(4,8,6), (1,2,6)(3,4,8)]126sage: G.is_isomorphic(pr1.image(G))127True128"""129H = self.codomain()130if J in self.domain():131J = PermutationGroup([J])132G = self._gap_().Image(J)133return H.subgroup(gap_group=G).gens()[0]134else:135G = self._gap_().Image(J)136return H.subgroup(gap_group=G)137138def __call__(self, g):139"""140Some python code for wrapping GAP's Images function but only for141permutation groups. Returns an error if g is not in G.142143EXAMPLES::144145sage: G = CyclicPermutationGroup(4)146sage: H = DihedralGroup(4)147sage: phi = PermutationGroupMorphism_im_gens(G, H, map(H, G.gens()))148sage: g = G([(1,3),(2,4)]); g149(1,3)(2,4)150sage: phi(g)151(1,3)(2,4)152"""153return self.image(g)154155class PermutationGroupMorphism_id(PermutationGroupMorphism):156pass157158class PermutationGroupMorphism_from_gap(PermutationGroupMorphism):159def __init__(self, G, H, gap_hom):160"""161This is a Python trick to allow Sage programmers to create a group162homomorphism using GAP using very general constructions. An example163of its usage is in the direct_product instance method of the164PermutationGroup_generic class in permgroup.py.165166Basic syntax:167168PermutationGroupMorphism_from_gap(domain_group,169range_group,'phi:=gap_hom_command;','phi') And don't forget the170line: from sage.groups.perm_gps.permgroup_morphism import171PermutationGroupMorphism_from_gap in your program.172173EXAMPLES::174175sage: from sage.groups.perm_gps.permgroup_morphism import PermutationGroupMorphism_from_gap176sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4)]])177sage: H = G.subgroup([G([(1,2,3,4)])])178sage: PermutationGroupMorphism_from_gap(H, G, gap.Identity)179Permutation group morphism:180From: Subgroup of (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]) generated by [(1,2,3,4)]181To: Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]182Defn: Identity183"""184if not all(isinstance(X, PermutationGroup_generic) for X in [G, H]):185raise TypeError, "Sorry, the groups must be permutation groups."186PermutationGroupMorphism.__init__(self, G, H)187self._gap_hom = gap_hom188189def _repr_defn(self):190"""191Returns the definition of this morphism. This is used when192printing the morphism.193194EXAMPLES::195196sage: from sage.groups.perm_gps.permgroup_morphism import PermutationGroupMorphism_from_gap197sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4)]])198sage: H = G.subgroup([G([(1,2,3,4)])])199sage: phi = PermutationGroupMorphism_from_gap(H, G, gap.Identity)200sage: phi._repr_defn()201'Identity'202"""203return str(self._gap_hom).replace('\n', '')204205def _gap_(self, gap=None):206"""207Returns a GAP version of this morphism.208209EXAMPLES::210211sage: from sage.groups.perm_gps.permgroup_morphism import PermutationGroupMorphism_from_gap212sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4)]])213sage: H = G.subgroup([G([(1,2,3,4)])])214sage: phi = PermutationGroupMorphism_from_gap(H, G, gap.Identity)215sage: phi._gap_()216Identity217"""218return self._gap_hom219220def __call__(self, g):221"""222Some python code for wrapping GAP's Images function but only for223permutation groups. Returns an error if g is not in G.224225EXAMPLES::226227sage: G = PSL(2,7)228sage: D = G.direct_product(G)229sage: H = D[0]230sage: pr1 = D[3]231sage: [pr1(g) for g in G.gens()]232[(3,7,5)(4,8,6), (1,2,6)(3,4,8)]233"""234return self.codomain()(self._gap_().Image(g))235236237class PermutationGroupMorphism_im_gens(PermutationGroupMorphism):238def __init__(self, G, H, gens=None, images=None):239"""240Some python code for wrapping GAP's GroupHomomorphismByImages241function but only for permutation groups. Can be expensive if G is242large. Returns "fail" if gens does not generate self or if the map243does not extend to a group homomorphism, self - other.244245EXAMPLES::246247sage: G = CyclicPermutationGroup(4)248sage: H = DihedralGroup(4)249sage: phi = PermutationGroupMorphism_im_gens(G, H, map(H, G.gens())); phi250Permutation group morphism:251From: Cyclic group of order 4 as a permutation group252To: Dihedral group of order 8 as a permutation group253Defn: [(1,2,3,4)] -> [(1,2,3,4)]254sage: g = G([(1,3),(2,4)]); g255(1,3)(2,4)256sage: phi(g)257(1,3)(2,4)258sage: images = ((4,3,2,1),)259sage: phi = PermutationGroupMorphism_im_gens(G, G, images)260sage: g = G([(1,2,3,4)]); g261(1,2,3,4)262sage: phi(g)263(1,4,3,2)264265AUTHORS:266267- David Joyner (2006-02)268"""269if not all([isinstance(X, PermutationGroup_generic) for X in [G, H]]):270raise TypeError, "Sorry, the groups must be permutation groups."271if images is not None:272deprecation(10334, 'only the images need to be specified')273else:274images = gens275PermutationGroupMorphism.__init__(self, G, H)276self._images = [H(img) for img in images]277278def _repr_defn(self):279"""280Returns the definition of this morphism. This is used when281printing the morphism.282283EXAMPLES::284285sage: G = CyclicPermutationGroup(4)286sage: H = DihedralGroup(4)287sage: phi = PermutationGroupMorphism_im_gens(G, H, map(H, G.gens()))288sage: phi._repr_defn()289'[(1,2,3,4)] -> [(1,2,3,4)]'290"""291return "%s -> %s"%(self.domain().gens(), self._images)292293def _gap_(self):294"""295Returns a GAP representation of this morphism.296297EXAMPLES::298299sage: G = CyclicPermutationGroup(4)300sage: H = DihedralGroup(4)301sage: phi = PermutationGroupMorphism_im_gens(G, H, map(H, G.gens()))302sage: phi._gap_()303GroupHomomorphismByImages( Group( [ (1,2,3,4) ] ), Group(304[ (1,2,3,4), (1,4)(2,3) ] ), [ (1,2,3,4) ], [ (1,2,3,4) ] )305"""306return self.domain()._gap_().GroupHomomorphismByImages(self.codomain(), self.domain().gens(), self._images)307308def is_PermutationGroupMorphism(f):309"""310Returns True if the argument ``f`` is a PermutationGroupMorphism.311312EXAMPLES::313314sage: from sage.groups.perm_gps.permgroup_morphism import is_PermutationGroupMorphism315sage: G = CyclicPermutationGroup(4)316sage: H = DihedralGroup(4)317sage: phi = PermutationGroupMorphism_im_gens(G, H, map(H, G.gens()))318sage: is_PermutationGroupMorphism(phi)319True320"""321return isinstance(f, PermutationGroupMorphism)322323324