Exemplo 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.rings.arith 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()])
Exemplo n.º 2
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]
Exemplo 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 = map(ZZ, lift_to_sl2z(c2,d2,m*n))
    r = (a3*b - b3*a) % m
    return [a3 + r*c3, b3 + r*d3, c3, d3]
Exemplo n.º 4
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}`.

    EXAMPLE::

        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]
    def _iterator_discriminant(self, epsilon, offset):
        """
        Return iterator over all possible discriminants of a Fourier index given a content ``eps``
        and a discriminant offset modulo `D`.
        
        INPUT:
            - `\epsilon` -- Integer; Content of an index.
            - ``offset`` -- Integer; Offset modulo D of the discriminant.

        OUTPUT:
            - Iterator over Integers.

        TESTS::
            sage: fac = HermitianModularFormD2Factory(4,-3)
            sage: list(fac._iterator_discriminant(2, 3))
            [0, 12, 24]
            sage: list(fac._iterator_discriminant(2, 2))
            [8, 20]
            sage: list(fac._iterator_discriminant(1, 2))
            [2, 5, 8, 11, 14, 17, 20, 23, 26]
        """
        mD = -self.__D
        periode = lcm(mD, epsilon**2)
        offset = crt(offset, 0, mD, epsilon**2) % periode

        return xrange(offset,
                      self.__precision._enveloping_discriminant_bound(),
                      periode)
    def _iterator_discriminant(self, epsilon, offset) :
        """
        Return iterator over all possible discriminants of a Fourier index given a content ``eps``
        and a discriminant offset modulo `D`.
        
        INPUT:
            - `\epsilon` -- Integer; Content of an index.
            - ``offset`` -- Integer; Offset modulo D of the discriminant.

        OUTPUT:
            - Iterator over Integers.

        TESTS::
            sage: fac = HermitianModularFormD2Factory(4,-3)
            sage: list(fac._iterator_discriminant(2, 3))
            [0, 12, 24]
            sage: list(fac._iterator_discriminant(2, 2))
            [8, 20]
            sage: list(fac._iterator_discriminant(1, 2))
            [2, 5, 8, 11, 14, 17, 20, 23, 26]
        """
        mD = -self.__D
        periode = lcm(mD, epsilon**2)
        offset = crt(offset, 0, mD, epsilon**2) % periode 
        
        return xrange( offset,
                       self.__precision._enveloping_discriminant_bound(),
                       periode )
Exemplo n.º 7
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.rings.arith 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()])
Exemplo 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)
Exemplo n.º 9
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)
Exemplo n.º 10
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 = map(ZZ, 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())
Exemplo n.º 11
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 = map(ZZ, 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:
                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())