Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/modular/modsym/relation_matrix.py
4045 views
1
"""
2
Relation matrices for ambient modular symbols spaces
3
4
This file contains functions that are used by the various ambient modular
5
symbols classes to compute presentations of spaces in terms of generators and
6
relations, using the standard methods based on Manin symbols.
7
"""
8
9
#*****************************************************************************
10
# Sage: System for Algebra and Geometry Experimentation
11
#
12
# Copyright (C) 2005 William Stein <[email protected]>
13
#
14
# Distributed under the terms of the GNU General Public License (GPL)
15
#
16
# This code is distributed in the hope that it will be useful,
17
# but WITHOUT ANY WARRANTY; without even the implied warranty of
18
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
# General Public License for more details.
20
#
21
# The full text of the GPL is available at:
22
#
23
# http://www.gnu.org/licenses/
24
#*****************************************************************************
25
26
SPARSE=True
27
28
import sage.matrix.matrix_space as matrix_space
29
import sage.matrix.all
30
import sage.rings.all as rings
31
from sage.misc.search import search
32
33
34
import sage.misc.misc as misc
35
36
import manin_symbols
37
38
39
# S = [0,-1; 1,0]
40
# T = [0,-1; 1,-1],
41
# T^2 = [-1, 1, -1, 0]
42
# I = [-1,0; 0,1]
43
44
45
######################################################################
46
# The following four functions are used to compute the quotient
47
# modulo the S, I, and T relations more efficiently that the generic
48
# code in the relation_matrix file:
49
# modS_relations -- compute the S relations.
50
# modI_quotient -- compute the I relations.
51
# T_relation_matrix -- matrix whose echelon form gives
52
# the quotient by 3-term T relations.
53
# gens_to_basis_matrix -- compute echelon form of 3-term
54
# relation matrix, and read off each
55
# generator in terms of basis.
56
# These four functions are orchestrated in the function
57
# compute_presentation
58
# which is defined below. See the comment at the beginning
59
# of that function for an overall description of the algorithm.
60
######################################################################
61
def modS_relations(syms):
62
"""
63
Compute quotient of Manin symbols by the S relations.
64
65
Here S is the 2x2 matrix [0, -1; 1, 0].
66
67
INPUT:
68
69
70
- ``syms`` - manin_symbols.ManinSymbols
71
72
73
OUTPUT:
74
75
76
- ``rels`` - set of pairs of pairs (j, s), where if
77
mod[i] = (j,s), then x_i = s\*x_j (mod S relations)
78
79
80
EXAMPLES::
81
82
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0
83
sage: from sage.modular.modsym.relation_matrix import modS_relations
84
85
::
86
87
sage: syms = ManinSymbolList_gamma0(2, 4); syms
88
Manin Symbol List of weight 4 for Gamma0(2)
89
sage: modS_relations(syms)
90
set([((3, -1), (4, 1)), ((5, -1), (5, 1)), ((1, 1), (6, 1)), ((0, 1), (7, 1)), ((3, 1), (4, -1)), ((2, 1), (8, 1))])
91
92
::
93
94
sage: syms = ManinSymbolList_gamma0(7, 2); syms
95
Manin Symbol List of weight 2 for Gamma0(7)
96
sage: modS_relations(syms)
97
set([((3, 1), (4, 1)), ((2, 1), (7, 1)), ((5, 1), (6, 1)), ((0, 1), (1, 1))])
98
99
Next we do an example with Gamma1::
100
101
sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma1
102
sage: syms = ManinSymbolList_gamma1(3,2); syms
103
Manin Symbol List of weight 2 for Gamma1(3)
104
sage: modS_relations(syms)
105
set([((3, 1), (6, 1)), ((0, 1), (5, 1)), ((0, 1), (2, 1)), ((3, 1), (4, 1)), ((6, 1), (7, 1)), ((1, 1), (2, 1)), ((1, 1), (5, 1)), ((4, 1), (7, 1))])
106
"""
107
if not isinstance(syms, manin_symbols.ManinSymbolList):
108
raise TypeError, "syms must be a ManinSymbolList"
109
tm = misc.verbose()
110
# We will fill in this set with the relations x_i + s*x_j = 0,
111
# where the notation is as in _sparse_2term_quotient.
112
rels = set()
113
for i in xrange(len(syms)):
114
j, s = syms.apply_S(i)
115
assert j != -1
116
if i < j:
117
rels.add( ((i,1),(j,s)) )
118
else:
119
rels.add( ((j,s),(i,1)) )
120
misc.verbose("finished creating S relations",tm)
121
return rels
122
123
def modI_relations(syms, sign):
124
"""
125
Compute quotient of Manin symbols by the I relations.
126
127
INPUT:
128
129
- ``syms`` - ManinSymbols
130
131
- ``sign`` - int (either -1, 0, or 1)
132
133
OUTPUT:
134
135
- ``rels`` - set of pairs of pairs (j, s), where if
136
mod[i] = (j,s), then x_i = s\*x_j (mod S relations)
137
138
EXAMPLE::
139
140
sage: L = sage.modular.modsym.manin_symbols.ManinSymbolList_gamma1(4, 3)
141
sage: sage.modular.modsym.relation_matrix.modI_relations(L, 1)
142
set([((14, 1), (20, 1)), ((0, 1), (0, -1)), ((7, 1), (7, -1)), ((9, 1), (3, -1)), ((3, 1), (9, -1)), ((16, 1), (22, 1)), ((10, 1), (4, -1)), ((1, 1), (1, -1)), ((19, 1), (19, 1)), ((8, 1), (2, -1)), ((12, 1), (12, 1)), ((20, 1), (14, 1)), ((21, 1), (15, 1)), ((5, 1), (11, -1)), ((15, 1), (21, 1)), ((22, 1), (16, 1)), ((6, 1), (6, -1)), ((2, 1), (8, -1)), ((17, 1), (23, 1)), ((4, 1), (10, -1)), ((18, 1), (18, 1)), ((11, 1), (5, -1)), ((23, 1), (17, 1)), ((13, 1), (13, 1))])
143
144
.. warning::
145
146
We quotient by the involution eta((u,v)) = (-u,v), which has
147
the opposite sign as the involution in Merel's Springer LNM
148
1585 paper! Thus our +1 eigenspace is his -1 eigenspace,
149
etc. We do this for consistency with MAGMA.
150
"""
151
tm = misc.verbose()
152
# We will fill in this set with the relations x_i - sign*s*x_j = 0,
153
# where the notation is as in _sparse_2term_quotient.
154
rels = set()
155
for i in xrange(len(syms)):
156
j, s = syms.apply_I(i)
157
assert j != -1
158
rels.add( ((i,1),(j,-sign*s)) )
159
misc.verbose("finished creating I relations",tm)
160
return rels
161
162
def T_relation_matrix_wtk_g0(syms, mod, field, sparse):
163
r"""
164
Compute a matrix whose echelon form gives the quotient by 3-term T
165
relations. Despite the name, this is used for all modular symbols spaces
166
(including those with character and those for `\Gamma_1` and `\Gamma_H`
167
groups), not just `\Gamma_0`.
168
169
INPUT:
170
171
- ``syms`` - ManinSymbols
172
173
- ``mod`` - list that gives quotient modulo some two-term relations, i.e.,
174
the S relations, and if sign is nonzero, the I relations.
175
176
- ``field`` - base_ring
177
178
- ``sparse`` - (True or False) whether to use sparse rather than dense
179
linear algebra
180
181
OUTPUT: A sparse matrix whose rows correspond to the reduction of
182
the T relations modulo the S and I relations.
183
184
EXAMPLE::
185
186
sage: from sage.modular.modsym.relation_matrix import *
187
sage: L = sage.modular.modsym.manin_symbols.ManinSymbolList_gamma_h(GammaH(36, [17,19]), 2)
188
sage: modS = sparse_2term_quotient(modS_relations(L), 216, QQ)
189
sage: T_relation_matrix_wtk_g0(L, modS, QQ, False)
190
72 x 216 dense matrix over Rational Field
191
sage: T_relation_matrix_wtk_g0(L, modS, GF(17), True)
192
72 x 216 sparse matrix over Finite Field of size 17
193
"""
194
tm = misc.verbose()
195
row = 0
196
entries = {}
197
already_seen = set()
198
w = syms.weight()
199
for i in xrange(len(syms)):
200
if i in already_seen:
201
continue
202
iT_plus_iTT = syms.apply_T(i) + syms.apply_TT(i)
203
j0, s0 = mod[i]
204
v = {j0:s0}
205
for j, s in iT_plus_iTT:
206
if w==2: already_seen.add(j)
207
j0, s0 = mod[j]
208
s0 = s*s0
209
if v.has_key(j0):
210
v[j0] += s0
211
else:
212
v[j0] = s0
213
for j0 in v.keys():
214
entries[(row, j0)] = v[j0]
215
row += 1
216
217
MAT = matrix_space.MatrixSpace(field, row,
218
len(syms), sparse=True)
219
R = MAT(entries)
220
if not sparse:
221
R = R.dense_matrix()
222
misc.verbose("finished (number of rows=%s)"%row, tm)
223
return R
224
225
def gens_to_basis_matrix(syms, relation_matrix, mod, field, sparse):
226
"""
227
Compute echelon form of 3-term relation matrix, and read off each
228
generator in terms of basis.
229
230
INPUT:
231
232
- ``syms`` - a ManinSymbols object
233
234
- ``relation_matrix`` - as output by
235
``__compute_T_relation_matrix(self, mod)``
236
237
- ``mod`` - quotient of modular symbols modulo the
238
2-term S (and possibly I) relations
239
240
- ``field`` - base field
241
242
- ``sparse`` - (bool): whether or not matrix should be
243
sparse
244
245
OUTPUT:
246
247
- ``matrix`` - a matrix whose ith row expresses the
248
Manin symbol generators in terms of a basis of Manin symbols
249
(modulo the S, (possibly I,) and T rels) Note that the entries of
250
the matrix need not be integers.
251
252
- ``list`` - integers i, such that the Manin symbols `x_i` are a basis.
253
254
EXAMPLE::
255
256
sage: from sage.modular.modsym.relation_matrix import *
257
sage: L = sage.modular.modsym.manin_symbols.ManinSymbolList_gamma1(4, 3)
258
sage: modS = sparse_2term_quotient(modS_relations(L), 24, GF(3))
259
sage: gens_to_basis_matrix(L, T_relation_matrix_wtk_g0(L, modS, GF(3), 24), modS, GF(3), True)
260
(24 x 2 sparse matrix over Finite Field of size 3, [13, 23])
261
"""
262
if not sage.matrix.all.is_Matrix(relation_matrix):
263
raise TypeError, "relation_matrix must be a matrix"
264
if not isinstance(mod, list):
265
raise TypeError, "mod must be a list"
266
267
misc.verbose(str(relation_matrix.parent()))
268
269
try:
270
h = relation_matrix.height()
271
except AttributeError:
272
h = 9999999
273
tm = misc.verbose("putting relation matrix in echelon form (height = %s)"%h)
274
if h < 10:
275
A = relation_matrix.echelon_form(algorithm='multimodular', height_guess=1)
276
else:
277
A = relation_matrix.echelon_form()
278
A.set_immutable()
279
tm = misc.verbose('finished echelon', tm)
280
281
tm = misc.verbose("Now creating gens --> basis mapping")
282
283
basis_set = set(A.nonpivots())
284
pivots = A.pivots()
285
286
basis_mod2 = set([j for j,c in mod if c != 0])
287
288
basis_set = basis_set.intersection(basis_mod2)
289
basis = list(basis_set)
290
basis.sort()
291
292
ONE = field(1)
293
294
misc.verbose("done doing setup",tm)
295
296
297
tm = misc.verbose("now forming quotient matrix")
298
M = matrix_space.MatrixSpace(field, len(syms), len(basis), sparse=sparse)
299
300
B = M(0)
301
cols_index = dict([(basis[i], i) for i in range(len(basis))])
302
303
for i in basis_mod2:
304
t, l = search(basis, i)
305
if t:
306
B[i,l] = ONE
307
else:
308
_, r = search(pivots, i) # so pivots[r] = i
309
# Set row i to -(row r of A), but where we only take
310
# the non-pivot columns of A:
311
B._set_row_to_negative_of_row_of_A_using_subset_of_columns(i, A, r, basis, cols_index)
312
313
misc.verbose("done making quotient matrix",tm)
314
315
# The following is very fast (over Q at least).
316
tm = misc.verbose('now filling in the rest of the matrix')
317
k = 0
318
for i in range(len(mod)):
319
j, s = mod[i]
320
if j != i and s != 0: # ignored in the above matrix
321
k += 1
322
B.set_row_to_multiple_of_row(i, j, s)
323
misc.verbose("set %s rows"%k)
324
tm = misc.verbose("time to fill in rest of matrix", tm)
325
326
return B, basis
327
328
def compute_presentation(syms, sign, field, sparse=None):
329
r"""
330
Compute the presentation for self, as a quotient of Manin symbols
331
modulo relations.
332
333
INPUT:
334
335
- ``syms`` - manin_symbols.ManinSymbols
336
337
- ``sign`` - integer (-1, 0, 1)
338
339
- ``field`` - a field
340
341
342
OUTPUT:
343
344
- sparse matrix whose rows give each generator
345
in terms of a basis for the quotient
346
347
- list of integers that give the basis for the
348
quotient
349
350
- mod: list where mod[i]=(j,s) means that x_i
351
= s\*x_j modulo the 2-term S (and possibly I) relations.
352
353
354
ALGORITHM:
355
356
#. Let `S = [0,-1; 1,0], T = [0,-1; 1,-1]`, and
357
`I = [-1,0; 0,1]`.
358
359
#. Let `x_0,\ldots, x_{n-1}` by a list of all
360
non-equivalent Manin symbols.
361
362
#. Form quotient by 2-term S and (possibly) I relations.
363
364
#. Create a sparse matrix `A` with `m` columns,
365
whose rows encode the relations
366
367
.. math::
368
369
[x_i] + [x_i T] + [x_i T^2] = 0.
370
371
372
There are about n such rows. The number of nonzero entries per row
373
is at most 3\*(k-1). Note that we must include rows for *all* i,
374
since even if `[x_i] = [x_j]`, it need not be the case
375
that `[x_i T] = [x_j T]`, since `S` and
376
`T` do not commute. However, in many cases we have an a
377
priori formula for the dimension of the quotient by all these
378
relations, so we can omit many relations and just check that there
379
are enough at the end--if there aren't, we add in more.
380
381
#. Compute the reduced row echelon form of `A` using sparse
382
Gaussian elimination.
383
384
#. Use what we've done above to read off a sparse matrix R that
385
uniquely expresses each of the n Manin symbols in terms of a subset
386
of Manin symbols, modulo the relations. This subset of Manin
387
symbols is a basis for the quotient by the relations.
388
389
390
EXAMPLE::
391
392
sage: L = sage.modular.modsym.manin_symbols.ManinSymbolList_gamma0(8,2)
393
sage: sage.modular.modsym.relation_matrix.compute_presentation(L, 1, GF(9,'a'), True)
394
(
395
[2 0 0]
396
[1 0 0]
397
[0 0 0]
398
[0 2 0]
399
[0 0 0]
400
[0 0 2]
401
[0 0 0]
402
[0 2 0]
403
[0 0 0]
404
[0 1 0]
405
[0 1 0]
406
[0 0 1], [1, 9, 11], [(1, 2), (1, 1), (0, 0), (9, 2), (0, 0), (11, 2), (0, 0), (9, 2), (0, 0), (9, 1), (9, 1), (11, 1)]
407
)
408
"""
409
if sparse is None:
410
if syms.weight() >= 6:
411
sparse = False
412
else:
413
sparse = True
414
R, mod = relation_matrix_wtk_g0(syms, sign, field, sparse)
415
B, basis = gens_to_basis_matrix(syms, R, mod, field, sparse)
416
return B, basis, mod
417
418
def relation_matrix_wtk_g0(syms, sign, field, sparse):
419
r"""
420
Compute the matrix of relations. Despite the name, this is used for all
421
spaces (not just for Gamma0). For a description of the algorithm, see the
422
docstring for ``compute_presentation``.
423
424
INPUT:
425
426
- ``syms``: sage.modular.modsym.manin_symbols.ManinSymbolList object
427
428
- ``sign``: integer (0, 1 or -1)
429
430
- ``field``: the base field (non-field base rings not supported at present)
431
432
- ``sparse``: (True or False) whether to use sparse arithmetic.
433
434
Note that ManinSymbolList objects already have a specific weight, so there
435
is no need for an extra ``weight`` parameter.
436
437
OUTPUT: a pair (R, mod) where
438
439
- R is a matrix as output by ``T_relation_matrix_wtk_g0``
440
441
- mod is a set of 2-term relations as output by ``sparse_2term_quotient``
442
443
EXAMPLE::
444
445
sage: L = sage.modular.modsym.manin_symbols.ManinSymbolList_gamma0(8,2)
446
sage: A = sage.modular.modsym.relation_matrix.relation_matrix_wtk_g0(L, 0, GF(2), True); A
447
(
448
[0 0 0 0 0 0 0 0 1 0 0 0]
449
[0 0 0 0 0 0 0 0 1 1 1 0]
450
[0 0 0 0 0 0 1 0 0 1 1 0]
451
[0 0 0 0 0 0 1 0 0 0 0 0], [(1, 1), (1, 1), (8, 1), (10, 1), (6, 1), (11, 1), (6, 1), (9, 1), (8, 1), (9, 1), (10, 1), (11, 1)]
452
)
453
sage: A[0].is_sparse()
454
True
455
"""
456
rels = modS_relations(syms)
457
if sign != 0:
458
# Let rels = rels union I relations.
459
rels.update(modI_relations(syms,sign))
460
461
if syms._apply_S_only_0pm1() and rings.is_RationalField(field):
462
import relation_matrix_pyx
463
mod = relation_matrix_pyx.sparse_2term_quotient_only_pm1(rels, len(syms))
464
else:
465
mod = sparse_2term_quotient(rels, len(syms), field)
466
467
R = T_relation_matrix_wtk_g0(syms, mod, field, sparse)
468
return R, mod
469
470
def sparse_2term_quotient(rels, n, F):
471
r"""
472
Performs Sparse Gauss elimination on a matrix all of whose columns
473
have at most 2 nonzero entries. We use an obvious algorithm, which
474
runs fast enough. (Typically making the list of relations takes
475
more time than computing this quotient.) This algorithm is more
476
subtle than just "identify symbols in pairs", since complicated
477
relations can cause generators to surprisingly equal 0.
478
479
INPUT:
480
481
482
- ``rels`` - set of pairs ((i,s), (j,t)). The pair
483
represents the relation s\*x_i + t\*x_j = 0, where the i, j must
484
be Python int's.
485
486
- ``n`` - int, the x_i are x_0, ..., x_n-1.
487
488
- ``F`` - base field
489
490
491
OUTPUT:
492
493
494
- ``mod`` - list such that mod[i] = (j,s), which means
495
that x_i is equivalent to s\*x_j, where the x_j are a basis for
496
the quotient.
497
498
499
EXAMPLE: We quotient out by the relations
500
501
.. math::
502
503
3*x0 - x1 = 0,\qquad x1 + x3 = 0,\qquad x2 + x3 = 0,\qquad x4 - x5 = 0
504
505
506
to get
507
508
::
509
510
sage: v = [((int(0),3), (int(1),-1)), ((int(1),1), (int(3),1)), ((int(2),1),(int(3),1)), ((int(4),1),(int(5),-1))]
511
sage: rels = set(v)
512
sage: n = 6
513
sage: from sage.modular.modsym.relation_matrix import sparse_2term_quotient
514
sage: sparse_2term_quotient(rels, n, QQ)
515
[(3, -1/3), (3, -1), (3, -1), (3, 1), (5, 1), (5, 1)]
516
"""
517
if not isinstance(rels, set):
518
raise TypeError, "rels must be a set"
519
n = int(n)
520
if not isinstance(F, rings.Ring):
521
raise TypeError, "F must be a ring."
522
523
tm = misc.verbose("Starting sparse 2-term quotient...")
524
free = range(n)
525
ONE = F(1)
526
ZERO = F(0)
527
coef = [ONE for i in xrange(n)]
528
related_to_me = [[] for i in xrange(n)]
529
for v0, v1 in rels:
530
c0 = coef[v0[0]] * F(v0[1])
531
c1 = coef[v1[0]] * F(v1[1])
532
533
# Mod out by the following relation:
534
#
535
# c0*free[v0[0]] + c1*free[v1[0]] = 0.
536
#
537
die = None
538
if c0 == ZERO and c1 == ZERO:
539
pass
540
elif c0 == ZERO and c1 != ZERO: # free[v1[0]] --> 0
541
die = free[v1[0]]
542
elif c1 == ZERO and c0 != ZERO:
543
die = free[v0[0]]
544
elif free[v0[0]] == free[v1[0]]:
545
if c0 + c1 != 0:
546
# all xi equal to free[v0[0]] must now equal to zero.
547
die = free[v0[0]]
548
else: # x1 = -c1/c0 * x2.
549
x = free[v0[0]]
550
free[x] = free[v1[0]]
551
coef[x] = -c1/c0
552
for i in related_to_me[x]:
553
free[i] = free[x]
554
coef[i] *= coef[x]
555
related_to_me[free[v1[0]]].append(i)
556
related_to_me[free[v1[0]]].append(x)
557
if die is not None:
558
for i in related_to_me[die]:
559
free[i] = 0
560
coef[i] = ZERO
561
free[die] = 0
562
coef[die] = ZERO
563
564
mod = [(free[i], coef[i]) for i in xrange(len(free))]
565
misc.verbose("finished",tm)
566
return mod
567
568
569
570
#############################################################
571
## The following two sparse_relation_matrix are not
572
## used by any modular symbols code. They're here for
573
## historical reasons, and can probably be safely deleted.
574
#############################################################
575
576
## def sparse_relation_matrix_wt2_g0n(list, field, sign=0):
577
## r"""
578
## Create the sparse relation matrix over $\Q$ for Manin symbols of
579
## weight 2 on $\Gamma_0(N)$, with given sign.
580
581
## INPUT:
582
## list -- sage.modular.modsym.p1list.List
583
## OUTPUT:
584
## A -- a sparse matrix that gives the 2-term and 3-term
585
## relations between Manin symbols.
586
587
## MORE DETAILS:
588
## \begin{enumerate}
589
## \item Create an empty sparse matrix.
590
591
## \item Let $S = [0,-1; 1,0]$, $T = [0,-1; 1,-1]$, $I = [-1,0; 0,1]$.
592
593
## \item Enter the T relations:
594
## $$
595
## x + x T = 0.
596
## $$
597
## Remove x and x*T from reps to consider.
598
599
## \item If sign $\neq 0$, enter the I relations:
600
## $$
601
## x - sign\cdot x\cdot I = 0.
602
## $$
603
604
## \item Enter the S relations in the matrix:
605
## $$
606
## x + x S + x S^2 = 0
607
## $$
608
## by putting 1s at cols corresponding to $x$, $x S$, and $x S^2$.
609
## Remove $x$, $x S$, and $x S^2$ from list of reps to consider.
610
## \end{enumerate}
611
## """
612
## ZERO = field(0)
613
## ONE = field(1)
614
## TWO = field(2)
615
616
## # This will be a dict of the entries of the sparse matrix, where
617
## # the notation is entries[(i,j)]=x.
618
## entries = {}
619
620
## # The current row
621
## row = 0
622
623
## ## The S relations
624
## already_seen= set([])
625
## for i in range(len(list)):
626
## if i in already_seen:
627
## continue
628
## u,v = list[i]
629
## j = list.index(v,-u)
630
## already_seen.add(j)
631
## if i != j:
632
## entries[(row,i)] = ONE
633
## entries[(row,j)] = ONE
634
## else:
635
## entries[(row,i)] = TWO
636
## row += 1
637
## number_of_S_relations = row
638
## misc.verbose("There were %s S relations"%(number_of_S_relations))
639
640
## ## The eta relations:
641
## ## eta((u,v)) = -(-u,v)
642
## if sign != 0:
643
## SIGN = field(sign)
644
## already_seen= set([])
645
## for i in range(len(list)):
646
## if i in already_seen:
647
## continue
648
## u, v = list[i]
649
## j = list.index(-u,v)
650
## already_seen.add(j)
651
## if i != j:
652
## entries[(row,i)] = ONE
653
## entries[(row,j)] = SIGN*ONE
654
## else:
655
## entries[(row,i)] = ONE + SIGN
656
## row += 1
657
## number_of_I_relations = row - number_of_S_relations
658
## misc.verbose("There were %s I relations"%(number_of_I_relations))
659
660
## ## The three-term T relations
661
## already_seen = set([])
662
## for i in range(len(list)):
663
## if i in already_seen:
664
## continue
665
## u,v = list[i]
666
## j1 = list.index(v,-u-v)
667
## already_seen.add(j1)
668
## j2 = list.index(-u-v,u)
669
## already_seen.add(j2)
670
## v = {i:ZERO, j1:ZERO, j2:ZERO}
671
## v[i] = ONE
672
## v[j1] += ONE
673
## v[j2] += ONE
674
## for x in v.keys():
675
## entries[(row,x)] = v[x]
676
## row += 1
677
678
## number_of_T_relations = row - number_of_I_relations - number_of_S_relations
679
## misc.verbose("There were %s T relations"%(number_of_T_relations))
680
681
## M = matrix_space.MatrixSpace(RationalField(), row,
682
## len(list), sparse=True)
683
## if not sparse:
684
## M = M.dense_matrix()
685
686
## return M(entries)
687
688
## def sparse_relation_matrix_wtk_g0n(M, field, sign=0):
689
## r"""
690
## Create the sparse relation matrix over $\Q$ for Manin symbols of
691
## given weight on $\Gamma_0(N)$, with given sign.
692
693
## INPUT:
694
## M -- manin_symbols.ManinSymbolList
695
## field -- base field
696
## weight -- the weight, an integer > 2
697
## sign -- element of [-1,0,1]
698
699
## OUTPUT:
700
## A -- a SparseMatrix that gives the 2-term and 3-term relations
701
## between Manin symbols.
702
703
## MORE DETAILS:
704
## \begin{enumerate}
705
## \item Create an empty sparse matrix.
706
707
## \item Let $S = [0,-1; 1,0]$, $T = [0,-1; 1,-1]$, $I = [-1,0; 0,1]$.
708
709
## \item Enter the $T$ relations:
710
## $$ x + x*T = 0 $$
711
## Remove $x$ and $x T$ from reps to consider.
712
713
## \item If sign $\neq 0$, enter the I relations:
714
## $$
715
## x + sign x I = 0.
716
## $$
717
718
## \item Enter the $S$ relations in the matrix:
719
## $$
720
## x + x S + x S^2 = 0
721
## $$
722
## by putting 1's at cols corresponding to $x$, $x S$, and $x S^2$.
723
## Remove x from list of reps to consider.
724
## \end{enumerate}
725
## """
726
## weight = M.weight()
727
## if not (isinstance(weight, int) and weight > 2):
728
## raise TypeError, "weight must be an int > 2"
729
730
## ZERO = field(0)
731
## ONE = field(1)
732
## TWO = field(2)
733
734
## # This will be a dict of the entries of the sparse matrix, where
735
## # the notation is entries[(i,j)]=x.
736
## entries = {}
737
738
## # The current row
739
## row = 0
740
741
## # The list of Manin symbol triples (i,u,v)
742
## n = len(M)
743
744
## ## The S relations
745
## already_seen= set([])
746
## for i in xrange(n):
747
## if i in already_seen:
748
## continue
749
## j, s = M.apply_S(i)
750
## already_seen.add(j)
751
## if i != j:
752
## entries[(row,i)] = ONE
753
## entries[(row,j)] = field(s)
754
## else:
755
## entries[(row,i)] = ONE+field(s)
756
## row += 1
757
## number_of_S_relations = row
758
## misc.verbose("There were %s S relations"%(number_of_S_relations))
759
## cnt = row
760
## ## The I relations
761
## if sign != 0:
762
## SIGN = field(sign)
763
## already_seen= set([])
764
## for i in xrange(n):
765
## if i in already_seen:
766
## continue
767
## j, s = M.apply_I(i)
768
## already_seen.add(j)
769
## if i != j:
770
## entries[(row,i)] = ONE
771
## entries[(row,j)] = -SIGN*field(s)
772
## else:
773
## entries[(row,i)] = ONE-SIGN*field(s)
774
## row += 1
775
## number_of_I_relations = row - number_of_S_relations
776
## misc.verbose("There were %s I relations"%(number_of_I_relations))
777
## cnt = row
778
779
## ## The T relations
780
## already_seen = set([])
781
## for i in xrange(n):
782
## if i in already_seen:
783
## continue
784
## iT_plus_iTT = M.apply_T(i) + M.apply_TT(i)
785
## v = {i:ONE}
786
## for j, s in iT_plus_iTT:
787
## if v.has_key(j):
788
## v[j] += field(s)
789
## else:
790
## v[j] = field(s)
791
## for j in v.keys():
792
## entries[(row, j)] = v[j]
793
## row += 1
794
795
796