Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/modular/modform/eisenstein_submodule.py
4057 views
1
# -*- coding: utf-8 -*-
2
"""
3
The Eisenstein Subspace
4
"""
5
6
from sage.structure.all import Sequence
7
from sage.misc.all import verbose
8
import sage.rings.all as rings
9
from sage.categories.all import Objects
10
from sage.matrix.all import Matrix
11
12
13
import eis_series
14
import element
15
import submodule
16
17
class EisensteinSubmodule(submodule.ModularFormsSubmodule):
18
"""
19
The Eisenstein submodule of an ambient space of modular forms.
20
"""
21
def __init__(self, ambient_space):
22
"""
23
Return the Eisenstein submodule of the given space.
24
25
EXAMPLES::
26
27
sage: E = ModularForms(23,4).eisenstein_subspace() ## indirect doctest
28
sage: E
29
Eisenstein subspace of dimension 2 of Modular Forms space of dimension 7 for Congruence Subgroup Gamma0(23) of weight 4 over Rational Field
30
sage: E == loads(dumps(E))
31
True
32
"""
33
verbose('creating eisenstein submodule of %s'%ambient_space)
34
d = ambient_space._dim_eisenstein()
35
V = ambient_space.module()
36
n = V.dimension()
37
self._start_position = int(n - d)
38
S = V.submodule([V.gen(i) for i in range(n-d,n)], check=False,
39
already_echelonized=True)
40
submodule.ModularFormsSubmodule.__init__(self, ambient_space, S)
41
42
def _repr_(self):
43
"""
44
Return the string representation of self.
45
46
EXAMPLES::
47
48
sage: E = ModularForms(23,4).eisenstein_subspace() ## indirect doctest
49
sage: E._repr_()
50
'Eisenstein subspace of dimension 2 of Modular Forms space of dimension 7 for Congruence Subgroup Gamma0(23) of weight 4 over Rational Field'
51
"""
52
return "Eisenstein subspace of dimension %s of %s"%(self.dimension(), self.ambient_module())
53
54
def eisenstein_submodule(self):
55
"""
56
Return the Eisenstein submodule of self.
57
(Yes, this is just self.)
58
59
EXAMPLES::
60
61
sage: E = ModularForms(23,4).eisenstein_subspace()
62
sage: E == E.eisenstein_submodule()
63
True
64
"""
65
return self
66
67
def modular_symbols(self, sign=0):
68
r"""
69
Return the corresponding space of modular symbols with given sign. This
70
will fail in weight 1.
71
72
.. warning::
73
74
If sign != 0, then the space of modular symbols will, in general,
75
only correspond to a *subspace* of this space of modular forms.
76
This can be the case for both sign +1 or -1.
77
78
EXAMPLES::
79
80
sage: E = ModularForms(11,2).eisenstein_submodule()
81
sage: M = E.modular_symbols(); M
82
Modular Symbols subspace of dimension 1 of Modular Symbols space
83
of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field
84
sage: M.sign()
85
0
86
87
sage: M = E.modular_symbols(sign=-1); M
88
Modular Symbols subspace of dimension 0 of Modular Symbols space of
89
dimension 1 for Gamma_0(11) of weight 2 with sign -1 over Rational Field
90
91
sage: E = ModularForms(1,12).eisenstein_submodule()
92
sage: E.modular_symbols()
93
Modular Symbols subspace of dimension 1 of Modular Symbols space of
94
dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field
95
96
sage: eps = DirichletGroup(13).0
97
sage: E = EisensteinForms(eps^2, 2)
98
sage: E.modular_symbols()
99
Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 4 and level 13, weight 2, character [zeta6], sign 0, over Cyclotomic Field of order 6 and degree 2
100
101
sage: E = EisensteinForms(eps, 1); E
102
Eisenstein subspace of dimension 1 of Modular Forms space of dimension 1, character [zeta12] and weight 1 over Cyclotomic Field of order 12 and degree 4
103
sage: E.modular_symbols()
104
Traceback (most recent call last):
105
...
106
ValueError: the weight must be at least 2
107
"""
108
try:
109
return self.__modular_symbols[sign]
110
except AttributeError:
111
self.__modular_symbols = {}
112
except KeyError:
113
pass
114
A = self.ambient_module()
115
S = A.modular_symbols(sign).eisenstein_submodule()
116
self.__modular_symbols[sign] = S
117
return S
118
119
class EisensteinSubmodule_params(EisensteinSubmodule):
120
def parameters(self):
121
r"""
122
Return a list of parameters for each Eisenstein series
123
spanning self. That is, for each such series, return a triple
124
of the form (`\psi`, `\chi`, level), where `\psi` and `\chi`
125
are the characters defining the Eisenstein series, and level
126
is the smallest level at which this series occurs.
127
128
EXAMPLES::
129
130
sage: ModularForms(24,2).eisenstein_submodule().parameters()
131
[(Dirichlet character modulo 24 of conductor 1 mapping 7 |--> 1, 13 |--> 1, 17 |--> 1, Dirichlet character modulo 24 of conductor 1 mapping 7 |--> 1, 13 |--> 1, 17 |--> 1, 2),
132
...
133
Dirichlet character modulo 24 of conductor 1 mapping 7 |--> 1, 13 |--> 1, 17 |--> 1, 24)]
134
sage: EisensteinForms(12,6).parameters()[-1]
135
(Dirichlet character modulo 12 of conductor 1 mapping 7 |--> 1, 5 |--> 1, Dirichlet character modulo 12 of conductor 1 mapping 7 |--> 1, 5 |--> 1, 12)
136
137
sage: pars = ModularForms(DirichletGroup(24).0,3).eisenstein_submodule().parameters()
138
sage: [(x[0].values_on_gens(),x[1].values_on_gens(),x[2]) for x in pars]
139
[((1, 1, 1), (-1, 1, 1), 1),
140
((1, 1, 1), (-1, 1, 1), 2),
141
((1, 1, 1), (-1, 1, 1), 3),
142
((1, 1, 1), (-1, 1, 1), 6),
143
((-1, 1, 1), (1, 1, 1), 1),
144
((-1, 1, 1), (1, 1, 1), 2),
145
((-1, 1, 1), (1, 1, 1), 3),
146
((-1, 1, 1), (1, 1, 1), 6)]
147
sage: EisensteinForms(DirichletGroup(24).0,1).parameters()
148
[(Dirichlet character modulo 24 of conductor 1 mapping 7 |--> 1, 13 |--> 1, 17 |--> 1, Dirichlet character modulo 24 of conductor 4 mapping 7 |--> -1, 13 |--> 1, 17 |--> 1, 1), (Dirichlet character modulo 24 of conductor 1 mapping 7 |--> 1, 13 |--> 1, 17 |--> 1, Dirichlet character modulo 24 of conductor 4 mapping 7 |--> -1, 13 |--> 1, 17 |--> 1, 2), (Dirichlet character modulo 24 of conductor 1 mapping 7 |--> 1, 13 |--> 1, 17 |--> 1, Dirichlet character modulo 24 of conductor 4 mapping 7 |--> -1, 13 |--> 1, 17 |--> 1, 3), (Dirichlet character modulo 24 of conductor 1 mapping 7 |--> 1, 13 |--> 1, 17 |--> 1, Dirichlet character modulo 24 of conductor 4 mapping 7 |--> -1, 13 |--> 1, 17 |--> 1, 6)]
149
"""
150
try:
151
return self.__parameters
152
except AttributeError:
153
char = self._parameters_character()
154
if char is None:
155
P = eis_series.compute_eisenstein_params(self.level(), self.weight())
156
else:
157
P = eis_series.compute_eisenstein_params(char, self.weight())
158
self.__parameters = P
159
return P
160
161
def new_submodule(self, p=None):
162
r"""
163
Return the new submodule of self.
164
165
EXAMPLE::
166
167
sage: e = EisensteinForms(Gamma0(225), 2).new_submodule(); e
168
Modular Forms subspace of dimension 3 of Modular Forms space of dimension 42 for Congruence Subgroup Gamma0(225) of weight 2 over Rational Field
169
sage: e.basis()
170
[
171
q + O(q^6),
172
q^2 + O(q^6),
173
q^4 + O(q^6)
174
]
175
"""
176
177
if p is not None: raise NotImplementedError
178
return self.submodule([self(x) for x in self._compute_q_expansion_basis(self.sturm_bound(), new=True)], check=False)
179
180
def _parameters_character(self):
181
"""
182
Return the character defining self.
183
184
EXAMPLES::
185
186
sage: EisensteinForms(DirichletGroup(33).1,5)._parameters_character()
187
Dirichlet character modulo 33 of conductor 11 mapping 23 |--> 1, 13 |--> zeta10
188
"""
189
return self.character()
190
191
def change_ring(self, base_ring):
192
"""
193
Return self as a module over base_ring.
194
195
EXAMPLES::
196
197
sage: E = EisensteinForms(12,2) ; E
198
Eisenstein subspace of dimension 5 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(12) of weight 2 over Rational Field
199
sage: E.basis()
200
[
201
1 + O(q^6),
202
q + 6*q^5 + O(q^6),
203
q^2 + O(q^6),
204
q^3 + O(q^6),
205
q^4 + O(q^6)
206
]
207
sage: E.change_ring(GF(5))
208
Eisenstein subspace of dimension 5 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(12) of weight 2 over Finite Field of size 5
209
sage: E.change_ring(GF(5)).basis()
210
[
211
1 + O(q^6),
212
q + q^5 + O(q^6),
213
q^2 + O(q^6),
214
q^3 + O(q^6),
215
q^4 + O(q^6)
216
]
217
"""
218
if base_ring == self.base_ring():
219
return self
220
A = self.ambient_module()
221
B = A.change_ring(base_ring)
222
return B.eisenstein_submodule()
223
224
def eisenstein_series(self):
225
"""
226
Return the Eisenstein series that span this space (over the
227
algebraic closure).
228
229
EXAMPLES::
230
231
sage: EisensteinForms(11,2).eisenstein_series()
232
[
233
5/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6)
234
]
235
sage: EisensteinForms(1,4).eisenstein_series()
236
[
237
1/240 + q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6)
238
]
239
sage: EisensteinForms(1,24).eisenstein_series()
240
[
241
236364091/131040 + q + 8388609*q^2 + 94143178828*q^3 + 70368752566273*q^4 + 11920928955078126*q^5 + O(q^6)
242
]
243
sage: EisensteinForms(5,4).eisenstein_series()
244
[
245
1/240 + q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6),
246
1/240 + q^5 + O(q^6)
247
]
248
sage: EisensteinForms(13,2).eisenstein_series()
249
[
250
1/2 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6)
251
]
252
253
sage: E = EisensteinForms(Gamma1(7),2)
254
sage: E.set_precision(4)
255
sage: E.eisenstein_series()
256
[
257
1/4 + q + 3*q^2 + 4*q^3 + O(q^4),
258
1/7*zeta6 - 3/7 + q + (-2*zeta6 + 1)*q^2 + (3*zeta6 - 2)*q^3 + O(q^4),
259
q + (-zeta6 + 2)*q^2 + (zeta6 + 2)*q^3 + O(q^4),
260
-1/7*zeta6 - 2/7 + q + (2*zeta6 - 1)*q^2 + (-3*zeta6 + 1)*q^3 + O(q^4),
261
q + (zeta6 + 1)*q^2 + (-zeta6 + 3)*q^3 + O(q^4)
262
]
263
264
sage: eps = DirichletGroup(13).0^2
265
sage: ModularForms(eps,2).eisenstein_series()
266
[
267
-7/13*zeta6 - 11/13 + q + (2*zeta6 + 1)*q^2 + (-3*zeta6 + 1)*q^3 + (6*zeta6 - 3)*q^4 - 4*q^5 + O(q^6),
268
q + (zeta6 + 2)*q^2 + (-zeta6 + 3)*q^3 + (3*zeta6 + 3)*q^4 + 4*q^5 + O(q^6)
269
]
270
271
sage: M = ModularForms(19,3).eisenstein_subspace()
272
sage: M.eisenstein_series()
273
[
274
]
275
276
sage: M = ModularForms(DirichletGroup(13).0, 1)
277
sage: M.eisenstein_series()
278
[
279
-1/13*zeta12^3 + 6/13*zeta12^2 + 4/13*zeta12 + 2/13 + q + (zeta12 + 1)*q^2 + zeta12^2*q^3 + (zeta12^2 + zeta12 + 1)*q^4 + (-zeta12^3 + 1)*q^5 + O(q^6)
280
]
281
282
sage: M = ModularForms(GammaH(15, [4]), 4)
283
sage: M.eisenstein_series()
284
[
285
1/240 + q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6),
286
1/240 + q^3 + O(q^6),
287
1/240 + q^5 + O(q^6),
288
1/240 + O(q^6),
289
1 + q - 7*q^2 - 26*q^3 + 57*q^4 + q^5 + O(q^6),
290
1 + q^3 + O(q^6),
291
q + 7*q^2 + 26*q^3 + 57*q^4 + 125*q^5 + O(q^6),
292
q^3 + O(q^6)
293
]
294
"""
295
try:
296
return self.__eisenstein_series
297
except AttributeError:
298
P = self.parameters()
299
E = Sequence([element.EisensteinSeries(self.change_ring(chi.base_ring()),
300
None, t, chi, psi) for \
301
chi, psi, t in P], immutable=True,
302
cr = True, universe=Objects())
303
assert len(E) == self.dimension(), "bug in enumeration of Eisenstein series."
304
self.__eisenstein_series = E
305
return E
306
307
def new_eisenstein_series(self):
308
r"""
309
Return a list of the Eisenstein series in this space that are new.
310
311
EXAMPLE::
312
313
sage: E = EisensteinForms(25, 4)
314
sage: E.new_eisenstein_series()
315
[q + 7*zeta4*q^2 - 26*zeta4*q^3 - 57*q^4 + O(q^6),
316
q - 9*q^2 - 28*q^3 + 73*q^4 + O(q^6),
317
q - 7*zeta4*q^2 + 26*zeta4*q^3 - 57*q^4 + O(q^6)]
318
"""
319
320
return [x for x in self.eisenstein_series() if x.new_level() == self.level()]
321
322
def _compute_q_expansion_basis(self, prec=None, new=False):
323
"""
324
Compute a q-expansion basis for self to precision prec.
325
326
EXAMPLES::
327
328
sage: EisensteinForms(22,4)._compute_q_expansion_basis(6)
329
[1 + O(q^6),
330
q + 28*q^3 - 8*q^4 + 126*q^5 + O(q^6),
331
q^2 + 9*q^4 + O(q^6),
332
O(q^6)]
333
sage: EisensteinForms(22,4)._compute_q_expansion_basis(15)
334
[1 + O(q^15),
335
q + 28*q^3 - 8*q^4 + 126*q^5 + 344*q^7 - 72*q^8 + 757*q^9 - 224*q^12 + 2198*q^13 + O(q^15),
336
q^2 + 9*q^4 + 28*q^6 + 73*q^8 + 126*q^10 + 252*q^12 + 344*q^14 + O(q^15),
337
q^11 + O(q^15)]
338
"""
339
if prec == None:
340
prec = self.prec()
341
else:
342
prec = rings.Integer(prec)
343
344
if new:
345
E = self.new_eisenstein_series()
346
else:
347
E = self.eisenstein_series()
348
K = self.base_ring()
349
V = K**prec
350
G = []
351
for e in E:
352
f = e.q_expansion(prec)
353
w = f.padded_list(prec)
354
L = f.base_ring()
355
if K.has_coerce_map_from(L):
356
G.append(V(w))
357
else:
358
# restrict scalars from L to K
359
r,d = cyclotomic_restriction(L,K)
360
s = [r(x) for x in w]
361
for i in range(d):
362
G.append(V([x[i] for x in s]))
363
364
W = V.submodule(G, check=False)
365
R = self._q_expansion_ring()
366
X = [R(f.list(), prec) for f in W.basis()]
367
if not new:
368
return X + [R(0,prec)]*(self.dimension() - len(X))
369
else:
370
return X
371
372
def _q_expansion(self, element, prec):
373
"""
374
Compute a q-expansion for a given element of self, expressed
375
as a vector of coefficients for the basis vectors of self,
376
viewing self as a subspace of the corresponding space of
377
modular forms.
378
379
EXAMPLES::
380
381
sage: E = EisensteinForms(17,4)
382
sage: (11*E.0 + 3*E.1).q_expansion(20)
383
11 + 3*q + 27*q^2 + 84*q^3 + 219*q^4 + 378*q^5 + 756*q^6 + 1032*q^7 + 1755*q^8 + 2271*q^9 + 3402*q^10 + 3996*q^11 + 6132*q^12 + 6594*q^13 + 9288*q^14 + 10584*q^15 + 14043*q^16 + 17379*q^17 + 20439*q^18 + 20580*q^19 + O(q^20)
384
sage: E._q_expansion([0,0,0,0,11,3],20)
385
11 + 3*q + 27*q^2 + 84*q^3 + 219*q^4 + 378*q^5 + 756*q^6 + 1032*q^7 + 1755*q^8 + 2271*q^9 + 3402*q^10 + 3996*q^11 + 6132*q^12 + 6594*q^13 + 9288*q^14 + 10584*q^15 + 14043*q^16 + 17379*q^17 + 20439*q^18 + 20580*q^19 + O(q^20)
386
"""
387
B = self.q_expansion_basis(prec)
388
f = self._q_expansion_zero()
389
for i in range(self._start_position, len(element)):
390
if element[i] != 0:
391
f += element[i] * B[i - self._start_position]
392
return f
393
394
395
class EisensteinSubmodule_g0_Q(EisensteinSubmodule_params):
396
r"""
397
Space of Eisenstein forms for `\Gamma_0(N)`.
398
"""
399
400
class EisensteinSubmodule_gH_Q(EisensteinSubmodule_params):
401
r"""
402
Space of Eisenstein forms for `\Gamma_H(N)`.
403
"""
404
def _parameters_character(self):
405
"""
406
Return the character defining self. Since self is
407
a space of Eisenstein forms on GammaH(N) rather than a space with fixed
408
character, we return the group GammaH(N) itself.
409
410
EXAMPLES::
411
412
sage: EisensteinForms(GammaH(9, [4]),4)._parameters_character()
413
Congruence Subgroup Gamma_H(9) with H generated by [4]
414
"""
415
return self.group()
416
417
def _convert_matrix_from_modsyms_eis(self, A):
418
r"""
419
Given a matrix acting on the space of modular symbols corresponding to
420
this space, calculate the matrix of the operator it induces on this
421
space itself. Used for Hecke and diamond operators.
422
423
This is a minor modification of the code used for cusp forms, which is
424
required because modular symbols "don't see the constant term": the
425
modular symbol method calculates the matrix of the operator with
426
respect to the unique basis of the modular forms space for which the
427
*non-constant* coefficients are in echelon form, and we need to modify
428
this to get a matrix with respect to the basis we're actually using.
429
430
EXAMPLES::
431
432
sage: EisensteinForms(Gamma1(6), 3).hecke_matrix(3) # indirect doctest
433
[ 1 0 72 0]
434
[ 0 0 36 -9]
435
[ 0 0 9 0]
436
[ 0 1 -4 10]
437
"""
438
from cuspidal_submodule import _convert_matrix_from_modsyms
439
symbs = self.modular_symbols(sign=0)
440
d = self.rank()
441
wrong_mat, pivs = _convert_matrix_from_modsyms(symbs, A)
442
c = Matrix(self.base_ring(), d, [self.basis()[i][j+1] for i in xrange(d) for j in pivs])
443
return c * wrong_mat * ~c
444
445
def _compute_hecke_matrix(self, n, bound=None):
446
r"""
447
Calculate the matrix of the Hecke operator `T_n` acting on this
448
space, via modular symbols.
449
450
INPUT:
451
452
- n: a positive integer
453
454
- bound: an integer such that any element of this space with
455
coefficients a_1, ..., a_b all zero must be the zero
456
element. If this turns out not to be true, the code will
457
increase the bound and try again. Setting bound = None is
458
equivalent to setting bound = self.dimension().
459
460
OUTPUT:
461
462
- a matrix (over `\QQ`)
463
464
ALGORITHM:
465
466
This uses the usual pairing between modular symbols and
467
modular forms, but in a slightly non-standard way. As for
468
cusp forms, we can find a basis for this space made up of
469
forms with q-expansions `c_m(f) = a_{i,j}(T_m)`, where
470
`T_m` denotes the matrix of the Hecke operator on the
471
corresponding modular symbols space. Then `c_m(T_n f) =
472
a_{i,j}(T_n* T_m)`. But we can't find the constant terms
473
by this method, so an extra step is required.
474
475
EXAMPLE::
476
477
sage: EisensteinForms(Gamma1(6), 3).hecke_matrix(3) # indirect doctest
478
[ 1 0 72 0]
479
[ 0 0 36 -9]
480
[ 0 0 9 0]
481
[ 0 1 -4 10]
482
"""
483
symbs = self.modular_symbols(sign=0)
484
T = symbs.hecke_matrix(n)
485
return self._convert_matrix_from_modsyms_eis(T)
486
487
def _compute_diamond_matrix(self, d):
488
r"""
489
Calculate the matrix of the diamond bracket operator <d> on this space,
490
using modular symbols.
491
492
EXAMPLE::
493
494
sage: E = EisensteinForms(Gamma1(7), 3)
495
sage: E._compute_diamond_matrix(3)
496
[ 27 126 294 770 2142 3528]
497
[56/3 85 200 530 1445 2408]
498
[11/3 14 22 66 233 392]
499
[ -1 -3 -3 -11 -51 -87]
500
[ -1 -4 -7 -20 -67 -112]
501
[-1/3 -2 -6 -15 -34 -56]
502
"""
503
symbs = self.modular_symbols(sign=0)
504
T = symbs.diamond_bracket_matrix(d)
505
return self._convert_matrix_from_modsyms_eis(T)
506
507
class EisensteinSubmodule_g1_Q(EisensteinSubmodule_gH_Q):
508
r"""
509
Space of Eisenstein forms for `\Gamma_1(N)`.
510
"""
511
def _parameters_character(self):
512
"""
513
Return the character defining self. Since self is a space of Eisenstein
514
forms on `\Gamma_1(N)`, all characters modulo the level are possible,
515
so we return the level.
516
517
EXAMPLES::
518
519
sage: EisensteinForms(Gamma1(7),4)._parameters_character()
520
7
521
"""
522
return self.level()
523
524
525
class EisensteinSubmodule_eps(EisensteinSubmodule_params):
526
"""
527
Space of Eisenstein forms with given Dirichlet character.
528
529
EXAMPLES::
530
531
sage: e = DirichletGroup(27,CyclotomicField(3)).0**2
532
sage: M = ModularForms(e,2,prec=10).eisenstein_subspace()
533
sage: M.dimension()
534
6
535
536
sage: M.eisenstein_series()
537
[
538
-1/3*zeta6 - 1/3 + q + (2*zeta6 - 1)*q^2 + q^3 + (-2*zeta6 - 1)*q^4 + (-5*zeta6 + 1)*q^5 + O(q^6),
539
-1/3*zeta6 - 1/3 + q^3 + O(q^6),
540
q + (-2*zeta6 + 1)*q^2 + (-2*zeta6 - 1)*q^4 + (5*zeta6 - 1)*q^5 + O(q^6),
541
q + (zeta6 + 1)*q^2 + 3*q^3 + (zeta6 + 2)*q^4 + (-zeta6 + 5)*q^5 + O(q^6),
542
q^3 + O(q^6),
543
q + (-zeta6 - 1)*q^2 + (zeta6 + 2)*q^4 + (zeta6 - 5)*q^5 + O(q^6)
544
]
545
sage: M.eisenstein_subspace().T(2).matrix().fcp()
546
(x + zeta3 + 2) * (x + 2*zeta3 + 1) * (x - 2*zeta3 - 1)^2 * (x - zeta3 - 2)^2
547
sage: ModularSymbols(e,2).eisenstein_subspace().T(2).matrix().fcp()
548
(x + zeta3 + 2) * (x + 2*zeta3 + 1) * (x - 2*zeta3 - 1)^2 * (x - zeta3 - 2)^2
549
550
sage: M.basis()
551
[
552
1 - 3*zeta3*q^6 + (-2*zeta3 + 2)*q^9 + O(q^10),
553
q + (5*zeta3 + 5)*q^7 + O(q^10),
554
q^2 - 2*zeta3*q^8 + O(q^10),
555
q^3 + (zeta3 + 2)*q^6 + 3*q^9 + O(q^10),
556
q^4 - 2*zeta3*q^7 + O(q^10),
557
q^5 + (zeta3 + 1)*q^8 + O(q^10)
558
]
559
560
"""
561
# TODO
562
#def _compute_q_expansion_basis(self, prec):
563
#B = EisensteinSubmodule_params._compute_q_expansion_basis(self, prec)
564
#raise NotImplementedError, "must restrict scalars down correctly."
565
566
567
from sage.rings.all import CyclotomicField, lcm, euler_phi
568
569
def cyclotomic_restriction(L,K):
570
r"""
571
Given two cyclotomic fields L and K, compute the compositum
572
M of K and L, and return a function and the index [M:K]. The
573
function is a map that acts as follows (here `M = Q(\zeta_m)`):
574
575
INPUT:
576
577
element alpha in L
578
579
OUTPUT:
580
581
a polynomial `f(x)` in `K[x]` such that `f(\zeta_m) = \alpha`,
582
where we view alpha as living in `M`. (Note that `\zeta_m`
583
generates `M`, not `L`.)
584
585
EXAMPLES::
586
587
sage: L = CyclotomicField(12) ; N = CyclotomicField(33) ; M = CyclotomicField(132)
588
sage: z, n = sage.modular.modform.eisenstein_submodule.cyclotomic_restriction(L,N)
589
sage: n
590
2
591
592
sage: z(L.0)
593
-zeta33^19*x
594
sage: z(L.0)(M.0)
595
zeta132^11
596
597
sage: z(L.0^3-L.0+1)
598
(zeta33^19 + zeta33^8)*x + 1
599
sage: z(L.0^3-L.0+1)(M.0)
600
zeta132^33 - zeta132^11 + 1
601
sage: z(L.0^3-L.0+1)(M.0) - M(L.0^3-L.0+1)
602
0
603
"""
604
if not L.has_coerce_map_from(K):
605
M = CyclotomicField(lcm(L.zeta_order(), K.zeta_order()))
606
f = cyclotomic_restriction_tower(M,K)
607
def g(x):
608
"""
609
Function returned by cyclotomic restriction.
610
611
INPUT:
612
613
element alpha in L
614
615
OUTPUT:
616
617
a polynomial `f(x)` in `K[x]` such that `f(\zeta_m) = \alpha`,
618
where we view alpha as living in `M`. (Note that `\zeta_m`
619
generates `M`, not `L`.)
620
621
EXAMPLES::
622
623
sage: L = CyclotomicField(12)
624
sage: N = CyclotomicField(33)
625
sage: g, n = sage.modular.modform.eisenstein_submodule.cyclotomic_restriction(L,N)
626
sage: g(L.0)
627
-zeta33^19*x
628
"""
629
return f(M(x))
630
return g, euler_phi(M.zeta_order())//euler_phi(K.zeta_order())
631
else:
632
return cyclotomic_restriction_tower(L,K), \
633
euler_phi(L.zeta_order())//euler_phi(K.zeta_order())
634
635
636
def cyclotomic_restriction_tower(L,K):
637
"""
638
Suppose L/K is an extension of cyclotomic fields and L=Q(zeta_m).
639
This function computes a map with the following property:
640
641
642
INPUT:
643
644
an element alpha in L
645
646
OUTPUT:
647
648
a polynomial `f(x)` in `K[x]` such that `f(zeta_m) = alpha`.
649
650
EXAMPLES::
651
652
sage: L = CyclotomicField(12) ; K = CyclotomicField(6)
653
sage: z = sage.modular.modform.eisenstein_submodule.cyclotomic_restriction_tower(L,K)
654
sage: z(L.0)
655
x
656
sage: z(L.0^2+L.0)
657
x + zeta6
658
"""
659
if not L.has_coerce_map_from(K):
660
raise ValueError, "K must be contained in L"
661
f = L.defining_polynomial()
662
R = K['x']
663
x = R.gen()
664
g = R(f)
665
h_ls = [ t[0] for t in g.factor() if t[0](L.gen(0)) == 0 ]
666
if len(h_ls) == 0:
667
raise ValueError, "K (= Q(\zeta_%s)) is not contained in L (= Q(\zeta_%s))"%(K._n(), L._n())
668
h = h_ls[0]
669
def z(a):
670
"""
671
Function returned by cyclotomic_restriction_tower.
672
673
INPUT:
674
675
an element alpha in L
676
677
OUTPUT:
678
679
a polynomial `f(x)` in `K[x]` such that `f(zeta_m) = alpha`.
680
681
EXAMPLES::
682
683
sage: L = CyclotomicField(121) ; K = CyclotomicField(11)
684
sage: z = sage.modular.modform.eisenstein_submodule.cyclotomic_restriction_tower(L,K)
685
sage: z(L.0)
686
x
687
sage: z(L.0^11)
688
zeta11
689
"""
690
return R(a.polynomial()) % h
691
return z
692
693
694