Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241818 views
1
r"""
2
We provide methods to create Fourier expansions of (weak) Jacobi forms `\mathrm{mod} p`.
3
"""
4
5
#===============================================================================
6
#
7
# Copyright (C) 2010 Martin Raum
8
#
9
# This program is free software; you can redistribute it and/or
10
# modify it under the terms of the GNU General Public License
11
# as published by the Free Software Foundation; either version 3
12
# of the License, or (at your option) any later version.
13
#
14
# This program is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
# General Public License for more details.
18
#
19
# You should have received a copy of the GNU General Public License
20
# along with this program; if not, see <http://www.gnu.org/licenses/>.
21
#
22
#===============================================================================
23
24
from sage.misc.all import prod
25
from sage.rings.all import PowerSeriesRing, GF
26
from sage.rings.all import binomial, factorial
27
from sage.structure.sage_object import SageObject
28
import operator
29
30
#===============================================================================
31
# JacobiFormD1NNModularFactory_class
32
#===============================================================================
33
34
class JacobiFormD1NNModularFactory_class (SageObject) :
35
36
def __init__(self, precision, p) :
37
self.__precision = precision
38
self.__power_series_ring = PowerSeriesRing(GF(p), 'q')
39
self.__p = int(p)
40
41
def index(self) :
42
return self.__precision.jacobi_index()
43
44
def power_series_ring(self) :
45
return self.__power_series_ring
46
47
def _qexp_precision(self) :
48
return self.__precision.index()
49
50
def _set_theta_factors(self, theta_factors) :
51
self.__theta_factors = theta_factors
52
53
def _theta_factors(self) :
54
try :
55
return self.__theta_factors
56
except AttributeError :
57
raise RuntimeError( "Theta factors have to be set first" )
58
59
def _set_eta_factor(self, eta_factor) :
60
self.__eta_factor = eta_factor
61
62
def _eta_factor(self) :
63
try :
64
return self.__eta_factor
65
except AttributeError :
66
raise RuntimeError( "Eta factor have to be set first" )
67
68
def by_taylor_expansion(self, fs, k) :
69
"""
70
We combine the theta decomposition and the heat operator as in [Sko].
71
This yields a bijections of Jacobi forms of weight `k` and
72
`M_k \times S_{k+2} \times .. \times S_{k+2m}`.
73
74
NOTE:
75
76
To make ``phi_divs`` integral we introduce an extra factor
77
`2^{\mathrm{index}} * \mathrm{factorial}(k + 2 * \mathrm{index} - 1)`.
78
"""
79
## we introduce an abbreviations
80
p = self.__p
81
PS = self.power_series_ring()
82
83
if not len(fs) == self.__precision.jacobi_index() + 1 :
84
raise ValueError("fs must be a list of m + 1 elliptic modular forms or their fourier expansion")
85
86
qexp_prec = self._qexp_precision()
87
if qexp_prec is None : # there are no forms below the precision
88
return dict()
89
90
f_divs = dict()
91
for (i, f) in enumerate(fs) :
92
f_divs[(i, 0)] = PS(f(qexp_prec), qexp_prec)
93
94
for i in xrange(self.__precision.jacobi_index() + 1) :
95
for j in xrange(1, self.__precision.jacobi_index() - i + 1) :
96
f_divs[(i,j)] = f_divs[(i, j - 1)].derivative().shift(1)
97
98
phi_divs = list()
99
for i in xrange(self.__precision.jacobi_index() + 1) :
100
## This is the formula in Skoruppas thesis. He uses d/ d tau instead of d / dz which yields
101
## a factor 4 m
102
phi_divs.append( sum( f_divs[(j, i - j)] * (4 * self.__precision.jacobi_index())**i
103
* binomial(i,j) * ( 2**self.index() // 2**i)
104
* prod(2*(i - l) + 1 for l in xrange(1, i))
105
* (factorial(k + 2*self.index() - 1) // factorial(i + k + j - 1))
106
* factorial(2*self.__precision.jacobi_index() + k - 1)
107
for j in xrange(i + 1) ) )
108
109
phi_coeffs = dict()
110
for r in xrange(self.index() + 1) :
111
series = sum( map(operator.mul, self._theta_factors()[r], phi_divs) )
112
series = self._eta_factor() * series
113
114
for n in xrange(qexp_prec) :
115
phi_coeffs[(n, r)] = int(series[n].lift()) % p
116
117
return phi_coeffs
118
119