Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
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