Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241849 views
1
r"""
2
Gradings of a polynomial quotient ring.
3
4
AUTHOR :
5
-- Martin Raum (2009 - 07 - 27) Initial version
6
"""
7
8
#===============================================================================
9
#
10
# Copyright (C) 2009 Martin Raum
11
#
12
# This program is free software; you can redistribute it and/or
13
# modify it under the terms of the GNU General Public License
14
# as published by the Free Software Foundation; either version 3
15
# of the License, or (at your option) any later version.
16
#
17
# This program is distributed in the hope that it will be useful,
18
# but WITHOUT ANY WARRANTY; without even the implied warranty of
19
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
# General Public License for more details.
21
#
22
# You should have received a copy of the GNU General Public License
23
# along with this program; if not, see <http://www.gnu.org/licenses/>.
24
#
25
#===============================================================================
26
27
from operator import mul
28
from operator import xor
29
from sage.misc.latex import latex
30
from sage.modules.free_module import FreeModule
31
from sage.rings.infinity import infinity
32
from sage.rings.integer import Integer
33
from sage.rings.integer_ring import ZZ
34
from sage.rings.polynomial.all import is_Polynomial, is_MPolynomial
35
from sage.structure.all import Sequence
36
from sage.structure.sage_object import SageObject
37
38
class Grading_abstract ( SageObject ) :
39
r"""
40
A common interface for monomial gradings of polynomial rings
41
`R[x_1, .., x_n]`.
42
"""
43
44
def ngens(self) :
45
r"""
46
The number of generators of the polynomial ring.
47
48
OUTPUT:
49
An integer.
50
51
TESTS::
52
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
53
sage: Grading_abstract().ngens()
54
Traceback (most recent call last):
55
...
56
NotImplementedError
57
"""
58
raise NotImplementedError
59
60
def gen(self, i) :
61
r"""
62
The grading associated to the `i`-th generator of the polynomial ring.
63
64
INPUT:
65
- `i` -- An integer.
66
67
OUTPUT:
68
A grading index.
69
70
TESTS::
71
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
72
sage: Grading_abstract().gen(1)
73
Traceback (most recent call last):
74
...
75
NotImplementedError
76
"""
77
raise NotImplementedError
78
79
def gens(self) :
80
r"""
81
The gradings of the generators of the polynomial ring.
82
83
OUTPUT:
84
A tuple of grading indices.
85
86
TESTS::
87
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
88
sage: Grading_abstract().gens()
89
Traceback (most recent call last):
90
...
91
NotImplementedError
92
"""
93
raise NotImplementedError
94
95
def index(self, x) :
96
r"""
97
The grading value of `x` with respect to this grading.
98
99
INPUT:
100
- `x` -- A tuple of length `n`.
101
102
OUTPUT:
103
A grading index.
104
105
TESTS::
106
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
107
sage: Grading_abstract().index((1))
108
Traceback (most recent call last):
109
...
110
NotImplementedError
111
"""
112
raise NotImplementedError
113
114
def basis(self, index, vars = None) :
115
r"""
116
All monomials that are have given grading index involving only the
117
given variables.
118
119
INPUT:
120
- ``index`` -- A grading index.
121
- ``vars`` -- A list of integers from `0` to `n - 1` or ``None``
122
(default: ``None``); If ``None`` all variables
123
will be considered.
124
125
OUTPUT:
126
A list of tuples of integers, each of which has length `n`.
127
128
TESTS::
129
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
130
sage: Grading_abstract().basis(1)
131
Traceback (most recent call last):
132
...
133
NotImplementedError
134
"""
135
raise NotImplementedError
136
137
def subgrading(self, gens) :
138
r"""
139
The grading of same type for the ring with only the variables given by
140
``gens``.
141
142
INPUT:
143
- ``gens`` - A list of integers.
144
145
OUTPUT:
146
An instance of :class:~`.Grading_abstract`.
147
148
TESTS::
149
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
150
sage: Grading_abstract().subgrading([1,2])
151
Traceback (most recent call last):
152
...
153
NotImplementedError
154
"""
155
raise NotImplementedError
156
157
def __contains__(self, x) :
158
r"""
159
TESTS::
160
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
161
sage: 1 in Grading_abstract()
162
Traceback (most recent call last):
163
...
164
NotImplementedError
165
"""
166
raise NotImplementedError
167
168
def _repr_(self) :
169
r"""
170
TESTS::
171
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
172
sage: Grading_abstract()
173
A grading
174
"""
175
return "A grading"
176
177
def _latex_(self) :
178
r"""
179
TESTS::
180
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
181
sage: latex( Grading_abstract() )
182
\text{A grading}
183
"""
184
return r"\text{A grading}"
185
186
#===============================================================================
187
# DegreeGrading
188
#===============================================================================
189
190
class DegreeGrading( Grading_abstract ) :
191
r"""
192
This class implements a monomial grading for a polynomial ring
193
`R[x_1, .., x_n]`.
194
"""
195
196
def __init__( self, degrees ) :
197
r"""
198
INPUT:
199
- ``degrees`` -- A list or tuple of `n` positive integers.
200
201
TESTS::
202
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
203
sage: g = DegreeGrading((1,2))
204
sage: g = DegreeGrading([5,2,3])
205
"""
206
207
self.__degrees = tuple(degrees)
208
self.__module = FreeModule(ZZ, len(degrees))
209
self.__module_basis = self.__module.basis()
210
211
def ngens(self) :
212
r"""
213
The number of generators of the polynomial ring.
214
215
OUTPUT:
216
An integer.
217
218
TESTS::
219
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
220
sage: DegreeGrading((1,2)).ngens()
221
2
222
sage: DegreeGrading([5,2,3]).ngens()
223
3
224
"""
225
return len(self.__degrees)
226
227
def gen(self, i) :
228
r"""
229
The number of generators of the polynomial ring.
230
231
OUTPUT:
232
An integer.
233
234
TESTS::
235
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
236
sage: DegreeGrading([5,2,3]).gen(0)
237
5
238
sage: DegreeGrading([5,2,3]).gen(3)
239
Traceback (most recent call last):
240
...
241
ValueError: Generator 3 does not exist.
242
"""
243
if i < len(self.__degrees) :
244
return self.__degrees[i]
245
246
raise ValueError("Generator %s does not exist." % (i,))
247
248
def gens(self) :
249
r"""
250
The gradings of the generators of the polynomial ring.
251
252
OUTPUT:
253
A tuple of integers.
254
255
TESTS::
256
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
257
sage: DegreeGrading((1,2)).gens()
258
(1, 2)
259
sage: DegreeGrading([5,2,3]).gens()
260
(5, 2, 3)
261
"""
262
return self.__degrees
263
264
def index(self, x) :
265
r"""
266
The grading value of `x` with respect to this grading.
267
268
INPUT:
269
- `x` -- A tuple of length `n`.
270
271
OUTPUT:
272
An integer.
273
274
TESTS::
275
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
276
sage: g = DegreeGrading([5,2,3])
277
sage: g.index((2,4,5))
278
33
279
sage: g.index((2,3))
280
Traceback (most recent call last):
281
...
282
ValueError: Tuple must have length 3.
283
"""
284
## TODO: We shouldn't need this.
285
#if len(x) == 0 : return infinity
286
287
if len(x) != len(self.__degrees) :
288
raise ValueError( "Tuple must have length %s." % (len(self.__degrees),))
289
290
return sum( map(mul, x, self.__degrees) )
291
292
def basis(self, index, vars = None) :
293
r"""
294
All monomials that are have given grading index involving only the
295
given variables.
296
297
INPUT:
298
- ``index`` -- A grading index.
299
- ``vars`` -- A list of integers from `0` to `n - 1` or ``None``
300
(default: ``None``); If ``None`` all variables
301
will be considered.
302
303
OUTPUT:
304
A list of elements in `\Z^n`.
305
306
TESTS::
307
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
308
sage: g = DegreeGrading([5,2,3])
309
sage: g.basis(2)
310
[(0, 1, 0)]
311
sage: g.basis(10, vars = [0])
312
[(2, 0, 0)]
313
sage: g.basis(20, vars = [1,2])
314
[(0, 10, 0), (0, 7, 2), (0, 4, 4), (0, 1, 6)]
315
sage: g.basis(-1)
316
[]
317
sage: g.basis(0)
318
[(0, 0, 0)]
319
"""
320
if index < 0 :
321
return []
322
elif index == 0 :
323
return [self.__module.zero_vector()]
324
325
if vars == None :
326
vars = [m for (m,d) in enumerate(self.__degrees) if d <= index]
327
if len(vars) == 0 :
328
return []
329
330
res = [ self.__module_basis[vars[0]] + m
331
for m in self.basis(index - self.__degrees[vars[0]], vars) ]
332
res += self.basis(index, vars[1:])
333
334
return res
335
336
def subgrading(self, gens) :
337
r"""
338
The grading of same type for the ring with only the variables given by
339
``gens``.
340
341
INPUT:
342
- ``gens`` - A list of integers.
343
344
OUTPUT:
345
An instance of :class:~`.DegreeGrading`.
346
347
TESTS::
348
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
349
sage: g = DegreeGrading([5,2,3])
350
sage: g.subgrading([2])
351
Degree grading (3,)
352
sage: g.subgrading([])
353
Degree grading ()
354
"""
355
return DegreeGrading([self.__degrees[i] for i in gens])
356
357
def __contains__(self, x) :
358
r"""
359
TESTS::
360
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
361
sage: g = DegreeGrading([5,2,3])
362
sage: 5 in g
363
True
364
sage: "t" in g
365
False
366
"""
367
return isinstance(x, (int, Integer))
368
369
def __cmp__(self, other) :
370
r"""
371
TESTS::
372
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
373
sage: g = DegreeGrading([5,2,3])
374
sage: g == DegreeGrading([5,2,3])
375
True
376
sage: g == DegreeGrading((2,4))
377
False
378
"""
379
c = cmp(type(self), type(other))
380
381
if c == 0 :
382
c = cmp(self.__degrees, other.__degrees)
383
384
return c
385
386
def __hash__(self) :
387
r"""
388
TESTS::
389
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
390
sage: hash( DegreeGrading([5,2,3]) )
391
-1302562269 # 32-bit
392
7573306103633312291 # 64-bit
393
"""
394
return hash(self.__degrees)
395
396
def _repr_(self) :
397
r"""
398
TESTS::
399
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
400
sage: DegreeGrading([5,2,3])
401
Degree grading (5, 2, 3)
402
"""
403
return "Degree grading %s" % str(self.__degrees)
404
405
def _latex_(self) :
406
r"""
407
TESTS::
408
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
409
sage: latex( DegreeGrading([5,2,3]) )
410
\text{Degree grading } \left(5, 2, 3\right)
411
"""
412
return r"\text{Degree grading }" + latex(self.__degrees)
413
414
class TrivialGrading ( Grading_abstract ) :
415
r"""
416
A grading for a polynomial ring `R[x_1, .., x_n]` assigning to every
417
element the same, arbitrary index.
418
"""
419
420
def __init__(self, nmb_generators, index) :
421
r"""
422
INPUT:
423
- ``nmb_generators`` -- A positive integer; The number `n` of
424
variables of the graded polynomial ring.
425
- ``index`` -- An arbitrary object; The index assigned to
426
all monomials.
427
428
TESTS::
429
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
430
sage: g = TrivialGrading( 3, "t" )
431
sage: g = TrivialGrading( 3, None )
432
"""
433
self.__ngens = nmb_generators
434
self.__index = index
435
436
def ngens(self) :
437
r"""
438
The number of generators of the polynomial ring.
439
440
OUTPUT:
441
An integer.
442
443
TESTS::
444
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
445
sage: TrivialGrading( 3, "t" ).ngens()
446
3
447
"""
448
return self.__ngens
449
450
def gen(self, i) :
451
r"""
452
The number of generators of the polynomial ring.
453
454
OUTPUT:
455
An arbitrary object.
456
457
TESTS::
458
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
459
sage: TrivialGrading( 3, "t" ).gen(2)
460
't'
461
sage: TrivialGrading( 3, "t" ).gen(3)
462
Traceback (most recent call last):
463
...
464
ValueError: Generator 3 does not exist.
465
"""
466
if i < self.__ngens :
467
return self.__index
468
469
raise ValueError("Generator %s does not exist." % (i,))
470
471
def gens(self) :
472
r"""
473
The gradings of the generators of the polynomial ring.
474
475
OUTPUT:
476
A tuple of objects of arbitrary but equal type.
477
478
TESTS::
479
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
480
sage: TrivialGrading( 3, "t" ).gens()
481
('t', 't', 't')
482
"""
483
return tuple(self.__ngens*[self.__index])
484
485
def index(self, x) :
486
r"""
487
The grading value of `x` with respect to this grading.
488
489
INPUT:
490
- `x` -- A tuple of length `n`.
491
492
OUTPUT:
493
A grading index.
494
495
TESTS::
496
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
497
sage: TrivialGrading( 3, "t" ).index((1,0,1))
498
't'
499
sage: TrivialGrading( 3, "t" ).index((1,0))
500
Traceback (most recent call last):
501
...
502
ValueError: Tuple must have length 3.
503
"""
504
if len(x) != self.__ngens :
505
raise ValueError( "Tuple must have length %s." % (self.__ngens,))
506
507
return self.__index
508
509
def basis(self, index, vars = None) :
510
r"""
511
All degree one monomials that are have given grading index involving only the
512
given variables.
513
514
INPUT:
515
- ``index`` -- A grading index.
516
- ``vars`` -- A list of integers from `0` to `n - 1` or ``None``
517
(default: ``None``); If ``None`` all variables
518
will be considered.
519
520
OUTPUT:
521
A list of tuples of integers, each of which has length `n`.
522
523
TESTS::
524
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
525
sage: TrivialGrading( 3, "t" ).basis('t')
526
[(1, 0, 0), (0, 1, 0), (0, 0, 1)]
527
sage: TrivialGrading( 3, "t" ).basis( None )
528
[]
529
"""
530
if index == self.__index :
531
if vars is None :
532
vars = range(self.__ngens)
533
534
return [ tuple(i*[0] + [1] + (self.__ngens - i - 1)*[0])
535
for i in vars ]
536
else :
537
return []
538
539
def subgrading(self, gens) :
540
r"""
541
The grading of same type for the ring with only the variables given by
542
``gens``.
543
544
INPUT:
545
- ``gens`` - A list of integers.
546
547
OUTPUT:
548
An instance of :class:~`.TrivialGrading`.
549
550
TESTS::
551
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
552
sage: TrivialGrading( 3, "t" ).subgrading([1,2])
553
Trivial grading on 2 generators with index 't'
554
sage: TrivialGrading( 3, "t" ).subgrading([])
555
Trivial grading on 0 generators with index 't'
556
"""
557
return TrivialGrading(len(gens), self.__index)
558
559
def __contains__(self, x) :
560
r"""
561
TESTS::
562
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
563
sage: g = TrivialGrading( 3, "t" )
564
sage: "t" in g
565
True
566
sage: (1,2,1) in g
567
False
568
sage: None in g
569
False
570
"""
571
return x == self.__index
572
573
def __cmp__(self, other) :
574
r"""
575
TESTS::
576
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
577
sage: g = TrivialGrading( 3, "t" )
578
sage: g == TrivialGrading( 3, "t" )
579
True
580
sage: g == TrivialGrading( 2, "t" )
581
False
582
sage: g == TrivialGrading( 3, None )
583
False
584
"""
585
c = cmp(type(self), type(other))
586
587
if c == 0 :
588
c = cmp(self.__ngens, other.__ngens)
589
if c == 0 :
590
c = cmp(self.__index, other.__index)
591
592
return c
593
594
def __hash__(self) :
595
r"""
596
TESTS::
597
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
598
sage: hash( TrivialGrading( 3, "t" ) )
599
1963142774 # 32-bit
600
14848044662 # 64-bit
601
"""
602
return reduce(xor, map(hash, [self.__ngens, self.__index]))
603
604
def _repr_(self) :
605
r"""
606
TESTS::
607
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
608
sage: TrivialGrading( 3, "t" )
609
Trivial grading on 3 generators with index 't'
610
"""
611
return "Trivial grading on %s generators with index %s" \
612
% (self.__ngens, repr(self.__index))
613
614
def _latex_(self) :
615
r"""
616
TESTS::
617
sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *
618
sage: latex( TrivialGrading( 3, "t" ) )
619
\text{Trivial grading on $3$ generators with index $\verb|t|$}
620
"""
621
return r"\text{Trivial grading on $%s$ generators with index $%s$}" \
622
% (latex(self.__ngens), latex(self.__index))
623
624