def weil_representation_kernel(self):
        r"""
        Compute a scalar `r` and a group `\Gamma` which contains the translation `T`
        so that `\diag(1, 1/r) \Gamma \diag(1, r) \subseteq \ker( \rho_D )`.

        OUTPUT:
        
        - A pair of an integer and an arithmetic group.
        """
        if self._L == matrix(
                2, [2, 1, 1, 2]) or self._L == -matrix(2, [2, 1, 1, 2]):
            return (ZZ(3), GammaH(9, [4]))
        if self._L == matrix(
                2, [2, 0, 0, 2]) or self._L == -matrix(2, [2, 0, 0, 2]):
            return (ZZ(4), GammaH(16, [5]))

        if self._L == matrix(
                2, [2, 0, 0, 4]) or self._L == -matrix(2, [2, 0, 0, 4]):
            return (ZZ(8), GammaH(64, [57]))

        level = 2 * self._L.inverse().denominator()
        return (level,
                GammaH(level**2,
                       filter(lambda n: n % level == 1, range(level**2))))
Beispiel #2
0
def JH(N, H):
    """
    Return the Jacobian `J_H(N)` of the modular curve
    `X_H(N)`.
    
    EXAMPLES::
    
        sage: JH(389,[16])
        Abelian variety JH(389,[16]) of dimension 64
    """
    key = 'JH(%s,%s)' % (N, H)
    try:
        return _get(key)
    except ValueError:
        from sage.modular.arithgroup.all import GammaH
        return _saved(key, GammaH(N, H).modular_abelian_variety())
Beispiel #3
0
    def group(self):
        r"""
        Return a `\Gamma_H` group which is the level of all of the relevant
        twists of `f`.

        EXAMPLE::

            sage: from sage.modular.local_comp.type_space import example_type_space
            sage: example_type_space().group()
            Congruence Subgroup Gamma_H(98) with H generated by [57]
        """
        p = self.prime()
        r = self.conductor()
        d = max(self.character_conductor(), r // 2)
        n = self.tame_level()
        chi = self.form().character()
        tame_H = [i for i in chi.kernel() if (i % p**r) == 1]
        wild_H = [crt(1 + p**d, 1, p**r, n)]
        return GammaH(n * p**r, tame_H + wild_H)
Beispiel #4
0
    def group(self):
        r"""
        Return a `\Gamma_H` group which is the level of all of the relevant
        twists of `f`.

        EXAMPLES::

            sage: from sage.modular.local_comp.type_space import example_type_space
            sage: example_type_space().group()
            Congruence Subgroup Gamma_H(98) with H generated by [15, 29, 43]
        """
        # Implementation here is not the most efficient but this is heavily not
        # time-critical, and getting it wrong can lead to subtle bugs.
        p = self.prime()
        r = self.conductor()
        d = max(self.character_conductor(), r // 2)
        n = self.tame_level()
        chi = self.form().character()
        tame_H = [i for i in chi.kernel() if (i % p**r) == 1]
        wild_H = [crt(x, 1, p**r, n) for x in range(p**r) if x % (p**d) == 1]
        return GammaH(n * p**r, tame_H + wild_H)
Beispiel #5
0
    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
Beispiel #6
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