Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241818 views
1
"""
2
Precision for Fourier expansions of Siegel modular forms
3
"""
4
5
6
from copy import deepcopy
7
import operator
8
9
from sage.rings.integer import Integer
10
from sage.rings.integer_ring import ZZ
11
from sage.functions.other import floor
12
from sage.functions.other import ceil
13
from sage.misc.functional import isqrt
14
from sage.structure.sage_object import SageObject
15
from sage.structure.element import RingElement
16
from sage.rings.all import infinity
17
import sage.structure.element
18
from sage.misc.latex import latex
19
20
#from copy import deepcopy
21
#import operator
22
23
24
25
#from sage.rings.integer import Integer
26
#from sage.functions.other import (floor, ceil)
27
#from sage.misc.functional import isqrt
28
#from sage.structure.sage_object import SageObject
29
#from sage.rings.all import infinity
30
#from fastmult import reduce_GL
31
32
33
#load 'fastmult.spyx'
34
#from fastmult import reduce_GL
35
36
37
38
class SiegelModularFormPrecision (SageObject):
39
r"""
40
Stores information on the precision of the Fourier expansion of a Siegel
41
modular form and provides checking.
42
"""
43
def __init__(self, prec):
44
r"""
45
INPUT
46
prec -- an integer or infinity or a triple (aprec, bprec, cprec) of integers.
47
or an instance of class SiegelModularFormPrecision
48
NOTE
49
We distinguish two types of precision bounds:
50
'disc' or 'box'. prec indicates that all terms q^(a,b,c)
51
with GL(2,Z)-reduced (a,b,c) are available such that
52
either 4ac-b^2 < prec ('disc'-precision) or else
53
one has componentwise
54
(a,b,c) < ( aprec, bprec, cprec)
55
('box'-precision).
56
57
EXAMPLES::
58
59
sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
60
sage: prec = SiegelModularFormPrecision(101)
61
sage: prec2 = SiegelModularFormPrecision(prec)
62
sage: prec
63
Discriminant precision for Siegel modular form with bound 101
64
sage: prec2
65
Discriminant precision for Siegel modular form with bound 101
66
sage: prec == prec2
67
True
68
sage: prec3 = SiegelModularFormPrecision((5,5,5))
69
sage: prec3
70
Box precision for Siegel modular form with bound (5, 5, 5)
71
sage: prec4 = SiegelModularFormPrecision(infinity)
72
sage: prec4
73
Infinity precision for Siegel modular form with bound +Infinity
74
sage: prec5 = SiegelModularFormPrecision((5,0,5))
75
sage: prec5.prec()
76
(0, 0, 0)
77
78
TESTS::
79
80
sage: prec = SiegelModularFormPrecision(101)
81
sage: TestSuite(prec).run()
82
"""
83
## copy constructor
84
if isinstance(prec, SiegelModularFormPrecision):
85
self.__type = deepcopy(prec.type())
86
self.__prec = deepcopy(prec.prec())
87
88
elif prec is infinity:
89
self.__type = 'infinity'
90
self.__prec = infinity
91
92
elif isinstance(prec, (int, Integer)):
93
self.__type = 'disc'
94
prec = max( 0, prec)
95
Dmod = prec % 4
96
if Dmod >= 2:
97
self.__prec = Integer(prec - Dmod + 1)
98
else:
99
self.__prec = Integer(prec)
100
101
elif isinstance(prec, tuple) and len(prec) == 3 and all([isinstance(e, (int, Integer)) for e in list(prec)]):
102
self.__type = 'box'
103
a,b,c = prec
104
a = min( a, c)
105
b = min( b, a)
106
if b <= 0:
107
self.__prec = ( 0,0,0 )
108
else:
109
self.__prec = ( Integer(a), Integer(b), Integer(c))
110
111
else:
112
raise TypeError, "incorrect type %s for prec" % type(prec)
113
114
def _repr_(self):
115
r"""
116
Returns the repr of self
117
118
EXAMPLES::
119
120
sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
121
sage: prec = SiegelModularFormPrecision(101)
122
sage: prec._repr_()
123
'Discriminant precision for Siegel modular form with bound 101'
124
"""
125
126
if self.type() == 'infinity':
127
n = "Infinity"
128
elif self.type() == 'disc':
129
n = "Discriminant"
130
elif self.type() == 'box':
131
n = "Box"
132
else:
133
raise RuntimeError, "Unexpected value of self.__type"
134
135
return "%s precision for Siegel modular form with bound %s" % \
136
(n, repr(self.__prec))
137
138
139
def _latex_(self):
140
r"""
141
Returns the latex of self
142
143
EXAMPLES::
144
145
sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
146
sage: prec = SiegelModularFormPrecision(101)
147
sage: prec._latex_()
148
'Discriminant precision for Siegel modular form with bound $101$'
149
150
"""
151
152
if self.__type == 'infinity':
153
n = "Infinity"
154
elif self.__type == 'disc':
155
n = "Discriminant"
156
elif self.__type == 'box':
157
n = "Box"
158
else:
159
raise ValueError, "Unexpected value of self.__type"
160
161
return "%s precision for Siegel modular form with bound $%s$" %(str(n),str(latex(self.__prec)))
162
163
164
def type(self):
165
r"""
166
Returns the type of self: box, disc or infinity
167
168
EXAMPLES::
169
170
sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
171
sage: prec = SiegelModularFormPrecision((2,2,2))
172
sage: prec = SiegelModularFormPrecision(infinity)
173
sage: prec.type()
174
'infinity'
175
sage: prec = SiegelModularFormPrecision(101)
176
sage: prec.type()
177
'disc'
178
179
"""
180
return self.__type
181
182
183
def prec(self):
184
r"""
185
Returns the tuple of the maximal box, the integer for the maximal discriminant
186
and infinity otherwise. If self is of type disc then it will return the
187
largest fundamental discriminant just below.
188
189
EXAMPLES::
190
191
sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
192
sage: prec = SiegelModularFormPrecision(11)
193
sage: prec.prec()
194
9
195
sage: prec = SiegelModularFormPrecision(8)
196
sage: prec.prec()
197
8
198
199
200
"""
201
return self.__prec
202
203
204
def is_in_bound(self, t):
205
r"""
206
Return True or False accordingly as the GL(2,Z)-reduction of
207
the tuple (a,b,c)=t is within the bounds of this precision.
208
209
EXAMPLES::
210
211
sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
212
sage: prec = SiegelModularFormPrecision(101)
213
sage: prec.is_in_bound((1,0,1))
214
True
215
sage: prec.is_in_bound((0,0,25))
216
True
217
sage: prec.is_in_bound((0,0,26))
218
False
219
sage: prec.is_in_bound((6,0,6))
220
False
221
sage: prec = SiegelModularFormPrecision((2,2,2))
222
sage: prec.is_in_bound((1,0,1))
223
True
224
sage: prec.is_in_bound((2,2,2))
225
False
226
227
228
TODO
229
fix this
230
231
NOTE
232
It is assumed that (a,b,c) is semi positive definite
233
"""
234
(a, b, c) = t
235
236
from fastmult import reduce_GL
237
if self.__type == 'infinity':
238
return True
239
elif self.__type == 'disc':
240
(a,b,c) = reduce_GL(a, b, c)
241
if a == 0 and b == 0:
242
return c < self.get_contents_bound_for_semi_definite_forms()
243
D = 4*a*c-b**2
244
if D < 0:
245
return False
246
if D > 0:
247
return D < self.__prec
248
elif self.__type == 'box':
249
(a, b, c) = reduce_GL(a, b, c)
250
return a < self.__prec[0] and b < self.__prec[1] and c < self.__prec[2]
251
else:
252
raise RuntimeError, "Unexpected value of self.__type"
253
254
255
def get_contents_bound_for_semi_definite_forms(self):
256
r"""
257
Return the bound for the contents of a semi positive definite
258
form falling within this precision.
259
260
EXAMPLES::
261
262
sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
263
sage: prec = SiegelModularFormPrecision(7)
264
sage: prec.get_contents_bound_for_semi_definite_forms()
265
2
266
sage: prec = SiegelModularFormPrecision(101)
267
sage: prec.get_contents_bound_for_semi_definite_forms()
268
26
269
270
271
NOTE
272
If (a,b,c) is semi positive definite, then it is GL(2,Z)-equivalent
273
to a the form (0,0,g) where g is the contents (gcd) of a,b,c.
274
275
I don't know what this does. It seems to only do it for singular forms-- NR
276
"""
277
if self.__type == 'infinity':
278
return infinity
279
elif self.__type == 'disc':
280
return ceil((self.__prec+1)/4)
281
elif self.__type == 'box':
282
return self.__prec[2]
283
else:
284
raise RuntimeError, "Unexpected value of self.__type"
285
286
287
def __lt__(self, other):
288
r"""
289
Return True if the set of GL(2,Z)-reduced forms within the precision self
290
is contained in but not equal to the coresponding set of forms within the
291
precision other.
292
293
EXAMPLES::
294
295
sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
296
sage: prec1 = SiegelModularFormPrecision(101)
297
sage: prec2 = SiegelModularFormPrecision(100)
298
sage: prec3 = SiegelModularFormPrecision(201)
299
sage: prec1
300
Discriminant precision for Siegel modular form with bound 101
301
sage: prec2
302
Discriminant precision for Siegel modular form with bound 100
303
sage: prec2 < prec1
304
True
305
sage: prec3 < prec1
306
False
307
sage: prec1.__lt__(prec3)
308
True
309
310
"""
311
if not isinstance(other, SiegelModularFormPrecision):
312
raise NotImplementedError, "can only compare with elements of the same class"
313
314
## TODO: implement comparison of precisions of different types
315
if self.__type != other.__type:
316
return False
317
318
if self.__type == 'box':
319
a,b,c = self.__prec
320
ao,bo,co = other.__prec
321
return a <= ao and b <= bo and c <= co \
322
and any([a < ao, b < bo, c < co])
323
324
elif self.__type == 'disc':
325
return self.__prec < other.__prec
326
327
else:
328
raise RuntimeError, "Unexpected value of self.__type"
329
330
331
def __le__(self, other):
332
r"""
333
Returns whether self <= other
334
335
EXAMPLES::
336
337
sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
338
sage: prec1 = SiegelModularFormPrecision(101)
339
sage: prec2 = SiegelModularFormPrecision(100)
340
sage: prec3 = SiegelModularFormPrecision(101)
341
sage: prec1 <= prec3
342
True
343
sage: prec1 <= prec2
344
False
345
sage: prec1 <= prec1
346
True
347
sage: prec4 = SiegelModularFormPrecision(infinity)
348
sage: prec5 = SiegelModularFormPrecision((5,5,5))
349
sage: prec5.__le__(prec4)
350
False
351
352
TO DO:
353
354
It seems eevrything should be <= infinity
355
356
"""
357
return self.__lt__(other) or self.__eq__(other)
358
359
360
def __eq__(self, other):
361
r"""
362
Returns self == other as defined by having the same prec and type
363
364
EXAMPLES::
365
366
sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
367
sage: prec1 = SiegelModularFormPrecision(101)
368
sage: prec2 = SiegelModularFormPrecision(100)
369
sage: prec3 = SiegelModularFormPrecision(101)
370
sage: prec4 = SiegelModularFormPrecision(infinity)
371
sage: prec5 = SiegelModularFormPrecision((5,5,5))
372
sage: prec1 == prec2
373
False
374
sage: prec1 == prec3
375
True
376
sage: prec4 == prec2
377
False
378
sage: prec4 == prec4
379
True
380
sage: prec5.__eq__(prec5)
381
True
382
383
"""
384
385
if not isinstance(other, SiegelModularFormPrecision):
386
raise NotImplementedError, "can only compare with elements of the same class"
387
388
return ( self.__type == other.type() and self.__prec == other.prec())
389
390
391
def __ne__(self, other):
392
r"""
393
Returns self != other
394
395
EXAMPLES::
396
397
sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
398
sage: prec1 = SiegelModularFormPrecision(101)
399
sage: prec2 = SiegelModularFormPrecision(100)
400
sage: prec3 = SiegelModularFormPrecision(101)
401
sage: prec1.__ne__(prec1)
402
False
403
sage: prec1 != prec2
404
True
405
sage: prec1 != prec3
406
False
407
"""
408
409
return not self.__eq__(other)
410
411
412
def __gt__(self, other):
413
r"""
414
Returns self > other
415
416
EXAMPLES::
417
418
sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
419
sage: prec = SiegelModularFormPrecision(101)
420
sage: prec2 = SiegelModularFormPrecision(100)
421
sage: prec > prec2
422
True
423
sage: prec2.__gt__(prec)
424
False
425
"""
426
427
return other.__lt__(self)
428
429
430
def __ge__(self, other):
431
r"""
432
Returns self >= other
433
434
EXAMPLES::
435
436
sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
437
sage: prec = SiegelModularFormPrecision(101)
438
sage: prec2 = SiegelModularFormPrecision(100)
439
sage: prec >= prec2
440
True
441
sage: prec.__ge__(prec)
442
True
443
"""
444
445
return self.__eq__(other) or other.__lt__(self)
446
447
448
def __iter__(self):
449
r"""
450
Iterate over all GL(2,Z)-reduced semi positive forms
451
which are within the bounds of this precision.
452
453
EXAMPLES::
454
455
sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
456
sage: prec = SiegelModularFormPrecision(11)
457
sage: for k in prec.__iter__(): print k
458
(0, 0, 0)
459
(0, 0, 1)
460
(0, 0, 2)
461
(1, 0, 1)
462
(1, 0, 2)
463
(1, 1, 1)
464
(1, 1, 2)
465
466
467
NOTE
468
The forms are enumerated in lexicographic order.
469
"""
470
if self.__type == 'disc':
471
bound = self.get_contents_bound_for_semi_definite_forms()
472
for c in xrange(0, bound):
473
yield (0,0,c)
474
475
atop = isqrt(self.__prec // 3)
476
if 3*atop*atop == self.__prec: atop -= 1
477
for a in xrange(1,atop + 1):
478
for b in xrange(a+1):
479
for c in xrange(a, ceil((b**2 + self.__prec)/(4*a))):
480
yield (a,b,c)
481
482
elif 'box' == self.__type:
483
(am, bm, cm) = self.__prec
484
for a in xrange(am):
485
for b in xrange( min(bm,a+1)):
486
for c in xrange(a, cm):
487
yield (a,b,c)
488
489
else:
490
raise RuntimeError, "Unexpected value of self.__type"
491
492
raise StopIteration
493
494
495
def positive_forms(self):
496
r"""
497
Iterate over all GL(2,Z)-reduced strictly positive forms
498
which are within the bounds of this precision.
499
500
EXAMPLES::
501
502
sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
503
sage: prec = SiegelModularFormPrecision(11)
504
sage: for k in prec.positive_forms(): print k
505
(1, 0, 1)
506
(1, 0, 2)
507
(1, 1, 1)
508
(1, 1, 2)
509
510
NOTE
511
The forms are enumerated in lexicographic order.
512
"""
513
if self.__type == 'disc':
514
atop = isqrt(self.__prec // 3)
515
if 3*atop*atop == self.__prec: atop -= 1
516
for a in xrange(1,atop + 1):
517
for b in xrange(a+1):
518
for c in xrange(a, ceil((b**2 + self.__prec)/(4*a))):
519
yield (a,b,c)
520
521
elif 'box' == self.__type:
522
(am, bm, cm) = self.__prec
523
for a in xrange(am):
524
for b in xrange( min(bm,a+1)):
525
for c in xrange(a, cm):
526
yield (a,b,c)
527
528
else:
529
raise RuntimeError, "Unexpected value of self.__type"
530
531
raise StopIteration
532
533