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