Path: blob/master/sage/modular/modform/cuspidal_submodule.py
4045 views
"""1The Cuspidal Subspace23EXAMPLES::45sage: S = CuspForms(SL2Z,12); S6Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for7Modular Group SL(2,Z) of weight 12 over Rational Field8sage: S.basis()9[10q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)11]1213sage: S = CuspForms(Gamma0(33),2); S14Cuspidal subspace of dimension 3 of Modular Forms space of dimension 6 for15Congruence Subgroup Gamma0(33) of weight 2 over Rational Field16sage: S.basis()17[18q - q^5 + O(q^6),19q^2 - q^4 - q^5 + O(q^6),20q^3 + O(q^6)21]2223sage: S = CuspForms(Gamma1(3),6); S24Cuspidal subspace of dimension 1 of Modular Forms space of dimension 3 for25Congruence Subgroup Gamma1(3) of weight 6 over Rational Field26sage: S.basis()27[28q - 6*q^2 + 9*q^3 + 4*q^4 + 6*q^5 + O(q^6)29]30"""3132#########################################################################33# Copyright (C) 2004--2006 William Stein <[email protected]>34#35# Distributed under the terms of the GNU General Public License (GPL)36#37# http://www.gnu.org/licenses/38#########################################################################3940from sage.rings.all import Integer41from sage.misc.all import verbose42from sage.matrix.all import Matrix4344import submodule45import vm_basis4647class CuspidalSubmodule(submodule.ModularFormsSubmodule):48"""49Base class for cuspidal submodules of ambient spaces of modular forms.50"""51def __init__(self, ambient_space):52"""53The cuspidal submodule of an ambient space of modular forms.5455EXAMPLES::5657sage: S = CuspForms(SL2Z,12); S58Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for59Modular Group SL(2,Z) of weight 12 over Rational Field60sage: S.basis()61[62q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)63]6465sage: S = CuspForms(Gamma0(33),2); S66Cuspidal subspace of dimension 3 of Modular Forms space of dimension 6 for67Congruence Subgroup Gamma0(33) of weight 2 over Rational Field68sage: S.basis()69[70q - q^5 + O(q^6),71q^2 - q^4 - q^5 + O(q^6),72q^3 + O(q^6)73]7475sage: S = CuspForms(Gamma1(3),6); S76Cuspidal subspace of dimension 1 of Modular Forms space of dimension 3 for77Congruence Subgroup Gamma1(3) of weight 6 over Rational Field78sage: S.basis()79[80q - 6*q^2 + 9*q^3 + 4*q^4 + 6*q^5 + O(q^6)81]82sage: S == loads(dumps(S))83True84"""85verbose('creating cuspidal submodule of %s'%ambient_space)86d = ambient_space._dim_cuspidal()87V = ambient_space.module()88G = [V.gen(i) for i in range(d)]89S = V.submodule(G, check=False, already_echelonized=True)90submodule.ModularFormsSubmodule.__init__(self, ambient_space, S)9192def _compute_q_expansion_basis(self, prec):93r"""94Compute a basis of q-expansions of self to the given precision. Not95implemented in this abstract base class.9697EXAMPLE::9899sage: M = CuspForms(GammaH(11,[2]), 2)100sage: sage.modular.modform.cuspidal_submodule.CuspidalSubmodule._compute_q_expansion_basis(M, 6)101Traceback (most recent call last):102...103NotImplementedError: q-expansion basis not implemented for "Cuspidal subspace of ..."104"""105raise NotImplementedError, 'q-expansion basis not implemented for "%s"' % self106107def _repr_(self):108"""109Return the string representation of self.110111EXAMPLES::112113sage: S = CuspForms(Gamma1(3),6); S._repr_()114'Cuspidal subspace of dimension 1 of Modular Forms space of dimension 3 for Congruence Subgroup Gamma1(3) of weight 6 over Rational Field'115"""116return "Cuspidal subspace of dimension %s of %s"%(self.dimension(), self.ambient_module())117118def is_cuspidal(self):119"""120Return True since spaces of cusp forms are cuspidal.121122EXAMPLES::123124sage: CuspForms(4,10).is_cuspidal()125True126"""127return True128129def modular_symbols(self, sign=0):130"""131Return the corresponding space of modular symbols with the given sign.132133EXAMPLES::134135sage: S = ModularForms(11,2).cuspidal_submodule()136sage: S.modular_symbols()137Modular Symbols subspace of dimension 2 of Modular Symbols space138of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field139140sage: S.modular_symbols(sign=-1)141Modular Symbols subspace of dimension 1 of Modular Symbols space142of dimension 1 for Gamma_0(11) of weight 2 with sign -1 over Rational Field143144sage: M = S.modular_symbols(sign=1); M145Modular Symbols subspace of dimension 1 of Modular Symbols space of146dimension 2 for Gamma_0(11) of weight 2 with sign 1 over Rational Field147sage: M.sign()1481149150sage: S = ModularForms(1,12).cuspidal_submodule()151sage: S.modular_symbols()152Modular Symbols subspace of dimension 2 of Modular Symbols space of153dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field154155sage: eps = DirichletGroup(13).0156sage: S = CuspForms(eps^2, 2)157158sage: S.modular_symbols(sign=0)159Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 4 and level 13, weight 2, character [zeta6], sign 0, over Cyclotomic Field of order 6 and degree 2160161sage: S.modular_symbols(sign=1)162Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 and level 13, weight 2, character [zeta6], sign 1, over Cyclotomic Field of order 6 and degree 2163164sage: S.modular_symbols(sign=-1)165Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 1 and level 13, weight 2, character [zeta6], sign -1, over Cyclotomic Field of order 6 and degree 2166"""167try:168return self.__modular_symbols[sign]169except AttributeError:170self.__modular_symbols = {}171except KeyError:172pass173A = self.ambient_module()174S = A.modular_symbols(sign).cuspidal_submodule()175self.__modular_symbols[sign] = S176return S177178179def change_ring(self, R):180r"""181Change the base ring of self to R, when this makes sense. This differs182from :meth:`~sage.modular.modform.space.ModularFormsSpace.base_extend`183in that there may not be a canonical map from self to the new space, as184in the first example below. If this space has a character then this may185fail when the character cannot be defined over R, as in the second186example.187188EXAMPLES::189190sage: chi = DirichletGroup(109, CyclotomicField(3)).0191sage: S9 = CuspForms(chi, 2, base_ring = CyclotomicField(9)); S9192Cuspidal subspace of dimension 8 of Modular Forms space of dimension 10, character [zeta3 + 1] and weight 2 over Cyclotomic Field of order 9 and degree 6193sage: S9.change_ring(CyclotomicField(3))194Cuspidal subspace of dimension 8 of Modular Forms space of dimension 10, character [zeta3 + 1] and weight 2 over Cyclotomic Field of order 3 and degree 2195sage: S9.change_ring(QQ)196Traceback (most recent call last):197...198ValueError: Space cannot be defined over Rational Field199"""200return self.ambient_module().change_ring(R).cuspidal_submodule()201202class CuspidalSubmodule_R(CuspidalSubmodule):203"""204Cuspidal submodule over a non-minimal base ring.205"""206def _compute_q_expansion_basis(self, prec):207r"""208EXAMPLE::209210sage: CuspForms(Gamma1(13), 2, base_ring=QuadraticField(-7, 'a')).q_expansion_basis() # indirect doctest211[212q - 4*q^3 - q^4 + 3*q^5 + O(q^6),213q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6)214]215"""216return submodule.ModularFormsSubmodule._compute_q_expansion_basis(self, prec)217218class CuspidalSubmodule_modsym_qexp(CuspidalSubmodule):219"""220Cuspidal submodule with q-expansions calculated via modular symbols.221"""222def _compute_q_expansion_basis(self, prec=None):223"""224Compute q-expansions of a basis for self (via modular symbols).225226EXAMPLES::227228sage: sage.modular.modform.cuspidal_submodule.CuspidalSubmodule_modsym_qexp(ModularForms(11,2))._compute_q_expansion_basis()229[230q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)231]232"""233if prec == None:234prec = self.prec()235else:236prec = Integer(prec)237if self.dimension() == 0:238return []239M = self.modular_symbols(sign = 1)240return M.q_expansion_basis(prec)241242def new_submodule(self, p=None):243r"""244Return the new subspace of this space of cusp forms. This is computed245using modular symbols.246247EXAMPLE::248249sage: CuspForms(55).new_submodule()250Modular Forms subspace of dimension 3 of Modular Forms space of dimension 8 for Congruence Subgroup Gamma0(55) of weight 2 over Rational Field251"""252symbs = self.modular_symbols(sign=1).new_subspace(p)253bas = []254for x in symbs.q_expansion_basis(self.sturm_bound()):255bas.append(self(x))256return self.submodule(bas, check=False)257258class CuspidalSubmodule_level1_Q(CuspidalSubmodule):259r"""260Space of cusp forms of level 1 over `\QQ`.261"""262def _compute_q_expansion_basis(self, prec=None):263"""264Compute q-expansions of a basis for self.265266EXAMPLES::267268sage: sage.modular.modform.cuspidal_submodule.CuspidalSubmodule_level1_Q(ModularForms(1,12))._compute_q_expansion_basis()269[270q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)271]272"""273if prec == None:274prec = self.prec()275else:276prec = Integer(prec)277return vm_basis.victor_miller_basis(self.weight(), prec,278cusp_only=True, var='q')279280class CuspidalSubmodule_g0_Q(CuspidalSubmodule_modsym_qexp):281r"""282Space of cusp forms for `\Gamma_0(N)` over `\QQ`.283"""284285class CuspidalSubmodule_gH_Q(CuspidalSubmodule_modsym_qexp):286r"""287Space of cusp forms for `\Gamma_1(N)` over `\QQ`.288"""289290def _compute_hecke_matrix(self, n):291r"""292Compute the matrix of the Hecke operator T_n acting on this space.293This is done directly using modular symbols, rather than using294q-expansions as for spaces with fixed character.295296EXAMPLE::297298sage: CuspForms(Gamma1(8), 4)._compute_hecke_matrix(2)299[ 0 -16 32]300[ 1 -10 18]301[ 0 -4 8]302303sage: CuspForms(GammaH(15, [4]), 3)._compute_hecke_matrix(17)304[ 18 22 -30 -60]305[ 4 0 6 -18]306[ 6 0 2 -20]307[ 6 12 -24 -20]308"""309symbs = self.modular_symbols(sign=1)310return _convert_matrix_from_modsyms(symbs, symbs.hecke_matrix(n))[0]311312def _compute_diamond_matrix(self, d):313r"""314EXAMPLE::315316sage: CuspForms(Gamma1(5), 6).diamond_bracket_matrix(3) # indirect doctest317[ -1 0 0]318[ 3 5 -12]319[ 1 2 -5]320sage: CuspForms(GammaH(15, [4]), 3)._compute_diamond_matrix(7)321[ 2 3 -9 -3]322[ 0 2 -3 0]323[ 0 1 -2 0]324[ 1 1 -3 -2]325"""326symbs = self.modular_symbols(sign=1)327return _convert_matrix_from_modsyms(symbs, symbs.diamond_bracket_matrix(d))[0]328329330class CuspidalSubmodule_g1_Q(CuspidalSubmodule_gH_Q):331r"""332Space of cusp forms for `\Gamma_1(N)` over `\QQ`.333"""334335class CuspidalSubmodule_eps(CuspidalSubmodule_modsym_qexp):336"""337Space of cusp forms with given Dirichlet character.338339EXAMPLES::340341sage: S = CuspForms(DirichletGroup(5).0,5); S342Cuspidal subspace of dimension 1 of Modular Forms space of dimension 3, character [zeta4] and weight 5 over Cyclotomic Field of order 4 and degree 2343344sage: S.basis()345[346q + (-zeta4 - 1)*q^2 + (6*zeta4 - 6)*q^3 - 14*zeta4*q^4 + (15*zeta4 + 20)*q^5 + O(q^6)347]348sage: f = S.0349sage: f.qexp()350q + (-zeta4 - 1)*q^2 + (6*zeta4 - 6)*q^3 - 14*zeta4*q^4 + (15*zeta4 + 20)*q^5 + O(q^6)351sage: f.qexp(7)352q + (-zeta4 - 1)*q^2 + (6*zeta4 - 6)*q^3 - 14*zeta4*q^4 + (15*zeta4 + 20)*q^5 + 12*q^6 + O(q^7)353sage: f.qexp(3)354q + (-zeta4 - 1)*q^2 + O(q^3)355sage: f.qexp(2)356q + O(q^2)357sage: f.qexp(1)358O(q^1)359"""360361#def _repr_(self):362# A = self.ambient_module()363# return "Cuspidal subspace of dimension %s of Modular Forms space with character %s and weight %s over %s"%(self.dimension(), self.character(), self.weight(), self.base_ring())364365366367def _convert_matrix_from_modsyms(symbs, T):368r"""369Given a space of modular symbols and a matrix T acting on it, calculate the370matrix of the corresponding operator on the echelon-form basis of the371corresponding space of modular forms.372373The matrix T *must* commute with the Hecke operators! We use this when T is374either a Hecke operator, or a diamond operator. This will *not work* for375the Atkin-Lehner operators, for instance, when there are oldforms present.376377OUTPUT:378A pair `(T_e, ps)` with `T_e` the converted matrix and `ps` a list379of pivot elements of the echelon basis.380381EXAMPLE::382383sage: CuspForms(Gamma1(5), 6).diamond_bracket_matrix(3) # indirect doctest384[ -1 0 0]385[ 3 5 -12]386[ 1 2 -5]387"""388d = symbs.rank()389390# create a vector space of appropriate dimension to391# contain our q-expansions392A = symbs.base_ring()393r = symbs.sturm_bound()394X = A**r395Y = X.zero_submodule()396basis = []397basis_images = []398399# we repeatedly use these matrices below, so we store them400# once as lists to save time.401hecke_matrix_ls = [ symbs.hecke_matrix(m).list() for m in range(1,r+1) ]402hecke_image_ls = [ (T*symbs.hecke_matrix(m)).list() for m in range(1,r+1) ]403404# compute the q-expansions of some cusp forms and their405# images under T_n406for i in xrange(d**2):407v = X([ hecke_matrix_ls[m][i] for m in xrange(r) ])408Ynew = Y.span(Y.basis() + [v])409if Ynew.rank() > Y.rank():410basis.append(v)411basis_images.append(X([ hecke_image_ls[m][i] for m in xrange(r) ]))412Y = Ynew413if len(basis) == d: break414415# now we can compute the matrix acting on the echelonized space of mod forms416# need to pass A as base ring since otherwise there are problems when the417# space has dimension 0418bigmat = Matrix(A, basis).augment(Matrix(A, basis_images))419bigmat.echelonize()420pivs = bigmat.pivots()421return bigmat.matrix_from_rows_and_columns(range(d), [ r+x for x in pivs ]), pivs422423424