Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241852 views
1
r"""
2
Implementation of base classes used as parameters for a ring of monoid
3
power series.
4
5
AUTHOR :
6
- Martin Raum (2009 - 07 - 25) Initial version
7
"""
8
9
#===============================================================================
10
#
11
# Copyright (C) 2009 Martin Raum
12
#
13
# This program is free software; you can redistribute it and/or
14
# modify it under the terms of the GNU General Public License
15
# as published by the Free Software Foundation; either version 3
16
# of the License, or (at your option) any later version.
17
#
18
# This program is distributed in the hope that it will be useful,
19
# but WITHOUT ANY WARRANTY; without even the implied warranty of
20
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21
# General Public License for more details.
22
#
23
# You should have received a copy of the GNU General Public License
24
# along with this program; if not, see <http://www.gnu.org/licenses/>.
25
#
26
#===============================================================================
27
28
from operator import xor
29
from sage.misc.latex import latex
30
from sage.categories.all import Rings
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.structure.sage_object import SageObject
35
36
#===============================================================================
37
# CharacterMonoid_class
38
#===============================================================================
39
40
class CharacterMonoid_class ( SageObject ) :
41
r"""
42
The characters for an equivariant monoid power series must
43
form a monoid. A basic implementation is given here.
44
"""
45
46
def __init__(self, G, C, codomain, eval, C_multiplicative = True) :
47
r"""
48
INPUT:
49
50
- `G` -- Every type accepted; Representative of a group which
51
the characters can be evaluated on.
52
- `C` -- A class implementing all functions of :class:`~.TrivialMonoid_class`;
53
A monoid whose elements represent one character each.
54
- ``codomain`` -- A ring; A common codomain for all characters.
55
- ``eval`` -- A function; It accepts a group element and a character,
56
returning the evaluation of this character at the
57
group element.
58
- ``C_multiplicative`` -- A boolean; If true the monoid `C` is assumed
59
to be multiplicative. Otherwise it is assumed to be additive.
60
61
NOTE:
62
The interface may change in the future, enforcing `G` to be a group.
63
64
EXAMPLES::
65
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
66
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
67
68
TESTS::
69
sage: cm = CharacterMonoid_class(None, TrivialMonoid(), AbelianGroup([3,3]), lambda g, c: 1)
70
sage: cm = CharacterMonoid_class("ZZ", ZZ, AbelianGroup([3,3]), lambda g, c: 1, True)
71
"""
72
self.__G = G
73
self.__C = C
74
self.__codomain = codomain
75
self.__eval = eval
76
self.__C_multiplicative = C_multiplicative
77
78
def ngens(self) :
79
r"""
80
OUTPUT:
81
An integer.
82
83
TESTS::
84
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
85
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
86
sage: cm.ngens()
87
1
88
sage: cm = CharacterMonoid_class("ZZ", AbelianGroup([3, 3]), ZZ, lambda g, c: 1)
89
sage: cm.ngens()
90
2
91
"""
92
return self.__C.ngens()
93
94
def gen(self, i = 0) :
95
r"""
96
OUTPUT:
97
An instance of :class:`~.CharacterMonoidElement_class`.
98
99
TESTS::
100
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
101
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
102
sage: cm.gen()
103
1
104
"""
105
return CharacterMonoidElement_class(self, self.__C.gen(i))
106
107
def gens(self) :
108
r"""
109
OUTPUT:
110
A tuple of instances of :class:`~.CharacterMonoidElement_class`.
111
112
TESTS::
113
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
114
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
115
sage: cm.gens()
116
(1,)
117
"""
118
return tuple(map(lambda c: CharacterMonoidElement_class(self, c), self.__C.gens()))
119
120
def group(self) :
121
r"""
122
Return the group, which is the common domain of all characters
123
of this monoid of characters.
124
125
OUTPUT:
126
Of arbitrary type.
127
128
TESTS::
129
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
130
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
131
sage: cm.group()
132
'ZZ'
133
"""
134
return self.__G
135
136
def codomain(self) :
137
r"""
138
Return the common codomain of all characters of this monoid of characters.
139
140
OUTPUT:
141
A ring.
142
143
EXAMPLES::
144
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
145
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
146
sage: cm.codomain()
147
Rational Field
148
"""
149
return self.__codomain
150
151
def monoid(self) :
152
r"""
153
Return the abstract monoid underlying this monoid of characters.
154
155
OUTPUT:
156
A monoid.
157
158
EXAMPLES::
159
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
160
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
161
sage: cm.monoid()
162
Trivial monoid
163
sage: cm = CharacterMonoid_class("ZZ", AbelianGroup([3, 3]), ZZ, lambda g, c: 1)
164
sage: cm.monoid()
165
Multiplicative Abelian Group isomorphic to C3 x C3
166
"""
167
return self.__C
168
169
def extends(self, other) :
170
r"""
171
Decide whether ``self`` extends ``other``. Namely, whether there is a is an embedding of ``other``
172
into ``self`` that is compatible with a common codomain. A negative answer does not mean
173
that there is no such embedding.
174
175
INPUT:
176
- other -- An instance of :class:.`~CharacterMonoid_class`.
177
178
OUTPUT:
179
A boolean.
180
181
EXAMPLES::
182
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
183
sage: cm1 = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
184
sage: cm2 = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
185
sage: cm1 == cm2
186
False
187
"""
188
return self == other
189
190
def _is_C_multiplicative(self) :
191
r"""
192
Return whether the underlying monoid is multiplicative.
193
194
OUTPUT:
195
A boolean.
196
197
TESTS::
198
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
199
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
200
sage: cm._is_C_multiplicative()
201
True
202
"""
203
return self.__C_multiplicative
204
205
def _eval_function(self) :
206
r"""
207
Return the evaluation function, mapping an element of the associated group and an element of ``self``
208
to an element of the codomain.
209
210
OUTPUT:
211
A function with signature `g, c \mapsto e`.
212
213
TESTS::
214
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
215
sage: e = lambda g, c: 1
216
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, e)
217
sage: e == cm._eval_function()
218
True
219
"""
220
return self.__eval
221
222
def _apply(self, g, c, b) :
223
r"""
224
Apply `c(g)` to some element `b` by multiplication.
225
226
INPUT:
227
- g -- Arbitrary type; A representative of the group.
228
- c -- An element of self; A character.
229
- b -- An element of a ring with embedding from the codomain. An element to
230
apply `c(g)` to.
231
232
OUTPUT:
233
An element of a ring.
234
235
EXAMPLES::
236
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
237
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
238
sage: cm._apply(1, 1, 2)
239
2
240
"""
241
return self.__eval(g, c) * b
242
243
def __cmp__(self, other) :
244
r"""
245
TESTS::
246
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
247
sage: cm1 = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
248
sage: cm2 = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
249
sage: cm1 == cm2
250
False
251
"""
252
c = cmp(type(self), type(other))
253
if c == 0 :
254
c = cmp(self.__G, other.__G)
255
if c == 0 :
256
c = cmp(self.__codomain, other.__codomain)
257
if c == 0 :
258
c = cmp(self.__C, other.__C)
259
if c == 0 and not self.__eval is other.__eval :
260
return -1
261
262
return c
263
264
def __iter__(self) :
265
r"""
266
TEST::
267
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
268
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
269
sage: list(cm)
270
[1]
271
"""
272
for c in self.__C :
273
yield CharacterMonoidElement_class(self, c)
274
275
raise StopIteration
276
277
def one_element(self) :
278
r"""
279
TESTS::
280
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
281
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
282
sage: cm.one_element()
283
1
284
"""
285
return CharacterMonoidElement_class(self, self.__C.one_element())
286
287
def __call__(self, x) :
288
r"""
289
Convert an element to ``self``.
290
291
INPUT:
292
- `x` -- An element that is convertible to :meth:~`.monoid()`.
293
294
OUTPUT:
295
An element of ``self``.
296
297
TESTS::
298
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
299
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
300
sage: cm(1)
301
1
302
"""
303
return CharacterMonoidElement_class(self, self.__C(x))
304
305
def __hash__(self) :
306
r"""
307
TESTS::
308
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
309
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
310
sage: d = dict([(cm.one_element, 0)]) # indirect doctest
311
"""
312
return xor(hash(self.__C), hash(self.__G))
313
314
def _repr_(self) :
315
r"""
316
TESTS::
317
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
318
sage: CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
319
Character monoid over Trivial monoid
320
"""
321
return "Character monoid over %s" % self.__C
322
323
def _latex_(self) :
324
r"""
325
TESTS::
326
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid
327
sage: latex(CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1))
328
\text{Character monoid over } \text{Trivial monoid}
329
"""
330
return r"\text{Character monoid over }" + latex(self.__C)
331
332
#===============================================================================
333
# CharacterMonoidElement_class
334
#===============================================================================
335
336
class CharacterMonoidElement_class ( SageObject ) :
337
"""
338
The element class of :class:`~.CharacterMonoid_class`.
339
"""
340
341
def __init__(self, parent, c) :
342
r"""
343
INPUT:
344
- ``parent`` -- An instance of :class:`~.CharacterMonoid_class`; The parent of ``self``.
345
- `c` -- An element of a monoid; The element in the underlying monoid of ``parent``
346
associated to ``self``.
347
348
TESTS::
349
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid
350
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
351
sage: c = CharacterMonoidElement_class(cm, cm.monoid().one_element())
352
"""
353
self.__parent = parent
354
self.__c = c
355
356
def parent(self) :
357
r"""
358
OUTPUT:
359
An instance of :class:`~.CharacterMonoid_class`.
360
361
TESTS::
362
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid
363
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
364
sage: c = CharacterMonoidElement_class(cm, cm.monoid().one_element())
365
sage: c.parent() is cm
366
True
367
"""
368
return self.__parent
369
370
def _monoid_element(self) :
371
r"""
372
The underlying element of the monoid.
373
374
OUTPUT:
375
An element of a character.
376
377
TESTS::
378
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid
379
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
380
sage: c = CharacterMonoidElement_class(cm, cm.monoid().one_element())
381
sage: c._monoid_element() == cm.monoid().one_element()
382
True
383
"""
384
return self.__c
385
386
def __call__(self, g) :
387
r"""
388
OUTPUT:
389
An element of the codomain of the parent.
390
391
TESTS::
392
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid
393
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
394
sage: c = CharacterMonoidElement_class(cm, cm.monoid().one_element())
395
sage: c(2)
396
1
397
398
Test old bug, where elements of the underlying monoid were passed to the eval function::
399
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1 if isinstance(c, CharacterMonoidElement_class) else -1)
400
sage: c = CharacterMonoidElement_class(cm, cm.monoid().one_element())
401
sage: c(2)
402
1
403
"""
404
return self.parent()._eval_function()(g, self)
405
406
def __mul__(left, right) :
407
r"""
408
NOTE:
409
If the underlying monoid is additive the character are nevertheless multiplied.
410
411
OUTPUT:
412
An instance of :class:`~.CharacterMonoidElement_class`.
413
414
TESTS::
415
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid
416
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
417
sage: c = CharacterMonoidElement_class(cm, cm.monoid().one_element())
418
sage: c * c # indirect doctest
419
1
420
sage: cm = CharacterMonoid_class("ZZ", ZZ, QQ, lambda g, c: 1, False)
421
sage: c = CharacterMonoidElement_class(cm, cm.monoid().one_element())
422
sage: c * c # indirect doctest
423
2
424
"""
425
if not isinstance(right, CharacterMonoidElement_class) or \
426
not left.parent() == right.parent() :
427
raise TypeError( "Right factor should be an element of the monoid." )
428
429
if left.parent()._is_C_multiplicative() :
430
return CharacterMonoidElement_class(left.parent(), left.__c * right.__c)
431
else :
432
return CharacterMonoidElement_class(left.parent(), left.__c + right.__c)
433
434
def __cmp__(self, other) :
435
r"""
436
TESTS::
437
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid
438
sage: cm = CharacterMonoid_class("ZZ", ZZ, QQ, lambda g, c: 1, False)
439
sage: c1 = CharacterMonoidElement_class(cm, cm.monoid().one_element())
440
sage: c2 = CharacterMonoidElement_class(cm, cm.monoid().one_element())
441
sage: c1 == c2 # indirect doctest
442
True
443
sage: c1 * c1 == c1 # indirect doctest
444
False
445
"""
446
c = cmp(type(self), type(other))
447
if c == 0 :
448
c = cmp(self.__parent, other.__parent)
449
if c == 0 :
450
c = cmp(self.__c, other.__c)
451
452
return c
453
454
def __hash__(self) :
455
r"""
456
OUTPUT:
457
An integer.
458
459
TESTS::
460
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid
461
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
462
sage: c1 = CharacterMonoidElement_class(cm, cm.monoid().one_element())
463
sage: hash(c1) # indirect doctest
464
-582796950 # 32-bit
465
-3589969894075844246 # 64-bit
466
"""
467
return xor(hash(self.__parent), hash(self.__c))
468
469
def _repr_(self) :
470
r"""
471
OUTPUT:
472
A string.
473
474
TESTS::
475
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid
476
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
477
sage: c1 = CharacterMonoidElement_class(cm, cm.monoid().one_element())
478
sage: repr(c1) # indirect doctest
479
'1'
480
"""
481
return repr(self.__c)
482
483
def _latex_(self) :
484
r"""
485
OUTPUT:
486
A string.
487
488
TESTS::
489
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid
490
sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)
491
sage: c1 = CharacterMonoidElement_class(cm, cm.monoid().one_element())
492
sage: latex(c1) # indirect doctest
493
1
494
"""
495
return latex(self.__c)
496
497
#===============================================================================
498
# TrivialMonoid
499
#===============================================================================
500
501
class TrivialMonoid ( SageObject ) :
502
r"""
503
A monoid with one element, which implements only functions that are necessary for
504
being an arguemnt of :meth:`~.CharacterMonoid_class.__init__`.
505
"""
506
507
def __init__(self) :
508
r"""
509
TESTS::
510
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid
511
sage: m = TrivialMonoid()
512
"""
513
SageObject.__init__(self)
514
515
def ngens(self) :
516
r"""
517
OUTPUT:
518
An integer.
519
520
TESTS::
521
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid
522
sage: m = TrivialMonoid()
523
sage: m.ngens()
524
1
525
"""
526
return 1
527
528
def gen(self, i = 0) :
529
r"""
530
OUTPUT:
531
An integer.
532
533
TESTS::
534
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid
535
sage: m = TrivialMonoid()
536
sage: m.gen()
537
1
538
sage: m.gen(1)
539
Traceback (most recent call last):
540
...
541
ValueError: Generator not defined.
542
"""
543
if i == 0 :
544
return Integer(1)
545
546
raise ValueError, "Generator not defined."
547
548
def gens(self) :
549
r"""
550
OUTPUT:
551
A tuple of integers.
552
553
TESTS::
554
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid
555
sage: m = TrivialMonoid()
556
sage: m.gens()
557
(1,)
558
"""
559
return (Integer(1), )
560
561
def one_element(self) :
562
r"""
563
OUTPUT:
564
An integer.
565
566
TESTS::
567
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid
568
sage: m = TrivialMonoid()
569
sage: m.one_element()
570
1
571
"""
572
return Integer(1)
573
574
def __call__(self, x) :
575
r"""
576
INPUT:
577
- `x` -- An integer.
578
579
OUTPUT:
580
An integer.
581
582
TESTS::
583
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid
584
sage: m = TrivialMonoid()
585
sage: m(1)
586
1
587
sage: m(2)
588
Traceback (most recent call last):
589
...
590
TypeError: Cannot convert 2 into Trivial monoid.
591
"""
592
if x == 1 :
593
return 1
594
595
raise TypeError( "Cannot convert %s into Trivial monoid." % (x,) )
596
597
def __cmp__(self, other) :
598
r"""
599
TESTS::
600
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid
601
sage: TrivialMonoid() == TrivialMonoid() # indirect doctest
602
True
603
"""
604
return cmp(type(self), type(other))
605
606
def __iter__(self) :
607
r"""
608
OUTPUT:
609
A generator over integers.
610
611
TESTS::
612
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid
613
sage: m = TrivialMonoid()
614
sage: list(m) # indirect doctest
615
[1]
616
"""
617
yield Integer(1)
618
619
raise StopIteration
620
621
def _repr_(self) :
622
r"""
623
OUTPUT:
624
A string.
625
626
TESTS::
627
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid
628
sage: m = TrivialMonoid()
629
sage: repr(m) # indirect doctest
630
'Trivial monoid'
631
"""
632
return "Trivial monoid"
633
634
def _latex_(self) :
635
r"""
636
OUTPUT:
637
A string.
638
639
TESTS::
640
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid
641
sage: m = TrivialMonoid()
642
sage: latex(m) # indirect doctest
643
\text{Trivial monoid}
644
"""
645
return r"\text{Trivial monoid}"
646
647
#===============================================================================
648
# TrivialCharacterMonoid
649
#===============================================================================
650
651
_trivial_evaluations = dict()
652
653
def TrivialCharacterMonoid(G, K) :
654
r"""
655
Return the monoid of characters with codomain `K` with one element.
656
657
INPUT:
658
- `K` -- A ring; The codomain for the characters.
659
660
OUTPUT:
661
An instance of :class:`~.CharacterMonoid_class`.
662
663
TESTS::
664
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialCharacterMonoid
665
sage: h = TrivialCharacterMonoid("ZZ", QQ)
666
sage: h
667
Character monoid over Trivial monoid
668
sage: h == TrivialCharacterMonoid("ZZ", QQ)
669
True
670
"""
671
global _trivial_evaluations
672
673
try :
674
eval = _trivial_evaluations[K]
675
except KeyError :
676
eval = lambda g, c : K.one_element()
677
_trivial_evaluations[K] = eval
678
679
return CharacterMonoid_class(G, TrivialMonoid(), K, eval)
680
681
#===============================================================================
682
# TrivialRepresentation
683
#===============================================================================
684
685
class TrivialRepresentation ( SageObject ) :
686
r"""
687
A trivial representation over a group `G` with codomain `K` occurring as a representation for
688
:class:`~fourier_expansion_framework.monoidpowerseries.EquivariantMonoidPowerSeriesAmbient_abstract`.
689
"""
690
691
def __init__(self, G, K) :
692
r"""
693
INPUT:
694
- `G` -- Arbitrary type; A group or representative of a group.
695
- `K` -- A module or ring; The codomain of the representation.
696
697
OUTPUT:
698
An instance of :class:`~.TrivialRepresentation`.
699
700
NOTE:
701
The interface may change late, enforcing `G` to be an actual group.
702
703
TESTS::
704
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation
705
sage: rep = TrivialRepresentation("ZZ", QQ) # indirect doctest
706
"""
707
self.__G = G
708
self.__K = K
709
710
def base_ring(self) :
711
r"""
712
The base ring of the representation, commuting with the action.
713
714
OUTPUT:
715
A ring.
716
717
TESTS::
718
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation
719
sage: rep = TrivialRepresentation("ZZ", QQ)
720
sage: rep.base_ring()
721
Rational Field
722
sage: rep = TrivialRepresentation("ZZ", FreeModule(ZZ, 3))
723
sage: rep.base_ring()
724
Integer Ring
725
"""
726
if self.__K in Rings() :
727
return self.__K
728
else :
729
return self.__K.base_ring()
730
731
def codomain(self) :
732
r"""
733
The codomain of the representation.
734
735
OUTPUT:
736
A ring or a module.
737
738
TESTS::
739
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation
740
sage: rep = TrivialRepresentation("ZZ", FreeModule(ZZ, 3))
741
sage: rep.codomain()
742
Ambient free module of rank 3 over the principal ideal domain Integer Ring
743
"""
744
return self.__K
745
746
def from_module(self, R) :
747
r"""
748
Construct a representation of the same type with codomain `R`.
749
750
INPUT:
751
752
- `R` -- A module that the representation can be restricted or
753
extended to.
754
755
OUTPUT:
756
757
- An instance of :class:`~.TrivialRepresentation`.
758
759
EXAMPLES::
760
761
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation
762
sage: rep = TrivialRepresentation("ZZ", FreeModule(ZZ, 3))
763
sage: rep2 = rep.from_module(FreeModule(QQ, 2))
764
sage: rep2.codomain()
765
Vector space of dimension 2 over Rational Field
766
"""
767
return TrivialRepresentation( self.__G, R )
768
769
def base_extend(self, L) :
770
r"""
771
Extend the representation's codomain by `L`.
772
773
INPUT:
774
- `L` -- A ring; A new base ring.
775
776
OUTPUT:
777
An instance of :class:`~.TrivialRepresentation`.
778
779
EXAMPLES::
780
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation
781
sage: rep = TrivialRepresentation("ZZ", FreeModule(ZZ, 3))
782
sage: repQQ = rep.base_extend(QQ)
783
sage: repQQ.codomain()
784
Vector space of dimension 3 over Rational Field
785
sage: repQQ.base_extend(GF(3))
786
Traceback (most recent call last):
787
...
788
TypeError: Base extension of self (over 'Rational Field') to ring 'Finite Field of size 3' not defined.
789
sage: rep = TrivialRepresentation("ZZ", ZZ)
790
sage: repQQ = rep.base_extend(QQ)
791
sage: repQQ.codomain()
792
Rational Field
793
sage: repQQ.base_extend(GF(3))
794
Traceback (most recent call last):
795
...
796
AssertionError
797
"""
798
if self.__K in Rings() :
799
assert L.has_coerce_map_from(self.__K)
800
return TrivialRepresentation( self.__G, L )
801
else :
802
return TrivialRepresentation( self.__G, self.__K.base_extend(L) )
803
804
def extends(self, other) :
805
r"""
806
Wheter ``self`` is an extension of ``other``.
807
808
INPUT:
809
- ``other`` -- A representation.
810
811
OUTPUT:
812
A boolean.
813
814
NOTE:
815
This does not necessarily mean that ``self`` ocurres as a base extension of
816
``other``.
817
818
EXAMPLES::
819
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation
820
sage: rep1 = TrivialRepresentation("ZZ", ZZ)
821
sage: rep2 = TrivialRepresentation("ZZ", QQ)
822
sage: rep1.extends(rep2)
823
False
824
sage: rep2.extends(rep1)
825
True
826
"""
827
if type(self) != type(other) :
828
return False
829
830
return self.__K.has_coerce_map_from(other.__K)
831
832
def group(self) :
833
r"""
834
The group that acts.
835
836
OUTPUT:
837
Arbitrary type.
838
839
EXAMPLES::
840
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation
841
sage: rep = TrivialRepresentation("ZZ", QQ)
842
sage: rep.group()
843
'ZZ'
844
"""
845
return self.__G
846
847
def _apply_function(self) :
848
r"""
849
A function that maps a group element and an element of the codomain to its image.
850
851
OUTPUT:
852
A function with signature `(g,a) \mapsto g.a`.
853
854
TESTS::
855
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation
856
sage: rep = TrivialRepresentation("ZZ", QQ)
857
sage: rep._apply_function() == rep.apply
858
True
859
"""
860
return self.apply
861
862
def apply(self, g, a) :
863
r"""
864
Return the image of `a` under the transformation `g`.
865
866
INPUT:
867
- `g` -- Arbitrary type; A group element.
868
- `a` -- An element of a ring of module; An elemento the codomain.
869
870
OUTPUT:
871
A element of the codomain.
872
873
TESTS::
874
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation
875
sage: rep = TrivialRepresentation("ZZ", QQ)
876
sage: rep.apply(2, 1/2)
877
1/2
878
"""
879
return a
880
881
def __cmp__(self, other) :
882
r"""
883
TESTS::
884
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation
885
sage: rep1 = TrivialRepresentation("ZZ", QQ)
886
sage: rep2 = TrivialRepresentation("ZZ", FreeModule(QQ, 1))
887
sage: rep1 == rep1 # indirect doctest
888
True
889
sage: rep1 == rep2 # indirect doctest
890
False
891
"""
892
c = cmp(type(self), type(other))
893
894
if c == 0 :
895
c = cmp(self.__G, self.__G)
896
if c == 0 :
897
c = cmp(self.__K, other.__K)
898
899
return c
900
901
def __hash__(self) :
902
r"""
903
TESTS::
904
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation
905
sage: rep = TrivialRepresentation("ZZ", QQ)
906
sage: hash(rep) # indirect doctest
907
-564657610 # 32-bit
908
-11520069220171210 # 64-bit
909
"""
910
return xor(hash(self.__G), hash(self.__K))
911
912
def _repr_(self) :
913
r"""
914
TESTS::
915
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation
916
sage: rep = TrivialRepresentation("ZZ", QQ)
917
sage: repr(rep)
918
'Trivial representation of ZZ on Rational Field'
919
"""
920
return "Trivial representation of %s on %s" % (self.__G, self.__K)
921
922
def _latex_(self) :
923
r"""
924
TESTS::
925
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation
926
sage: rep = TrivialRepresentation("ZZ", QQ)
927
sage: latex(rep)
928
\text{Trivial representation of $\verb|ZZ|$ on $\Bold{Q}$}
929
"""
930
return r"\text{Trivial representation of $%s$ on $%s$}" % (latex(self.__G), latex(self.__K))
931
932
#===============================================================================
933
# NNMonoid
934
#===============================================================================
935
936
class NNMonoid( SageObject ) :
937
r"""
938
Monoid of all natural numbers with zero as is can occure as an arguement of
939
:class:`~fourier_expansion_framework.monoidpowerseries.MonoidPowerSeriesAmbient_abstract`.
940
"""
941
942
def __init__(self, reduced = True) :
943
r"""
944
INPUT:
945
- ``reduce`` -- A boolean (default: True); Wheter ``self`` is equipped with an action
946
or not.
947
948
OUTPUT:
949
An instance of :class:`~.NNmonoid`.
950
951
TESTS::
952
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
953
sage: m = NNMonoid()
954
"""
955
self.__reduced = reduced
956
957
def ngens(self) :
958
r"""
959
OUTPUT:
960
An integer.
961
962
TESTS::
963
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
964
sage: m = NNMonoid()
965
sage: m.ngens()
966
1
967
"""
968
return 1
969
970
def gen(self, i = 0) :
971
r"""
972
OUTPUT:
973
An integer.
974
975
TESTS::
976
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
977
sage: m = NNMonoid()
978
sage: m.gen()
979
1
980
sage: m.gen(1)
981
Traceback (most recent call last):
982
...
983
ValueError: Generator not defined.
984
"""
985
986
if i == 0 :
987
return 1
988
989
raise ValueError( "Generator not defined." )
990
991
def gens(self) :
992
r"""
993
OUTPUT:
994
A tuple of integers.
995
996
TESTS::
997
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
998
sage: m = NNMonoid()
999
sage: m.gens()
1000
(1,)
1001
"""
1002
return tuple([self.gen(i) for i in xrange(self.ngens())])
1003
1004
def is_commutative(self) :
1005
r"""
1006
Whether the monoid is commutative or not.
1007
1008
OUTPUT:
1009
A boolean.
1010
1011
TESTS::
1012
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1013
sage: m = NNMonoid()
1014
sage: m.is_commutative()
1015
True
1016
"""
1017
return True
1018
1019
def monoid(self) :
1020
r"""
1021
If ``self`` respects the action of the trivial group return the underlying
1022
monoid without this action. Otherwise return a copy of ``self``.
1023
1024
OUTPUT:
1025
An instance of :class:`~.NNMonoid`.
1026
1027
TESTS::
1028
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1029
sage: m_a = NNMonoid()
1030
sage: m_woa = NNMonoid(False)
1031
sage: m_a.monoid() == m_woa
1032
True
1033
sage: m_woa.monoid() == m_woa
1034
True
1035
sage: m_woa.monoid() is m_woa
1036
False
1037
"""
1038
return NNMonoid(False)
1039
1040
def group(self) :
1041
r"""
1042
If ``self`` respects the action of a group return representative.
1043
1044
OUTPUT:
1045
Arbitrary type.
1046
1047
TESTS::
1048
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1049
sage: m_a = NNMonoid()
1050
sage: m_woa = NNMonoid(False)
1051
sage: m_a.group()
1052
'1'
1053
sage: m_woa.group()
1054
Traceback (most recent call last):
1055
...
1056
ArithmeticError: Monoid is not equipped with a group action.
1057
"""
1058
if self.__reduced :
1059
return "1"
1060
else :
1061
raise ArithmeticError( "Monoid is not equipped with a group action.")
1062
1063
def is_monoid_action(self) :
1064
r"""
1065
In case ``self`` respects the action of a group, decide whether this action is a monoid action
1066
on the underlying monoid.
1067
1068
OUTPUT:
1069
A boolean.
1070
1071
TESTS::
1072
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1073
sage: m_a = NNMonoid()
1074
sage: m_woa = NNMonoid(False)
1075
sage: m_a.is_monoid_action()
1076
1
1077
sage: m_woa.is_monoid_action()
1078
Traceback (most recent call last):
1079
...
1080
ArithmeticError: Monoid is not equipped with a group action.
1081
"""
1082
if self.__reduced :
1083
return True
1084
else :
1085
raise ArithmeticError( "Monoid is not equipped with a group action.")
1086
1087
def filter(self, bound) :
1088
r"""
1089
Return a filter with given bound associated to this monoid.
1090
1091
INPUT:
1092
- ``bound`` -- An integer; An upper bound for natural numbers.
1093
1094
OUTPUT:
1095
An instance of :class:`~.NNFilter`.
1096
1097
TESTS::
1098
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1099
sage: m_a = NNMonoid()
1100
sage: m_woa = NNMonoid(False)
1101
sage: f = m_a.filter(5)
1102
sage: f.index()
1103
5
1104
sage: f.is_reduced()
1105
True
1106
sage: f = m_woa.filter(7)
1107
sage: f.is_reduced()
1108
False
1109
"""
1110
return NNFilter(bound, self.__reduced)
1111
1112
def filter_all(self) :
1113
r"""
1114
Return the filter associated to this monoid which contains all elements.
1115
1116
OUTPUT:
1117
An instance of :class:`~.NNFilter`.
1118
1119
TESTS::
1120
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1121
sage: m_a = NNMonoid()
1122
sage: m_woa = NNMonoid(False)
1123
sage: f = m_a.filter_all()
1124
sage: f.index()
1125
+Infinity
1126
sage: f.is_reduced()
1127
True
1128
sage: m_woa.filter_all().is_reduced()
1129
False
1130
"""
1131
return NNFilter(infinity, self.__reduced)
1132
1133
def zero_filter(self) :
1134
r"""
1135
Return the filter associated to this monoid which contains no elements.
1136
1137
OUTPUT:
1138
An instance of :class:`~.NNFilter`.
1139
1140
TESTS::
1141
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1142
sage: m_a = NNMonoid()
1143
sage: m_woa = NNMonoid(False)
1144
sage: f = m_a.zero_filter()
1145
sage: f.index()
1146
0
1147
sage: f.is_reduced()
1148
True
1149
sage: m_woa.zero_filter().is_reduced()
1150
False
1151
"""
1152
return NNFilter(0, self.__reduced)
1153
1154
def minimal_composition_filter(self, ls, rs) :
1155
r"""
1156
Given two lists `ls` and `rs` of natural numbers return a filter that contains
1157
all the sums `l + r` of elements `l \in ls,\, r \in rs`.
1158
1159
INPUT:
1160
- `ls` -- A list of integers.
1161
- `rs` -- A list of integers.
1162
1163
OUTPUT:
1164
An instance of :class:`~.NNFilter`.
1165
1166
TESTS::
1167
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1168
sage: m = NNMonoid()
1169
sage: m.minimal_composition_filter([], []).is_reduced()
1170
True
1171
sage: m = NNMonoid(False)
1172
sage: m.minimal_composition_filter([], []).is_reduced()
1173
False
1174
sage: m = NNMonoid()
1175
sage: m.minimal_composition_filter([], []).index()
1176
0
1177
sage: m.minimal_composition_filter([], [1]).index()
1178
0
1179
sage: m.minimal_composition_filter([1], []).index()
1180
0
1181
sage: m.minimal_composition_filter([1], [1]).index()
1182
3
1183
sage: m.minimal_composition_filter([1,2,4], [1,5]).index()
1184
10
1185
"""
1186
if len(ls) == 0 or len(rs) == 0 :
1187
return NNFilter(0, self.__reduced)
1188
1189
return NNFilter(max(0, max(ls) + max(rs) + 1), self.__reduced)
1190
1191
def _reduction_function(self) :
1192
r"""
1193
In case ``self`` respects the action of a group, return the
1194
reduction funtion for elements of this monoid.
1195
1196
SEE::
1197
:meth:`~.reduce`
1198
1199
OUTPUT:
1200
A function accepting one argument.
1201
1202
TESTS::
1203
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1204
sage: m = NNMonoid()
1205
sage: m._reduction_function() == m.reduce
1206
True
1207
sage: m = NNMonoid(False)
1208
sage: m._reduction_function()
1209
Traceback (most recent call last):
1210
...
1211
ArithmeticError: Monoid is not equipped with a group action.
1212
"""
1213
if self.__reduced :
1214
return self.reduce
1215
else :
1216
raise ArithmeticError( "Monoid is not equipped with a group action." )
1217
1218
def reduce(self, s) :
1219
r"""
1220
Reduce a natural number with respect to the trivial groups.
1221
1222
INPUT:
1223
- `s` -- An integer.
1224
1225
OUTPUT:
1226
The pair `(s, 1)`.
1227
1228
TESTS::
1229
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1230
sage: m = NNMonoid()
1231
sage: m.reduce(7)
1232
(7, 1)
1233
"""
1234
return (s, 1)
1235
1236
def decompositions(self, s) :
1237
r"""
1238
Decompose a natural number `s` in to a sum of two.
1239
1240
INPUT:
1241
- `s` -- An integer.
1242
1243
OUTPUT:
1244
A generator of pairs of integers.
1245
1246
EXAMPLES::
1247
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1248
sage: m = NNMonoid()
1249
sage: list(m.decompositions(4))
1250
[(0, 4), (1, 3), (2, 2), (3, 1), (4, 0)]
1251
"""
1252
for n in xrange(s+1) :
1253
yield (n, s-n)
1254
1255
raise StopIteration
1256
1257
def zero_element(self) :
1258
r"""
1259
The zero element of this monoid.
1260
1261
OUTPUT:
1262
An integer.
1263
1264
TESTS:
1265
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1266
sage: m = NNMonoid()
1267
sage: m.zero_element()
1268
0
1269
"""
1270
return 0
1271
1272
def __contains__(self, x) :
1273
r"""
1274
TESTS::
1275
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1276
sage: m = NNMonoid()
1277
sage: 2 in m
1278
True
1279
sage: 'a' in m
1280
False
1281
sage: -1 in m
1282
False
1283
"""
1284
return isinstance(x, (int, Integer)) and x >= 0
1285
1286
def __cmp__(self, other) :
1287
r"""
1288
TESTS::
1289
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1290
sage: m = NNMonoid()
1291
sage: m == NNMonoid()
1292
True
1293
sage: m == NNMonoid(False)
1294
False
1295
"""
1296
c = cmp(type(self), type(other))
1297
if c == 0 :
1298
c = cmp(self.__reduced, other.__reduced)
1299
1300
return c
1301
1302
def __hash__(self) :
1303
r"""
1304
TESTS::
1305
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1306
sage: hash(NNMonoid())
1307
1
1308
sage: hash(NNMonoid(False))
1309
0
1310
"""
1311
return hash(self.__reduced)
1312
1313
def _repr_(self) :
1314
r"""
1315
TESTS::
1316
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1317
sage: repr(NNMonoid())
1318
'NN with action'
1319
sage: repr(NNMonoid(False))
1320
'NN'
1321
"""
1322
if not self.__reduced :
1323
return "NN"
1324
else :
1325
return "NN with action"
1326
1327
def _latex_(self) :
1328
r"""
1329
TESTS::
1330
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid
1331
sage: latex(NNMonoid())
1332
\Bold{N}\text{ with action}
1333
sage: latex(NNMonoid(False))
1334
\Bold{N}
1335
"""
1336
if not self.__reduced :
1337
return r"\Bold{N}"
1338
else :
1339
return r"\Bold{N}\text{ with action}"
1340
1341
#===============================================================================
1342
# NNFilter
1343
#===============================================================================
1344
1345
class NNFilter ( SageObject ) :
1346
r"""
1347
A filter for the monoid of natrual numbers bounding elements by their value.
1348
"""
1349
1350
def __init__(self, bound, reduced = True) :
1351
r"""
1352
INPUT:
1353
- ``bound`` -- An integer; A bound for the natural numbers.
1354
- ``reduced`` -- A boolean (default: True); If True the action of the trivial
1355
group is respected by the filter.
1356
1357
OUTPUT:
1358
An instance of :class:`~.NNFilter`.
1359
1360
TESTS::
1361
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter
1362
sage: f = NNFilter(3) # indirect doctest
1363
sage: f = NNFilter(7, False) # indirect doctest
1364
"""
1365
if isinstance(bound, NNFilter) :
1366
bound = bound.index()
1367
1368
self.__bound = bound
1369
self.__reduced = reduced
1370
1371
def is_infinite(self) :
1372
r"""
1373
Whether the filter contains infinitely many elements.
1374
1375
OUTPUT:
1376
A boolean.
1377
1378
TESTS::
1379
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter
1380
sage: NNFilter(3).is_infinite()
1381
False
1382
sage: NNFilter(infinity).is_infinite()
1383
True
1384
"""
1385
return self.__bound is infinity
1386
1387
def is_all(self) :
1388
r"""
1389
Whether the filter contains all elements of the associated monoid.
1390
1391
OUTPUT:
1392
A boolean.
1393
1394
TESTS::
1395
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter
1396
sage: NNFilter(3).is_all()
1397
False
1398
sage: NNFilter(infinity).is_all()
1399
True
1400
"""
1401
return self.is_infinite()
1402
1403
def index(self) :
1404
r"""
1405
Return the bound for this filter.
1406
1407
OUTPUT:
1408
An integer.
1409
1410
TESTS::
1411
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter
1412
sage: NNFilter(3).index()
1413
3
1414
"""
1415
return self.__bound
1416
1417
def is_reduced(self) :
1418
r"""
1419
Whether the filter respects the action of a group.
1420
1421
OUTPUT:
1422
A boolean.
1423
1424
TESTS::
1425
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter
1426
sage: NNFilter(3).is_reduced()
1427
True
1428
sage: NNFilter(7, False).is_reduced()
1429
False
1430
"""
1431
return self.__reduced
1432
1433
def __contains__(self, n) :
1434
r"""
1435
TESTS::
1436
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter
1437
sage: f = NNFilter(10)
1438
sage: 3 in f # indirect doctest
1439
True
1440
sage: 10 in f # indirect doctest
1441
False
1442
sage: 78 in NNFilter(infinity) # indirect doctest
1443
True
1444
"""
1445
if self.__bound is infinity :
1446
return True
1447
1448
return n < self.__bound
1449
1450
def __iter__(self) :
1451
r"""
1452
OUTPUT:
1453
A generator over integers.
1454
1455
TESTS::
1456
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter
1457
sage: list(NNFilter(4)) == range(4) # indirect doctest
1458
True
1459
sage: list(NNFilter(infinity))
1460
Traceback (most recent call last):
1461
...
1462
ArithmeticError: Cannot iterate over infinite filters.
1463
"""
1464
if self.__bound is infinity :
1465
raise ArithmeticError( "Cannot iterate over infinite filters." )
1466
1467
for n in xrange(self.__bound) :
1468
yield n
1469
1470
raise StopIteration
1471
1472
def __cmp__(self, other) :
1473
r"""
1474
TESTS::
1475
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter
1476
sage: NNFilter(4) == NNFilter(4) # indirect doctest
1477
True
1478
sage: NNFilter(4) == NNFilter(5) # indirect doctest
1479
False
1480
sage: NNFilter(4) == NNFilter(4, False) # indirect doctest
1481
False
1482
"""
1483
c = cmp(type(self), type(other))
1484
if c == 0 :
1485
c = cmp(self.__reduced, other.__reduced)
1486
if c == 0 :
1487
c = cmp(self.__bound, other.__bound)
1488
1489
return c
1490
1491
def __hash__(self) :
1492
r"""
1493
TESTS::
1494
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter
1495
sage: hash(NNFilter(4)) # indirect doctest
1496
21
1497
sage: hash(NNFilter(7, False)) # indirect doctest
1498
7
1499
"""
1500
return hash(self.__bound) + 17 * hash(self.__reduced)
1501
1502
def _repr_(self) :
1503
r"""
1504
TESTS::
1505
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter
1506
sage: repr(NNFilter(3))
1507
'Filtered NN with action up to 3'
1508
sage: repr(NNFilter(4, False))
1509
'Filtered NN up to 4'
1510
"""
1511
if self.__reduced :
1512
return "Filtered NN with action up to %s" % self.__bound
1513
else :
1514
return "Filtered NN up to %s" % self.__bound
1515
1516
def _latex_(self) :
1517
r"""
1518
TESTS::
1519
sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter
1520
sage: latex(NNFilter(3))
1521
\text{Filtered $\Bold{N}$ with action up to $3$}
1522
sage: latex(NNFilter(4, False))
1523
\text{Filtered $\Bold{N}$ up to $4$}
1524
"""
1525
if self.__reduced :
1526
return r"\text{Filtered $\Bold{N}$ with action up to $%s$}" % latex(self.__bound)
1527
else :
1528
return r"\text{Filtered $\Bold{N}$ up to $%s$}" % latex(self.__bound)
1529
1530