Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241818 views
1
from siegel_modular_form import SiegelModularForm, SiegelModularForm_class, SMF_DEFAULT_PREC
2
from sage.algebras.algebra import Algebra
3
from sage.misc.all import cached_method
4
from sage.rings.all import ZZ
5
from sage.structure.factory import UniqueFactory
6
7
class SiegelModularFormsAlgebraFactory(UniqueFactory):
8
"""
9
A factory for creating algebras of Siegel modular forms. It
10
handles making sure that they are unique as well as handling
11
pickling. For more details, see
12
:class:`~sage.structure.factory.UniqueFactory` and
13
:mod:`~sage.modular.siegel.siegel_modular_forms_algebra`.
14
15
EXAMPLES::
16
17
sage: S = SiegelModularFormsAlgebra()
18
sage: S.construction()
19
(SMFAlg{"Sp(4,Z)", "even", 2, 101}, Integer Ring)
20
sage: R.<a, b> = QQ[]
21
sage: S = SiegelModularFormsAlgebra(coeff_ring=R)
22
sage: S.construction()
23
(SMFAlg{"Sp(4,Z)", "even", 2, 101}, Multivariate Polynomial Ring in a, b over Rational Field)
24
sage: S is loads(dumps(S))
25
True
26
sage: TestSuite(S).run()
27
"""
28
def create_key(self, coeff_ring=ZZ, group='Sp(4,Z)', weights='even', degree=2, default_prec=SMF_DEFAULT_PREC):
29
"""
30
Create a key which uniquely defines this algebra of Siegel modular
31
forms.
32
33
TESTS::
34
35
sage: SiegelModularFormsAlgebra.create_key(coeff_ring=QQ, group='Gamma0(5)', weights='all', degree=2, default_prec=41)
36
(SMFAlg{"Gamma0(5)", "all", 2, 41}(FractionField(...)), Integer Ring)
37
"""
38
from sage.rings.ring import is_Ring
39
if not is_Ring(coeff_ring):
40
raise TypeError, 'The coefficient ring must be a ring'
41
if not (isinstance(group, str) or group is None):
42
raise TypeError, 'The group must be given by a string, or None'
43
if not weights in ('even', 'all'):
44
raise ValueError, "The argument weights must be 'even' or 'all'"
45
try:
46
degree = int(degree)
47
except TypeError:
48
raise TypeError, 'The degree must be a positive integer'
49
if degree < 1:
50
raise ValueError, 'The degree must be a positive integer'
51
if degree == 1:
52
raise ValueError, 'Use ModularForms if you want to work with Siegel modular forms of degree 1'
53
if degree > 2:
54
raise NotImplementedError, 'Siegel modular forms of degree > 2 are not yet implemented'
55
try:
56
default_prec = int(default_prec)
57
except TypeError:
58
raise TypeError, 'The default precision must be a positive integer'
59
60
from pushout import SiegelModularFormsAlgebraFunctor
61
F = SiegelModularFormsAlgebraFunctor(group=group, weights=weights, degree=degree, default_prec=default_prec)
62
63
while hasattr(coeff_ring, 'construction'):
64
C = coeff_ring.construction()
65
if C is None:
66
break
67
F = F * C[0]
68
coeff_ring = C[1]
69
return (F, coeff_ring)
70
71
def create_object(self, version, key):
72
"""
73
Return the algebra of Siegel modular forms corresponding to the
74
key ``key``.
75
76
TESTS::
77
78
sage: key = SiegelModularFormsAlgebra.create_key(coeff_ring=QQ, group='Gamma0(5)', weights='all', degree=2, default_prec=41)
79
sage: SiegelModularFormsAlgebra.create_object('1.0', key)
80
Algebra of Siegel modular forms of degree 2 and all weights on Gamma0(5) over Rational Field
81
"""
82
C, R = key
83
from pushout import CompositConstructionFunctor, SiegelModularFormsAlgebraFunctor
84
if isinstance(C, CompositConstructionFunctor):
85
F = C.all[-1]
86
if len(C.all) > 1:
87
R = CompositConstructionFunctor(*C.all[:-1])(R)
88
else:
89
F = C
90
if not isinstance(F, SiegelModularFormsAlgebraFunctor):
91
raise TypeError, "We expected a SiegelModularFormsAlgebraFunctor, not %s"%type(F)
92
return SiegelModularFormsAlgebra_class(coeff_ring=R, group=F._group, weights=F._weights, degree=F._degree, default_prec=F._default_prec)
93
94
SiegelModularFormsAlgebra = SiegelModularFormsAlgebraFactory('SiegelModularFormsAlgebra')
95
96
97
class SiegelModularFormsAlgebra_class(Algebra):
98
def __init__(self, coeff_ring=ZZ, group='Sp(4,Z)', weights='even', degree=2, default_prec=SMF_DEFAULT_PREC):
99
r"""
100
Initialize an algebra of Siegel modular forms of degree ``degree``
101
with coefficients in ``coeff_ring``, on the group ``group``.
102
If ``weights`` is 'even', then only forms of even weights are
103
considered; if ``weights`` is 'all', then all forms are
104
considered.
105
106
EXAMPLES::
107
108
sage: A = SiegelModularFormsAlgebra(QQ)
109
sage: B = SiegelModularFormsAlgebra(ZZ)
110
sage: A._coerce_map_from_(B)
111
True
112
sage: B._coerce_map_from_(A)
113
False
114
sage: A._coerce_map_from_(ZZ)
115
True
116
"""
117
self.__coeff_ring = coeff_ring
118
self.__group = group
119
self.__weights = weights
120
self.__degree = degree
121
self.__default_prec = default_prec
122
R = coeff_ring
123
from sage.algebras.all import GroupAlgebra
124
if isinstance(R, GroupAlgebra):
125
R = R.base_ring()
126
from sage.rings.polynomial.polynomial_ring import is_PolynomialRing
127
if is_PolynomialRing(R):
128
self.__base_ring = R.base_ring()
129
else:
130
self.__base_ring = R
131
from sage.categories.all import Algebras
132
Algebra.__init__(self, base=self.__base_ring, category=Algebras(self.__base_ring))
133
134
@cached_method
135
def gens(self, prec=None):
136
"""
137
Return the ring generators of this algebra.
138
139
EXAMPLES::
140
141
sage: S = SiegelModularFormsAlgebra()
142
sage: S.gens()
143
[Igusa_4, Igusa_6, Igusa_10, Igusa_12]
144
145
TESTS::
146
147
sage: S = SiegelModularFormsAlgebra(group='Gamma0(2)')
148
sage: S.gens()
149
Traceback (most recent call last):
150
...
151
NotImplementedError: Not yet implemented
152
"""
153
if prec is None:
154
prec = self.default_prec()
155
return _siegel_modular_forms_generators(self, prec=prec)
156
157
def is_commutative(self):
158
r"""
159
Return True since all our algebras are commutative.
160
161
EXAMPLES::
162
163
sage: S = SiegelModularFormsAlgebra(coeff_ring=QQ)
164
sage: S.is_commutative()
165
True
166
"""
167
return True
168
169
@cached_method
170
def ngens(self):
171
r"""
172
Return the number of generators of this algebra of Siegel modular
173
forms.
174
175
EXAMPLES::
176
177
sage: S = SiegelModularFormsAlgebra(coeff_ring=QQ)
178
sage: S.ngens()
179
4
180
"""
181
return len(self.gens())
182
183
@cached_method
184
def gen(self, i, prec=None):
185
r"""
186
Return the `i`-th generator of this algebra.
187
188
EXAMPLES::
189
190
sage: S = SiegelModularFormsAlgebra(coeff_ring=QQ)
191
sage: S.ngens()
192
4
193
sage: S.gen(2)
194
Igusa_10
195
"""
196
return self.gens(prec=prec)[i]
197
198
def coeff_ring(self):
199
r"""
200
Return the ring of coefficients of this algebra.
201
202
EXAMPLES::
203
204
sage: S = SiegelModularFormsAlgebra(coeff_ring=QQ)
205
sage: S.coeff_ring()
206
Rational Field
207
"""
208
return self.__coeff_ring
209
210
def group(self):
211
"""
212
Return the modular group of this algebra.
213
214
EXAMPLES::
215
216
sage: S = SiegelModularFormsAlgebra(group='Gamma0(7)')
217
sage: S.group()
218
'Gamma0(7)'
219
"""
220
return self.__group
221
222
def weights(self):
223
"""
224
Return 'even' or 'all' depending on whether this algebra
225
contains only even weight forms, or forms of all weights.
226
227
EXAMPLES::
228
229
sage: S = SiegelModularFormsAlgebra(weights='even')
230
sage: S.weights()
231
'even'
232
sage: S = SiegelModularFormsAlgebra(weights='all')
233
sage: S.weights()
234
'all'
235
"""
236
return self.__weights
237
238
def degree(self):
239
"""
240
Return the degree of the modular forms in this algebra.
241
242
EXAMPLES::
243
244
sage: S = SiegelModularFormsAlgebra()
245
sage: S.degree()
246
2
247
"""
248
return self.__degree
249
250
def default_prec(self):
251
"""
252
Return the default precision for the Fourier expansions of
253
modular forms in this algebra.
254
255
EXAMPLES::
256
257
sage: S = SiegelModularFormsAlgebra(default_prec=41)
258
sage: S.default_prec()
259
41
260
"""
261
return self.__default_prec
262
263
def _repr_(self):
264
r"""
265
Return the plain text representation of this algebra.
266
267
EXAMPLES::
268
269
sage: S = SiegelModularFormsAlgebra(coeff_ring=QQ)
270
sage: S._repr_()
271
'Algebra of Siegel modular forms of degree 2 and even weights on Sp(4,Z) over Rational Field'
272
"""
273
return 'Algebra of Siegel modular forms of degree %s and %s weights on %s over %s'%(self.__degree, self.__weights, self.__group, self.__coeff_ring)
274
275
def _latex_(self):
276
r"""
277
Return the latex representation of this algebra.
278
279
EXAMPLES::
280
281
sage: S = SiegelModularFormsAlgebra(coeff_ring=QQ)
282
sage: S._latex_()
283
'\\texttt{Algebra of Siegel modular forms of degree }2\\texttt{ and even weights on Sp(4,Z) over }\\Bold{Q}'
284
"""
285
from sage.misc.all import latex
286
return r'\texttt{Algebra of Siegel modular forms of degree }%s\texttt{ and %s weights on %s over }%s' %(latex(self.__degree), self.__weights, self.__group, latex(self.__coeff_ring))
287
288
def _coerce_map_from_(self, other):
289
r"""
290
Return True if it is possible to coerce from ``other`` into the
291
algebra of Siegel modular forms ``self``.
292
293
EXAMPLES::
294
295
sage: S = SiegelModularFormsAlgebra(coeff_ring=QQ)
296
sage: R = SiegelModularFormsAlgebra(coeff_ring=ZZ)
297
sage: S._coerce_map_from_(R)
298
True
299
sage: R._coerce_map_from_(S)
300
False
301
sage: S._coerce_map_from_(ZZ)
302
True
303
"""
304
if self.base_ring().has_coerce_map_from(other):
305
return True
306
if isinstance(other, SiegelModularFormsAlgebra_class):
307
if (self.group() == other.group()) or (other.group() == 'Sp(4,Z)'):
308
if self.coeff_ring().has_coerce_map_from(other.coeff_ring()):
309
if self.degree() == other.degree():
310
return True
311
return False
312
313
def _element_constructor_(self, x):
314
r"""
315
Return the element of the algebra ``self`` corresponding to ``x``.
316
317
EXAMPLES::
318
319
sage: S = SiegelModularFormsAlgebra(coeff_ring=QQ)
320
sage: B = SiegelModularFormsAlgebra(coeff_ring=ZZ).1
321
sage: S(B)
322
Igusa_6
323
sage: S(1/5)
324
1/5
325
sage: S(1/5).parent() is S
326
True
327
sage: S._element_constructor_(2.67)
328
Traceback (most recent call last):
329
...
330
TypeError: Unable to construct an element of Algebra of Siegel modular forms of degree 2 and even weights on Sp(4,Z) over Rational Field corresponding to 2.67000000000000
331
sage: S.base_extend(RR)._element_constructor_(2.67)
332
2.67000000000000
333
"""
334
if isinstance(x, (int, long)):
335
x = ZZ(x)
336
if isinstance(x, float):
337
from sage.rings.all import RR
338
x = RR(x)
339
if isinstance(x, complex):
340
from sage.rings.all import CC
341
x = CC(x)
342
343
if isinstance(x.parent(), SiegelModularFormsAlgebra_class):
344
d = dict((f, self.coeff_ring()(x[f])) for f in x.coeffs())
345
return self.element_class(parent=self, weight=x.weight(), coeffs=d, prec=x.prec(), name=x.name())
346
347
R = self.base_ring()
348
if R.has_coerce_map_from(x.parent()):
349
d = {(0, 0, 0): R(x)}
350
from sage.rings.all import infinity
351
return self.element_class(parent=self, weight=0, coeffs=d, prec=infinity, name=str(x))
352
else:
353
raise TypeError, "Unable to construct an element of %s corresponding to %s" %(self, x)
354
355
Element = SiegelModularForm_class
356
357
def _an_element_(self):
358
r"""
359
Return an element of the algebra ``self``.
360
361
EXAMPLES::
362
363
sage: S = SiegelModularFormsAlgebra(coeff_ring=QQ)
364
sage: z = S._an_element_()
365
sage: z in S
366
True
367
"""
368
return self(0)
369
370
def base_extend(self, R):
371
r"""
372
Extends the base ring of the algebra ``self`` to ``R``.
373
374
EXAMPLES::
375
376
sage: S = SiegelModularFormsAlgebra(coeff_ring=QQ)
377
sage: S.base_extend(RR)
378
Algebra of Siegel modular forms of degree 2 and even weights on Sp(4,Z) over Real Field with 53 bits of precision
379
"""
380
#B = self.base_ring()
381
S = self.coeff_ring()
382
from sage.rings.polynomial.polynomial_ring import is_PolynomialRing
383
if is_PolynomialRing(S):
384
xS = S.base_extend(R)
385
elif R.has_coerce_map_from(S):
386
xS = R
387
else:
388
raise TypeError, "cannot extend to %s" %R
389
return SiegelModularFormsAlgebra(coeff_ring=xS, group=self.group(), weights=self.weights(), degree=self.degree(), default_prec=self.default_prec())
390
391
def construction(self):
392
r"""
393
Return the construction of the algebra ``self``.
394
395
EXAMPLES::
396
397
sage: S = SiegelModularFormsAlgebra(coeff_ring=QQ)
398
sage: S.construction()
399
(SMFAlg{"Sp(4,Z)", "even", 2, 101}, Rational Field)
400
"""
401
from pushout import SiegelModularFormsAlgebraFunctor
402
return SiegelModularFormsAlgebraFunctor(self.group(), self.weights(), self.degree(), self.default_prec()), self.coeff_ring()
403
404
405
406
def _siegel_modular_forms_generators(parent, prec=None, degree=0):
407
r"""
408
Compute the four Igusa generators of the ring of Siegel modular forms
409
of degree 2 and level 1 and even weight (this happens if weights='even').
410
If weights = 'all' you get the Siegel modular forms of degree 2, level 1
411
and even and odd weight.
412
413
EXAMPLES::
414
415
sage: A, B, C, D = SiegelModularFormsAlgebra().gens()
416
sage: C[(2, 0, 9)]
417
-390420
418
sage: D[(4, 2, 5)]
419
17689760
420
sage: A2, B2, C2, D2 = SiegelModularFormsAlgebra().gens(prec=50)
421
sage: A[(1, 0, 1)] == A2[(1, 0, 1)]
422
True
423
sage: A3, B3, C3, D3 = SiegelModularFormsAlgebra().gens(prec=500)
424
sage: B2[(2, 1, 3)] == B3[(2, 1, 3)]
425
True
426
427
TESTS::
428
429
sage: from sage.modular.siegel.siegel_modular_forms_algebra import _siegel_modular_forms_generators
430
sage: S = SiegelModularFormsAlgebra()
431
sage: S.gens() == _siegel_modular_forms_generators(S)
432
True
433
"""
434
group = parent.group()
435
weights = parent.weights()
436
if prec is None:
437
prec = parent.default_prec()
438
if group == 'Sp(4,Z)' and 0 == degree:
439
from sage.modular.all import ModularForms
440
E4 = ModularForms(1, 4).gen(0)
441
M6 = ModularForms(1, 6)
442
E6 = ModularForms(1, 6).gen(0)
443
M8 = ModularForms(1, 8)
444
M10 = ModularForms(1, 10)
445
Delta = ModularForms(1, 12).cuspidal_subspace().gen(0)
446
M14 = ModularForms(1, 14)
447
A = SiegelModularForm(60*E4, M6(0), prec=prec, name='Igusa_4')
448
B = SiegelModularForm(-84*E6, M8(0), prec=prec, name='Igusa_6')
449
C = SiegelModularForm(M10(0), -Delta, prec=prec, name='Igusa_10')
450
D = SiegelModularForm(Delta, M14(0), prec=prec, name='Igusa_12')
451
# TODO: the base_ring of A, B, ... should be ZZ
452
# Here a hack for now:
453
a = [A, B, C, D]
454
b = []
455
from sage.rings.all import ZZ
456
for F in a:
457
c = F.coeffs()
458
for f in c.iterkeys():
459
c[f] = ZZ(c[f])
460
F = parent.element_class(parent=parent, weight=F.weight(), coeffs=c, prec=prec, name=F.name())
461
b.append(F)
462
if weights == 'even': return b
463
if weights == 'all':
464
from fastmult import chi35
465
coeffs35 = chi35(prec, b[0], b[1], b[2], b[3])
466
from sage.groups.all import KleinFourGroup
467
G = KleinFourGroup()
468
from sage.algebras.all import GroupAlgebra
469
R = GroupAlgebra(G)
470
det = R(G.gen(0))
471
E = parent.element_class(parent=parent, weight=35, coeffs=coeffs35, prec=prec, name='Delta_35')
472
E = E*det
473
b.append(E)
474
return b
475
raise ValueError, "weights = '%s': should be 'all' or 'even'" %weights
476
if group == 'Sp(4,Z)' and weights == 'even' and 2 == degree:
477
b = _siegel_modular_forms_generators(parent=parent)
478
c = []
479
for F in b:
480
i = b.index(F)
481
for G in b[(i+1):]:
482
c.append(F.satoh_bracket(G))
483
return c
484
raise NotImplementedError, "Not yet implemented"
485
486
487