Path: blob/master/sage/groups/matrix_gps/matrix_group_morphism.py
4057 views
"""1Homomorphisms Between Matrix Groups23AUTHORS:45- David Joyner and William Stein (2006-03): initial version67- David Joyner (2006-05): examples89- Simon King (2011-01): cleaning and improving code10"""1112#*****************************************************************************13# Copyright (C) 2006 David Joyner and William Stein <[email protected]>14#15# Distributed under the terms of the GNU General Public License (GPL)16# as published by the Free Software Foundation; either version 2 of17# the License, or (at your option) any later version.18# http://www.gnu.org/licenses/19#*****************************************************************************2021from sage.interfaces.gap import gap22from sage.categories.morphism import *23from sage.misc.latex import latex2425class MatrixGroupMap(Morphism):26"""27A set-theoretic map between matrix groups.28"""29def __init__(self, parent):30Morphism.__init__(self, parent)3132def _repr_type(self):33return "MatrixGroup"3435class MatrixGroupMorphism(MatrixGroupMap):36pass3738class MatrixGroupMorphism_im_gens(MatrixGroupMorphism):39"""40Some python code for wrapping GAP's GroupHomomorphismByImages41function but only for matrix groups. Can be expensive if G is42large.4344EXAMPLES::4546sage: F = GF(5); MS = MatrixSpace(F,2,2)47sage: G = MatrixGroup([MS([1,1,0,1])])48sage: H = MatrixGroup([MS([1,0,1,1])])49sage: phi = G.hom(H.gens())50sage: phi51Homomorphism : Matrix group over Finite Field of size 5 with 1 generators:52[[[1, 1], [0, 1]]] --> Matrix group over Finite Field of size 5 with 1 generators:53[[[1, 0], [1, 1]]]54sage: phi(MS([1,1,0,1]))55[1 0]56[1 1]57sage: F = GF(7); MS = MatrixSpace(F,2,2)58sage: F.multiplicative_generator()59360sage: G = MatrixGroup([MS([3,0,0,1])])61sage: a = G.gens()[0]^262sage: phi = G.hom([a])63"""64def __init__(self, homset, imgsH, check=True):65MatrixGroupMorphism.__init__(self, homset) # sets the parent66G = homset.domain()67H = homset.codomain()68gaplist_gens = [gap(x) for x in G.gens()]69gaplist_imgs = [gap(x) for x in imgsH]70genss = '[%s]'%(','.join(str(v) for v in gaplist_gens))71imgss = '[%s]'%(','.join(str(v) for v in gaplist_imgs))72args = '%s, %s, %s, %s'%(G._gap_init_(), H._gap_init_(), genss, imgss)73self._gap_str = 'GroupHomomorphismByImages(%s)'%args74phi0 = gap(self)75if gap.eval("IsGroupHomomorphism(%s)"%phi0.name())!="true":76raise ValueError,"The map "+str(gensG)+"-->"+str(imgsH)+" isn't a homomorphism."7778def _repr_(self):79"""80EXAMPLES::8182sage: F = GF(5); MS = MatrixSpace(F,2,2)83sage: G = MatrixGroup([MS([1,1,0,1])])84sage: H = MatrixGroup([MS([1,0,1,1])])85sage: phi = G.hom(H.gens())86sage: phi87Homomorphism : Matrix group over Finite Field of size 5 with 1 generators:88[[[1, 1], [0, 1]]] --> Matrix group over Finite Field of size 5 with 1 generators:89[[[1, 0], [1, 1]]]90sage: phi(MS([1,1,0,1]))91[1 0]92[1 1]93"""94return "Homomorphism : %s --> %s"%(self.domain(),self.codomain())9596def _latex_(self):97r"""98EXAMPLES::99100sage: F = GF(5); MS = MatrixSpace(F,2,2)101sage: G = MatrixGroup([MS([1,1,0,1])])102sage: phi = G.hom(G.gens())103sage: print latex(phi)104\left\langle \left(\begin{array}{rr}1051 & 1 \\1060 & 1107\end{array}\right) \right\rangle \rightarrow{} \left\langle \left(\begin{array}{rr}1081 & 1 \\1090 & 1110\end{array}\right) \right\rangle111"""112return "%s \\rightarrow{} %s"%(latex(self.domain()), latex(self.codomain()))113114def _gap_init_(self):115return self._gap_str116117def kernel(self):118"""119Return the kernel of ``self``, i.e., a matrix group.120121EXAMPLES::122123sage: F = GF(7); MS = MatrixSpace(F,2,2)124sage: F.multiplicative_generator()1253126sage: G = MatrixGroup([MS([3,0,0,1])])127sage: a = G.gens()[0]^2128sage: phi = G.hom([a])129sage: phi.kernel()130Matrix group over Finite Field of size 7 with 1 generators:131[[[6, 0], [0, 1]]]132133"""134gap_ker = gap(self).Kernel()135from sage.all import MatrixGroup136F = self.domain().base_ring()137return MatrixGroup([x._matrix_(F) for x in gap_ker.GeneratorsOfGroup()])138139def pushforward(self, J, *args,**kwds):140"""141The image of an element or a subgroup.142143INPUT:144145``J`` -- a subgroup or an element of the domain of ``self``.146147OUTPUT:148149The image of ``J`` under ``self``150151NOTE:152153``pushforward`` is the method that is used when a map is called on154anything that is not an element of its domain. For historical reasons,155we keep the alias ``image()`` for this method.156157EXAMPLES::158159sage: F = GF(7); MS = MatrixSpace(F,2,2)160sage: F.multiplicative_generator()1613162sage: G = MatrixGroup([MS([3,0,0,1])])163sage: a = G.gens()[0]^2164sage: phi = G.hom([a])165sage: phi.image(G.gens()[0]) # indirect doctest166[2 0]167[0 1]168sage: H = MatrixGroup([MS(a.list())])169sage: H170Matrix group over Finite Field of size 7 with 1 generators:171[[[2, 0], [0, 1]]]172173The following tests against trac ticket #10659::174175sage: phi(H) # indirect doctestest176Matrix group over Finite Field of size 7 with 1 generators:177[[[4, 0], [0, 1]]]178"""179phi = gap(self)180F = self.codomain().base_ring()181from sage.all import MatrixGroup182gapJ = gap(J)183if gap.eval("IsGroup(%s)"%gapJ.name()) == "true":184return MatrixGroup([x._matrix_(F) for x in phi.Image(gapJ).GeneratorsOfGroup()])185return phi.Image(gapJ)._matrix_(F)186187image = pushforward188189def _call_( self, g ):190"""191Some python code for wrapping GAP's Images function for a matrix192group G. Returns an error if g is not in G.193194EXAMPLES::195196sage: F = GF(5); MS = MatrixSpace(F,2,2)197sage: g = MS([1,1,0,1])198sage: G = MatrixGroup([g])199sage: phi = G.hom(G.gens())200sage: phi(G.0)201[1 1]202[0 1]203sage: phi(G(g^2))204[1 2]205[0 1]206207::208209sage: F = GF(5); MS = MatrixSpace(F,2,2)210sage: gens = [MS([1,2, -1,1]),MS([1,1, 0,1])]211sage: G = MatrixGroup(gens)212sage: phi = G.hom(G.gens())213sage: phi(G.0)214[1 2]215[4 1]216sage: phi(G.1)217[1 1]218[0 1]219220TEST:221222The following tests that the call method was successfully223improved in trac ticket #10659::224225sage: O = WeylGroup(['D',6])226sage: r = prod(O.gens())227sage: r_ = r^-1228sage: f = O.hom([r*x*r_ for x in O.gens()]) # long time (19s on sage.math, 2011)229sage: [f(x) for x in O.gens()] # long time230[231[1 0 0 0 0 0] [1 0 0 0 0 0] [1 0 0 0 0 0] [ 0 0 0 0 -1 0]232[0 0 1 0 0 0] [0 1 0 0 0 0] [0 1 0 0 0 0] [ 0 1 0 0 0 0]233[0 1 0 0 0 0] [0 0 0 1 0 0] [0 0 1 0 0 0] [ 0 0 1 0 0 0]234[0 0 0 1 0 0] [0 0 1 0 0 0] [0 0 0 0 1 0] [ 0 0 0 1 0 0]235[0 0 0 0 1 0] [0 0 0 0 1 0] [0 0 0 1 0 0] [-1 0 0 0 0 0]236[0 0 0 0 0 1], [0 0 0 0 0 1], [0 0 0 0 0 1], [ 0 0 0 0 0 1],237<BLANKLINE>238[0 0 0 0 0 1] [ 0 0 0 0 0 -1]239[0 1 0 0 0 0] [ 0 1 0 0 0 0]240[0 0 1 0 0 0] [ 0 0 1 0 0 0]241[0 0 0 1 0 0] [ 0 0 0 1 0 0]242[0 0 0 0 1 0] [ 0 0 0 0 1 0]243[1 0 0 0 0 0], [-1 0 0 0 0 0]244]245sage: f(O) # long time246Matrix group over Rational Field with 6 generators:247[[[1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1]], [[1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1]], [[1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1]], [[0, 0, 0, 0, -1, 0], [0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0], [-1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1]], [[0, 0, 0, 0, 0, 1], [0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0], [1, 0, 0, 0, 0, 0]], [[0, 0, 0, 0, 0, -1], [0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0], [-1, 0, 0, 0, 0, 0]]]248249"""250phi = gap(self)251G = self.domain()252F = G.base_ring()253h = gap(g)254return phi.Image(h)._matrix_(F)255256257