# Commits

committed 828d928

finished matrix groups

• Participants
• Parent commits 64f083b
• Branches default

# File revert_conjugacy_class.patch

• Ignore whitespace
-# HG changeset patch
-# Parent 9f5f569815a13a8b2f93b783737a1ab0e93fef86
-
-diff --git a/sage/groups/matrix_gps/matrix_group.py b/sage/groups/matrix_gps/matrix_group.py
---- a/sage/groups/matrix_gps/matrix_group.py
-+++ b/sage/groups/matrix_gps/matrix_group.py
-@@ -90,8 +90,6 @@
- from sage.structure.sage_object import SageObject
- from sage.groups.class_function import ClassFunction
- from sage.misc.decorators import rename_keyword
--from sage.groups.conjugacy_classes import ConjugacyClassGAP
--from sage.misc.cachefunc import cached_method
-
- #################################################################
-
-@@ -771,50 +769,7 @@
-         F    = self.field_of_definition()
-         self.__reps = Sequence([self(g._matrix_(F)) for g in reps], cr=True, universe=self, check=False)
-         return self.__reps
--
--    def conjugacy_class(self, g):
--        r"""
--        Return the conjugacy class of g inside of self.
--
--        INPUT:
--
--        - g -- an element of self
--
--        OUTPUT:
--
--        The conjugacy class of g in the group self. If self is the
--        group denoted by G, this method computes the set
--        \{x^{-1}gx\ \vert\ x\in G\}.
-
--        EXAMPLES::
--
--            sage: G = SL(3, GF(3))
--            sage: g = G.gens()[0]
--            sage: G.conjugacy_class(g)
--            Conjugacy class of [1 1 0]
--            [0 1 0]
--            [0 0 1] in Special Linear Group of degree 3 over Finite Field of size 3
--        """
--        return ConjugacyClassGAP(self, g)
--
--    @cached_method
--    def conjugacy_classes(self):
--        r"""
--        Return a list with all the conjugacy classes of self.
--
--        EXAMPLES::
--
--            sage: G = SL(2, GF(2))
--            sage: G.conjugacy_classes()
--            [Conjugacy class of [1 0]
--            [0 1] in Special Linear Group of degree 2 over Finite Field of size 2, Conjugacy class of [0 1]
--            [1 0] in Special Linear Group of degree 2 over Finite Field of size 2, Conjugacy class of [0 1]
--            [1 1] in Special Linear Group of degree 2 over Finite Field of size 2]
--        """
--        CC = self._gap_().ConjugacyClasses()
--        reps = list(gap.List(CC, 'x -> Representative(x)'))
--        return [ConjugacyClassGAP(self, self(g._matrix_(self.field_of_definition()))) for g in reps]
--
-     def center(self):
-         """
-         Return the center of this linear group as a matrix group.
-diff --git a/sage/groups/matrix_gps/matrix_group_element.py b/sage/groups/matrix_gps/matrix_group_element.py
---- a/sage/groups/matrix_gps/matrix_group_element.py
-+++ b/sage/groups/matrix_gps/matrix_group_element.py
-@@ -461,18 +461,4 @@
-         lrws = [list(x) for x in rws]
-         return lrws
-
--    def conjugacy_class(self):
--        r"""
--        Return the conjugacy class of self.
-
--        EXAMPLES::
--
--            sage: G = SL(2, GF(2))
--            sage: g = G.gens()[0]
--            sage: g.conjugacy_class()
--            Conjugacy class of [1 1]
--            [0 1] in Special Linear Group of degree 2 over Finite Field of size 2
--        """
--        from sage.groups.conjugacy_classes import ConjugacyClassGAP
--        return ConjugacyClassGAP(self.parent(), self)
--

# File series

• Ignore whitespace
 trac_14188_vb.patch
 trac_14188_docfix.patch
-trac_14187_lazy_import_test.patch
 trac_13249_vb.patch
 trac_13249_volume.patch
 trac_12553_ppl_count_points.patch
 trac_3416_jacobians.patch
 trac_3416_fixes.patch
 trac_13826_star_imports_race.patch
-revert_conjugacy_class.patch
+trac_14187_lazy_import_test.patch
+trac_14187_lazy_everywhere.patch
 trac_14014_parents_for_matrix_groups.patch
 trac_14015_affine_group.patch
 trac_12892_orbit_closure_morphism.patch

# File trac_14014_parents_for_matrix_groups.patch

• Ignore whitespace
 # HG changeset patch
-# Parent f07b3a222b87ba6ccd40aef724f66405823e39df
+# Parent 5f3cdd58f81e71b8dba2b922ab5ae0eae67127ac

 Update matrix groups to new parents and LibGAP.

      sage: G.random_element()             # random output
      [5 5 5 1]
      [0 2 6 3]
+diff --git a/sage/algebras/group_algebra.py b/sage/algebras/group_algebra.py
+--- a/sage/algebras/group_algebra.py
++++ b/sage/algebras/group_algebra.py
+@@ -29,8 +29,7 @@
+ from sage.algebras.algebra import Algebra
+ from sage.algebras.algebra_element import AlgebraElement
+ from sage.rings.all import IntegerRing
+-from sage.groups.group import Group
+-from sage.groups.old import Group as OldGroup
++from sage.groups.group import Group, is_Group
+ from sage.structure.formal_sum import FormalSums, FormalSum
+ from sage.sets.set import Set
+
+@@ -68,7 +67,7 @@
+         if not base_ring.is_commutative():
+             raise NotImplementedError("Base ring must be commutative")
+
+-        if not isinstance(group, (Group, OldGroup)):
++        if not is_Group(group):
+             raise TypeError('"%s" is not a group' % group)
+
+         ParentWithGens.__init__(self, base_ring, category = GroupAlgebras(base_ring))
+diff --git a/sage/algebras/group_algebra_new.py b/sage/algebras/group_algebra_new.py
+--- a/sage/algebras/group_algebra_new.py
++++ b/sage/algebras/group_algebra_new.py
+@@ -255,12 +255,11 @@
+             sage: GroupAlgebra(GL(3, GF(7)))
+             Group algebra of group "General Linear Group of degree 3 over Finite Field of size 7" over base ring Integer Ring
+         """
+-        from sage.groups.group import Group
+-        from sage.groups.old import Group as OldGroup
++        from sage.groups.group import is_Group
+         if not base_ring.is_commutative():
+             raise NotImplementedError("Base ring must be commutative")
+
+-        if not isinstance(group, (Group, OldGroup)):
++        if not is_Group(group):
+             raise TypeError('"%s" is not a group' % group)
+
+         self._group = group
+@@ -593,8 +592,8 @@
+             sage: GroupAlgebra(DihedralGroup(6), QQ).random_element()
+             -1/95*(2,6)(3,5) - 1/2*(1,3)(4,6)
+             sage: GroupAlgebra(SU(2, 13), QQ).random_element(1)
+-            1/2*[      1 9*a + 2]
+-            [9*a + 2      12]
++            1/2*[       6  5*a + 4]
++            [6*a + 10       12]
+         """
+         a = self(0)
+         for i in range(n):
+@@ -726,14 +725,13 @@
+             sage: OG(FormalSum([ (1, G(2)), (2, RR(0.77)) ]) )
+             Traceback (most recent call last):
+             ...
+-            TypeError: Cannot coerce 0.770000000000000 to a 2-by-2 matrix over Finite Field of size 7
+-
++            TypeError: Attempt to coerce non-integral RealNumber to Integer
+             sage: OG(OG.base_ring().gens()[1])
+             sqrt5*[1 0]
+             [0 1]
+         """
+         from sage.rings.all import is_Ring
+-        from sage.groups.old import Group
++        from sage.groups.group import is_Group
+         from sage.structure.formal_sum import FormalSum
+         k = self.base_ring()
+         G = self.group()
+@@ -753,7 +751,7 @@
+         elif is_Ring(S):
+             # coerce to multiple of identity element
+             return k(x) * self(1)
+-        elif isinstance(S, Group):
++        elif is_Group(S):
+             # Check whether group coerces to base_ring first.
+             if k.has_coerce_map_from(S):
+                 return k(x) * self(1)
+diff --git a/sage/categories/action.pyx b/sage/categories/action.pyx
+--- a/sage/categories/action.pyx
++++ b/sage/categories/action.pyx
+@@ -232,11 +232,10 @@
+     def __init__(self, Action action):
+         G = action.G
+         try:
+-            from sage.groups.old import Group as OldGroup
+-            from sage.groups.group import Group
++            from sage.groups.group import is_Group
+             # We must be in the case that parent(~a) == parent(a)
+             # so we can invert in call_c code below.
+-            if (isinstance(G, (Group, OldGroup)) and G.is_multiplicative()) or G.is_field():
++            if (is_Group(G) and G.is_multiplicative()) or G.is_field():
+                 Action.__init__(self, G, action.underlying_set(), action._is_left)
+                 self._action = action
+                 return
+diff --git a/sage/categories/coxeter_groups.py b/sage/categories/coxeter_groups.py
+--- a/sage/categories/coxeter_groups.py
++++ b/sage/categories/coxeter_groups.py
+@@ -150,26 +150,12 @@
+
+                 sage: W=WeylGroup(['A',3])
+                 sage: W.some_elements()
+-                [[0 1 0 0]
+-                [1 0 0 0]
+-                [0 0 1 0]
+-                [0 0 0 1],
+-                 [1 0 0 0]
+-                [0 0 1 0]
+-                [0 1 0 0]
+-                [0 0 0 1],
+-                 [1 0 0 0]
+-                [0 1 0 0]
+-                [0 0 0 1]
+-                [0 0 1 0],
+-                 [1 0 0 0]
+-                [0 1 0 0]
+-                [0 0 1 0]
+-                [0 0 0 1],
+-                 [0 0 0 1]
+-                [1 0 0 0]
+-                [0 1 0 0]
+-                [0 0 1 0]]
++                [
++                [0 1 0 0]  [1 0 0 0]  [1 0 0 0]  [1 0 0 0]  [0 0 0 1]
++                [1 0 0 0]  [0 0 1 0]  [0 1 0 0]  [0 1 0 0]  [1 0 0 0]
++                [0 0 1 0]  [0 1 0 0]  [0 0 0 1]  [0 0 1 0]  [0 1 0 0]
++                [0 0 0 1], [0 0 0 1], [0 0 1 0], [0 0 0 1], [0 0 1 0]
++                ]
+                 sage: W.order()
+                 24
+             """
+@@ -237,16 +223,10 @@
+                 sage: W = WeylGroup(["A",1,1])
+                 sage: I = W.weak_order_ideal(predicate = lambda w: w.length() <= 2)
+                 sage: list(iter(I))
+-                [[1 0]
+-                 [0 1],
+-                 [-1  2]
+-                 [ 0  1],
+-                 [ 3 -2]
+-                 [ 2 -1],
+-                 [ 1  0]
+-                 [ 2 -1],
+-                 [-1  2]
+-                 [-2  3]]
++                [
++                [1 0]  [-1  2]  [ 3 -2]  [ 1  0]  [-1  2]
++                [0 1], [ 0  1], [ 2 -1], [ 2 -1], [-2  3]
++                ]
+
+             Even when the result is finite, some features of
+             :class:FiniteEnumeratedSets are not available::
+@@ -262,16 +242,10 @@
+                 sage: I.cardinality()
+                 5
+                 sage: list(I)
+-                [[1 0]
+-                 [0 1],
+-                 [-1  2]
+-                 [ 0  1],
+-                 [ 3 -2]
+-                 [ 2 -1],
+-                 [ 1  0]
+-                 [ 2 -1],
+-                 [-1  2]
+-                 [-2  3]]
++                [
++                [1 0]  [-1  2]  [ 3 -2]  [ 1  0]  [-1  2]
++                [0 1], [ 0  1], [ 2 -1], [ 2 -1], [-2  3]
++                ]
+
+             .. rubric:: Background
+
+diff --git a/sage/categories/finite_groups.py b/sage/categories/finite_groups.py
+--- a/sage/categories/finite_groups.py
++++ b/sage/categories/finite_groups.py
+@@ -66,7 +66,7 @@
+             sage: G = FiniteGroups().example(); G
+             General Linear Group of degree 2 over Finite Field of size 3
+         """
+-        from sage.groups.matrix_gps.general_linear import GL
++        from sage.groups.matrix_gps.linear import GL
+         return GL(2,3)
+
+     class ParentMethods:
+@@ -188,12 +188,13 @@
+
+             EXAMPLES::
+
+-                sage: W = WeylGroup(['C',6])
+-                sage: W.conjugacy_classes()
++                sage: from sage.groups.group import FiniteGroup
++                sage: G = FiniteGroup()
++                sage: G.conjugacy_classes()
+                 Traceback (most recent call last):
+                 ...
+-                NotImplementedError: Listing the conjugacy classes for group
+-                  Weyl Group of type ['C', 6] (as a matrix group acting on the ambient space) is not implemented
++                NotImplementedError: Listing the conjugacy classes for
++                group <type 'sage.groups.group.FiniteGroup'> is not implemented
+             """
+             raise NotImplementedError("Listing the conjugacy classes for group %s is not implemented"%self)
+
+@@ -220,8 +221,10 @@
+                 sage: h = H(matrix(GF(5),2,[1,2, -1, 1]))
+                 sage: h.conjugacy_class()
+                 Conjugacy class of [1 2]
+-                [4 1] in Matrix group over Finite Field of size 5 with 2 generators:
+-                [[[1, 2], [4, 1]], [[1, 1], [0, 1]]]
++                [4 1] in Matrix group over Finite Field of size 5 with 2 generators (
++                [1 2]  [1 1]
++                [4 1], [0 1]
++                )
+             """
+             return self.parent().conjugacy_class(self)
+
+diff --git a/sage/categories/groups.py b/sage/categories/groups.py
+--- a/sage/categories/groups.py
++++ b/sage/categories/groups.py
+@@ -44,14 +44,14 @@
+         return [Monoids()]
+
+     def example(self):
+-        from sage.rings.rational_field import QQ
+-        from sage.groups.matrix_gps.general_linear import GL
+         """
+         EXAMPLES::
+
+             sage: Groups().example()
+             General Linear Group of degree 4 over Rational Field
+         """
++        from sage.rings.rational_field import QQ
++        from sage.groups.matrix_gps.linear import GL
+         return GL(4,QQ)
+
+     class ParentMethods:
+diff --git a/sage/combinat/root_system/pieri_factors.py b/sage/combinat/root_system/pieri_factors.py
+--- a/sage/combinat/root_system/pieri_factors.py
++++ b/sage/combinat/root_system/pieri_factors.py
+@@ -299,10 +299,12 @@
+             [[5, 4, 3, 2, 1]]
+
+             sage: WeylGroup(['B',4]).pieri_factors().maximal_elements()
+-            [[-1  0  0  0]
++            [
++            [-1  0  0  0]
+             [ 0  1  0  0]
+             [ 0  0  1  0]
+-            [ 0  0  0  1]]
++            [ 0  0  0  1]
++            ]
+         """
+         ct = self.W.cartan_type()
+
 diff --git a/sage/combinat/root_system/weyl_group.py b/sage/combinat/root_system/weyl_group.py
 --- a/sage/combinat/root_system/weyl_group.py
 +++ b/sage/combinat/root_system/weyl_group.py
-@@ -36,8 +36,8 @@
+@@ -7,6 +7,7 @@
+ - Mike Hansen (2008): initial version
+ - Anne Schilling (2008): initial version
+ - Nicolas Thiery (2008): initial version
++- Volker Braun (2013): LibGAP-based matrix groups
+
+ EXAMPLES:
+
+@@ -36,8 +37,8 @@
  #
  #                  http://www.gnu.org/licenses/
  #*****************************************************************************
 -from sage.groups.matrix_gps.matrix_group import MatrixGroup_gens
 -from sage.groups.matrix_gps.matrix_group_element import MatrixGroupElement
-+from sage.groups.old_matrix_gps.matrix_group import MatrixGroup_gens
-+from sage.groups.old_matrix_gps.matrix_group_element import MatrixGroupElement
++from sage.groups.matrix_gps.finitely_generated import FinitelyGeneratedMatrixGroup_gap
++from sage.groups.matrix_gps.group_element import MatrixGroupElement_gap
  from sage.rings.all import ZZ, QQ
  from sage.interfaces.gap import gap
  #from sage.misc.cache import Cache
+@@ -149,7 +150,10 @@
+     else:
+         return WeylGroup_gens(ct.root_system().ambient_space(), prefix=prefix)
+
+-class WeylGroup_gens(ClearCacheOnPickle, UniqueRepresentation, MatrixGroup_gens):
++
++class WeylGroup_gens(ClearCacheOnPickle, UniqueRepresentation,
++                     FinitelyGeneratedMatrixGroup_gap):
++
+     @staticmethod
+     def __classcall__(cls, domain, prefix=None):
+         return super(WeylGroup_gens, cls).__classcall__(cls, domain, prefix)
+@@ -169,10 +173,17 @@
+         else:
+             category = WeylGroups()
+         self.n = domain.dimension() # Really needed?
+-        # MatrixGroup_gens takes plain matrices as input. So we can't do:
+-        #MatrixGroup_gens.__init__(self, list(self.simple_reflections()))
+         self._prefix = prefix
+-        MatrixGroup_gens.__init__(self, [self.morphism_matrix(self.domain().simple_reflection(i)) for i in self.index_set()], category = category)
++
++        # FinitelyGeneratedMatrixGroup_gap takes plain matrices as input
++        gens_matrix = [self.morphism_matrix(self.domain().simple_reflection(i))
++                       for i in self.index_set()]
++        from sage.libs.all import libgap
++        libgap_group = libgap.Group(gens_matrix)
++        degree = ZZ(self.domain().dimension())
++        ring = self.domain().base_ring()
++        FinitelyGeneratedMatrixGroup_gap.__init__(
++            self, degree, ring, libgap_group, category=category)
+
+     @cached_method
+     def cartan_type(self):
+@@ -273,7 +284,7 @@
+
+         EXAMPLES::
+
+-            sage: W = WeylGroup("B2",prefix="s")
++            sage: W = WeylGroup("B2", prefix="s")
+             sage: refdict = W.reflections(); refdict
+             Finite family {s1: (1, -1), s2*s1*s2: (1, 1), s1*s2*s1: (1, 0), s2: (0, 1)}
+             sage: [refdict[r]+r.action(refdict[r]) for r in refdict.keys()]
+@@ -283,7 +294,9 @@
+         ret = {}
+         try:
+             for alp in self.domain().positive_roots():
+-                r = self.__call__(Matrix([self.domain().reflection(alp)(x).to_vector() for x in self.domain().basis()]))
++                m = Matrix([self.domain().reflection(alp)(x).to_vector()
++                            for x in self.domain().basis()])
++                r = self(m)
+                 ret[r] = alp
+             return Family(ret)
+         except StandardError:
+@@ -297,18 +310,12 @@
+
+             sage: G = WeylGroup(['A',3])
+             sage: G.gens()
+-            [[0 1 0 0]
+-             [1 0 0 0]
+-             [0 0 1 0]
+-             [0 0 0 1],
+-             [1 0 0 0]
+-             [0 0 1 0]
+-             [0 1 0 0]
+-             [0 0 0 1],
+-             [1 0 0 0]
+-             [0 1 0 0]
+-             [0 0 0 1]
+-             [0 0 1 0]]
++            [
++            [0 1 0 0]  [1 0 0 0]  [1 0 0 0]
++            [1 0 0 0]  [0 0 1 0]  [0 1 0 0]
++            [0 0 1 0]  [0 1 0 0]  [0 0 0 1]
++            [0 0 0 1], [0 0 0 1], [0 0 1 0]
++            ]
+         """
+         return list(self.simple_reflections())
+
+@@ -327,41 +334,41 @@
+                                                                                                       type=False))
+
+
+-    def __call__(self, x):
+-        """
+-        EXAMPLES::
++    # def __call__(self, x):
++    #     """
++    #     EXAMPLES::
+
+-            sage: W = WeylGroup(['A',2])
+-            sage: W(1)
+-            [1 0 0]
+-            [0 1 0]
+-            [0 0 1]
++    #         sage: W = WeylGroup(['A',2])
++    #         sage: W(1)
++    #         [1 0 0]
++    #         [0 1 0]
++    #         [0 0 1]
+
+-        ::
++    #     ::
+
+-            sage: W(2)
+-            Traceback (most recent call last):
+-            ...
+-            TypeError: no way to coerce element into self.
++    #         sage: W(2)
++    #         Traceback (most recent call last):
++    #         ...
++    #         TypeError: no way to coerce element into self.
+
+-            sage: W2 = WeylGroup(['A',3])
+-            sage: W(1) in W2  # indirect doctest
+-            False
++    #         sage: W2 = WeylGroup(['A',3])
++    #         sage: W(1) in W2  # indirect doctest
++    #         False
+
+-        """
+-        if isinstance(x, self.element_class) and x.parent() is self:
+-            return x
+-        from sage.matrix.matrix import is_Matrix
+-        if not (x in ZZ or is_Matrix(x)): # this should be handled by self.matrix_space()(x)
+-            raise TypeError, "no way to coerce element into self"
+-        M = self.matrix_space()(x)
+-        # This is really bad, especially for infinite groups!
+-        # TODO: compute the image of rho, compose by s_i until back in
+-        # the fundamental chamber. Return True iff the matrix is the identity
+-        g = self._element_constructor_(M)
+-        if not gap(g) in gap(self):
+-            raise TypeError, "no way to coerce element into self."
+-        return g
++    #     """
++    #     if isinstance(x, self.element_class) and x.parent() is self:
++    #         return x
++    #     from sage.matrix.matrix import is_Matrix
++    #     if not (x in ZZ or is_Matrix(x)): # this should be handled by self.matrix_space()(x)
++    #         raise TypeError, "no way to coerce element into self"
++    #     M = self.matrix_space()(x)
++    #     # This is really bad, especially for infinite groups!
++    #     # TODO: compute the image of rho, compose by s_i until back in
++    #     # the fundamental chamber. Return True iff the matrix is the identity
++    #     g = self._element_constructor_(M)
++    #     if not gap(g) in gap(self):
++    #         raise TypeError, "no way to coerce element into self."
++    #     return g
+
+         # Here is a first attempt, which is not guaranteed to terminate
+         # because g might map the simple roots all over the place.
+@@ -399,9 +406,10 @@
+
+             sage: G = WeylGroup(['A',1])
+             sage: G.list()
+-            [[1 0]
+-             [0 1], [0 1]
+-             [1 0]]
++            [
++            [1 0]  [0 1]
++            [0 1], [1 0]
++            ]
+
+             sage: G = WeylGroup(['A',3,1])
+             sage: G.list()
+@@ -438,13 +446,15 @@
+
+     def character_table(self):
+         """
+-        Returns the GAP character table as a string. For larger tables you
++        Returns the character table as a matrix
++
++        Each row is an irreducible character. For larger tables you
+         may preface this with a command such as
+         gap.eval("SizeScreen([120,40])") in order to widen the screen.
+-
++
+         EXAMPLES::
+
+-            sage: print WeylGroup(['A',3]).character_table()
++            sage: WeylGroup(['A',3]).character_table()
+             CT1
+             <BLANKLINE>
+                  2  3  2  2  .  3
+@@ -458,7 +468,9 @@
+             X.4     3 -1  1  . -1
+             X.5     1  1  1  1  1
+         """
+-        return gap.eval("Display(CharacterTable(%s))"%gap(self).name())
++        gens_str = ', '.join(str(g.gap()) for g  in self.gens())
++        ctbl = gap('CharacterTable(Group({0}))'.format(gens_str))
++        return ctbl.Display()
+
+     @cached_method
+     def one(self):
+@@ -746,7 +758,7 @@
+         assert(not self.weyl_group(self._prefix).is_finite())
+         assert(self.is_finite())
+
+-class WeylGroupElement(MatrixGroupElement):
++class WeylGroupElement(MatrixGroupElement_gap):
+     """
+     Class for a Weyl Group elements
+     """
+@@ -758,9 +770,8 @@
+             sage: s1 = G.simple_reflection(1)
+             sage: TestSuite(s1).run()
+         """
+-        MatrixGroupElement.__init__(self, g, parent)
+-        self.__matrix = self._MatrixGroupElement__mat
+-        self.__matrix.set_immutable()
++        MatrixGroupElement_gap.__init__(self, g, parent, check=False)
++        self.__matrix = self.matrix()
+         self._parent = parent
+
+     def __hash__(self):
+@@ -779,12 +790,12 @@
+         """
+         return self._parent.domain()
+
+-    def __repr__(self):
++    def _repr_(self):
+         """
+         EXAMPLES::
+
+             sage: W = WeylGroup(['A',2,1], prefix="s")
+-            sage: [s0,s1,s2]=W.simple_reflections()
++            sage: [s0,s1,s2] = W.simple_reflections()
+             sage: s0*s1
+             s0*s1
+             sage: W = WeylGroup(['A',2,1])
+@@ -795,7 +806,7 @@
+             [ 0  0  1]
+         """
+         if self._parent._prefix is None:
+-            return MatrixGroupElement.__repr__(self)
++            return MatrixGroupElement_gap._repr_(self)
+         else:
+             redword = self.reduced_word()
+             if len(redword) == 0:
+@@ -824,7 +835,7 @@
+             \end{array}\right)
+         """
+         if self._parent._prefix is None:
+-            return MatrixGroupElement._latex_(self)
++            return MatrixGroupElement_gap._latex_(self)
+         else:
+             redword = self.reduced_word()
+             if len(redword) == 0:
+@@ -832,23 +843,6 @@
+             else:
+                 return "".join(["%s_{%d}"%(self._parent._prefix, i) for i in redword])
+
+-    def matrix(self):
+-        """
+-        Returns self as a matrix.
+-
+-        EXAMPLES::
+-
+-            sage: W = WeylGroup(['A',2])
+-            sage: s1 = W.simple_reflection(1)
+-            sage: m = s1.matrix(); m
+-            [0 1 0]
+-            [1 0 0]
+-            [0 0 1]
+-            sage: m.parent()
+-            Full MatrixSpace of 3 by 3 dense matrices over Rational Field
+-        """
+-        return self.__matrix
+-
+     def __eq__(self, other):
+         """
+         EXAMPLES::
+@@ -886,54 +880,6 @@
+             return cmp(self._parent.cartan_type(), other._parent.cartan_type())
+         return cmp(self.matrix(), other.matrix())
+
+-    def parent(self):
+-        """
+-        Returns self's parent.
+-
+-        EXAMPLES::
+-
+-            sage: W = WeylGroup(['A',2])
+-            sage: s = W.simple_reflections()
+-            sage: s[1].parent()
+-            Weyl Group of type ['A', 2] (as a matrix group acting on the ambient space)
+-        """
+-        return self._parent
+-
+-    def _mul_(self, other):
+-        """
+-        EXAMPLES::
+-
+-            sage: W = WeylGroup(['A',2])
+-            sage: s = W.simple_reflections()
+-            sage: s[1]*s[1]
+-            [1 0 0]
+-            [0 1 0]
+-            [0 0 1]
+-        """
+-        return self.parent()._element_constructor_(self.__matrix * other.__matrix)
+-
+-    def inverse(self):
+-        """
+-        Returns the inverse of self.
+-
+-        EXAMPLES::
+-
+-            sage: W = WeylGroup(['A',2])
+-            sage: w = W.unit()
+-            sage: w = w.inverse()
+-            sage: type(w.inverse()) == W.element_class
+-            True
+-            sage: W=WeylGroup(['A',2])
+-            sage: w=W.from_reduced_word([2,1])
+-            sage: w.inverse().reduced_word()
+-            [1, 2]
+-            sage: ~w == w.inverse()
+-            True
+-        """
+-        return self.parent()._element_constructor_(self.matrix().inverse())
+-
+-    __invert__ = inverse
+-
+     def action(self, v):
+         """
+         Returns the action of self on the vector v.
 diff --git a/sage/groups/all.py b/sage/groups/all.py
 --- a/sage/groups/all.py
 +++ b/sage/groups/all.py


      def norm(self):
-@@ -707,3 +756,705 @@
+@@ -707,3 +756,704 @@
          """
          rest = self._gap_classfunction.InducedClassFunction(G._gap_())
          return ClassFunction(G, rest)
 +
 +    EXAMPLES::
 +
-+        sage: from sage.groups.libgap_class_function import ClassFunction
 +        sage: G = SO(3,3)
 +        sage: values  = [1, -1, -1, 1, 2]
 +        sage: chi = ClassFunction(G, values); chi

  TESTS::

-@@ -90,10 +92,14 @@
+@@ -58,6 +60,15 @@
+ from sage.categories.enumerated_sets import EnumeratedSets
+ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
+
++# TODO
++#
++# Don't derive from Parent if there are no elements
++#
++# @cached_method must not return mutable containers (lists), use
++# tuples instead.
++
++
++
+ class ConjugacyClass(Parent):
+     r"""
+     Generic conjugacy classes for elements in a group.
+@@ -90,10 +101,14 @@
          """
          self._parent = group
          self._representative = element

      def __repr__(self):
          r"""
-@@ -300,9 +306,10 @@
+@@ -300,17 +315,25 @@
              sage: h = H(matrix(F,2,[1,2, -1, 1]))
              sage: ConjugacyClassGAP(H,h)
              Conjugacy class of [1 2]
 +            [4 1], [0 1]
 +            )
          """
-         try:
+-        try:
++        try:
++            # GAP interface
              self._gap_group = group._gap_()
+             self._gap_representative = element._gap_()
+-            self._gap_conjugacy_class = self._gap_group.ConjugacyClass(self._gap_representative)
+-            ConjugacyClass.__init__(self, group, element)
+-        except TypeError:
+-            raise TypeError("The group %s cannot be defined as a GAP group"%group)
++        except (AttributeError, TypeError):
++            try:
++                # LibGAP
++                self._gap_group = group.gap()
++                self._gap_representative = element.gap()
++            except (AttributeError, TypeError):
++                raise TypeError("The group %s cannot be defined as a GAP group"%group)
++
++        self._gap_conjugacy_class = self._gap_group.ConjugacyClass(self._gap_representative)
++        ConjugacyClass.__init__(self, group, element)
+
+     def _gap_(self):
+         r"""
 diff --git a/sage/groups/free_group.py b/sage/groups/free_group.py
 --- a/sage/groups/free_group.py
 +++ b/sage/groups/free_group.py
 diff --git a/sage/groups/group.pyx b/sage/groups/group.pyx
 --- a/sage/groups/group.pyx
 +++ b/sage/groups/group.pyx
-@@ -40,7 +40,7 @@
+@@ -23,6 +23,31 @@
+ from sage.rings.infinity import infinity
+ from sage.rings.integer_ring import ZZ
+
++def is_Group(x):
++    """
++    Return whether x is a group object.
++
++    INPUT:
++
++    - x -- anything.
++
++    OUTPUT:
++
++    Boolean.
++
++    EXAMPLES::
++
++        sage: F.<a,b> = FreeGroup()
++        sage: from sage.groups.group import is_Group
++        sage: is_Group(F)
++        True
++        sage: is_Group("a string")
++        False
++    """
++    from sage.groups.old import Group as OldGroup
++    return isinstance(x, (Group, OldGroup))
++
++
+ cdef class Group(Parent):
+     """
+     Base class for all groups
+@@ -40,7 +65,7 @@
          _test_elements_eq, _test_inverse, _test_one,
          _test_pickling, _test_prod, _test_some_elements
      """
          """
          The Python constructor

-@@ -56,8 +56,7 @@
+@@ -56,8 +81,7 @@
              sage: G = Group(category = CommutativeAdditiveGroups())
              Traceback (most recent call last):
              ...
              sage: G._repr_option('element_is_atomic')
              False

-@@ -73,9 +72,11 @@
+@@ -73,9 +97,11 @@
          if category is None:
              category = Groups()
          else:

      def __contains__(self, x):
          r"""
+@@ -252,6 +278,28 @@
+     """
+     Generic finite group.
+     """
++
++    def __init__(self, base=None, gens=None, category=None):
++        """
++        The Python constructor
++
++        TESTS::
++
++            sage: from sage.groups.group import FiniteGroup
++            sage: G = FiniteGroup()
++            sage: G.category()
++            Category of finite groups
++        """
++        from sage.categories.finite_groups import FiniteGroups
++        if category is None:
++            category = FiniteGroups()
++        else:
++            if not isinstance(category, tuple):
++                category = (category,)
++            if not any(cat.is_subcategory(FiniteGroups()) for cat in category):
++                raise ValueError("%s is not a subcategory of %s"%(category, FiniteGroups()))
++        Parent.__init__(self, base=base, gens=gens, category=category)
++
+     def is_finite(self):
+         """
+         Return True.
 diff --git a/sage/groups/groups_catalog.py b/sage/groups/groups_catalog.py
 --- a/sage/groups/groups_catalog.py
 +++ b/sage/groups/groups_catalog.py
 new file mode 100644
 --- /dev/null
 +++ b/sage/groups/libgap_mixin.py
-@@ -0,0 +1,500 @@
+@@ -0,0 +1,555 @@
 +"""
 +Mix-in Class for libGAP-based Groups
 +
 +        G = self.gap()
 +        reps = [ cc.Representative() for cc in G.ConjugacyClasses() ]
 +        return tuple(self(g) for g in reps)
++
++    @cached_method
++    def conjugacy_classes(self):
++        r"""
++        Return a list with all the conjugacy classes of self.
++
++        EXAMPLES::
++
++            sage: G = SL(2, GF(2))
++            sage: G.conjugacy_classes()
++            (Conjugacy class of [1 0]
++             [0 1] in Special Linear Group of degree 2 over Finite Field of size 2,
++             Conjugacy class of [0 1]
++             [1 0] in Special Linear Group of degree 2 over Finite Field of size 2,
++             Conjugacy class of [0 1]
++             [1 1] in Special Linear Group of degree 2 over Finite Field of size 2)
++        """
++        from sage.groups.conjugacy_classes import ConjugacyClassGAP
++        G = self.gap()
++        reps = [ cc.Representative() for cc in G.ConjugacyClasses() ]
++        return tuple(ConjugacyClassGAP(self, self(g)) for g in reps)
 +
 +    def class_function(self, values):
 +        """
 +        """
 +        return self(self.gap().Random())
 +
-+
 +    def list(self):
 +        """
 +        List all elements of this group.
 +        elements = self.gap().Elements()
 +        return tuple(self(x) for x in elements)
 +
-+
-+
++    def is_isomorphic(self, H):
++        """
++        Test whether self and H are isomorphic groups.
++
++        INPUT:
++
++        - H -- a group.
++
++        OUTPUT:
++
++        Boolean.
++
++        EXAMPLES::
++
++            sage: m1 = matrix(GF(3), [[1,1],[0,1]])
++            sage: m2 = matrix(GF(3), [[1,2],[0,1]])
++            sage: F = MatrixGroup(m1)
++            sage: G = MatrixGroup(m1, m2)
++            sage: H = MatrixGroup(m2)
++            sage: F.is_isomorphic(G)
++            True
++            sage: G.is_isomorphic(H)
++            True
++            sage: F.is_isomorphic(H)
++            True
++            sage: F==G, G==H, F==H
++            (False, False, False)
++        """
++        iso = self.gap().IsomorphismGroups(H.gap())
++        if iso.is_bool():   # fail means not isomorphic
++            try:
++                iso.sage()
++                assert False
++            except ValueError:
++                pass
++            return False
++        return True
 diff --git a/sage/groups/libgap_wrapper.pyx b/sage/groups/libgap_wrapper.pyx
 --- a/sage/groups/libgap_wrapper.pyx
 +++ b/sage/groups/libgap_wrapper.pyx
 new file mode 100644
 --- /dev/null
 +++ b/sage/groups/matrix_gps/finitely_generated.py
-@@ -0,0 +1,747 @@
+@@ -0,0 +1,736 @@
 +"""
 +Finitely Generated Matrix Groups
 +
 +        ...
 +        AttributeError: 'LinearMatrixGroup_generic_with_category' object has no attribute 'gens'
 +    """
++    if isinstance(gens[-1], dict):   # hack for unpickling
++        kwds.update(gens[-1])
++        gens = gens[:-1]
 +    check = kwds.get('check', True)
 +    if len(gens) == 1:
 +        if isinstance(gens[0], (list, tuple)):
 +
 +    EXAMPLES::
 +
-+        sage: m1 = matrix(QQ, [[1,2],[3,4]])
-+        sage: m2 = matrix(QQ, [[1,3],[-1,0]])
++        sage: m1 = matrix(GF(11), [[1,2],[3,4]])
++        sage: m2 = matrix(GF(11), [[1,3],[10,0]])
 +        sage: G = MatrixGroup(m1, m2);  G
-+        Matrix group over Rational Field with 2 generators (
++        Matrix group over Finite Field of size 11 with 2 generators (
 +        [1 2]  [ 1  3]
-+        [3 4], [-1  0]
++        [3 4], [10  0]
 +        )
 +        sage: type(G)
 +        <class 'sage.groups.matrix_gps.finitely_generated.FinitelyGeneratedMatrixGroup_gap_with_category'>
 +            [3 4], [-1  0]
 +            )
 +        """
-+        return (MatrixGroup, tuple(g.matrix() for g in self.gens()))
++        return (MatrixGroup,
++                tuple(g.matrix() for g in self.gens()) + ({'check':False},))
 +
 +    def __cmp__(self, other):
 +        """
 +                            sage_eval(gap.eval("MCF.IsIrreducible")) ]))
 +        return sorted(L)
 +
-+
-+    # def _gap_init_(self):
-+    #     """
-+    #     Returns a string representation of the corresponding GAP object.
-+
-+    #     EXAMPLES::
-+
-+    #         sage: F = GF(5); MS = MatrixSpace(F,2,2)
-+    #         sage: gens = [MS([[1,2],[-1,1]]),MS([[1,1],[0,1]])]
-+    #         sage: G = MatrixGroup(gens)
-+    #         sage: G._gap_init_() # The variable $sage11 belongs to gap(F) and is somehow random -+ # 'Group([[Z(5)^0,Z(5)^1],[Z(5)^2,Z(5)^0]]*One($sage11),[[Z(5)^0,Z(5)^0],[0*Z(5),Z(5)^0]]*One($sage11))' -+ # sage: gap(G._gap_init_()) -+ # Group([ [ [ Z(5)^0, Z(5) ], [ Z(5)^2, Z(5)^0 ] ], -+ # [ [ Z(5)^0, Z(5)^0 ], [ 0*Z(5), Z(5)^0 ] ] ]) -+ # """ -+ # gens_gap = ','.join([x._gap_init_() for x in self._generator_matrices]) -+ # return 'Group(%s)'%gens_gap -+ -+ -+ -+ -+ -+ -+ # def invariant_generators(self): -+ # r""" -+ # Computes generators for the polynomial ring -+ # F[x_1,\ldots,x_n]^G, where G in GL(n,F) is a finite -+ # matrix group. -+  -+ # In the "good characteristic" case the polynomials returned form a -+ # minimal generating set for the algebra of G-invariant polynomials. -+ # In the "bad" case, the polynomials returned are primary and -+ # secondary invariants, forming a not necessarily minimal generating -+ # set for the algebra of G-invariant polynomials. -+  -+ # ALGORITHM: -+ -+ # Wraps Singular's invariant_algebra_reynolds and invariant_ring -+ # in finvar.lib. -+ -+ # EXAMPLES:: -+  -+ # sage: F = GF(7); MS = MatrixSpace(F,2,2) -+ # sage: gens = [MS([[0,1],[-1,0]]),MS([[1,1],[2,3]])] -+ # sage: G = MatrixGroup(gens) -+ # sage: G.invariant_generators() -+ # [x1^7*x2 - x1*x2^7,  -+ # x1^12 - 2*x1^9*x2^3 - x1^6*x2^6 + 2*x1^3*x2^9 + x2^12,  -+ # x1^18 + 2*x1^15*x2^3 + 3*x1^12*x2^6 + 3*x1^6*x2^12 - 2*x1^3*x2^15 + x2^18] -+ # sage: q = 4; a = 2 -+ # sage: MS = MatrixSpace(QQ, 2, 2) -+ # sage: gen1 = [[1/a,(q-1)/a],[1/a, -1/a]]; gen2 = [[1,0],[0,-1]]; gen3 = [[-1,0],[0,1]] -+ # sage: G = MatrixGroup([MS(gen1),MS(gen2),MS(gen3)]) -+ # sage: G.cardinality() -+ # 12 -+ # sage: G.invariant_generators() -+ # [x1^2 + 3*x2^2, x1^6 + 15*x1^4*x2^2 + 15*x1^2*x2^4 + 33*x2^6] -+ # sage: F = GF(5); MS = MatrixSpace(F,2,2) -+ # sage: gens = [MS([[1,2],[-1,1]]),MS([[1,1],[-1,1]])] -+ # sage: G = MatrixGroup(gens) -+ # sage: G.invariant_generators() # long time (67s on sage.math, 2012) -+ # [x1^20 + x1^16*x2^4 + x1^12*x2^8 + x1^8*x2^12 + x1^4*x2^16 + x2^20,  -+ # x1^20*x2^4 + x1^16*x2^8 + x1^12*x2^12 + x1^8*x2^16 + x1^4*x2^20] -+ # sage: F=CyclotomicField(8) -+ # sage: z=F.gen() -+ # sage: a=z+1/z -+ # sage: b=z^2 -+ # sage: MS=MatrixSpace(F,2,2) -+ # sage: g1=MS([[1/a,1/a],[1/a,-1/a]]) -+ # sage: g2=MS([[1,0],[0,b]]) -+ # sage: g3=MS([[b,0],[0,1]]) -+ # sage: G=MatrixGroup([g1,g2,g3]) -+ # sage: G.invariant_generators() # long time (12s on sage.math, 2011) -+ # [x1^8 + 14*x1^4*x2^4 + x2^8, -+ # x1^24 + 10626/1025*x1^20*x2^4 + 735471/1025*x1^16*x2^8 + 2704156/1025*x1^12*x2^12 +  -+ # 735471/1025*x1^8*x2^16 + 10626/1025*x1^4*x2^20 + x2^24] -+  -+ # AUTHORS: -+ -+ # - David Joyner, Simon King and Martin Albrecht. -+  -+ # REFERENCES: -+ -+ # - Singular reference manual -+ -+ # - B. Sturmfels, "Algorithms in invariant theory", Springer-Verlag, 1993. -+ -+ # - S. King, "Minimal Generating Sets of non-modular invariant rings of -+ # finite groups", arXiv:math.AC/0703035 -+ # """ -+ # from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -+ # from sage.interfaces.singular import singular -+ # gens = self.gens() -+ # singular.LIB("finvar.lib") -+ # n = self.degree() #len((gens[0].matrix()).rows()) -+ # F = self.base_ring() -+ # q = F.characteristic() -+ # ## test if the field is admissible -+ # if F.gen()==1: # we got the rationals or GF(prime) -+ # FieldStr = str(F.characteristic()) -+ # elif hasattr(F,'polynomial'): # we got an algebraic extension -+ # if len(F.gens())>1: -+ # raise NotImplementedError, "can only deal with finite fields and (simple algebraic extensions of) the rationals" -+ # FieldStr = '(%d,%s)'%(F.characteristic(),str(F.gen())) -+ # else: # we have a transcendental extension -+ # FieldStr = '(%d,%s)'%(F.characteristic(),','.join([str(p) for p in F.gens()])) -+  -+ # ## Setting Singular's variable names -+ # ## We need to make sure that field generator and variables get different names. -+ # if str(F.gen())[0]=='x':  -+ # VarStr = 'y' -+ # else: -+ # VarStr = 'x' -+ # VarNames='('+','.join((VarStr+str(i+1) for i in range(n)))+')' -+ # R=singular.ring(FieldStr,VarNames,'dp') -+ # if hasattr(F,'polynomial') and F.gen()!=1: # we have to define minpoly -+ # singular.eval('minpoly = '+str(F.polynomial()).replace('x',str(F.gen()))) -+ # A = [singular.matrix(n,n,str((x.matrix()).list())) for x in gens] -+ # Lgens = ','.join((x.name() for x in A)) -+ # PR = PolynomialRing(F,n,[VarStr+str(i) for i in range(1,n+1)]) -+ # if q == 0 or (q > 0 and self.cardinality()%q != 0): -+ # from sage.all import Integer, Matrix -+ # gapself = self.gap() -+ -+ # ReyName = 't'+singular._next_var_name() -+ # singular.eval('matrix %s[%d][%d]'%(ReyName,self.cardinality(),n)) -+ # En = gapself.Enumerator() -+ # for i in range(1,self.cardinality()+1): -+ # M = Matrix(En[i],F) -+ # D = [{} for foobar in range(self.degree())] -+ # for x,y in M.dict().items(): -+ # D[x[0]][x[1]] = y -+ # for row in range(self.degree()): -+ # for t in D[row].items(): -+ # singular.eval('%s[%d,%d]=%s[%d,%d]+(%s)*var(%d)'%(ReyName,i,row+1,ReyName,i,row+1, repr(t[1]),t[0]+1)) -+ # foobar = singular(ReyName) -+ # IRName = 't'+singular._next_var_name() -+ # singular.eval('matrix %s = invariant_algebra_reynolds(%s)'%(IRName,ReyName)) -+ -+ # OUT = [singular.eval(IRName+'[1,%d]'%(j)) for j in range(1,1+singular('ncols('+IRName+')'))] -+ # return [PR(gen) for gen in OUT] -+ -+ # if self.cardinality()%q == 0: -+ # PName = 't'+singular._next_var_name() -+ # SName = 't'+singular._next_var_name() -+ # singular.eval('matrix %s,%s=invariant_ring(%s)'%(PName,SName,Lgens)) -+ # OUT = [ -+ # singular.eval(PName+'[1,%d]'%(j))  -+ # for j in range(1,1+singular('ncols('+PName+')')) -+ # ] + [ -+ # singular.eval(SName+'[1,%d]'%(j))  -+ # for j in range(2,1+singular('ncols('+SName+')'))] -+ # return [PR(gen) for gen in OUT] ++ def invariant_generators(self):  ++ r"""  ++ Return invariant ring generators. ++ ++ Computes generators for the polynomial ring ++ F[x_1,\ldots,x_n]^G, where G in GL(n,F) is a finite matrix ++ group. ++  ++ In the "good characteristic" case the polynomials returned ++ form a minimal generating set for the algebra of G-invariant ++ polynomials. In the "bad" case, the polynomials returned ++ are primary and secondary invariants, forming a not ++ necessarily minimal generating set for the algebra of ++ G-invariant polynomials. ++  ++ ALGORITHM: ++ ++ Wraps Singular's invariant_algebra_reynolds and invariant_ring ++ in finvar.lib. ++  ++ EXAMPLES:: ++  ++ sage: F = GF(7); MS = MatrixSpace(F,2,2) ++ sage: gens = [MS([[0,1],[-1,0]]),MS([[1,1],[2,3]])] ++ sage: G = MatrixGroup(gens) ++ sage: G.invariant_generators() ++ [x1^7*x2 - x1*x2^7, x1^12 - 2*x1^9*x2^3 - x1^6*x2^6 + 2*x1^3*x2^9 + x2^12, x1^18 + 2*x1^15*x2^3 + 3*x1^12*x2^6 + 3*x1^6*x2^12 - 2*x1^3*x2^15 + x2^18] ++ sage: q = 4; a = 2 ++ sage: MS = MatrixSpace(QQ, 2, 2) ++ sage: gen1 = [[1/a,(q-1)/a],[1/a, -1/a]]; gen2 = [[1,0],[0,-1]]; gen3 = [[-1,0],[0,1]] ++ sage: G = MatrixGroup([MS(gen1),MS(gen2),MS(gen3)]) ++ sage: G.cardinality() ++ 12 ++ sage: G.invariant_generators() ++ [x1^2 + 3*x2^2, x1^6 + 15*x1^4*x2^2 + 15*x1^2*x2^4 + 33*x2^6] ++ sage: F = GF(5); MS = MatrixSpace(F,2,2) ++ sage: gens = [MS([[1,2],[-1,1]]),MS([[1,1],[-1,1]])] ++ sage: G = MatrixGroup(gens) ++ sage: G.invariant_generators() # long time (67s on sage.math, 2012) ++ [x1^20 + x1^16*x2^4 + x1^12*x2^8 + x1^8*x2^12 + x1^4*x2^16 + x2^20, x1^20*x2^4 + x1^16*x2^8 + x1^12*x2^12 + x1^8*x2^16 + x1^4*x2^20] ++ sage: F=CyclotomicField(8) ++ sage: z=F.gen() ++ sage: a=z+1/z ++ sage: b=z^2 ++ sage: MS=MatrixSpace(F,2,2) ++ sage: g1=MS([[1/a,1/a],[1/a,-1/a]]) ++ sage: g2=MS([[1,0],[0,b]]) ++ sage: g3=MS([[b,0],[0,1]]) ++ sage: G=MatrixGroup([g1,g2,g3]) ++ sage: G.invariant_generators() # long time (12s on sage.math, 2011) ++ [x1^8 + 14*x1^4*x2^4 + x2^8, ++ x1^24 + 10626/1025*x1^20*x2^4 + 735471/1025*x1^16*x2^8 + 2704156/1025*x1^12*x2^12 + 735471/1025*x1^8*x2^16 + 10626/1025*x1^4*x2^20 + x2^24] ++  ++ AUTHORS: ++  ++ - David Joyner, Simon King and Martin Albrecht. ++  ++ REFERENCES: ++  ++ - Singular reference manual ++  ++ - B. Sturmfels, "Algorithms in invariant theory", Springer-Verlag, ++ 1993. ++  ++ - S. King, "Minimal Generating Sets of non-modular invariant ++ rings of finite groups", arXiv:math.AC/0703035  ++ """ ++ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing ++ from sage.interfaces.singular import singular ++ gens = self.gens() ++ singular.LIB("finvar.lib") ++ n = self.degree() #len((gens[0].matrix()).rows()) ++ F = self.base_ring() ++ q = F.characteristic() ++ ## test if the field is admissible ++ if F.gen()==1: # we got the rationals or GF(prime) ++ FieldStr = str(F.characteristic()) ++ elif hasattr(F,'polynomial'): # we got an algebraic extension ++ if len(F.gens())>1: ++ raise NotImplementedError("can only deal with finite fields and (simple algebraic extensions of) the rationals") ++ FieldStr = '(%d,%s)'%(F.characteristic(),str(F.gen())) ++ else: # we have a transcendental extension ++ FieldStr = '(%d,%s)'%(F.characteristic(),','.join([str(p) for p in F.gens()])) ++  ++ ## Setting Singular's variable names ++ ## We need to make sure that field generator and variables get different names. ++ if str(F.gen())[0]=='x':  ++ VarStr = 'y' ++ else: ++ VarStr = 'x' ++ VarNames='('+','.join((VarStr+str(i+1) for i in range(n)))+')' ++ R=singular.ring(FieldStr,VarNames,'dp') ++ if hasattr(F,'polynomial') and F.gen()!=1: # we have to define minpoly ++ singular.eval('minpoly = '+str(F.polynomial()).replace('x',str(F.gen()))) ++ A = [singular.matrix(n,n,str((x.matrix()).list())) for x in gens] ++ Lgens = ','.join((x.name() for x in A)) ++ PR = PolynomialRing(F,n,[VarStr+str(i) for i in range(1,n+1)]) ++ ++ if q == 0 or (q > 0 and self.cardinality()%q != 0): ++ from sage.all import Integer, Matrix ++ try: ++ elements = [ g.matrix() for g in self.list() ] ++ except (TypeError,ValueError): ++ elements ++ if elements is not None: ++ ReyName = 't'+singular._next_var_name() ++ singular.eval('matrix %s[%d][%d]'%(ReyName,self.cardinality(),n)) ++ for i in range(1,self.cardinality()+1): ++ M = Matrix(elements[i-1],F) ++ D = [{} for foobar in range(self.degree())] ++ for x,y in M.dict().items(): ++ D[x[0]][x[1]] = y ++ for row in range(self.degree()): ++ for t in D[row].items(): ++ singular.eval('%s[%d,%d]=%s[%d,%d]+(%s)*var(%d)' ++ %(ReyName,i,row+1,ReyName,i,row+1, repr(t[1]),t[0]+1)) ++ foobar = singular(ReyName) ++ IRName = 't'+singular._next_var_name() ++ singular.eval('matrix %s = invariant_algebra_reynolds(%s)'%(IRName,ReyName)) ++ else: ++ ReyName = 't'+singular._next_var_name() ++ singular.eval('list %s=group_reynolds((%s))'%(ReyName,Lgens)) ++ IRName = 't'+singular._next_var_name() ++ singular.eval('matrix %s = invariant_algebra_reynolds(%s[1])'%(IRName,ReyName)) ++ ++ OUT = [singular.eval(IRName+'[1,%d]'%(j))  ++ for j in range(1,1+singular('ncols('+IRName+')'))] ++ return [PR(gen) for gen in OUT] ++ if self.cardinality()%q == 0: ++ PName = 't'+singular._next_var_name() ++ SName = 't'+singular._next_var_name() ++ singular.eval('matrix %s,%s=invariant_ring(%s)'%(PName,SName,Lgens)) ++ OUT = [ ++ singular.eval(PName+'[1,%d]'%(j))  ++ for j in range(1,1+singular('ncols('+PName+')')) ++ ] + [ ++ singular.eval(SName+'[1,%d]'%(j)) for j in range(2,1+singular('ncols('+SName+')')) ++ ] ++ return [PR(gen) for gen in OUT]  +  diff --git a/sage/groups/matrix_gps/general_linear.py b/sage/groups/matrix_gps/general_linear.py  deleted file mode 100644  new file mode 100644  --- /dev/null  +++ b/sage/groups/matrix_gps/group_element.py -@@ -0,0 +1,560 @@ +@@ -0,0 +1,472 @@  +"""  +Matrix Group Elements  +  + return  + if convert:  + M = parent.matrix_space()(M) ++ from sage.libs.gap.libgap import libgap ++ M_gap = libgap(M)  + if check:  + if not is_Matrix(M):  + raise TypeError('M must be a matrix')  + if M.parent() is not parent.matrix_space():  + raise TypeError('M must be a in the matrix space of the group') -+ parent._check_matrix(M) -+ from sage.libs.gap.libgap import libgap -+ ElementLibGAP.__init__(self, libgap(M), parent) ++ parent._check_matrix(M, M_gap) ++ ElementLibGAP.__init__(self, M_gap, parent)  +  + def __reduce__(self):  + """  + Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3  + """  + g = self.gap() -+ return g.matrix(self.base_ring()) ++ m = g.matrix(self.base_ring()) ++ m.set_immutable() ++ return m  +  + def conjugacy_class(self):  + r"""  + from sage.groups.conjugacy_classes import ConjugacyClassGAP  + return ConjugacyClassGAP(self.parent(), self)  + -+ # def _gap_init_(self): -+ # """ -+ # Return a string representation of a Gap object corresponding to -+ # this matrix group element. -+  -+ # EXAMPLES:: -+  -+ # sage: k = GF(7); G = MatrixGroup([matrix(k,2,[1,1,0,1]), matrix(k,2,[1,0,0,2])]); g = G.1 -+ # sage: g._gap_init_() # The variable$sage27 belongs to gap(k) and is somehow random
-+    #         '[[Z(7)^0,0*Z(7)],[0*Z(7),Z(7)^2]]*One(\$sage27)'
-+    #         sage: gap(g._gap_init_())
-+    #         [ [ Z(7)^0, 0*Z(7) ], [ 0*Z(7), Z(7)^2 ] ]
-+
-+    #     It may be better to use gap(the matrix), since the result is
-+    #     cached.
-+
-+    #     ::
-+
-+    #         sage: gap(G.1)
-+    #         [ [ Z(7)^0, 0*Z(7) ], [ 0*Z(7), Z(7)^2 ] ]
-+    #         sage: gap(G.1).IsMatrix()
-+    #         true
-+    #     """
-+    #     return self.__mat._gap_init_()
-+
-+    # def _latex_(self):
-+    #     r"""
-+    #     Return the GAP latex version of this matrix.
-+
-+    #     AUTHORS:
-+
-+    #     - S. Kohl: Wrote the GAP function.
-+
-+    #     EXAMPLES::
-+
-+    #         sage: F = GF(3); MS = MatrixSpace(F,2,2)
-+    #         sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]
-+    #         sage: G = MatrixGroup(gens)
-+    #         sage: g = G([[1, 1], [0, 1]])
-+    #         sage: print g._gap_latex_()
-+    #         \left(\begin{array}{rr}%
-+    #         Z(3)^{0}&Z(3)^{0}\\%
-+    #         0*Z(3)&Z(3)^{0}\\%
-+    #         \end{array}\right)%
-+
-+    #     Type view(g._latex_()) to see the object in an xdvi window
-+    #     (assuming you have latex and xdvi installed).
-+    #     """
-+    #     s1 = self.__mat._gap_init_()
-+    #     s2 = gap.eval("LaTeX("+s1+")")
-+    #     return eval(s2)
-+
-+
-+    # def __eq__(self, other):
-+    #     """
-+    #     EXAMPLES::
-+
-+    #         sage: F = GF(3); MS = MatrixSpace(F,2)
-+    #         sage: gens = [MS([1,0, 0,1]), MS([1,1, 0,1])]
-+    #         sage: G = MatrixGroup(gens)
-+    #         sage: H = MatrixGroup(gens)
-+    #         sage: g = G([1,1, 0,1])
-+    #         sage: h = H([1,1, 0,1])
-+    #         sage: g == h
-+    #         True
-+    #     """
-+    #     return have_same_parent(self, other) and self.__mat == other.__mat
-+
-+    # def __ne__(self, other):
-+    #     """
-+    #     EXAMPLES::
-+
-+    #         sage: F = GF(3); MS = MatrixSpace(F,2)
-+    #         sage: gens = [MS([1,0, 0,1]), MS([1,1, 0,1])]
-+    #         sage: G = MatrixGroup(gens)
-+    #         sage: H = MatrixGroup(gens)
-+    #         sage: g = G([1,1, 0,1])
-+    #         sage: h = H([1,1, 0,1])
-+    #         sage: g != h
-+    #         False
-+    #     """
-+    #     return not self.__eq__(other)
-+
-+    def __setstate__(self, state):
-+        """
-+        sage: load('/tmp/pickle_jar/_class__sage_groups_matrix_gps_matrix_group_element_MatrixGroupElement__.sobj')
-+
-+        sage: explain_pickle(file='/tmp/pickle_jar/_class__sage_groups_matrix_gps_matrix_group_element_MatrixGroupElement__.sobj')
-+
-+        """
-+        print state
 +
 diff --git a/sage/groups/matrix_gps/homset.py b/sage/groups/matrix_gps/homset.py
 --- a/sage/groups/matrix_gps/homset.py
 +++ b/sage/groups/matrix_gps/homset.py
-@@ -1,5 +1,5 @@
+@@ -4,6 +4,8 @@
+ AUTHORS:
+
+ - William Stein (2006-05-07): initial version
++
++- Volker Braun (2013-1) port to new Parent, libGAP
  """
--Matrix Group Homsets
-+hMatrix Group Homsets
-
- AUTHORS:
-
-@@ -17,22 +17,18 @@
+
+ ##############################################################################
+@@ -17,22 +19,18 @@
  ##############################################################################

  from sage.groups.group_homset import GroupHomset_generic
          sage: F = GF(5)
          sage: gens = [matrix(F,2,[1,2, -1, 1]), matrix(F,2, [1,1, 0,1])]
          sage: G = MatrixGroup(gens)
-@@ -43,35 +39,23 @@
+@@ -43,35 +41,23 @@
      """
      return isinstance(x, MatrixGroupHomset)

          EXAMPLES::

              sage: F = GF(5)
-@@ -79,11 +63,18 @@
+@@ -79,11 +65,18 @@
              sage: G = MatrixGroup(gens)
              sage: from sage.groups.matrix_gps.homset import MatrixGroupHomset
              sage: MatrixGroupHomset(G, G)

      def __call__(self, im_gens, check=True):
          """
-@@ -91,10 +82,15 @@
+@@ -91,10 +84,15 @@

          INPUT:


          EXAMPLES::

-@@ -104,15 +100,18 @@
+@@ -104,15 +102,18 @@
              sage: from sage.groups.matrix_gps.homset import MatrixGroupHomset
              sage: M = MatrixGroupHomset(G, G)
              sage: M(gens)
 +
 +class LinearMatrixGroup_generic(NamedMatrixGroup_generic):
 +
-+    def _check_matrix(self, x):
++    def _check_matrix(self, x, *args):
 +        """a
 +        Check whether the matrix x is special linear.
 +
 +                raise TypeError('matrix must non-zero determinant')
 +
 +
-+class LinearMatrixGroup_gap(LinearMatrixGroup_generic, NamedMatrixGroup_gap):
++class LinearMatrixGroup_gap(NamedMatrixGroup_gap, LinearMatrixGroup_generic):
 +    pass
 diff --git a/sage/groups/matrix_gps/matrix_group.py b/sage/groups/matrix_gps/matrix_group.py
 --- a/sage/groups/matrix_gps/matrix_group.py
  #
  #  Distributed under the terms of the GNU General Public License (GPL)
  #
-@@ -74,30 +51,28 @@
+@@ -74,32 +51,28 @@
  ##############################################################################


  from sage.structure.sage_object import SageObject
 -from sage.groups.class_function import ClassFunction
  from sage.misc.decorators import rename_keyword
-+from sage.misc.cachefunc import cached_method
-+
+-from sage.groups.conjugacy_classes import ConjugacyClassGAP
+ from sage.misc.cachefunc import cached_method
+
 +from sage.groups.group import Group
 +from sage.groups.libgap_wrapper import ParentLibGAP
 +from sage.groups.libgap_mixin import GroupMixinLibGAP
 +
 +from sage.groups.matrix_gps.group_element import (
 +    is_MatrixGroupElement, MatrixGroupElement_generic, MatrixGroupElement_gap)
-
++
  #################################################################

 -class MatrixGroup_generic(Group):
      EXAMPLES::

          sage: from sage.groups.matrix_gps.matrix_group import is_MatrixGroup
-@@ -110,163 +85,248 @@
+@@ -112,163 +85,251 @@
          sage: is_MatrixGroup(MatrixGroup([matrix(2,[1,1,0,1])]))
          True
      """

 -class MatrixGroup_gap(MatrixGroup_generic):
 -    Element = MatrixGroupElement
-+    def _check_matrix(self, x):
++    def _check_matrix(self, x, *args):
 +        """
 +        Check whether the matrix x defines a group element.

 +        - x -- a Sage matrix in the correct matrix space (degree
 +          and base ring).
 +
++        - *args -- optional other representations of x,
++          depending on the group implementation. Ignored by default.
++
 +        OUTPUT:
 +
 +        A TypeError must be raised if x is invalid.
      def matrix_space(self):
          """
          Return the matrix space corresponding to this matrix group.
-@@ -280,958 +340,224 @@
+@@ -282,1001 +343,263 @@
              sage: G = MatrixGroup([MS(1), MS([1,2,3,4])])
              sage: G.matrix_space()
              Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 5
 +        Construct a homset.

 -    def base_ring(self):
--        """
++        INPUT:
++
++        - G -- group. The codomain.
++
++        - cat -- a category. Must be unset.
++
++        OUTPUT:
++
++        The set of homomorphisms from self to G.
++
++        EXAMPLES::
++
++            sage: MS = MatrixSpace(SR, 2, 2)
++            sage: G = MatrixGroup([MS(1), MS([1,2,3,4])])
++            sage: G.Hom(G)
++            Set of Homomorphisms from Matrix group over Symbolic Ring with 2 generators (
++            [1 0]  [1 2]
++            [0 1], [3 4]
++            ) to Matrix group over Symbolic Ring with 2 generators (
++            [1 0]  [1 2]
++            [0 1], [3 4]
++            )
+         """
 -        Return the base ring of this matrix group.
--
++        if not (cat is None or (cat is G.category() and cat is self.category())):
++            raise TypeError
++        if not is_MatrixGroup(G):
++            raise TypeError, "G (=%s) must be a matrix group."%G
++        import homset
++        return homset.MatrixGroupHomset(self, G)
++
++    def hom(self, x):
++        """
++        Return the group homomorphism defined by x
++
++        INPUT:
++
++        - x -- a list/tuple/iterable of matrix group elements.
++
++        OUTPUT:
++
++        The group homomorphism defined by x.
++
++        EXAMPLES::
++
++            sage: G = MatrixGroup([matrix(GF(5), [[1,3],[0,1]])])
++            sage: H = MatrixGroup([matrix(GF(5), [[1,2],[0,1]])])
++            sage: G.hom([H.gen(0)])
++            Homomorphism : Matrix group over Finite Field of size 5 with 1 generators (
++            [1 3]
++            [0 1]
++            ) --> Matrix group over Finite Field of size 5 with 1 generators (
++            [1 2]
++            [0 1]
++            )
++        """
++        v = Sequence(x)
++        U = v.universe()
++        if not is_MatrixGroup(U):
++            raise TypeError, "u (=%s) must have universe a matrix group."%U
++        return self.Hom(U)(x)
++
++
++
++###################################################################
++#
++# Matrix group over a ring that GAP understands
++#
++###################################################################
++
++class MatrixGroup_gap(GroupMixinLibGAP, MatrixGroup_generic, ParentLibGAP):
++
++    Element = MatrixGroupElement_gap
++
++    def __init__(self, degree, base_ring, libgap_group, ambient=None, category=None):
++        """
++        Base class for matrix groups that implements GAP interface.
++
++        INPUT:
+
 -        EXAMPLES::
--
++        - degree -- integer. The degree (matrix size) of the
++           matrix group.
+
 -            sage: GL(2,GF(3)).base_ring()
 -            Finite Field of size 3
 -            sage: G = SU(3,GF(5))
 -            Finite Field of size 5
 -            sage: G.field_of_definition()
 -            Finite Field in a of size 5^2
--        """
++        - base_ring -- ring. The base ring of the matrices.
++
++        - libgap_group -- the defining libgap group.
++
++        - ambient -- A derived class of :class:ParentLibGAP or
++          None (default). The ambient class if libgap_group
++          has been defined as a subgroup.
++
++        TESTS::
++
++            sage: from sage.groups.matrix_gps.matrix_group import MatrixGroup_gap
++            sage: MatrixGroup_gap(2, ZZ, libgap.eval('GL(2, Integers)'))
++            Matrix group over Integer Ring with 3 generators (
++            [0 1]  [-1  0]  [1 1]
++            [1 0], [ 0  1], [0 1]
++            )
+         """
 -        return self.__R
-+        INPUT:
++        ParentLibGAP.__init__(self, libgap_group, ambient=ambient)
++        MatrixGroup_generic.__init__(self, degree, base_ring, category=category)

 -    base_field = base_ring
-+        - G -- group. The codomain.
++    def _check_matrix(self, x_sage, x_gap):
++        """
++        Check whether the matrix x defines a group element.

 -    def is_abelian(self):
 -        r"""
 -        Note: The result is cached, since it tends to get called
 -        rather often (e.g. by word_problem) and it's very slow to
 -        use the Gap interface every time.
-+        - cat -- a category. Must be unset.
-
--        EXAMPLES::
--
++        This is used by the element constructor (if you pass
++        check=True, the default) that the defining matrix is valid
++        for this parent. Derived classes must override this to verify
++        that the matrix is, for example, orthogonal or symplectic.
++
++        INPUT:
++
++        - x_sage -- a Sage matrix in the correct matrix space (degree
++          and base ring).
++
++        - x_gap -- the corresponding LibGAP matrix.
++
++        OUTPUT:
++
++        A TypeError must be raised if x is invalid.
+
+         EXAMPLES::
+
 -            sage: SL(1, 17).is_abelian()
 -            True
 -            sage: SL(2, 17).is_abelian()
 -        except AttributeError:
 -            self.__is_abelian = self._gap_().IsAbelian().bool()
 -            return self.__is_abelian
-+        OUTPUT:
-
+-
 -    def is_finite(self):
 -        """
 -        Return True if this matrix group is finite.
 -        Backward compatibility alias for :meth:.cardinality.
 -
 -        Might be deprecated in the future.
-+        The set of homomorphisms from self to G.
-
-         EXAMPLES::
-
+-
+-        EXAMPLES::
+-
 -            sage: G = Sp(4,GF(3))
 -            sage: G.order()
 -            51840
-+            sage: MS = MatrixSpace(SR, 2, 2)
-+            sage: G = MatrixGroup([MS(1), MS([1,2,3,4])])
-+            sage: G.Hom(G)
-+            Set of Homomorphisms from Matrix group over Symbolic Ring with 2 generators (
-+            [1 0]  [1 2]
-+            [0 1], [3 4]
-+            ) to Matrix group over Symbolic Ring with 2 generators (
-+            [1 0]  [1 2]
-+            [0 1], [3 4]
-+            )
-         """
+-        """
 -        return self.cardinality()
-+        if not (cat is None or (cat is G.category() and cat is self.category())):
-+            raise TypeError
-+        if not is_MatrixGroup(G):
-+            raise TypeError, "G (=%s) must be a matrix group."%G
-+        import homset
-+        return homset.MatrixGroupHomset(self, G)
-
+-
 -    def __len__(self):
-+    def hom(self, x):
-         """
+-        """
 -        __len__ has been removed ! to get the number of element in a
 -        matrix group, use :meth:.cardinality.
 -
 -
 -            sage: G = GO(3,GF(5))
 -            sage: len(G)
--            Traceback (most recent call last):
--            ...
++            sage: m1 = matrix(GF(11), [(0, -1), (1, 0)])
++            sage: m2 = matrix(GF(11), [(0, -1), (1, -1)])
++            sage: G = MatrixGroup([m1, m2])
++            sage: G([1,2,0,1])
++            [1 2]
++            [0 1]
++            sage: G([1,1,1,0])
+             Traceback (most recent call last):
+             ...
 -            AttributeError: __len__ has been removed; use .cardinality() instead
--
--        """
++            TypeError: matrix is not in the finitely generated group
++        """
++        from sage.libs.gap.libgap import libgap
++        libgap_contains = libgap.eval('\in')
++        is_contained = libgap_contains(x_gap, self.gap())
++        if not is_contained.sage():
++            raise TypeError('matrix is not in the finitely generated group')
+
++    def _subgroup_constructor(self, libgap_subgroup):
+         """
 -        raise AttributeError, "__len__ has been removed; use .cardinality() instead"
--
++        Return a finitely generated subgroup.
+
 -    def gens(self):
 -        """
 -        Return generators for this matrix group.
 -                        cr=True, universe=self, check=False)
 -        self.__gens = gens
 -        return gens
--
++        See
++        :meth:sage.groups.libgap_wrapper.ParentLibGAP._subgroup_constructor
++        for details.
+
 -    def ngens(self):
 -        """
 -        Return the number of generators of this linear group.
 -            2
 -        """
 -        return len(self.gens())
--
++        TESTS::
+
 -
 -    def gen(self, n):
 -        """
 -            [1 3]
 -            [0 3]
 -            sage: G.random_element() in G
--            True
--        """
++            sage: SL2Z = SL(2,ZZ)
++            sage: S, T = SL2Z.gens()
++            sage: G = SL2Z.subgroup([T^2]); G   # indirect doctest
++            Matrix group over Integer Ring with 1 generators (
++            [1 2]
++            [0 1]
++            )
++            sage: G.ambient() is SL2Z
+             True
+         """
 -        # Note: even with fixed random seed, the Random() element
 -        # returned by gap does depend on execution order and
 -        # architecture. Presumably due to different memory loctions.
 -        current_randstate().set_seed_gap()
 -        F = self.field_of_definition()
 -        return self.element_class(gap(self).Random()._matrix_(F), self, check=False)
--
++        from sage.groups.matrix_gps.finitely_generated import FinitelyGeneratedMatrixGroup_gap
++        return FinitelyGeneratedMatrixGroup_gap(self.degree(), self.base_ring(),
++                                                libgap_subgroup, ambient=self)
+
 -    def random(self):
 -        """
 -        Deprecated. Use self.random_element() instead.
 -        """
 -        raise NotImplementedError, "Deprecated: use random_element() instead"
--
--
+
+
 -    def __contains__(self, x):
 -        """
 -        Return True if x is an element of this abelian group.
 -        F    = self.field_of_definition()
 -        self.__reps = Sequence([self(g._matrix_(F)) for g in reps], cr=True, universe=self, check=False)
 -        return self.__reps
--
+-
+-    def conjugacy_class(self, g):
+-        r"""
+-        Return the conjugacy class of g inside of self.
+-
+-        INPUT:
+-
+-        - g -- an element of self
+-
+-        OUTPUT:
+-
+-        The conjugacy class of g in the group self. If self is the
+-        group denoted by G, this method computes the set
+-        \{x^{-1}gx\ \vert\ x\in G\}.
+-
+-        EXAMPLES::
+-
+-            sage: G = SL(3, GF(3))
+-            sage: g = G.gens()[0]
+-            sage: G.conjugacy_class(g)
+-            Conjugacy class of [1 1 0]
+-            [0 1 0]
+-            [0 0 1] in Special Linear Group of degree 3 over Finite Field of size 3
+-        """
+-        return ConjugacyClassGAP(self, g)
+-
+-    @cached_method
+-    def conjugacy_classes(self):
+-        r"""
+-        Return a list with all the conjugacy classes of self.
+-
+-        EXAMPLES::
+-
+-            sage: G = SL(2, GF(2))
+-            sage: G.conjugacy_classes()
+-            [Conjugacy class of [1 0]
+-            [0 1] in Special Linear Group of degree 2 over Finite Field of size 2, Conjugacy class of [0 1]
+-            [1 0] in Special Linear Group of degree 2 over Finite Field of size 2, Conjugacy class of [0 1]
+-            [1 1] in Special Linear Group of degree 2 over Finite Field of size 2]
+-        """
+-        CC = self._gap_().ConjugacyClasses()
+-        reps = list(gap.List(CC, 'x -> Representative(x)'))
+-        return [ConjugacyClassGAP(self, self(g._matrix_(self.field_of_definition()))) for g in reps]
+-
 -    def center(self):