Path: blob/master/src/sage/groups/matrix_gps/group_element.py
8815 views
"""1Matrix Group Elements23EXAMPLES::45sage: F = GF(3); MS = MatrixSpace(F,2,2)6sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]7sage: G = MatrixGroup(gens); G8Matrix group over Finite Field of size 3 with 2 generators (9[1 0] [1 1]10[0 1], [0 1]11)12sage: g = G([[1,1],[0,1]])13sage: h = G([[1,2],[0,1]])14sage: g*h15[1 0]16[0 1]1718You cannot add two matrices, since this is not a group operation.19You can coerce matrices back to the matrix space and add them20there::2122sage: g + h23Traceback (most recent call last):24...25TypeError: unsupported operand type(s) for +:26'FinitelyGeneratedMatrixGroup_gap_with_category.element_class' and27'FinitelyGeneratedMatrixGroup_gap_with_category.element_class'2829sage: g.matrix() + h.matrix()30[2 0]31[0 2]3233Similarly, you cannot multiply group elements by scalars but you can34do it with the underlying matrices::3536sage: 2*g37Traceback (most recent call last):38...39TypeError: unsupported operand parent(s) for '*': 'Integer Ring' and 'Matrix group over Finite Field of size 3 with 2 generators (40[1 0] [1 1]41[0 1], [0 1]42)'4344AUTHORS:4546- David Joyner (2006-05): initial version David Joyner4748- David Joyner (2006-05): various modifications to address William49Stein's TODO's.5051- William Stein (2006-12-09): many revisions.5253- Volker Braun (2013-1) port to new Parent, libGAP.54"""5556#*****************************************************************************57# Copyright (C) 2006 David Joyner and William Stein <[email protected]>58# Copyright (C) 2013 Volker Braun <[email protected]>59#60# Distributed under the terms of the GNU General Public License (GPL)61#62# http://www.gnu.org/licenses/63#*****************************************************************************6465from sage.interfaces.gap import gap66from sage.structure.element import MultiplicativeGroupElement67from sage.matrix.matrix import Matrix, is_Matrix68from sage.structure.factorization import Factorization69from sage.structure.sage_object import have_same_parent70from sage.libs.gap.element import GapElement, GapElement_List71from sage.misc.cachefunc import cached_method72from sage.groups.libgap_wrapper import ElementLibGAP73from sage.groups.libgap_mixin import GroupElementMixinLibGAP747576def is_MatrixGroupElement(x):77"""78Test whether ``x`` is a matrix group element7980INPUT:8182- ``x`` -- anything.8384OUTPUT:8586Boolean.8788EXAMPLES::8990sage: from sage.groups.matrix_gps.group_element import is_MatrixGroupElement91sage: is_MatrixGroupElement('helloooo')92False9394sage: G = GL(2,3)95sage: is_MatrixGroupElement(G.an_element())96True97"""98return isinstance(x, MatrixGroupElement_base)99100101102class MatrixGroupElement_base(MultiplicativeGroupElement):103"""104Base class for elements of matrix groups.105106You should use one of the two subclasses:107108* :class:`MatrixGroupElement_sage` implements the group109mulitplication using Sage matrices.110111* :class:`MatrixGroupElement_gap` implements the group112mulitplication using libGAP matrices.113114The base class only assumes that derived classes implement115:meth:`matrix`.116117EXAMPLES::118119sage: F = GF(3); MS = MatrixSpace(F,2,2)120sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]121sage: G = MatrixGroup(gens)122sage: g = G.random_element()123sage: type(g)124<class 'sage.groups.matrix_gps.group_element.FinitelyGeneratedMatrixGroup_gap_with_category.element_class'>125"""126127def _repr_(self):128"""129Return string representation of this matrix.130131EXAMPLES::132133sage: F = GF(3); MS = MatrixSpace(F,2,2)134sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]135sage: G = MatrixGroup(gens)136sage: g = G([[1, 1], [0, 1]])137sage: g # indirect doctest138[1 1]139[0 1]140sage: g._repr_()141'[1 1]\n[0 1]'142"""143return str(self.matrix())144145def _latex_(self):146r"""147EXAMPLES::148149sage: F = GF(3); MS = MatrixSpace(F,2,2)150sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]151sage: G = MatrixGroup(gens)152sage: g = G([[1, 1], [0, 1]])153sage: print g._latex_()154\left(\begin{array}{rr}1551 & 1 \\1560 & 1157\end{array}\right)158159Type ``view(g._latex_())`` to see the object in an160xdvi window (assuming you have latex and xdvi installed).161"""162return self.matrix()._latex_()163164def _act_on_(self, x, self_on_left):165"""166EXAMPLES::167168sage: G = GL(4,7)169sage: G.0 * vector([1,2,3,4])170(3, 2, 3, 4)171sage: v = vector(GF(7), [3,2,1,-1])172sage: g = G.1173sage: v * g == v * g.matrix() # indirect doctest174True175"""176if not is_MatrixGroupElement(x) and x not in self.parent().base_ring():177try:178if self_on_left:179return self.matrix() * x180else:181return x * self.matrix()182except TypeError:183return None184185def __cmp__(self, other):186"""187EXAMPLES::188189sage: F = GF(3); MS = MatrixSpace(F,2)190sage: gens = [MS([1,0, 0,1]), MS([1,1, 0,1])]191sage: G = MatrixGroup(gens)192sage: g = G([1,1, 0,1])193sage: h = G([1,1, 0,1])194sage: g == h195True196sage: g == G.one()197False198"""199return cmp(self.matrix(), other.matrix())200201def list(self):202"""203Return list representation of this matrix.204205EXAMPLES::206207sage: F = GF(3); MS = MatrixSpace(F,2,2)208sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]209sage: G = MatrixGroup(gens)210sage: g = G.0211sage: g212[1 0]213[0 1]214sage: g.list()215[[1, 0], [0, 1]]216"""217return map(list, self.matrix().rows())218219220###################################################################221#222# Matrix groups elements implemented with Sage matrices223#224###################################################################225226class MatrixGroupElement_generic(MatrixGroupElement_base):227228def __init__(self, parent, M, check=True, convert=True):229r"""230Element of a matrix group over a generic ring.231232The group elements are implemented as Sage matrices.233234INPUT:235236- ``M`` -- a matrix.237238- ``parent`` -- the parent.239240- ``check`` -- bool (default: ``True``). If true does some241type checking.242243- ``convert`` -- bool (default: ``True``). If true convert244``M`` to the right matrix space.245246TESTS::247248sage: F = GF(3); MS = MatrixSpace(F,2,2)249sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]250sage: G = MatrixGroup(gens)251sage: g = G.random_element()252sage: TestSuite(g).run()253"""254if convert:255M = parent.matrix_space()(M)256if check:257if not is_Matrix(M):258raise TypeError('M must be a matrix')259if M.parent() is not parent.matrix_space():260raise TypeError('M must be a in the matrix space of the group')261parent._check_matrix(M)262super(MatrixGroupElement_generic, self).__init__(parent)263if M.is_immutable():264self._matrix = M265else:266self._matrix = M.__copy__()267self._matrix.set_immutable()268269def matrix(self):270"""271Obtain the usual matrix (as an element of a matrix space)272associated to this matrix group element.273274One reason to compute the associated matrix is that matrices275support a huge range of functionality.276277EXAMPLES::278279sage: k = GF(7); G = MatrixGroup([matrix(k,2,[1,1,0,1]), matrix(k,2,[1,0,0,2])])280sage: g = G.0281sage: g.matrix()282[1 1]283[0 1]284sage: parent(g.matrix())285Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7286287Matrices have extra functionality that matrix group elements288do not have::289290sage: g.matrix().charpoly('t')291t^2 + 5*t + 1292"""293return self._matrix294295def _mul_(self,other):296"""297Return the product of self and other, which must have identical298parents.299300EXAMPLES::301302sage: F = GF(3); MS = MatrixSpace(F,2)303sage: gens = [MS([1,0, 0,1]), MS([1,1, 0,1])]304sage: G = MatrixGroup(gens)305sage: g = G([1,1, 0,1])306sage: h = G([1,1, 0,1])307sage: g*h # indirect doctest308[1 2]309[0 1]310"""311parent = self.parent()312return parent.element_class(parent, self._matrix * other._matrix,313check=False, convert=False)314315def __invert__(self):316"""317Return the inverse group element318319OUTPUT:320321A matrix group element.322323EXAMPLES::324325sage: G = GL(2,3)326sage: g = G([1,2,1,0]); g327[1 2]328[1 0]329sage: g.__invert__()330[0 1]331[2 1]332sage: g * (~g)333[1 0]334[0 1]335"""336parent = self.parent()337return parent.element_class(parent, ~self._matrix, check=False, convert=False)338339inverse = __invert__340341def conjugacy_class(self):342r"""343Return the conjugacy class of ``self``.344345OUTPUT:346347The conjugacy class of ``g`` in the group ``self``. If ``self`` is the348group denoted by `G`, this method computes the set349`\{x^{-1}gx\ \vert\ x\in G\}`.350351EXAMPLES::352353sage: G = SL(2, GF(2))354sage: g = G.gens()[0]355sage: g.conjugacy_class()356Conjugacy class of [1 1]357[0 1] in Special Linear Group of degree 2 over Finite Field of size 2358"""359from sage.groups.conjugacy_classes import ConjugacyClass360return ConjugacyClass(self.parent(), self)361362363###################################################################364#365# Matrix group elements implemented in GAP366#367###################################################################368369class MatrixGroupElement_gap(GroupElementMixinLibGAP, MatrixGroupElement_base, ElementLibGAP):370371def __init__(self, parent, M, check=True, convert=True):372r"""373Element of a matrix group over a generic ring.374375The group elements are implemented as Sage matrices.376377INPUT:378379- ``M`` -- a matrix.380381- ``parent`` -- the parent.382383- ``check`` -- bool (default: ``True``). If true does some384type checking.385386- ``convert`` -- bool (default: ``True``). If true convert387``M`` to the right matrix space.388389TESTS::390391sage: MS = MatrixSpace(GF(3),2,2)392sage: G = MatrixGroup(MS([[1,0],[0,1]]), MS([[1,1],[0,1]]))393sage: G.gen(0)394[1 0]395[0 1]396sage: g = G.random_element()397sage: TestSuite(g).run()398"""399if isinstance(M, GapElement):400ElementLibGAP.__init__(self, parent, M)401return402if convert:403M = parent.matrix_space()(M)404from sage.libs.gap.libgap import libgap405M_gap = libgap(M)406if check:407if not is_Matrix(M):408raise TypeError('M must be a matrix')409if M.parent() is not parent.matrix_space():410raise TypeError('M must be a in the matrix space of the group')411parent._check_matrix(M, M_gap)412ElementLibGAP.__init__(self, parent, M_gap)413414def __reduce__(self):415"""416Implement pickling.417418TESTS::419420sage: MS = MatrixSpace(GF(3), 2, 2)421sage: G = MatrixGroup(MS([[1,0],[0,1]]), MS([[1,1],[0,1]]))422sage: loads(G.gen(0).dumps())423[1 0]424[0 1]425"""426return (self.parent(), (self.matrix(),))427428@cached_method429def matrix(self):430"""431Obtain the usual matrix (as an element of a matrix space)432associated to this matrix group element.433434EXAMPLES::435436sage: F = GF(3); MS = MatrixSpace(F,2,2)437sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]438sage: G = MatrixGroup(gens)439sage: G.gen(0).matrix()440[1 0]441[0 1]442sage: _.parent()443Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3444"""445g = self.gap()446m = g.matrix(self.base_ring())447m.set_immutable()448return m449450def conjugacy_class(self):451r"""452Return the conjugacy class of ``self``.453454OUTPUT:455456The conjugacy class of ``g`` in the group ``self``. If ``self`` is the457group denoted by `G`, this method computes the set458`\{x^{-1}gx\ \vert\ x\in G\}`.459460EXAMPLES::461462sage: G = SL(2, QQ)463sage: g = G([[1,1],[0,1]])464sage: g.conjugacy_class()465Conjugacy class of [1 1]466[0 1] in Special Linear Group of degree 2 over Rational Field467"""468from sage.groups.conjugacy_classes import ConjugacyClassGAP469return ConjugacyClassGAP(self.parent(), self)470471472473474