Ejemplo n.º 1
0
    def central_character(self):
        r"""
        Return the central character of this representation. This is the
        restriction to `\QQ_p^\times` of the unique smooth character `\omega`
        of `\mathbf{A}^\times / \QQ^\times` such that `\omega(\varpi_\ell) =
        \ell^j \varepsilon(\ell)` for all primes `\ell \nmid Np`, where
        `\varpi_\ell` is a uniformiser at `\ell`, `\varepsilon` is the
        Nebentypus character of the newform `f`, and `j` is the twist factor
        (see the documentation for :func:`~LocalComponent`).

        EXAMPLES::

            sage: LocalComponent(Newform('27a'), 3).central_character()
            Character of Q_3*, of level 0, mapping 3 |--> 1

            sage: LocalComponent(Newforms(Gamma1(5), 5, names='c')[0], 5).central_character()
            Character of Q_5*, of level 1, mapping 2 |--> c0 + 1, 5 |--> 125

            sage: LocalComponent(Newforms(DirichletGroup(24)([1, -1,-1]), 3, names='a')[0], 2).central_character()
            Character of Q_2*, of level 3, mapping 7 |--> 1, 5 |--> -1, 2 |--> -2
        """
        from sage.arith.all import crt
        chi = self.newform().character()
        f = self.prime() ** self.conductor()
        N = self.newform().level() // f
        G = DirichletGroup(f, self.coefficient_field())
        chip = G([chi(crt(ZZ(x), 1, f, N)) for x in G.unit_gens()]).primitive_character()
        a = crt(1, self.prime(), f, N)

        if chip.conductor() == 1:
            return SmoothCharacterGroupQp(self.prime(), self.coefficient_field()).character(0, [chi(a) * self.prime()**self.twist_factor()])
        else:
            return SmoothCharacterGroupQp(self.prime(), self.coefficient_field()).character(chip.conductor().valuation(self.prime()), list((~chip).values_on_gens()) + [chi(a) * self.prime()**self.twist_factor()])
Ejemplo n.º 2
0
    def central_character(self):
        r"""
        Return the central character of this representation. This is the
        restriction to `\QQ_p^\times` of the unique smooth character `\omega`
        of `\mathbf{A}^\times / \QQ^\times` such that `\omega(\varpi_\ell) =
        \ell^j \varepsilon(\ell)` for all primes `\ell \nmid Np`, where
        `\varpi_\ell` is a uniformiser at `\ell`, `\varepsilon` is the
        Nebentypus character of the newform `f`, and `j` is the twist factor
        (see the documentation for :func:`~LocalComponent`).

        EXAMPLES::

            sage: LocalComponent(Newform('27a'), 3).central_character()
            Character of Q_3*, of level 0, mapping 3 |--> 1

            sage: LocalComponent(Newforms(Gamma1(5), 5, names='c')[0], 5).central_character()
            Character of Q_5*, of level 1, mapping 2 |--> c0 + 1, 5 |--> 125

            sage: LocalComponent(Newforms(DirichletGroup(24)([1, -1,-1]), 3, names='a')[0], 2).central_character()
            Character of Q_2*, of level 3, mapping 7 |--> 1, 5 |--> -1, 2 |--> -2
        """
        from sage.arith.all import crt
        chi = self.newform().character()
        f = self.prime() ** self.conductor()
        N = self.newform().level() // f
        G = DirichletGroup(f, self.coefficient_field())
        chip = G([chi(crt(ZZ(x), 1, f, N)) for x in G.unit_gens()]).primitive_character()
        a = crt(1, self.prime(), f, N)

        if chip.conductor() == 1:
            return SmoothCharacterGroupQp(self.prime(), self.coefficient_field()).character(0, [chi(a) * self.prime()**self.twist_factor()])
        else:
            return SmoothCharacterGroupQp(self.prime(), self.coefficient_field()).character(chip.conductor().valuation(self.prime()), list((~chip).values_on_gens()) + [chi(a) * self.prime()**self.twist_factor()])
Ejemplo n.º 3
0
def lift_to_gamma1(g, m, n):
    r"""
    If ``g = [a,b,c,d]`` is a list of integers defining a `2 \times 2` matrix
    whose determinant is `1 \pmod m`, return a list of integers giving the
    entries of a matrix which is congruent to `g \pmod m` and to
    `\begin{pmatrix} 1 & * \\ 0 & 1 \end{pmatrix} \pmod n`. Here `m` and `n`
    must be coprime.

    Here `m` and `n` should be coprime positive integers. Either of `m` and `n`
    can be `1`. If `n = 1`, this still makes perfect sense; this is what is
    called by the function :func:`~lift_matrix_to_sl2z`. If `m = 1` this is a
    rather silly question, so we adopt the convention of always returning the
    identity matrix.

    The result is always a list of Sage integers (unlike ``lift_to_sl2z``,
    which tends to return Python ints).

    EXAMPLE::

        sage: from sage.modular.local_comp.liftings import lift_to_gamma1
        sage: A = matrix(ZZ, 2, lift_to_gamma1([10, 11, 3, 11], 19, 5)); A
        [371  68]
        [ 60  11]
        sage: A.det() == 1
        True
        sage: A.change_ring(Zmod(19))
        [10 11]
        [ 3 11]
        sage: A.change_ring(Zmod(5))
        [1 3]
        [0 1]
        sage: m = list(SL2Z.random_element())
        sage: n = lift_to_gamma1(m, 11, 17)
        sage: assert matrix(Zmod(11), 2, n) == matrix(Zmod(11),2,m)
        sage: assert matrix(Zmod(17), 2, [n[0], 0, n[2], n[3]]) == 1
        sage: type(lift_to_gamma1([10,11,3,11],19,5)[0])
        <type 'sage.rings.integer.Integer'>

    Tests with `m = 1` and with `n = 1`::

        sage: lift_to_gamma1([1,1,0,1], 5, 1)
        [1, 1, 0, 1]
        sage: lift_to_gamma1([2,3,11,22], 1, 5)
        [1, 0, 0, 1]
    """
    if m == 1:
        return [ZZ(1), ZZ(0), ZZ(0), ZZ(1)]
    a, b, c, d = [ZZ(x) for x in g]
    if not (a * d - b * c) % m == 1:
        raise ValueError("Determinant is {0} mod {1}, should be 1".format(
            (a * d - b * c) % m, m))
    c2 = crt(c, 0, m, n)
    d2 = crt(d, 1, m, n)
    a3, b3, c3, d3 = [ZZ(_) for _ in lift_to_sl2z(c2, d2, m * n)]
    r = (a3 * b - b3 * a) % m
    return [a3 + r * c3, b3 + r * d3, c3, d3]
Ejemplo n.º 4
0
def lift_to_gamma1(g, m, n):
    r"""
    If ``g = [a,b,c,d]`` is a list of integers defining a `2 \times 2` matrix
    whose determinant is `1 \pmod m`, return a list of integers giving the
    entries of a matrix which is congruent to `g \pmod m` and to
    `\begin{pmatrix} 1 & * \\ 0 & 1 \end{pmatrix} \pmod n`. Here `m` and `n`
    must be coprime.

    Here `m` and `n` should be coprime positive integers. Either of `m` and `n`
    can be `1`. If `n = 1`, this still makes perfect sense; this is what is
    called by the function :func:`~lift_matrix_to_sl2z`. If `m = 1` this is a
    rather silly question, so we adopt the convention of always returning the
    identity matrix.

    The result is always a list of Sage integers (unlike ``lift_to_sl2z``,
    which tends to return Python ints).

    EXAMPLES::

        sage: from sage.modular.local_comp.liftings import lift_to_gamma1
        sage: A = matrix(ZZ, 2, lift_to_gamma1([10, 11, 3, 11], 19, 5)); A
        [371  68]
        [ 60  11]
        sage: A.det() == 1
        True
        sage: A.change_ring(Zmod(19))
        [10 11]
        [ 3 11]
        sage: A.change_ring(Zmod(5))
        [1 3]
        [0 1]
        sage: m = list(SL2Z.random_element())
        sage: n = lift_to_gamma1(m, 11, 17)
        sage: assert matrix(Zmod(11), 2, n) == matrix(Zmod(11),2,m)
        sage: assert matrix(Zmod(17), 2, [n[0], 0, n[2], n[3]]) == 1
        sage: type(lift_to_gamma1([10,11,3,11],19,5)[0])
        <type 'sage.rings.integer.Integer'>

    Tests with `m = 1` and with `n = 1`::

        sage: lift_to_gamma1([1,1,0,1], 5, 1)
        [1, 1, 0, 1]
        sage: lift_to_gamma1([2,3,11,22], 1, 5)
        [1, 0, 0, 1]
    """
    if m == 1:
        return [ZZ(1),ZZ(0),ZZ(0),ZZ(1)]
    a,b,c,d = [ZZ(x) for x in g]
    if not (a*d - b*c) % m == 1:
        raise ValueError( "Determinant is {0} mod {1}, should be 1".format((a*d - b*c) % m, m) )
    c2 = crt(c, 0, m, n)
    d2 = crt(d, 1, m, n)
    a3,b3,c3,d3 = [ZZ(_) for _ in lift_to_sl2z(c2,d2,m*n)]
    r = (a3*b - b3*a) % m
    return [a3 + r*c3, b3 + r*d3, c3, d3]
Ejemplo n.º 5
0
def lift_ramified(g, p, u, n):
    r"""
    Given four integers `a,b,c,d` with `p \mid c` and `ad - bc = 1 \pmod{p^u}`,
    find `a',b',c',d'` congruent to `a,b,c,d \pmod{p^u}`, with `c' = c
    \pmod{p^{u+1}}`, such that `a'd' - b'c'` is exactly 1, and `\begin{pmatrix}
    a & b \\ c & d \end{pmatrix}` is in `\Gamma_1(n)`.

    Algorithm: Uses :func:`~lift_to_gamma1` to get a lifting modulo `p^u`, and
    then adds an appropriate multiple of the top row to the bottom row in order
    to get the bottom-left entry correct modulo `p^{u+1}`.

    EXAMPLES::

        sage: from sage.modular.local_comp.liftings import lift_ramified
        sage: lift_ramified([2,2,3,2], 3, 1, 1)
        [5, 8, 3, 5]
        sage: lift_ramified([8,2,12,2], 3, 2, 23)
        [323, 110, -133584, -45493]
        sage: type(lift_ramified([8,2,12,2], 3, 2, 23)[0])
        <type 'sage.rings.integer.Integer'>
    """
    a,b,c,d = lift_to_gamma1(g, p**u, n)
    r = crt( (c - g[2]) / p**u * inverse_mod(a, p), 0, p, n)
    c = c - p**u * r * a
    d = d - p**u * r * b
    # assert (c - g[2]) % p**(u+1) == 0
    return [a,b,c,d]
Ejemplo n.º 6
0
    def parallel_function_combination(point_p_max):
        r"""
        Function used in parallel computation, computes rational
        points lifted.
        """
        rat_points = set()
        for tupl in xmrange(len_modulo_points):
            point = []
            for k in range(N):
                # lift all coordinates of given point using chinese remainder theorem
                L = [
                    modulo_points[j][tupl[j]][k].lift()
                    for j in range(len_primes - 1)
                ]
                L.append(point_p_max[k].lift())
                point.append(crt(L, primes_list))

            for i in range(num_comp):
                for j in range(comp_dim_relative[i]):
                    m[i][j] = point[dim_prefix[i] + j]

            # generating matrix to compute LLL reduction for each component
            M = [matrix(ZZ, comp_dim_relative[i] + 1, comp_dim_relative[i], m[i]) \
                                                                for i in range(num_comp)]
            A = [M[i].LLL() for i in range(num_comp)]
            point = []
            for i in range(num_comp):
                point.extend(A[i][1])

            # check if all coordinates of this point satisfy height bound
            bound_satisfied = True
            for coordinate in point:
                if coordinate.abs() > bound:
                    bound_satisfied = False
                    break
            if not bound_satisfied:
                continue

            try:
                rat_points.add(
                    X(point))  # checks if this point lies on X or not
            except:
                pass

        return [list(_) for _ in rat_points]
Ejemplo n.º 7
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)
Ejemplo n.º 8
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)
Ejemplo n.º 9
0
    def _unif_ramified(self):
        r"""
        Return the action of [0,-1,p,0], in the ramified (odd p-power level)
        case.

        EXAMPLES::

            sage: from sage.modular.local_comp.type_space import example_type_space
            sage: T = example_type_space(3)
            sage: T._unif_ramified()
            [-1  0]
            [ 0 -1]

        """
        p = self.prime()
        k = self.form().weight()
        return (self.t_space.atkin_lehner_operator(p).matrix().transpose() *
                p**(-(k - 2) * self.u()) * self.t_space.diamond_bracket_matrix(
                    crt(1, p**self.u(), p**self.u(),
                        self.tame_level())).transpose())
Ejemplo n.º 10
0
    def parallel_function_combination(point_p_max):
        r"""
        Function used in parallel computation, computes rational
        points lifted.
        """
        rat_points = set()
        for tupl in xmrange(len_modulo_points):
            point = []
            for k in range(N + 1):
                # lift all coordinates of given point using chinese remainder theorem
                L = [
                    modulo_points[j][tupl[j]][k].lift()
                    for j in range(len_primes - 1)
                ]
                L.append(point_p_max[k].lift())
                point.append(crt(L, primes_list))

            for i in range(N + 1):
                m[i] = point[i]

            M = matrix(ZZ, N + 2, N + 1, m)
            A = M.LLL()
            point = list(A[1])

            # check if all coordinates of this point satisfy height bound
            bound_satisfied = True
            for coordinate in point:
                if coordinate.abs() > bound:
                    bound_satisfied = False
                    break
            if not bound_satisfied:
                continue

            try:
                pt = X(list(A[1]))
            except TypeError:
                pass
            else:
                rat_points.add(pt)

        return [list(_) for _ in rat_points]
Ejemplo n.º 11
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)
Ejemplo n.º 12
0
    def rho(self, g):
        r"""
        Calculate the action of the group element `g` on the type space.

        EXAMPLE::

            sage: from sage.modular.local_comp.type_space import example_type_space
            sage: T = example_type_space(2)
            sage: m = T.rho([2,0,0,1]); m
            [ 1 -2  1  0]
            [ 1 -1  0  1]
            [ 1  0 -1  1]
            [ 0  1 -2  1]
            sage: v = T.eigensymbol_subspace().basis()[0]
            sage: m * v == v
            True

        We test that it is a left action::

            sage: T = example_type_space(0)
            sage: a = [0,5,4,3]; b = [0,2,3,5]; ab = [1,4,2,2]
            sage: T.rho(ab) == T.rho(a) * T.rho(b)
            True

        An odd level example::

            sage: from sage.modular.local_comp.type_space import TypeSpace
            sage: T = TypeSpace(Newform('54a'), 3)
            sage: a = [0,1,3,0]; b = [2,1,0,1]; ab = [0,1,6,3]
            sage: T.rho(ab) == T.rho(a) * T.rho(b)
            True
        """
        if not self.is_minimal():
            raise NotImplementedError(
                "Group action on non-minimal type space not implemented")

        if self.u() == 0:
            # silly special case: rep is principal series or special, so SL2
            # action on type space is trivial
            raise ValueError("Representation is not supercuspidal")

        p = self.prime()
        f = p**self.u()
        g = [ZZ(_) for _ in g]
        d = (g[0] * g[3] - g[2] * g[1])

        # g is in S(K_0) (easy case)
        if d % f == 1:
            return self._rho_s(g)

        # g is in K_0, but not in S(K_0)

        if d % p != 0:
            try:
                a = self._a
            except AttributeError:
                self._discover_torus_action()
                a = self._a
            i = 0
            while (d * a**i) % f != 1:
                i += 1
                if i > f: raise ArithmeticError
            return self._rho_s([a**i * g[0], g[1], a**i * g[2], g[3]
                                ]) * self._amat**(-i)

        # funny business

        if (self.conductor() % 2 == 0):
            if all([x.valuation(p) > 0 for x in g]):
                eps = self.form().character()(crt(1, p, f, self.tame_level()))
                return ~eps * self.rho([x // p for x in g])
            else:
                raise ArithmeticError("g(={0}) not in K".format(g))

        else:
            m = matrix(ZZ, 2, g)
            s = m.det().valuation(p)
            mm = (matrix(QQ, 2, [0, -1, p, 0])**(-s) * m).change_ring(ZZ)
            return self._unif_ramified()**s * self.rho(mm.list())
Ejemplo n.º 13
0
    def rho(self, g):
        r"""
        Calculate the action of the group element `g` on the type space.

        EXAMPLE::

            sage: from sage.modular.local_comp.type_space import example_type_space
            sage: T = example_type_space(2)
            sage: m = T.rho([2,0,0,1]); m
            [ 1 -2  1  0]
            [ 1 -1  0  1]
            [ 1  0 -1  1]
            [ 0  1 -2  1]
            sage: v = T.eigensymbol_subspace().basis()[0]
            sage: m * v == v
            True

        We test that it is a left action::

            sage: T = example_type_space(0)
            sage: a = [0,5,4,3]; b = [0,2,3,5]; ab = [1,4,2,2]
            sage: T.rho(ab) == T.rho(a) * T.rho(b)
            True

        An odd level example::

            sage: from sage.modular.local_comp.type_space import TypeSpace
            sage: T = TypeSpace(Newform('54a'), 3)
            sage: a = [0,1,3,0]; b = [2,1,0,1]; ab = [0,1,6,3]
            sage: T.rho(ab) == T.rho(a) * T.rho(b)
            True
        """
        if not self.is_minimal():
            raise NotImplementedError( "Group action on non-minimal type space not implemented" )

        if self.u() == 0:
           # silly special case: rep is principal series or special, so SL2
           # action on type space is trivial
           raise ValueError( "Representation is not supercuspidal" )

        p = self.prime()
        f = p**self.u()
        g = [ZZ(_) for _ in g]
        d = (g[0]*g[3] - g[2]*g[1])

        # g is in S(K_0) (easy case)
        if d % f == 1:
            return self._rho_s(g)

        # g is in K_0, but not in S(K_0)

        if d % p != 0:
            try:
                a = self._a
            except AttributeError:
                self._discover_torus_action()
                a = self._a
            i = 0
            while (d * a**i) % f != 1:
                i += 1
                if i > f: raise ArithmeticError
            return self._rho_s([a**i*g[0], g[1], a**i*g[2], g[3]]) * self._amat**(-i)

        # funny business

        if (self.conductor() % 2 == 0):
            if all([x.valuation(p) > 0 for x in g]):
                eps = self.form().character()(crt(1, p, f, self.tame_level()))
                return ~eps * self.rho([x // p for x in g])
            else:
                raise ArithmeticError( "g(={0}) not in K".format(g) )

        else:
            m = matrix(ZZ, 2, g)
            s = m.det().valuation(p)
            mm = (matrix(QQ, 2, [0, -1, p, 0])**(-s) * m).change_ring(ZZ)
            return self._unif_ramified()**s * self.rho(mm.list())