Ticket #6670: trac_6670-jhp.patch

File trac_6670-jhp.patch, 32.0 KB (added by John Palmieri, 11 years ago)
  • doc/en/reference/algebras.rst

    # HG changeset patch
    # User J. H. Palmieri <palmieri@math.washington.edu>
    # Date 1311891470 25200
    # Node ID ad609fc9ed37cd579b8402b749c38d0ebf415299
    # Parent  57e08f919b352054d47c864bdcdaab3bc33692f2
    #6670: Port group algebras to the current coercion system
    
    diff --git a/doc/en/reference/algebras.rst b/doc/en/reference/algebras.rst
    a b Algebras 
    1212   sage/algebras/free_algebra_quotient
    1313   sage/algebras/free_algebra_quotient_element
    1414
     15   sage/algebras/group_algebra_new
     16
    1517   sage/algebras/steenrod/steenrod_algebra
    1618   sage/algebras/steenrod/steenrod_algebra_bases
    1719   sage/algebras/steenrod/steenrod_algebra_misc
  • sage/algebras/all.py

    diff --git a/sage/algebras/all.py b/sage/algebras/all.py
    a b from free_algebra_quotient import FreeAl 
    3131
    3232from steenrod.all import *
    3333
    34 from group_algebra import GroupAlgebra, GroupAlgebraElement
     34from group_algebra_new import GroupAlgebra
    3535
    3636from iwahori_hecke_algebra import IwahoriHeckeAlgebraT
    3737from affine_nil_temperley_lieb import AffineNilTemperleyLiebTypeA
  • sage/algebras/group_algebra.py

    diff --git a/sage/algebras/group_algebra.py b/sage/algebras/group_algebra.py
    a b from sage.structure.formal_sum import Fo 
    3434from sage.sets.set import Set
    3535
    3636
     37from sage.misc.misc import deprecation
     38deprecation("The module group_algebra is deprecated and will be removed in a future version of Sage. Use group_algebra_new instead.")
     39
     40
    3741class GroupAlgebra(Algebra):
    3842
    3943    def __init__(self, group, base_ring = IntegerRing()):
    class GroupAlgebra(Algebra): 
    4650
    4751        EXAMPLES::
    4852
     53            sage: from sage.algebras.group_algebra import GroupAlgebra
     54            doctest:1: DeprecationWarning:...           
    4955            sage: GroupAlgebra(GL(3, GF(7)))
    5056            Group algebra of group "General Linear Group of degree 3 over Finite
    5157            Field of size 7" over base ring Integer Ring
    class GroupAlgebra(Algebra): 
    7278    def group(self):
    7379        r""" Return the group of this group algebra.
    7480        EXAMPLES:
     81            sage: from sage.algebras.group_algebra import GroupAlgebra
    7582            sage: GroupAlgebra(GL(3, GF(11))).group()
    7683            General Linear Group of degree 3 over Finite Field of size 11
    7784            sage: GroupAlgebra(SymmetricGroup(10)).group()
    class GroupAlgebra(Algebra): 
    8491        self.group() is abelian.
    8592
    8693        EXAMPLES:
     94            sage: from sage.algebras.group_algebra import GroupAlgebra
    8795            sage: GroupAlgebra(SymmetricGroup(2)).is_commutative()
    8896            True
    8997            sage: GroupAlgebra(SymmetricGroup(3)).is_commutative()
    class GroupAlgebra(Algebra): 
    95103        r""" Return True if self is a field. This is always false unless
    96104        self.group() is trivial and self.base_ring() is a field.
    97105        EXAMPLES:
     106            sage: from sage.algebras.group_algebra import GroupAlgebra
    98107            sage: GroupAlgebra(SymmetricGroup(2)).is_field()
    99108            False
    100109            sage: GroupAlgebra(SymmetricGroup(1)).is_field()
    class GroupAlgebra(Algebra): 
    111120        self.group() and self.base_ring() are both finite.
    112121       
    113122        EXAMPLES:
     123            sage: from sage.algebras.group_algebra import GroupAlgebra
    114124            sage: GroupAlgebra(SymmetricGroup(2), IntegerModRing(10)).is_finite()
    115125            True
    116126            sage: GroupAlgebra(SymmetricGroup(2)).is_finite()
    class GroupAlgebra(Algebra): 
    126136        and self.base_ring().
    127137
    128138        EXAMPLES:
     139            sage: from sage.algebras.group_algebra import GroupAlgebra
    129140            sage: GroupAlgebra(GL(3, GF(7))).is_exact()
    130141            True
    131142            sage: GroupAlgebra(GL(3, GF(7)), RR).is_exact()
    class GroupAlgebra(Algebra): 
    145156        finitely generated.
    146157
    147158        EXAMPLES:
     159            sage: from sage.algebras.group_algebra import GroupAlgebra
    148160            sage: GroupAlgebra(SymmetricGroup(2)).is_integral_domain()
    149161            False
    150162            sage: GroupAlgebra(SymmetricGroup(1)).is_integral_domain()
    class GroupAlgebra(Algebra): 
    199211        Return an element of self.
    200212       
    201213        EXAMPLE:
     214            sage: from sage.algebras.group_algebra import GroupAlgebra
    202215            sage: GroupAlgebra(SU(2, 13), QQ).an_element() # random; hideous formatting!
    203216            -1/95*[       9 2*a + 12]
    204217            [       0        3] - 4*[      9 9*a + 2]
    class GroupAlgebra(Algebra): 
    229242            -- a GroupAlgebraElement instance whose parent is self.
    230243
    231244        EXAMPLES:
     245            sage: from sage.algebras.group_algebra import GroupAlgebra
    232246            sage: G = AbelianGroup(1)
    233247            sage: f = G.gen()
    234248            sage: ZG = GroupAlgebra(G)
    class GroupAlgebra(Algebra): 
    266280    def __eq__(self, other):
    267281        r""" Test for equality.
    268282        EXAMPLES:
     283            sage: from sage.algebras.group_algebra import GroupAlgebra
    269284            sage: GroupAlgebra(AbelianGroup(1)) == GroupAlgebra(AbelianGroup(1))
    270285            True
    271286            sage: GroupAlgebra(AbelianGroup(1), QQ) == GroupAlgebra(AbelianGroup(1), ZZ)
    class GroupAlgebra(Algebra): 
    288303        The class of elements of self, which is GroupAlgebraElement.
    289304
    290305        EXAMPLES:
     306            sage: from sage.algebras.group_algebra import GroupAlgebra
    291307            sage: GroupAlgebra(SU(2, GF(4,'a'))).element_class()
    292308            <class 'sage.algebras.group_algebra.GroupAlgebraElement'>
    293309        """
    class GroupAlgebraElement(AlgebraElement 
    329345        Add self to other.
    330346       
    331347        EXAMPLE:
     348            sage: from sage.algebras.group_algebra import GroupAlgebra
    332349            sage: G = GL(3, GF(7))
    333350            sage: ZG = GroupAlgebra(G)
    334351            sage: g1 = G([0,0,2,2,5,0,6,6,2])
    class GroupAlgebraElement(AlgebraElement 
    345362        r""" Calculate self*right, where both self and right are GroupAlgebraElements.
    346363       
    347364        EXAMPLE:
     365            sage: from sage.algebras.group_algebra import GroupAlgebra
    348366            sage: G = GL(3, GF(7))
    349367            sage: ZG = GroupAlgebra(G)
    350368            sage: a, b = G.random_element(), G.random_element()
    class GroupAlgebraElement(AlgebraElement 
    375393        r""" Test if self is equal to other.
    376394
    377395        EXAMPLES:
     396            sage: from sage.algebras.group_algebra import GroupAlgebra
    378397            sage: G = AbelianGroup(1,[4])
    379398            sage: a = GroupAlgebra(G)(1)
    380399            sage: b = GroupAlgebra(G)(2)
  • new file sage/algebras/group_algebra_new.py

    diff --git a/sage/algebras/group_algebra_new.py b/sage/algebras/group_algebra_new.py
    new file mode 100644
    - +  
     1r"""
     2Group algebras
     3
     4This module implements group algebras for arbitrary groups over
     5arbitrary commutative rings.
     6
     7EXAMPLES::
     8
     9    sage: D4 = DihedralGroup(4)
     10    sage: kD4 = GroupAlgebra(D4, GF(7))
     11    sage: a = kD4.an_element(); a
     12    () + 2*(2,4) + 3*(1,2)(3,4) + (1,2,3,4)
     13    sage: a * a
     14    (1,2)(3,4) + (1,2,3,4) + 3*(1,3) + (1,3)(2,4) + 6*(1,4,3,2) + 2*(1,4)(2,3)
     15
     16Given the group and the base ring, the corresponding group algebra is unique::
     17
     18    sage: A = GroupAlgebra(GL(3, QQ), ZZ)
     19    sage: B = GroupAlgebra(GL(3, QQ), ZZ)
     20    sage: A is B
     21    True
     22    sage: C = GroupAlgebra(GL(3, QQ), QQ)
     23    sage: A == C
     24    False
     25
     26As long as there is no natural map from the group to the base ring,
     27you can easily convert elements of the group to the group algebra::
     28
     29    sage: A = GroupAlgebra(DihedralGroup(2), ZZ)
     30    sage: g = DihedralGroup(2).gen(0); g
     31    (3,4)
     32    sage: A(g)
     33    (3,4)
     34    sage: A(2) * g
     35    2*(3,4)
     36
     37Since there is a natural inclusion from the dihedral group `D_2` of
     38order 4 into the symmetric group `S_4` of order 4!, and since there is
     39a natural map from the integers to the rationals, there is a natural
     40map from `\ZZ[D_2]` to `\QQ[S_4]`::
     41
     42    sage: A = GroupAlgebra(DihedralGroup(2), ZZ)
     43    sage: B = GroupAlgebra(SymmetricGroup(4), QQ)
     44    sage: a = A.an_element(); a
     45    () + 3*(3,4) + 3*(1,2)
     46    sage: b = B.an_element(); b
     47    () + 2*(3,4) + 3*(2,3) + (1,2,3,4)
     48    sage: B(a)
     49    () + 3*(3,4) + 3*(1,2)
     50    sage: a * b  # a is automatically converted to an element of B
     51    7*() + 5*(3,4) + 3*(2,3) + 9*(2,3,4) + 3*(1,2) + 6*(1,2)(3,4) + 3*(1,2,3) + (1,2,3,4) + 9*(1,3,2) + 3*(1,3,4)
     52    sage: parent(a * b)
     53    Group algebra of group "SymmetricGroup(4)" over base ring Rational Field
     54
     55    sage: G = GL(3, GF(7))
     56    sage: ZG = GroupAlgebra(G)
     57    sage: c, d = G.random_element(), G.random_element()
     58    sage: zc, zd = ZG(c), ZG(d)
     59    sage: zc * d == zc * zd  # d is automatically converted to an element of ZG
     60    True
     61
     62There is no obvious map in the other direction, though::
     63
     64    sage: A(b)
     65    Traceback (most recent call last):
     66    ...
     67    TypeError: Don't know how to create an element of Group algebra of group "Dihedral group of order 4 as a permutation group" over base ring Integer Ring from () + 2*(3,4) + 3*(2,3) + (1,2,3,4)
     68
     69Group algebras have the structure of Hopf algebras::
     70
     71    sage: a = kD4.an_element(); a
     72    () + 2*(2,4) + 3*(1,2)(3,4) + (1,2,3,4)
     73    sage: a.antipode()
     74    () + 2*(2,4) + 3*(1,2)(3,4) + (1,4,3,2)
     75    sage: a.coproduct()
     76    () # () + 2*(2,4) # (2,4) + 3*(1,2)(3,4) # (1,2)(3,4) + (1,2,3,4) # (1,2,3,4)
     77
     78.. note::
     79
     80    As alluded to above, it is problematic to make group algebras fit
     81    nicely with Sage's coercion model. The problem is that (for
     82    example) if G is the additive group `(\ZZ,+)`, and `R = \ZZ[G]` is
     83    its group ring, then the integer 2 can be coerced into R in two
     84    ways -- via G, or via the base ring -- and *the answers are
     85    different*. In practice we get around this by preventing elements
     86    of a group `H` from coercing automatically into a group ring
     87    `k[G]` if `H` coerces into both `k` and `G`.  This is unfortunate,
     88    but it seems like the most sensible solution in this ambiguous
     89    situation.
     90
     91AUTHOR:
     92
     93- David Loeffler (2008-08-24): initial version
     94- Martin Raum (2009-08): update to use new coercion model -- see trac
     95  ticket #6670
     96- John Palmieri (2011-07): more updates to coercion, categories, etc.,
     97  group algebras constructed using CombinatorialFreeModule -- see trac
     98  ticket #6670
     99"""
     100
     101#*****************************************************************************
     102#       Copyright (C) 2008 William Stein <wstein@gmail.com>
     103#                     2008 David Loeffler <d.loeffler.01@cantab.net>
     104#                     2009 Martin Raum <mraum@mpim-bonn.mpg.de>
     105#                     2011 John Palmieri <palmieri@math.washington.edu>
     106#  Distributed under the terms of the GNU General Public License (GPL)
     107#                  http://www.gnu.org/licenses/
     108#*****************************************************************************
     109
     110from sage.algebras.algebra import Algebra
     111from sage.rings.all import IntegerRing
     112from sage.misc.cachefunc import cached_method
     113from sage.categories.pushout import ConstructionFunctor
     114from sage.combinat.free_module import CombinatorialFreeModule
     115from sage.categories.all import Rings, HopfAlgebrasWithBasis
     116
     117class GroupAlgebraFunctor (ConstructionFunctor) :
     118    r"""
     119    For a fixed group, a functor sending a commutative ring to the
     120    corresponding group algebra.
     121
     122    INPUT :
     123
     124    - ``group`` -- the group associated to each group algebra under
     125      consideration.
     126 
     127    EXAMPLES::
     128 
     129        sage: from sage.algebras.group_algebra_new import GroupAlgebraFunctor
     130        sage: F = GroupAlgebraFunctor(KleinFourGroup())
     131        sage: loads(dumps(F)) == F
     132        True
     133        sage: GroupAlgebra(SU(2, GF(4, 'a')), IntegerModRing(12)).category()
     134        Category of hopf algebras with basis over Ring of integers modulo 12
     135    """
     136    def __init__(self, group) :
     137        r"""
     138        See :class:`GroupAlgebraFunctor` for full documentation.
     139       
     140        EXAMPLES::
     141 
     142            sage: from sage.algebras.group_algebra_new import GroupAlgebraFunctor
     143            sage: GroupAlgebra(SU(2, GF(4, 'a')), IntegerModRing(12)).category()
     144            Category of hopf algebras with basis over Ring of integers modulo 12
     145        """
     146        self.__group = group
     147 
     148        ConstructionFunctor.__init__(self, Rings(), Rings())
     149
     150    def group(self) :
     151        r"""
     152        Return the group which is associated to this functor.
     153
     154        EXAMPLES::
     155
     156            sage: from sage.algebras.group_algebra_new import GroupAlgebraFunctor
     157            sage: GroupAlgebraFunctor(CyclicPermutationGroup(17)).group() == CyclicPermutationGroup(17)
     158            True
     159         """
     160        return self.__group
     161
     162    def __call__(self, base_ring) :
     163        r"""
     164        Create the group algebra with given base ring over self.group().
     165
     166        INPUT :
     167
     168        - ``base_ring`` - the base ring of the group algebra.
     169
     170        OUTPUT:
     171
     172        A group algebra.
     173
     174        EXAMPLES::
     175
     176            sage: from sage.algebras.group_algebra_new import GroupAlgebraFunctor
     177            sage: F = GroupAlgebraFunctor(CyclicPermutationGroup(17))
     178            sage: F(QQ)
     179            Group algebra of group "Cyclic group of order 17 as a permutation group" over base ring Rational Field
     180        """
     181        return GroupAlgebra(self.__group, base_ring)
     182
     183class GroupAlgebra(CombinatorialFreeModule, Algebra):
     184    r"""
     185    Create the given group algebra.
     186
     187    INPUT:
     188
     189    - ``group``, a group
     190    - ``base_ring`` (optional, default `\ZZ`), a commutative ring
     191
     192    OUTPUT:
     193
     194    -- a ``GroupAlgebra`` instance.
     195
     196    EXAMPLES::
     197
     198        sage: GroupAlgebra(GL(3, GF(7)))
     199        Group algebra of group "General Linear Group of degree 3 over Finite Field of size 7" over base ring Integer Ring
     200        sage: GroupAlgebra(GL(3, GF(7)), QQ)
     201        Group algebra of group "General Linear Group of degree 3 over Finite Field of size 7" over base ring Rational Field
     202        sage: GroupAlgebra(1)
     203        Traceback (most recent call last):
     204        ...
     205        TypeError: "1" is not a group
     206
     207        sage: GroupAlgebra(SU(2, GF(4, 'a')), IntegerModRing(12)).category()
     208        Category of hopf algebras with basis over Ring of integers modulo 12
     209        sage: GroupAlgebra(KleinFourGroup()) is GroupAlgebra(KleinFourGroup())
     210        True
     211
     212    TESTS::
     213
     214        sage: A = GroupAlgebra(GL(3, GF(7)))
     215        sage: A.has_coerce_map_from(GL(3, GF(7)))
     216        True
     217        sage: G = SymmetricGroup(5)
     218        sage: x,y = G.gens()
     219        sage: A = GroupAlgebra(G)
     220        sage: A( A(x) )
     221        (1,2,3,4,5)
     222    """
     223    def __init__(self, group, base_ring=IntegerRing()):
     224        r"""
     225        See :class:`GroupAlgebra` for full documentation.
     226
     227        EXAMPLES::
     228
     229            sage: GroupAlgebra(GL(3, GF(7)))
     230            Group algebra of group "General Linear Group of degree 3 over Finite Field of size 7" over base ring Integer Ring
     231        """
     232        from sage.groups.group import Group
     233        if not base_ring.is_commutative():
     234            raise NotImplementedError, "Base ring must be commutative"
     235
     236        if not isinstance(group, Group):
     237            raise TypeError, '"%s" is not a group' % group
     238
     239        self._group = group
     240        CombinatorialFreeModule.__init__(self, base_ring, group,
     241                                         prefix='',
     242                                         bracket=False,
     243                                         category=HopfAlgebrasWithBasis(base_ring))
     244
     245        if not base_ring.has_coerce_map_from(group) :
     246            ## some matrix groups assume that coercion is only valid to
     247            ## other matrix groups. This is a workaround
     248            ## call _element_constructor_ to coerce group elements
     249            #try :
     250            self._populate_coercion_lists_(coerce_list=[base_ring, group])
     251            #except TypeError :
     252            #    self._populate_coercion_lists_( coerce_list = [base_ring] )
     253        else :
     254            self._populate_coercion_lists_(coerce_list=[base_ring])
     255
     256    # Methods taken from sage.categories.examples.hopf_algebras_with_basis:
     257
     258    @cached_method
     259    def one_basis(self):
     260        """
     261        Returns the one of the group, which indexes the one of this
     262        algebra, as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`.
     263
     264        EXAMPLES::
     265
     266            sage: A = GroupAlgebra(DihedralGroup(6), QQ)
     267            sage: A.one_basis()
     268            ()
     269            sage: A.one()
     270            ()
     271        """
     272        return self._group.one()
     273
     274    def product_on_basis(self, g1, g2):
     275        r"""
     276        Product, on basis elements, as per
     277        :meth:`AlgebrasWithBasis.ParentMethods.product_on_basis`.
     278
     279        The product of two basis elements is induced by the product of
     280        the corresponding elements of the group.
     281
     282        EXAMPLES::
     283
     284            sage: A = GroupAlgebra(DihedralGroup(3), QQ)
     285            sage: (a, b) = A._group.gens()
     286            sage: a*b
     287            (1,2)
     288            sage: A.product_on_basis(a, b)
     289            (1,2)
     290        """
     291        return self.basis()[g1 * g2]
     292
     293    @cached_method
     294    def algebra_generators(self):
     295        r"""
     296        The generators of this algebra, as per
     297        :meth:`Algebras.ParentMethods.algebra_generators`.
     298
     299        They correspond to the generators of the group.
     300
     301        EXAMPLES::
     302
     303            sage: A = GroupAlgebra(DihedralGroup(3), QQ); A
     304            Group algebra of group "Dihedral group of order 6 as a permutation group" over base ring Rational Field
     305            sage: A.algebra_generators()
     306            Finite family {(1,2,3): (1,2,3), (1,3): (1,3)}
     307        """
     308        from sage.sets.family import Family
     309        return Family(self._group.gens(), self.monomial)
     310
     311    gens = algebra_generators
     312
     313    def coproduct_on_basis(self, g):
     314        r"""
     315        Coproduct, on basis elements, as per :meth:`HopfAlgebrasWithBasis.ParentMethods.coproduct_on_basis`.
     316
     317        The basis elements are group-like: `\Delta(g) = g \otimes g`.
     318
     319        EXAMPLES::
     320
     321            sage: A = GroupAlgebra(DihedralGroup(3), QQ)
     322            sage: (a, b) = A._group.gens()
     323            sage: A.coproduct_on_basis(a)
     324            (1,2,3) # (1,2,3)
     325        """
     326        from sage.categories.all import tensor
     327        g = self.monomial(g)
     328        return tensor([g, g])
     329
     330    def counit_on_basis(self, g):
     331        r"""
     332        Counit, on basis elements, as per :meth:`HopfAlgebrasWithBasis.ParentMethods.counit_on_basis`.
     333
     334        The counit on the basis elements is 1.
     335
     336        EXAMPLES::
     337
     338            sage: A = GroupAlgebra(DihedralGroup(6), QQ)
     339            sage: (a, b) = A._group.gens()
     340            sage: A.counit_on_basis(a)
     341            1
     342        """
     343        return self.base_ring().one()
     344
     345    def antipode_on_basis(self, g):
     346        r"""
     347        Antipode, on basis elements, as per :meth:`HopfAlgebrasWithBasis.ParentMethods.antipode_on_basis`.
     348
     349        It is given, on basis elements, by `\chi(g) = g^{-1}`
     350
     351        EXAMPLES::
     352
     353            sage: A = GroupAlgebra(DihedralGroup(3), QQ)
     354            sage: (a, b) = A._group.gens()
     355            sage: A.antipode_on_basis(a)
     356            (1,3,2)
     357        """
     358        return self.monomial(~g)
     359
     360    # other methods:
     361
     362    def ngens(self) :
     363        r"""
     364        Return the number of generators.
     365
     366        EXAMPLES::
     367
     368            sage: GroupAlgebra(SL2Z).ngens()
     369            2
     370            sage: GroupAlgebra(DihedralGroup(4), RR).ngens()
     371            2
     372        """
     373        return self.algebra_generators().cardinality()
     374
     375    def gen(self, i = 0) :
     376        r"""
     377        EXAMPLES::
     378
     379            sage: A = GroupAlgebra(GL(3, GF(7)))
     380            sage: A.gen(0)
     381            [3 0 0]
     382            [0 1 0]
     383            [0 0 1]
     384        """
     385        return self.monomial(self._group.gen(i))
     386
     387    def group(self):
     388        r"""
     389        Return the group of this group algebra.
     390       
     391        EXAMPLES::
     392
     393            sage: GroupAlgebra(GL(3, GF(11))).group()
     394            General Linear Group of degree 3 over Finite Field of size 11
     395            sage: GroupAlgebra(SymmetricGroup(10)).group()
     396            Symmetric group of order 10! as a permutation group
     397        """
     398        return self._group
     399
     400    def is_commutative(self):
     401        r"""
     402        Return True if self is a commutative ring. True if and only if
     403        ``self.group()`` is abelian.
     404
     405        EXAMPLES::
     406
     407            sage: GroupAlgebra(SymmetricGroup(2)).is_commutative()
     408            True
     409            sage: GroupAlgebra(SymmetricGroup(3)).is_commutative()
     410            False
     411        """
     412        return self.group().is_abelian()
     413
     414    def is_field(self, proof = True):
     415        r"""
     416        Return True if self is a field. This is always false unless
     417        ``self.group()`` is trivial and ``self.base_ring()`` is a field.
     418       
     419        EXAMPLES::
     420
     421            sage: GroupAlgebra(SymmetricGroup(2)).is_field()
     422            False
     423            sage: GroupAlgebra(SymmetricGroup(1)).is_field()
     424            False
     425            sage: GroupAlgebra(SymmetricGroup(1), QQ).is_field()
     426            True
     427        """
     428        if not self.base_ring().is_field(proof):
     429            return False
     430        return (self.group().order() == 1)
     431
     432    def is_finite(self):
     433        r"""
     434        Return True if self is finite, which is true if and only if
     435        ``self.group()`` and ``self.base_ring()`` are both finite.
     436       
     437        EXAMPLES::
     438
     439            sage: GroupAlgebra(SymmetricGroup(2), IntegerModRing(10)).is_finite()
     440            True
     441            sage: GroupAlgebra(SymmetricGroup(2)).is_finite()
     442            False
     443            sage: GroupAlgebra(AbelianGroup(1), IntegerModRing(10)).is_finite()
     444            False
     445        """
     446        return (self.base_ring().is_finite() and self.group().is_finite())
     447
     448    def is_exact(self):
     449        r"""
     450        Return True if elements of self have exact representations, which is
     451        true of self if and only if it is true of ``self.group()`` and
     452        ``self.base_ring()``.
     453
     454        EXAMPLES::
     455
     456            sage: GroupAlgebra(GL(3, GF(7))).is_exact()
     457            True
     458            sage: GroupAlgebra(GL(3, GF(7)), RR).is_exact()
     459            False
     460            sage: GroupAlgebra(GL(3, pAdicRing(7))).is_exact() # not implemented correctly (not my fault)!
     461            False
     462        """
     463        return self.group().is_exact() and self.base_ring().is_exact()
     464
     465    def is_integral_domain(self, proof = True):
     466        r"""
     467        Return True if self is an integral domain.
     468       
     469        This is false unless ``self.base_ring()`` is an integral domain, and
     470        even then it is false unless ``self.group()`` has no nontrivial
     471        elements of finite order. I don't know if this condition suffices, but
     472        it obviously does if the group is abelian and finitely generated.
     473
     474        EXAMPLES::
     475
     476            sage: GroupAlgebra(SymmetricGroup(2)).is_integral_domain()
     477            False
     478            sage: GroupAlgebra(SymmetricGroup(1)).is_integral_domain()
     479            True
     480            sage: GroupAlgebra(SymmetricGroup(1), IntegerModRing(4)).is_integral_domain()
     481            False
     482            sage: GroupAlgebra(AbelianGroup(1)).is_integral_domain()
     483            True
     484            sage: GroupAlgebra(AbelianGroup(2, [0,2])).is_integral_domain()
     485            False
     486            sage: GroupAlgebra(GL(2, ZZ)).is_integral_domain() # not implemented
     487            False
     488        """
     489        from sage.sets.set import Set
     490        ans = False
     491        try:
     492            if self.base_ring().is_integral_domain():
     493                if self.group().is_finite():
     494                    if self.group().order() > 1:
     495                        ans = False
     496                    else:
     497                        ans = True
     498                else:
     499                    if self.group().is_abelian():
     500                        invs = self.group().invariants()
     501                        if Set(invs) != Set([0]):
     502                            ans = False
     503                        else:
     504                            ans = True
     505                    else:
     506                        raise NotImplementedError
     507            else:
     508                ans = False
     509        except AttributeError:
     510            if proof:
     511                raise NotImplementedError, "cannot determine whether self is an integral domain"
     512        except NotImplementedError:
     513            if proof:
     514                raise NotImplementedError, "cannot determine whether self is an integral domain"
     515       
     516        return ans
     517
     518    # I haven't written is_noetherian(), because I don't know when group
     519    # algebras are noetherian, and I haven't written is_prime_field(), because
     520    # I don't know if that means "is canonically isomorphic to a prime field"
     521    # or "is identical to a prime field".
     522
     523    def __cmp__(self, other) :
     524        r"""
     525        Compare two algebras self and other. They are considered equal if and only
     526        if their base rings and their groups coincide.
     527
     528        EXAMPLES::
     529
     530            sage: GroupAlgebra(AbelianGroup(1)) == GroupAlgebra(AbelianGroup(1))
     531            True
     532            sage: GroupAlgebra(AbelianGroup(1), QQ) == GroupAlgebra(AbelianGroup(1), ZZ)
     533            False
     534            sage: GroupAlgebra(AbelianGroup(2)) == GroupAlgebra(AbelianGroup(1))
     535            False
     536            sage: A = GroupAlgebra(KleinFourGroup(), ZZ)
     537            sage: B = GroupAlgebra(KleinFourGroup(), QQ)
     538            sage: A == B
     539            False
     540            sage: A == A
     541            True
     542        """
     543        c = cmp(type(self), type(other))
     544
     545        if c == 0 :
     546            c = cmp(self._group, other._group)
     547        if c == 0 :
     548            c = cmp(self.base_ring(), other.base_ring())
     549
     550        return c
     551
     552    def random_element(self, n=2):
     553        r"""
     554        Return a 'random' element of self.
     555
     556        INPUT:
     557
     558        - n -- integer (optional, default 2), number of summands
     559
     560        Algorithm: return a sum of n terms, each of which is formed by
     561        multiplying a random element of the base ring by a random
     562        element of the group.
     563
     564        EXAMPLE::
     565
     566            sage: GroupAlgebra(DihedralGroup(6), QQ).random_element()
     567            -97/190*(1,6)(2,5)(3,4)
     568            sage: GroupAlgebra(SU(2, 13), QQ).random_element(1)
     569            1/2*[       8 11*a + 1]
     570            [   a + 6        3]
     571        """
     572        a = self(0)
     573        for i in range(n):
     574            a += self.term(self.group().random_element(),
     575                           self.base_ring().random_element())
     576        return a
     577
     578    def construction(self) :
     579        r"""
     580        EXAMPLES::
     581
     582            sage: A = GroupAlgebra(KleinFourGroup(), QQ)
     583            sage: A.construction()                                       
     584            (GroupAlgebraFunctor, Rational Field)
     585        """
     586        return GroupAlgebraFunctor(self._group), self.base_ring()
     587
     588    def _repr_(self):
     589        r"""
     590        String representation of self. See GroupAlgebra.__init__ for a doctest.
     591
     592        EXAMPLES::
     593
     594            sage: A = GroupAlgebra(KleinFourGroup(), ZZ)
     595            sage: A # indirect doctest
     596            Group algebra of group "The Klein 4 group of order 4, as a permutation group" over base ring Integer Ring
     597        """
     598        return "Group algebra of group \"%s\" over base ring %s" % \
     599               (self.group(), self.base_ring())
     600
     601    def _latex_(self):
     602        r"""Latex string of self.
     603       
     604        EXAMPLES::
     605
     606            sage: A = GroupAlgebra(KleinFourGroup(), ZZ)
     607            sage: latex(A) # indirect doctest
     608            \Bold{Z}[\langle (3,4), (1,2) \rangle]
     609        """
     610        from sage.misc.all import latex
     611        return "%s[%s]" % (latex(self.base_ring()), latex(self.group()))
     612
     613    # coercion methods:
     614
     615    def _coerce_map_from_(self, S):
     616        r"""
     617        True if there is a coercion from ``S`` to ``self``, False otherwise.
     618        The actual coercion is done by the :meth:`_element_constructor_`
     619        method.
     620
     621        INPUT:
     622
     623        -  ``S`` - a Sage object.
     624
     625        The objects that coerce into a group algebra `k[G]` are:
     626
     627        - any group algebra `R[H]` as long as `R` coerces into `k` and
     628          `H` coerces into `G`.
     629
     630        - any ring `R` which coerces into `k`
     631       
     632        - any group `H` which coerces into either `k` or `G`.
     633
     634        Note that if `H` is a group which coerces into both `k` and
     635        `G`, then Sage will always use the map to `k`.  For example,
     636        if `\ZZ` is the ring (or group) of integers, then `\ZZ` will
     637        coerce to any `k[G]`, by sending `\ZZ` to `k`.
     638
     639        EXAMPLES::
     640
     641            sage: A = GroupAlgebra(SymmetricGroup(4), QQ)
     642            sage: B = GroupAlgebra(SymmetricGroup(3), ZZ)
     643            sage: A._coerce_map_from_(B)
     644            True
     645            sage: B._coerce_map_from_(A)
     646            False
     647            sage: A._coerce_map_from_(ZZ)
     648            True
     649            sage: A._coerce_map_from_(CC)
     650            False
     651            sage: A._coerce_map_from_(SymmetricGroup(5))
     652            False
     653            sage: A._coerce_map_from_(SymmetricGroup(2))
     654            True
     655        """
     656        from sage.rings.all import is_Ring
     657        from sage.groups.group import Group
     658        k = self.base_ring()
     659        G = self.group()
     660        if isinstance(S, GroupAlgebra):
     661            return (k.has_coerce_map_from(S.base_ring())
     662                    and G.has_coerce_map_from(S.group()))
     663        if is_Ring(S):
     664            return k.has_coerce_map_from(S)
     665        if isinstance(S,Group):
     666            return k.has_coerce_map_from(S) or G.has_coerce_map_from(S)
     667
     668    def _element_constructor_(self, x):
     669        r"""
     670        Try to turn ``x`` into an element of ``self``.
     671
     672        INPUT:
     673
     674        - ``x`` - an element of some group algebra or of a
     675          ring or of a group
     676
     677        OUTPUT: ``x`` as a member of ``self``.
     678
     679            sage: G = KleinFourGroup()
     680            sage: f = G.gen(0)
     681            sage: ZG = GroupAlgebra(G)
     682            sage: ZG(f)  # indirect doctest
     683            (3,4)
     684            sage: ZG(1) == ZG(G(1))
     685            True
     686            sage: G = AbelianGroup(1)
     687            sage: ZG = GroupAlgebra(G)
     688            sage: f = ZG.group().gen()
     689            sage: ZG(FormalSum([(1,f), (2, f**2)]))
     690            f + 2*f^2
     691            sage: G = GL(2,7)
     692            sage: OG = GroupAlgebra(G, ZZ[sqrt(5)])
     693            sage: OG(2)
     694            2*[1 0]
     695            [0 1]
     696            sage: OG(G(2)) # conversion is not the obvious one
     697            [2 0]
     698            [0 2]
     699            sage: OG(FormalSum([ (1, G(2)), (2, RR(0.77)) ]) )
     700            Traceback (most recent call last):
     701            ...
     702            TypeError: Cannot coerce 0.770000000000000 to a 2-by-2 matrix over Finite Field of size 7
     703
     704            sage: OG(OG.base_ring().gens()[1])
     705            sqrt5*[1 0]
     706            [0 1]
     707        """
     708        from sage.rings.all import is_Ring
     709        from sage.groups.group import Group
     710        from sage.structure.formal_sum import FormalSum
     711        k = self.base_ring()
     712        G = self.group()
     713        S = x.parent()
     714        if isinstance(S, GroupAlgebra):
     715            if self.has_coerce_map_from(S):
     716                # coerce monomials, coerce coefficients, reassemble
     717                d = x.monomial_coefficients()
     718                new_d = {}
     719                for g in d:
     720                    g1 = G(g)
     721                    if g1 in new_d:
     722                        new_d[g1] += k(d[g]) + new_d[g1]
     723                    else:
     724                        new_d[g1] = k(d[g])
     725                return self._from_dict(new_d)
     726        elif is_Ring(S):
     727            # coerce to multiple of identity element
     728            return k(x) * self(1)
     729        elif isinstance(S, Group):
     730            # Check whether group coerces to base_ring first.
     731            if k.has_coerce_map_from(S):
     732                return k(x) * self(1)
     733            if G.has_coerce_map_from(S):
     734                return self.monomial(self.group()(x))
     735        elif isinstance(x, FormalSum) and k.has_coerce_map_from(S.base_ring()):
     736            y = [(G(g), k(coeff)) for coeff,g in x]
     737            return self.sum_of_terms(y)
     738        raise TypeError, "Don't know how to create an element of %s from %s" % \
     739                             (self, x)