Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/algebras/free_algebra_quotient_element.py
4129 views
1
"""
2
Free algebra quotient elements
3
4
AUTHORS:
5
- William Stein (2011-11-19): improved doctest coverage to 100%
6
- David Kohel (2005-09): initial version
7
8
"""
9
10
from __future__ import with_statement
11
12
#*****************************************************************************
13
# Copyright (C) 2005 David Kohel <[email protected]>
14
#
15
# Distributed under the terms of the GNU General Public License (GPL)
16
#
17
# This code is distributed in the hope that it will be useful,
18
# but WITHOUT ANY WARRANTY; without even the implied warranty
19
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20
#
21
# See the GNU General Public License for more details; the full text
22
# is available at:
23
#
24
# http://www.gnu.org/licenses/
25
#*****************************************************************************
26
27
from sage.misc.misc import repr_lincomb
28
from sage.rings.ring_element import RingElement
29
from sage.rings.integer import Integer
30
from sage.algebras.algebra_element import AlgebraElement
31
from sage.modules.free_module_element import FreeModuleElement
32
from sage.monoids.free_monoid_element import FreeMonoidElement
33
from sage.algebras.free_algebra_element import FreeAlgebraElement
34
from sage.structure.parent_gens import localvars
35
36
def is_FreeAlgebraQuotientElement(x):
37
"""
38
EXAMPLES::
39
40
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
41
sage: sage.algebras.free_algebra_quotient_element.is_FreeAlgebraQuotientElement(i)
42
True
43
44
Of course this is testing the data type::
45
46
sage: sage.algebras.free_algebra_quotient_element.is_FreeAlgebraQuotientElement(1)
47
False
48
sage: sage.algebras.free_algebra_quotient_element.is_FreeAlgebraQuotientElement(H(1))
49
True
50
"""
51
return isinstance(x, FreeAlgebraQuotientElement)
52
53
class FreeAlgebraQuotientElement(AlgebraElement):
54
def __init__(self, A, x):
55
"""
56
Create the element x of the FreeAlgebraQuotient A.
57
58
EXAMPLES::
59
60
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(ZZ)
61
sage: sage.algebras.free_algebra_quotient.FreeAlgebraQuotientElement(H, i)
62
i
63
sage: a = sage.algebras.free_algebra_quotient.FreeAlgebraQuotientElement(H, 1); a
64
1
65
sage: a in H
66
True
67
68
TESTS::
69
70
sage: TestSuite(i).run()
71
"""
72
AlgebraElement.__init__(self, A)
73
Q = self.parent()
74
75
if isinstance(x, FreeAlgebraQuotientElement) and x.parent() == Q:
76
self.__vector = Q.module()(x.vector())
77
return
78
if isinstance(x, (int, long, Integer)):
79
self.__vector = Q.module().gen(0) * x
80
return
81
elif isinstance(x, FreeModuleElement) and x.parent() is Q.module():
82
self.__vector = x
83
return
84
elif isinstance(x, FreeModuleElement) and x.parent() == A.module():
85
self.__vector = x
86
return
87
R = A.base_ring()
88
M = A.module()
89
F = A.monoid()
90
B = A.monomial_basis()
91
92
if isinstance(x, (int, long, Integer)):
93
self.__vector = x*M.gen(0)
94
elif isinstance(x, RingElement) and not isinstance(x, AlgebraElement) and x in R:
95
self.__vector = x * M.gen(0)
96
elif isinstance(x, FreeMonoidElement) and x.parent() is F:
97
if x in B:
98
self.__vector = M.gen(B.index(x))
99
else:
100
raise AttributeError("Argument x (= %s) is not in monomial basis"%x)
101
elif isinstance(x, list) and len(x) == A.dimension():
102
try:
103
self.__vector = M(x)
104
except TypeError:
105
raise TypeError("Argument x (= %s) is of the wrong type."%x)
106
elif isinstance(x, FreeAlgebraElement) and x.parent() is A.free_algebra():
107
# Need to do more work here to include monomials not
108
# represented in the monomial basis.
109
self.__vector = M(0)
110
for m, c in x._FreeAlgebraElement__monomial_coefficients.iteritems():
111
self.__vector += c*M.gen(B.index(m))
112
elif isinstance(x, dict):
113
self.__vector = M(0)
114
for m, c in x.iteritems():
115
self.__vector += c*M.gen(B.index(m))
116
elif isinstance(x, AlgebraElement) and x.parent().ambient_algebra() is A:
117
self.__vector = x.ambient_algebra_element().vector()
118
else:
119
raise TypeError("Argument x (= %s) is of the wrong type."%x)
120
121
def _repr_(self):
122
"""
123
EXAMPLES::
124
125
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(ZZ)
126
sage: i._repr_()
127
'i'
128
"""
129
Q = self.parent()
130
M = Q.monoid()
131
with localvars(M, Q.variable_names()):
132
cffs = list(self.__vector)
133
mons = Q.monomial_basis()
134
return repr_lincomb(zip(mons, cffs), strip_one=True)
135
136
def _latex_(self):
137
"""
138
EXAMPLES::
139
140
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
141
sage: ((2/3)*i - j)._latex_()
142
'\\frac{2}{3}i + \\left(-1\\right)j'
143
"""
144
Q = self.parent()
145
M = Q.monoid()
146
with localvars(M, Q.variable_names()):
147
cffs = tuple(self.__vector)
148
mons = Q.monomial_basis()
149
return repr_lincomb(zip(mons, cffs), is_latex=True, strip_one=True)
150
151
def vector(self):
152
"""
153
Return underlying vector representation of this element.
154
155
EXAMPLES::
156
157
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
158
sage: ((2/3)*i - j).vector()
159
(0, 2/3, -1, 0)
160
"""
161
return self.__vector
162
163
def __cmp__(self, right):
164
"""
165
Compare two quotient algebra elements; done by comparing the
166
underlying vector representatives.
167
168
EXAMPLES::
169
170
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
171
sage: cmp(i,j)
172
1
173
sage: cmp(j,i)
174
-1
175
sage: cmp(i,i)
176
0
177
sage: i == 1
178
False
179
sage: i + j == j + i
180
True
181
"""
182
return cmp(self.vector(), right.vector())
183
184
def __neg__(self):
185
"""
186
Return negative of self.
187
188
EXAMPLES::
189
190
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
191
sage: -i
192
-i
193
sage: -(2/3*i - 3/7*j + k)
194
-2/3*i + 3/7*j - k
195
"""
196
y = self.parent()(0)
197
y.__vector = -self.__vector
198
return y
199
200
def _add_(self, y):
201
"""
202
EXAMPLES::
203
204
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
205
sage: 2/3*i + 4*j + k
206
2/3*i + 4*j + k
207
"""
208
A = self.parent()
209
z = A(0)
210
z.__vector = self.__vector + y.__vector
211
return z
212
213
def _sub_(self, y):
214
"""
215
EXAMPLES::
216
217
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
218
sage: 2/3*i - 4*j
219
2/3*i - 4*j
220
sage: a = 2/3*i - 4*j; a
221
2/3*i - 4*j
222
sage: a - a
223
0
224
"""
225
A = self.parent()
226
z = A(0)
227
z.__vector = self.__vector - y.__vector
228
return z
229
230
def _mul_(self, y):
231
"""
232
EXAMPLES::
233
234
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
235
sage: a = (5 + 2*i - 3/5*j + 17*k); a*(a+10)
236
-5459/25 + 40*i - 12*j + 340*k
237
238
Double check that the above is actually right::
239
240
sage: R.<i,j,k> = QuaternionAlgebra(QQ,-1,-1)
241
sage: a = (5 + 2*i - 3/5*j + 17*k); a*(a+10)
242
-5459/25 + 40*i - 12*j + 340*k
243
"""
244
A = self.parent()
245
def monomial_product(X,w,m):
246
mats = X._FreeAlgebraQuotient__matrix_action
247
for (j,k) in m._element_list:
248
M = mats[int(j)]
249
for l in range(k): w *= M
250
return w
251
u = self.__vector.__copy__()
252
v = y.__vector
253
z = A(0)
254
B = A.monomial_basis()
255
for i in range(A.dimension()):
256
c = v[i]
257
if c != 0: z.__vector += monomial_product(A,c*u,B[i])
258
return z
259
260
def _rmul_(self, c):
261
"""
262
EXAMPLES::
263
264
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
265
sage: 3 * (-1+i-2*j+k)
266
-3 + 3*i - 6*j + 3*k
267
sage: (-1+i-2*j+k)._rmul_(3)
268
-3 + 3*i - 6*j + 3*k
269
"""
270
return self.parent([c*a for a in self.__vector])
271
272
def _lmul_(self, c):
273
"""
274
EXAMPLES::
275
276
sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
277
sage: (-1+i-2*j+k) * 3
278
-3 + 3*i - 6*j + 3*k
279
sage: (-1+i-2*j+k)._lmul_(3)
280
-3 + 3*i - 6*j + 3*k
281
"""
282
return self.parent([a*c for a in self.__vector])
283
284
285