Path: blob/master/src/sage/modular/modform/constructor.py
8820 views
# -*- coding: utf-8 -*-1"""2Creating Spaces of Modular Forms34EXAMPLES::56sage: m = ModularForms(Gamma1(4),11)7sage: m8Modular Forms space of dimension 6 for Congruence Subgroup Gamma1(4) of weight 11 over Rational Field9sage: m.basis()10[11q - 134*q^5 + O(q^6),12q^2 + 80*q^5 + O(q^6),13q^3 + 16*q^5 + O(q^6),14q^4 - 4*q^5 + O(q^6),151 + 4092/50521*q^2 + 472384/50521*q^3 + 4194300/50521*q^4 + O(q^6),16q + 1024*q^2 + 59048*q^3 + 1048576*q^4 + 9765626*q^5 + O(q^6)17]1819"""2021#########################################################################22# Copyright (C) 2004--2006 William Stein <[email protected]>23#24# Distributed under the terms of the GNU General Public License (GPL)25#26# http://www.gnu.org/licenses/27#########################################################################2829import weakref30import re3132import sage.modular.arithgroup.all as arithgroup33import sage.modular.dirichlet as dirichlet34import sage.rings.all as rings3536from sage.rings.commutative_ring import is_CommutativeRing3738import ambient_eps39import ambient_g040import ambient_g141import ambient_R42import defaults434445def canonical_parameters(group, level, weight, base_ring):46"""47Given a group, level, weight, and base_ring as input by the user,48return a canonicalized version of them, where level is a Sage49integer, group really is a group, weight is a Sage integer, and50base_ring a Sage ring. Note that we can't just get the level from51the group, because we have the convention that the character for52Gamma1(N) is None (which makes good sense).5354INPUT:555657- ``group`` - int, long, Sage integer, group,58dirichlet character, or5960- ``level`` - int, long, Sage integer, or group6162- ``weight`` - coercible to Sage integer6364- ``base_ring`` - commutative Sage ring656667OUTPUT:686970- ``level`` - Sage integer7172- ``group`` - congruence subgroup7374- ``weight`` - Sage integer7576- ``ring`` - commutative Sage ring777879EXAMPLES::8081sage: from sage.modular.modform.constructor import canonical_parameters82sage: v = canonical_parameters(5, 5, int(7), ZZ); v83(5, Congruence Subgroup Gamma0(5), 7, Integer Ring)84sage: type(v[0]), type(v[1]), type(v[2]), type(v[3])85(<type 'sage.rings.integer.Integer'>,86<class 'sage.modular.arithgroup.congroup_gamma0.Gamma0_class_with_category'>,87<type 'sage.rings.integer.Integer'>,88<type 'sage.rings.integer_ring.IntegerRing_class'>)89sage: canonical_parameters( 5, 7, 7, ZZ )90Traceback (most recent call last):91...92ValueError: group and level do not match.93"""94weight = rings.Integer(weight)95if weight <= 0:96raise NotImplementedError, "weight must be at least 1"9798if isinstance(group, dirichlet.DirichletCharacter):99if ( group.level() != rings.Integer(level) ):100raise ValueError, "group.level() and level do not match."101group = group.minimize_base_ring()102level = rings.Integer(level)103104elif arithgroup.is_CongruenceSubgroup(group):105if ( rings.Integer(level) != group.level() ):106raise ValueError, "group.level() and level do not match."107# normalize the case of SL2Z108if arithgroup.is_SL2Z(group) or \109arithgroup.is_Gamma1(group) and group.level() == rings.Integer(1):110group = arithgroup.Gamma0(rings.Integer(1))111112elif group is None:113pass114115else:116try:117m = rings.Integer(group)118except TypeError:119raise TypeError, "group of unknown type."120level = rings.Integer(level)121if ( m != level ):122raise ValueError, "group and level do not match."123group = arithgroup.Gamma0(m)124125if not is_CommutativeRing(base_ring):126raise TypeError, "base_ring (=%s) must be a commutative ring"%base_ring127128# it is *very* important to include the level as part of the data129# that defines the key, since dirichlet characters of different130# levels can compare equal, but define much different modular131# forms spaces.132return level, group, weight, base_ring133134_cache = {}135136def ModularForms_clear_cache():137"""138Clear the cache of modular forms.139140EXAMPLES::141142sage: M = ModularForms(37,2)143sage: sage.modular.modform.constructor._cache == {}144False145146::147148sage: sage.modular.modform.constructor.ModularForms_clear_cache()149sage: sage.modular.modform.constructor._cache150{}151"""152global _cache153_cache = {}154155def ModularForms(group = 1,156weight = 2,157base_ring = None,158use_cache = True,159prec = defaults.DEFAULT_PRECISION):160r"""161Create an ambient space of modular forms.162163INPUT:164165166- ``group`` - A congruence subgroup or a Dirichlet167character eps.168169- ``weight`` - int, the weight, which must be an170integer = 1.171172- ``base_ring`` - the base ring (ignored if group is173a Dirichlet character)174175176Create using the command ModularForms(group, weight, base_ring)177where group could be either a congruence subgroup or a Dirichlet178character.179180EXAMPLES: First we create some spaces with trivial character::181182sage: ModularForms(Gamma0(11),2).dimension()1832184sage: ModularForms(Gamma0(1),12).dimension()1852186187If we give an integer N for the congruence subgroup, it defaults to188`\Gamma_0(N)`::189190sage: ModularForms(1,12).dimension()1912192sage: ModularForms(11,4)193Modular Forms space of dimension 4 for Congruence Subgroup Gamma0(11) of weight 4 over Rational Field194195We create some spaces for `\Gamma_1(N)`.196197::198199sage: ModularForms(Gamma1(13),2)200Modular Forms space of dimension 13 for Congruence Subgroup Gamma1(13) of weight 2 over Rational Field201sage: ModularForms(Gamma1(13),2).dimension()20213203sage: [ModularForms(Gamma1(7),k).dimension() for k in [2,3,4,5]]204[5, 7, 9, 11]205sage: ModularForms(Gamma1(5),11).dimension()20612207208We create a space with character::209210sage: e = (DirichletGroup(13).0)^2211sage: e.order()2126213sage: M = ModularForms(e, 2); M214Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 6 and degree 2215sage: f = M.T(2).charpoly('x'); f216x^3 + (-2*zeta6 - 2)*x^2 - 2*zeta6*x + 14*zeta6 - 7217sage: f.factor()218(x - zeta6 - 2) * (x - 2*zeta6 - 1) * (x + zeta6 + 1)219220We can also create spaces corresponding to the groups `\Gamma_H(N)` intermediate221between `\Gamma_0(N)` and `\Gamma_1(N)`::222223sage: G = GammaH(30, [11])224sage: M = ModularForms(G, 2); M225Modular Forms space of dimension 20 for Congruence Subgroup Gamma_H(30) with H generated by [11] of weight 2 over Rational Field226sage: M.T(7).charpoly().factor() # long time (7s on sage.math, 2011)227(x + 4) * x^2 * (x - 6)^4 * (x + 6)^4 * (x - 8)^7 * (x^2 + 4)228229More examples of spaces with character::230231sage: e = DirichletGroup(5, RationalField()).gen(); e232Dirichlet character modulo 5 of conductor 5 mapping 2 |--> -1233234sage: m = ModularForms(e, 2); m235Modular Forms space of dimension 2, character [-1] and weight 2 over Rational Field236sage: m == loads(dumps(m))237True238sage: m.T(2).charpoly('x')239x^2 - 1240sage: m = ModularForms(e, 6); m.dimension()2414242sage: m.T(2).charpoly('x')243x^4 - 917*x^2 - 42284244245This came up in a subtle bug (trac #5923)::246247sage: ModularForms(gp(1), gap(12))248Modular Forms space of dimension 2 for Modular Group SL(2,Z) of weight 12 over Rational Field249250This came up in another bug (related to trac #8630)::251252sage: chi = DirichletGroup(109, CyclotomicField(3)).0253sage: ModularForms(chi, 2, base_ring = CyclotomicField(15))254Modular Forms space of dimension 10, character [zeta3 + 1] and weight 2 over Cyclotomic Field of order 15 and degree 8255256We create some weight 1 spaces. The first example works fine, since we can prove purely by Riemann surface theory that there are no weight 1 cusp forms::257258sage: M = ModularForms(Gamma1(11), 1); M259Modular Forms space of dimension 5 for Congruence Subgroup Gamma1(11) of weight 1 over Rational Field260sage: M.basis()261[2621 + 22*q^5 + O(q^6),263q + 4*q^5 + O(q^6),264q^2 - 4*q^5 + O(q^6),265q^3 - 5*q^5 + O(q^6),266q^4 - 3*q^5 + O(q^6)267]268sage: M.cuspidal_subspace().basis()269[270]271sage: M == M.eisenstein_subspace()272True273274This example doesn't work so well, because we can't calculate the cusp275forms; but we can still work with the Eisenstein series.276277sage: M = ModularForms(Gamma1(57), 1); M278Modular Forms space of dimension (unknown) for Congruence Subgroup Gamma1(57) of weight 1 over Rational Field279sage: M.basis()280Traceback (most recent call last):281...282NotImplementedError: Computation of dimensions of weight 1 cusp forms spaces not implemented in general283sage: M.cuspidal_subspace().basis()284Traceback (most recent call last):285...286NotImplementedError: Computation of dimensions of weight 1 cusp forms spaces not implemented in general287288sage: E = M.eisenstein_subspace(); E289Eisenstein subspace of dimension 36 of Modular Forms space of dimension (unknown) for Congruence Subgroup Gamma1(57) of weight 1 over Rational Field290sage: (E.0 + E.2).q_expansion(40)2911 + q^2 + 1473/2*q^36 - 1101/2*q^37 + q^38 - 373/2*q^39 + O(q^40)292293"""294if isinstance(group, dirichlet.DirichletCharacter):295if base_ring is None:296base_ring = group.minimize_base_ring().base_ring()297if base_ring is None:298base_ring = rings.QQ299300if isinstance(group, dirichlet.DirichletCharacter) \301or arithgroup.is_CongruenceSubgroup(group):302level = group.level()303else:304level = group305306key = canonical_parameters(group, level, weight, base_ring)307308if use_cache and _cache.has_key(key):309M = _cache[key]()310if not (M is None):311M.set_precision(prec)312return M313314(level, group, weight, base_ring) = key315316M = None317if arithgroup.is_Gamma0(group):318M = ambient_g0.ModularFormsAmbient_g0_Q(group.level(), weight)319if base_ring != rings.QQ:320M = ambient_R.ModularFormsAmbient_R(M, base_ring)321322elif arithgroup.is_Gamma1(group):323M = ambient_g1.ModularFormsAmbient_g1_Q(group.level(), weight)324if base_ring != rings.QQ:325M = ambient_R.ModularFormsAmbient_R(M, base_ring)326327elif arithgroup.is_GammaH(group):328M = ambient_g1.ModularFormsAmbient_gH_Q(group, weight)329if base_ring != rings.QQ:330M = ambient_R.ModularFormsAmbient_R(M, base_ring)331332elif isinstance(group, dirichlet.DirichletCharacter):333eps = group334if eps.base_ring().characteristic() != 0:335# TODO -- implement this336# Need to add a lift_to_char_0 function for characters,337# and need to still remember eps.338raise NotImplementedError, "currently the character must be over a ring of characteristic 0."339eps = eps.minimize_base_ring()340if eps.is_trivial():341return ModularForms(eps.modulus(), weight, base_ring,342use_cache = use_cache,343prec = prec)344M = ambient_eps.ModularFormsAmbient_eps(eps, weight)345if base_ring != eps.base_ring():346M = M.base_extend(base_ring) # ambient_R.ModularFormsAmbient_R(M, base_ring)347348if M is None:349raise NotImplementedError, \350"computation of requested space of modular forms not defined or implemented"351352M.set_precision(prec)353_cache[key] = weakref.ref(M)354return M355356357def CuspForms(group = 1,358weight = 2,359base_ring = None,360use_cache = True,361prec = defaults.DEFAULT_PRECISION):362"""363Create a space of cuspidal modular forms.364365See the documentation for the ModularForms command for a366description of the input parameters.367368EXAMPLES::369370sage: CuspForms(11,2)371Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field372"""373return ModularForms(group, weight, base_ring,374use_cache=use_cache, prec=prec).cuspidal_submodule()375376377def EisensteinForms(group = 1,378weight = 2,379base_ring = None,380use_cache = True,381prec = defaults.DEFAULT_PRECISION):382"""383Create a space of eisenstein modular forms.384385See the documentation for the ModularForms command for a386description of the input parameters.387388EXAMPLES::389390sage: EisensteinForms(11,2)391Eisenstein subspace of dimension 1 of Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field392"""393return ModularForms(group, weight, base_ring,394use_cache=use_cache, prec=prec).eisenstein_submodule()395396397398def Newforms(group, weight=2, base_ring=None, names=None):399r"""400Returns a list of the newforms of the given weight and level (or weight,401level and character). These are calculated as402`\operatorname{Gal}(\overline{F} / F)`-orbits, where `F` is the given base403field.404405INPUT:406407408- ``group`` - the congruence subgroup of the newform, or a Nebentypus409character410411- ``weight`` - the weight of the newform (default 2)412413- ``base_ring`` - the base ring (defaults to `\QQ` for spaces without414character, or the base ring of the character otherwise)415416- ``names`` - if the newform has coefficients in a417number field, a generator name must be specified418419420EXAMPLES::421422sage: Newforms(11, 2)423[q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)]424sage: Newforms(65, names='a')425[q - q^2 - 2*q^3 - q^4 - q^5 + O(q^6),426q + a1*q^2 + (a1 + 1)*q^3 + (-2*a1 - 1)*q^4 + q^5 + O(q^6),427q + a2*q^2 + (-a2 + 1)*q^3 + q^4 - q^5 + O(q^6)]428429A more complicated example involving both a nontrivial character, and a430base field that is not minimal for that character::431432sage: K.<i> = QuadraticField(-1)433sage: chi = DirichletGroup(5, K)[3]434sage: len(Newforms(chi, 7, names='a'))4351436sage: x = polygen(K); L.<c> = K.extension(x^2 - 402*i)437sage: N = Newforms(chi, 7, base_ring = L); len(N)4382439sage: sorted([N[0][2], N[1][2]]) == sorted([1/2*c - 5/2*i - 5/2, -1/2*c - 5/2*i - 5/2])440True441442We test that :trac:`8630` is fixed::443444sage: chi = DirichletGroup(109, CyclotomicField(3)).0445sage: CuspForms(chi, 2, base_ring = CyclotomicField(9))446Cuspidal 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 6447"""448return CuspForms(group, weight, base_ring).newforms(names)449450451def Newform(identifier, group=None, weight=2, base_ring=rings.QQ, names=None):452"""453INPUT:454455456- ``identifier`` - a canonical label, or the index of457the specific newform desired458459- ``group`` - the congruence subgroup of the newform460461- ``weight`` - the weight of the newform (default 2)462463- ``base_ring`` - the base ring464465- ``names`` - if the newform has coefficients in a466number field, a generator name must be specified467468469EXAMPLES::470471sage: Newform('67a', names='a')472q + 2*q^2 - 2*q^3 + 2*q^4 + 2*q^5 + O(q^6)473sage: Newform('67b', names='a')474q + a1*q^2 + (-a1 - 3)*q^3 + (-3*a1 - 3)*q^4 - 3*q^5 + O(q^6)475"""476if isinstance(group, str) and names is None:477names = group478if isinstance(identifier, str):479group, identifier = parse_label(identifier)480if weight != 2:481raise ValueError, "Canonical label not implemented for higher weight forms."482elif base_ring != rings.QQ:483raise ValueError, "Canonical label not implemented except for over Q."484elif group is None:485raise ValueError, "Must specify a group or a label."486return Newforms(group, weight, base_ring, names=names)[identifier]487488489def parse_label(s):490"""491Given a string s corresponding to a newform label, return the492corresponding group and index.493494EXAMPLES::495496sage: sage.modular.modform.constructor.parse_label('11a')497(Congruence Subgroup Gamma0(11), 0)498sage: sage.modular.modform.constructor.parse_label('11aG1')499(Congruence Subgroup Gamma1(11), 0)500sage: sage.modular.modform.constructor.parse_label('11wG1')501(Congruence Subgroup Gamma1(11), 22)502"""503m = re.match(r'(\d+)([a-z]+)((?:G.*)?)$', s)504if not m:505raise ValueError, "Invalid label: %s" % s506N, order, G = m.groups()507N = int(N)508index = 0509for c in reversed(order):510index = 26*index + ord(c)-ord('a')511if G == '' or G == 'G0':512G = arithgroup.Gamma0(N)513elif G == 'G1':514G = arithgroup.Gamma1(N)515elif G[:2] == 'GH':516if G[2] != '[' or G[-1] != ']':517raise ValueError, "Invalid congruence subgroup label: %s" % G518gens = [int(g.strip()) for g in G[3:-1].split(',')]519return arithgroup.GammaH(N, gens)520else:521raise ValueError, "Invalid congruence subgroup label: %s" % G522return G, index523524525526527