Path: blob/master/src/sage/modular/modsym/heilbronn.pyx
8820 views
"""1Heilbronn matrix computation2"""34#*****************************************************************************5# Copyright (C) 2004 William Stein <[email protected]>6#7# Distributed under the terms of the GNU General Public License (GPL)8#9# This code is distributed in the hope that it will be useful,10# but WITHOUT ANY WARRANTY; without even the implied warranty of11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12# General Public License for more details.13#14# The full text of the GPL is available at:15#16# http://www.gnu.org/licenses/17#*****************************************************************************1819import sage.rings.arith2021import sage.misc.misc2223include 'sage/ext/cdefs.pxi'24include 'sage/ext/interrupt.pxi'25include 'sage/ext/stdsage.pxi'26from sage.libs.flint.flint cimport *27include "sage/libs/flint/fmpz_poly.pxi"2829cdef extern from "<math.h>":30float roundf(float x)3132cimport p1list33import p1list34cdef p1list.export export35export = p1list.export()3637from apply cimport Apply38cdef Apply PolyApply= Apply()3940from sage.rings.integer cimport Integer41from sage.matrix.matrix_rational_dense cimport Matrix_rational_dense42from sage.matrix.matrix_cyclo_dense cimport Matrix_cyclo_dense4344ctypedef long long llong4546cdef int llong_prod_mod(int a, int b, int N):47cdef int c48c = <int> ( ((<llong> a) * (<llong> b)) % (<llong> N) )49if c < 0:50c = c + N51return c5253cdef struct list:54int *v55int i # how many positions of list are filled56int n # how much memory has been allocated5758cdef int* expand(int *v, int n, int new_length) except NULL:59cdef int *w, i60w = <int*> sage_malloc(new_length*sizeof(int))61if w == <int*> 0:62return NULL63if v:64for i in range(n):65w[i] = v[i]66sage_free(v)67return w6869cdef int list_append(list* L, int a) except -1:70cdef int j71if L.i >= L.n:72j = 10 + 2*L.n73L.v = expand(L.v, L.n, j)74L.n = j75L.v[L.i] = a76L.i = L.i + 17778cdef int list_append4(list* L, int a, int b, int c, int d) except -1:79list_append(L, a)80list_append(L, b)81list_append(L, c)82list_append(L, d)8384cdef void list_clear(list L):85sage_free(L.v)8687cdef void list_init(list* L):88L.n = 1689L.i = 090L.v = expand(<int*>0, 0, L.n)919293cdef class Heilbronn:94cdef int length95cdef list list9697def __dealloc__(self):98list_clear(self.list)99100def _initialize_list(self):101"""102Initialize the list of matrices corresponding to self. (This103function is automatically called during initialization.)104105.. note:106107This function must be overridden by all derived classes!108109EXAMPLES::110111sage: H = sage.modular.modsym.heilbronn.Heilbronn()112sage: H._initialize_list()113Traceback (most recent call last):114...115NotImplementedError116"""117raise NotImplementedError118119def __getitem__(self, int n):120"""121Return the nth matrix in self.122123EXAMPLES::124125sage: H = HeilbronnCremona(11)126sage: H[17]127[-1, 0, 1, -11]128sage: H[98234]129Traceback (most recent call last):130...131IndexError132"""133if n < 0 or n >= self.length:134raise IndexError135return [self.list.v[4*n], self.list.v[4*n+1], \136self.list.v[4*n+2], self.list.v[4*n+3]]137138def __len__(self):139"""140Return the number of matrices in self.141142EXAMPLES::143144sage: HeilbronnCremona(2).__len__()1454146"""147return self.length148149def to_list(self):150"""151Return the list of Heilbronn matrices corresponding to self. Each152matrix is given as a list of four ints.153154EXAMPLES::155156sage: H = HeilbronnCremona(2); H157The Cremona-Heilbronn matrices of determinant 2158sage: H.to_list()159[[1, 0, 0, 2], [2, 0, 0, 1], [2, 1, 0, 1], [1, 0, 1, 2]]160"""161cdef int i162L = []163for i in range(self.length):164L.append([self.list.v[4*i], self.list.v[4*i+1], \165self.list.v[4*i+2], self.list.v[4*i+3]])166return L167168cdef apply_only(self, int u, int v, int N, int* a, int* b):169"""170INPUT:171172173- ``u, v, N`` - integers174175- ``a, b`` - preallocated int arrays of the length176self.177178179OUTPUT: sets the entries of a,b180181EXAMPLES::182183sage: M = ModularSymbols(33,2,1) # indirect test184sage: sage.modular.modsym.heilbronn.hecke_images_gamma0_weight2(1,0,33,[2,3],M.manin_gens_to_basis())185[ 3 0 1 0 -1 1]186[ 3 2 2 0 -2 2]187sage: z = M((1,0))188sage: [M.T(n)(z).element() for n in [2,2]]189[(3, 0, 1, 0, -1, 1), (3, 0, 1, 0, -1, 1)]190"""191cdef Py_ssize_t i192sig_on()193if N == 1: # easy special case194for i in range(self.length):195a[i] = b[i] = 0196if N < 32768: # use ints with no reduction modulo N197for i in range(self.length):198a[i] = u*self.list.v[4*i] + v*self.list.v[4*i+2]199b[i] = u*self.list.v[4*i+1] + v*self.list.v[4*i+3]200elif N < 46340: # use ints but reduce mod N so can add two201for i in range(self.length):202a[i] = (u * self.list.v[4*i])%N + (v * self.list.v[4*i+2])%N203b[i] = (u * self.list.v[4*i+1])%N + (v * self.list.v[4*i+3])%N204else:205for i in range(self.length):206a[i] = llong_prod_mod(u,self.list.v[4*i],N) + llong_prod_mod(v,self.list.v[4*i+2], N)207b[i] = llong_prod_mod(u,self.list.v[4*i+1],N) + llong_prod_mod(v,self.list.v[4*i+3], N)208sig_off()209210cdef apply_to_polypart(self, fmpz_poly_t* ans, int i, int k):211"""212INPUT:213214- ``ans`` - fmpz_poly_t\*; pre-allocated an215initialized array of self.length fmpz_poly_t's216- ``i`` - integer217- ``k`` - integer218219OUTPUT: sets entries of ans220"""221cdef int j, m = k-2222for j in range(self.length):223PolyApply.apply_to_monomial_flint(ans[j], i, m,224self.list.v[4*j], self.list.v[4*j+1],225self.list.v[4*j+2], self.list.v[4*j+3])226227def apply(self, int u, int v, int N):228"""229Return a list of pairs ((c,d),m), which is obtained as follows: 1)230Compute the images (a,b) of the vector (u,v) (mod N) acted on by231each of the HeilbronnCremona matrices in self. 2) Reduce each (a,b)232to canonical form (c,d) using p1normalize 3) Sort. 4) Create the233list ((c,d),m), where m is the number of times that (c,d) appears234in the list created in steps 1-3 above. Note that the pairs235((c,d),m) are sorted lexicographically by (c,d).236237INPUT:238239- ``u, v, N`` - integers240241OUTPUT: list242243EXAMPLES::244245sage: H = sage.modular.modsym.heilbronn.HeilbronnCremona(2); H246The Cremona-Heilbronn matrices of determinant 2247sage: H.apply(1,2,7)248[((1, 5), 1), ((1, 6), 1), ((1, 1), 1), ((1, 4), 1)]249"""250cdef int i, a, b, c, d, s251cdef object X252M = {}253t = sage.misc.misc.verbose("start making list M.",level=5)254sig_on()255if N < 32768: # use ints with no reduction modulo N256for i in range(self.length):257a = u*self.list.v[4*i] + v*self.list.v[4*i+2]258b = u*self.list.v[4*i+1] + v*self.list.v[4*i+3]259export.c_p1_normalize_int(N, a, b, &c, &d, &s, 0)260X = (c,d)261if M.has_key(X):262M[X] = M[X] + 1263else:264M[X] = 1265elif N < 46340: # use ints but reduce mod N so can add two266for i in range(self.length):267a = (u * self.list.v[4*i])%N + (v * self.list.v[4*i+2])%N268b = (u * self.list.v[4*i+1])%N + (v * self.list.v[4*i+3])%N269export.c_p1_normalize_int(N, a, b, &c, &d, &s, 0)270X = (c,d)271if M.has_key(X):272M[X] = M[X] + 1273else:274M[X] = 1275else:276for i in range(self.length):277a = llong_prod_mod(u,self.list.v[4*i],N) + llong_prod_mod(v,self.list.v[4*i+2], N)278b = llong_prod_mod(u,self.list.v[4*i+1],N) + llong_prod_mod(v,self.list.v[4*i+3], N)279export.c_p1_normalize_llong(N, a, b, &c, &d, &s, 0)280X = (c,d)281if M.has_key(X):282M[X] = M[X] + 1283else:284M[X] = 1285t = sage.misc.misc.verbose("finished making list M.",t, level=5)286mul = []287for x,y in M.items():288mul.append((x,y))289t = sage.misc.misc.verbose("finished making mul list.",t, level=5)290sig_off()291return mul292293cdef class HeilbronnCremona(Heilbronn):294cdef public int p295296def __init__(self, int p):297"""298Create the list of Heilbronn-Cremona matrices of determinant p.299300EXAMPLES::301302sage: H = HeilbronnCremona(3) ; H303The Cremona-Heilbronn matrices of determinant 3304sage: H.to_list()305[[1, 0, 0, 3],306[3, 1, 0, 1],307[1, 0, 1, 3],308[3, 0, 0, 1],309[3, -1, 0, 1],310[-1, 0, 1, -3]]311"""312if p <= 1 or not sage.rings.arith.is_prime(p):313raise ValueError, "p must be >= 2 and prime"314self.p = p315self._initialize_list()316317def __repr__(self):318"""319Return the string representation of self.320321EXAMPLES::322323sage: HeilbronnCremona(691).__repr__()324'The Cremona-Heilbronn matrices of determinant 691'325"""326return "The Cremona-Heilbronn matrices of determinant %s"%self.p327328def _initialize_list(self):329"""330Initialize the list of matrices corresponding to self. (This331function is automatically called during initialization.)332333EXAMPLES::334335sage: H = HeilbronnCremona.__new__(HeilbronnCremona)336sage: H.p = 5337sage: H338The Cremona-Heilbronn matrices of determinant 5339sage: H.to_list()340[]341sage: H._initialize_list()342sage: H.to_list()343[[1, 0, 0, 5],344[5, 2, 0, 1],345[2, 1, 1, 3],346[1, 0, 3, 5],347[5, 1, 0, 1],348[1, 0, 1, 5],349[5, 0, 0, 1],350[5, -1, 0, 1],351[-1, 0, 1, -5],352[5, -2, 0, 1],353[-2, 1, 1, -3],354[1, 0, -3, 5]]355"""356cdef int r, x1, x2, y1, y2, a, b, c, x3, y3, q, n, p357cdef list *L358list_init(&self.list)359L = &self.list360p = self.p361362list_append4(L, 1,0,0,p)363364# When p==2, then Heilbronn matrices are365# [[1,0,0,2], [2,0,0,1], [2,1,0,1], [1,0,1,2]]366# which are not given by the algorithm below.367if p == 2:368list_append4(L, 2,0,0,1)369list_append4(L, 2,1,0,1)370list_append4(L, 1,0,1,2)371self.length = 4372return373374# NOTE: In C, -p/2 means "round toward 0", but in Python it375# means "round down."376sig_on()377for r in range(-p/2, p/2+1):378x1=p; x2=-r; y1=0; y2=1; a=-p; b=r; c=0; x3=0; y3=0; q=0379list_append4(L, x1,x2,y1,y2)380while b:381q = <int>roundf(<float>a / <float> b)382c = a - b*q383a = -b384b = c385x3 = q*x2 - x1386x1 = x2; x2 = x3; y3 = q*y2 - y1; y1 = y2; y2 = y3387list_append4(L, x1,x2, y1,y2)388self.length = L.i/4389sig_off()390391392cdef class HeilbronnMerel(Heilbronn):393cdef public int n394395def __init__(self, int n):396r"""397Initialize the list of Merel-Heilbronn matrices of determinant398`n`.399400EXAMPLES::401402sage: H = HeilbronnMerel(3) ; H403The Merel-Heilbronn matrices of determinant 3404sage: H.to_list()405[[1, 0, 0, 3],406[1, 0, 1, 3],407[1, 0, 2, 3],408[2, 1, 1, 2],409[3, 0, 0, 1],410[3, 1, 0, 1],411[3, 2, 0, 1]]412"""413if n <= 0:414raise ValueError, "n (=%s) must be >= 1"%n415self.n = n416self._initialize_list()417418def __repr__(self):419"""420Return the string representation of self.421422EXAMPLES::423424sage: HeilbronnMerel(8).__repr__()425'The Merel-Heilbronn matrices of determinant 8'426"""427return "The Merel-Heilbronn matrices of determinant %s"%self.n428429def _initialize_list(self):430"""431Initialize the list of matrices corresponding to self. (This432function is automatically called during initialization.)433434EXAMPLES::435436sage: H = HeilbronnMerel.__new__(HeilbronnMerel)437sage: H.n = 5438sage: H439The Merel-Heilbronn matrices of determinant 5440sage: H.to_list()441[]442sage: H._initialize_list()443sage: H.to_list()444[[1, 0, 0, 5],445[1, 0, 1, 5],446[1, 0, 2, 5],447[1, 0, 3, 5],448[1, 0, 4, 5],449[2, 1, 1, 3],450[2, 1, 3, 4],451[3, 1, 1, 2],452[3, 2, 2, 3],453[4, 3, 1, 2],454[5, 0, 0, 1],455[5, 1, 0, 1],456[5, 2, 0, 1],457[5, 3, 0, 1],458[5, 4, 0, 1]]459"""460cdef int a, q, d, b, c, bc, n461cdef list *L462list_init(&self.list)463L = &self.list464n = self.n465466sig_on()467for a in range(1, n+1):468## We have ad-bc=n so c=0 and ad=n, or b=(ad-n)/c469## Must have ad - n >= 0, so d must be >= Ceiling(n/a).470q = n/a471if q*a == n:472d = q473for b in range(a):474list_append4(L, a,b,0,d)475for c in range(1, d):476list_append4(L, a,0,c,d)477for d in range(q+1, n+1):478bc = a*d-n479## Divisor c of bc must satisfy Floor(bc/c) lt a and c lt d.480## c ge (bc div a + 1) <=> Floor(bc/c) lt a (for integers)481## c le d - 1 <=> c lt d482for c in range(bc/a + 1, d):483if bc % c == 0:484list_append4(L,a,bc/c,c,d)485self.length = L.i/4486sig_off()487488489############################################################################490# Fast application of Heilbronn operators to computation of491# systems of Hecke eigenvalues.492# GAMMA0 trivial character weight 2 case493############################################################################494495496def hecke_images_gamma0_weight2(int u, int v, int N, indices, R):497"""498INPUT:499500- ``u, v, N`` - integers so that gcd(u,v,N) = 1501- ``indices`` - a list of positive integers502- ``R`` - matrix over QQ that writes each elements of503P1 = P1List(N) in terms of a subset of P1.504505506OUTPUT: a dense matrix whose columns are the images T_n(x)507for n in indices and x the Manin symbol (u,v), expressed508in terms of the basis.509510EXAMPLES::511512sage: M = ModularSymbols(23,2,1)513sage: A = sage.modular.modsym.heilbronn.hecke_images_gamma0_weight2(1,0,23,[1..6],M.manin_gens_to_basis())514sage: A515[ 1 0 0]516[ 3 0 -1]517[ 4 -2 -1]518[ 7 -2 -2]519[ 6 0 -2]520[12 -2 -4]521sage: z = M((1,0))522sage: [M.T(n)(z).element() for n in [1..6]]523[(1, 0, 0), (3, 0, -1), (4, -2, -1), (7, -2, -2), (6, 0, -2), (12, -2, -4)]524525TESTS::526527sage: M = ModularSymbols(389,2,1,GF(7))528sage: C = M.cuspidal_subspace()529sage: N = C.new_subspace()530sage: D = N.decomposition()531sage: D[1].q_eigenform(10, 'a') # indirect doctest532q + 4*q^2 + 2*q^3 + 6*q^5 + q^6 + 5*q^7 + 6*q^8 + q^9 + O(q^10)533534"""535cdef p1list.P1List P1 = p1list.P1List(N)536537# Create a zero dense matrix over QQ with len(indices) rows538# and #P^1(N) columns.539cdef Matrix_rational_dense T540from sage.matrix.all import matrix541from sage.rings.all import QQ542T = matrix(QQ, len(indices), len(P1), sparse=False)543original_base_ring = R.base_ring()544if original_base_ring != QQ:545R = R.change_ring(QQ)546547cdef Py_ssize_t i, j548cdef int *a, *b, k549550cdef Heilbronn H551552t = sage.misc.misc.verbose("computing non-reduced images of symbol under Hecke operators",553level=1, caller_name='hecke_images_gamma0_weight2')554for i, n in enumerate(indices):555# List the Heilbronn matrices of determinant n defined by Cremona or Merel556H = HeilbronnCremona(n) if sage.rings.arith.is_prime(n) else HeilbronnMerel(n)557558# Allocate memory to hold images of (u,v) under all Heilbronn matrices559a = <int*> sage_malloc(sizeof(int)*H.length)560if not a: raise MemoryError561b = <int*> sage_malloc(sizeof(int)*H.length)562if not b: raise MemoryError563564# Compute images of (u,v) under all Heilbronn matrices565H.apply_only(u, v, N, a, b)566567# Compute the indexes of these images.568# We just store them in the array a for simplicity.569for j in range(H.length):570# Compute index of the symbol a[j], b[j] in the standard list.571k = P1.index(a[j], b[j])572573# Now fill in row i of the matrix T.574if k != -1:575# The following line is just a dangerous direct way to do: T[i,k] += 1576T._add_ui_unsafe_assuming_int(i,k,1)577578# Free a and b579sage_free(a)580sage_free(b)581582t = sage.misc.misc.verbose("finished computing non-reduced images",583t, level=1, caller_name='hecke_images_gamma0_weight2')584585t = sage.misc.misc.verbose("Now reducing images of symbol",586level=1, caller_name='hecke_images_gamma0_weight2')587588# Return the product T * R, whose rows are the image of (u,v) under589# the Hecke operators T_n for n in indices.590if max(indices) <= 30: # In this case T tends to be very sparse591ans = T.sparse_matrix()._matrix_times_matrix_dense(R)592sage.misc.misc.verbose("did reduction using sparse multiplication",593t, level=1, caller_name='hecke_images_gamma0_weight2')594elif R.is_sparse():595ans = T * R.dense_matrix()596sage.misc.misc.verbose("did reduction using dense multiplication",597t, level=1, caller_name='hecke_images_gamma0_weight2')598else:599ans = T * R600sage.misc.misc.verbose("did reduction using dense multiplication",601t, level=1, caller_name='hecke_images_gamma0_weight2')602603if original_base_ring != QQ:604ans = ans.change_ring(original_base_ring)605606return ans607608609############################################################################610# Fast application of Heilbronn operators to computation of611# systems of Hecke eigenvalues.612# Nontrivial character but weight 2.613############################################################################614615616def hecke_images_nonquad_character_weight2(int u, int v, int N, indices, chi, R):617"""618Return images of the Hecke operators `T_n` for `n`619in the list indices, where chi must be a quadratic Dirichlet620character with values in QQ.621622R is assumed to be the relation matrix of a weight modular symbols623space over QQ with character chi.624625INPUT:626627- ``u, v, N`` - integers so that gcd(u,v,N) = 1628- ``indices`` - a list of positive integers629- ``chi`` - a Dirichlet character that takes values630in a nontrivial extension of QQ.631- ``R`` - matrix over QQ that writes each elements of632P1 = P1List(N) in terms of a subset of P1.633634635OUTPUT: a dense matrix with entries in the field QQ(chi) (the636values of chi) whose columns are the images T_n(x) for n in637indices and x the Manin symbol (u,v), expressed in terms of the638basis.639640EXAMPLES::641642sage: chi = DirichletGroup(13).0^2643sage: M = ModularSymbols(chi)644sage: eps = M.character()645sage: R = M.manin_gens_to_basis()646sage: sage.modular.modsym.heilbronn.hecke_images_nonquad_character_weight2(1,0,13,[1,2,6],eps,R)647[ 1 0 0 0]648[ zeta6 + 2 0 0 -1]649[ 7 -2*zeta6 + 1 -zeta6 - 1 -2*zeta6]650sage: x = M((1,0)); x.element()651(1, 0, 0, 0)652sage: M.T(2)(x).element()653(zeta6 + 2, 0, 0, -1)654sage: M.T(6)(x).element()655(7, -2*zeta6 + 1, -zeta6 - 1, -2*zeta6)656"""657cdef p1list.P1List P1 = p1list.P1List(N)658659from sage.rings.all import QQ660K = chi.base_ring()661662if K == QQ:663raise TypeError, "character must not be trivial or quadratic"664665if R.base_ring() != K:666R = R.change_ring(K)667668# Create a zero dense matrix over K with len(indices) rows669# and #P^1(N) columns.670cdef Matrix_cyclo_dense T671from sage.matrix.all import matrix672T = matrix(K, len(indices), len(P1), sparse=False)673674cdef Py_ssize_t i, j675cdef int *a, *b, k, scalar676677cdef Heilbronn H678679t = sage.misc.misc.verbose("computing non-reduced images of symbol under Hecke operators",680level=1, caller_name='hecke_images_character_weight2')681682# Make a matrix over the rational numbers each of whose columns683# are the values of the character chi.684cdef Matrix_rational_dense chi_vals685z = [t.list() for t in chi.values()]686chi_vals = matrix(QQ, z).transpose()687688for i, n in enumerate(indices):689H = HeilbronnCremona(n) if sage.rings.arith.is_prime(n) else HeilbronnMerel(n)690691# Allocate memory to hold images of (u,v) under all Heilbronn matrices692a = <int*> sage_malloc(sizeof(int)*H.length)693if not a: raise MemoryError694b = <int*> sage_malloc(sizeof(int)*H.length)695if not b: raise MemoryError696697# Compute images of (u,v) under all Heilbronn matrices698H.apply_only(u, v, N, a, b)699700for j in range(H.length):701# Compute index of the symbol a[j], b[j] in the standard list.702P1.index_and_scalar(a[j], b[j], &k, &scalar)703# Now fill in row i of the matrix T.704if k != -1:705# The following line is just a dangerous direct way to do: T[i,k] += chi(scalar)706# T[i,k] += chi(scalar)707# This code makes assumptions about the internal structure708# of matrices over cyclotomic fields. It's nasty, but it709# is exactly what is needed to get a solid 100 or more710# times speedup.711scalar %= N712if scalar < 0: scalar += N713# Note that the next line totally dominates the runtime of this whole function.714T._matrix._add_col_j_of_A_to_col_i_of_self(i * T._ncols + k, chi_vals, scalar)715716# Free a and b717sage_free(a)718sage_free(b)719720return T * R721722def hecke_images_quad_character_weight2(int u, int v, int N, indices, chi, R):723"""724INPUT:725726- ``u, v, N`` - integers so that gcd(u,v,N) = 1727- ``indices`` - a list of positive integers728- ``chi`` - a Dirichlet character that takes values in QQ729- ``R`` - matrix over QQ(chi) that writes each elements of P1 =730P1List(N) in terms of a subset of P1.731732733OUTPUT: a dense matrix with entries in the rational field QQ (the734values of chi) whose columns are the images T_n(x) for n in735indices and x the Manin symbol (u,v), expressed in terms of the736basis.737738EXAMPLES::739740sage: chi = DirichletGroup(29,QQ).0741sage: M = ModularSymbols(chi)742sage: R = M.manin_gens_to_basis()743sage: sage.modular.modsym.heilbronn.hecke_images_quad_character_weight2(2,1,29,[1,3,4],chi,R)744[ 0 0 0 0 0 -1]745[ 0 1 0 1 1 1]746[ 0 -2 0 2 -2 -1]747sage: x = M((2,1)) ; x.element()748(0, 0, 0, 0, 0, -1)749sage: M.T(3)(x).element()750(0, 1, 0, 1, 1, 1)751sage: M.T(4)(x).element()752(0, -2, 0, 2, -2, -1)753"""754cdef p1list.P1List P1 = p1list.P1List(N)755from sage.rings.all import QQ756if chi.base_ring() != QQ:757raise TypeError, "character must takes values in QQ"758759# Create a zero dense matrix over QQ with len(indices) rows760# and #P^1(N) columns.761cdef Matrix_rational_dense T762from sage.matrix.all import matrix763T = matrix(QQ, len(indices), len(P1), sparse=False)764765if R.base_ring() != QQ:766R = R.change_ring(QQ)767768cdef Py_ssize_t i, j769cdef int *a, *b, k, scalar770cdef Heilbronn H771772t = sage.misc.misc.verbose("computing non-reduced images of symbol under Hecke operators",773level=1, caller_name='hecke_images_quad_character_weight2')774775# Make a matrix over the rational numbers each of whose columns776# are the values of the character chi.777_chivals = chi.values()778cdef int *chi_vals = <int*>sage_malloc(sizeof(int)*len(_chivals))779if not chi_vals: raise MemoryError780for i in range(len(_chivals)):781chi_vals[i] = _chivals[i]782783for i, n in enumerate(indices):784H = HeilbronnCremona(n) if sage.rings.arith.is_prime(n) else HeilbronnMerel(n)785a = <int*> sage_malloc(sizeof(int)*H.length)786if not a: raise MemoryError787b = <int*> sage_malloc(sizeof(int)*H.length)788if not b: raise MemoryError789790H.apply_only(u, v, N, a, b)791for j in range(H.length):792P1.index_and_scalar(a[j], b[j], &k, &scalar)793if k != -1:794# This is just T[i,k] += chi(scalar)795scalar %= N796if scalar < 0: scalar += N797if chi_vals[scalar] > 0:798T._add_ui_unsafe_assuming_int(i, k, 1)799elif chi_vals[scalar] < 0:800T._sub_ui_unsafe_assuming_int(i, k, 1)801sage_free(a); sage_free(b)802803sage_free(chi_vals)804return T * R805806807808809############################################################################810# Fast application of Heilbronn operators to computation of811# systems of Hecke eigenvalues.812# Trivial character and weight > 2.813############################################################################814815def hecke_images_gamma0_weight_k(int u, int v, int i, int N, int k, indices, R):816"""817INPUT:818819- ``u, v, N`` - integers so that gcd(u,v,N) = 1820- ``i`` - integer with 0 = i = k-2821- ``k`` - weight822- ``indices`` - a list of positive integers823- ``R`` - matrix over QQ that writes each elements of824P1 = P1List(N) in terms of a subset of P1.825826OUTPUT: a dense matrix with rational entries whose columns are the827images T_n(x) for n in indices and x the Manin symbol828[`X^i*Y^(k-2-i), (u,v)`], expressed in terms of the basis.829830EXAMPLES::831832sage: M = ModularSymbols(15,6,sign=-1)833sage: R = M.manin_gens_to_basis()834sage: sage.modular.modsym.heilbronn.hecke_images_gamma0_weight_k(4,1,3,15,6,[1,11,12], R)835[ 0 0 1/8 -1/8 0 0 0 0]836[-4435/22 -1483/22 -112 -4459/22 2151/22 -5140/11 4955/22 2340/11]837[ 1253/22 1981/22 -2 3177/22 -1867/22 6560/11 -7549/22 -612/11]838sage: x = M((3,4,1)) ; x.element()839(0, 0, 1/8, -1/8, 0, 0, 0, 0)840sage: M.T(11)(x).element()841(-4435/22, -1483/22, -112, -4459/22, 2151/22, -5140/11, 4955/22, 2340/11)842sage: M.T(12)(x).element()843(1253/22, 1981/22, -2, 3177/22, -1867/22, 6560/11, -7549/22, -612/11)844"""845cdef p1list.P1List P1 = p1list.P1List(N)846847# The Manin symbols are enumerated as848# all [0, (u,v)] for (u,v) in P^1(N) then849# all [1, (u,v)] for (u,v) in P^1(N) etc.850# So we create a zero dense matrix over QQ with len(indices) rows851# and #P^1(N) * (k-1) columns.852cdef Matrix_rational_dense T853from sage.matrix.all import matrix854from sage.rings.all import QQ855T = matrix(QQ, len(indices), len(P1)*(k-1), sparse=False)856857if R.base_ring() != QQ:858R = R.change_ring(QQ)859860cdef Py_ssize_t j, m, z, w, n, p861cdef int *a, *b862863n = len(P1)864865cdef Heilbronn H866cdef fmpz_poly_t* poly867cdef Integer coeff = Integer()868cdef mpz_t tmp869mpz_init(tmp)870871for z, m in enumerate(indices):872H = HeilbronnCremona(m) if sage.rings.arith.is_prime(m) else HeilbronnMerel(m)873874# Allocate memory to hold images of (u,v) under all Heilbronn matrices875a = <int*> sage_malloc(sizeof(int)*H.length)876if not a: raise MemoryError877b = <int*> sage_malloc(sizeof(int)*H.length)878if not b: raise MemoryError879880# Compute images of (u,v) under all Heilbronn matrices881H.apply_only(u, v, N, a, b)882883# Compute images of X^i Y^(2-k-i) under each Heilbronn matrix884poly = <fmpz_poly_t*> sage_malloc(sizeof(fmpz_poly_t)*H.length)885for j in range(H.length):886fmpz_poly_init(poly[j])887888# The following line dominates the runtime of this entire function:889H.apply_to_polypart(poly, i, k)890891# Compute the indexes of these images.892# We just store them in the array a for simplicity.893for j in range(H.length):894# Compute index of the symbol a[j], b[j] in the standard list.895p = P1.index(a[j], b[j])896# Now fill in row z of the matrix T.897if p != -1:898for w in range(k-1):899# The following two lines are just a vastly faster version of:900# T[z, n*w + p] += poly[j][w]901# They use that we know that T has only integer entries.902fmpz_poly_get_coeff_mpz(tmp, poly[j], w)903mpz_add(mpq_numref(T._matrix[z][n*w+p]), mpq_numref(T._matrix[z][n*w+p]), tmp)904905# Free a and b906sage_free(a)907sage_free(b)908909# Free poly part910for j in range(H.length):911fmpz_poly_clear(poly[j])912sage_free(poly)913914mpz_clear(tmp)915916# Return the product T * R, whose rows are the image of (u,v) under917# the Hecke operators T_n for n in indices.918return T * R.dense_matrix()919920921############################################################################922# Fast application of Heilbronn operators to computation of923# systems of Hecke eigenvalues.924# Nontrivial character of order > 2 and weight > 2925############################################################################926927# TODO928929############################################################################930# Fast application of Heilbronn operators to computation of931# systems of Hecke eigenvalues.932# Nontrivial character of order = 2 and weight > 2933############################################################################934935# TODO936937938