code / alex / psage / psage / modform / paramodularforms / paramodularformd2_fourierexpansion_cython.pyx
241818 viewsr"""1Functions for reduction of Fourier indices and for multiplication of2paramodular modular forms.34AUTHORS:56- Martin Raum (2010 - 04 - 09) Intitial version7"""89#===============================================================================10#11# Copyright (C) 2010 Martin Raum12#13# This program is free software; you can redistribute it and/or14# modify it under the terms of the GNU General Public License15# as published by the Free Software Foundation; either version 316# of the License, or (at your option) any later version.17#18# This program is distributed in the hope that it will be useful,19# but WITHOUT ANY WARRANTY; without even the implied warranty of20# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU21# General Public License for more details.22#23# You should have received a copy of the GNU General Public License24# along with this program; if not, see <http://www.gnu.org/licenses/>.25#26#===============================================================================2728include "interrupt.pxi"29include "stdsage.pxi"30include "cdefs.pxi"3132include 'sage/ext/gmp.pxi'3334from sage.rings.arith import gcd35from sage.rings.integer cimport Integer3637## [a,b,c] a quadratic form; (u,x) an element of P1(ZZ/pZZ)38cdef struct para_index :39int a40int b41int c42int u43int x4445#####################################################################46#####################################################################47#####################################################################4849cdef dict _inverse_mod_N_cache = dict()5051#####################################################################52#####################################################################53#####################################################################5455#===============================================================================56# apply_GL_to_form57#===============================================================================5859cpdef apply_GL_to_form(g, s) :60"""61Return g s g^\tr if s is written as a matrix [a, b/2, b/2, c].62"""63cdef int a, b, c, u, x6465(u, x) = g66(a,b,c) = s6768if u == 0 :69return (c, b, a)70else :71return (a, b + 2*x*a, c + b*x + x**2 * a)7273#===============================================================================74# reduce75#===============================================================================7677def reduce_GL(index, p1list) :78r"""79A reduced form `((a,b,c), l)` satisfies `0 \le b \le a \le c`.80"""81cdef int a, b, c, l, u, x, N82cdef para_index res8384((a,b,c), l) = index85(u, x) = p1list[l]86N = p1list.N()8788res = _reduce_ux(a, b, c, u, x, N)8990## We use an exceptional rule for N = 1, since otherwise l = -191if N == 1 :92return (((res.a, res.b, res.c), 0), 0)93else :94return (((res.a, res.b, res.c), p1list.index(res.u,res.x)), 0)9596#===============================================================================97# _reduce_ux98#===============================================================================99100cdef para_index _reduce_ux(int a, int b, int c, int u, int x, int N) :101r"""102We reduce the pair `(t, v)` by right action of `GL_2(ZZ)`.103v is a left coset representative with respect to `(GL_2(ZZ))_0 (N)`.104`(x, u)` is the second row of `v`.105106NOTE:107The quadratic form is reduced following Algorithm 5.4.2 found in Cohen's108Computational Algebraic Number Theory.109"""110cdef para_index res111cdef int twoa, q, r112cdef int tmp113114115global _inverse_mod_N_cache116if not N in _inverse_mod_N_cache :117invN = PY_NEW(dict)118119for i in xrange(N) :120if gcd(i,N) == 1 :121invN[i] = Integer(i).inverse_mod(N)122_inverse_mod_N_cache[N] = invN123124inverse_mod_N = _inverse_mod_N_cache[N]125126if b < 0 :127b = -b128129if u != 0 :130x = (-x) % N131132while ( b > a or a > c ) :133twoa = 2 * a134135#if b not in range(-a+1,a+1):136if b > a :137## apply Euclidean step (translation)138q = b // twoa #(2*a)139r = b % twoa #(2*a)140if r > a :141## want (quotient and) remainder such that -a < r <= a142r = r - twoa # 2*a;143q = q + 1144c = c - b*q + a*q*q145b = r146147if u != 0 :148x = (x + q) % N149150## apply symmetric step (reflection) if necessary151if a > c:152#(a,c) = (c,a)153tmp = c154c = a155a = tmp156157if u == 0 :158u = 1159x = 0160elif x == 0 :161u = 0162x = 1163else :164x = (-inverse_mod_N[x]) % N165166#b = abs(b)167if b < 0:168b = -b169170if u != 0 :171x = (-x) % N172## iterate173## We're finished! Return the GL2(ZZ)-reduced form (a,b,c):174175res.a = a176res.b = b177res.c = c178res.u = u179res.x = x180181return res182183184