Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" Hecke Operators on `q`-expansions """ from __future__ import absolute_import
#***************************************************************************** # Copyright (C) 2004-2006 William Stein <wstein@gmail.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #*****************************************************************************
from sage.modular.dirichlet import DirichletGroup, is_DirichletCharacter from sage.rings.all import ZZ, Integer, Infinity, CyclotomicField from sage.arith.all import divisors, gcd
from sage.rings.power_series_ring_element import is_PowerSeries
from sage.matrix.all import matrix, MatrixSpace from .element import is_ModularFormElement
def hecke_operator_on_qexp(f, n, k, eps = None, prec=None, check=True, _return_list=False): r""" Given the `q`-expansion `f` of a modular form with character `\varepsilon`, this function computes the image of `f` under the Hecke operator `T_{n,k}` of weight `k`.
EXAMPLES::
sage: M = ModularForms(1,12) sage: hecke_operator_on_qexp(M.basis()[0], 3, 12) 252*q - 6048*q^2 + 63504*q^3 - 370944*q^4 + O(q^5) sage: hecke_operator_on_qexp(M.basis()[0], 1, 12, prec=7) q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 + O(q^7) sage: hecke_operator_on_qexp(M.basis()[0], 1, 12) q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 - 16744*q^7 + 84480*q^8 - 113643*q^9 - 115920*q^10 + 534612*q^11 - 370944*q^12 - 577738*q^13 + O(q^14)
sage: M.prec(20) 20 sage: hecke_operator_on_qexp(M.basis()[0], 3, 12) 252*q - 6048*q^2 + 63504*q^3 - 370944*q^4 + 1217160*q^5 - 1524096*q^6 + O(q^7) sage: hecke_operator_on_qexp(M.basis()[0], 1, 12) q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 - 16744*q^7 + 84480*q^8 - 113643*q^9 - 115920*q^10 + 534612*q^11 - 370944*q^12 - 577738*q^13 + 401856*q^14 + 1217160*q^15 + 987136*q^16 - 6905934*q^17 + 2727432*q^18 + 10661420*q^19 - 7109760*q^20 + O(q^21)
sage: (hecke_operator_on_qexp(M.basis()[0], 1, 12)*252).add_bigoh(7) 252*q - 6048*q^2 + 63504*q^3 - 370944*q^4 + 1217160*q^5 - 1524096*q^6 + O(q^7)
sage: hecke_operator_on_qexp(M.basis()[0], 6, 12) -6048*q + 145152*q^2 - 1524096*q^3 + O(q^4)
An example on a formal power series::
sage: R.<q> = QQ[[]] sage: f = q + q^2 + q^3 + q^7 + O(q^8) sage: hecke_operator_on_qexp(f, 3, 12) q + O(q^3) sage: hecke_operator_on_qexp(delta_qexp(24), 3, 12).prec() 8 sage: hecke_operator_on_qexp(delta_qexp(25), 3, 12).prec() 9
An example of computing `T_{p,k}` in characteristic `p`::
sage: p = 199 sage: fp = delta_qexp(prec=p^2+1, K=GF(p)) sage: tfp = hecke_operator_on_qexp(fp, p, 12) sage: tfp == fp[p] * fp True sage: tf = hecke_operator_on_qexp(delta_qexp(prec=p^2+1), p, 12).change_ring(GF(p)) sage: tfp == tf True """ # Need to have base_ring=ZZ to work over finite fields, since # ZZ can coerce to GF(p), but QQ can't. raise TypeError("f (=%s) must be a power series or modular form"%f) raise TypeError("eps (=%s) must be a Dirichlet character"%eps)
# always want at least three coefficients, but not too many, unless # requested else:
# if computing T_{p^a} in characteristic p, use the simpler (and faster) # formula else: d in divisors(gcd(n, m)) if (m*n) % (d*d) == 0]) else:
def _hecke_operator_on_basis(B, V, n, k, eps): """ Does the work for hecke_operator_on_basis once the input is normalized.
EXAMPLES::
sage: hecke_operator_on_basis(ModularForms(1,16).q_expansion_basis(30), 3, 16) # indirect doctest [ -3348 0] [ 0 14348908]
The following used to cause a segfault due to accidentally transposed second and third argument (:trac:`2107`)::
sage: B = victor_miller_basis(100,30) sage: t2 = hecke_operator_on_basis(B, 100, 2) Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent. """ for f in B]
def hecke_operator_on_basis(B, n, k, eps=None, already_echelonized = False): r""" Given a basis `B` of `q`-expansions for a space of modular forms with character `\varepsilon` to precision at least `\#B\cdot n+1`, this function computes the matrix of `T_n` relative to `B`.
.. note::
If the elements of B are not known to sufficient precision, this function will report that the vectors are linearly dependent (since they are to the specified precision).
INPUT:
- ``B`` - list of q-expansions
- ``n`` - an integer >= 1
- ``k`` - an integer
- ``eps`` - Dirichlet character
- ``already_echelonized`` -- bool (default: False); if True, use that the basis is already in Echelon form, which saves a lot of time.
EXAMPLES::
sage: sage.modular.modform.constructor.ModularForms_clear_cache() sage: ModularForms(1,12).q_expansion_basis() [ q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6), 1 + 65520/691*q + 134250480/691*q^2 + 11606736960/691*q^3 + 274945048560/691*q^4 + 3199218815520/691*q^5 + O(q^6) ] sage: hecke_operator_on_basis(ModularForms(1,12).q_expansion_basis(), 3, 12) Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent.
sage: hecke_operator_on_basis(ModularForms(1,12).q_expansion_basis(30), 3, 12) [ 252 0] [ 0 177148]
TESTS:
This shows that the problem with finite fields reported at :trac:`8281` is solved::
sage: bas_mod5 = [f.change_ring(GF(5)) for f in victor_miller_basis(12, 20)] sage: hecke_operator_on_basis(bas_mod5, 2, 12) [4 0] [0 1]
This shows that empty input is handled sensibly (:trac:`12202`)::
sage: x = hecke_operator_on_basis([], 3, 12); x [] sage: x.parent() Full MatrixSpace of 0 by 0 dense matrices over Cyclotomic Field of order 1 and degree 1 sage: y = hecke_operator_on_basis([], 3, 12, eps=DirichletGroup(13).0^2); y [] sage: y.parent() Full MatrixSpace of 0 by 0 dense matrices over Cyclotomic Field of order 12 and degree 4 """ raise TypeError("B (=%s) must be a list or tuple"%B) else: all_powerseries = False raise TypeError("each element of B must be a power series") already_echelonized = already_echelonized)
|