Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241818 views
1
r"""
2
The Hecke action for paramodular forms of degree 2.
3
4
AUTHOR :
5
-- Martin Raum (2010 - 05 - 04) Initial version, based on Siegel modular forms case.
6
"""
7
8
#===============================================================================
9
#
10
# Copyright (C) 2010 Martin Raum
11
#
12
# This program is free software; you can redistribute it and/or
13
# modify it under the terms of the GNU General Public License
14
# as published by the Free Software Foundation; either version 3
15
# of the License, or (at your option) any later version.
16
#
17
# This program is distributed in the hope that it will be useful,
18
# but WITHOUT ANY WARRANTY; without even the implied warranty of
19
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
# General Public License for more details.
21
#
22
# You should have received a copy of the GNU General Public License
23
# along with this program; if not, see <http://www.gnu.org/licenses/>.
24
#
25
#===============================================================================
26
27
from psage.modform.paramodularforms.paramodularformd2_fourierexpansion_cython import apply_GL_to_form
28
from sage.misc.cachefunc import cached_method
29
from sage.misc.latex import latex
30
from sage.modular.modsym.p1list import P1List
31
from sage.rings.arith import gcd
32
from sage.rings.integer import Integer
33
from sage.structure.sage_object import SageObject
34
from psage.modform.paramodularforms import siegelmodularformg2_misc_cython
35
36
_paramodularformd2_heckeoperator_cache = dict()
37
38
#===============================================================================
39
# SiegelModularFormG2FourierExpansionHeckeAction
40
#===============================================================================
41
42
def ParamodularFormD2FourierExpansionHeckeAction( n ) :
43
global _paramodularformd2_heckeoperator_cache
44
45
try :
46
return _paramodularformd2_heckeoperator_cache[n]
47
except KeyError :
48
A = ParamodularFormD2FourierExpansionHeckeAction_class(n)
49
_paramodularformd2_heckeoperator_cache[n] = A
50
51
return A
52
53
#===============================================================================
54
# ParamodularFormD2FourierExpansionHeckeAction_class
55
#===============================================================================
56
57
class ParamodularFormD2FourierExpansionHeckeAction_class (SageObject):
58
r"""
59
Implements a Hecke operator acting on paramodular modular forms of degree 2.
60
"""
61
62
def __init__(self, n):
63
self.__l = n
64
65
self.__l_divisors = siegelmodularformg2_misc_cython.divisor_dict(n + 1)
66
67
def eval(self, expansion, weight = None) :
68
if weight is None :
69
try :
70
weight = expansion.weight()
71
except AttributeError :
72
raise ValueError, "weight must be defined for the Hecke action"
73
74
precision = expansion.precision()
75
if precision.is_infinite() :
76
precision = expansion._bounding_precision()
77
else :
78
precision = precision._hecke_operator(self.__l)
79
characters = expansion.non_zero_components()
80
expansion_level = precision.level()
81
82
if gcd(expansion_level, self.__l) != 1 :
83
raise ValueError, "Level of expansion and of Hecke operator must be coprime."
84
85
hecke_expansion = dict()
86
for ch in characters :
87
hecke_expansion[ch] = dict( (k, self.hecke_coeff(expansion, ch, k, weight, expansion_level))
88
for k in precision )
89
90
result = expansion.parent()._element_constructor_(hecke_expansion)
91
result._set_precision(expansion.precision()._hecke_operator(self.__l))
92
93
return result
94
95
# TODO : reimplement in cython
96
def hecke_coeff(self, expansion, ch, ((a,b,c), l), k, N) :
97
r"""
98
Computes the coefficient indexed by $(a,b,c)$ of $T(\ell) (F)$
99
"""
100
character_eval = expansion.parent()._character_eval_function()
101
102
if N == 1 :
103
## We have to consider that now (a,b,c) -> (c, b, a)
104
raise NotImplementedError
105
106
(a, b, c) = apply_GL_to_form(expansion.precision()._p1list()[l], (a, b, c))
107
108
ell = self.__l
109
coeff = 0
110
for t1 in self.__l_divisors[ell]:
111
for t2 in self.__l_divisors[t1]:
112
for V in self.get_representatives(t1/t2, N):
113
(aprime, bprime, cprime) = self.change_variables(V,(a,b,c))
114
if aprime % t1 == 0 and bprime % t2 == 0 and cprime % (N * t2) == 0:
115
coeff = coeff + character_eval(V, ch) * t1**(k-2)*t2**(k-1) \
116
* expansion[( ch, (( (ell*aprime) //t1**2,
117
(ell*bprime) //t1//t2,
118
(ell*cprime) //t2**2 ), 1) )]
119
120
return coeff
121
122
@cached_method
123
def get_representatives( self, t, N) :
124
r"""
125
A helper function used in hecke_coeff that computes the right
126
coset representatives of $\Gamma^0(t) \cap \Gamma_0(N) \ Gamma_0(N)$ where
127
$\Gamma^0(t)$ is the subgroup of $SL(2,Z)$ where the upper right hand
128
corner is divisible by $t$.
129
130
NOTE
131
We use the bijection $\Gamma^0(t)\SL(2,Z) \rightarrow P^1(\Z/t\Z)$
132
given by $A \mapsto [1:0]A$.
133
"""
134
if t == 1 : return [(1,0,0,1)]
135
136
rep_list = []
137
138
for (x,y) in P1List(t):
139
## we know that (N, x, y) = 1
140
N1 = gcd(N, x)
141
if N1 != 1 :
142
x = x + t * N // N1
143
144
## we calculate a pair c,d satisfying a minimality condition
145
## to make later multiplications cheaper
146
(_, d, c) = Integer(x)._xgcd(Integer(N * y), minimal=True)
147
148
#print (x, y, -N * c, d)
149
rep_list.append((x, y, -N * c, d))
150
151
return rep_list
152
153
@staticmethod
154
def change_variables((a,b,c,d), (n,r,m)):
155
r"""
156
A helper function used in hecke_coeff that computes the
157
quadratic form [nprime,rprime,mprime] given by $Q((x,y) V)$
158
where $Q=[n,r,m]$ and $V$ is a 2 by 2 matrix given by (a,b,c,d)
159
"""
160
return ( n*a**2 + r*a*b + m*b**2, 2*(n*a*c + m*b*d) + r*(a*d + c*b), \
161
n*c**2 + r*c*d + m*d**2 )
162
163
def _repr_(self) :
164
return '%s-th Hecke operator for paramodular forms' % self.__l
165
166
def _latex_(self) :
167
return latex(self.__n) + '-th Hecke operator for paramodular forms'
168
169