Path: blob/master/src/sage/algebras/group_algebra_new.py
8818 views
r"""1Group algebras23This module implements group algebras for arbitrary groups over4arbitrary commutative rings.56EXAMPLES::78sage: D4 = DihedralGroup(4)9sage: kD4 = GroupAlgebra(D4, GF(7))10sage: a = kD4.an_element(); a11() + 2*(2,4) + 3*(1,2)(3,4) + (1,2,3,4)12sage: a * a13(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)1415Given the group and the base ring, the corresponding group algebra is unique::1617sage: A = GroupAlgebra(GL(3, QQ), ZZ)18sage: B = GroupAlgebra(GL(3, QQ), ZZ)19sage: A is B20True21sage: C = GroupAlgebra(GL(3, QQ), QQ)22sage: A == C23False2425As long as there is no natural map from the group to the base ring,26you can easily convert elements of the group to the group algebra::2728sage: A = GroupAlgebra(DihedralGroup(2), ZZ)29sage: g = DihedralGroup(2).gen(0); g30(3,4)31sage: A(g)32(3,4)33sage: A(2) * g342*(3,4)3536Since there is a natural inclusion from the dihedral group `D_2` of37order 4 into the symmetric group `S_4` of order 4!, and since there is38a natural map from the integers to the rationals, there is a natural39map from `\ZZ[D_2]` to `\QQ[S_4]`::4041sage: A = GroupAlgebra(DihedralGroup(2), ZZ)42sage: B = GroupAlgebra(SymmetricGroup(4), QQ)43sage: a = A.an_element(); a44() + 3*(3,4) + 3*(1,2)45sage: b = B.an_element(); b46() + 2*(3,4) + 3*(2,3) + (1,2,3,4)47sage: B(a)48() + 3*(3,4) + 3*(1,2)49sage: a * b # a is automatically converted to an element of B507*() + 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)51sage: parent(a * b)52Group algebra of group "Symmetric group of order 4! as a permutation group" over base ring Rational Field5354sage: G = GL(3, GF(7))55sage: ZG = GroupAlgebra(G)56sage: c, d = G.random_element(), G.random_element()57sage: zc, zd = ZG(c), ZG(d)58sage: zc * d == zc * zd # d is automatically converted to an element of ZG59True6061There is no obvious map in the other direction, though::6263sage: A(b)64Traceback (most recent call last):65...66TypeError: 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)6768Group algebras have the structure of Hopf algebras::6970sage: a = kD4.an_element(); a71() + 2*(2,4) + 3*(1,2)(3,4) + (1,2,3,4)72sage: a.antipode()73() + 2*(2,4) + 3*(1,2)(3,4) + (1,4,3,2)74sage: a.coproduct()75() # () + 2*(2,4) # (2,4) + 3*(1,2)(3,4) # (1,2)(3,4) + (1,2,3,4) # (1,2,3,4)7677.. note::7879As alluded to above, it is problematic to make group algebras fit80nicely with Sage's coercion model. The problem is that (for81example) if G is the additive group `(\ZZ,+)`, and `R = \ZZ[G]` is82its group ring, then the integer 2 can be coerced into R in two83ways -- via G, or via the base ring -- and *the answers are84different*. In practice we get around this by preventing elements85of a group `H` from coercing automatically into a group ring86`k[G]` if `H` coerces into both `k` and `G`. This is unfortunate,87but it seems like the most sensible solution in this ambiguous88situation.8990AUTHOR:9192- David Loeffler (2008-08-24): initial version93- Martin Raum (2009-08): update to use new coercion model -- see trac94ticket #667095- John Palmieri (2011-07): more updates to coercion, categories, etc.,96group algebras constructed using CombinatorialFreeModule -- see trac97ticket #667098"""99100#*****************************************************************************101# Copyright (C) 2008 William Stein <[email protected]>102# 2008 David Loeffler <[email protected]>103# 2009 Martin Raum <[email protected]>104# 2011 John Palmieri <[email protected]>105# Distributed under the terms of the GNU General Public License (GPL)106# http://www.gnu.org/licenses/107#*****************************************************************************108109from sage.algebras.algebra import Algebra110from sage.rings.all import IntegerRing111from sage.misc.cachefunc import cached_method112from sage.categories.pushout import ConstructionFunctor113from sage.combinat.free_module import CombinatorialFreeModule114from sage.categories.all import Rings, HopfAlgebrasWithBasis, Hom115from sage.categories.morphism import SetMorphism116117118class GroupAlgebraFunctor (ConstructionFunctor) :119r"""120For a fixed group, a functor sending a commutative ring to the121corresponding group algebra.122123INPUT :124125- ``group`` -- the group associated to each group algebra under126consideration.127128EXAMPLES::129130sage: from sage.algebras.group_algebra_new import GroupAlgebraFunctor131sage: F = GroupAlgebraFunctor(KleinFourGroup())132sage: loads(dumps(F)) == F133True134sage: GroupAlgebra(SU(2, GF(4, 'a')), IntegerModRing(12)).category()135Category of hopf algebras with basis over Ring of integers modulo 12136"""137def __init__(self, group) :138r"""139See :class:`GroupAlgebraFunctor` for full documentation.140141EXAMPLES::142143sage: from sage.algebras.group_algebra_new import GroupAlgebraFunctor144sage: GroupAlgebra(SU(2, GF(4, 'a')), IntegerModRing(12)).category()145Category of hopf algebras with basis over Ring of integers modulo 12146"""147self.__group = group148149ConstructionFunctor.__init__(self, Rings(), Rings())150151def group(self) :152r"""153Return the group which is associated to this functor.154155EXAMPLES::156157sage: from sage.algebras.group_algebra_new import GroupAlgebraFunctor158sage: GroupAlgebraFunctor(CyclicPermutationGroup(17)).group() == CyclicPermutationGroup(17)159True160"""161return self.__group162163def _apply_functor(self, base_ring) :164r"""165Create the group algebra with given base ring over ``self.group()``.166167INPUT :168169- ``base_ring`` - the base ring of the group algebra.170171OUTPUT:172173A group algebra.174175EXAMPLES::176177sage: from sage.algebras.group_algebra_new import GroupAlgebraFunctor178sage: F = GroupAlgebraFunctor(CyclicPermutationGroup(17))179sage: F(QQ)180Group algebra of group "Cyclic group of order 17 as a permutation group" over base ring Rational Field181"""182return GroupAlgebra(self.__group, base_ring)183184def _apply_functor_to_morphism(self, f) :185r"""186Lift a homomorphism of rings to the corresponding homomorphism of the group algebras of ``self.group()``.187188INPUT:189190- ``f`` - a morphism of rings.191192OUTPUT:193194A morphism of group algebras.195196EXAMPLES::197198sage: G = SymmetricGroup(3)199sage: A = GroupAlgebra(G, ZZ)200sage: h = sage.categories.morphism.SetMorphism(Hom(ZZ, GF(5), Rings()), lambda x: GF(5)(x))201sage: hh = A.construction()[0](h)202sage: hh(A.0 + 5 * A.1)203(1,2,3)204"""205codomain = self(f.codomain())206return SetMorphism(Hom(self(f.domain()), codomain, Rings()), lambda x: sum(codomain(g) * f(c) for (g, c) in dict(x).iteritems()))207208class GroupAlgebra(CombinatorialFreeModule, Algebra):209r"""210Create the given group algebra.211212INPUT:213214- ``group``, a group215- ``base_ring`` (optional, default `\ZZ`), a commutative ring216217OUTPUT:218219-- a ``GroupAlgebra`` instance.220221EXAMPLES::222223sage: GroupAlgebra(GL(3, GF(7)))224Group algebra of group "General Linear Group of degree 3 over Finite Field of size 7" over base ring Integer Ring225sage: GroupAlgebra(GL(3, GF(7)), QQ)226Group algebra of group "General Linear Group of degree 3 over Finite Field of size 7" over base ring Rational Field227sage: GroupAlgebra(1)228Traceback (most recent call last):229...230TypeError: "1" is not a group231232sage: GroupAlgebra(SU(2, GF(4, 'a')), IntegerModRing(12)).category()233Category of hopf algebras with basis over Ring of integers modulo 12234sage: GroupAlgebra(KleinFourGroup()) is GroupAlgebra(KleinFourGroup())235True236237TESTS::238239sage: A = GroupAlgebra(GL(3, GF(7)))240sage: A.has_coerce_map_from(GL(3, GF(7)))241True242sage: G = SymmetricGroup(5)243sage: x,y = G.gens()244sage: A = GroupAlgebra(G)245sage: A( A(x) )246(1,2,3,4,5)247"""248def __init__(self, group, base_ring=IntegerRing()):249r"""250See :class:`GroupAlgebra` for full documentation.251252EXAMPLES::253254sage: GroupAlgebra(GL(3, GF(7)))255Group algebra of group "General Linear Group of degree 3 over Finite Field of size 7" over base ring Integer Ring256"""257from sage.groups.group import is_Group258if not base_ring.is_commutative():259raise NotImplementedError("Base ring must be commutative")260261if not is_Group(group):262raise TypeError('"%s" is not a group' % group)263264self._group = group265CombinatorialFreeModule.__init__(self, base_ring, group,266prefix='',267bracket=False,268category=HopfAlgebrasWithBasis(base_ring))269270if not base_ring.has_coerce_map_from(group) :271## some matrix groups assume that coercion is only valid to272## other matrix groups. This is a workaround273## call _element_constructor_ to coerce group elements274#try :275self._populate_coercion_lists_(coerce_list=[base_ring, group])276#except TypeError :277# self._populate_coercion_lists_( coerce_list = [base_ring] )278else :279self._populate_coercion_lists_(coerce_list=[base_ring])280281# Methods taken from sage.categories.examples.hopf_algebras_with_basis:282283@cached_method284def one_basis(self):285"""286Returns the one of the group, which indexes the one of this287algebra, as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`.288289EXAMPLES::290291sage: A = GroupAlgebra(DihedralGroup(6), QQ)292sage: A.one_basis()293()294sage: A.one()295()296"""297return self._group.one()298299def product_on_basis(self, g1, g2):300r"""301Product, on basis elements, as per302:meth:`AlgebrasWithBasis.ParentMethods.product_on_basis`.303304The product of two basis elements is induced by the product of305the corresponding elements of the group.306307EXAMPLES::308309sage: A = GroupAlgebra(DihedralGroup(3), QQ)310sage: (a, b) = A._group.gens()311sage: a*b312(1,2)313sage: A.product_on_basis(a, b)314(1,2)315"""316return self.basis()[g1 * g2]317318@cached_method319def algebra_generators(self):320r"""321The generators of this algebra, as per322:meth:`Algebras.ParentMethods.algebra_generators`.323324They correspond to the generators of the group.325326EXAMPLES::327328sage: A = GroupAlgebra(DihedralGroup(3), QQ); A329Group algebra of group "Dihedral group of order 6 as a permutation group" over base ring Rational Field330sage: A.algebra_generators()331Finite family {(1,2,3): (1,2,3), (1,3): (1,3)}332"""333from sage.sets.family import Family334return Family(self._group.gens(), self.monomial)335336gens = algebra_generators337338def coproduct_on_basis(self, g):339r"""340Coproduct, on basis elements, as per :meth:`HopfAlgebrasWithBasis.ParentMethods.coproduct_on_basis`.341342The basis elements are group-like: `\Delta(g) = g \otimes g`.343344EXAMPLES::345346sage: A = GroupAlgebra(DihedralGroup(3), QQ)347sage: (a, b) = A._group.gens()348sage: A.coproduct_on_basis(a)349(1,2,3) # (1,2,3)350"""351from sage.categories.all import tensor352g = self.monomial(g)353return tensor([g, g])354355def counit_on_basis(self, g):356r"""357Counit, on basis elements, as per :meth:`HopfAlgebrasWithBasis.ParentMethods.counit_on_basis`.358359The counit on the basis elements is 1.360361EXAMPLES::362363sage: A = GroupAlgebra(DihedralGroup(6), QQ)364sage: (a, b) = A._group.gens()365sage: A.counit_on_basis(a)3661367"""368return self.base_ring().one()369370def antipode_on_basis(self, g):371r"""372Antipode, on basis elements, as per :meth:`HopfAlgebrasWithBasis.ParentMethods.antipode_on_basis`.373374It is given, on basis elements, by `\chi(g) = g^{-1}`375376EXAMPLES::377378sage: A = GroupAlgebra(DihedralGroup(3), QQ)379sage: (a, b) = A._group.gens()380sage: A.antipode_on_basis(a)381(1,3,2)382"""383return self.monomial(~g)384385# other methods:386387def ngens(self) :388r"""389Return the number of generators.390391EXAMPLES::392393sage: GroupAlgebra(SL2Z).ngens()3942395sage: GroupAlgebra(DihedralGroup(4), RR).ngens()3962397"""398return self.algebra_generators().cardinality()399400def gen(self, i = 0) :401r"""402EXAMPLES::403404sage: A = GroupAlgebra(GL(3, GF(7)))405sage: A.gen(0)406[3 0 0]407[0 1 0]408[0 0 1]409"""410return self.monomial(self._group.gen(i))411412def group(self):413r"""414Return the group of this group algebra.415416EXAMPLES::417418sage: GroupAlgebra(GL(3, GF(11))).group()419General Linear Group of degree 3 over Finite Field of size 11420sage: GroupAlgebra(SymmetricGroup(10)).group()421Symmetric group of order 10! as a permutation group422"""423return self._group424425def is_commutative(self):426r"""427Return True if self is a commutative ring. True if and only if428``self.group()`` is abelian.429430EXAMPLES::431432sage: GroupAlgebra(SymmetricGroup(2)).is_commutative()433True434sage: GroupAlgebra(SymmetricGroup(3)).is_commutative()435False436"""437return self.group().is_abelian()438439def is_field(self, proof = True):440r"""441Return True if self is a field. This is always false unless442``self.group()`` is trivial and ``self.base_ring()`` is a field.443444EXAMPLES::445446sage: GroupAlgebra(SymmetricGroup(2)).is_field()447False448sage: GroupAlgebra(SymmetricGroup(1)).is_field()449False450sage: GroupAlgebra(SymmetricGroup(1), QQ).is_field()451True452"""453if not self.base_ring().is_field(proof):454return False455return (self.group().order() == 1)456457def is_finite(self):458r"""459Return True if self is finite, which is true if and only if460``self.group()`` and ``self.base_ring()`` are both finite.461462EXAMPLES::463464sage: GroupAlgebra(SymmetricGroup(2), IntegerModRing(10)).is_finite()465True466sage: GroupAlgebra(SymmetricGroup(2)).is_finite()467False468sage: GroupAlgebra(AbelianGroup(1), IntegerModRing(10)).is_finite()469False470"""471return (self.base_ring().is_finite() and self.group().is_finite())472473def is_exact(self):474r"""475Return True if elements of self have exact representations, which is476true of self if and only if it is true of ``self.group()`` and477``self.base_ring()``.478479EXAMPLES::480481sage: GroupAlgebra(GL(3, GF(7))).is_exact()482True483sage: GroupAlgebra(GL(3, GF(7)), RR).is_exact()484False485sage: GroupAlgebra(GL(3, pAdicRing(7))).is_exact() # not implemented correctly (not my fault)!486False487"""488return self.group().is_exact() and self.base_ring().is_exact()489490def is_integral_domain(self, proof = True):491r"""492Return True if self is an integral domain.493494This is false unless ``self.base_ring()`` is an integral domain, and495even then it is false unless ``self.group()`` has no nontrivial496elements of finite order. I don't know if this condition suffices, but497it obviously does if the group is abelian and finitely generated.498499EXAMPLES::500501sage: GroupAlgebra(SymmetricGroup(2)).is_integral_domain()502False503sage: GroupAlgebra(SymmetricGroup(1)).is_integral_domain()504True505sage: GroupAlgebra(SymmetricGroup(1), IntegerModRing(4)).is_integral_domain()506False507sage: GroupAlgebra(AbelianGroup(1)).is_integral_domain()508True509sage: GroupAlgebra(AbelianGroup(2, [0,2])).is_integral_domain()510False511sage: GroupAlgebra(GL(2, ZZ)).is_integral_domain() # not implemented512False513"""514from sage.sets.set import Set515ans = False516try:517if self.base_ring().is_integral_domain():518if self.group().is_finite():519if self.group().order() > 1:520ans = False521else:522ans = True523else:524if self.group().is_abelian():525invs = self.group().invariants()526if Set(invs) != Set([0]):527ans = False528else:529ans = True530else:531raise NotImplementedError532else:533ans = False534except AttributeError:535if proof:536raise NotImplementedError("cannot determine whether self is an integral domain")537except NotImplementedError:538if proof:539raise NotImplementedError("cannot determine whether self is an integral domain")540541return ans542543# I haven't written is_noetherian(), because I don't know when group544# algebras are noetherian, and I haven't written is_prime_field(), because545# I don't know if that means "is canonically isomorphic to a prime field"546# or "is identical to a prime field".547548def __cmp__(self, other) :549r"""550Compare two algebras self and other. They are considered equal if and only551if their base rings and their groups coincide.552553EXAMPLES::554555sage: GroupAlgebra(AbelianGroup(1)) == GroupAlgebra(AbelianGroup(1))556True557sage: GroupAlgebra(AbelianGroup(1), QQ) == GroupAlgebra(AbelianGroup(1), ZZ)558False559sage: GroupAlgebra(AbelianGroup(2)) == GroupAlgebra(AbelianGroup(1))560False561sage: A = GroupAlgebra(KleinFourGroup(), ZZ)562sage: B = GroupAlgebra(KleinFourGroup(), QQ)563sage: A == B564False565sage: A == A566True567"""568c = cmp(type(self), type(other))569570if c == 0 :571c = cmp(self._group, other._group)572if c == 0 :573c = cmp(self.base_ring(), other.base_ring())574575return c576577def random_element(self, n=2):578r"""579Return a 'random' element of self.580581INPUT:582583- n -- integer (optional, default 2), number of summands584585Algorithm: return a sum of n terms, each of which is formed by586multiplying a random element of the base ring by a random587element of the group.588589EXAMPLE::590591sage: GroupAlgebra(DihedralGroup(6), QQ).random_element()592-1/95*(2,6)(3,5) - 1/2*(1,3)(4,6)593sage: GroupAlgebra(SU(2, 13), QQ).random_element(1)5941/2*[ 11 a + 6]595[2*a + 12 11]596"""597a = self(0)598for i in range(n):599a += self.term(self.group().random_element(),600self.base_ring().random_element())601return a602603def construction(self) :604r"""605EXAMPLES::606607sage: A = GroupAlgebra(KleinFourGroup(), QQ)608sage: A.construction()609(GroupAlgebraFunctor, Rational Field)610"""611return GroupAlgebraFunctor(self._group), self.base_ring()612613def _repr_(self):614r"""615String representation of self. See GroupAlgebra.__init__ for a doctest.616617EXAMPLES::618619sage: A = GroupAlgebra(KleinFourGroup(), ZZ)620sage: A # indirect doctest621Group algebra of group "The Klein 4 group of order 4, as a permutation group" over base ring Integer Ring622"""623return "Group algebra of group \"%s\" over base ring %s" % \624(self.group(), self.base_ring())625626def _latex_(self):627r"""Latex string of self.628629EXAMPLES::630631sage: A = GroupAlgebra(KleinFourGroup(), ZZ)632sage: latex(A) # indirect doctest633\Bold{Z}[\langle (3,4), (1,2) \rangle]634"""635from sage.misc.all import latex636return "%s[%s]" % (latex(self.base_ring()), latex(self.group()))637638# coercion methods:639640def _coerce_map_from_(self, S):641r"""642True if there is a coercion from ``S`` to ``self``, False otherwise.643The actual coercion is done by the :meth:`_element_constructor_`644method.645646INPUT:647648- ``S`` - a Sage object.649650The objects that coerce into a group algebra `k[G]` are:651652- any group algebra `R[H]` as long as `R` coerces into `k` and653`H` coerces into `G`.654655- any ring `R` which coerces into `k`656657- any group `H` which coerces into either `k` or `G`.658659Note that if `H` is a group which coerces into both `k` and660`G`, then Sage will always use the map to `k`. For example,661if `\ZZ` is the ring (or group) of integers, then `\ZZ` will662coerce to any `k[G]`, by sending `\ZZ` to `k`.663664EXAMPLES::665666sage: A = GroupAlgebra(SymmetricGroup(4), QQ)667sage: B = GroupAlgebra(SymmetricGroup(3), ZZ)668sage: A._coerce_map_from_(B)669True670sage: B._coerce_map_from_(A)671False672sage: A._coerce_map_from_(ZZ)673True674sage: A._coerce_map_from_(CC)675False676sage: A._coerce_map_from_(SymmetricGroup(5))677False678sage: A._coerce_map_from_(SymmetricGroup(2))679True680"""681from sage.rings.ring import is_Ring682from sage.groups.old import Group683k = self.base_ring()684G = self.group()685if isinstance(S, GroupAlgebra):686return (k.has_coerce_map_from(S.base_ring())687and G.has_coerce_map_from(S.group()))688if is_Ring(S):689return k.has_coerce_map_from(S)690if isinstance(S,Group):691return k.has_coerce_map_from(S) or G.has_coerce_map_from(S)692693def _element_constructor_(self, x):694r"""695Try to turn ``x`` into an element of ``self``.696697INPUT:698699- ``x`` - an element of some group algebra or of a700ring or of a group701702OUTPUT: ``x`` as a member of ``self``.703704sage: G = KleinFourGroup()705sage: f = G.gen(0)706sage: ZG = GroupAlgebra(G)707sage: ZG(f) # indirect doctest708(3,4)709sage: ZG(1) == ZG(G(1))710True711sage: G = AbelianGroup(1)712sage: ZG = GroupAlgebra(G)713sage: f = ZG.group().gen()714sage: ZG(FormalSum([(1,f), (2, f**2)]))715f + 2*f^2716sage: G = GL(2,7)717sage: OG = GroupAlgebra(G, ZZ[sqrt(5)])718sage: OG(2)7192*[1 0]720[0 1]721sage: OG(G(2)) # conversion is not the obvious one722[2 0]723[0 2]724sage: OG(FormalSum([ (1, G(2)), (2, RR(0.77)) ]) )725Traceback (most recent call last):726...727TypeError: Attempt to coerce non-integral RealNumber to Integer728sage: OG(OG.base_ring().gens()[1])729sqrt5*[1 0]730[0 1]731"""732from sage.rings.ring import is_Ring733from sage.groups.group import is_Group734from sage.structure.formal_sum import FormalSum735k = self.base_ring()736G = self.group()737S = x.parent()738if isinstance(S, GroupAlgebra):739if self.has_coerce_map_from(S):740# coerce monomials, coerce coefficients, reassemble741d = x.monomial_coefficients()742new_d = {}743for g in d:744g1 = G(g)745if g1 in new_d:746new_d[g1] += k(d[g]) + new_d[g1]747else:748new_d[g1] = k(d[g])749return self._from_dict(new_d)750elif is_Ring(S):751# coerce to multiple of identity element752return k(x) * self(1)753elif is_Group(S):754# Check whether group coerces to base_ring first.755if k.has_coerce_map_from(S):756return k(x) * self(1)757if G.has_coerce_map_from(S):758return self.monomial(self.group()(x))759elif isinstance(x, FormalSum) and k.has_coerce_map_from(S.base_ring()):760y = [(G(g), k(coeff)) for coeff,g in x]761return self.sum_of_terms(y)762raise TypeError("Don't know how to create an element of %s from %s" % \763(self, x))764765766