Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241818 views
1
r"""
2
Functions for reduction of Fourier indices and for multiplication of
3
paramodular modular forms.
4
5
AUTHORS:
6
7
- Martin Raum (2010 - 04 - 09) Intitial version
8
"""
9
10
#===============================================================================
11
#
12
# Copyright (C) 2010 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
include "interrupt.pxi"
30
include "stdsage.pxi"
31
include "cdefs.pxi"
32
33
include 'sage/ext/gmp.pxi'
34
35
from sage.rings.arith import gcd
36
from sage.rings.integer cimport Integer
37
38
## [a,b,c] a quadratic form; (u,x) an element of P1(ZZ/pZZ)
39
cdef struct para_index :
40
int a
41
int b
42
int c
43
int u
44
int x
45
46
#####################################################################
47
#####################################################################
48
#####################################################################
49
50
cdef dict _inverse_mod_N_cache = dict()
51
52
#####################################################################
53
#####################################################################
54
#####################################################################
55
56
#===============================================================================
57
# apply_GL_to_form
58
#===============================================================================
59
60
cpdef apply_GL_to_form(g, s) :
61
"""
62
Return g s g^\tr if s is written as a matrix [a, b/2, b/2, c].
63
"""
64
cdef int a, b, c, u, x
65
66
(u, x) = g
67
(a,b,c) = s
68
69
if u == 0 :
70
return (c, b, a)
71
else :
72
return (a, b + 2*x*a, c + b*x + x**2 * a)
73
74
#===============================================================================
75
# reduce
76
#===============================================================================
77
78
def reduce_GL(index, p1list) :
79
r"""
80
A reduced form `((a,b,c), l)` satisfies `0 \le b \le a \le c`.
81
"""
82
cdef int a, b, c, l, u, x, N
83
cdef para_index res
84
85
((a,b,c), l) = index
86
(u, x) = p1list[l]
87
N = p1list.N()
88
89
res = _reduce_ux(a, b, c, u, x, N)
90
91
## We use an exceptional rule for N = 1, since otherwise l = -1
92
if N == 1 :
93
return (((res.a, res.b, res.c), 0), 0)
94
else :
95
return (((res.a, res.b, res.c), p1list.index(res.u,res.x)), 0)
96
97
#===============================================================================
98
# _reduce_ux
99
#===============================================================================
100
101
cdef para_index _reduce_ux(int a, int b, int c, int u, int x, int N) :
102
r"""
103
We reduce the pair `(t, v)` by right action of `GL_2(ZZ)`.
104
v is a left coset representative with respect to `(GL_2(ZZ))_0 (N)`.
105
`(x, u)` is the second row of `v`.
106
107
NOTE:
108
The quadratic form is reduced following Algorithm 5.4.2 found in Cohen's
109
Computational Algebraic Number Theory.
110
"""
111
cdef para_index res
112
cdef int twoa, q, r
113
cdef int tmp
114
115
116
global _inverse_mod_N_cache
117
if not N in _inverse_mod_N_cache :
118
invN = PY_NEW(dict)
119
120
for i in xrange(N) :
121
if gcd(i,N) == 1 :
122
invN[i] = Integer(i).inverse_mod(N)
123
_inverse_mod_N_cache[N] = invN
124
125
inverse_mod_N = _inverse_mod_N_cache[N]
126
127
if b < 0 :
128
b = -b
129
130
if u != 0 :
131
x = (-x) % N
132
133
while ( b > a or a > c ) :
134
twoa = 2 * a
135
136
#if b not in range(-a+1,a+1):
137
if b > a :
138
## apply Euclidean step (translation)
139
q = b // twoa #(2*a)
140
r = b % twoa #(2*a)
141
if r > a :
142
## want (quotient and) remainder such that -a < r <= a
143
r = r - twoa # 2*a;
144
q = q + 1
145
c = c - b*q + a*q*q
146
b = r
147
148
if u != 0 :
149
x = (x + q) % N
150
151
## apply symmetric step (reflection) if necessary
152
if a > c:
153
#(a,c) = (c,a)
154
tmp = c
155
c = a
156
a = tmp
157
158
if u == 0 :
159
u = 1
160
x = 0
161
elif x == 0 :
162
u = 0
163
x = 1
164
else :
165
x = (-inverse_mod_N[x]) % N
166
167
#b = abs(b)
168
if b < 0:
169
b = -b
170
171
if u != 0 :
172
x = (-x) % N
173
## iterate
174
## We're finished! Return the GL2(ZZ)-reduced form (a,b,c):
175
176
res.a = a
177
res.b = b
178
res.c = c
179
res.u = u
180
res.x = x
181
182
return res
183
184