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