1. Volker Braun
  2. MQ for Sage toric varieties

Commits

Volker Braun  committed 828d928

finished matrix groups

  • Participants
  • Parent commits 64f083b
  • Branches default

Comments (0)

Files changed (4)

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

View file
  • 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

View file
  • 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):