Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241818 views
1
r"""
2
Functions to create and use basis of graded modules which are products of
3
Maass lifts.
4
5
AUTHORS:
6
7
- Martin Raum (2009 - 08 - 03) Initial version
8
"""
9
10
#===============================================================================
11
#
12
# Copyright (C) 2009 Martin Raum
13
#
14
# This program is free software; you can redistribute it and/or
15
# modify it under the terms of the GNU General Public License
16
# as published by the Free Software Foundation; either version 3
17
# of the License, or (at your option) any later version.
18
#
19
# This program is distributed in the hope that it will be useful,
20
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22
# General Public License for more details.
23
#
24
# You should have received a copy of the GNU General Public License
25
# along with this program; if not, see <http://www.gnu.org/licenses/>.
26
#
27
#===============================================================================
28
29
from sage.matrix.constructor import matrix
30
from sage.misc.misc import prod
31
from sage.rings.arith import random_prime
32
from sage.rings.integer_ring import ZZ
33
from sage.rings.padics.factory import Qp
34
from sage.rings.rational_field import QQ
35
from psage.modform.paramodularforms.siegelmodularformg2_fegenerators import SiegelModularFormG2MaassLift
36
from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_lazyelement import EquivariantMonoidPowerSeries_LazyMultiplication
37
from psage.modform.paramodularforms.siegelmodularformg2_submodule import SiegelModularFormG2Submodule_maassspace
38
from sage.interfaces.magma import magma
39
40
def spanning_maass_products(ring, weight, subspaces = None, lazy_rank_check = False) :
41
r"""This function is intended to quickly find good generators. This may be
42
calculated in low precision and then ported to higher.
43
44
the maass spaces of all subspaces are expected to be ordered the same way as
45
``ring.type()._maass_generator_preimages``.
46
"""
47
## Outline :
48
## - get the basis as polynomials form the ring
49
## - get the maass products, convert them to polynomials and try to
50
## construct a basis
51
## - get the maass space associated to this weight and get its coordinates
52
## - return a basis containing of maass forms and the products
53
54
if subspaces is None :
55
subspaces = dict()
56
57
assert ring.base_ring() is QQ or ring.base_ring() is ZZ, \
58
"%s doesn't have rational base field" % ring
59
60
dim = ring.graded_submodule(weight).dimension()
61
precision = ring.fourier_expansion_precision()
62
maass_lift_func = ring.type()._maass_generators
63
maass_lift_preimage_func = ring.type()._maass_generator_preimages
64
65
lift_polys = []; preims = []
66
monomials = set()
67
68
for k in xrange(min((weight // 2) - ((weight // 2) % 2), weight - 4), 3, -2) :
69
if k not in subspaces :
70
subspaces[k] = ring.graded_submodule(k)
71
if weight - k not in subspaces :
72
subspaces[weight - k] = ring.graded_submodule(weight - k)
73
74
try :
75
kgs = zip(subspaces[k].maass_space()._provided_basis(), maass_lift_preimage_func(k))
76
ogs = zip(subspaces[weight - k].maass_space()._provided_basis(), maass_lift_preimage_func(weight - k))
77
except ValueError :
78
continue
79
80
for f_coords,f_pre in kgs :
81
for g_coords,g_pre in ogs :
82
assert f_coords.parent().graded_ambient() is ring
83
assert g_coords.parent().graded_ambient() is ring
84
85
f = ring(f_coords)
86
g = ring(g_coords)
87
88
fg_poly = (f*g)._reduce_polynomial()
89
monomials = monomials.union(set(fg_poly.monomials()))
90
91
M = matrix( QQ, len(lift_polys) + 1,
92
[ poly.monomial_coefficient(m)
93
for poly in lift_polys + [fg_poly]
94
for m in monomials] )
95
96
# TODO : Use linbox
97
try :
98
if magma(M).Rank() <= len(lift_polys) :
99
continue
100
except TypeError :
101
for i in xrange(10) :
102
Mp = matrix(Qp(random_prime(10**10), 10), M)
103
if Mp.rank() > len(lift_polys) : break
104
else :
105
if lazy_rank_check :
106
continue
107
elif M.rank() <= len(lift_polys) :
108
continue
109
110
lift_polys.append(fg_poly)
111
preims.append([f_pre, g_pre])
112
113
if len(lift_polys) == dim :
114
break
115
116
if len(lift_polys) == dim :
117
ss = construct_from_maass_products(ring, weight, zip(preims, lift_polys), True, False, True)
118
poly_coords = [[0]*i + [1] + (len(lift_polys) - i - 1)*[0] for i in xrange(len(lift_polys))]
119
else :
120
# The products of two Maass lifts don't span this space
121
# we hence have to consider the Maass lifts
122
ss = ring.graded_submodule(weight)
123
poly_coords = [ss.coordinates(ring(p)) for p in lift_polys]
124
125
maass_lifts = maass_lift_func(weight, precision)
126
preims[0:0] = [[p] for p in maass_lift_preimage_func(weight)]
127
all_coords = map(ss.coordinates, maass_lifts) + poly_coords
128
129
M = matrix(QQ, all_coords).transpose()
130
131
nmb_mls = len(maass_lifts)
132
for i in xrange(10) :
133
Mp = matrix(Qp(random_prime(10**10), 10), M)
134
pvs = Mp.pivots()
135
if pvs[:nmb_mls] == range(nmb_mls) and \
136
len(pvs) == dim :
137
break
138
else :
139
pvs = M.pivots()
140
141
142
if len(pvs) == dim :
143
return [(preims[i], ring(ss(all_coords[i])).polynomial()) for i in pvs]
144
else :
145
raise RuntimeError, "The products of at most two Maass lifts don't span " + \
146
"this space"
147
148
def construct_from_maass_products(ring, weight, products, is_basis = True,
149
provides_maass_spezialschar = False,
150
is_integral = False,
151
lazy_rank_check = True) :
152
r"""
153
Pass the return value of spanning_maass_products of a space of Siegel modular
154
forms of same type. This will return a space using these forms.
155
Whenever ``is_basis`` is False the the products are first filtered to yield a
156
basis.
157
"""
158
assert QQ.has_coerce_map_from(ring.base_ring()) or ring.base_ring() is ZZ, \
159
"%s doesn't have rational base field" % ring
160
161
dim = ring.graded_submodule(weight).dimension()
162
163
## if the products don't provide a basis, we have to choose one
164
if not is_basis :
165
## we prefer to use Maass lifts, since they are very cheap
166
maass_forms = []; non_maass_forms = []
167
for p in products :
168
if len(p[0]) == 1 :
169
maass_forms.append(p)
170
else :
171
non_maass_forms.append(p)
172
173
174
monomials = set()
175
lift_polys = []
176
products = []
177
for lifts, lift_poly in maass_forms + non_maass_forms :
178
red_poly = ring(ring.relations().ring()(lift_poly))._reduce_polynomial()
179
monomials = monomials.union(set(red_poly.monomials()))
180
181
M = matrix( QQ, len(lift_polys) + 1,
182
[ poly.monomial_coefficient(m)
183
for poly in lift_polys + [lift_poly]
184
for m in monomials] )
185
186
# TODO : Use linbox
187
try :
188
if magma(M).Rank() > len(lift_polys) :
189
break
190
except TypeError :
191
for i in xrange(10) :
192
Mp = matrix(Qp(random_prime(10**10), 10), M)
193
if Mp.rank() > len(lift_polys) : break
194
else :
195
if lazy_rank_check :
196
continue
197
elif M.rank() <= len(lift_polys) :
198
continue
199
200
lift_polys.append(red_poly)
201
products.append((lifts, red_poly))
202
203
if len(products) == dim :
204
break
205
else :
206
raise ValueError, "products don't provide a basis"
207
208
basis = []
209
210
if provides_maass_spezialschar :
211
maass_form_indices = []
212
for i, (lifts, lift_poly) in enumerate(products) :
213
e = ring(ring.relations().ring()(lift_poly))
214
215
if len(lifts) == 1 :
216
l = lifts[0]
217
e._set_fourier_expansion(
218
SiegelModularFormG2MaassLift(l[0], l[1], ring.fourier_expansion_precision(),
219
is_integral = is_integral) )
220
elif len(lifts) == 2 :
221
(l0, l1) = tuple(lifts)
222
e._set_fourier_expansion(
223
EquivariantMonoidPowerSeries_LazyMultiplication(
224
SiegelModularFormG2MaassLift(l0[0], l0[1], ring.fourier_expansion_precision(),
225
is_integral = is_integral),
226
SiegelModularFormG2MaassLift(l1[0], l1[1], ring.fourier_expansion_precision(),
227
is_integral = is_integral) ) )
228
229
else :
230
e._set_fourier_expansion(
231
prod( SiegelModularFormG2MaassLift(l[0], l[1], ring.precision(),
232
is_integral = is_integral)
233
for l in lifts) )
234
basis.append(e)
235
236
if provides_maass_spezialschar and len(lifts) == 1 :
237
maass_form_indices.append(i)
238
239
ss = ring._submodule(basis, grading_indices = (weight,), is_heckeinvariant = True)
240
if provides_maass_spezialschar :
241
maass_coords = [ ss([0]*i + [1] + [0]*(dim-i-1))
242
for i in maass_form_indices ]
243
ss.maass_space.set_cache(
244
SiegelModularFormG2Submodule_maassspace(ss, map(ss, maass_coords)) )
245
246
return ss
247
248