Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/algebras/free_algebra_quotient.py
4146 views
1
"""
2
Free algebra quotients
3
4
TESTS::
5
6
sage: n = 2
7
sage: A = FreeAlgebra(QQ,n,'x')
8
sage: F = A.monoid()
9
sage: i, j = F.gens()
10
sage: mons = [ F(1), i, j, i*j ]
11
sage: r = len(mons)
12
sage: M = MatrixSpace(QQ,r)
13
sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]) ]
14
sage: H2.<i,j> = A.quotient(mons,mats)
15
sage: H2 == loads(dumps(H2))
16
True
17
sage: i == loads(dumps(i))
18
True
19
"""
20
21
#*****************************************************************************
22
# Copyright (C) 2005 David Kohel <[email protected]>
23
#
24
# Distributed under the terms of the GNU General Public License (GPL)
25
#
26
# This code is distributed in the hope that it will be useful,
27
# but WITHOUT ANY WARRANTY; without even the implied warranty
28
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
29
#
30
# See the GNU General Public License for more details; the full text
31
# is available at:
32
#
33
# http://www.gnu.org/licenses/
34
#*****************************************************************************
35
36
from sage.modules.free_module import FreeModule
37
from sage.algebras.algebra import Algebra
38
from sage.algebras.free_algebra import is_FreeAlgebra
39
from sage.algebras.free_algebra_quotient_element import FreeAlgebraQuotientElement
40
from sage.structure.parent_gens import ParentWithGens
41
from sage.structure.unique_representation import UniqueRepresentation
42
43
class FreeAlgebraQuotient(UniqueRepresentation, Algebra, object):
44
@staticmethod
45
def __classcall__(cls, A, mons, mats, names):
46
"""
47
Used to support unique representation.
48
49
EXAMPLES::
50
51
sage: H = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0] # indirect doctest
52
sage: H1 = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0]
53
sage: H is H1
54
True
55
"""
56
new_mats = []
57
for M in mats:
58
M = M.parent()(M)
59
M.set_immutable()
60
new_mats.append(M)
61
return super(FreeAlgebraQuotient, cls).__classcall__(cls, A, tuple(mons),
62
tuple(new_mats), tuple(names))
63
64
Element = FreeAlgebraQuotientElement
65
def __init__(self, A, mons, mats, names):
66
"""
67
Returns a quotient algebra defined via the action of a free algebra
68
A on a (finitely generated) free module. The input for the quotient
69
algebra is a list of monomials (in the underlying monoid for A)
70
which form a free basis for the module of A, and a list of
71
matrices, which give the action of the free generators of A on this
72
monomial basis.
73
74
EXAMPLES:
75
76
Quaternion algebra defined in terms of three generators::
77
78
sage: n = 3
79
sage: A = FreeAlgebra(QQ,n,'i')
80
sage: F = A.monoid()
81
sage: i, j, k = F.gens()
82
sage: mons = [ F(1), i, j, k ]
83
sage: M = MatrixSpace(QQ,4)
84
sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]), M([0,0,0,1, 0,0,-1,0, 0,1,0,0, -1,0,0,0]) ]
85
sage: H3.<i,j,k> = FreeAlgebraQuotient(A,mons,mats)
86
sage: x = 1 + i + j + k
87
sage: x
88
1 + i + j + k
89
sage: x**128
90
-170141183460469231731687303715884105728 + 170141183460469231731687303715884105728*i + 170141183460469231731687303715884105728*j + 170141183460469231731687303715884105728*k
91
92
Same algebra defined in terms of two generators, with some penalty
93
on already slow arithmetic.
94
95
::
96
97
sage: n = 2
98
sage: A = FreeAlgebra(QQ,n,'x')
99
sage: F = A.monoid()
100
sage: i, j = F.gens()
101
sage: mons = [ F(1), i, j, i*j ]
102
sage: r = len(mons)
103
sage: M = MatrixSpace(QQ,r)
104
sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]) ]
105
sage: H2.<i,j> = A.quotient(mons,mats)
106
sage: k = i*j
107
sage: x = 1 + i + j + k
108
sage: x
109
1 + i + j + i*j
110
sage: x**128
111
-170141183460469231731687303715884105728 + 170141183460469231731687303715884105728*i + 170141183460469231731687303715884105728*j + 170141183460469231731687303715884105728*i*j
112
113
TEST::
114
115
sage: TestSuite(H2).run()
116
117
"""
118
if not is_FreeAlgebra(A):
119
raise TypeError("Argument A must be an algebra.")
120
R = A.base_ring()
121
# if not R.is_field(): # TODO: why?
122
# raise TypeError, "Base ring of argument A must be a field."
123
n = A.ngens()
124
assert n == len(mats)
125
self.__free_algebra = A
126
self.__ngens = n
127
self.__dim = len(mons)
128
self.__module = FreeModule(R,self.__dim)
129
self.__matrix_action = mats
130
self.__monomial_basis = mons # elements of free monoid
131
Algebra.__init__(self, R, names, normalize=True)
132
133
def __eq__(self, right):
134
"""
135
Return True if all defining properties of self and right match up.
136
137
EXAMPLES::
138
139
sage: HQ = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0]
140
sage: HZ = sage.algebras.free_algebra_quotient.hamilton_quatalg(ZZ)[0]
141
sage: HQ == HQ
142
True
143
sage: HQ == HZ
144
False
145
sage: HZ == QQ
146
False
147
"""
148
return isinstance(right, FreeAlgebraQuotient) and \
149
self.ngens() == right.ngens() and \
150
self.rank() == right.rank() and \
151
self.module() == right.module() and \
152
self.matrix_action() == right.matrix_action() and \
153
self.monomial_basis() == right.monomial_basis()
154
155
156
def _element_constructor_(self, x):
157
"""
158
EXAMPLES::
159
160
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
161
sage: H._element_constructor_(i) is i
162
True
163
sage: a = H._element_constructor_(1); a
164
1
165
sage: a in H
166
True
167
sage: a = H._element_constructor_([1,2,3,4]); a
168
1 + 2*i + 3*j + 4*k
169
"""
170
if isinstance(x, FreeAlgebraQuotientElement) and x.parent() is self:
171
return x
172
return self.element_class(self,x)
173
174
def _coerce_map_from_(self,S):
175
"""
176
EXAMPLES::
177
178
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
179
sage: H._coerce_map_from_(H)
180
True
181
sage: H._coerce_map_from_(QQ)
182
True
183
sage: H._coerce_map_from_(GF(7))
184
False
185
"""
186
return S==self or self.__free_algebra.has_coerce_map_from(S)
187
188
def _repr_(self):
189
"""
190
EXAMPLES::
191
192
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
193
sage: H._repr_()
194
"Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Rational Field"
195
"""
196
R = self.base_ring()
197
n = self.__ngens
198
r = self.__module.dimension()
199
x = self.variable_names()
200
return "Free algebra quotient on %s generators %s and dimension %s over %s"%(n,x,r,R)
201
202
def gen(self, i):
203
"""
204
The i-th generator of the algebra.
205
206
EXAMPLES::
207
208
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
209
sage: H.gen(0)
210
i
211
sage: H.gen(2)
212
k
213
214
An IndexError is raised if an invalid generator is requested::
215
216
sage: H.gen(3)
217
Traceback (most recent call last):
218
...
219
IndexError: Argument i (= 3) must be between 0 and 2.
220
221
Negative indexing into the generators is not supported::
222
223
sage: H.gen(-1)
224
Traceback (most recent call last):
225
...
226
IndexError: Argument i (= -1) must be between 0 and 2.
227
"""
228
n = self.__ngens
229
if i < 0 or not i < n:
230
raise IndexError("Argument i (= %s) must be between 0 and %s."%(i, n-1))
231
R = self.base_ring()
232
F = self.__free_algebra.monoid()
233
n = self.__ngens
234
return self.element_class(self,{F.gen(i):R(1)})
235
236
def ngens(self):
237
"""
238
The number of generators of the algebra.
239
240
EXAMPLES::
241
242
sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].ngens()
243
3
244
"""
245
return self.__ngens
246
247
def dimension(self):
248
"""
249
The rank of the algebra (as a free module).
250
251
EXAMPLES::
252
253
sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].dimension()
254
4
255
"""
256
return self.__dim
257
258
def matrix_action(self):
259
"""
260
EXAMPLES::
261
262
sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].matrix_action()
263
(
264
[ 0 1 0 0] [ 0 0 1 0] [ 0 0 0 1]
265
[-1 0 0 0] [ 0 0 0 1] [ 0 0 -1 0]
266
[ 0 0 0 -1] [-1 0 0 0] [ 0 1 0 0]
267
[ 0 0 1 0], [ 0 -1 0 0], [-1 0 0 0]
268
)
269
"""
270
return self.__matrix_action
271
272
def monomial_basis(self):
273
"""
274
EXAMPLES::
275
276
sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].monomial_basis()
277
(1, i0, i1, i2)
278
"""
279
return self.__monomial_basis
280
281
def rank(self):
282
"""
283
The rank of the algebra (as a free module).
284
285
EXAMPLES::
286
287
sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].rank()
288
4
289
"""
290
return self.__dim
291
292
def module(self):
293
"""
294
The free module of the algebra.
295
296
sage: H = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0]; H
297
Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Rational Field
298
sage: H.module()
299
Vector space of dimension 4 over Rational Field
300
"""
301
return self.__module
302
303
def monoid(self):
304
"""
305
The free monoid of generators of the algebra.
306
307
EXAMPLES::
308
309
sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].monoid()
310
Free monoid on 3 generators (i0, i1, i2)
311
"""
312
return self.__free_algebra.monoid()
313
314
def monomial_basis(self):
315
"""
316
The free monoid of generators of the algebra as elements of a free
317
monoid.
318
319
EXAMPLES::
320
321
sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].monomial_basis()
322
(1, i0, i1, i2)
323
"""
324
return self.__monomial_basis
325
326
def free_algebra(self):
327
"""
328
The free algebra generating the algebra.
329
330
EXAMPLES::
331
332
sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].free_algebra()
333
Free Algebra on 3 generators (i0, i1, i2) over Rational Field
334
"""
335
return self.__free_algebra
336
337
338
def hamilton_quatalg(R):
339
"""
340
Hamilton quaternion algebra over the commutative ring R,
341
constructed as a free algebra quotient.
342
343
INPUT:
344
- R -- a commutative ring
345
346
OUTPUT:
347
- Q -- quaternion algebra
348
- gens -- generators for Q
349
350
EXAMPLES::
351
352
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(ZZ)
353
sage: H
354
Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Integer Ring
355
sage: i^2
356
-1
357
sage: i in H
358
True
359
360
Note that there is another vastly more efficient models for
361
quaternion algebras in Sage; the one here is mainly for testing
362
purposes::
363
364
sage: R.<i,j,k> = QuaternionAlgebra(QQ,-1,-1) # much fast than the above
365
"""
366
n = 3
367
from sage.algebras.free_algebra import FreeAlgebra
368
from sage.matrix.all import MatrixSpace
369
A = FreeAlgebra(R, n, 'i')
370
F = A.monoid()
371
i, j, k = F.gens()
372
mons = [ F(1), i, j, k ]
373
M = MatrixSpace(R,4)
374
mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]), M([0,0,0,1, 0,0,-1,0, 0,1,0,0, -1,0,0,0]) ]
375
H3 = FreeAlgebraQuotient(A,mons,mats, names=('i','j','k'))
376
return H3, H3.gens()
377
378
379