Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/modular/modsym/manin_symbols.py
8820 views
1
# -*- coding: utf-8 -*-
2
"""
3
Manin symbols
4
5
This module defines the class ManinSymbol. A Manin Symbol of
6
weight `k`, level `N` has the form `[P(X,Y),(u:v)]` where
7
`P(X,Y)\in\mathbb{Z}[X,Y]` is homogeneous of weight `k-2` and
8
`(u:v)\in\mathbb{P}^1(\mathbb{Z}/N\mathbb{Z}).` The ManinSymbol class
9
holds a "monomial Manin Symbol" of the simpler form
10
`[X^iY^{k-2-i},(u:v)]`, which is stored as a triple `(i,u,v)`; the
11
weight and level are obtained from the parent structure, which is a
12
ManinSymbolList.
13
14
Integer matrices `[a,b;c,d]` act on Manin Symbols on the right,
15
sending `[P(X,Y),(u,v)]` to `[P(aX+bY,cX+dY),(u,v)g]`. Diagonal
16
matrices (with `b=c=0`, such as `I=[-1,0;0,1]` and `J=[-1,0;0,-1]`)
17
and anti-diagonal matrices (with `a=d=0`, such as `S=[0,-1;1,0]`) map
18
monomial Manin Symbols to monomial Manin Symbols, up to a scalar
19
factor. For general matrices (such as `T=[0,1,-1,-1]` and
20
`T^2=[-1,-1;0,1]`) the image of a monomial Manin Symbol is expressed
21
as a formal sum of monomial Manin Symbols, with integer coefficients.
22
23
There are various different classes holding lists of Manin symbols of
24
different types. The hierarchy is as follows:
25
26
::
27
28
class ManinSymbolList(SageObject)
29
30
class ManinSymbolList_group(ManinSymbolList)
31
class ManinSymbolList_gamma0(ManinSymbolList_group)
32
class ManinSymbolList_gamma1(ManinSymbolList_group)
33
class ManinSymbolList_gamma_h(ManinSymbolList_group)
34
35
class ManinSymbolList_character(ManinSymbolList)
36
37
"""
38
39
#*****************************************************************************
40
# Sage: System for Algebra and Geometry Experimentation
41
#
42
# Copyright (C) 2005 William Stein <[email protected]>
43
#
44
# Distributed under the terms of the GNU General Public License (GPL)
45
#
46
# This code is distributed in the hope that it will be useful,
47
# but WITHOUT ANY WARRANTY; without even the implied warranty of
48
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
49
# General Public License for more details.
50
#
51
# The full text of the GPL is available at:
52
#
53
# http://www.gnu.org/licenses/
54
#*****************************************************************************
55
56
import sage.matrix.all
57
import sage.modular.cusps as cusps
58
import sage.modular.modsym.p1list as p1list
59
import sage.modular.modsym.g1list as g1list
60
import sage.modular.modsym.ghlist as ghlist
61
import sage.modular.modsym.modular_symbols
62
import sage.rings.arith as arith
63
import sage.rings.all as rings
64
65
from sage.structure.sage_object import SageObject
66
67
from apply import apply_to_monomial
68
69
def is_ManinSymbol(x):
70
"""
71
Returns True if ``x`` is a ManinSymbol.
72
73
EXAMPLES::
74
75
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0, is_ManinSymbol
76
sage: m = ManinSymbolList_gamma0(6, 4)
77
sage: is_ManinSymbol(m[3])
78
False
79
sage: s = ManinSymbol(m,m[3])
80
sage: s
81
[Y^2,(1,2)]
82
sage: is_ManinSymbol(s)
83
True
84
85
"""
86
return isinstance(x, ManinSymbol)
87
88
class ManinSymbolList(SageObject):
89
"""
90
Base class for lists of all Manin symbols for a given weight, group or character.
91
"""
92
def __init__(self, weight, list):
93
"""
94
Constructor for a ManinSymbolList.
95
96
INPUT:
97
98
- ``weight``- the weight of the symbols.
99
- ``list``- the list of symbols.
100
101
On construction, a ManinSymbolList constructs a dict for
102
rapid determination of the index of any given symbol.
103
104
This is a base class only; users will only directly construct
105
objects in the derived classes ManinSymbolList_gamma0,
106
ManinSymbolList_gamma1, ManinSymbolList_gamma_h,
107
ManinSymbolList_gamma_character. Many standard methods are
108
only implemented in the derived classes.
109
110
EXAMPLES::
111
112
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList
113
sage: ManinSymbolList(6,P1List(11))
114
<class 'sage.modular.modsym.manin_symbols.ManinSymbolList'>
115
116
"""
117
self._weight = weight
118
self._list = list
119
self._index = dict([(list[i],i) for i in range(len(list))])
120
121
def __cmp__(self, right):
122
"""
123
Comparison function for ManinSymbolList objects.
124
125
EXAMPLES::
126
127
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList
128
sage: m1 = ManinSymbolList(6,P1List(11))
129
sage: m2 = ManinSymbolList(6,P1List(13))
130
sage: m3 = ManinSymbolList(4,P1List(11))
131
sage: m1 < m2
132
True
133
sage: m2 < m3
134
False
135
sage: m1 < m3
136
False
137
"""
138
if not isinstance(right, ManinSymbolList):
139
return cmp(type(self), type(right))
140
return cmp((self._weight, self._list), (right._weight, right._list))
141
142
def __getitem__(self, n):
143
"""
144
Returns the `n`th ManinSymbol in this ManinSymbolList
145
146
EXAMPLES::
147
148
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList
149
sage: m = ManinSymbolList(6,P1List(11))
150
sage: m[4]
151
(1, 3)
152
"""
153
return self._list[n]
154
155
def __len__(self):
156
"""
157
Returns the length of this ManinSymbolList
158
159
EXAMPLES::
160
161
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList
162
sage: m = ManinSymbolList(6,P1List(11))
163
sage: len(m)
164
12
165
"""
166
return len(self._list)
167
168
def apply(self, j, X):
169
"""
170
Apply the matrix `X=[a,b;c,d]` to the `j`-th Manin symbol.
171
172
Implemented in derived classes.
173
174
EXAMPLES::
175
176
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList
177
sage: m = ManinSymbolList(6,P1List(11))
178
sage: m.apply(10, [1,2,0,1])
179
Traceback (most recent call last):
180
...
181
NotImplementedError: Only implemented in derived classes
182
183
"""
184
raise NotImplementedError, "Only implemented in derived classes"
185
186
def _apply_S_only_0pm1(self):
187
"""
188
Return True if the coefficient when applying the S relation is
189
always 0, 1, or -1. This is useful for optimizing code in
190
relation_matrix.py.
191
192
EXAMPLES::
193
194
sage: eps = DirichletGroup(4).gen(0)
195
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character
196
sage: ManinSymbolList_character(eps,2)._apply_S_only_0pm1()
197
True
198
sage: eps = DirichletGroup(7).gen(0)
199
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character
200
sage: ManinSymbolList_character(eps,2)._apply_S_only_0pm1()
201
False
202
"""
203
return False # derived classes could overload and put True
204
205
def apply_S(self, j):
206
"""
207
Apply the matrix `S=[0,-1;1,0]` to the `j`-th Manin symbol.
208
209
Implemented in derived classes.
210
211
EXAMPLES::
212
213
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList
214
sage: m = ManinSymbolList(6,P1List(11))
215
sage: m.apply_S(10)
216
Traceback (most recent call last):
217
...
218
NotImplementedError: Only implemented in derived classes
219
"""
220
raise NotImplementedError, "Only implemented in derived classes"
221
222
def apply_I(self, j):
223
"""
224
Apply the matrix `I=[-1,0;0,1]` to the `j`-th Manin symbol.
225
226
Implemented in derived classes.
227
228
EXAMPLES::
229
230
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList
231
sage: m = ManinSymbolList(6,P1List(11))
232
sage: m.apply_I(10)
233
Traceback (most recent call last):
234
...
235
NotImplementedError: Only implemented in derived classes
236
"""
237
raise NotImplementedError, "Only implemented in derived classes"
238
239
def apply_T(self, j):
240
"""
241
Apply the matrix `T=[0,1;-1,-1]` to the `j`-th Manin symbol.
242
243
Implemented in derived classes.
244
245
EXAMPLES::
246
247
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList
248
sage: m = ManinSymbolList(6,P1List(11))
249
sage: m.apply_T(10)
250
Traceback (most recent call last):
251
...
252
NotImplementedError: Only implemented in derived classes
253
"""
254
raise NotImplementedError, "Only implemented in derived classes"
255
256
def apply_TT(self, j):
257
"""
258
Apply the matrix `TT=T^2=[-1,-1;0,1]` to the `j`-th Manin symbol.
259
260
Implemented in derived classes.
261
262
EXAMPLES::
263
264
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList
265
sage: m = ManinSymbolList(6,P1List(11))
266
sage: m.apply_TT(10)
267
Traceback (most recent call last):
268
...
269
NotImplementedError: Only implemented in derived classes
270
"""
271
raise NotImplementedError, "Only implemented in derived classes"
272
273
def index(self, x):
274
"""
275
Return the index of ``x`` in the list of Manin symbols, where ``x`` is a
276
3-tuple of ints. If ``x`` is not in the list, then return -1.
277
278
INPUT:
279
280
- ``x`` - 3-tuple of integers, `(i,u,v)` defining a valid Manin symbol, which need not be normalized.
281
282
OUTPUT:
283
284
(``int``) the index of the normalized Manin symbol equivalent to `(i,u,v)`.
285
286
EXAMPLES::
287
288
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList
289
sage: m = ManinSymbolList(6,P1List(11))
290
sage: m.index(m[2])
291
2
292
sage: all([i == m.index(m[i]) for i in xrange(len(m))])
293
True
294
"""
295
if self._index.has_key(x):
296
return self._index[x]
297
x = self.normalize(x)
298
try:
299
return self._index[x]
300
except KeyError:
301
return -1
302
303
def manin_symbol_list(self):
304
"""
305
Returns all the ManinSymbols in this ManinSymbolList as a list
306
307
Cached for subsequent calls.
308
309
OUTPUT:
310
311
a list of ``ManinSymbol`` objects, which is a copy of the complete list
312
of Manin symbols.
313
314
EXAMPLES::
315
316
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList
317
sage: m = ManinSymbolList(6,P1List(11))
318
sage: m.manin_symbol_list() # not implemented for the base class
319
320
::
321
322
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
323
sage: m = ManinSymbolList_gamma0(6, 4)
324
sage: m.manin_symbol_list()
325
[[Y^2,(0,1)],
326
[Y^2,(1,0)],
327
[Y^2,(1,1)],
328
...
329
[X^2,(3,1)],
330
[X^2,(3,2)]]
331
332
"""
333
import copy
334
try:
335
return copy.copy(self.__manin_symbol_list)
336
except AttributeError:
337
self.__manin_symbol_list = [self.manin_symbol(i) \
338
for i in xrange(len(self))]
339
return copy.copy(self.__manin_symbol_list)
340
341
def manin_symbol(self, i):
342
"""
343
Returns the i'th ManinSymbol in this ManinSymbolList.
344
345
INPUT:
346
347
348
- ``i`` - integer, a valid index of a symbol in this list.
349
350
351
OUTPUT:
352
353
``ManinSymbol`` - the `i`'th Manin symbol in the list.
354
355
EXAMPLES::
356
357
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList
358
sage: m = ManinSymbolList(6,P1List(11))
359
sage: m.manin_symbol(3) # not implemented for base class
360
361
::
362
363
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
364
sage: m = ManinSymbolList_gamma0(6, 4)
365
sage: s = m.manin_symbol(3); s
366
[Y^2,(1,2)]
367
sage: type(s)
368
<class 'sage.modular.modsym.manin_symbols.ManinSymbol'>
369
"""
370
return ManinSymbol(self, self._list[int(i)])
371
372
def normalize(self, x):
373
"""
374
Returns a normalized ManinSymbol from x.
375
376
To be implemented in derived classes.
377
378
EXAMPLES::
379
380
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList
381
sage: m = ManinSymbolList(6,P1List(11))
382
sage: m.normalize((0,6,7)) # not implemented in base class
383
384
"""
385
raise NotImplementedError, "Only implemented in derived classes"
386
387
def weight(self):
388
"""
389
Returns the weight of the ManinSymbols in this ManinSymbolList.
390
391
392
OUTPUT:
393
394
``integer`` - the weight of the Manin symbols in the list.
395
396
EXAMPLES::
397
398
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
399
sage: m = ManinSymbolList_gamma0(6, 4)
400
sage: m.weight()
401
4
402
"""
403
return self._weight
404
405
class ManinSymbolList_group(ManinSymbolList):
406
"""
407
Base class for Manin symbol lists for a given group.
408
409
INPUT:
410
411
412
- ``level`` - integer level
413
414
- ``weight`` - integer weight
415
416
- ``syms`` - something with a normalize and list
417
method, e.g., P1List.
418
419
EXAMPLES::
420
421
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_group
422
sage: ManinSymbolList_group(11, 2, P1List(11))
423
<class 'sage.modular.modsym.manin_symbols.ManinSymbolList_group'>
424
425
"""
426
def __init__(self, level, weight, syms):
427
"""
428
Constructor for class ManinSymbolList_group.
429
430
INPUT:
431
432
- ``level`` - integer level
433
434
- ``weight`` - integer weight
435
436
- ``syms`` - something with a normalize and list method, e.g., P1List.
437
438
EXAMPLES::
439
440
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_group
441
sage: ManinSymbolList_group(11, 2, P1List(11))
442
<class 'sage.modular.modsym.manin_symbols.ManinSymbolList_group'>
443
444
"""
445
self.__level = level
446
self.__syms = syms # syms is anything with a normalize and list method.
447
448
# The list returned from P1List is guaranteed to be sorted.
449
# Thus each list constructed below is also sorted. This is
450
# important since the index function assumes the list is sorted.
451
L = [(i, u, v) for i in range(weight - 2 + 1) \
452
for u, v in syms.list()]
453
ManinSymbolList.__init__(self, weight, L)
454
455
def level(self):
456
"""
457
Return the level of this ManinSymbolList.
458
459
EXAMPLES::
460
461
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
462
sage: ManinSymbolList_gamma0(5,2).level()
463
5
464
465
::
466
467
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma1
468
sage: ManinSymbolList_gamma1(51,2).level()
469
51
470
471
::
472
473
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma_h
474
sage: ManinSymbolList_gamma_h(GammaH(117, [4]),2).level()
475
117
476
"""
477
return self.__level
478
479
def apply_S(self, j):
480
"""
481
Apply the matrix `S=[0,-1,1,0]` to the `j`-th Manin symbol.
482
483
INPUT:
484
485
- ``j`` - (int) a symbol index
486
487
OUTPUT:
488
489
``(k, s)`` where k is the index of the symbol obtained by acting on the
490
`j`'th symbol with `S`, and `s` is the parity of of the `j`'th symbol
491
(a Python ``int``, either 1 or -1).
492
493
EXAMPLE::
494
495
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
496
sage: m = ManinSymbolList_gamma0(5,8)
497
sage: m.apply_S(4)
498
(40, 1)
499
sage: [m.apply_S(i) for i in xrange(len(m))]
500
[(37, 1),
501
(36, 1),
502
(41, 1),
503
(39, 1),
504
(40, 1),
505
(38, 1),
506
(31, -1),
507
(30, -1),
508
(35, -1),
509
(33, -1),
510
(34, -1),
511
(32, -1),
512
...
513
(4, 1),
514
(2, 1)]
515
"""
516
i, u, v = self._list[j]
517
k = self.index((self._weight-2-i, v, -u))
518
if i%2==0:
519
return k, 1
520
else:
521
return k, -1
522
523
def _apply_S_only_0pm1(self):
524
"""
525
Return True if the coefficient when applying the S relation is
526
always 0, 1, or -1. This is useful for optimizing code in
527
relation_matrix.py.
528
529
EXAMPLES::
530
531
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
532
sage: ManinSymbolList_gamma0(5,8)._apply_S_only_0pm1()
533
True
534
"""
535
return True
536
537
def apply_I(self, j):
538
"""
539
Apply the matrix `I=[-1,0,0,1]` to the `j`-th Manin symbol.
540
541
INPUT:
542
543
- ``j`` - (int) a symbol index
544
545
OUTPUT:
546
547
``(k, s)`` where k is the index of the symbol obtained by acting on the
548
`j`'th symbol with `I`, and `s` is the parity of of the `j`'th symbol
549
(a Python ``int``, either 1 or -1)
550
551
EXAMPLE::
552
553
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
554
sage: m = ManinSymbolList_gamma0(5,8)
555
sage: m.apply_I(4)
556
(3, 1)
557
sage: [m.apply_I(i) for i in xrange(10)]
558
[(0, 1),
559
(1, 1),
560
(5, 1),
561
(4, 1),
562
(3, 1),
563
(2, 1),
564
(6, -1),
565
(7, -1),
566
(11, -1),
567
(10, -1)]
568
"""
569
i, u, v = self._list[j]
570
k = self.index((i, -u, v))
571
if i%2==0:
572
return k, 1
573
else:
574
return k, -1
575
576
def apply_T(self, j):
577
"""
578
Apply the matrix `T=[0,1,-1,-1]` to the `j`-th Manin symbol.
579
580
INPUT:
581
582
- ``j`` - (int) a symbol index
583
584
OUTPUT: see documentation for apply()
585
586
EXAMPLE::
587
588
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
589
sage: m = ManinSymbolList_gamma0(5,8)
590
sage: m.apply_T(4)
591
[(3, 1), (9, -6), (15, 15), (21, -20), (27, 15), (33, -6), (39, 1)]
592
sage: [m.apply_T(i) for i in xrange(10)]
593
[[(5, 1), (11, -6), (17, 15), (23, -20), (29, 15), (35, -6), (41, 1)],
594
[(0, 1), (6, -6), (12, 15), (18, -20), (24, 15), (30, -6), (36, 1)],
595
[(4, 1), (10, -6), (16, 15), (22, -20), (28, 15), (34, -6), (40, 1)],
596
[(2, 1), (8, -6), (14, 15), (20, -20), (26, 15), (32, -6), (38, 1)],
597
[(3, 1), (9, -6), (15, 15), (21, -20), (27, 15), (33, -6), (39, 1)],
598
[(1, 1), (7, -6), (13, 15), (19, -20), (25, 15), (31, -6), (37, 1)],
599
[(5, 1), (11, -5), (17, 10), (23, -10), (29, 5), (35, -1)],
600
[(0, 1), (6, -5), (12, 10), (18, -10), (24, 5), (30, -1)],
601
[(4, 1), (10, -5), (16, 10), (22, -10), (28, 5), (34, -1)],
602
[(2, 1), (8, -5), (14, 10), (20, -10), (26, 5), (32, -1)]]
603
"""
604
k = self._weight
605
i, u, v = self._list[j]
606
u, v = self.__syms.normalize(v,-u-v)
607
if (k-2) % 2 == 0:
608
s = 1
609
else:
610
s = -1
611
z = []
612
a = rings.ZZ(k-2-i)
613
for j in range(k-2-i+1):
614
m = self.index((j, u, v))
615
z.append((m, s * a.binomial(j)))
616
s *= -1
617
return z
618
619
def apply_TT(self, j):
620
"""
621
Apply the matrix `TT=[-1,-1,0,1]` to the `j`-th Manin symbol.
622
623
INPUT:
624
625
- ``j`` - (int) a symbol index
626
627
OUTPUT: see documentation for apply()
628
629
EXAMPLE::
630
631
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
632
sage: m = ManinSymbolList_gamma0(5,8)
633
sage: m.apply_TT(4)
634
[(38, 1)]
635
sage: [m.apply_TT(i) for i in xrange(10)]
636
[[(37, 1)],
637
[(41, 1)],
638
[(39, 1)],
639
[(40, 1)],
640
[(38, 1)],
641
[(36, 1)],
642
[(31, -1), (37, 1)],
643
[(35, -1), (41, 1)],
644
[(33, -1), (39, 1)],
645
[(34, -1), (40, 1)]]
646
"""
647
k = self._weight
648
i, u, v = self._list[j]
649
u, v = self.__syms.normalize(-u-v,u)
650
if (k-2-i) % 2 == 0:
651
s = 1
652
else:
653
s = -1
654
z = []
655
a = rings.ZZ(i)
656
for j in range(i+1):
657
m = self.index((k-2-i+j, u, v))
658
z.append((m, s * a.binomial(j)))
659
s *= -1
660
return z
661
662
def apply(self, j, m):
663
r"""
664
Apply the matrix `m=[a,b;c,d]` to the `j`-th Manin symbol.
665
666
INPUT:
667
668
- ``j`` - (int) a symbol index
669
670
- ``m = [a, b, c, d]`` a list of 4 integers, which defines a 2x2 matrix.
671
672
673
OUTPUT:
674
675
a list of pairs `(j_i, \alpha_i)`, where each `\alpha_i` is a nonzero
676
integer, `j_i` is an integer (index of the `j_i`-th Manin symbol), and
677
`\sum_i \alpha_i\*x_{j_i}` is the image of the j-th Manin symbol under
678
the right action of the matrix [a,b;c,d]. Here the right action of
679
g=[a,b;c,d] on a Manin symbol `[P(X,Y),(u,v)]` is
680
`[P(aX+bY,cX+dY),(u,v)\*g]`.
681
682
EXAMPLE::
683
684
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
685
sage: m = ManinSymbolList_gamma0(5,8)
686
sage: m.apply(40,[2,3,1,1])
687
[(0, 729), (6, 2916), (12, 4860), (18, 4320), (24, 2160), (30, 576), (36, 64)]
688
689
"""
690
a, b, c, d = m[0], m[1], m[2], m[3]
691
i, u, v = self[j]
692
P = apply_to_monomial(i, self._weight-2, a, b, c, d)
693
m = self.index((0, u*a+v*c, u*b+v*d))
694
if m == -1:
695
return []
696
r = len(self.__syms)
697
return [(m + r*k, P[k]) for k in range(self._weight-2+1)
698
if P[k] != 0]
699
700
def normalize(self, x):
701
"""
702
Returns the normalization of the ModSym ``x`` with respect to this
703
list.
704
705
INPUT:
706
707
- ``x`` - (3-tuple of ints) a tuple defining a ManinSymbol.
708
709
OUTPUT:
710
711
``(i,u,v)`` - (3-tuple of ints) another tuple defining the associated
712
normalized ManinSymbol.
713
714
EXAMPLE::
715
716
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
717
sage: m = ManinSymbolList_gamma0(5,8)
718
sage: [m.normalize(s.tuple()) for s in m.manin_symbol_list()][:10]
719
[(0, 0, 1),
720
(0, 1, 0),
721
(0, 1, 1),
722
(0, 1, 2),
723
(0, 1, 3),
724
(0, 1, 4),
725
(1, 0, 1),
726
(1, 1, 0),
727
(1, 1, 1),
728
(1, 1, 2)]
729
"""
730
u,v = self.__syms.normalize(x[1],x[2])
731
return (x[0],u,v)
732
733
734
class ManinSymbolList_gamma0(ManinSymbolList_group):
735
r"""
736
Class for Manin Symbols for `\Gamma_0(N)`.
737
738
INPUT:
739
740
- ``level`` - (integer): the level.
741
742
- ``weight`` - (integer): the weight.
743
744
EXAMPLE::
745
746
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
747
sage: m = ManinSymbolList_gamma0(5,2); m
748
Manin Symbol List of weight 2 for Gamma0(5)
749
sage: m.manin_symbol_list()
750
[(0,1), (1,0), (1,1), (1,2), (1,3), (1,4)]
751
sage: m = ManinSymbolList_gamma0(6,4); m
752
Manin Symbol List of weight 4 for Gamma0(6)
753
sage: len(m)
754
36
755
"""
756
def __init__(self, level, weight):
757
"""
758
Constructor for a ModularSymbolList for Gamma_0(N)
759
760
EXAMPLES::
761
762
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
763
sage: M11 = ManinSymbolList_gamma0(11,2)
764
sage: M11
765
Manin Symbol List of weight 2 for Gamma0(11)
766
sage: M11 == loads(dumps(M11))
767
True
768
"""
769
ManinSymbolList_group.__init__(self, level, weight, p1list.P1List(level))
770
771
def __repr__(self):
772
"""
773
String representation.
774
775
EXAMPLES::
776
777
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
778
sage: M11 = ManinSymbolList_gamma0(11,2)
779
sage: str(M11)
780
'Manin Symbol List of weight 2 for Gamma0(11)'
781
782
"""
783
return "Manin Symbol List of weight %s for Gamma0(%s)"%(
784
self.weight(), self.level())
785
786
787
class ManinSymbolList_gamma1(ManinSymbolList_group):
788
r"""
789
Class for Manin Symbols for `\Gamma_1(N)`.
790
791
INPUT:
792
793
- ``level`` - (integer): the level.
794
795
- ``weight`` - (integer): the weight.
796
797
EXAMPLE::
798
799
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma1
800
sage: m = ManinSymbolList_gamma1(5,2); m
801
Manin Symbol List of weight 2 for Gamma1(5)
802
sage: m.manin_symbol_list()
803
[(0,1),
804
(0,2),
805
(0,3),
806
...
807
(4,3),
808
(4,4)]
809
sage: m = ManinSymbolList_gamma1(6,4); m
810
Manin Symbol List of weight 4 for Gamma1(6)
811
sage: len(m)
812
72
813
sage: m == loads(dumps(m))
814
True
815
"""
816
def __init__(self, level, weight):
817
"""
818
Constructor for a ModularSymbolList for `\Gamma_0(N)`.
819
820
EXAMPLES::
821
822
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma1
823
sage: M11 = ManinSymbolList_gamma1(11,2)
824
sage: M11
825
Manin Symbol List of weight 2 for Gamma1(11)
826
"""
827
ManinSymbolList_group.__init__(self, level, weight, g1list.G1list(level))
828
829
def __repr__(self):
830
"""
831
Return the string representation of this ManinSymbbol list.
832
833
EXAMPLES::
834
835
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma1
836
sage: M11 = ManinSymbolList_gamma1(11,4)
837
sage: str(M11)
838
'Manin Symbol List of weight 4 for Gamma1(11)'
839
"""
840
return "Manin Symbol List of weight %s for Gamma1(%s)"%(
841
self.weight(), self.level())
842
843
844
class ManinSymbolList_gamma_h(ManinSymbolList_group):
845
r"""
846
Class for Manin Symbols for `\Gamma_H(N)`.
847
848
INPUT:
849
850
- ``group`` - (integer): the congruence subgroup.
851
852
- ``weight`` - (integer): the weight.
853
854
EXAMPLE::
855
856
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma_h
857
sage: G = GammaH(117, [4])
858
sage: m = ManinSymbolList_gamma_h(G,2); m
859
Manin Symbol List of weight 2 for Congruence Subgroup Gamma_H(117) with H generated by [4]
860
sage: m.manin_symbol_list()[100:110]
861
[(1,88),
862
(1,89),
863
(1,90),
864
(1,91),
865
(1,92),
866
(1,93),
867
(1,94),
868
(1,95),
869
(1,96),
870
(1,97)]
871
sage: len(m.manin_symbol_list())
872
2016
873
sage: m == loads(dumps(m))
874
True
875
"""
876
def __init__(self, group, weight):
877
r"""
878
Constructor for Manin Symbols for `\Gamma_H(N)`.
879
880
EXAMPLE::
881
882
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma_h
883
sage: G = GammaH(117, [4])
884
sage: m = ManinSymbolList_gamma_h(G,2); m
885
Manin Symbol List of weight 2 for Congruence Subgroup Gamma_H(117) with H generated by [4]
886
"""
887
self.__group = group
888
ManinSymbolList_group.__init__(self, group.level(), weight, ghlist.GHlist(group))
889
890
def group(self):
891
"""
892
Return the group associated to self.
893
894
EXAMPLES::
895
896
sage: ModularSymbols(GammaH(12, [5]), 2).manin_symbols().group()
897
Congruence Subgroup Gamma_H(12) with H generated by [5]
898
"""
899
return self.__group
900
901
def __repr__(self):
902
"""
903
Return the string representation of self.
904
905
EXAMPLES::
906
907
sage: ModularSymbols(GammaH(12, [5]), 2).manin_symbols().__repr__()
908
'Manin Symbol List of weight 2 for Congruence Subgroup Gamma_H(12) with H generated by [5]'
909
"""
910
return "Manin Symbol List of weight %s for %s"%(
911
self.weight(), self.group())
912
913
914
class ManinSymbolList_character(ManinSymbolList):
915
"""
916
List of Manin Symbols with character.
917
918
INPUT:
919
920
- ``character`` - (DirichletCharacter) the Dirichlet character.
921
922
- ``weight`` - (integer) the weight.
923
924
EXAMPLE::
925
926
sage: eps = DirichletGroup(4).gen(0)
927
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character
928
sage: m = ManinSymbolList_character(eps,2); m
929
Manin Symbol List of weight 2 for Gamma1(4) with character [-1]
930
sage: m.manin_symbol_list()
931
[(0,1), (1,0), (1,1), (1,2), (1,3), (2,1)]
932
sage: m == loads(dumps(m))
933
True
934
"""
935
def __init__(self, character, weight):
936
"""
937
Constructor for objects of class ManinSymbolList_character
938
939
INPUT:
940
941
942
- ``character`` - (DirichletCharacter) the Dirichlet character.
943
944
- ``weight`` - (integer) the weight.
945
946
EXAMPLE::
947
948
sage: eps = DirichletGroup(4).gen(0)
949
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character
950
sage: m = ManinSymbolList_character(eps,2); m
951
Manin Symbol List of weight 2 for Gamma1(4) with character [-1]
952
sage: m.manin_symbol_list()
953
[(0,1), (1,0), (1,1), (1,2), (1,3), (2,1)]
954
955
"""
956
self.__level = character.modulus()
957
self.__P1 = p1list.P1List(self.level())
958
959
# We make a copy of the character *only* to program around what seems
960
# to be a bug in the cPickle module in some obscure case.
961
# If we don't due this, then this doctest fails.
962
# sage: M = ModularSymbols(DirichletGroup(5).0)
963
# sage: loads(dumps(M)) == M
964
965
self.__character = character.__copy__()
966
967
# The list returned from P1List is guaranteed to be sorted.
968
# Thus each list constructed below is also sorted. This is
969
# important since the index function assumes the list is sorted.
970
L = [(i, u, v) for i in range(weight-2+1) \
971
for u, v in self.__P1.list()]
972
self.__list = L
973
ManinSymbolList.__init__(self, weight, L)
974
975
def __repr__(self):
976
"""
977
Standard function returning string representation.
978
979
EXAMPLE::
980
981
sage: eps = DirichletGroup(4).gen(0)
982
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character
983
sage: m = ManinSymbolList_character(eps,2); m
984
Manin Symbol List of weight 2 for Gamma1(4) with character [-1]
985
sage: str(m) # indirect doctest
986
'Manin Symbol List of weight 2 for Gamma1(4) with character [-1]'
987
"""
988
return "Manin Symbol List of weight %s for Gamma1(%s) with character %s"%(
989
self.weight(), self.level(), self.character()._repr_short_())
990
991
def level(self):
992
"""
993
Return the level of this ManinSymbolList.
994
995
OUTPUT:
996
997
``integer`` - the level of the symbols in this list.
998
999
EXAMPLES::
1000
1001
sage: eps = DirichletGroup(4).gen(0)
1002
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character
1003
sage: ManinSymbolList_character(eps,4).level()
1004
4
1005
"""
1006
return self.__level
1007
1008
def apply(self, j, m):
1009
"""
1010
Apply the integer matrix `m=[a,b;c,d]` to the `j`-th Manin symbol.
1011
1012
INPUT:
1013
1014
1015
- ``j`` (integer): the index of the symbol to act on.
1016
1017
- ``m`` (list of ints): `[a,b,c,d]` where `m = [a, b; c, d]` is the matrix to be applied.
1018
1019
1020
OUTPUT:
1021
1022
A list of pairs `(j, c_i)`, where each `c_i` is an
1023
integer, `j` is an integer (the `j`-th Manin symbol), and the
1024
sum `c_i*x_i` is the image of self under the right action
1025
of the matrix `[a,b;c,d]`. Here the right action of
1026
`g=[a,b;c,d]` on a Manin symbol `[P(X,Y),(u,v)]` is by
1027
definition `[P(aX+bY,cX+dY),(u,v)*g]`.
1028
1029
EXAMPLES::
1030
1031
sage: eps = DirichletGroup(4).gen(0)
1032
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character
1033
sage: m = ManinSymbolList_character(eps,4)
1034
sage: m[6]
1035
(1, 0, 1)
1036
sage: m.apply(4, [1,0,0,1])
1037
[(4, 1)]
1038
sage: m.apply(1, [-1,0,0,1])
1039
[(1, -1)]
1040
"""
1041
a, b, c, d = m[0], m[1], m[2], m[3]
1042
i, u, v = self[int(j)]
1043
P = apply_to_monomial(i, self._weight-2, a, b, c, d)
1044
m, s = self.index((0, u*a+v*c, u*b+v*d))
1045
if m == -1 or s == 0:
1046
return []
1047
r = len(self.__P1)
1048
return [(m + r*k, s*P[k]) for k in range(self._weight-2+1)
1049
if P[k] != 0]
1050
1051
def apply_S(self, j):
1052
"""
1053
Apply the matrix `S=[0,1;-1,0]` to the `j`-th Manin symbol.
1054
1055
INPUT:
1056
1057
- ``j`` - (integer) a symbol index.
1058
1059
OUTPUT:
1060
1061
``(k, s)`` where `k` is the index of the symbol obtained by acting
1062
on the `j`'th symbol with `S`, and `s` is the parity of the
1063
`j`'th symbol.
1064
1065
EXAMPLE::
1066
1067
sage: eps = DirichletGroup(4).gen(0)
1068
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character
1069
sage: m = ManinSymbolList_character(eps,2); m
1070
Manin Symbol List of weight 2 for Gamma1(4) with character [-1]
1071
sage: m.apply_S(4)
1072
(2, -1)
1073
sage: [m.apply_S(i) for i in xrange(len(m))]
1074
[(1, 1), (0, -1), (4, 1), (5, -1), (2, -1), (3, 1)]
1075
"""
1076
i, u, v = self._list[j]
1077
k, s = self.index((self._weight-2-i, v, -u))
1078
if i%2==0:
1079
return k, s
1080
else:
1081
return k, -s
1082
1083
def _apply_S_only_0pm1(self):
1084
"""
1085
Return True if the coefficient when applying the S relation is
1086
always 0, 1, or -1. This is useful for optimizing code in
1087
relation_matrix.py.
1088
1089
EXAMPLES::
1090
1091
sage: eps = DirichletGroup(4).gen(0)
1092
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character
1093
sage: ManinSymbolList_character(eps,2)._apply_S_only_0pm1()
1094
True
1095
sage: ManinSymbolList_character(DirichletGroup(13).0,2)._apply_S_only_0pm1()
1096
False
1097
"""
1098
return self.__character.order() <= 2
1099
1100
def apply_I(self, j):
1101
"""
1102
Apply the matrix `I=[-1,0,0,1]` to the `j`-th Manin symbol.
1103
1104
INPUT:
1105
1106
- ``j`` - (integer) a symbol index
1107
1108
OUTPUT:
1109
1110
``(k, s)`` where `k` is the index of the symbol obtained by acting
1111
on the `j`'th symbol with `I`, and `s` is the parity of of the
1112
`j`'th symbol.
1113
1114
EXAMPLE::
1115
1116
sage: eps = DirichletGroup(4).gen(0)
1117
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character
1118
sage: m = ManinSymbolList_character(eps,2); m
1119
Manin Symbol List of weight 2 for Gamma1(4) with character [-1]
1120
sage: m.apply_I(4)
1121
(2, -1)
1122
sage: [m.apply_I(i) for i in xrange(len(m))]
1123
[(0, 1), (1, -1), (4, -1), (3, -1), (2, -1), (5, 1)]
1124
"""
1125
i, u, v = self._list[j]
1126
k, s = self.index((i, -u, v))
1127
if i%2==0:
1128
return k, s
1129
else:
1130
return k, -s
1131
1132
def apply_T(self, j):
1133
"""
1134
Apply the matrix `T=[0,1,-1,-1]` to the j-th Manin symbol.
1135
1136
INPUT:
1137
1138
- ``j`` - (integer) a symbol index.
1139
1140
OUTPUT:
1141
1142
A list of pairs `(j, c_i)`, where each `c_i` is an
1143
integer, `j` is an integer (the `j`-th Manin symbol), and the
1144
sum `c_i*x_i` is the image of self under the right action
1145
of the matrix `T`.
1146
1147
EXAMPLE::
1148
1149
sage: eps = DirichletGroup(4).gen(0)
1150
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character
1151
sage: m = ManinSymbolList_character(eps,2); m
1152
Manin Symbol List of weight 2 for Gamma1(4) with character [-1]
1153
sage: m.apply_T(4)
1154
[(1, -1)]
1155
sage: [m.apply_T(i) for i in xrange(len(m))]
1156
[[(4, 1)], [(0, -1)], [(3, 1)], [(5, 1)], [(1, -1)], [(2, 1)]]
1157
"""
1158
k = self._weight
1159
i, u, v = self._list[j]
1160
u, v, r = self.__P1.normalize_with_scalar(v,-u-v)
1161
r = self.__character(r)
1162
if (k-2) % 2 == 0:
1163
s = r
1164
else:
1165
s = -r
1166
z = []
1167
a = rings.ZZ(k-2-i)
1168
for j in range(k-2-i+1):
1169
m, r = self.index((j, u, v))
1170
z.append((m, s * r * a.binomial(j)))
1171
s *= -1
1172
return z
1173
1174
def apply_TT(self, j):
1175
"""
1176
Apply the matrix `TT=[-1,-1,0,1]` to the `j`-th Manin symbol.
1177
1178
INPUT:
1179
1180
- ``j`` - (integer) a symbol index
1181
1182
OUTPUT:
1183
1184
A list of pairs `(j, c_i)`, where each `c_i` is an
1185
integer, `j` is an integer (the `j`-th Manin symbol), and the
1186
sum `c_i*x_i` is the image of self under the right action
1187
of the matrix `T^2`.
1188
1189
EXAMPLE::
1190
1191
sage: eps = DirichletGroup(4).gen(0)
1192
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character
1193
sage: m = ManinSymbolList_character(eps,2); m
1194
Manin Symbol List of weight 2 for Gamma1(4) with character [-1]
1195
sage: m.apply_TT(4)
1196
[(0, 1)]
1197
sage: [m.apply_TT(i) for i in xrange(len(m))]
1198
[[(1, -1)], [(4, -1)], [(5, 1)], [(2, 1)], [(0, 1)], [(3, 1)]]
1199
"""
1200
k = self._weight
1201
i, u, v = self._list[j]
1202
u, v, r = self.__P1.normalize_with_scalar(-u-v,u)
1203
r = self.__character(r)
1204
if (k-2-i) % 2 == 0:
1205
s = r
1206
else:
1207
s = -r
1208
z = []
1209
a = rings.ZZ(i)
1210
for j in range(i+1):
1211
m, r = self.index((k-2-i+j, u, v))
1212
z.append((m, s * r * a.binomial(j)))
1213
s *= -1
1214
return z
1215
1216
def character(self):
1217
"""
1218
Return the character of this ManinSymbolList_character object.
1219
1220
OUTPUT:
1221
1222
The Dirichlet character of this Manin symbol list.
1223
1224
EXAMPLE::
1225
1226
sage: eps = DirichletGroup(4).gen(0)
1227
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character
1228
sage: m = ManinSymbolList_character(eps,2); m
1229
Manin Symbol List of weight 2 for Gamma1(4) with character [-1]
1230
sage: m.character()
1231
Dirichlet character modulo 4 of conductor 4 mapping 3 |--> -1
1232
1233
"""
1234
return self.__character
1235
1236
def index(self, x):
1237
"""
1238
Returns the index in the list of standard Manin symbols of a
1239
symbol that is equivalent, modulo a scalar `s`, to
1240
``x``. Returns the index and the scalar.
1241
1242
If ``x`` is not in the list, return (-1, 0).
1243
1244
INPUT:
1245
1246
- ``x`` - 3-tuple of integers `(i,u,v)`, defining an element of this list of Manin symbols, which need not be normalized.
1247
1248
OUTPUT:
1249
1250
``(i, s)`` where i (``int``) is the index of the Manin symbol
1251
equivalent to `(i,u,v)` (or -1) and ``s`` is the scalar (an element of
1252
the base field) or the int 0.
1253
1254
EXAMPLE::
1255
1256
sage: eps = DirichletGroup(4).gen(0)
1257
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character
1258
sage: m = ManinSymbolList_character(eps,4); m
1259
Manin Symbol List of weight 4 for Gamma1(4) with character [-1]
1260
sage: [m.index(s.tuple()) for s in m.manin_symbol_list()]
1261
[(0, 1),
1262
(1, 1),
1263
(2, 1),
1264
(3, 1),
1265
...
1266
(16, 1),
1267
(17, 1)]
1268
"""
1269
if self._index.has_key(x):
1270
return self._index[x], 1
1271
x, s= self.normalize(x)
1272
try:
1273
return self._index[x], s
1274
except KeyError:
1275
return -1, 0
1276
1277
def normalize(self, x):
1278
"""
1279
Returns the normalization of the Manin Symbol ``x`` with respect to this
1280
list, together with the normalizing scalar.
1281
1282
INPUT:
1283
1284
- ``x`` - 3-tuple of integers ``(i,u,v)``, defining an element of this
1285
list of Manin symbols, which need not be normalized.
1286
1287
OUTPUT:
1288
1289
``((i,u,v),s)``, where ``(i,u,v)`` is the normalized Manin symbol equivalent
1290
to ``x``, and ``s`` is the normalizing scalar.
1291
1292
EXAMPLE::
1293
1294
sage: eps = DirichletGroup(4).gen(0)
1295
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character
1296
sage: m = ManinSymbolList_character(eps,4); m
1297
Manin Symbol List of weight 4 for Gamma1(4) with character [-1]
1298
sage: [m.normalize(s.tuple()) for s in m.manin_symbol_list()]
1299
[((0, 0, 1), 1),
1300
((0, 1, 0), 1),
1301
((0, 1, 1), 1),
1302
...
1303
((2, 1, 3), 1),
1304
((2, 2, 1), 1)]
1305
"""
1306
u,v,s = self.__P1.normalize_with_scalar(x[1],x[2])
1307
return (x[0],u,v), self.__character(s)
1308
1309
1310
# class x__ManinSymbolList_gamma1(ManinSymbolList):
1311
# r"""
1312
# List of Manin symbols for `\Gamma_1(N)`.
1313
1314
# EXAMPLE::
1315
1316
# sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
1317
# sage: m = ManinSymbolList_gamma0(5,2); m
1318
# Manin Symbol List of weight 2 for Gamma0(5)
1319
# sage: m.manin_symbol_list()
1320
# [(0,1), (1,0), (1,1), (1,2), (1,3), (1,4)]
1321
# sage: m = ManinSymbolList_gamma0(6,4); m
1322
# Manin Symbol List of weight 4 for Gamma0(6)
1323
# sage: len(m)
1324
# 36
1325
# """
1326
# def __init__(self, level, weight):
1327
# r"""
1328
# Constructor for list of Manin symbols for `\Gamma_1(N)`.
1329
# """
1330
# self.__level = level
1331
# self.__G1 = g1list.G1list(self.level())
1332
# # The list returned from P1List is guaranteed to be sorted.
1333
# # Thus each list constructed below is also sorted. This is
1334
# # important since the index function assumes the list is sorted.
1335
# L = [(i, u, v) for i in range(weight-2+1) for \
1336
# u, v in self.__G1.list()]
1337
# ManinSymbolList.__init__(self, weight, L)
1338
1339
# def __repr__(self):
1340
# """
1341
# Returns a string representation for this ManinSymbol list.
1342
# """
1343
# return "Manin Symbol List of weight %s for Gamma1(%s)"%(
1344
# self.weight(), self.level())
1345
1346
# def apply_S(self, j):
1347
# """
1348
# Apply the matrix `S=[0,1,-1,0]` to the j-th Manin symbol.
1349
1350
# INPUT:
1351
1352
# - `j` - (int) a symbol index
1353
1354
# OUTPUT:
1355
1356
# (k, s) where k is the index of the symbol obtained by acting
1357
# on the `j`'th symbol with `S`, and `s` is the parity of of the
1358
# `j`'th symbol.
1359
1360
# """
1361
# i, u, v = self._list[j]
1362
# k = self.index((self._weight-2-i, v, -u))
1363
# if i%2==0:
1364
# return k, 1
1365
# else:
1366
# return k, -1
1367
1368
# def apply_I(self, j):
1369
# """
1370
# Apply the matrix `I=[-1,0,0,1]` to the j-th Manin symbol.
1371
1372
# INPUT:
1373
1374
# - `j` - (int) a symbol index
1375
1376
# OUTPUT:
1377
1378
# (k, s) where k is the index of the symbol obtained by acting
1379
# on the `j`'th symbol with `I`, and `s` is the parity of of the
1380
# `j`'th symbol.
1381
1382
# """
1383
# i, u, v = self._list[j]
1384
# k = self.index((i, -u, v))
1385
# if i%2==0:
1386
# return k, 1
1387
# else:
1388
# return k, -1
1389
1390
# def apply_J(self, j):
1391
# """
1392
# Apply the matrix `J=[-1,0,0,-1]` to the j-th Manin symbol.
1393
1394
# INPUT:
1395
1396
# - `j` - (int) a symbol index
1397
1398
# OUTPUT:
1399
1400
# (k, s) where k is the index of the symbol obtained by acting
1401
# on the `j`'th symbol with `J`, and `s` is 1.
1402
1403
# """
1404
# """
1405
# Apply 2x2 matrix J = [-1,0,0,-1].
1406
# """
1407
# i, u, v = self._list[j]
1408
# N = self.__level
1409
# return self.index((i, -u, -v)), 1
1410
1411
# def apply_T(self, j):
1412
# """
1413
# Apply the matrix `T=[0,1,-1,-1]` to the j-th Manin symbol.
1414
1415
# INPUT:
1416
1417
# - `j` - (int) a symbol index
1418
1419
# OUTPUT: see documentation for apply()
1420
1421
# """
1422
# k = self._weight
1423
# i, u, v = self._list[j]
1424
# u, v = self.__G1.normalize(v,-u-v)
1425
# if (k-2) % 2 == 0:
1426
# s = 1
1427
# else:
1428
# s = -1
1429
# z = []
1430
# for j in range(k-2-i +1):
1431
# m = self.index((j, u, v))
1432
# z.append((m,s*arith.binomial(k-2-i,j)))
1433
# s *= -1
1434
# return z
1435
1436
# def apply_TT(self, j):
1437
# """
1438
# Apply the matrix `TT=[-1,-1,0,1]` to the j-th Manin symbol.
1439
1440
# INPUT:
1441
1442
# - `j` - (int) a symbol index
1443
1444
# OUTPUT: see documentation for apply()
1445
1446
# """
1447
# k = self._weight
1448
# i, u, v = self._list[j]
1449
# u, v = self.__G1.normalize(-u-v,u)
1450
# if (k-2-i) % 2 == 0:
1451
# s = 1
1452
# else:
1453
# s = -1
1454
# z = []
1455
# for j in range(i+1):
1456
# m = self.index((k-2-i+j, u, v))
1457
# z.append((m,s*arith.binomial(i,j)))
1458
# s *= -1
1459
# return z
1460
1461
# def apply(self, j, m):
1462
# """
1463
# Apply the integer matrix `m=[a,b;c,d]` to the `j`-th Manin symbol.
1464
1465
# INPUT:
1466
1467
# - ``j`` - (integer): the index of the symbol to act on.
1468
1469
# - ``m`` - `m = [a, b; c, d]`, a list of 4 integers.
1470
1471
1472
# OUTPUT: a list of pairs (j, c_i), where each c_i is an
1473
# integer, j is an integer (the j-th Manin symbol), and the sum
1474
# c_i\*x_i is the image of self under the right action of the
1475
# matrix [a,b;c,d]. Here the right action of g=[a,b;c,d] on a Manin
1476
# symbol [P(X,Y),(u,v)] is [P(aX+bY,cX+dY),(u,v)\*g].
1477
# """
1478
# a, b, c, d = m[0], m[1], m[2], m[3]
1479
# i, u, v = self[j]
1480
# P = apply_to_monomial(i, self._weight-2, a, b, c, d)
1481
# m = self.index((0, u*a+v*c, u*b+v*d))
1482
# if m == -1:
1483
# return []
1484
# r = len(self.__G1)
1485
# return [(m + r*k, P[k]) for k in range(self._weight-2+1)
1486
# if P[k] != 0]
1487
1488
# def normalize(self, x):
1489
# """
1490
# Returns the normalization of the ModSym x with respect to this
1491
# list.
1492
# """
1493
# u,v = self.__G1.normalize(x[1],x[2])
1494
# return (x[0],u,v)
1495
1496
1497
class ManinSymbol(SageObject):
1498
r"""
1499
A Manin symbol `[X^i\cdot Y^{k-2-i},(u,v)]`.
1500
1501
INPUT:
1502
1503
- ``parent`` - ManinSymbolList.
1504
1505
- ``t`` - a 3-tuple `(i,u,v)` of integers.
1506
1507
EXAMPLES::
1508
1509
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1510
sage: m = ManinSymbolList_gamma0(5,2)
1511
sage: s = ManinSymbol(m,(2,2,3)); s
1512
(2,3)
1513
sage: s == loads(dumps(s))
1514
True
1515
1516
::
1517
1518
sage: m = ManinSymbolList_gamma0(5,8)
1519
sage: s = ManinSymbol(m,(2,2,3)); s
1520
[X^2*Y^4,(2,3)]
1521
1522
"""
1523
def __init__(self, parent, t):
1524
r"""
1525
Create a Manin symbol `[X^i*Y^{k-2-i},(u,v)]`, where
1526
`k` is the weight.
1527
1528
INPUT:
1529
1530
1531
- ``parent`` - ManinSymbolList
1532
1533
- ``t`` - a 3-tuple (i,u,v) of int's.
1534
1535
EXAMPLES::
1536
1537
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1538
sage: m = ManinSymbolList_gamma0(5,2)
1539
sage: s = ManinSymbol(m,(2,2,3)); s
1540
(2,3)
1541
1542
::
1543
1544
sage: m = ManinSymbolList_gamma0(5,8)
1545
sage: s = ManinSymbol(m,(2,2,3)); s
1546
[X^2*Y^4,(2,3)]
1547
1548
"""
1549
if not isinstance(parent, ManinSymbolList):
1550
raise TypeError, "parent (=%s) must be of type ManinSymbolList."%(
1551
parent)
1552
self.__parent = parent
1553
if not isinstance(t, tuple):
1554
raise TypeError, "t (=%s) must be of type tuple."%t
1555
self.__t = t
1556
1557
def tuple(self):
1558
r"""
1559
Return the 3-tuple `(i,u,v)` of this ManinSymbol.
1560
1561
EXAMPLES::
1562
1563
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1564
sage: m = ManinSymbolList_gamma0(5,8)
1565
sage: s = ManinSymbol(m,(2,2,3))
1566
sage: s.tuple()
1567
(2, 2, 3)
1568
1569
"""
1570
return self.__t
1571
1572
def __get_i(self):
1573
"""
1574
Return the `i` field of this ManinSymbol `(i,u,v)`.
1575
1576
EXAMPLES::
1577
1578
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1579
sage: m = ManinSymbolList_gamma0(5,8)
1580
sage: s = ManinSymbol(m,(2,2,3))
1581
sage: s._ManinSymbol__get_i()
1582
2
1583
sage: s.i
1584
2
1585
"""
1586
return self.__t[0]
1587
1588
i = property(__get_i)
1589
def __get_u(self):
1590
"""
1591
Return the `u` field of this ManinSymbol `(i,u,v)`.
1592
1593
EXAMPLES::
1594
1595
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1596
sage: m = ManinSymbolList_gamma0(5,8)
1597
sage: s = ManinSymbol(m,(2,2,3))
1598
sage: s.u # indirect doctest
1599
2
1600
"""
1601
return self.__t[1]
1602
u = property(__get_u)
1603
1604
def __get_v(self):
1605
"""
1606
Return the `v` field of this ManinSymbol `(i,u,v)`.
1607
1608
EXAMPLES::
1609
1610
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1611
sage: m = ManinSymbolList_gamma0(5,8)
1612
sage: s = ManinSymbol(m,(2,2,3))
1613
sage: s.v # indirect doctest
1614
3
1615
"""
1616
return self.__t[2]
1617
v = property(__get_v)
1618
1619
def _repr_(self):
1620
"""
1621
Returns a string representation of this ManinSymbol.
1622
1623
EXAMPLES::
1624
1625
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1626
sage: m = ManinSymbolList_gamma0(5,8)
1627
sage: s = ManinSymbol(m,(2,2,3))
1628
sage: str(s) # indirect doctest
1629
'[X^2*Y^4,(2,3)]'
1630
"""
1631
if self.weight() > 2:
1632
polypart = _print_polypart(self.i, self.weight()-2-self.i)
1633
return "[%s,(%s,%s)]"%\
1634
(polypart, self.u, self.v)
1635
return "(%s,%s)"%(self.u, self.v)
1636
1637
def _latex_(self):
1638
"""
1639
Returns a LaTeX representation of this ManinSymbol.
1640
1641
EXAMPLES::
1642
1643
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1644
sage: m = ManinSymbolList_gamma0(5,8)
1645
sage: s = ManinSymbol(m,(2,2,3))
1646
sage: latex(s) # indirect doctest
1647
[X^2*Y^4,(2,3)]
1648
"""
1649
return self._repr_()
1650
1651
def __cmp__(self, other):
1652
"""
1653
Comparison function for ManinSymbols.
1654
1655
EXAMPLES::
1656
1657
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1658
sage: m = ManinSymbolList_gamma0(5,8)
1659
sage: slist = m.manin_symbol_list()
1660
sage: cmp(slist[10],slist[20])
1661
-1
1662
sage: cmp(slist[20],slist[10])
1663
1
1664
sage: cmp(slist[20],slist[20])
1665
0
1666
"""
1667
if not isinstance(other, ManinSymbol):
1668
return -1
1669
if self.__t == other.__t:
1670
return 0
1671
return cmp(self.tuple(), other.tuple())
1672
1673
def __mul__(self, matrix):
1674
"""
1675
Returns the result of applying a matrix to this ManinSymbol.
1676
1677
1678
EXAMPLES::
1679
1680
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1681
sage: m = ManinSymbolList_gamma0(5,2)
1682
sage: s = ManinSymbol(m,(0,2,3))
1683
sage: s*[1,2,0,1]
1684
(2,7)
1685
1686
::
1687
1688
sage: m = ManinSymbolList_gamma0(5,8)
1689
sage: s = ManinSymbol(m,(2,2,3))
1690
sage: s*[1,2,0,1]
1691
Traceback (most recent call last):
1692
...
1693
NotImplementedError: ModSym * Matrix only implemented in weight 2
1694
"""
1695
if self.weight() > 2:
1696
raise NotImplementedError("ModSym * Matrix only implemented "
1697
"in weight 2")
1698
from sage.matrix.matrix import is_Matrix
1699
if is_Matrix(matrix):
1700
if (not matrix.nrows() == 2) or (not matrix.ncols() == 2):
1701
raise ValueError("matrix(=%s) must be 2x2" % matrix)
1702
matrix = matrix.list()
1703
return ManinSymbol(self.parent(), \
1704
(self.i,
1705
matrix[0]*self.u + matrix[2]*self.v,\
1706
matrix[1]*self.u + matrix[3]*self.v))
1707
raise ArithmeticError("Multiplication of %s by %s not defined." % (self, matrix))
1708
1709
1710
def apply(self, a,b,c,d):
1711
"""
1712
Return the image of self under the matrix `[a,b;c,d]`.
1713
1714
Not implemented for raw ManinSymbol objects, only for members
1715
of ManinSymbolLists.
1716
1717
EXAMPLE::
1718
1719
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1720
sage: m = ManinSymbolList_gamma0(5,2)
1721
sage: m.apply(10,[1,0,0,1]) # not implemented for base class
1722
"""
1723
raise NotImplementedError
1724
1725
def __copy__(self):
1726
"""
1727
Return a copy of this ManinSymbol.
1728
1729
EXAMPLES::
1730
1731
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1732
sage: m = ManinSymbolList_gamma0(5,8)
1733
sage: s = ManinSymbol(m,(2,2,3))
1734
sage: s2 = copy(s)
1735
sage: s2
1736
[X^2*Y^4,(2,3)]
1737
1738
"""
1739
return ManinSymbol(self.parent(), (self.i, self.u, self.v))
1740
1741
def lift_to_sl2z(self, N=None):
1742
r"""
1743
Returns a lift of this Manin Symbol to `SL_2(\mathbb{Z})`.
1744
1745
If this Manin symbol is `(c,d)` and `N` is its level, this
1746
function returns a list `[a,b, c',d']` that defines a 2x2
1747
matrix with determinant 1 and integer entries, such that
1748
`c=c'` (mod `N`) and `d=d'` (mod `N`).
1749
1750
EXAMPLES::
1751
1752
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1753
sage: m = ManinSymbolList_gamma0(5,8)
1754
sage: s = ManinSymbol(m,(2,2,3))
1755
sage: s
1756
[X^2*Y^4,(2,3)]
1757
sage: s.lift_to_sl2z()
1758
[1, 1, 2, 3]
1759
1760
"""
1761
if N is None:
1762
N = self.level()
1763
if N == 1:
1764
return [1,0,0,1]
1765
c = self.u
1766
d = self.v
1767
g, z1, z2 = arith.XGCD(c,d)
1768
1769
# We're lucky: z1*c + z2*d = 1.
1770
if g==1:
1771
return [z2, -z1, c, d]
1772
1773
# Have to try harder.
1774
if c == 0:
1775
c += N;
1776
if d == 0:
1777
d += N;
1778
m = c;
1779
1780
# compute prime-to-d part of m.
1781
while True:
1782
g = arith.GCD(m,d)
1783
if g == 1:
1784
break
1785
m //= g
1786
1787
# compute prime-to-N part of m.
1788
while True:
1789
g = arith.GCD(m,N);
1790
if g == 1:
1791
break
1792
m //= g
1793
d += N*m
1794
g, z1, z2 = arith.XGCD(c,d)
1795
assert g==1
1796
return [z2, -z1, c, d]
1797
1798
def endpoints(self, N=None):
1799
r"""
1800
Returns cusps `alpha`, `beta` such that this Manin symbol, viewed as a
1801
symbol for level `N`, is `X^i*Y^{k-2-i} \{alpha, beta\}`.
1802
1803
EXAMPLES::
1804
1805
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1806
sage: m = ManinSymbolList_gamma0(5,8)
1807
sage: s = ManinSymbol(m,(2,2,3)); s
1808
[X^2*Y^4,(2,3)]
1809
sage: s.endpoints()
1810
(1/3, 1/2)
1811
"""
1812
if N is None:
1813
N = self.parent().level()
1814
else:
1815
N=int(N)
1816
if N < 1:
1817
raise ArithmeticError, "N must be positive"
1818
a,b,c,d = self.lift_to_sl2z()
1819
return cusps.Cusp(b,d), cusps.Cusp(a,c)
1820
1821
def parent(self):
1822
"""
1823
Return the parent of this ManinSymbol.
1824
1825
1826
EXAMPLES::
1827
1828
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1829
sage: m = ManinSymbolList_gamma0(5,8)
1830
sage: s = ManinSymbol(m,(2,2,3))
1831
sage: s.parent()
1832
Manin Symbol List of weight 8 for Gamma0(5)
1833
"""
1834
return self.__parent
1835
1836
def weight(self):
1837
"""
1838
Return the weight of this ManinSymbol.
1839
1840
EXAMPLES::
1841
1842
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1843
sage: m = ManinSymbolList_gamma0(5,8)
1844
sage: s = ManinSymbol(m,(2,2,3))
1845
sage: s.weight()
1846
8
1847
1848
"""
1849
return self.__parent.weight()
1850
1851
def level(self):
1852
"""
1853
Return the level of this ManinSymbol.
1854
1855
EXAMPLES::
1856
1857
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1858
sage: m = ManinSymbolList_gamma0(5,8)
1859
sage: s = ManinSymbol(m,(2,2,3))
1860
sage: s.level()
1861
5
1862
1863
"""
1864
return self.__parent.level()
1865
1866
def modular_symbol_rep(self):
1867
"""
1868
Returns a representation of self as a formal sum of modular
1869
symbols.
1870
1871
The result is not cached.
1872
1873
EXAMPLES::
1874
1875
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1876
sage: m = ManinSymbolList_gamma0(5,8)
1877
sage: s = ManinSymbol(m,(2,2,3))
1878
sage: s.modular_symbol_rep()
1879
144*X^6*{1/3, 1/2} - 384*X^5*Y*{1/3, 1/2} + 424*X^4*Y^2*{1/3, 1/2} - 248*X^3*Y^3*{1/3, 1/2} + 81*X^2*Y^4*{1/3, 1/2} - 14*X*Y^5*{1/3, 1/2} + Y^6*{1/3, 1/2}
1880
1881
1882
"""
1883
# TODO: It would likely be much better to do this slightly more directly
1884
from sage.modular.modsym.modular_symbols import ModularSymbol
1885
x = ModularSymbol(self.__parent, self.i, 0, rings.infinity)
1886
a,b,c,d = self.lift_to_sl2z()
1887
return x.apply([a,b,c,d])
1888
1889
def _print_polypart(i, j):
1890
r"""
1891
Helper function for printing the polynomial part `X^iY^j` of a ManinSymbol.
1892
1893
EXAMPLES::
1894
1895
sage: from sage.modular.modsym.manin_symbols import _print_polypart
1896
sage: _print_polypart(2,3)
1897
'X^2*Y^3'
1898
sage: _print_polypart(2,0)
1899
'X^2'
1900
sage: _print_polypart(0,1)
1901
'Y'
1902
"""
1903
if i > 1:
1904
xpart = "X^%s"%i
1905
elif i == 1:
1906
xpart = "X"
1907
else:
1908
xpart = ""
1909
if j > 1:
1910
ypart = "Y^%s"%j
1911
elif j == 1:
1912
ypart = "Y"
1913
else:
1914
ypart = ""
1915
if len(xpart) > 0 and len(ypart) > 0:
1916
times = "*"
1917
else:
1918
times = ""
1919
if len(xpart + ypart) > 0:
1920
polypart = "%s%s%s"%(xpart, times, ypart)
1921
else:
1922
polypart = ""
1923
return polypart
1924
1925