Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241818 views
1
"""
2
Functions to reduce indices of Jacobi forms and to multiply expansions
3
of Jacobi forms.
4
5
AUTHORS:
6
7
- Martin Raum (2010 - 04 - 05) 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
include "interrupt.pxi"
30
include "stdsage.pxi"
31
include "cdefs.pxi"
32
33
include 'sage/ext/gmp.pxi'
34
35
from sage.rings.integer cimport Integer
36
from sage.rings.ring cimport Ring
37
38
cdef struct jac_index_sgn :
39
int n
40
int r
41
int s
42
43
#####################################################################
44
#####################################################################
45
#####################################################################
46
47
#===============================================================================
48
# creduce
49
#===============================================================================
50
51
def creduce(k, m) :
52
cdef jac_index_sgn res
53
54
(n, r) = k
55
res = _creduce(n, r, m)
56
57
return ((res.n, res.r), res.s)
58
59
#===========================================================================
60
# _creduce
61
#===========================================================================
62
63
cdef jac_index_sgn _creduce(int n, int r, int m) :
64
cdef int r_red, n_red, s
65
cdef jac_index_sgn res
66
67
r_red = r % (2 * m)
68
if r_red > m :
69
res.s = -1
70
r_red = 2 * m - r_red
71
else :
72
res.s = 1
73
74
n_red = n - (r**2 - r_red**2)/(4 * m)
75
76
while n_red < 0 :
77
r_red = r_red + 2 * m
78
n_red = n + (4*m*r_red - 4*m**2)
79
80
res.n = n_red
81
res.r = r_red
82
83
return res
84
85
#####################################################################
86
#####################################################################
87
#####################################################################
88
89
#===============================================================================
90
# mult_coeff_int
91
#===============================================================================
92
93
cpdef mult_coeff_int(result_key, coeffs_dict1, coeffs_dict2, ch1, ch2, result, int m) :
94
r"""
95
Returns the value at ``result_key`` of the coefficient dictionary of the product
96
of the two Jacobi forms with dictionary ``coeffs_dict1`` and ``coeffs_dict2``.
97
"""
98
cdef int n,r
99
cdef int n1, r1
100
cdef int n2, r2
101
cdef int fm
102
103
cdef mpz_t sqrt1, sqrt2, tmp, mpz_zero
104
cdef mpz_t left, right
105
cdef mpz_t acc
106
107
mpz_init(sqrt1)
108
mpz_init(sqrt2)
109
mpz_init(tmp)
110
mpz_init(mpz_zero)
111
mpz_init(left)
112
mpz_init(right)
113
mpz_init(acc)
114
115
(n,r) = result_key
116
117
_sig_on
118
fm = 4 * m
119
for n1 in range(n + 1) :
120
n2 = n - n1
121
122
mpz_set_si(sqrt1, fm * n1)
123
mpz_sqrt(sqrt1, sqrt1)
124
125
mpz_set_si(sqrt2, fm * n2)
126
mpz_sqrt(sqrt2, sqrt2)
127
128
for r1 in range( r1 - mpz_get_si(sqrt2),
129
min( r1 + mpz_get_si(sqrt2) + 1,
130
mpz_get_si(sqrt1) + 1 ) ) :
131
r2 = r - r1
132
get_coeff_int(left, n1, r1, ch1, coeffs_dict1, m)
133
if mpz_cmp(left, mpz_zero) == 0 : continue
134
135
get_coeff_int(right, n2, r2, ch2, coeffs_dict2, m)
136
if mpz_cmp(right, mpz_zero) == 0 : continue
137
138
mpz_mul(tmp, left, right)
139
mpz_add(acc, acc, tmp)
140
_sig_off
141
142
mpz_set((<Integer>result).value, acc)
143
144
mpz_clear(sqrt1)
145
mpz_clear(sqrt2)
146
mpz_clear(tmp)
147
mpz_clear(mpz_zero)
148
mpz_clear(left)
149
mpz_clear(right)
150
mpz_clear(acc)
151
152
return result
153
154
#===============================================================================
155
# mult_coeff_int_weak
156
#===============================================================================
157
158
cpdef mult_coeff_int_weak(result_key, coeffs_dict1, coeffs_dict2, ch1, ch2, result, m) :
159
r"""
160
Returns the value at ``result_key`` of the coefficient dictionary of the product
161
of the two weak Jacobi forms with dictionary ``coeffs_dict1`` and ``coeffs_dict2``.
162
"""
163
cdef int n,r
164
cdef int n1, r1
165
cdef int n2, r2
166
cdef int fm, msq
167
168
cdef mpz_t sqrt1, sqrt2, tmp, mpz_zero
169
cdef mpz_t left, right
170
cdef mpz_t acc
171
172
mpz_init(sqrt1)
173
mpz_init(sqrt2)
174
mpz_init(tmp)
175
mpz_init(mpz_zero)
176
mpz_init(left)
177
mpz_init(right)
178
mpz_init(acc)
179
180
(n,r) = result_key
181
182
_sig_on
183
fm = 4 * m
184
msq = m**2
185
for n1 in range(n + 1) :
186
n2 = n - n1
187
188
mpz_set_si(sqrt1, fm * n1 + msq)
189
mpz_sqrt(sqrt1, sqrt1)
190
191
mpz_set_si(sqrt2, fm * n2 + msq)
192
mpz_sqrt(sqrt2, sqrt2)
193
194
for r1 in range( r1 - mpz_get_si(sqrt2),
195
min( r1 + mpz_get_si(sqrt2) + 1,
196
mpz_get_si(sqrt1) + 1 ) ) :
197
r2 = r - r1
198
get_coeff_int(left, n1, r1, ch1, coeffs_dict1, m)
199
if mpz_cmp(left, mpz_zero) == 0 : continue
200
201
get_coeff_int(right, n2, r2, ch2, coeffs_dict2, m)
202
if mpz_cmp(right, mpz_zero) == 0 : continue
203
204
mpz_mul(tmp, left, right)
205
mpz_add(acc, acc, tmp)
206
_sig_off
207
208
mpz_set((<Integer>result).value, acc)
209
210
mpz_clear(sqrt1)
211
mpz_clear(sqrt2)
212
mpz_clear(tmp)
213
mpz_clear(mpz_zero)
214
mpz_clear(left)
215
mpz_clear(right)
216
mpz_clear(acc)
217
218
return result
219
220
#==============================================================================
221
# mult_coeff_generic
222
#==============================================================================
223
224
cpdef mult_coeff_generic(result_key, coeffs_dict1, coeffs_dict2, ch1, ch2, result, int m) :
225
r"""
226
Returns the value at ``result_key`` of the coefficient dictionary of the product
227
of the two Jacobi forms with dictionary ``coeffs_dict1`` and ``coeffs_dict2``.
228
"""
229
cdef int n,r
230
cdef int n1, r1
231
cdef int n2, r2
232
cdef int fm
233
234
cdef mpz_t sqrt1, sqrt2, tmp, mpz_zero
235
236
mpz_init(sqrt1)
237
mpz_init(sqrt2)
238
239
(n,r) = result_key
240
241
_sig_on
242
fm = 4 * m
243
for n1 in range(n + 1) :
244
n2 = n - n1
245
246
mpz_set_si(sqrt1, fm * n1)
247
mpz_sqrt(sqrt1, sqrt1)
248
249
mpz_set_si(sqrt2, fm * n2)
250
mpz_sqrt(sqrt2, sqrt2)
251
252
for r1 in range( r1 - mpz_get_si(sqrt2),
253
min( r1 + mpz_get_si(sqrt2) + 1,
254
mpz_get_si(sqrt1) + 1 ) ) :
255
r2 = r - r1
256
left = get_coeff_generic(n1, r1, ch1, coeffs_dict1, m)
257
if left is None : continue
258
259
right = get_coeff_generic(n2, r2, ch2, coeffs_dict2, m)
260
if right is None : continue
261
262
result += left*right
263
_sig_off
264
265
mpz_clear(sqrt1)
266
mpz_clear(sqrt2)
267
268
return result
269
270
#===============================================================================
271
# mult_coeff_generic_weak
272
#===============================================================================
273
274
cpdef mult_coeff_generic_weak(result_key, coeffs_dict1, coeffs_dict2, ch1, ch2, result, int m) :
275
r"""
276
Returns the value at ``result_key`` of the coefficient dictionary of the product
277
of the two Jacobi forms with dictionary ``coeffs_dict1`` and ``coeffs_dict2``.
278
"""
279
cdef int n,r
280
cdef int n1, r1
281
cdef int n2, r2
282
cdef int fm, msq
283
284
cdef mpz_t sqrt1, sqrt2, tmp, mpz_zero
285
286
mpz_init(sqrt1)
287
mpz_init(sqrt2)
288
289
(n,r) = result_key
290
291
_sig_on
292
fm = 4 * m
293
msq = m**2
294
for n1 in range(n + 1) :
295
n2 = n - n1
296
297
mpz_set_si(sqrt1, fm * n1 + msq)
298
mpz_sqrt(sqrt1, sqrt1)
299
300
mpz_set_si(sqrt2, fm * n2 + msq)
301
mpz_sqrt(sqrt2, sqrt2)
302
303
for r1 in range( r1 - mpz_get_si(sqrt2),
304
min( r1 + mpz_get_si(sqrt2) + 1,
305
mpz_get_si(sqrt1) + 1 ) ) :
306
r2 = r - r1
307
left = get_coeff_generic(n1, r1, ch1, coeffs_dict1, m)
308
if left is None : continue
309
310
right = get_coeff_generic(n2, r2, ch2, coeffs_dict2, m)
311
if right is None : continue
312
313
result += left*right
314
_sig_off
315
316
mpz_clear(sqrt1)
317
mpz_clear(sqrt2)
318
319
return result
320
321
#####################################################################
322
#####################################################################
323
#####################################################################
324
325
#===============================================================================
326
# get_coeff_int
327
#===============================================================================
328
329
cdef inline void get_coeff_int(mpz_t dest, int n, int r, int ch, coeffs_dict, int m) :
330
cdef jac_index_sgn tmp_ind
331
332
mpz_set_si(dest, 0)
333
334
tmp_ind = _creduce(n, r, m)
335
try :
336
mpz_set(dest, (<Integer>(coeffs_dict[(tmp_ind.n, tmp_ind.r)])).value)
337
if ch == -1 and tmp_ind.s == -1 :
338
mpz_neg(dest, dest)
339
except KeyError :
340
pass
341
342
#===============================================================================
343
# get_coeff_generic
344
#===============================================================================
345
346
cdef inline get_coeff_generic(int n, int r, int ch, coeffs_dict, int m):
347
cdef jac_index_sgn tmp_ind
348
349
tmp_ind = _creduce(n, r, m)
350
try :
351
if ch == -1 and tmp_ind.s == -1 :
352
return -coeffs_dict[(tmp_ind.n, tmp_ind.r)]
353
else :
354
return coeffs_dict[(tmp_ind.n, tmp_ind.r)]
355
356
except KeyError :
357
return None
358
g
359