Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/algebras/free_algebra_element.py
8818 views
1
"""
2
Free algebra elements
3
4
AUTHORS:
5
6
- David Kohel (2005-09)
7
8
TESTS::
9
10
sage: R.<x,y> = FreeAlgebra(QQ,2)
11
sage: x == loads(dumps(x))
12
True
13
sage: x*y
14
x*y
15
sage: (x*y)^0
16
1
17
sage: (x*y)^3
18
x*y*x*y*x*y
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.misc.misc import repr_lincomb
37
from sage.monoids.free_monoid_element import FreeMonoidElement
38
from sage.algebras.algebra_element import AlgebraElement
39
40
class FreeAlgebraElement(AlgebraElement):
41
"""
42
A free algebra element.
43
"""
44
def __init__(self, A, x):
45
"""
46
Create the element ``x`` of the FreeAlgebra ``A``.
47
48
TESTS::
49
50
sage: F.<x,y,z> = FreeAlgebra(QQ, 3)
51
sage: elt = x^3 * y - z^2*x
52
sage: TestSuite(elt).run()
53
"""
54
if isinstance(x, FreeAlgebraElement):
55
x = x.__monomial_coefficients
56
AlgebraElement.__init__(self, A)
57
R = A.base_ring()
58
if isinstance(x, AlgebraElement): #and x.parent() == A.base_ring():
59
self.__monomial_coefficients = { A.monoid()(1):R(x) }
60
elif isinstance(x, FreeMonoidElement):
61
self.__monomial_coefficients = { x:R(1) }
62
elif True:
63
self.__monomial_coefficients = dict([ (A.monoid()(e1),R(e2)) for e1,e2 in x.items()])
64
else:
65
raise TypeError("Argument x (= %s) is of the wrong type."%x)
66
67
def __iter__(self):
68
"""
69
Returns an iterator which yields tuples of coefficient and monomial.
70
71
EXAMPLES::
72
73
sage: a = FreeAlgebra(QQ, 5, 'a').gens()
74
sage: list(3*a[0]*a[1]*a[4]**3*a[0]+1)
75
[(1, 1), (3, a0*a1*a4^3*a0)]
76
"""
77
for (key,val) in self.__monomial_coefficients.iteritems():
78
yield (val,key)
79
80
def _repr_(self):
81
"""
82
Return string representation of self.
83
84
EXAMPLES::
85
86
sage: A.<x,y,z>=FreeAlgebra(ZZ,3)
87
sage: repr(-x+3*y*z) # indirect doctest
88
'-x + 3*y*z'
89
90
Trac ticket #11068 enables the use of local variable names::
91
92
sage: from sage.structure.parent_gens import localvars
93
sage: with localvars(A, ['a','b','c']):
94
... print -x+3*y*z
95
...
96
-a + 3*b*c
97
98
"""
99
v = sorted(self.__monomial_coefficients.items())
100
P = self.parent()
101
M = P.monoid()
102
from sage.structure.parent_gens import localvars
103
with localvars(M, P.variable_names(), normalize=False):
104
x = repr_lincomb(v, strip_one=True)
105
return x
106
107
def _latex_(self):
108
r"""
109
Return latex representation of self.
110
111
EXAMPLES::
112
113
sage: A.<x,y,z>=FreeAlgebra(ZZ,3)
114
sage: latex(-x+3*y^20*z) # indirect doctest
115
-x + 3y^{20}z
116
sage: alpha,beta,gamma=FreeAlgebra(ZZ,3,'alpha,beta,gamma').gens()
117
sage: latex(alpha-beta)
118
\alpha - \beta
119
"""
120
v = sorted(self.__monomial_coefficients.items())
121
return repr_lincomb(v, strip_one=True, is_latex=True)
122
123
def __call__(self, *x, **kwds):
124
"""
125
EXAMPLES::
126
127
sage: A.<x,y,z>=FreeAlgebra(ZZ,3)
128
sage: (x+3*y).subs(x=1,y=2,z=14)
129
7
130
sage: (2*x+y).subs({x:1,y:z})
131
2 + z
132
sage: f=x+3*y+z
133
sage: f(1,2,1/2)
134
15/2
135
sage: f(1,2)
136
Traceback (most recent call last):
137
...
138
ValueError: must specify as many values as generators in parent
139
140
AUTHORS:
141
142
- Joel B. Mohler (2007-10-27)
143
"""
144
if len(kwds)>0 and len(x)>0:
145
raise ValueError("must not specify both a keyword and positional argument")
146
147
if len(kwds)>0:
148
p = self.parent()
149
def extract_from(kwds,g):
150
for x in g:
151
try:
152
return kwds[x]
153
except KeyError:
154
pass
155
return None
156
157
x = [extract_from(kwds,(p.gen(i),p.variable_name(i))) for i in range(p.ngens())]
158
elif isinstance(x[0],tuple):
159
x = x[0]
160
161
if len(x) != self.parent().ngens():
162
raise ValueError("must specify as many values as generators in parent")
163
164
# I don't start with 0, because I don't want to preclude evaluation with
165
#arbitrary objects (e.g. matrices) because of funny coercion.
166
result = None
167
for m, c in self.__monomial_coefficients.iteritems():
168
if result is None:
169
result = c*m(x)
170
else:
171
result += c*m(x)
172
173
if result is None:
174
return self.parent()(0)
175
return result
176
177
def __cmp__(left, right):
178
"""
179
Compare two free algebra elements with the same parents.
180
181
The ordering is the one on the underlying sorted list of
182
(monomial,coefficients) pairs.
183
184
EXAMPLES::
185
186
sage: R.<x,y> = FreeAlgebra(QQ,2)
187
sage: x < y
188
True
189
sage: x * y < y * x
190
True
191
sage: y * x < x * y
192
False
193
"""
194
v = sorted(left.__monomial_coefficients.items())
195
w = sorted(right.__monomial_coefficients.items())
196
return cmp(v, w)
197
198
def _add_(self, y):
199
"""
200
Return sum of self and y (another free algebra element with the
201
same parents)
202
203
EXAMPLES::
204
205
sage: R.<x,y> = FreeAlgebra(QQ,2)
206
sage: x + y # indirect doctest
207
x + y
208
"""
209
A = self.parent()
210
## if isinstance(y, (int, long, Integer)):
211
## z_elt = dict(self.__monomial_coefficients)
212
## e = A.monoid()(1)
213
## if z_elt.has_key(e):
214
## z_elt[e] += A.base_ring()(y)
215
## else:
216
## z_elt[e] = A.base_ring()(y)
217
## z = A(0)
218
## z.__monomial_coefficients = z_elt
219
## return z
220
## if not isinstance(y, FreeAlgebraElement) or not A == y.parent():
221
## raise TypeError, "Argument y (= %s) is of the wrong type."%y
222
z_elt = dict(self.__monomial_coefficients)
223
for m, c in y.__monomial_coefficients.iteritems():
224
if m in z_elt:
225
cm = z_elt[m] + c
226
if cm == 0:
227
del z_elt[m]
228
else:
229
z_elt[m] = cm
230
else:
231
z_elt[m] = c
232
z = A(0)
233
z.__monomial_coefficients = z_elt
234
return z
235
236
def _neg_(self):
237
"""
238
Return negation of self
239
240
EXAMPLES::
241
242
sage: R.<x,y> = FreeAlgebra(QQ,2)
243
sage: -(x+y) # indirect doctest
244
-x - y
245
"""
246
y = self.parent()(0)
247
y_elt = {}
248
for m, c in self.__monomial_coefficients.iteritems():
249
y_elt[m] = -c
250
y.__monomial_coefficients = y_elt
251
return y
252
253
def _sub_(self, y):
254
"""
255
Return self minus y (another free algebra element with the same
256
parents)
257
258
EXAMPLES::
259
260
sage: R.<x,y> = FreeAlgebra(QQ,2)
261
sage: x - y # indirect doctest
262
x - y
263
"""
264
A = self.parent()
265
## if isinstance(y, (int, long, Integer)):
266
## z_elt = dict(self.__monomial_coefficients)
267
## e = A.monoid()(1)
268
## if z_elt.has_key(e):
269
## z_elt[e] += A.base_ring()(-y)
270
## else:
271
## z_elt[e] = A.base_ring()(-y)
272
## z = A(0)
273
## z.__monomial_coefficients = z_elt
274
## return z
275
## if not isinstance(y, FreeAlgebraElement) or not A == y.parent():
276
## raise TypeError, "Argument y (= %s) is of the wrong type."%y
277
z_elt = dict(self.__monomial_coefficients)
278
for m, c in y.__monomial_coefficients.iteritems():
279
if m in z_elt:
280
cm = z_elt[m] - c
281
if cm == 0:
282
del z_elt[m]
283
else:
284
z_elt[m] = cm
285
else:
286
z_elt[m] = -c
287
z = A(0)
288
z.__monomial_coefficients = z_elt
289
return z
290
291
def _mul_(self, y):
292
"""
293
Return product of self and y (another free algebra element with the
294
same parents)
295
296
EXAMPLES::
297
298
sage: A.<x,y,z>=FreeAlgebra(ZZ,3)
299
sage: (x+y+x*y)*(x+y+1) # indirect doctest
300
x + y + x^2 + 2*x*y + y*x + y^2 + x*y*x + x*y^2
301
"""
302
A = self.parent()
303
z_elt = {}
304
for mx, cx in self.__monomial_coefficients.iteritems():
305
for my, cy in y.__monomial_coefficients.iteritems():
306
key = mx*my
307
if key in z_elt:
308
z_elt[key] += cx*cy
309
else:
310
z_elt[key] = cx*cy
311
z = A(0)
312
z.__monomial_coefficients = z_elt
313
return z
314
315
def to_pbw_basis(self):
316
"""
317
Return ``self`` in the Poincare-Birkhoff-Witt (PBW) basis.
318
319
EXAMPLES::
320
321
sage: F.<x,y,z> = FreeAlgebra(ZZ, 3)
322
sage: p = x^2*y + 3*y*x + 2
323
sage: p.to_pbw_basis()
324
2*PBW[1] + 3*PBW[y]*PBW[x] + PBW[x^2*y] + PBW[x*y]*PBW[x] + PBW[y]*PBW[x]^2
325
"""
326
return self.parent().pbw_element(self)
327
328
329