Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/algebras/letterplace/letterplace_ideal.pyx
8822 views
1
###############################################################################
2
#
3
# Copyright (C) 2011 Simon King <[email protected]>
4
# Distributed under the terms of the GNU General Public License (GPL),
5
# version 2 or any later version. The full text of the GPL is available at:
6
# http://www.gnu.org/licenses/
7
#
8
###############################################################################
9
10
"""
11
Homogeneous ideals of free algebras.
12
13
For twosided ideals and when the base ring is a field, this
14
implementation also provides Groebner bases and ideal containment
15
tests.
16
17
EXAMPLES::
18
19
sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace')
20
sage: F
21
Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
22
sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F
23
sage: I
24
Twosided Ideal (x*y + y*z, x*x + x*y - y*x - y*y) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
25
26
One can compute Groebner bases out to a finite degree, can compute normal
27
forms and can test containment in the ideal::
28
29
sage: I.groebner_basis(degbound=3)
30
Twosided Ideal (y*y*y - y*y*z + y*z*y - y*z*z, y*y*x + y*y*z + y*z*x + y*z*z, x*y + y*z, x*x - y*x - y*y - y*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
31
sage: (x*y*z*y*x).normal_form(I)
32
y*z*z*y*z + y*z*z*z*x + y*z*z*z*z
33
sage: x*y*z*y*x - (x*y*z*y*x).normal_form(I) in I
34
True
35
36
AUTHOR:
37
38
- Simon King (2011-03-22): See :trac:`7797`.
39
40
"""
41
42
from sage.rings.noncommutative_ideals import Ideal_nc
43
from sage.libs.singular.function import lib, singular_function
44
from sage.algebras.letterplace.free_algebra_letterplace cimport FreeAlgebra_letterplace
45
from sage.algebras.letterplace.free_algebra_element_letterplace cimport FreeAlgebraElement_letterplace
46
from sage.all import Infinity
47
48
#####################
49
# Define some singular functions
50
lib("freegb.lib")
51
singular_system=singular_function("system")
52
poly_reduce=singular_function("NF")
53
54
class LetterplaceIdeal(Ideal_nc):
55
"""
56
Graded homogeneous ideals in free algebras.
57
58
In the two-sided case over a field, one can compute Groebner bases
59
up to a degree bound, normal forms of graded homogeneous elements
60
of the free algebra, and ideal containment.
61
62
EXAMPLES::
63
64
sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace')
65
sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F
66
sage: I
67
Twosided Ideal (x*y + y*z, x*x + x*y - y*x - y*y) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
68
sage: I.groebner_basis(2)
69
Twosided Ideal (x*y + y*z, x*x - y*x - y*y - y*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
70
sage: I.groebner_basis(4)
71
Twosided Ideal (y*z*y*y - y*z*y*z + y*z*z*y - y*z*z*z, y*z*y*x + y*z*y*z + y*z*z*x + y*z*z*z, y*y*z*y - y*y*z*z + y*z*z*y - y*z*z*z, y*y*z*x + y*y*z*z + y*z*z*x + y*z*z*z, y*y*y - y*y*z + y*z*y - y*z*z, y*y*x + y*y*z + y*z*x + y*z*z, x*y + y*z, x*x - y*x - y*y - y*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
72
73
Groebner bases are cached. If one has computed a Groebner basis
74
out to a high degree then it will also be returned if a Groebner
75
basis with a lower degree bound is requested::
76
77
sage: I.groebner_basis(2)
78
Twosided Ideal (y*z*y*y - y*z*y*z + y*z*z*y - y*z*z*z, y*z*y*x + y*z*y*z + y*z*z*x + y*z*z*z, y*y*z*y - y*y*z*z + y*z*z*y - y*z*z*z, y*y*z*x + y*y*z*z + y*z*z*x + y*z*z*z, y*y*y - y*y*z + y*z*y - y*z*z, y*y*x + y*y*z + y*z*x + y*z*z, x*y + y*z, x*x - y*x - y*y - y*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
79
80
Of course, the normal form of any element has to satisfy the following::
81
82
sage: x*y*z*y*x - (x*y*z*y*x).normal_form(I) in I
83
True
84
85
Left and right ideals can be constructed, but only twosided ideals provide
86
Groebner bases::
87
88
sage: JL = F*[x*y+y*z,x^2+x*y-y*x-y^2]; JL
89
Left Ideal (x*y + y*z, x*x + x*y - y*x - y*y) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
90
sage: JR = [x*y+y*z,x^2+x*y-y*x-y^2]*F; JR
91
Right Ideal (x*y + y*z, x*x + x*y - y*x - y*y) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
92
sage: JR.groebner_basis(2)
93
Traceback (most recent call last):
94
...
95
TypeError: This ideal is not two-sided. We can only compute two-sided Groebner bases
96
sage: JL.groebner_basis(2)
97
Traceback (most recent call last):
98
...
99
TypeError: This ideal is not two-sided. We can only compute two-sided Groebner bases
100
101
Also, it is currently not possible to compute a Groebner basis when the base
102
ring is not a field::
103
104
sage: FZ.<a,b,c> = FreeAlgebra(ZZ, implementation='letterplace')
105
sage: J = FZ*[a^3-b^3]*FZ
106
sage: J.groebner_basis(2)
107
Traceback (most recent call last):
108
...
109
TypeError: Currently, we can only compute Groebner bases if the ring of coefficients is a field
110
111
The letterplace implementation of free algebras also provides integral degree weights
112
for the generators, and we can compute Groebner bases for twosided graded homogeneous
113
ideals::
114
115
sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace',degrees=[1,2,3])
116
sage: I = F*[x*y+z-y*x,x*y*z-x^6+y^3]*F
117
sage: I.groebner_basis(Infinity)
118
Twosided Ideal (x*z*z - y*x*x*z - y*x*y*y + y*x*z*x + y*y*y*x + z*x*z + z*y*y - z*z*x,
119
x*y - y*x + z,
120
x*x*x*x*z*y*y + x*x*x*z*y*y*x - x*x*x*z*y*z - x*x*z*y*x*z + x*x*z*y*y*x*x +
121
x*x*z*y*y*y - x*x*z*y*z*x - x*z*y*x*x*z - x*z*y*x*z*x +
122
x*z*y*y*x*x*x + 2*x*z*y*y*y*x - 2*x*z*y*y*z - x*z*y*z*x*x -
123
x*z*y*z*y + y*x*z*x*x*x*x*x - 4*y*x*z*x*x*z - 4*y*x*z*x*z*x +
124
4*y*x*z*y*x*x*x + 3*y*x*z*y*y*x - 4*y*x*z*y*z + y*y*x*x*x*x*z +
125
y*y*x*x*x*z*x - 3*y*y*x*x*z*x*x - y*y*x*x*z*y +
126
5*y*y*x*z*x*x*x + 4*y*y*x*z*y*x - 4*y*y*y*x*x*z +
127
4*y*y*y*x*z*x + 3*y*y*y*y*z + 4*y*y*y*z*x*x + 6*y*y*y*z*y +
128
y*y*z*x*x*x*x + y*y*z*x*z + 7*y*y*z*y*x*x + 7*y*y*z*y*y -
129
7*y*y*z*z*x - y*z*x*x*x*z - y*z*x*x*z*x + 3*y*z*x*z*x*x +
130
y*z*x*z*y + y*z*y*x*x*x*x - 3*y*z*y*x*z + 7*y*z*y*y*x*x +
131
3*y*z*y*y*y - 3*y*z*y*z*x - 5*y*z*z*x*x*x - 4*y*z*z*y*x +
132
4*y*z*z*z - z*y*x*x*x*z - z*y*x*x*z*x - z*y*x*z*x*x -
133
z*y*x*z*y + z*y*y*x*x*x*x - 3*z*y*y*x*z + 3*z*y*y*y*x*x +
134
z*y*y*y*y - 3*z*y*y*z*x - z*y*z*x*x*x - 2*z*y*z*y*x +
135
2*z*y*z*z - z*z*x*x*x*x*x + 4*z*z*x*x*z + 4*z*z*x*z*x -
136
4*z*z*y*x*x*x - 3*z*z*y*y*x + 4*z*z*y*z + 4*z*z*z*x*x +
137
2*z*z*z*y,
138
x*x*x*x*x*z + x*x*x*x*z*x + x*x*x*z*x*x + x*x*z*x*x*x + x*z*x*x*x*x +
139
y*x*z*y - y*y*x*z + y*z*z + z*x*x*x*x*x - z*z*y,
140
x*x*x*x*x*x - y*x*z - y*y*y + z*z)
141
of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
142
143
Again, we can compute normal forms::
144
145
sage: (z*I.0-I.1).normal_form(I)
146
0
147
sage: (z*I.0-x*y*z).normal_form(I)
148
-y*x*z + z*z
149
150
"""
151
def __init__(self, ring, gens, coerce=True, side = "twosided"):
152
"""
153
INPUT:
154
155
- ``ring``: A free algebra in letterplace implementation.
156
- ``gens``: List, tuple or sequence of generators.
157
- ``coerce`` (optional bool, default ``True``):
158
Shall ``gens`` be coerced first?
159
- ``side``: optional string, one of ``"twosided"`` (default),
160
``"left"`` or ``"right"``. Determines whether the ideal
161
is a left, right or twosided ideal. Groebner bases or
162
only supported in the twosided case.
163
164
TEST::
165
166
sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace')
167
sage: from sage.algebras.letterplace.letterplace_ideal import LetterplaceIdeal
168
sage: LetterplaceIdeal(F,x)
169
Twosided Ideal (x) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
170
sage: LetterplaceIdeal(F,[x,y],side='left')
171
Left Ideal (x, y) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
172
173
It is not correctly detected that this class inherits from an
174
extension class. Therefore, we have to skip one item of the
175
test suite::
176
177
sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F
178
sage: TestSuite(I).run(skip=['_test_category'],verbose=True)
179
running ._test_eq() . . . pass
180
running ._test_not_implemented_methods() . . . pass
181
running ._test_pickling() . . . pass
182
183
"""
184
Ideal_nc.__init__(self, ring, gens, coerce=coerce, side=side)
185
self.__GB = self
186
self.__uptodeg = 0
187
def groebner_basis(self, degbound=None):
188
"""
189
Twosided Groebner basis with degree bound.
190
191
INPUT:
192
193
- ``degbound`` (optional integer, or Infinity): If it is provided,
194
a Groebner basis at least out to that degree is returned. By
195
default, the current degree bound of the underlying ring is used.
196
197
ASSUMPTIONS:
198
199
Currently, we can only compute Groebner bases for twosided
200
ideals, and the ring of coefficients must be a field. A
201
`TypeError` is raised if one of these conditions is violated.
202
203
NOTES:
204
205
- The result is cached. The same Groebner basis is returned
206
if a smaller degree bound than the known one is requested.
207
- If the degree bound Infinity is requested, it is attempted to
208
compute a complete Groebner basis. But we can not guarantee
209
that the computation will terminate, since not all twosided
210
homogeneous ideals of a free algebra have a finite Groebner
211
basis.
212
213
EXAMPLES::
214
215
sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace')
216
sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F
217
218
Since `F` was cached and since its degree bound can not be
219
decreased, it may happen that, as a side effect of other tests,
220
it already has a degree bound bigger than 3. So, we can not
221
test against the output of ``I.groebner_basis()``::
222
223
sage: F.set_degbound(3)
224
sage: I.groebner_basis() # not tested
225
Twosided Ideal (y*y*y - y*y*z + y*z*y - y*z*z, y*y*x + y*y*z + y*z*x + y*z*z, x*y + y*z, x*x - y*x - y*y - y*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
226
sage: I.groebner_basis(4)
227
Twosided Ideal (y*z*y*y - y*z*y*z + y*z*z*y - y*z*z*z, y*z*y*x + y*z*y*z + y*z*z*x + y*z*z*z, y*y*z*y - y*y*z*z + y*z*z*y - y*z*z*z, y*y*z*x + y*y*z*z + y*z*z*x + y*z*z*z, y*y*y - y*y*z + y*z*y - y*z*z, y*y*x + y*y*z + y*z*x + y*z*z, x*y + y*z, x*x - y*x - y*y - y*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
228
sage: I.groebner_basis(2) is I.groebner_basis(4)
229
True
230
sage: G = I.groebner_basis(4)
231
sage: G.groebner_basis(3) is G
232
True
233
234
If a finite complete Groebner basis exists, we can compute
235
it as follows::
236
237
sage: I = F*[x*y-y*x,x*z-z*x,y*z-z*y,x^2*y-z^3,x*y^2+z*x^2]*F
238
sage: I.groebner_basis(Infinity)
239
Twosided Ideal (z*z*z*y*y + z*z*z*z*x, z*x*x*x + z*z*z*y, y*z - z*y, y*y*x + z*x*x, y*x*x - z*z*z, x*z - z*x, x*y - y*x) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
240
241
Since the commutators of the generators are contained in the ideal,
242
we can verify the above result by a computation in a polynomial ring
243
in negative lexicographic order::
244
245
sage: P.<c,b,a> = PolynomialRing(QQ,order='neglex')
246
sage: J = P*[a^2*b-c^3,a*b^2+c*a^2]
247
sage: J.groebner_basis()
248
[b*a^2 - c^3, b^2*a + c*a^2, c*a^3 + c^3*b, c^3*b^2 + c^4*a]
249
250
Aparently, the results are compatible, by sending `a` to `x`, `b`
251
to `y` and `c` to `z`.
252
253
"""
254
cdef FreeAlgebra_letterplace A = self.ring()
255
cdef FreeAlgebraElement_letterplace x
256
if degbound is None:
257
degbound = A.degbound()
258
if self.__uptodeg >= degbound:
259
return self.__GB
260
if not A.base().is_field():
261
raise TypeError, "Currently, we can only compute Groebner bases if the ring of coefficients is a field"
262
if self.side()!='twosided':
263
raise TypeError, "This ideal is not two-sided. We can only compute two-sided Groebner bases"
264
if degbound == Infinity:
265
while self.__uptodeg<Infinity:
266
test_bound = 2*max([x._poly.degree() for x in self.__GB.gens()])
267
self.groebner_basis(test_bound)
268
return self.__GB
269
# Set the options required by letterplace
270
from sage.libs.singular.option import LibSingularOptions
271
libsingular_options = LibSingularOptions()
272
bck = (libsingular_options['redTail'],libsingular_options['redSB'])
273
libsingular_options['redTail'] = True
274
libsingular_options['redSB'] = True
275
A.set_degbound(degbound)
276
P = A._current_ring
277
out = [FreeAlgebraElement_letterplace(A,X,check=False) for X in
278
singular_system("freegb",P.ideal([x._poly for x in self.__GB.gens()]),
279
degbound,A.__ngens, ring = P)]
280
libsingular_options['redTail'] = bck[0]
281
libsingular_options['redSB'] = bck[1]
282
self.__GB = A.ideal(out,side='twosided',coerce=False)
283
if degbound >= 2*max([x._poly.degree() for x in out]):
284
degbound = Infinity
285
self.__uptodeg = degbound
286
self.__GB.__uptodeg = degbound
287
return self.__GB
288
289
def __contains__(self,x):
290
"""
291
The containment test is based on a normal form computation.
292
293
EXAMPLES::
294
295
sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace')
296
sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F
297
sage: x*I.0-I.1*y+I.0*y in I # indirect doctest
298
True
299
sage: 1 in I
300
False
301
302
"""
303
R = self.ring()
304
return (x in R) and R(x).normal_form(self).is_zero()
305
306
def reduce(self, G):
307
"""
308
Reduction of this ideal by another ideal,
309
or normal form of an algebra element with respect to this ideal.
310
311
INPUT:
312
313
- ``G``: A list or tuple of elements, an ideal,
314
the ambient algebra, or a single element.
315
316
OUTPUT:
317
318
- The normal form of ``G`` with respect to this ideal, if
319
``G`` is an element of the algebra.
320
- The reduction of this ideal by the elements resp. generators
321
of ``G``, if ``G`` is a list, tuple or ideal.
322
- The zero ideal, if ``G`` is the algebra containing this ideal.
323
324
EXAMPLES::
325
326
sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace')
327
sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F
328
sage: I.reduce(F)
329
Twosided Ideal (0) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
330
sage: I.reduce(x^3)
331
-y*z*x - y*z*y - y*z*z
332
sage: I.reduce([x*y])
333
Twosided Ideal (y*z, x*x - y*x - y*y) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
334
sage: I.reduce(F*[x^2+x*y,y^2+y*z]*F)
335
Twosided Ideal (x*y + y*z, -y*x + y*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
336
337
"""
338
P = self.ring()
339
if not isinstance(G,(list,tuple)):
340
if G==P:
341
return P.ideal([P.zero_element()])
342
if G in P:
343
return G.normal_form(self)
344
G = G.gens()
345
C = P.current_ring()
346
sI = C.ideal([C(X.letterplace_polynomial()) for X in self.gens()], coerce=False)
347
selfdeg = max([x.degree() for x in sI.gens()])
348
gI = P._reductor_(G, selfdeg)
349
from sage.libs.singular.option import LibSingularOptions
350
libsingular_options = LibSingularOptions()
351
bck = (libsingular_options['redTail'],libsingular_options['redSB'])
352
libsingular_options['redTail'] = True
353
libsingular_options['redSB'] = True
354
sI = poly_reduce(sI,gI, ring=C, attributes={gI:{"isSB":1}})
355
libsingular_options['redTail'] = bck[0]
356
libsingular_options['redSB'] = bck[1]
357
return P.ideal([FreeAlgebraElement_letterplace(P,x,check=False) for x in sI], coerce=False)
358
359