Ejemplo n.º 1
0
 def create_key(self,
                group,
                weight=None,
                sign=0,
                p=None,
                prec_cap=None,
                base=None,
                coefficients=None):
     #print group, weight, sign, p, prec_cap, base, coefficients
     if sign not in (-1, 0, 1):
         raise ValueError("sign must be -1, 0, 1")
     if isinstance(group, (int, Integer)):
         character = None
     elif isinstance(group, DirichletCharacter):
         character = group
     if coefficients is None:
         #OverconvergentDistributions can handle prec_cap and base being None
         coefficients = OverconvergentDistributions(weight, p, prec_cap,
                                                    base, character)
     if isinstance(group, (int, Integer)):
         p = coefficients.prime()
         if group % p != 0:
             group *= p
         group = Gamma0(group)
     elif isinstance(group, DirichletCharacter):
         p = coefficients.prime()
         group = group.modulus()
         if group % p != 0:
             group *= p
         group = Gamma0(group)
     return (group, coefficients, sign)
Ejemplo n.º 2
0
def dimension_new_cusp_forms(X, k=2, p=0):
    """
    Return the dimension of the new (or `p`-new) subspace of
    cusp forms for the character or group `X`.

    INPUT:

    -  ``X`` -- integer, congruence subgroup or Dirichlet
       character

    -  ``k`` -- weight (integer)

    -  ``p`` -- 0 or a prime

    EXAMPLES::

        sage: from sage.modular.dims import dimension_new_cusp_forms
        sage: dimension_new_cusp_forms(100,2)
        1

        sage: dimension_new_cusp_forms(Gamma0(100),2)
        1
        sage: dimension_new_cusp_forms(Gamma0(100),4)
        5

        sage: dimension_new_cusp_forms(Gamma1(100),2)
        141
        sage: dimension_new_cusp_forms(Gamma1(100),4)
        463

        sage: dimension_new_cusp_forms(DirichletGroup(100).1^2,2)
        2
        sage: dimension_new_cusp_forms(DirichletGroup(100).1^2,4)
        8

        sage: sum(dimension_new_cusp_forms(e,3) for e in DirichletGroup(30))
        12
        sage: dimension_new_cusp_forms(Gamma1(30),3)
        12

    Check that :trac:`12640` is fixed::

        sage: dimension_new_cusp_forms(DirichletGroup(1)(1), 12)
        1
        sage: dimension_new_cusp_forms(DirichletGroup(2)(1), 24)
        1
    """
    if is_GammaH(X):
        return X.dimension_new_cusp_forms(k, p=p)
    elif isinstance(X, dirichlet.DirichletCharacter):
        N = X.modulus()
        if N <= 2:
            return Gamma0(N).dimension_new_cusp_forms(k, p=p)
        else:
            # Gamma1(N) for N<=2 just returns Gamma0(N), which has no
            # eps parameter. See trac #12640.
            return Gamma1(N).dimension_new_cusp_forms(k, eps=X, p=p)
    elif isinstance(X, (int, Integer)):
        return Gamma0(X).dimension_new_cusp_forms(k, p=p)
    raise TypeError(f"X (={X}) must be an integer, a Dirichlet character or a congruence subgroup of type Gamma0, Gamma1 or GammaH")
Ejemplo n.º 3
0
    def hecke_bound(self):
        r"""
        Return an integer B such that the Hecke operators `T_n`, for `n\leq B`,
        generate the full Hecke algebra as a module over the base ring. Note
        that we include the `n` with `n` not coprime to the level.

        At present this returns an unproven guess for non-cuspidal spaces which
        appears to be valid for `M_k(\Gamma_0(N))`, where k and N are the
        weight and level of self. (It is clearly valid for *cuspidal* spaces
        of any fixed character, as a consequence of the Sturm bound theorem.)
        It returns a hopelessly wrong answer for spaces of full level
        `\Gamma_1`.

        TODO: Get rid of this dreadful bit of code.

        EXAMPLE::

            sage: ModularSymbols(17, 4).hecke_bound()
            15
            sage: ModularSymbols(Gamma1(17), 4).hecke_bound() # wrong!
            15
        """
        try:
            if self.is_cuspidal():
                return Gamma0(self.level()).sturm_bound(self.weight())
        except AttributeError:
            pass
        misc.verbose(
            "WARNING: ambient.py -- hecke_bound; returning unproven guess.")
        return Gamma0(self.level()).sturm_bound(self.weight()) + 2 * Gamma0(
            self.level()).dimension_eis(self.weight()) + 5
Ejemplo n.º 4
0
def modular_ratio_space(chi):
    r"""
    Compute the space of 'modular ratios', i.e. meromorphic modular forms f
    level N and character chi such that f * E is a holomorphic cusp form for
    every Eisenstein series E of weight 1 and character 1/chi.

    Elements are returned as q-expansions up to precision R, where R is one
    greater than the weight 3 Sturm bound.

    EXAMPLES::

        sage: chi = DirichletGroup(31,QQ).0
        sage: sage.modular.modform.weight1.modular_ratio_space(chi)
        [q - 8/3*q^3 + 13/9*q^4 + 43/27*q^5 - 620/81*q^6 + 1615/243*q^7 + 3481/729*q^8 + O(q^9),
         q^2 - 8/3*q^3 + 13/9*q^4 + 70/27*q^5 - 620/81*q^6 + 1858/243*q^7 + 2752/729*q^8 + O(q^9)]
    """
    from sage.modular.modform.constructor import EisensteinForms, CuspForms

    if chi(-1) == 1:
        return []
    N = chi.modulus()
    chi = chi.minimize_base_ring()
    K = chi.base_ring()
    R = Gamma0(N).sturm_bound(3) + 1
    verbose("Working precision is %s" % R, level=1)
    verbose("Coeff field is %s" % K, level=1)

    V = K**R
    I = V
    d = I.rank()

    t = verbose("Calculating Eisenstein forms in weight 1...", level=1)
    B0 = EisensteinForms(~chi, 1).q_echelon_basis(prec=R)
    B = [b + B0[0] for b in B0]
    verbose("Done (dimension %s)" % len(B), level=1, t=t)

    t = verbose("Calculating in weight 2...", level=1)
    C = CuspForms(Gamma0(N), 2).q_echelon_basis(prec=R)
    verbose("Done (dimension %s)" % len(C), t=t, level=1)

    t = verbose("Computing candidate space", level=1)
    for b in B:
        quots = (c / b for c in C)
        W = V.span(V(x.padded_list(R)) for x in quots)
        I = I.intersection(W)
        if I.rank() < d:
            verbose(" Cut down to dimension %s" % I.rank(), level=1)
            d = I.rank()
        if I.rank() == 0:
            break

    verbose("Done: intersection is %s-dimensional" % I.dimension(),
            t=t,
            level=1)

    A = PowerSeriesRing(K, 'q')
    return [A(x.list()).add_bigoh(R) for x in I.gens()]
Ejemplo n.º 5
0
Archivo: space.py Proyecto: shalec/sage
def ps_modsym_from_elliptic_curve(E, sign = 0, implementation='eclib'):
    r"""
    Return the overconvergent modular symbol associated to
    an elliptic curve defined over the rationals.

    INPUT:

    - ``E`` -- an elliptic curve defined over the rationals

    - ``sign`` -- the sign (default: 0). If nonzero, returns either
      the plus (if ``sign`` == 1) or the minus (if ``sign`` == -1) modular
      symbol. The default of 0 returns the sum of the plus and minus symbols.

    - ``implementation`` --  either 'eclib' (default) or 'sage'. This
      determines which implementation of the underlying classical
      modular symbols is used.

    OUTPUT:

    The overconvergent modular symbol associated to ``E``

    EXAMPLES::

        sage: E = EllipticCurve('113a1')
        sage: symb = E.pollack_stevens_modular_symbol() # indirect doctest
        sage: symb
        Modular symbol of level 113 with values in Sym^0 Q^2
        sage: symb.values()
        [-1/2, 1, -1, 0, 0, 1, 1, -1, 0, -1, 0, 0, 0, 1, -1, 0, 0, 0, 1, 0, 0]

        sage: E = EllipticCurve([0,1])
        sage: symb = E.pollack_stevens_modular_symbol()
        sage: symb.values()
        [-1/6, 1/3, 1/2, 1/6, -1/6, 1/3, -1/3, -1/2, -1/6, 1/6, 0, -1/6, -1/6]
    """
    if not (E.base_ring() is QQ):
        raise ValueError("The elliptic curve must be defined over the "
                         "rationals.")
    sign = Integer(sign)
    if sign not in [0, 1, -1]:
        raise ValueError("The sign must be either 0, 1 or -1")
    N = E.conductor()
    V = PollackStevensModularSymbols(Gamma0(N), 0)
    D = V.coefficient_module()
    manin = V.source()
    # if sage's modular symbols are used we take the
    # normalization given by 'L_ratio' in modular_symbol
    if sign <= 0:
        minus_sym = E.modular_symbol(sign=-1, implementation=implementation)
    if sign >= 0:
        plus_sym = E.modular_symbol(sign=1, implementation=implementation)
    val = {}
    for g in manin.gens():
        ac, bd = cusps_from_mat(g)
        val[g] = D(0)
        if sign >= 0:
            val[g] += D(plus_sym(ac) - plus_sym(bd))
        if sign <= 0:
            val[g] += D(minus_sym(ac) - minus_sym(bd))
    return V(val)
Ejemplo n.º 6
0
def sturm_bound(level, weight=2):
    r"""
    Returns the Sturm bound for modular forms with given level and weight. For
    more details, see the documentation for the sturm_bound method of
    sage.modular.arithgroup.CongruenceSubgroup objects.
    
    INPUT:
    
    
    -  ``level`` - an integer (interpreted as a level for Gamma0) or a congruence subgroup
    
    -  ``weight`` - an integer `\geq 2` (default: 2)
    
    EXAMPLES::
    
        sage: sturm_bound(11,2)
        2
        sage: sturm_bound(389,2)
        65
        sage: sturm_bound(1,12)
        1
        sage: sturm_bound(100,2)
        30
        sage: sturm_bound(1,36)
        3    
        sage: sturm_bound(11)
        2
    """
    if is_ArithmeticSubgroup(level):
        if level.is_congruence():
            return level.sturm_bound(weight)
        else:
            raise ValueError, "No Sturm bound defined for noncongruence subgroups"
    if isinstance(level, (int, long, Integer)):
        return Gamma0(level).sturm_bound(weight)
Ejemplo n.º 7
0
    def create_key(self,
                   group,
                   weight=None,
                   sign=0,
                   base_ring=None,
                   p=None,
                   prec_cap=None,
                   coefficients=None):
        r"""
        Sanitize input.

        EXAMPLES::

            sage: D = OverconvergentDistributions(3, 7, prec_cap=10)
            sage: M = PollackStevensModularSymbols(Gamma0(7), coefficients=D) # indirect doctest
        """
        if sign not in (-1, 0, 1):
            raise ValueError("sign must be -1, 0, 1")

        if isinstance(group, (int, Integer)):
            group = Gamma0(group)

        if coefficients is None:
            if isinstance(group, DirichletCharacter):
                character = group.minimize_base_ring()
                group = Gamma0(character.modulus())
                if character.is_trivial():
                    character = None
            else:
                character = None

            if weight is None:
                raise ValueError("you must specify a weight "
                                 "or coefficient module")

            if prec_cap is None:
                coefficients = Symk(weight, base_ring, character)
            else:
                coefficients = OverconvergentDistributions(
                    weight, p, prec_cap, base_ring, character)
        else:
            if weight is not None or base_ring is not None or p is not None or prec_cap is not None:
                raise ValueError("if coefficients are specified, then weight, "
                                 "base_ring, p, and prec_cap must take their "
                                 "default value None")

        return (group, coefficients, sign)
Ejemplo n.º 8
0
    def __init__(self, group, base_ring=QQ):
        r"""
        The ring of modular forms (of weights 0 or at least 2) for a congruence
        subgroup of `{\rm SL}_2(\ZZ)`, with coefficients in a specified base ring.

        INPUT:

        - ``group`` -- a congruence subgroup of `{\rm SL}_2(\ZZ)`, or a
          positive integer `N` (interpreted as `\Gamma_0(N)`)

        - ``base_ring`` (ring, default: `\QQ`) -- a base ring, which should be
          `\QQ`, `\ZZ`, or the integers mod `p` for some prime `p`.

        EXAMPLES::

            sage: ModularFormsRing(Gamma1(13))
            Ring of modular forms for Congruence Subgroup Gamma1(13) with coefficients in Rational Field
            sage: m = ModularFormsRing(4); m
            Ring of modular forms for Congruence Subgroup Gamma0(4) with coefficients in Rational Field
            sage: m.modular_forms_of_weight(2)
            Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(4) of weight 2 over Rational Field
            sage: m.modular_forms_of_weight(10)
            Modular Forms space of dimension 6 for Congruence Subgroup Gamma0(4) of weight 10 over Rational Field
            sage: m == loads(dumps(m))
            True
            sage: m.generators()
            [(2, 1 + 24*q^2 + 24*q^4 + 96*q^6 + 24*q^8 + O(q^10)),
            (2, q + 4*q^3 + 6*q^5 + 8*q^7 + 13*q^9 + O(q^10))]
            sage: m.q_expansion_basis(2,10)
            [1 + 24*q^2 + 24*q^4 + 96*q^6 + 24*q^8 + O(q^10),
             q + 4*q^3 + 6*q^5 + 8*q^7 + 13*q^9 + O(q^10)]
            sage: m.q_expansion_basis(3,10)
            []
            sage: m.q_expansion_basis(10,10)
            [1 + 10560*q^6 + 3960*q^8 + O(q^10),
             q - 8056*q^7 - 30855*q^9 + O(q^10),
             q^2 - 796*q^6 - 8192*q^8 + O(q^10),
             q^3 + 66*q^7 + 832*q^9 + O(q^10),
             q^4 + 40*q^6 + 528*q^8 + O(q^10),
             q^5 + 20*q^7 + 190*q^9 + O(q^10)]
        """
        if isinstance(group, (int, long, Integer)):
            group = Gamma0(group)
        elif not is_CongruenceSubgroup(group):
            raise ValueError("Group (=%s) should be a congruence subgroup")

        if base_ring != ZZ and not base_ring.is_prime_field():
            raise ValueError(
                "Base ring (=%s) should be QQ, ZZ or a finite prime field")

        self.__group = group
        self.__base_ring = base_ring
        self.__cached_maxweight = ZZ(-1)
        self.__cached_gens = []
        self.__cached_cusp_maxweight = ZZ(-1)
        self.__cached_cusp_gens = []
Ejemplo n.º 9
0
    def __init__(self, group, base_ring=QQ):
        r"""
        INPUT:

        - ``group`` -- a congruence subgroup of `{\rm SL}_2(\ZZ)`, or a
          positive integer `N` (interpreted as `\Gamma_0(N)`)

        - ``base_ring`` (ring, default: `\QQ`) -- a base ring, which should be
          `\QQ`, `\ZZ`, or the integers mod `p` for some prime `p`.

        TESTS::

        Check that :trac:`15037` is fixed::

            sage: ModularFormsRing(3.4)
            Traceback (most recent call last):
            ...
            ValueError: Group (=3.40000000000000) should be a congruence subgroup
            sage: ModularFormsRing(Gamma0(2), base_ring=PolynomialRing(ZZ,x))
            Traceback (most recent call last):
            ...
            ValueError: Base ring (=Univariate Polynomial Ring in x over Integer Ring) should be QQ, ZZ or a finite prime field

        ::

            sage: TestSuite(ModularFormsRing(1)).run()
            sage: TestSuite(ModularFormsRing(Gamma0(6))).run()
            sage: TestSuite(ModularFormsRing(Gamma1(4))).run()

        .. TODO::

            - Add graded modular forms over non-trivial Dirichlet character;
            - makes gen_forms returns modular forms over base rings other than `QQ`;
            - implement binary operations between two forms with different groups.
        """
        if isinstance(group, (int, Integer)):
            group = Gamma0(group)
        elif not is_CongruenceSubgroup(group):
            raise ValueError("Group (=%s) should be a congruence subgroup" %
                             group)

        if base_ring != ZZ and not base_ring.is_field(
        ) and not base_ring.is_finite():
            raise ValueError(
                "Base ring (=%s) should be QQ, ZZ or a finite prime field" %
                base_ring)

        self.__group = group
        self.__cached_maxweight = ZZ(-1)
        self.__cached_gens = []
        self.__cached_cusp_maxweight = ZZ(-1)
        self.__cached_cusp_gens = []
        Parent.__init__(self,
                        base=base_ring,
                        category=GradedAlgebras(base_ring))
Ejemplo n.º 10
0
def AbelianVariety(X):
    """
    Create the abelian variety corresponding to the given defining
    data.

    INPUT:


    -  ``X`` - an integer, string, newform, modsym space,
       congruence subgroup or tuple of congruence subgroups


    OUTPUT: a modular abelian variety

    EXAMPLES::

        sage: AbelianVariety(Gamma0(37))
        Abelian variety J0(37) of dimension 2
        sage: AbelianVariety('37a')
        Newform abelian subvariety 37a of dimension 1 of J0(37)
        sage: AbelianVariety(Newform('37a'))
        Newform abelian subvariety 37a of dimension 1 of J0(37)
        sage: AbelianVariety(ModularSymbols(37).cuspidal_submodule())
        Abelian variety J0(37) of dimension 2
        sage: AbelianVariety((Gamma0(37), Gamma0(11)))
        Abelian variety J0(37) x J0(11) of dimension 3
        sage: AbelianVariety(37)
        Abelian variety J0(37) of dimension 2
        sage: AbelianVariety([1,2,3])
        Traceback (most recent call last):
        ...
        TypeError: X must be an integer, string, newform, modsym space, congruence subgroup or tuple of congruence subgroups
    """
    if isinstance(X, (int, long, Integer)):
        X = Gamma0(X)
    if is_CongruenceSubgroup(X):
        X = X.modular_symbols().cuspidal_submodule()
    elif isinstance(X, str):
        from sage.modular.modform.constructor import Newform
        f = Newform(X, names='a')
        return ModularAbelianVariety_newform(f, internal_name=True)
    elif isinstance(X, sage.modular.modform.element.Newform):
        return ModularAbelianVariety_newform(X)

    if is_ModularSymbolsSpace(X):
        return abvar.ModularAbelianVariety_modsym(X)

    if isinstance(X,
                  (tuple, list)) and all([is_CongruenceSubgroup(G)
                                          for G in X]):
        return abvar.ModularAbelianVariety(X)

    raise TypeError(
        "X must be an integer, string, newform, modsym space, congruence subgroup or tuple of congruence subgroups"
    )
Ejemplo n.º 11
0
    def __init__(self, group=1, base_ring=QQ, name='E2'):
        r"""
        INPUT:

        - ``group`` (default: `{\rm SL}_2(\ZZ)`) -- a congruence subgroup of
          `{\rm SL}_2(\ZZ)`, or a positive integer `N` (interpreted as
          `\Gamma_0(N)`).

        - ``base_ring`` (ring, default: `\QQ`) -- a base ring, which should be
          `\QQ`, `\ZZ`, or the integers mod `p` for some prime `p`.

        - ``name`` (str, default: ``'E2'``) -- a variable name corresponding to
          the weight 2 Eisenstein series.

        TESTS:

            sage: M = QuasiModularForms(1)
            sage: M.group()
            Modular Group SL(2,Z)
            sage: M.base_ring()
            Rational Field
            sage: QuasiModularForms(Integers(5))
            Traceback (most recent call last):
            ...
            ValueError: Group (=Ring of integers modulo 5) should be a congruence subgroup

        ::

            sage: TestSuite(QuasiModularForms(1)).run()
            sage: TestSuite(QuasiModularForms(Gamma0(3))).run()
            sage: TestSuite(QuasiModularForms(Gamma1(3))).run()
        """
        if not isinstance(name, str):
            raise TypeError("`name` must be a string")
        #check if the group is SL2(Z)
        if isinstance(group, (int, Integer)):
            group = Gamma0(group)
        elif not is_CongruenceSubgroup(group):
            raise ValueError("Group (=%s) should be a congruence subgroup" %
                             group)

        #Check if the base ring is the rationnal field
        if base_ring != QQ:
            raise NotImplementedError(
                "base ring other than Q are not yet supported for quasimodular forms ring"
            )

        self.__group = group
        self.__modular_forms_subring = ModularFormsRing(group, base_ring)
        self.__polynomial_subring = self.__modular_forms_subring[name]
        Parent.__init__(self,
                        base=base_ring,
                        category=GradedAlgebras(base_ring))
Ejemplo n.º 12
0
def dimension_supersingular_module(prime, level=1):
    r"""
    Return the dimension of the Supersingular module, which is
    equal to the dimension of the space of modular forms of weight `2`
    and conductor equal to ``prime`` times ``level``.

    INPUT:

    - ``prime`` -- integer, prime

    - ``level`` -- integer, positive

    OUTPUT:

    - dimension -- integer, nonnegative

    EXAMPLES:

    The code below computes the dimensions of Supersingular modules
    with level=1 and prime = 7, 15073 and 83401::

        sage: dimension_supersingular_module(7)
        1

        sage: dimension_supersingular_module(15073)
        1256

        sage: dimension_supersingular_module(83401)
        6950

    .. NOTE::

        The case of level > 1 has not been implemented yet.

    AUTHORS:

    - David Kohel -- [email protected]

    - Iftikhar Burhanuddin - [email protected]
    """
    if not (Integer(prime).is_prime()):
        raise ValueError("%s is not a prime" % prime)

    if level == 1:
        return Gamma0(prime).dimension_modular_forms(2)

    # list of genus(X_0(level)) equal to zero
    # elif (level in [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 16, 18, 25]):
    # compute basis

    else:
        raise NotImplementedError
Ejemplo n.º 13
0
Archivo: tests.py Proyecto: yjjcc/sage
    def __init__(self, index=20, index_max=50, odd_probability=0.5):
        r"""
        Create an arithmetic subgroup testing object.

        INPUT:

        - ``index`` - the index of random subgroup to test

        - ``index_max`` - the maximum index for congruence subgroup to test

        EXAMPLES::

            sage: from sage.modular.arithgroup.tests import Test
            sage: Test()
            Arithmetic subgroup testing class
        """
        self.congroups = []
        i = 1
        self.odd_probability = odd_probability
        if index % 4:
            self.odd_probability = 0
        while Gamma(i).index() < index_max:
            self.congroups.append(Gamma(i))
            i += 1
        i = 1
        while Gamma0(i).index() < index_max:
            self.congroups.append(Gamma0(i))
            i += 1
        i = 2
        while Gamma1(i).index() < index_max:
            self.congroups.append(Gamma1(i))
            M = Zmod(i)
            U = [x for x in M if x.is_unit()]
            for j in range(1, len(U) - 1):
                self.congroups.append(GammaH(i, prandom.sample(U, j)))
            i += 1

        self.index = index
Ejemplo n.º 14
0
    def _p_stabilize_parent_space(self, p, new_base_ring):
        r"""
        Return the space of Pollack-Stevens modular symbols of level
        `p N`, with changed base ring.  This is used internally when
        constructing the `p`-stabilization of a modular symbol.

        INPUT:

        - ``p`` -- prime number
        - ``new_base_ring`` -- the base ring of the result

        OUTPUT:

        The space of modular symbols of level `p N`, where `N` is the level
        of this space.

        EXAMPLES::

            sage: D = OverconvergentDistributions(2, 7)
            sage: M = PollackStevensModularSymbols(Gamma(13), coefficients=D)
            sage: M._p_stabilize_parent_space(7, M.base_ring())
            Space of overconvergent modular symbols for Congruence Subgroup
            Gamma(91) with sign 0 and values in Space of 7-adic distributions
            with k=2 action and precision cap 20

            sage: D = OverconvergentDistributions(4, 17)
            sage: M = PollackStevensModularSymbols(Gamma1(3), coefficients=D)
            sage: M._p_stabilize_parent_space(17, Qp(17))
            Space of overconvergent modular symbols for Congruence
            Subgroup Gamma1(51) with sign 0 and values in Space of
            17-adic distributions with k=4 action and precision cap 20
        """
        N = self.level()
        if N % p == 0:
            raise ValueError("the level is not prime to p")
        from sage.modular.arithgroup.all import (Gamma, is_Gamma, Gamma0,
                                                 is_Gamma0, Gamma1, is_Gamma1)
        G = self.group()
        if is_Gamma0(G):
            G = Gamma0(N * p)
        elif is_Gamma1(G):
            G = Gamma1(N * p)
        elif is_Gamma(G):
            G = Gamma(N * p)
        else:
            raise NotImplementedError
        return PollackStevensModularSymbols(
            G,
            coefficients=self.coefficient_module().change_ring(new_base_ring),
            sign=self.sign())
Ejemplo n.º 15
0
def dimension_modular_forms(X, k=2):
    r"""
    The dimension of the space of cusp forms for the given congruence
    subgroup (either `\Gamma_0(N)`, `\Gamma_1(N)`, or
    `\Gamma_H(N)`) or Dirichlet character.

    INPUT:


    -  ``X`` - congruence subgroup or Dirichlet character

    -  ``k`` - weight (integer)


    EXAMPLES::

        sage: dimension_modular_forms(Gamma0(11),2)
        2
        sage: dimension_modular_forms(Gamma0(11),0)
        1
        sage: dimension_modular_forms(Gamma1(13),2)
        13
        sage: dimension_modular_forms(GammaH(11, [10]), 2)
        10
        sage: dimension_modular_forms(GammaH(11, [10]))
        10
        sage: dimension_modular_forms(GammaH(11, [10]), 4)
        20
        sage: e = DirichletGroup(20).1
        sage: dimension_modular_forms(e,3)
        9
        sage: dimension_cusp_forms(e,3)
        3
        sage: dimension_eis(e,3)
        6
        sage: dimension_modular_forms(11,2)
        2
    """
    if isinstance(X, integer_types + (Integer, )):
        return Gamma0(X).dimension_modular_forms(k)
    elif is_ArithmeticSubgroup(X):
        return X.dimension_modular_forms(k)
    elif isinstance(X, dirichlet.DirichletCharacter):
        return Gamma1(X.modulus()).dimension_modular_forms(k, eps=X)
    else:
        raise TypeError(
            "Argument 1 must be an integer, a Dirichlet character or an arithmetic subgroup."
        )
Ejemplo n.º 16
0
    def dimension(self):
        r"""
        Return the dimension of the space of modular forms of weight 2
        and level equal to the level associated to ``self``.

        INPUT:

        - ``self`` -- SupersingularModule object

        OUTPUT:

        - integer -- dimension, nonnegative

        EXAMPLES::

            sage: S = SupersingularModule(7)
            sage: S.dimension()
            1

            sage: S = SupersingularModule(15073)
            sage: S.dimension()
            1256

            sage: S = SupersingularModule(83401)
            sage: S.dimension()
            6950

        .. NOTE::

           The case of level > 1 has not yet been implemented.

        AUTHORS:

        - David Kohel -- [email protected]

        - Iftikhar Burhanuddin -- [email protected]
        """
        try:
            return self.__dimension
        except AttributeError:
            pass
        if self.__level == 1:
            G = Gamma0(self.__prime)
            self.__dimension = G.dimension_modular_forms(2)
        else:
            raise NotImplementedError
        return self.__dimension
Ejemplo n.º 17
0
    def __init__(self, group, weight=2, eps=1e-20, delta=1e-2, tp=[2, 3, 5]):
        """
        Create a new space of numerical eigenforms.

        EXAMPLES::

            sage: numerical_eigenforms(61) # indirect doctest
            Numerical Hecke eigenvalues for Congruence Subgroup Gamma0(61) of weight 2
        """
        if isinstance(group, integer_types + (Integer, )):
            group = Gamma0(Integer(group))
        self._group = group
        self._weight = Integer(weight)
        self._tp = tp
        if self._weight < 2:
            raise ValueError("weight must be at least 2")
        self._eps = eps
        self._delta = delta
Ejemplo n.º 18
0
def J0(N):
    """
    Return the Jacobian `J_0(N)` of the modular curve
    `X_0(N)`.
    
    EXAMPLES::
    
        sage: J0(389)
        Abelian variety J0(389) of dimension 32
    
    The result is cached::
    
        sage: J0(33) is J0(33)
        True
    """
    key = 'J0(%s)' % N
    try:
        return _get(key)
    except ValueError:
        from sage.modular.arithgroup.all import Gamma0
        J = Gamma0(N).modular_abelian_variety()
        return _saved(key, J)
Ejemplo n.º 19
0
def hecke_stable_subspace(chi, aux_prime=ZZ(2)):
    r"""
    Compute a q-expansion basis for S_1(chi).

    Results are returned as q-expansions to a certain fixed (and fairly high)
    precision. If more precision is required this can be obtained with
    :func:`modular_ratio_to_prec`.

    EXAMPLES::

        sage: from sage.modular.modform.weight1 import hecke_stable_subspace
        sage: hecke_stable_subspace(DirichletGroup(59, QQ).0)
        [q - q^3 + q^4 - q^5 - q^7 - q^12 + q^15 + q^16 + 2*q^17 - q^19 - q^20 + q^21 + q^27 - q^28 - q^29 + q^35 + O(q^40)]
    """
    # Deal quickly with the easy cases.
    if chi(-1) == 1: return []
    N = chi.modulus()
    H = chi.kernel()
    G = GammaH(N, H)
    try:
        if ArithmeticSubgroup.dimension_cusp_forms(G, 1) == 0:
            verbose("no wt 1 cusp forms for N=%s, chi=%s by Riemann-Roch" %
                    (N, chi._repr_short_()),
                    level=1)
            return []
    except NotImplementedError:
        pass

    from sage.modular.modform.constructor import EisensteinForms
    chi = chi.minimize_base_ring()
    K = chi.base_ring()

    # Auxiliary prime for Hecke stability method
    l = aux_prime
    while l.divides(N):
        l = l.next_prime()
    verbose("Auxiliary prime: %s" % l, level=1)

    # Compute working precision
    R = l * Gamma0(N).sturm_bound(l + 2)

    t = verbose("Computing modular ratio space", level=1)
    mrs = modular_ratio_space(chi)

    t = verbose("Computing modular ratios to precision %s" % R, level=1)
    qexps = [modular_ratio_to_prec(chi, f, R) for f in mrs]
    verbose("Done", t=t, level=1)

    # We want to compute the largest subspace of I stable under T_l. To do
    # this, we compute I intersect T_l(I) modulo q^(R/l), and take its preimage
    # under T_l, which is then well-defined modulo q^R.

    from sage.modular.modform.hecke_operator_on_qexp import hecke_operator_on_qexp

    t = verbose("Computing Hecke-stable subspace", level=1)
    A = PowerSeriesRing(K, 'q')
    r = R // l
    V = K**R
    W = K**r
    Tl_images = [hecke_operator_on_qexp(f, l, 1, chi) for f in qexps]
    qvecs = [V(x.padded_list(R)) for x in qexps]
    qvecs_trunc = [W(x.padded_list(r)) for x in qexps]
    Tvecs = [W(x.padded_list(r)) for x in Tl_images]

    I = V.submodule(qvecs)
    Iimage = W.span(qvecs_trunc)
    TlI = W.span(Tvecs)
    Jimage = Iimage.intersection(TlI)
    J = I.Hom(W)(Tvecs).inverse_image(Jimage)

    verbose("Hecke-stable subspace is %s-dimensional" % J.dimension(),
            t=t,
            level=1)

    if J.rank() == 0: return []

    # The theory does not guarantee that J is exactly S_1(chi), just that it is
    # intermediate between S_1(chi) and M_1(chi). In every example I know of,
    # it is equal to S_1(chi), but just for honesty, we check this anyway.
    t = verbose("Checking cuspidality", level=1)
    JEis = V.span(
        V(x.padded_list(R))
        for x in EisensteinForms(chi, 1).q_echelon_basis(prec=R))
    D = JEis.intersection(J)
    if D.dimension() != 0:
        raise ArithmeticError("Got non-cuspidal form!")
    verbose("Done", t=t, level=1)
    qexps = Sequence(A(x.list()).add_bigoh(R) for x in J.gens())
    return qexps
 def sturm_bound(self):
     from sage.modular.arithgroup.all import Gamma0
     # TODO: justify (see article of Buzzard and Stein)
     return Gamma0(self.level()).sturm_bound(self.weight())
Ejemplo n.º 21
0
def dimension_eis(X, k=2):
    """
    The dimension of the space of Eisenstein series for the given
    congruence subgroup.
    
    INPUT:
    
    
    -  ``X`` - congruence subgroup or Dirichlet character
       or integer
    
    -  ``k`` - weight (integer)
    
    
    EXAMPLES::
    
        sage: dimension_eis(5,4)
        2
    
    ::
    
        sage: dimension_eis(Gamma0(11),2)
        1
        sage: dimension_eis(Gamma1(13),2)
        11
        sage: dimension_eis(Gamma1(2006),2)
        3711
    
    ::
    
        sage: e = DirichletGroup(13).0
        sage: e.order()
        12
        sage: dimension_eis(e,2)
        0
        sage: dimension_eis(e^2,2)
        2
    
    ::
    
        sage: e = DirichletGroup(13).0
        sage: e.order()
        12
        sage: dimension_eis(e,2)
        0
        sage: dimension_eis(e^2,2)
        2
        sage: dimension_eis(e,13)
        2
    
    ::
    
        sage: G = DirichletGroup(20)
        sage: dimension_eis(G.0,3)
        4
        sage: dimension_eis(G.1,3)
        6
        sage: dimension_eis(G.1^2,2)
        6
    
    ::
    
        sage: G = DirichletGroup(200)
        sage: e = prod(G.gens(), G(1))
        sage: e.conductor()
        200
        sage: dimension_eis(e,2)
        4
    
    ::
    
        sage: dimension_modular_forms(Gamma1(4), 11)
        6
    """

    if is_ArithmeticSubgroup(X):
        return X.dimension_eis(k)
    elif isinstance(X, dirichlet.DirichletCharacter):
        return Gamma1(X.modulus()).dimension_eis(k, X)
    elif isinstance(X, (int, long, Integer)):
        return Gamma0(X).dimension_eis(k)
    else:
        raise TypeError, "Argument in dimension_eis must be an integer, a Dirichlet character, or a finite index subgroup of SL2Z (got %s)" % X
Ejemplo n.º 22
0
def dimension_cusp_forms(X, k=2):
    r"""
    The dimension of the space of cusp forms for the given congruence
    subgroup or Dirichlet character.
    
    INPUT:
    
    
    -  ``X`` - congruence subgroup or Dirichlet character
       or integer
    
    -  ``k`` - weight (integer)
    
    
    EXAMPLES::
    
        sage: dimension_cusp_forms(5,4)
        1        
    
    ::
    
        sage: dimension_cusp_forms(Gamma0(11),2)
        1
        sage: dimension_cusp_forms(Gamma1(13),2)
        2
    
    ::
    
        sage: dimension_cusp_forms(DirichletGroup(13).0^2,2)
        1
        sage: dimension_cusp_forms(DirichletGroup(13).0,3)
        1
    
    ::
    
        sage: dimension_cusp_forms(Gamma0(11),2)
        1
        sage: dimension_cusp_forms(Gamma0(11),0)
        0
        sage: dimension_cusp_forms(Gamma0(1),12)
        1
        sage: dimension_cusp_forms(Gamma0(1),2)
        0
        sage: dimension_cusp_forms(Gamma0(1),4)
        0
    
    ::
    
        sage: dimension_cusp_forms(Gamma0(389),2)
        32
        sage: dimension_cusp_forms(Gamma0(389),4)
        97
        sage: dimension_cusp_forms(Gamma0(2005),2)
        199
        sage: dimension_cusp_forms(Gamma0(11),1)
        0
    
    ::
    
        sage: dimension_cusp_forms(Gamma1(11),2)
        1
        sage: dimension_cusp_forms(Gamma1(1),12)
        1
        sage: dimension_cusp_forms(Gamma1(1),2)
        0
        sage: dimension_cusp_forms(Gamma1(1),4)
        0
    
    ::
    
        sage: dimension_cusp_forms(Gamma1(389),2)
        6112
        sage: dimension_cusp_forms(Gamma1(389),4)
        18721
        sage: dimension_cusp_forms(Gamma1(2005),2)
        159201
    
    ::
    
        sage: dimension_cusp_forms(Gamma1(11),1)
        0
    
    ::
    
        sage: e = DirichletGroup(13).0
        sage: e.order()
        12
        sage: dimension_cusp_forms(e,2)
        0
        sage: dimension_cusp_forms(e^2,2)
        1

    Check that Trac #12640 is fixed::

        sage: dimension_cusp_forms(DirichletGroup(1)(1), 12)
        1
        sage: dimension_cusp_forms(DirichletGroup(2)(1), 24)
        5        
    """
    if isinstance(X, dirichlet.DirichletCharacter):
        N = X.modulus()
        if N <= 2:
            return Gamma0(N).dimension_cusp_forms(k)
        else:
            return Gamma1(N).dimension_cusp_forms(k, X)
    elif is_ArithmeticSubgroup(X):
        return X.dimension_cusp_forms(k)
    elif isinstance(X, (Integer, int, long)):
        return Gamma0(X).dimension_cusp_forms(k)
    else:
        raise TypeError, "Argument 1 must be a Dirichlet character, an integer or a finite index subgroup of SL2Z"