def change_ring(self, base_ring): """ Return space with same defining parameters as this ambient space of modular symbols, but defined over a different base ring. EXAMPLES:: sage: m = ModularForms(DirichletGroup(13).0^2,2); m Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 6 and degree 2 sage: m.change_ring(CyclotomicField(12)) Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 12 and degree 4 It must be possible to change the ring of the underlying Dirichlet character:: sage: m.change_ring(QQ) Traceback (most recent call last): ... ValueError: cannot coerce element of order 6 into self """ if self.base_ring() == base_ring: return self return ambient_R.ModularFormsAmbient_R(self, base_ring=base_ring)
def ModularForms(group = 1, weight = 2, base_ring = None, use_cache = True, prec = defaults.DEFAULT_PRECISION): r""" Create an ambient space of modular forms. INPUT: - ``group`` - A congruence subgroup or a Dirichlet character eps. - ``weight`` - int, the weight, which must be an integer = 1. - ``base_ring`` - the base ring (ignored if group is a Dirichlet character) Create using the command ModularForms(group, weight, base_ring) where group could be either a congruence subgroup or a Dirichlet character. EXAMPLES: First we create some spaces with trivial character:: sage: ModularForms(Gamma0(11),2).dimension() 2 sage: ModularForms(Gamma0(1),12).dimension() 2 If we give an integer N for the congruence subgroup, it defaults to `\Gamma_0(N)`:: sage: ModularForms(1,12).dimension() 2 sage: ModularForms(11,4) Modular Forms space of dimension 4 for Congruence Subgroup Gamma0(11) of weight 4 over Rational Field We create some spaces for `\Gamma_1(N)`. :: sage: ModularForms(Gamma1(13),2) Modular Forms space of dimension 13 for Congruence Subgroup Gamma1(13) of weight 2 over Rational Field sage: ModularForms(Gamma1(13),2).dimension() 13 sage: [ModularForms(Gamma1(7),k).dimension() for k in [2,3,4,5]] [5, 7, 9, 11] sage: ModularForms(Gamma1(5),11).dimension() 12 We create a space with character:: sage: e = (DirichletGroup(13).0)^2 sage: e.order() 6 sage: M = ModularForms(e, 2); M Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 6 and degree 2 sage: f = M.T(2).charpoly('x'); f x^3 + (-2*zeta6 - 2)*x^2 - 2*zeta6*x + 14*zeta6 - 7 sage: f.factor() (x - zeta6 - 2) * (x - 2*zeta6 - 1) * (x + zeta6 + 1) We can also create spaces corresponding to the groups `\Gamma_H(N)` intermediate between `\Gamma_0(N)` and `\Gamma_1(N)`:: sage: G = GammaH(30, [11]) sage: M = ModularForms(G, 2); M Modular Forms space of dimension 20 for Congruence Subgroup Gamma_H(30) with H generated by [11] of weight 2 over Rational Field sage: M.T(7).charpoly().factor() # long time (7s on sage.math, 2011) (x + 4) * x^2 * (x - 6)^4 * (x + 6)^4 * (x - 8)^7 * (x^2 + 4) More examples of spaces with character:: sage: e = DirichletGroup(5, RationalField()).gen(); e Dirichlet character modulo 5 of conductor 5 mapping 2 |--> -1 sage: m = ModularForms(e, 2); m Modular Forms space of dimension 2, character [-1] and weight 2 over Rational Field sage: m == loads(dumps(m)) True sage: m.T(2).charpoly('x') x^2 - 1 sage: m = ModularForms(e, 6); m.dimension() 4 sage: m.T(2).charpoly('x') x^4 - 917*x^2 - 42284 This came up in a subtle bug (trac #5923):: sage: ModularForms(gp(1), gap(12)) Modular Forms space of dimension 2 for Modular Group SL(2,Z) of weight 12 over Rational Field This came up in another bug (related to trac #8630):: sage: chi = DirichletGroup(109, CyclotomicField(3)).0 sage: ModularForms(chi, 2, base_ring = CyclotomicField(15)) Modular Forms space of dimension 10, character [zeta3 + 1] and weight 2 over Cyclotomic Field of order 15 and degree 8 We 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:: sage: M = ModularForms(Gamma1(11), 1); M Modular Forms space of dimension 5 for Congruence Subgroup Gamma1(11) of weight 1 over Rational Field sage: M.basis() [ 1 + 22*q^5 + O(q^6), q + 4*q^5 + O(q^6), q^2 - 4*q^5 + O(q^6), q^3 - 5*q^5 + O(q^6), q^4 - 3*q^5 + O(q^6) ] sage: M.cuspidal_subspace().basis() [ ] sage: M == M.eisenstein_subspace() True This example doesn't work so well, because we can't calculate the cusp forms; but we can still work with the Eisenstein series. sage: M = ModularForms(Gamma1(57), 1); M Modular Forms space of dimension (unknown) for Congruence Subgroup Gamma1(57) of weight 1 over Rational Field sage: M.basis() Traceback (most recent call last): ... NotImplementedError: Computation of dimensions of weight 1 cusp forms spaces not implemented in general sage: M.cuspidal_subspace().basis() Traceback (most recent call last): ... NotImplementedError: Computation of dimensions of weight 1 cusp forms spaces not implemented in general sage: E = M.eisenstein_subspace(); E Eisenstein subspace of dimension 36 of Modular Forms space of dimension (unknown) for Congruence Subgroup Gamma1(57) of weight 1 over Rational Field sage: (E.0 + E.2).q_expansion(40) 1 + q^2 + 1473/2*q^36 - 1101/2*q^37 + q^38 - 373/2*q^39 + O(q^40) """ if isinstance(group, dirichlet.DirichletCharacter): if base_ring is None: base_ring = group.minimize_base_ring().base_ring() if base_ring is None: base_ring = rings.QQ if isinstance(group, dirichlet.DirichletCharacter) \ or arithgroup.is_CongruenceSubgroup(group): level = group.level() else: level = group key = canonical_parameters(group, level, weight, base_ring) if use_cache and _cache.has_key(key): M = _cache[key]() if not (M is None): M.set_precision(prec) return M (level, group, weight, base_ring) = key M = None if arithgroup.is_Gamma0(group): M = ambient_g0.ModularFormsAmbient_g0_Q(group.level(), weight) if base_ring != rings.QQ: M = ambient_R.ModularFormsAmbient_R(M, base_ring) elif arithgroup.is_Gamma1(group): M = ambient_g1.ModularFormsAmbient_g1_Q(group.level(), weight) if base_ring != rings.QQ: M = ambient_R.ModularFormsAmbient_R(M, base_ring) elif arithgroup.is_GammaH(group): M = ambient_g1.ModularFormsAmbient_gH_Q(group, weight) if base_ring != rings.QQ: M = ambient_R.ModularFormsAmbient_R(M, base_ring) elif isinstance(group, dirichlet.DirichletCharacter): eps = group if eps.base_ring().characteristic() != 0: # TODO -- implement this # Need to add a lift_to_char_0 function for characters, # and need to still remember eps. raise NotImplementedError, "currently the character must be over a ring of characteristic 0." eps = eps.minimize_base_ring() if eps.is_trivial(): return ModularForms(eps.modulus(), weight, base_ring, use_cache = use_cache, prec = prec) M = ambient_eps.ModularFormsAmbient_eps(eps, weight) if base_ring != eps.base_ring(): M = M.base_extend(base_ring) # ambient_R.ModularFormsAmbient_R(M, base_ring) if M is None: raise NotImplementedError, \ "computation of requested space of modular forms not defined or implemented" M.set_precision(prec) _cache[key] = weakref.ref(M) return M