Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/algebras/group_algebra.py
4097 views
1
r"""
2
Class for group algebras of arbitrary groups (over a general commutative base
3
ring).
4
5
NOTE:
6
-- It seems to be impossible to make this fit nicely with Sage's coercion
7
model. The problem is that (for example) if G is the additive group (ZZ,+),
8
and R = ZZ[G] is its group ring, then the integer 2 can be coerced into R
9
in two ways -- via G, or via the base ring -- and *the answers are
10
different*. In practice we get around this by preventing elements of G
11
coercing automatically into ZZ[G], which is a shame, but makes more sense
12
than preventing elements of the base ring doing so.
13
14
AUTHOR:
15
-- David Loeffler (2008-08-24): initial version
16
"""
17
18
#*****************************************************************************
19
# Copyright (C) 2008 William Stein <[email protected]>
20
# 2008 David Loeffler <[email protected]>
21
#
22
# Distributed under the terms of the GNU General Public License (GPL)
23
# http://www.gnu.org/licenses/
24
#*****************************************************************************
25
26
27
from sage.categories.all import GroupAlgebras
28
from sage.structure.parent_gens import ParentWithGens
29
from sage.algebras.algebra import Algebra
30
from sage.algebras.algebra_element import AlgebraElement
31
from sage.rings.all import IntegerRing
32
from sage.groups.group import Group
33
from sage.structure.formal_sum import FormalSums, FormalSum
34
from sage.sets.set import Set
35
36
37
from sage.misc.misc import deprecation
38
deprecation("The module group_algebra is deprecated and will be removed in a future version of Sage. Use group_algebra_new instead.")
39
40
41
class GroupAlgebra(Algebra):
42
43
def __init__(self, group, base_ring = IntegerRing()):
44
r""" Create the given group algebra.
45
INPUT:
46
-- (Group) group: a generic group.
47
-- (Ring) base_ring: a commutative ring.
48
OUTPUT:
49
-- a GroupAlgebra instance.
50
51
EXAMPLES::
52
53
sage: from sage.algebras.group_algebra import GroupAlgebra
54
doctest:1: DeprecationWarning:...
55
sage: GroupAlgebra(GL(3, GF(7)))
56
Group algebra of group "General Linear Group of degree 3 over Finite
57
Field of size 7" over base ring Integer Ring
58
sage: GroupAlgebra(1)
59
Traceback (most recent call last):
60
...
61
TypeError: "1" is not a group
62
63
sage: GroupAlgebra(SU(2, GF(4, 'a')), IntegerModRing(12)).category()
64
Category of group algebras over Ring of integers modulo 12
65
66
"""
67
if not base_ring.is_commutative():
68
raise NotImplementedError("Base ring must be commutative")
69
70
if not isinstance(group, Group):
71
raise TypeError('"%s" is not a group' % group)
72
73
ParentWithGens.__init__(self, base_ring, category = GroupAlgebras(base_ring))
74
75
self._formal_sum_module = FormalSums(base_ring)
76
self._group = group
77
78
def group(self):
79
r""" Return the group of this group algebra.
80
EXAMPLES:
81
sage: from sage.algebras.group_algebra import GroupAlgebra
82
sage: GroupAlgebra(GL(3, GF(11))).group()
83
General Linear Group of degree 3 over Finite Field of size 11
84
sage: GroupAlgebra(SymmetricGroup(10)).group()
85
Symmetric group of order 10! as a permutation group
86
"""
87
return self._group
88
89
def is_commutative(self):
90
r""" Return True if self is a commutative ring. True if and only if
91
self.group() is abelian.
92
93
EXAMPLES:
94
sage: from sage.algebras.group_algebra import GroupAlgebra
95
sage: GroupAlgebra(SymmetricGroup(2)).is_commutative()
96
True
97
sage: GroupAlgebra(SymmetricGroup(3)).is_commutative()
98
False
99
"""
100
return self.group().is_abelian()
101
102
def is_field(self, proof = True):
103
r""" Return True if self is a field. This is always false unless
104
self.group() is trivial and self.base_ring() is a field.
105
EXAMPLES:
106
sage: from sage.algebras.group_algebra import GroupAlgebra
107
sage: GroupAlgebra(SymmetricGroup(2)).is_field()
108
False
109
sage: GroupAlgebra(SymmetricGroup(1)).is_field()
110
False
111
sage: GroupAlgebra(SymmetricGroup(1), QQ).is_field()
112
True
113
"""
114
if not self.base_ring().is_field(proof):
115
return False
116
return (self.group().order() == 1)
117
118
def is_finite(self):
119
r""" Return True if self is finite, which is true if and only if
120
self.group() and self.base_ring() are both finite.
121
122
EXAMPLES:
123
sage: from sage.algebras.group_algebra import GroupAlgebra
124
sage: GroupAlgebra(SymmetricGroup(2), IntegerModRing(10)).is_finite()
125
True
126
sage: GroupAlgebra(SymmetricGroup(2)).is_finite()
127
False
128
sage: GroupAlgebra(AbelianGroup(1), IntegerModRing(10)).is_finite()
129
False
130
"""
131
return (self.base_ring().is_finite() and self.group().is_finite())
132
133
def is_exact(self):
134
r""" Return True if elements of self have exact representations,
135
which is true of self if and only if it is true of self.group()
136
and self.base_ring().
137
138
EXAMPLES:
139
sage: from sage.algebras.group_algebra import GroupAlgebra
140
sage: GroupAlgebra(GL(3, GF(7))).is_exact()
141
True
142
sage: GroupAlgebra(GL(3, GF(7)), RR).is_exact()
143
False
144
sage: GroupAlgebra(GL(3, pAdicRing(7))).is_exact() # not implemented correctly (not my fault)!
145
False
146
"""
147
return self.group().is_exact() and self.base_ring().is_exact()
148
149
def is_integral_domain(self, proof = True):
150
r""" Return True if self is an integral domain.
151
152
This is false unless
153
self.base_ring() is an integral domain, and even then it is false unless
154
self.group() has no nontrivial elements of finite order. I don't know if
155
this condition suffices, but it obviously does if the group is abelian and
156
finitely generated.
157
158
EXAMPLES:
159
sage: from sage.algebras.group_algebra import GroupAlgebra
160
sage: GroupAlgebra(SymmetricGroup(2)).is_integral_domain()
161
False
162
sage: GroupAlgebra(SymmetricGroup(1)).is_integral_domain()
163
True
164
sage: GroupAlgebra(SymmetricGroup(1), IntegerModRing(4)).is_integral_domain()
165
False
166
sage: GroupAlgebra(AbelianGroup(1)).is_integral_domain()
167
True
168
sage: GroupAlgebra(AbelianGroup(2, [0,2])).is_integral_domain()
169
False
170
sage: GroupAlgebra(GL(2, ZZ)).is_integral_domain() # not implemented
171
False
172
"""
173
ans = False
174
try:
175
if self.base_ring().is_integral_domain():
176
if self.group().is_finite():
177
if self.group().order() > 1:
178
ans = False
179
else:
180
ans = True
181
else:
182
if self.group().is_abelian():
183
invs = self.group().invariants()
184
if Set(invs) != Set([0]):
185
ans = False
186
else:
187
ans = True
188
else:
189
raise NotImplementedError
190
else:
191
ans = False
192
except AttributeError:
193
if proof:
194
raise NotImplementedError("cannot determine whether self is an integral domain")
195
except NotImplementedError:
196
if proof:
197
raise NotImplementedError("cannot determine whether self is an integral domain")
198
199
return ans
200
201
# I haven't written is_noetherian(), because I don't know when group
202
# algebras are noetherian, and I haven't written is_prime_field(), because
203
# I don't know if that means "is canonically isomorphic to a prime field"
204
# or "is identical to a prime field".
205
206
def _coerce_impl(self, x):
207
return self(self.base_ring().coerce(x))
208
209
def _an_element_impl(self):
210
"""
211
Return an element of self.
212
213
EXAMPLE:
214
sage: from sage.algebras.group_algebra import GroupAlgebra
215
sage: GroupAlgebra(SU(2, 13), QQ).an_element() # random; hideous formatting!
216
-1/95*[ 9 2*a + 12]
217
[ 0 3] - 4*[ 9 9*a + 2]
218
[3*a + 5 1]
219
"""
220
try:
221
return self(self._formal_sum_module([
222
(self.base_ring().random_element(), self.group().random_element()),
223
(self.base_ring().random_element(), self.group().random_element()),
224
]))
225
except: # base ring or group might not implement .random_element()
226
return self(self._formal_sum_module([ (self.base_ring().an_element(), self.group().an_element()) ]))
227
228
def __call__(self, x, check=True):
229
r"""
230
Create an element of this group algebra.
231
232
INPUT:
233
-- x: either a FormalSum element consisting of elements of
234
self.group(), an element of self.base_ring(), or an element
235
of self.group().
236
-- check (boolean): whether or not to check that the given elements
237
really do lie in self.group(). Chiefly provided to speed up
238
arithmetic operations with elements that have already been checked
239
to lie in the group.
240
241
OUTPUT:
242
-- a GroupAlgebraElement instance whose parent is self.
243
244
EXAMPLES:
245
sage: from sage.algebras.group_algebra import GroupAlgebra
246
sage: G = AbelianGroup(1)
247
sage: f = G.gen()
248
sage: ZG = GroupAlgebra(G)
249
sage: ZG(f)
250
f
251
sage: ZG(1) == ZG(G(1))
252
True
253
sage: ZG(FormalSum([(1,f), (2, f**2)]))
254
2*f^2 + f
255
sage: G = GL(2,7)
256
sage: OG = GroupAlgebra(G, ZZ[sqrt(5)])
257
sage: OG(2)
258
2*[1 0]
259
[0 1]
260
sage: OG(G(2)) # conversion is not the obvious one
261
[2 0]
262
[0 2]
263
sage: OG(FormalSum([ (1, G(2)), (2, RR(0.77)) ]) )
264
Traceback (most recent call last):
265
...
266
TypeError: 0.770000000000000 is not an element of group General Linear Group of degree 2 over Finite Field of size 7
267
268
Ordering of elements in output unpredictable as sort order of such wildly
269
dissimilar elements is subject to change between platforms and versions
270
(see trac ticket \#4373).
271
sage: OG(FormalSum([ (1, G(2)), (2, RR(0.77)) ]), check=False) # random
272
[2 0]
273
[0 2] + 2*0.770000000000000
274
sage: OG(OG.base_ring().gens()[1])
275
sqrt5*[1 0]
276
[0 1]
277
"""
278
return GroupAlgebraElement(self, x, check)
279
280
def __eq__(self, other):
281
r""" Test for equality.
282
EXAMPLES:
283
sage: from sage.algebras.group_algebra import GroupAlgebra
284
sage: GroupAlgebra(AbelianGroup(1)) == GroupAlgebra(AbelianGroup(1))
285
True
286
sage: GroupAlgebra(AbelianGroup(1), QQ) == GroupAlgebra(AbelianGroup(1), ZZ)
287
False
288
sage: GroupAlgebra(AbelianGroup(2)) == GroupAlgebra(AbelianGroup(1))
289
False
290
"""
291
if not isinstance(other, GroupAlgebra):
292
return False
293
else:
294
return self.base_ring() == other.base_ring() and self.group() == other.group()
295
296
def _repr_(self):
297
r""" String representation of self. See GroupAlgebra.__init__ for a
298
doctest."""
299
return "Group algebra of group \"%s\" over base ring %s" % (self.group(), self.base_ring())
300
301
def element_class(self):
302
r"""
303
The class of elements of self, which is GroupAlgebraElement.
304
305
EXAMPLES:
306
sage: from sage.algebras.group_algebra import GroupAlgebra
307
sage: GroupAlgebra(SU(2, GF(4,'a'))).element_class()
308
<class 'sage.algebras.group_algebra.GroupAlgebraElement'>
309
"""
310
return GroupAlgebraElement
311
312
313
class GroupAlgebraElement(AlgebraElement):
314
315
def __init__(self, parent, x, check):
316
r""" Create an element of the parent group algebra. Not intended to be
317
called by the user; see GroupAlgebra.__call__ for examples and
318
doctests."""
319
AlgebraElement.__init__(self, parent)
320
321
if not hasattr(x, 'parent'):
322
x = IntegerRing()(x) # occasionally coercion framework tries to pass a Python int
323
324
if isinstance(x, FormalSum):
325
if check:
326
for c,d in x._data:
327
if d.parent() != self.parent().group():
328
raise TypeError("%s is not an element of group %s" % (d, self.parent().group()))
329
self._fs = x
330
else:
331
self._fs = x
332
333
elif self.base_ring().has_coerce_map_from(x.parent()):
334
self._fs = self.parent()._formal_sum_module([ (x, self.parent().group()(1)) ])
335
elif self.parent().group().has_coerce_map_from(x.parent()):
336
self._fs = self.parent()._formal_sum_module([ (1, self.parent().group()(x)) ])
337
else:
338
raise TypeError("Don't know how to create an element of %s from %s" % (self.parent(), x))
339
340
def _repr_(self):
341
return self._fs._repr_()
342
343
def _add_(self, other):
344
r"""
345
Add self to other.
346
347
EXAMPLE:
348
sage: from sage.algebras.group_algebra import GroupAlgebra
349
sage: G = GL(3, GF(7))
350
sage: ZG = GroupAlgebra(G)
351
sage: g1 = G([0,0,2,2,5,0,6,6,2])
352
sage: s = ZG(g1)
353
sage: s + s
354
2*[0 0 2]
355
[2 5 0]
356
[6 6 2]
357
"""
358
fs_sum = self._fs + other._fs
359
return self.parent()(fs_sum, check=False)
360
361
def _mul_(self, right):
362
r""" Calculate self*right, where both self and right are GroupAlgebraElements.
363
364
EXAMPLE:
365
sage: from sage.algebras.group_algebra import GroupAlgebra
366
sage: G = GL(3, GF(7))
367
sage: ZG = GroupAlgebra(G)
368
sage: a, b = G.random_element(), G.random_element()
369
sage: za, zb = ZG(a), ZG(b)
370
sage: za*ZG(2) # random
371
2*[4,5,0]
372
[0,5,1]
373
[2,5,1]
374
sage: za*2 == za*ZG(2)
375
True
376
sage: (ZG(1) + za)*(ZG(2) + zb) == ZG(FormalSum([ (2,G(1)), (2,a), (1, b), (1, a*b)]))
377
True
378
sage: za*za == za^2
379
True
380
"""
381
d1 = self._fs._data
382
d2 = right._fs._data
383
new = []
384
for (a1, g1) in d1:
385
for a2,g2 in d2:
386
if self.parent().group().is_multiplicative():
387
new.append( (a1*a2, g1*g2) )
388
else:
389
new.append( (a1*a2, g1 + g2) )
390
return self.parent()( self.parent()._formal_sum_module(new), check=False)
391
392
def __eq__(self, other):
393
r""" Test if self is equal to other.
394
395
EXAMPLES:
396
sage: from sage.algebras.group_algebra import GroupAlgebra
397
sage: G = AbelianGroup(1,[4])
398
sage: a = GroupAlgebra(G)(1)
399
sage: b = GroupAlgebra(G)(2)
400
sage: a + a == b
401
True
402
sage: a == b
403
False
404
sage: a == GroupAlgebra(AbelianGroup(1, [5]))(1)
405
False
406
"""
407
if isinstance(other, GroupAlgebraElement) and self.parent() == other.parent():
408
return self._fs == other._fs
409
else:
410
return False
411
412