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