Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/modular/modsym/manin_symbols.py
4097 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
"""
1696
if self.weight() > 2:
1697
raise NotImplementedError, "ModSym * Matrix only implemented in weight 2"
1698
if sage.matrix.all.is_Matrix(matrix):
1699
assert matrix.nrows() == 2 and matrix.ncols()==2, "matrix must be 2x2"
1700
matrix = matrix.list()
1701
return ManinSymbol(self.parent(), \
1702
(self.i,
1703
matrix[0]*self.u + matrix[2]*self.v,\
1704
matrix[1]*self.u + matrix[3]*self.v))
1705
raise ArithmeticError, "Multiplication of %s by %s not defined."%(self, matrix)
1706
1707
1708
def apply(self, a,b,c,d):
1709
"""
1710
Return the image of self under the matrix `[a,b;c,d]`.
1711
1712
Not implemented for raw ManinSymbol objects, only for members
1713
of ManinSymbolLists.
1714
1715
EXAMPLE::
1716
1717
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1718
sage: m = ManinSymbolList_gamma0(5,2)
1719
sage: m.apply(10,[1,0,0,1]) # not implemented for base class
1720
"""
1721
raise NotImplementedError
1722
1723
def __copy__(self):
1724
"""
1725
Return a copy of this ManinSymbol.
1726
1727
EXAMPLES::
1728
1729
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1730
sage: m = ManinSymbolList_gamma0(5,8)
1731
sage: s = ManinSymbol(m,(2,2,3))
1732
sage: s2 = copy(s)
1733
sage: s2
1734
[X^2*Y^4,(2,3)]
1735
1736
"""
1737
return ManinSymbol(self.parent(), (self.i, self.u, self.v))
1738
1739
def lift_to_sl2z(self, N=None):
1740
r"""
1741
Returns a lift of this Manin Symbol to `SL_2(\mathbb{Z})`.
1742
1743
If this Manin symbol is `(c,d)` and `N` is its level, this
1744
function returns a list `[a,b, c',d']` that defines a 2x2
1745
matrix with determinant 1 and integer entries, such that
1746
`c=c'` (mod `N`) and `d=d'` (mod `N`).
1747
1748
EXAMPLES::
1749
1750
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1751
sage: m = ManinSymbolList_gamma0(5,8)
1752
sage: s = ManinSymbol(m,(2,2,3))
1753
sage: s
1754
[X^2*Y^4,(2,3)]
1755
sage: s.lift_to_sl2z()
1756
[1, 1, 2, 3]
1757
1758
"""
1759
if N is None:
1760
N = self.level()
1761
if N == 1:
1762
return [1,0,0,1]
1763
c = self.u
1764
d = self.v
1765
g, z1, z2 = arith.XGCD(c,d)
1766
1767
# We're lucky: z1*c + z2*d = 1.
1768
if g==1:
1769
return [z2, -z1, c, d]
1770
1771
# Have to try harder.
1772
if c == 0:
1773
c += N;
1774
if d == 0:
1775
d += N;
1776
m = c;
1777
1778
# compute prime-to-d part of m.
1779
while True:
1780
g = arith.GCD(m,d)
1781
if g == 1:
1782
break
1783
m //= g
1784
1785
# compute prime-to-N part of m.
1786
while True:
1787
g = arith.GCD(m,N);
1788
if g == 1:
1789
break
1790
m //= g
1791
d += N*m
1792
g, z1, z2 = arith.XGCD(c,d)
1793
assert g==1
1794
return [z2, -z1, c, d]
1795
1796
def endpoints(self, N=None):
1797
r"""
1798
Returns cusps `alpha`, `beta` such that this Manin symbol, viewed as a
1799
symbol for level `N`, is `X^i*Y^{k-2-i} \{alpha, beta\}`.
1800
1801
EXAMPLES::
1802
1803
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1804
sage: m = ManinSymbolList_gamma0(5,8)
1805
sage: s = ManinSymbol(m,(2,2,3)); s
1806
[X^2*Y^4,(2,3)]
1807
sage: s.endpoints()
1808
(1/3, 1/2)
1809
"""
1810
if N is None:
1811
N = self.parent().level()
1812
else:
1813
N=int(N)
1814
if N < 1:
1815
raise ArithmeticError, "N must be positive"
1816
a,b,c,d = self.lift_to_sl2z()
1817
return cusps.Cusp(b,d), cusps.Cusp(a,c)
1818
1819
def parent(self):
1820
"""
1821
Return the parent of this ManinSymbol.
1822
1823
1824
EXAMPLES::
1825
1826
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1827
sage: m = ManinSymbolList_gamma0(5,8)
1828
sage: s = ManinSymbol(m,(2,2,3))
1829
sage: s.parent()
1830
Manin Symbol List of weight 8 for Gamma0(5)
1831
"""
1832
return self.__parent
1833
1834
def weight(self):
1835
"""
1836
Return the weight of this ManinSymbol.
1837
1838
EXAMPLES::
1839
1840
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1841
sage: m = ManinSymbolList_gamma0(5,8)
1842
sage: s = ManinSymbol(m,(2,2,3))
1843
sage: s.weight()
1844
8
1845
1846
"""
1847
return self.__parent.weight()
1848
1849
def level(self):
1850
"""
1851
Return the level of this ManinSymbol.
1852
1853
EXAMPLES::
1854
1855
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1856
sage: m = ManinSymbolList_gamma0(5,8)
1857
sage: s = ManinSymbol(m,(2,2,3))
1858
sage: s.level()
1859
5
1860
1861
"""
1862
return self.__parent.level()
1863
1864
def modular_symbol_rep(self):
1865
"""
1866
Returns a representation of self as a formal sum of modular
1867
symbols.
1868
1869
The result is not cached.
1870
1871
EXAMPLES::
1872
1873
sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0
1874
sage: m = ManinSymbolList_gamma0(5,8)
1875
sage: s = ManinSymbol(m,(2,2,3))
1876
sage: s.modular_symbol_rep()
1877
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}
1878
1879
1880
"""
1881
# TODO: It would likely be much better to do this slightly more directly
1882
from sage.modular.modsym.modular_symbols import ModularSymbol
1883
x = ModularSymbol(self.__parent, self.i, 0, rings.infinity)
1884
a,b,c,d = self.lift_to_sl2z()
1885
return x.apply([a,b,c,d])
1886
1887
def _print_polypart(i, j):
1888
r"""
1889
Helper function for printing the polynomial part `X^iY^j` of a ManinSymbol.
1890
1891
EXAMPLES::
1892
1893
sage: from sage.modular.modsym.manin_symbols import _print_polypart
1894
sage: _print_polypart(2,3)
1895
'X^2*Y^3'
1896
sage: _print_polypart(2,0)
1897
'X^2'
1898
sage: _print_polypart(0,1)
1899
'Y'
1900
"""
1901
if i > 1:
1902
xpart = "X^%s"%i
1903
elif i == 1:
1904
xpart = "X"
1905
else:
1906
xpart = ""
1907
if j > 1:
1908
ypart = "Y^%s"%j
1909
elif j == 1:
1910
ypart = "Y"
1911
else:
1912
ypart = ""
1913
if len(xpart) > 0 and len(ypart) > 0:
1914
times = "*"
1915
else:
1916
times = ""
1917
if len(xpart + ypart) > 0:
1918
polypart = "%s%s%s"%(xpart, times, ypart)
1919
else:
1920
polypart = ""
1921
return polypart
1922
1923