Ejemplo n.º 1
0
    def _isomorphism(self, prec=20):
        r"""
        Return the isomorphism between ``self.curve()`` and the given
        curve in the form of a list ``[u,r,s,t]`` of `p`-adic numbers.

        For this to exist the given curve has to have split
        multiplicative reduction over `\QQ_p`.

        More precisely, if `E` has coordinates `x` and `y` and the Tate
        curve has coordinates `X`, `Y` with `Y^2 + XY = X^3 + s_4 X +s_6`
        then `X = u^2 x +r` and `Y = u^3 y +s u^2 x +t`.

        INPUT:

        - ``prec`` - the `p`-adic precision, default is 20.

        EXAMPLES::

            sage: eq = EllipticCurve('130a1').tate_curve(5)
            sage: eq._isomorphism(prec=5)
            [2 + 3*5^2 + 2*5^3 + 4*5^4 + O(5^5),
             4 + 3*5 + 4*5^2 + 2*5^3 + O(5^5),
             3 + 2*5 + 5^2 + 5^3 + 2*5^4 + O(5^5),
             2 + 5 + 3*5^2 + 5^3 + 5^4 + O(5^5)]
        """
        if not self.is_split():
            raise RuntimeError("The curve must have split multiplicative "
                               "reduction")
        C = self._Csquare(prec=prec + 4).sqrt()
        R = Qp(self._p, prec)
        C = R(C)
        s = (C * R(self._E.a1()) - R.one()) / R(2)
        r = (C ** 2 * R(self._E.a2()) + s + s ** 2) / R(3)
        t = (C ** 3 * R(self._E.a3()) - r) / R(2)
        return [C, r, s, t]
Ejemplo n.º 2
0
    def _isomorphism(self, prec=20):
        r"""
        Return the isomorphism between ``self.curve()`` and the given
        curve in the form of a list ``[u,r,s,t]`` of `p`-adic numbers.

        For this to exist the given curve has to have split
        multiplicative reduction over `\QQ_p`.

        More precisely, if `E` has coordinates `x` and `y` and the Tate
        curve has coordinates `X`, `Y` with `Y^2 + XY = X^3 + s_4 X +s_6`
        then `X = u^2 x +r` and `Y = u^3 y +s u^2 x +t`.

        INPUT:

        - ``prec`` - the `p`-adic precision, default is 20.

        EXAMPLES::

            sage: eq = EllipticCurve('130a1').tate_curve(5)
            sage: eq._isomorphism(prec=5)
            [2 + 3*5^2 + 2*5^3 + 4*5^4 + O(5^5),
             4 + 3*5 + 4*5^2 + 2*5^3 + O(5^5),
             3 + 2*5 + 5^2 + 5^3 + 2*5^4 + O(5^5),
             2 + 5 + 3*5^2 + 5^3 + 5^4 + O(5^5)]
        """
        if not self.is_split():
            raise RuntimeError("The curve must have split multiplicative "
                               "reduction")
        C = self._Csquare(prec=prec + 4).sqrt()
        R = Qp(self._p, prec)
        C = R(C)
        s = (C * R(self._E.a1()) - R.one()) / R(2)
        r = (C**2 * R(self._E.a2()) + s + s**2) / R(3)
        t = (C**3 * R(self._E.a3()) - r) / R(2)
        return [C, r, s, t]
Ejemplo n.º 3
0
    def lift(self, P, prec=20):
        r"""
        Given a point `P` in the formal group of the elliptic curve `E` with split multiplicative reduction,
        this produces an element `u` in `\QQ_p^{\times}` mapped to the point `P` by the Tate parametrisation.
        The algorithm return the unique such element in `1+p\ZZ_p`.

        INPUT:

        - ``P`` - a point on the elliptic curve.

        - ``prec`` - the `p`-adic precision, default is 20.

        EXAMPLES::

            sage: e = EllipticCurve('130a1')
            sage: eq = e.tate_curve(5)
            sage: P = e([-6,10])
            sage: l = eq.lift(12*P, prec=10); l
            1 + 4*5 + 5^3 + 5^4 + 4*5^5 + 5^6 + 5^7 + 4*5^8 + 5^9 + O(5^10)

        Now we map the lift l back and check that it is indeed right.::

            sage: eq.parametrisation_onto_original_curve(l)
            (4*5^-2 + 2*5^-1 + 4*5 + 3*5^3 + 5^4 + 2*5^5 + 4*5^6 + O(5^7) : 2*5^-3 + 5^-1 + 4 + 4*5 + 5^2 + 3*5^3 + 4*5^4 + O(5^6) : 1 + O(5^20))
            sage: e5 = e.change_ring(Qp(5,9))
            sage: e5(12*P)
            (4*5^-2 + 2*5^-1 + 4*5 + 3*5^3 + 5^4 + 2*5^5 + 4*5^6 + O(5^7) : 2*5^-3 + 5^-1 + 4 + 4*5 + 5^2 + 3*5^3 + 4*5^4 + O(5^6) : 1 + O(5^9))
        """
        p = self._p
        R = Qp(self._p, prec)
        if not self._E == P.curve():
            raise ValueError("The point must lie on the original curve.")
        if not self.is_split():
            raise ValueError(
                "The curve must have split multiplicative reduction.")
        if P.is_zero():
            return R.one()
        if P[0].valuation(p) >= 0:
            raise ValueError("The point must lie in the formal group.")

        Eq = self.curve(prec=prec)
        C, r, s, t = self._isomorphism(prec=prec)
        xx = r + C**2 * P[0]
        yy = t + s * C**2 * P[0] + C**3 * P[1]
        try:
            Eq([xx, yy])
        except Exception:
            raise RuntimeError("Bug : Point %s does not lie on the curve " %
                               (xx, yy))

        tt = -xx / yy
        eqhat = Eq.formal()
        eqlog = eqhat.log(prec + 3)
        z = eqlog(tt)
        u = ZZ.one()
        fac = ZZ.one()
        for i in range(1, 2 * prec + 1):
            fac *= i
            u += z**i / fac
        return u
Ejemplo n.º 4
0
    def parameter(self, prec=20):
        r"""
        Return the Tate parameter `q` such that the curve is isomorphic
        over the algebraic closure of `\QQ_p` to the curve
        `\QQ_p^{\times}/q^{\ZZ}`.

        INPUT:

        - ``prec`` -- the `p`-adic precision, default is 20.

        EXAMPLES::

            sage: eq = EllipticCurve('130a1').tate_curve(5)
            sage: eq.parameter(prec=5)
            3*5^3 + 3*5^4 + 2*5^5 + 2*5^6 + 3*5^7 + O(5^8)
        """
        qE = getattr(self, "_q", None)
        if qE and qE.precision_relative() >= prec:
            return Qp(self._p, prec=prec)(qE)

        E4 = EisensteinForms(weight=4).basis()[0]
        Delta = CuspForms(weight=12).basis()[0]
        j = (E4.q_expansion(prec + 3))**3 / Delta.q_expansion(prec + 3)
        jinv = (1 / j).power_series()
        q_in_terms_of_jinv = jinv.reverse()
        R = Qp(self._p, prec=prec)
        qE = q_in_terms_of_jinv(R(1 / self._E.j_invariant()))
        self._q = qE
        return qE
Ejemplo n.º 5
0
    def lift(self, P, prec=20):
        r"""
        Given a point `P` in the formal group of the elliptic curve `E` with split multiplicative reduction,
        this produces an element `u` in `\QQ_p^{\times}` mapped to the point `P` by the Tate parametrisation.
        The algorithm return the unique such element in `1+p\ZZ_p`.

        INPUT:

        - ``P`` - a point on the elliptic curve.

        - ``prec`` - the `p`-adic precision, default is 20.

        EXAMPLES::

            sage: e = EllipticCurve('130a1')
            sage: eq = e.tate_curve(5)
            sage: P = e([-6,10])
            sage: l = eq.lift(12*P, prec=10); l
            1 + 4*5 + 5^3 + 5^4 + 4*5^5 + 5^6 + 5^7 + 4*5^8 + 5^9 + O(5^10)

        Now we map the lift l back and check that it is indeed right.::

            sage: eq.parametrisation_onto_original_curve(l)
            (4*5^-2 + 2*5^-1 + 4*5 + 3*5^3 + 5^4 + 2*5^5 + 4*5^6 + O(5^7) : 2*5^-3 + 5^-1 + 4 + 4*5 + 5^2 + 3*5^3 + 4*5^4 + O(5^6) : 1 + O(5^20))
            sage: e5 = e.change_ring(Qp(5,9))
            sage: e5(12*P)
            (4*5^-2 + 2*5^-1 + 4*5 + 3*5^3 + 5^4 + 2*5^5 + 4*5^6 + O(5^7) : 2*5^-3 + 5^-1 + 4 + 4*5 + 5^2 + 3*5^3 + 4*5^4 + O(5^6) : 1 + O(5^9))
        """
        p = self._p
        R = Qp(self._p, prec)
        if not self._E == P.curve():
            raise ValueError("The point must lie on the original curve.")
        if not self.is_split():
            raise ValueError("The curve must have split multiplicative reduction.")
        if P.is_zero():
            return R.one()
        if P[0].valuation(p) >= 0:
            raise ValueError("The point must lie in the formal group.")

        Eq = self.curve(prec=prec)
        C, r, s, t = self._isomorphism(prec=prec)
        xx = r + C ** 2 * P[0]
        yy = t + s * C ** 2 * P[0] + C ** 3 * P[1]
        try:
            Eq([xx, yy])
        except Exception:
            raise RuntimeError("Bug : Point %s does not lie on the curve " %
                               (xx, yy))

        tt = -xx / yy
        eqhat = Eq.formal()
        eqlog = eqhat.log(prec + 3)
        z = eqlog(tt)
        u = ZZ.one()
        fac = ZZ.one()
        for i in range(1, 2 * prec + 1):
            fac *= i
            u += z ** i / fac
        return u
Ejemplo n.º 6
0
    def completions(self, p, M):
        r"""
        If `K` is the base_ring of self, this function takes all maps
        `K-->Q_p` and applies them to self return a list of
        (modular symbol,map: `K-->Q_p`) as map varies over all such maps.

        .. NOTE::

            This only returns all completions when `p` splits completely in `K`

        INPUT:

        - ``p`` -- prime

        - ``M`` -- precision

        OUTPUT:

        - A list of tuples (modular symbol,map: `K-->Q_p`) as map varies over all such maps

        EXAMPLES::

            sage: from sage.modular.pollack_stevens.space import ps_modsym_from_simple_modsym_space
            sage: D = ModularSymbols(67,2,1).cuspidal_submodule().new_subspace().decomposition()[1]
            sage: f = ps_modsym_from_simple_modsym_space(D)
            sage: f.completions(41,10)
            [(Modular symbol with values in Sym^0 Q_41^2, Ring morphism:
              From: Number Field in alpha with defining polynomial x^2 + 3*x + 1
              To:   41-adic Field with capped relative precision 10
              Defn: alpha |--> 5 + 22*41 + 19*41^2 + 10*41^3 + 28*41^4 + 22*41^5 + 9*41^6 + 25*41^7 + 40*41^8 + 8*41^9 + O(41^10)), (Modular symbol with values in Sym^0 Q_41^2, Ring morphism:
              From: Number Field in alpha with defining polynomial x^2 + 3*x + 1
              To:   41-adic Field with capped relative precision 10
              Defn: alpha |--> 33 + 18*41 + 21*41^2 + 30*41^3 + 12*41^4 + 18*41^5 + 31*41^6 + 15*41^7 + 32*41^9 + O(41^10))]
        """
        K = self.base_ring()
        f = K.defining_polynomial()
        R = Qp(p,M+10)['x']
        x = R.gen()
        v = R(f).roots()
        if len(v) == 0:
            L = Qp(p,M).extension(f,names='a')
            a = L.gen()
            V = self.parent().change_ring(L)
            Dist = V.coefficient_module()
            psi = K.hom([K.gen()],L)
            embedded_sym = self.__class__(self._map.apply(psi,codomain=Dist, to_moments=True),V, construct=True)
            ans = [embedded_sym,psi]
            return ans
            #raise ValueError, "No coercion possible -- no prime over p has degree 1"
        else:
            roots = [r[0] for r in v]
            ans = []
            V = self.parent().change_ring(Qp(p, M))
            Dist = V.coefficient_module()
            for r in roots:
                psi = K.hom([r],Qp(p,M))
                embedded_sym = self.__class__(self._map.apply(psi, codomain=Dist, to_moments=True), V, construct=True)
                ans.append((embedded_sym,psi))
            return ans
Ejemplo n.º 7
0
    def parametrisation_onto_tate_curve(self, u, prec=None):
        r"""
        Given an element `u` in `\QQ_p^{\times}`, this computes its image on the Tate curve
        under the `p`-adic uniformisation of `E`.

        INPUT:

        - ``u`` -- a non-zero `p`-adic number.

        - ``prec`` -- the `p`-adic precision, default is the relative precision of ``u``
          otherwise 20.


        EXAMPLES::

            sage: eq = EllipticCurve('130a1').tate_curve(5)
            sage: eq.parametrisation_onto_tate_curve(1+5+5^2+O(5^10), prec=10)
            (5^-2 + 4*5^-1 + 1 + 2*5 + 3*5^2 + 2*5^5 + 3*5^6 + O(5^7) : 4*5^-3 + 2*5^-1 + 4 + 2*5 + 3*5^4 + 2*5^5 + O(5^6) : 1 + O(5^10))
            sage: eq.parametrisation_onto_tate_curve(1+5+5^2+O(5^10))
            (5^-2 + 4*5^-1 + 1 + 2*5 + 3*5^2 + 2*5^5 + 3*5^6 + O(5^7) : 4*5^-3 + 2*5^-1 + 4 + 2*5 + 3*5^4 + 2*5^5 + O(5^6) : 1 + O(5^10))
            sage: eq.parametrisation_onto_tate_curve(1+5+5^2+O(5^10), prec=20)
            Traceback (most recent call last):
            ...
            ValueError: Requested more precision than the precision of u

        """

        if prec is None:
            prec = getattr(u, "precision_relative", lambda: 20)()
        u = Qp(self._p, prec)(u)
        if prec > u.precision_relative():
            raise ValueError(
                "Requested more precision than the precision of u")
        if u == 1:
            return self.curve(prec=prec)(0)

        q = self.parameter(prec=prec)
        un = u * q**(-(u.valuation() / q.valuation()).floor())

        precn = (prec / q.valuation()).floor() + 4

        # formulas in Silverman II (Advanced Topics in the Arithmetic
        # of Elliptic curves, p. 425)

        xx = un / (1 - un)**2 + sum([
            q**n * un / (1 - q**n * un)**2 + q**n / un /
            (1 - q**n / un)**2 - 2 * q**n / (1 - q**n)**2
            for n in range(1, precn)
        ])

        yy = un**2 / (1 - un)**3 + sum([
            q**(2 * n) * un**2 / (1 - q**n * un)**3 - q**n / un /
            (1 - q**n / un)**3 + q**n / (1 - q**n)**2 for n in range(1, precn)
        ])

        return self.curve(prec=prec)([xx, yy])
Ejemplo n.º 8
0
    def padic_regulator(self, prec=20):
        r"""
        Compute the canonical `p`-adic regulator on the extended Mordell-Weil group as in [MTT]_
        (with the correction of [Wer]_ and sign convention in [SW]_.)

        The `p`-adic Birch and Swinnerton-Dyer conjecture predicts
        that this value appears in the formula for the leading term of
        the `p`-adic L-function.

        INPUT:

        - ``prec`` -- the `p`-adic precision, default is 20.

        REFERENCES:

        [MTT]_

        .. [Wer] Annette Werner, Local heights on abelian varieties and
           rigid analytic uniformization, Doc. Math. 3 (1998), 301-319.

        [SW]_

        EXAMPLES::

            sage: eq = EllipticCurve('130a1').tate_curve(5)
            sage: eq.padic_regulator()
            2*5^-1 + 1 + 2*5 + 2*5^2 + 3*5^3 + 3*5^6 + 5^7 + 3*5^9 + 3*5^10 + 3*5^12 + 4*5^13 + 3*5^15 + 2*5^16 + 3*5^18 + 4*5^19 + O(5^20)

        """
        prec = prec + 4

        K = Qp(self._p, prec=prec)
        rank = self._E.rank()
        if rank == 0:
            return K.one()

        if not self.is_split():
            raise NotImplementedError(
                "The p-adic regulator is not implemented for non-split multiplicative reduction."
            )

        basis = self._E.gens()
        M = matrix.matrix(K, rank, rank, 0)

        height = self.padic_height(prec=prec)
        point_height = [height(P) for P in basis]
        for i in range(rank):
            for j in range(i + 1, rank):
                M[i, j] = M[j, i] = (-point_height[i] - point_height[j] +
                                     height(basis[i] + basis[j])) / 2
        for i in range(rank):
            M[i, i] = point_height[i]

        return M.determinant()
Ejemplo n.º 9
0
def get_ulog(ualg, K, p, prec):
    QQp = Qp(p,prec)
    K = ualg.parent()
    try:
        phi = K.hom([K.gen().minpoly().roots(QQp)[0][0]])
        Kp = QQp
    except IndexError:
        Kp = QQp.extension(K.gen().minpoly(),names=str(K.gen())+'_p')
        ap = Kp.gen()
        phi = K.hom([ap])
    return phi(ualg).log(p_branch = 0)
Ejemplo n.º 10
0
    def padic_regulator(self, prec=20):
        r"""
        Compute the canonical `p`-adic regulator on the extended Mordell-Weil group as in [MTT]_
        (with the correction of [Wer]_ and sign convention in [SW]_.)

        The `p`-adic Birch and Swinnerton-Dyer conjecture predicts
        that this value appears in the formula for the leading term of
        the `p`-adic L-function.

        INPUT:

        - ``prec`` -- the `p`-adic precision, default is 20.

        REFERENCES:

        [MTT]_

        .. [Wer] Annette Werner, Local heights on abelian varieties and
           rigid analytic uniformization, Doc. Math. 3 (1998), 301-319.

        [SW]_

        EXAMPLES::

            sage: eq = EllipticCurve('130a1').tate_curve(5)
            sage: eq.padic_regulator()
            2*5^-1 + 1 + 2*5 + 2*5^2 + 3*5^3 + 3*5^6 + 5^7 + 3*5^9 + 3*5^10 + 3*5^12 + 4*5^13 + 3*5^15 + 2*5^16 + 3*5^18 + 4*5^19 + O(5^20)

        """
        prec = prec + 4

        K = Qp(self._p, prec=prec)
        rank = self._E.rank()
        if rank == 0:
            return K.one()

        if not self.is_split():
            raise NotImplementedError("The p-adic regulator is not implemented for non-split multiplicative reduction.")

        basis = self._E.gens()
        M = matrix.matrix(K, rank, rank, 0)

        height = self.padic_height(prec=prec)
        point_height = [height(P) for P in basis]
        for i in range(rank):
            for j in range(i + 1, rank):
                M[i, j] = M[j, i] = (- point_height[i] - point_height[j] + height(basis[i] + basis[j])) / 2
        for i in range(rank):
            M[i, i] = point_height[i]

        return M.determinant()
Ejemplo n.º 11
0
def logp_fcn(p, p_prec, a):
    r"""
    INPUT:
    
    - ``p``: prime
    - ``p_prec: desired ``p``-adic precision
    - ``z``
    
    OUTPUT:
    
    - The ``p``-adic logarithm of 
    this is the *function* on Z_p^* which sends z to log_p(z) using a power series truncated at p_prec terms"""
    R = Qp(p, 2 * p_prec)
    a = a / R.teichmuller(a)
    return sum([((-1) ** (m - 1)) * ((a - 1) ** m) / m for m in range(1, p_prec)])
Ejemplo n.º 12
0
 def completion(self, p, prec, extras={}):
     if p == infinity.Infinity:
         from sage.rings.real_mpfr import create_RealField
         return create_RealField(prec, **extras)
     else:
         from sage.rings.padics.factory import Qp
         return Qp(p, prec, **extras)
Ejemplo n.º 13
0
    def fraction_field(self, print_mode=None):
        r"""
        Returns the fraction field of ``self``.

        INPUT:

        - ``print_mode`` - a dictionary containing print options.
          Defaults to the same options as this ring.

        OUTPUT:

        - the fraction field of ``self``.

        EXAMPLES::

            sage: R = Zp(5, print_mode='digits')
            sage: K = R.fraction_field(); repr(K(1/3))[3:]
            '31313131313131313132'
            sage: L = R.fraction_field({'max_ram_terms':4}); repr(L(1/3))[3:]
            '3132'
        """
        if self.is_field() and print_mode is None:
            return self
        from sage.rings.padics.factory import Qp
        if self.is_floating_point():
            mode = 'floating-point'
        else:
            mode = 'capped-rel'
        return Qp(self.prime(),
                  self.precision_cap(),
                  mode,
                  print_mode=self._modified_print_mode(print_mode),
                  names=self._uniformizer_print())
Ejemplo n.º 14
0
    def E2(self, prec=20):
        r"""
        Return the value of the `p`-adic Eisenstein series of weight 2
        evaluated on the elliptic curve having split multiplicative
        reduction.

        INPUT:

        - ``prec`` - the `p`-adic precision, default is 20.

        EXAMPLES::

            sage: eq = EllipticCurve('130a1').tate_curve(5)
            sage: eq.E2(prec=10)
            4 + 2*5^2 + 2*5^3 + 5^4 + 2*5^5 + 5^7 + 5^8 + 2*5^9 + O(5^10)

            sage: T = EllipticCurve('14').tate_curve(7)
            sage: T.E2(30)
            2 + 4*7 + 7^2 + 3*7^3 + 6*7^4 + 5*7^5 + 2*7^6 + 7^7 + 5*7^8 + 6*7^9 + 5*7^10 + 2*7^11 + 6*7^12 + 4*7^13 + 3*7^15 + 5*7^16 + 4*7^17 + 4*7^18 + 2*7^20 + 7^21 + 5*7^22 + 4*7^23 + 4*7^24 + 3*7^25 + 6*7^26 + 3*7^27 + 6*7^28 + O(7^30)
        """
        p = self._p
        Csq = self._Csquare(prec=prec)
        qE = self._q
        n = qE.valuation()
        R = Qp(p, prec)
        e2 = Csq * (1 - 24 * sum(
            [qE**i / (1 - qE**i)**2
             for i in range(1, (prec / n).floor() + 5)]))
        return R(e2)
Ejemplo n.º 15
0
    def __init__(self, base, ideal=None):
        """
        The Python constructor.

        EXAMPLES::

            sage: Berkovich_Cp_Affine(3)
            Affine Berkovich line over Cp(3) of precision 20
        """
        if base in ZZ:
            if base.is_prime():
                base = Qp(base)  # change to Qpbar
            else:
                raise ValueError("non-prime passed into Berkovich space")
        if is_AffineSpace(base):
            base = base.base_ring()
        if base in NumberFields():
            if ideal is None:
                raise ValueError('passed a number field but not an ideal')
            if base is not QQ:
                if not isinstance(ideal, NumberFieldFractionalIdeal):
                    raise ValueError(
                        'ideal was not an ideal of a number field')
                if ideal.number_field() != base:
                    raise ValueError('passed number field ' + \
                        '%s but ideal was an ideal of %s' %(base, ideal.number_field()))
                prime = ideal.smallest_integer()
            else:
                if ideal not in QQ:
                    raise ValueError('ideal was not an element of QQ')
                prime = ideal
            if not ideal.is_prime():
                raise ValueError('passed non prime ideal')
            self._base_type = 'number field'
        elif isinstance(base,
                        sage.rings.abc.pAdicField):  # change base to Qpbar
            prime = base.prime()
            ideal = None
            self._base_type = 'padic field'
        else:
            raise ValueError("base of Berkovich Space must be a padic field " + \
                "or a number field")
        self._ideal = ideal
        self._p = prime
        Parent.__init__(self, base=base, category=TopologicalSpaces())
Ejemplo n.º 16
0
    def padic_regulator(self, prec=20):
        r"""
        Computes the canonical `p`-adic regulator on the extended Mordell-Weil group as in [MTT]
        (with the correction of [Wer] and sign convention in [SW].)
        The `p`-adic Birch and Swinnerton-Dyer conjecture
        predicts that this value appears in the formula for the leading term of the
        `p`-adic L-function.

        INPUT:

        - ``prec`` - the `p`-adic precision, default is 20.

        REFERENCES:

        - [MTT] B. Mazur, J. Tate, and J. Teitelbaum,
          On `p`-adic analogues of the conjectures of Birch and
          Swinnerton-Dyer, Inventiones mathematicae 84, (1986), 1-48.

        - [Wer] Annette Werner, Local heights on abelian varieties and rigid analytic unifomization,
          Doc. Math. 3 (1998), 301-319.

        - [SW] William Stein and Christian Wuthrich, Computations About Tate-Shafarevich Groups
          using Iwasawa theory, preprint 2009.

        EXAMPLES::

            sage: eq = EllipticCurve('130a1').tate_curve(5)
            sage: eq.padic_regulator()
            2*5^-1 + 1 + 2*5 + 2*5^2 + 3*5^3 + 3*5^6 + 5^7 + 3*5^9 + 3*5^10 + 3*5^12 + 4*5^13 + 3*5^15 + 2*5^16 + 3*5^18 + 4*5^19 + O(5^20)

        """
        prec = prec + 4

        K = Qp(self._p, prec=prec)
        rank = self._E.rank()
        if rank == 0:
            return K(1)

        if not self.is_split():
            raise NotImplementedError(
                "The p-adic regulator is not implemented for non-split multiplicative reduction."
            )

        basis = self._E.gens()
        M = matrix.matrix(K, rank, rank, 0)

        height = self.padic_height(prec=prec)
        point_height = [height(P) for P in basis]
        for i in range(rank):
            for j in range(i + 1, rank):
                M[i, j] = M[j, i] = (-point_height[i] - point_height[j] +
                                     height(basis[i] + basis[j])) / 2
        for i in range(rank):
            M[i, i] = point_height[i]

        return M.determinant()
Ejemplo n.º 17
0
    def __init__(self, base, ideal=None):
        """
        The Python constructor.

        EXAMPLES::

            sage: Berkovich_Cp_Projective(3)
            Projective Berkovich line over Cp(3) of precision 20
        """
        if base in ZZ:
            if base.is_prime():
                base = ProjectiveSpace(Qp(base), 1)
            else:
                raise ValueError("non-prime passed into Berkovich space")
        if base in NumberFields() or isinstance(base,
                                                sage.rings.abc.pAdicField):
            base = ProjectiveSpace(base, 1)
        if not is_ProjectiveSpace(base):
            try:
                base = ProjectiveSpace(base)
            except:
                raise ValueError(
                    "base of projective Berkovich space must be projective space"
                )
        if not isinstance(base.base_ring(), sage.rings.abc.pAdicField):
            if base.base_ring() not in NumberFields():
                raise ValueError("base of projective Berkovich space must be " + \
                    "projective space over Qp or a number field")
            else:
                if ideal is None:
                    raise ValueError('passed a number field but not an ideal')
                if base.base_ring() is not QQ:
                    if not isinstance(ideal, NumberFieldFractionalIdeal):
                        raise ValueError('ideal was not a number field ideal')
                    if ideal.number_field() != base.base_ring():
                        raise ValueError('passed number field ' + \
                            '%s but ideal was an ideal of %s' %(base.base_ring(), ideal.number_field()))
                    prime = ideal.smallest_integer()
                else:
                    if ideal not in QQ:
                        raise ValueError('ideal was not an element of QQ')
                    prime = ideal
                if not ideal.is_prime():
                    raise ValueError('passed non prime ideal')
                self._base_type = 'number field'
        else:
            prime = base.base_ring().prime()
            ideal = None
            self._base_type = 'padic field'
        if base.dimension_relative() != 1:
            raise ValueError("base of projective Berkovich space must be " + \
                "projective space of dimension 1 over Qp or a number field")
        self._p = prime
        self._ideal = ideal
        Parent.__init__(self, base=base, category=TopologicalSpaces())
Ejemplo n.º 18
0
def test_formula_display45(Lp, p, E, K, remove_numpoints=False):
    from sage.arith.misc import algdep
    prec = Lp.parent().precision_cap() + 100
    QQp = Qp(p, prec)
    hK = K.class_number()
    EFp = p + 1 - E.ap(p)
    phi = K.hom([K.gen().minpoly().roots(QQp)[0][0]])
    u = phi((K.ideal(p).factor()[0][0]**hK).gens_reduced()[0])
    if u.valuation() == 0:
        u = phi((K.ideal(p).factor()[1][0]**hK).gens_reduced()[0])
    assert u.valuation() > 0
    ulog = u.log(0)

    PH = E.heegner_point(K.discriminant())
    PH = PH.point_exact(200)  # Hard-coded, DEBUG
    H = PH[0].parent()
    H1, H_to_H1, K_to_H1, _ = H.composite_fields(K, both_maps=True)[0]
    kgen = K_to_H1(K.gen())
    sigmas = [o for o in H1.automorphisms() if o(kgen) == kgen]
    EH1 = E.change_ring(H1)
    EK = E.change_ring(K)
    PK = EH1(0)
    for sigma in sigmas:
        PK += EH1(sigma(H_to_H1(PH[0])), sigma(H_to_H1(PH[1])))

    PK = EK(K(PK[0]), K(PK[1]))
    nn = 1
    while True:
        nPK = nn * PK
        PKpn = E.change_ring(QQp)((phi(nPK[0]), phi(nPK[1])))
        try:
            tvar = -phi(nPK[0] / nPK[1])
            logPK = E.change_ring(QQp).formal_group().log(prec)(tvar) / nn
            break
        except (ZeroDivisionError, ValueError):
            nn += 1
            print 'nn=', nn
    assert PK.order() == Infinity

    print "------------------------------------"
    print "p = %s, cond(E) = %s, disc(K) = %s" % (p, E.conductor(),
                                                  K.discriminant())
    print "------------------------------------"
    print "h_K = %s" % hK
    print "# E(F_p) = %s" % EFp
    if remove_numpoints:
        EFp = 1
        print "  (not taking them into account)"
    print "PK = %s" % PK

    ratio = Lp / ((EFp**2 * logPK**2) / (p * (p - 1) * hK * ulog))

    print "ratio = %s" % algdep(ratio, 1).roots(QQ)[0][0]
    return ratio
Ejemplo n.º 19
0
def log_of_heegner_point(E,K,p,prec):
    QQp = Qp(p,prec)
    try:
        phi = K.hom([K.gen().minpoly().roots(QQp)[0][0]])
        Kp = QQp
    except IndexError:
        Kp = QQp.extension(K.gen().minpoly(),names=str(K.gen())+'_p')
        ap = Kp.gen()
        phi = K.hom([ap])
    PH = E.heegner_point(K.discriminant())
    PH = PH.point_exact(2000) # Hard-coded, DEBUG
    H = PH[0].parent()
    try:
        H1, H_to_H1, K_to_H1, _  = H.composite_fields(K,both_maps = True)[0]
        Hrel = H1.relativize(K_to_H1,'b')
        def tr(x):
            return x.trace(K) / Hrel.relative_degree()
    except AttributeError:
        H1, H_to_H1, K_to_H1 = K, lambda x:x, lambda x:x
        Hrel = K
        def tr(x):
            return x
    Kgen = K.gen(0)
    sigmas = [sigma for sigma in Hrel.automorphisms() if sigma(Kgen) == Kgen]
    EH1 = E.change_ring(H1)
    EHrel = E.change_ring(Hrel)
    EK = E.change_ring(K)
    PK = EHrel(0)
    for sigma in sigmas:
        PK += EHrel([Hrel(sigma(H_to_H1(PH[0]))),Hrel(sigma(H_to_H1(PH[1])))])

    EFp = (p**Kp.degree()+1-E.ap(p))
    PK = EK([tr(PK[0]),tr(PK[1])])
    n = 1
    nPK = PK
    while not (phi(nPK[0]).valuation() < 0 and phi(nPK[1]).valuation() < 0):
        n += 1
        nPK += PK
    tvar = -phi(nPK[0]/nPK[1])
    logPK = E.change_ring(Kp).formal_group().log(prec)(tvar) / n
    return logPK
Ejemplo n.º 20
0
    def teichmuller(self, prec):
        r"""
        Return Teichmuller lifts to the given precision.
        
        INPUT:
            - ``prec`` - a positive integer.
            
        OUTPUT:
            - a list of `p`-adic numbers, the cached Teichmuller lifts 

        EXAMPLES::
        
            sage: L = EllipticCurve('11a').padic_lseries(7)
            sage: L.teichmuller(1)
            [0, 1, 2, 3, 4, 5, 6]
            sage: L.teichmuller(2)
            [0, 1, 30, 31, 18, 19, 48]
        """
        p = self._p
        K = Qp(p, prec, print_mode='series')        
        return [Integer(0)] + \
               [a.residue(prec).lift() for a in K.teichmuller_system()]
Ejemplo n.º 21
0
    def teichmuller(self, prec):
        r"""
        Return Teichmuller lifts to the given precision.

        INPUT:
            - ``prec`` - a positive integer.

        OUTPUT:
            - a list of `p`-adic numbers, the cached Teichmuller lifts

        EXAMPLES::

            sage: L = EllipticCurve('11a').padic_lseries(7)
            sage: L.teichmuller(1)
            [0, 1, 2, 3, 4, 5, 6]
            sage: L.teichmuller(2)
            [0, 1, 30, 31, 18, 19, 48]
        """
        p = self._p
        K = Qp(p, prec, print_mode='series')
        return [Integer(0)] + \
               [a.residue(prec).lift() for a in K.teichmuller_system()]
Ejemplo n.º 22
0
    def psi(self):
        r"""
        The embedding $\Q(\alpha) \into \Q_p(a)$ sending $\alpha \mapsto a$.
        """
        K_f = self._hecke_eigenvalue_field
        p = self._p
        #        kbar = K_f.residue_field(p)
        Q = Qp(p)

        ###split case
        pOK = K_f.factor(p)
        if (len(pOK) == 2 and pOK[0][1] == 1):
            R = Q['x']
            r1, r2 = R(K_f.defining_polynomial()).roots()
            psi1 = K_f.hom([r1[0]])
            psi2 = K_f.hom([r2[0]])
            return [psi1, psi2]
        else:
            F = Q.extension(K_f.defining_polynomial(), names='a')
            a = F.gen()
            psi = self._psis = [K_f.hom([a])]
            return psi
Ejemplo n.º 23
0
    def psi(self):
    	"""
        The embedding $\Q(\alpha) \into \Q_p(a)$ sending $\alpha \mapsto a$.
	"""
        K_f = self._hecke_eigenvalue_field
        p = self._p
#        kbar = K_f.residue_field(p)
        Q = Qp(p)

        ###split case
        pOK = K_f.factor(p)
        if (len(pOK) == 2 and pOK[0][1] == 1):
            R = Q['x']
            r1, r2 = R(K_f.defining_polynomial()).roots()
            psi1 = K_f.hom([r1[0]])
            psi2 = K_f.hom([r2[0]])
            return [psi1, psi2]
        else:
            F = Q.extension(K_f.defining_polynomial(),names='a')
            a = F.gen()
            psi = self._psis = [K_f.hom([a])]
            return psi
Ejemplo n.º 24
0
def automorphy_factor_vector(p, a, c, k, chi, p_prec, var_prec, R):
    """
    EXAMPLES::
        
        sage: from sage.modular.pollack_stevens.families_util import automorphy_factor_vector
        sage: automorphy_factor_vector(3, 1, 3, 0, None, 4, 3, PowerSeriesRing(ZpCA(3), 'w'))
        [1 + O(3^20), O(3^21) + (3 + 3^2 + 2*3^3 + O(3^21))*w + (3^2 + 2*3^3 + O(3^22))*w^2, O(3^22) + (3^2 + 2*3^3 + O(3^22))*w + (2*3^2 + O(3^22))*w^2, O(3^22) + (3^2 + 3^3 + O(3^22))*w + (2*3^3 + O(3^23))*w^2]
        sage: automorphy_factor_vector(3, 1, 3, 2, None, 4, 3, PowerSeriesRing(ZpCA(3), 'w'))
        [1 + O(3^20),
         O(3^21) + (3 + 3^2 + 2*3^3 + O(3^21))*w + (3^2 + 2*3^3 + O(3^22))*w^2,
         O(3^22) + (3^2 + 2*3^3 + O(3^22))*w + (2*3^2 + O(3^22))*w^2,
         O(3^22) + (3^2 + 3^3 + O(3^22))*w + (2*3^3 + O(3^23))*w^2]
        sage: p, a, c, k, chi, p_prec, var_prec, R = 11, -3, 11, 0, None, 6, 4, PowerSeriesRing(ZpCA(11, 6), 'w')
        sage: automorphy_factor_vector(p, a, c, k, chi, p_prec, var_prec, R)
        [1 + O(11^6) + (7*11^2 + 4*11^3 + 11^4 + 9*11^5 + 3*11^6 + 10*11^7 + O(11^8))*w + (2*11^3 + 2*11^5 + 2*11^6 + 6*11^7 + 8*11^8 + O(11^9))*w^2 + (6*11^4 + 4*11^5 + 5*11^6 + 6*11^7 + 4*11^9 + O(11^10))*w^3,
         O(11^7) + (7*11 + 11^2 + 2*11^3 + 3*11^4 + 4*11^5 + 3*11^6 + O(11^7))*w + (2*11^2 + 4*11^3 + 5*11^4 + 10*11^5 + 10*11^6 + 2*11^7 + O(11^8))*w^2 + (6*11^3 + 6*11^4 + 2*11^5 + 9*11^6 + 9*11^7 + 2*11^8 + O(11^9))*w^3,
         O(11^8) + (3*11^2 + 4*11^4 + 2*11^5 + 6*11^6 + 10*11^7 + O(11^8))*w + (8*11^2 + 7*11^3 + 8*11^4 + 8*11^5 + 11^6 + O(11^8))*w^2 + (3*11^3 + 9*11^4 + 10*11^5 + 5*11^6 + 10*11^7 + 11^8 + O(11^9))*w^3,
         O(11^9) + (8*11^3 + 3*11^4 + 3*11^5 + 7*11^6 + 2*11^7 + 6*11^8 + O(11^9))*w + (10*11^3 + 6*11^5 + 7*11^6 + O(11^9))*w^2 + (4*11^3 + 11^4 + 8*11^8 + O(11^9))*w^3,
         O(11^10) + (2*11^4 + 9*11^5 + 8*11^6 + 5*11^7 + 4*11^8 + 6*11^9 + O(11^10))*w + (6*11^5 + 3*11^6 + 5*11^7 + 7*11^8 + 4*11^9 + O(11^10))*w^2 + (2*11^4 + 8*11^6 + 2*11^7 + 9*11^8 + 7*11^9 + O(11^10))*w^3,
         O(11^11) + (2*11^5 + 10*11^6 + 10*11^7 + 10*11^8 + 10*11^9 + 10*11^10 + O(11^11))*w + (5*11^5 + 10*11^6 + 10*11^7 + 10*11^8 + 10*11^9 + 10*11^10 + O(11^11))*w^2 + (2*11^5 + 10*11^6 + 10*11^7 + 10*11^8 + 10*11^9 + 10*11^10 + O(11^11))*w^3]
        sage: k = 2
        sage: automorphy_factor_vector(p, a, c, k, chi, p_prec, var_prec, R)
        [9 + 6*11^2 + 11^3 + 9*11^4 + 8*11^5 + O(11^6) + (8*11^2 + 8*11^3 + 10*11^4 + 6*11^5 + 5*11^7 + O(11^8))*w + (7*11^3 + 11^4 + 8*11^5 + 9*11^7 + 10*11^8 + O(11^9))*w^2 + (10*11^4 + 7*11^5 + 7*11^6 + 3*11^7 + 8*11^8 + 4*11^9 + O(11^10))*w^3,
         O(11^7) + (8*11 + 3*11^2 + 6*11^3 + 11^4 + 6*11^5 + 11^6 + O(11^7))*w + (7*11^2 + 4*11^3 + 5*11^4 + 10*11^6 + 5*11^7 + O(11^8))*w^2 + (10*11^3 + 3*11^4 + 4*11^5 + 7*11^6 + 10*11^7 + 3*11^8 + O(11^9))*w^3,
         O(11^8) + (5*11^2 + 2*11^3 + 10*11^4 + 3*11^5 + 8*11^6 + 7*11^7 + O(11^8))*w + (6*11^2 + 3*11^3 + 5*11^4 + 11^5 + 5*11^6 + 9*11^7 + O(11^8))*w^2 + (5*11^3 + 6*11^4 + 5*11^5 + 2*11^6 + 9*11^7 + 6*11^8 + O(11^9))*w^3,
         O(11^9) + (6*11^3 + 11^5 + 8*11^6 + 9*11^7 + 2*11^8 + O(11^9))*w + (2*11^3 + 8*11^4 + 4*11^5 + 6*11^6 + 11^7 + 8*11^8 + O(11^9))*w^2 + (3*11^3 + 11^4 + 3*11^5 + 11^6 + 5*11^7 + 6*11^8 + O(11^9))*w^3,
         O(11^10) + (7*11^4 + 5*11^5 + 3*11^6 + 10*11^7 + 10*11^8 + 11^9 + O(11^10))*w + (10*11^5 + 9*11^6 + 6*11^7 + 6*11^8 + 10*11^9 + O(11^10))*w^2 + (7*11^4 + 11^5 + 7*11^6 + 5*11^7 + 6*11^8 + 2*11^9 + O(11^10))*w^3,
         O(11^11) + (7*11^5 + 3*11^6 + 8*11^8 + 5*11^9 + 8*11^10 + O(11^11))*w + (11^5 + 6*11^6 + 7*11^7 + 11^8 + 2*11^10 + O(11^11))*w^2 + (7*11^5 + 3*11^6 + 8*11^8 + 5*11^9 + 8*11^10 + O(11^11))*w^3]
    """
    S = PolynomialRing(R, 'z')
    z = S.gens()[0]
    w = R.gen()
    aut = S(1)
    for n in range(1, var_prec):
        ## RP: I doubled the precision in "z" here to account for the loss of precision from plugging in arg in below
        ## This should be done better.
        LB = logpp_binom(n, p, ceil(p_prec * (p - 1) / (p - 2)))
        ta = ZZ(Qp(p, 2 * max(p_prec, var_prec)).teichmuller(a))
        arg = (a / ta - 1) / p + c / (p * ta) * z
        aut += LB(arg).truncate(p_prec) * (w**n)
    aut *= (ta**k)
    #if not (chi is None):
    #    aut *= chi(a)
    aut = aut.list()
    len_aut = len(aut)
    if len_aut == p_prec:
        return aut
    elif len_aut > p_prec:
        return aut[:p_prec]
    return aut + [R.zero_element()] * (p_prec - len_aut)
Ejemplo n.º 25
0
 def change_precision(self, new_prec):
     """
         Returns a FamiliesOfOMS coefficient module with same input data as self, but with precision cap ``new_prec``
     """
     #print new_prec
     if new_prec == self._prec_cap:
         return self
     base_coeffs = self.base_ring().base_ring()
     if new_prec[0] > base_coeffs.precision_cap():
         #THERE'S NO WAY TO EXTEND PRECISION ON BASE RING!!! This is a crappy hack:
         if base_coeffs.is_field():
             base_coeffs = Qp(self.prime(), new_prec[0])
         else:
             base_coeffs = ZpCA(self.prime(), new_prec[0])
     return FamiliesOfOverconvergentDistributions(self._k, prec_cap = new_prec, base_coeffs=base_coeffs, character=self._character, adjuster=self._adjuster, act_on_left=self.action().is_left(), dettwist=self._dettwist, variable_name = self.base_ring().variable_name())
Ejemplo n.º 26
0
    def completion(self, p, prec, extras={}):
        r"""
        Return the completion of `\QQ` at `p`.

        EXAMPLES::

            sage: QQ.completion(infinity, 53)
            Real Field with 53 bits of precision
            sage: QQ.completion(5, 15, {'print_mode': 'bars'})
            5-adic Field with capped relative precision 15
        """
        if p == infinity.Infinity:
            from sage.rings.real_mpfr import create_RealField
            return create_RealField(prec, **extras)
        else:
            from sage.rings.padics.factory import Qp
            return Qp(p, prec, **extras)
Ejemplo n.º 27
0
    def parametrisation_onto_original_curve(self, u, prec=None):
        r"""
        Given an element `u` in `\QQ_p^{\times}`, this computes its image on the original curve
        under the `p`-adic uniformisation of `E`.

        INPUT:

        - ``u`` -- a non-zero `p`-adic number.

        - ``prec`` -- the `p`-adic precision, default is the relative precision of ``u``
          otherwise 20.

        EXAMPLES::

            sage: eq = EllipticCurve('130a1').tate_curve(5)
            sage: eq.parametrisation_onto_original_curve(1+5+5^2+O(5^10))
            (4*5^-2 + 4*5^-1 + 4 + 2*5^3 + 3*5^4 + 2*5^6 + O(5^7) :
            3*5^-3 + 5^-2 + 4*5^-1 + 1 + 4*5 + 5^2 + 3*5^5 + O(5^6) :
            1 + O(5^10))
            sage: eq.parametrisation_onto_original_curve(1+5+5^2+O(5^10), prec=20)
            Traceback (most recent call last):
            ...
            ValueError: Requested more precision than the precision of u

        Here is how one gets a 4-torsion point on `E` over `\QQ_5`::

            sage: R = Qp(5,30)
            sage: i = R(-1).sqrt()
            sage: T = eq.parametrisation_onto_original_curve(i, prec=30); T
            (2 + 3*5 + 4*5^2 + 2*5^3 + 5^4 + 4*5^5 + 2*5^7 + 5^8 + 5^9 + 5^12 + 3*5^13 + 3*5^14 + 5^15 + 4*5^17 + 5^18 + 3*5^19 + 2*5^20 + 4*5^21 + 5^22 + 3*5^23 + 3*5^24 + 4*5^25 + 3*5^26 + 3*5^27 + 3*5^28 + 3*5^29 + O(5^30) : 3*5 + 5^2 + 5^4 + 3*5^5 + 3*5^7 + 2*5^8 + 4*5^9 + 5^10 + 2*5^11 + 4*5^13 + 2*5^14 + 4*5^15 + 4*5^16 + 3*5^17 + 2*5^18 + 4*5^20 + 2*5^21 + 2*5^22 + 4*5^23 + 4*5^24 + 4*5^25 + 5^26 + 3*5^27 + 2*5^28 + O(5^30) : 1 + O(5^30))
            sage: 4*T
            (0 : 1 + O(5^30) : 0)
        """
        if not self.is_split():
            raise ValueError("The curve must have split multiplicative "
                             "reduction.")
        if prec is None:
            prec = getattr(u, "precision_relative", lambda: 20)()

        P = self.parametrisation_onto_tate_curve(u, prec=prec)
        C, r, s, t = self._inverse_isomorphism(prec=prec)
        xx = r + C**2 * P[0]
        yy = t + s * C**2 * P[0] + C**3 * P[1]
        R = Qp(self._p, prec)
        E_over_Qp = self._E.base_extend(R)
        return E_over_Qp([xx, yy])
Ejemplo n.º 28
0
 def _height(P, check=True):
     if check:
         assert P.curve(
         ) == self._E, "the point P must lie on the curve from which the height function was created"
     Q = n * P
     cQ = denominator(Q[0])
     q = self.parameter(prec=prec)
     nn = q.valuation()
     precp = prec + nn + 2
     uQ = self.lift(Q, prec=precp)
     si = self.__padic_sigma_square(uQ, prec=precp)
     q = self.parameter(prec=precp)
     nn = q.valuation()
     qEu = q / p**nn
     res = -(log(si * self._Csquare(prec=precp) / cQ) +
             log(uQ)**2 / log(qEu)) / n**2
     R = Qp(self._p, prec)
     return R(res)
Ejemplo n.º 29
0
    def parametrisation_onto_original_curve(self, u, prec=20):
        r"""
        Given an element `u` in `\QQ_p^{\times}`, this computes its image on the original curve
        under the `p`-adic uniformisation of `E`.

        INPUT:

        - ``u`` - a non-zero `p`-adic number.

        - ``prec`` - the `p`-adic precision, default is 20.

        EXAMPLES::

            sage: eq = EllipticCurve('130a1').tate_curve(5)
            sage: eq.parametrisation_onto_original_curve(1+5+5^2+O(5^10))
            (4*5^-2 + 4*5^-1 + 4 + 2*5^3 + 3*5^4 + 2*5^6 + O(5^7) :
            3*5^-3 + 5^-2 + 4*5^-1 + 1 + 4*5 + 5^2 + 3*5^5 + O(5^6) : 1 + O(5^20))

        Here is how one gets a 4-torsion point on `E` over `\QQ_5`::

            sage: R = Qp(5,10)
            sage: i = R(-1).sqrt()
            sage: T = eq.parametrisation_onto_original_curve(i); T
            (2 + 3*5 + 4*5^2 + 2*5^3 + 5^4 + 4*5^5 + 2*5^7 + 5^8 + 5^9 + O(5^10) :
            3*5 + 5^2 + 5^4 + 3*5^5 + 3*5^7 + 2*5^8 + 4*5^9 + O(5^10) : 1 + O(5^20))
            sage: 4*T
            (0 : 1 + O(5^20) : 0)
        """
        if not self.is_split():
            raise ValueError(
                "The curve must have split multiplicative reduction.")
        P = self.parametrisation_onto_tate_curve(u, prec=20)
        isom = self._inverse_isomorphism(prec=prec)
        C = isom[0]
        r = isom[1]
        s = isom[2]
        t = isom[3]
        xx = r + C**2 * P[0]
        yy = t + s * C**2 * P[0] + C**3 * P[1]
        R = Qp(self._p, prec)
        E_over_Qp = self._E.base_extend(R)
        return E_over_Qp([xx, yy])
Ejemplo n.º 30
0
def find_Apow_and_ord(A, E, p, prec):
    f_degree = A.change_ring(
        GF(p)).charpoly().splitting_field(names='a').degree()
    r = (p**f_degree - 1) * p**prec
    Apow = take_power(A, r - 1)
    Ar = multiply_and_reduce(Apow, A)
    Ar = ech_form(Ar, p)
    Ar.change_ring(Qp(p, prec))
    ord_basis = []
    for o in Ar.rows():
        if o.is_zero():
            break
        ord_basis.append(o)
    try:
        E = E.apply_map(lambda x: x.lift())
    except AttributeError:
        pass
    ord_basis_qexp = Matrix(ord_basis).apply_map(
        lambda x: x.lift()).change_ring(QQ) * E
    return Apow, ord_basis_qexp
Ejemplo n.º 31
0
 def change_precision(self, new_prec):
     """
         Returns an OMS coefficient module with same input data as self, but with precision cap ``new_prec``
     """
     if new_prec == self._prec_cap:
         return self
     base = self.base_ring()
     if new_prec > base.precision_cap():
         #THERE'S NO WAY TO EXTEND PRECISION ON BASE RING!!! This is a crappy hack:
         if self.base_ring().is_field():
             base = Qp(self.prime(), new_prec)
         else:
             base = ZpCA(self.prime(), new_prec)
     return OverconvergentDistributions(self._k,
                                        prec_cap=new_prec,
                                        base=base,
                                        character=self._character,
                                        adjuster=self._adjuster,
                                        act_on_left=self.action().is_left(),
                                        dettwist=self._dettwist)
Ejemplo n.º 32
0
def define_qexpansions_from_dirichlet_character(p, prec, eps, num_coefficients, magma):
    QQp = Qp(p,prec)
    N = eps.modulus()
    g1qexp = sage_character_to_magma(eps,N=N,magma=magma).ModularForms(1).EisensteinSeries()[1].qExpansion(num_coefficients + 20).Eltseq().sage()  # DEBUG

    den = lcm([QQ(o).denominator() for o in g1qexp])
    g1qexp = [ZZ(den * o) for o in g1qexp]
    print len(g1qexp)

    g0 = ModFormqExp(g1qexp, QQp, weight=1, character = eps, level = N)

    weight = 1
    alpha = 1

    qexp_plus = [QQp(o) for o in g1qexp]
    qexp_minus = [QQp(o) for o in g1qexp]
    for i in range(len(g1qexp) // p):
        qexp_plus[p * i] += g1qexp[i]
        qexp_minus[p * i] -= g1qexp[i]

    gammaplus = ModFormqExp(qexp_plus, QQp, weight=1, level = N)
    gammaminus = ModFormqExp(qexp_minus, QQp, weight=1, level = N)
    return gammaplus, gammaminus, g0
Ejemplo n.º 33
0
    def curve(self, prec=20):
        r"""
        Return the `p`-adic elliptic curve of the form
        `y^2+x y = x^3 + s_4 x+s_6`.

        This curve with split multiplicative reduction is isomorphic
        to the given curve over the algebraic closure of `\QQ_p`.

        INPUT:

        - ``prec`` -- the `p`-adic precision, default is 20.

        EXAMPLES::

            sage: eq = EllipticCurve('130a1').tate_curve(5)
            sage: eq.curve(prec=5)
            Elliptic Curve defined by y^2 + (1+O(5^5))*x*y  = x^3 +
            (2*5^4+5^5+2*5^6+5^7+3*5^8+O(5^9))*x +
            (2*5^3+5^4+2*5^5+5^7+O(5^8)) over 5-adic
            Field with capped relative precision 5
        """

        Eq = getattr(self, "__curve", None)
        if Eq and Eq.a6().precision_relative() >= prec:
            return Eq.change_ring(Qp(self._p, prec))

        qE = self.parameter(prec=prec)
        precp = prec + 2
        tate_a4 = -5 * self.__sk(3, precp)
        tate_a6 = (tate_a4 - 7 * self.__sk(5, precp)) / 12
        R = qE.parent()
        Eq = EllipticCurve(
            [R.one(), R.zero(),
             R.zero(), R(tate_a4),
             R(tate_a6)])
        self.__curve = Eq
        return Eq
Ejemplo n.º 34
0
def test_formula_display45(Lp, p, E, K, outfile=None):
    from sage.arith.misc import algdep
    prec = Lp.parent().precision_cap() + 100
    QQp = Qp(p,prec)
    hK = K.class_number()
    EFp = p+1 - E.ap(p)
    phi = K.hom([K.gen().minpoly().roots(QQp)[0][0]])
    ualg = (K.ideal(p).factor()[0][0]**hK).gens_reduced()[0]

    ulog = get_ulog(ualg, K, p, prec)
    logPK = log_of_heegner_point(E,K,p,prec)

    fwrite("------------------------------------", outfile)
    fwrite("p = %s, cond(E) = %s, disc(K) = %s"%(p,E.conductor(),K.discriminant()), outfile)
    fwrite("------------------------------------", outfile)
    fwrite("h_K = %s"%hK, outfile)
    fwrite("# E(F_p) = %s"%EFp, outfile)
    fwrite("u satisfies: %s"%ualg.minpoly(), outfile)
    fwrite("ulog = %s"%ulog, outfile)
    fwrite("logPK = %s"%logPK, outfile)
    ratio = Lp / ( (EFp**2 * logPK**2 ) / (p * (p-1) * hK * ulog) )
    fwrite("ratio = %s"%ratio, outfile)
    fwrite("ratio ~ %s"%algdep(ratio, 1).roots(QQ)[0][0], outfile)
    return ratio
Ejemplo n.º 35
0
def logp_fcn(p, p_prec, z):
    """this is the *function* on Z_p^* which sends z to log_p(z) using a power series truncated at p_prec terms"""
    R = Qp(p, 2 * p_prec)
    z = z / R.teichmuller(z)
    return sum([((-1) ** (m - 1)) * ((z - 1) ** m) / m for m in range(1, p_prec)])
Ejemplo n.º 36
0
def python(z, locals=None):
    """
    Return the closest Python/Sage equivalent of the given pari object.

    INPUT:

        - `z` -- pari object

        - `locals` -- optional dictionary used in fallback cases that
          involve sage_eval

    The component parts of a t_COMPLEX may be t_INT, t_REAL, t_INTMOD,
    t_FRAC, t_PADIC.  The components need not have the same type
    (e.g. if z=2+1.2*I then z.real() is t_INT while z.imag() is
    t_REAL().  They are converted as follows:

    t_INT:    ZZ[i]
    t_FRAC:   QQ(i)
    t_REAL:   ComplexField(prec) for equivalent precision
    t_INTMOD, t_PADIC: raise NotImplementedError

    EXAMPLES::

        sage: a = pari('(3+I)').python(); a
        i + 3
        sage: a.parent()
        Maximal Order in Number Field in i with defining polynomial x^2 + 1

        sage: a = pari('2^31-1').python(); a
        2147483647
        sage: a.parent()
        Integer Ring

        sage: a = pari('12/34').python(); a
        6/17
        sage: a.parent()
        Rational Field

        sage: a = pari('1.234').python(); a
        1.23400000000000000
        sage: a.parent()
        Real Field with 64 bits of precision

        sage: a = pari('(3+I)/2').python(); a
        1/2*i + 3/2
        sage: a.parent()
        Number Field in i with defining polynomial x^2 + 1

    Conversion of complex numbers: the next example is converting from
    an element of the Symbolic Ring, which goes via the string
    representation::

        sage: I = SR(I)
        sage: a = pari(1.0+2.0*I).python(); a
        1.00000000000000000 + 2.00000000000000000*I
        sage: type(a)
        <type 'sage.rings.complex_number.ComplexNumber'>
        sage: a.parent()
        Complex Field with 64 bits of precision

    For architecture-independent complex numbers, start from a
    suitable ComplexField::

        sage: z = pari(CC(1.0+2.0*I)); z
        1.00000000000000 + 2.00000000000000*I
        sage: a=z.python(); a
        1.00000000000000000 + 2.00000000000000000*I
        sage: a.parent()
        Complex Field with 64 bits of precision

    Vectors and matrices::

        sage: a = pari('[1,2,3,4]')
        sage: a
        [1, 2, 3, 4]
        sage: a.type()
        't_VEC'
        sage: b = a.python(); b
        [1, 2, 3, 4]
        sage: type(b)
        <type 'list'>

        sage: a = pari('[1,2;3,4]')
        sage: a.type()
        't_MAT'
        sage: b = a.python(); b
        [1 2]
        [3 4]
        sage: b.parent()
        Full MatrixSpace of 2 by 2 dense matrices over Integer Ring

        sage: a = pari('Vecsmall([1,2,3,4])')
        sage: a.type()
        't_VECSMALL'
        sage: a.python()
        [1, 2, 3, 4]

    We use the locals dictionary::

        sage: f = pari('(2/3)*x^3 + x - 5/7 + y')
        sage: x,y=var('x,y')
        sage: import sage.libs.pari.gen_py
        sage: sage.libs.pari.gen_py.python(f, {'x':x, 'y':y})
        2/3*x^3 + x + y - 5/7
        sage: sage.libs.pari.gen_py.python(f)
        Traceback (most recent call last):
        ...
        NameError: name 'x' is not defined

    Conversion of p-adics::

        sage: K = Qp(11,5)
        sage: x = K(11^-10 + 5*11^-7 + 11^-6); x
        11^-10 + 5*11^-7 + 11^-6 + O(11^-5)
        sage: y = pari(x); y
        11^-10 + 5*11^-7 + 11^-6 + O(11^-5)
        sage: y.sage()
        11^-10 + 5*11^-7 + 11^-6 + O(11^-5)
        sage: pari(K(11^-5)).sage()
        11^-5 + O(11^0)
    """
    from sage.libs.pari.pari_instance import prec_words_to_bits

    t = z.type()
    if t == "t_REAL":
        return RealField(prec_words_to_bits(z.precision()))(z)
    elif t == "t_FRAC":
        Q = RationalField()
        return Q(z)
    elif t == "t_INT":
        Z = IntegerRing()
        return Z(z)
    elif t == "t_COMPLEX":
        tx = z.real().type()
        ty = z.imag().type()
        if tx in ["t_INTMOD", "t_PADIC"] or ty in ["t_INTMOD", "t_PADIC"]:
            raise NotImplementedError(
                "No conversion to python available for t_COMPLEX with t_INTMOD or t_PADIC components"
            )
        if tx == "t_REAL" or ty == "t_REAL":
            xprec = z.real().precision()  # will be 0 if exact
            yprec = z.imag().precision()  # will be 0 if exact
            if xprec == 0:
                prec = prec_words_to_bits(yprec)
            elif yprec == 0:
                prec = prec_words_to_bits(xprec)
            else:
                prec = max(prec_words_to_bits(xprec),
                           prec_words_to_bits(yprec))
            R = RealField(prec)
            C = ComplexField(prec)
            return C(R(z.real()), R(z.imag()))
        if tx == "t_FRAC" or ty == "t_FRAC":
            return QuadraticField(-1, 'i')([python(c) for c in list(z)])
        if tx == "t_INT" or ty == "t_INT":
            return QuadraticField(
                -1, 'i').ring_of_integers()([python(c) for c in list(z)])
        raise NotImplementedError(
            "No conversion to python available for t_COMPLEX with components %s"
            % (tx, ty))
    elif t == "t_VEC":
        return [python(x) for x in z.python_list()]
    elif t == "t_VECSMALL":
        return z.python_list_small()
    elif t == "t_MAT":
        from sage.matrix.constructor import matrix
        return matrix(z.nrows(), z.ncols(), [
            python(z[i, j]) for i in range(z.nrows()) for j in range(z.ncols())
        ])
    elif t == "t_PADIC":
        from sage.rings.padics.factory import Qp
        Z = IntegerRing()
        p = z.padicprime()
        rprec = Z(z.padicprec(p)) - Z(z._valp())
        K = Qp(Z(p), rprec)
        return K(z.lift())
    else:
        from sage.misc.sage_eval import sage_eval
        return sage_eval(str(z), locals=locals)
Ejemplo n.º 37
0
    def an_padic(self, p, prec=0, use_twists=True):
        r"""
        Returns the conjectural order of `Sha(E/\QQ)`,
        according to the `p`-adic analogue of the Birch
        and Swinnerton-Dyer conjecture as formulated
        in [MTT]_ and [BP]_.

        REFERENCES:

        .. [MTT] \B. Mazur, J. Tate, and J. Teitelbaum, On `p`-adic
           analogues of the conjectures of Birch and Swinnerton-Dyer,
           Inventiones mathematicae 84, (1986), 1-48.

        .. [BP] Dominique Bernardi and Bernadette Perrin-Riou,
           Variante `p`-adique de la conjecture de Birch et
           Swinnerton-Dyer (le cas supersingulier),
           C. R. Acad. Sci. Paris, Sér I. Math., 317 (1993), no. 3,
           227-232.

        INPUT:

        - ``p`` - a prime > 3

        - ``prec`` (optional) - the precision used in the computation of the
          `p`-adic L-Series

        - ``use_twists`` (default = ``True``) - If ``True`` the algorithm may
          change to a quadratic twist with minimal conductor to do the modular
          symbol computations rather than using the modular symbols of the
          curve itself. If ``False`` it forces the computation using the
          modular symbols of the curve itself.

        OUTPUT:  `p`-adic number - that conjecturally equals `\# Sha(E/\QQ)`.

        If ``prec`` is set to zero (default) then the precision is set so that
        at least the first `p`-adic digit of conjectural `\# Sha(E/\QQ)` is
        determined.

        EXAMPLES:

        Good ordinary examples::

            sage: EllipticCurve('11a1').sha().an_padic(5)    # rank 0
            1 + O(5^22)
            sage: EllipticCurve('43a1').sha().an_padic(5)    # rank 1
            1 + O(5)
            sage: EllipticCurve('389a1').sha().an_padic(5,4) # rank 2, long time (2s on sage.math, 2011)
            1 + O(5^3)
            sage: EllipticCurve('858k2').sha().an_padic(7)   # rank 0, non trivial sha, long time (10s on sage.math, 2011)
            7^2 + O(7^24)
            sage: EllipticCurve('300b2').sha().an_padic(3)   # 9 elements in sha, long time (2s on sage.math, 2011)
            3^2 + O(3^24)
            sage: EllipticCurve('300b2').sha().an_padic(7, prec=6)  # long time
            2 + 7 + O(7^8)

        Exceptional cases::

            sage: EllipticCurve('11a1').sha().an_padic(11) # rank 0
            1 + O(11^22)
            sage: EllipticCurve('130a1').sha().an_padic(5) # rank 1
            1 + O(5)

        Non-split, but rank 0 case (:trac:`7331`)::

            sage: EllipticCurve('270b1').sha().an_padic(5) # rank 0, long time (2s on sage.math, 2011)
            1 + O(5^22)

        The output has the correct sign::

            sage: EllipticCurve('123a1').sha().an_padic(41) # rank 1, long time (3s on sage.math, 2011)
            1 + O(41)

        Supersingular cases::

            sage: EllipticCurve('34a1').sha().an_padic(5) # rank 0
            1 + O(5^22)
            sage: EllipticCurve('53a1').sha().an_padic(5) # rank 1, long time (11s on sage.math, 2011)
            1 + O(5)

        Cases that use a twist to a lower conductor::

            sage: EllipticCurve('99a1').sha().an_padic(5)
            1 + O(5)
            sage: EllipticCurve('240d3').sha().an_padic(5)  # sha has 4 elements here
            4 + O(5)
            sage: EllipticCurve('448c5').sha().an_padic(7,prec=4, use_twists=False)  # long time (2s on sage.math, 2011)
            2 + 7 + O(7^6)
            sage: EllipticCurve([-19,34]).sha().an_padic(5)  # see trac #6455, long time (4s on sage.math, 2011)
            1 + O(5)

        Test for :trac:`15737`::

            sage: E = EllipticCurve([-100,0])
            sage: s = E.sha()
            sage: s.an_padic(13)
            1 + O(13^20)
        """
        try:
            return self.__an_padic[(p,prec)]
        except AttributeError:
            self.__an_padic = {}
        except KeyError:
            pass

        E = self.Emin
        tam = E.tamagawa_product()
        tors = E.torsion_order()**2
        r = E.rank()
        if r > 0 :
            reg = E.padic_regulator(p)
        else:
            if E.is_supersingular(p):
                reg = vector([ Qp(p,20)(1), 0 ])
            else:
                reg = Qp(p,20)(1)

        if use_twists and p > 2:
            Et, D = E.minimal_quadratic_twist()
            # trac 6455 : we have to assure that the twist back is allowed
            D = ZZ(D)
            if D % p == 0:
                D = ZZ(D/p)
            for ell in D.prime_divisors():
                if ell % 2 == 1:
                    if Et.conductor() % ell**2 == 0:
                        D = ZZ(D/ell)
            ve = valuation(D,2)
            de = ZZ( (D/2**ve).abs() )
            if de % 4 == 3:
                de = -de
            Et = E.quadratic_twist(de)
            # now check individually if we can twist by -1 or 2 or -2
            Nmin = Et.conductor()
            Dmax = de
            for DD in [-4*de,8*de,-8*de]:
                Et = E.quadratic_twist(DD)
                if Et.conductor() < Nmin and valuation(Et.conductor(),2) <= valuation(DD,2):
                    Nmin = Et.conductor()
                    Dmax = DD
            D = Dmax
            Et = E.quadratic_twist(D)
            lp = Et.padic_lseries(p)
        else :
            lp = E.padic_lseries(p)
            D = 1

        if r == 0 and D == 1:
            # short cut for rank 0 curves, we do not
            # to compute the p-adic L-function, the leading
            # term will be the L-value divided by the Neron
            # period.
            ms = E.modular_symbol(sign=+1, normalize='L_ratio')
            lstar = ms(0)/E.real_components()
            bsd = tam/tors
            if prec == 0:
                #prec = valuation(lstar/bsd, p)
                prec = 20
            shan = Qp(p,prec=prec+2)(lstar/bsd)


        elif E.is_ordinary(p):
            K = reg.parent()
            lg = log(K(1+p))

            if (E.is_good(p) or E.ap(p) == -1):
                if not E.is_good(p):
                    eps = 2
                else:
                    eps = (1-arith.kronecker_symbol(D,p)/lp.alpha())**2
                # according to the p-adic BSD this should be equal to the leading term of the p-adic L-series divided by sha:
                bsdp = tam * reg * eps/tors/lg**r
            else:
                r += 1   # exceptional zero
                eq = E.tate_curve(p)
                Li = eq.L_invariant()

                # according to the p-adic BSD (Mazur-Tate-Teitelbaum)
                # this should be equal to the leading term of the p-adic L-series divided by sha:
                bsdp = tam * reg * Li/tors/lg**r


            v = bsdp.valuation()
            if v > 0:
                verbose("the prime is irregular for this curve.")

            # determine how much prec we need to prove at least the
            # triviality of the p-primary part of Sha

            if prec == 0:
                n = max(v,2)
                bounds = lp._prec_bounds(n,r+1)
                while bounds[r] <= v:
                    n += 1
                    bounds = lp._prec_bounds(n,r+1)
                verbose("set precision to %s"%n)
            else:
                n = max(2,prec)

            not_yet_enough_prec = True
            while not_yet_enough_prec:
                lps = lp.series(n,quadratic_twist=D,prec=r+1)
                lstar = lps[r]
                if (lstar != 0) or (prec != 0):
                    not_yet_enough_prec = False
                else:
                    n += 1
                    verbose("increased precision to %s"%n)

            shan = lstar/bsdp

        elif E.is_supersingular(p):
            K = reg[0].parent()
            lg = log(K(1+p))


            # according to the p-adic BSD this should be equal to the leading term of the D_p - valued
            # L-series :
            bsdp = tam /tors/lg**r * reg
            # note this is an element in Q_p^2

            verbose("the algebraic leading terms : %s"%bsdp)

            v = [bsdp[0].valuation(),bsdp[1].valuation()]

            if prec == 0:
                n = max(min(v)+2,3)
            else:
                n = max(3,prec)

            verbose("...computing the p-adic L-series")
            not_yet_enough_prec = True
            while not_yet_enough_prec:
                lps = lp.Dp_valued_series(n,quadratic_twist=D,prec=r+1)
                lstar = [lps[0][r],lps[1][r]]
                verbose("the leading terms : %s"%lstar)
                if (lstar[0] != 0 or lstar[1] != 0) or ( prec != 0):
                    not_yet_enough_prec = False
                else:
                    n += 1
                    verbose("increased precision to %s"%n)

            verbose("...putting things together")
            if bsdp[0] != 0:
                shan0 = lstar[0]/bsdp[0]
            else:
                shan0 = 0   # this should actually never happen
            if bsdp[1] != 0:
                shan1 = lstar[1]/bsdp[1]
            else:
                shan1 = 0   # this should conjecturally only happen when the rank is 0
            verbose("the two values for Sha : %s"%[shan0,shan1])

            # check consistency (the first two are only here to avoid a bug in the p-adic L-series
            # (namely the coefficients of zero-relative precision are treated as zero)
            if shan0 != 0 and shan1 != 0 and shan0 - shan1 != 0:
                raise RuntimeError("There must be a bug in the supersingular routines for the p-adic BSD.")

            #take the better
            if shan1 == 0 or shan0.precision_relative() > shan1.precision_relative():
                shan = shan0
            else:
                shan = shan1

        else:
            raise ValueError("The curve has to have semi-stable reduction at p.")

        self.__an_padic[(p,prec)] = shan
        return shan
Ejemplo n.º 38
0
    def an_padic(self, p, prec=0, use_twists=True):
        r"""
        Returns the conjectural order of `Sha(E/\QQ)`,
        according to the `p`-adic analogue of the Birch
        and Swinnerton-Dyer conjecture as formulated
        in [MTT]_ and [BP]_.

        REFERENCES:

        .. [MTT] B. Mazur, J. Tate, and J. Teitelbaum, On `p`-adic
           analogues of the conjectures of Birch and Swinnerton-Dyer,
           Inventiones mathematicae 84, (1986), 1-48.

        .. [BP] Dominique Bernardi and Bernadette Perrin-Riou,
           Variante `p`-adique de la conjecture de Birch et
           Swinnerton-Dyer (le cas supersingulier),
           C. R. Acad. Sci. Paris, Ser I. Math, 317 (1993), no 3,
           227-232.

        .. [SW] William Stein and Christian Wuthrich, Computations
           About Tate-Shafarevich Groups using Iwasawa theory,
           preprint 2009.

        INPUT:

        - ``p`` - a prime > 3

        - ``prec`` (optional) - the precision used in the computation of the `p`-adic L-Series

        - ``use_twists`` (default = ``True``) - If ``True`` the algorithm may change
          to a quadratic twist with minimal conductor to do the modular
          symbol computations rather than using the modular symbols of the
          curve itself. If ``False`` it forces the computation using the
          modular symbols of the curve itself.

        OUTPUT:  `p`-adic number - that conjecturally equals `\# Sha(E/\QQ)`.

        If ``prec`` is set to zero (default) then the precision is set so that
        at least the first `p`-adic digit of conjectural `\# Sha(E/\QQ)` is
        determined.

        EXAMPLES:

        Good ordinary examples::

            sage: EllipticCurve('11a1').sha().an_padic(5)    # rank 0
            1 + O(5^2)
            sage: EllipticCurve('43a1').sha().an_padic(5)    # rank 1
            1 + O(5)
            sage: EllipticCurve('389a1').sha().an_padic(5,4) # rank 2, long time (2s on sage.math, 2011)
            1 + O(5^3)
            sage: EllipticCurve('858k2').sha().an_padic(7)   # rank 0, non trivial sha, long time (10s on sage.math, 2011)
            Traceback (most recent call last):                           # 32-bit (see ticket :trac: `112111`)
            ...                                                          # 32-bit
            OverflowError: Python int too large to convert to C long     # 32-bit
            7^2 + O(7^6) # 64-bit
            sage: EllipticCurve('300b2').sha().an_padic(3)   # 9 elements in sha, long time (2s on sage.math, 2011)
            3^2 + O(3^6)
            sage: EllipticCurve('300b2').sha().an_padic(7, prec=6)  # long time
            2 + 7 + O(7^8)

        Exceptional cases::

            sage: EllipticCurve('11a1').sha().an_padic(11) # rank 0
            1 + O(11^2)
            sage: EllipticCurve('130a1').sha().an_padic(5) # rank 1
            1 + O(5)

        Non-split, but rank 0 case (:trac:`7331`)::

            sage: EllipticCurve('270b1').sha().an_padic(5) # rank 0, long time (2s on sage.math, 2011)
            1 + O(5^2)

        The output has the correct sign::

            sage: EllipticCurve('123a1').sha().an_padic(41) # rank 1, long time (3s on sage.math, 2011)
            1 + O(41)

        Supersingular cases::

            sage: EllipticCurve('34a1').sha().an_padic(5) # rank 0
            1 + O(5^2)
            sage: EllipticCurve('53a1').sha().an_padic(5) # rank 1, long time (11s on sage.math, 2011)
            1 + O(5)

        Cases that use a twist to a lower conductor::

            sage: EllipticCurve('99a1').sha().an_padic(5)
            1 + O(5)
            sage: EllipticCurve('240d3').sha().an_padic(5)  # sha has 4 elements here
            4 + O(5)
            sage: EllipticCurve('448c5').sha().an_padic(7,prec=4, use_twists=False)  # long time (2s on sage.math, 2011)
            2 + 7 + O(7^6)
            sage: EllipticCurve([-19,34]).sha().an_padic(5)  # see :trac: `6455`, long time (4s on sage.math, 2011)
            1 + O(5)
        """
        try:
            return self.__an_padic[(p,prec)]
        except AttributeError:
            self.__an_padic = {}
        except KeyError:
            pass

        E = self.Emin
        tam = E.tamagawa_product()
        tors = E.torsion_order()**2
        reg = E.padic_regulator(p)
        # todo : here we should cache the rank computation
        r = E.rank()


        if use_twists and p > 2:
            Et, D = E.minimal_quadratic_twist()
            # trac 6455 : we have to assure that the twist back is allowed
            D = ZZ(D)
            if D % p == 0:
                D = D/p
            for ell in D.prime_divisors():
                if ell % 2 == 1:
                    if Et.conductor() % ell**2 == 0:
                        D = D/ell
            ve = valuation(D,2)
            de = (D/2**ve).abs()
            if de % 4 == 3:
                de = -de
            Et = E.quadratic_twist(de)
            # now check individually if we can twist by -1 or 2 or -2
            Nmin = Et.conductor()
            Dmax = de
            for DD in [-4*de,8*de,-8*de]:
                Et = E.quadratic_twist(DD)
                if Et.conductor() < Nmin and valuation(Et.conductor(),2) <= valuation(DD,2):
                    Nmin = Et.conductor()
                    Dmax = DD
            D = Dmax
            Et = E.quadratic_twist(D)
            lp = Et.padic_lseries(p)
        else :
            lp = E.padic_lseries(p)
            D = 1

        if r == 0 and D == 1:
            # short cut for rank 0 curves, we do not
            # to compute the p-adic L-function, the leading
            # term will be the L-value divided by the Neron
            # period.
            ms = E.modular_symbol(sign=+1, normalize='L_ratio')
            lstar = ms(0)/E.real_components()
            bsd = tam/tors
            if prec == 0:
                prec = valuation(lstar/bsd, p)
            shan = Qp(p,prec=prec+2)(lstar/bsd)


        elif E.is_ordinary(p):
            K = reg.parent()
            lg = log(K(1+p))

            if (E.is_good(p) or E.ap(p) == -1):
                if not E.is_good(p):
                    eps = 2
                else:
                    eps = (1-arith.kronecker_symbol(D,p)/lp.alpha())**2
                # according to the p-adic BSD this should be equal to the leading term of the p-adic L-series divided by sha:
                bsdp = tam * reg * eps/tors/lg**r
            else:
                r += 1   # exceptional zero
                eq = E.tate_curve(p)
                Li = eq.L_invariant()

                # according to the p-adic BSD (Mazur-Tate-Teitelbaum)
                # this should be equal to the leading term of the p-adic L-series divided by sha:
                bsdp = tam * reg * Li/tors/lg**r


            v = bsdp.valuation()
            if v > 0:
                verbose("the prime is irregular.")

            # determine how much prec we need to prove at least the triviality of
            # the p-primary part of Sha

            if prec == 0:
                n = max(v,2)
                bounds = lp._prec_bounds(n,r+1)
                while bounds[r] <= v:
                    n += 1
                    bounds = lp._prec_bounds(n,r+1)
                verbose("set precision to %s"%n)
            else:
                n = max(2,prec)

            not_yet_enough_prec = True
            while not_yet_enough_prec:
                lps = lp.series(n,quadratic_twist=D,prec=r+1)
                lstar = lps[r]
                if (lstar != 0) or (prec != 0):
                    not_yet_enough_prec = False
                else:
                    n += 1
                    verbose("increased precision to %s"%n)

            shan = lstar/bsdp

        elif E.is_supersingular(p):
            K = reg[0].parent()
            lg = log(K(1+p))


            # according to the p-adic BSD this should be equal to the leading term of the D_p - valued
            # L-series :
            bsdp = tam /tors/lg**r * reg
            # note this is an element in Q_p^2

            verbose("the algebraic leading terms : %s"%bsdp)

            v = [bsdp[0].valuation(),bsdp[1].valuation()]

            if prec == 0:
                n = max(min(v)+2,3)
            else:
                n = max(3,prec)

            verbose("...computing the p-adic L-series")
            not_yet_enough_prec = True
            while not_yet_enough_prec:
                lps = lp.Dp_valued_series(n,quadratic_twist=D,prec=r+1)
                lstar = [lps[0][r],lps[1][r]]
                verbose("the leading terms : %s"%lstar)
                if (lstar[0] != 0 or lstar[1] != 0) or ( prec != 0):
                    not_yet_enough_prec = False
                else:
                    n += 1
                    verbose("increased precision to %s"%n)

            verbose("...putting things together")
            if bsdp[0] != 0:
                shan0 = lstar[0]/bsdp[0]
            else:
                shan0 = 0   # this should actually never happen
            if bsdp[1] != 0:
                shan1 = lstar[1]/bsdp[1]
            else:
                shan1 = 0   # this should conjecturally only happen when the rank is 0
            verbose("the two values for Sha : %s"%[shan0,shan1])

            # check consistency (the first two are only here to avoid a bug in the p-adic L-series
            # (namely the coefficients of zero-relative precision are treated as zero)
            if shan0 != 0 and shan1 != 0 and shan0 - shan1 != 0:
                raise RuntimeError("There must be a bug in the supersingular routines for the p-adic BSD.")

            #take the better
            if shan1 == 0 or shan0.precision_relative() > shan1.precision_relative():
                shan = shan0
            else:
                shan = shan1

        else:
            raise ValueError("The curve has to have semi-stable reduction at p.")

        self.__an_padic[(p,prec)] = shan
        return shan
Ejemplo n.º 39
0
    def alpha(self, prec=20):
        r"""
        Return a `p`-adic root `\alpha` of the polynomial `x^2 - a_p x
        + p` with `ord_p(\alpha) < 1`.  In the ordinary case this is
        just the unit root.

        INPUT:
        -  ``prec`` - positive integer, the `p`-adic precision of the root.

        EXAMPLES:

        """
        try:
            return self._alpha[prec]
        except AttributeError:
            self._alpha = {}
        except KeyError:
            pass
       
        J = self._J
        p = self._p
        Q = Qp(p)
        try:
            a_p = self._ap
        except AttributeError:
            a_p = self._ap = self.ap() 

        try:
            psis = self._psis
        except AttributeError:
            psis = self._psis = self.psi()

        K_f = self.hecke_eigenvalue_field()
        if len(psis) == 1:
   	    F = Q.extension(K_f.defining_polynomial(),names='a')
            a = F.gen()
            G = K_f.embeddings(K_f)
            if G[0](K_f.gen()) == K_f.gen():
                conj_map = G[1]
            else: 
                conj_map = G[0]
            v = self._dual_eigenvector
            v_conj = vector(conj_map(a) for a in v)
            a_p_conj = conj_map(a_p)
            R = F['x']
            x = R.gen()
	    psi = psis[0]
            a_p_padic = psi(a_p)
	    a_p_conj_padic = psi(a_p_conj)
            f = x**2 - (a_p_padic)*x + p
            fconj = x**2 - (a_p_conj_padic)*x + p
            norm_f = f*fconj
            norm_f_basefield = norm_f.change_ring(Q)
            FF = norm_f_basefield().factor()
            root0 = -f.gcd(FF[0][0])[0]
            root1 = -f.gcd(FF[1][0])[0]
            if root0.valuation() < 1:
                padic_lseries_alpha = [root0]
            else:
                padic_lseries_alpha = [root1]

        else:
            a_p_conj_padic = []
            a_p_padic = []
            for psi in psis:
                a_p_padic = a_p_padic + [psi(a_p)]

            R = Q['x']
            x = R.gen()
            padic_lseries_alpha = []
            for aps in a_p_padic:
                f = R(x**2 - aps*x + p)
                roots = f.roots()
                root0 = roots[0][0]
                root1 = roots[1][0]
                if root0.valuation() < 1:
                    padic_lseries_alpha = padic_lseries_alpha + [root0]
                else:
                    padic_lseries_alpha = padic_lseries_alpha + [root1]
                
        return padic_lseries_alpha  
Ejemplo n.º 40
0
    def hilbert_symbol_negative_at_S(self, S, b, check=True):
        r"""
        Returns an integer that has a negative Hilbert symbol with respect
        to a given rational number and a given set of primes (or places).

        The function is algorithm 3.4.1 in [Kir2016]_. It finds an integer `a`
        that has negative Hilbert symbol with respect to a given rational number
        exactly at a given set of primes (or places).

        INPUT:

        - ``S`` -- a list of rational primes, the infinite place as real
          embedding of `\QQ` or as -1
        - ``b`` -- a non-zero rational number which is a non-square locally
          at every prime in ``S``.
        - ``check`` -- ``bool`` (default:``True``) perform additional checks on
          input and confirm the output.

        OUTPUT:

        - An integer `a` that has negative Hilbert symbol `(a,b)_p` for
          every place `p` in `S` and no other place.

        EXAMPLES::

            sage: QQ.hilbert_symbol_negative_at_S([-1,5,3,2,7,11,13,23], -10/7)
            -9867
            sage: QQ.hilbert_symbol_negative_at_S([3, 5, QQ.places()[0], 11], -15)
            -33
            sage: QQ.hilbert_symbol_negative_at_S([3, 5], 2)
            15

        TESTS::

            sage: QQ.hilbert_symbol_negative_at_S(5/2, -2)
            Traceback (most recent call last):
            ...
            TypeError: first argument must be a list or integer

        ::

            sage: QQ.hilbert_symbol_negative_at_S([1, 3], 0)
            Traceback (most recent call last):
            ...
            ValueError: second argument must be nonzero

        ::

            sage: QQ.hilbert_symbol_negative_at_S([-1, 3, 5], 2)
            Traceback (most recent call last):
            ...
            ValueError: list should be of even cardinality

        ::

            sage: QQ.hilbert_symbol_negative_at_S([1, 3], 2)
            Traceback (most recent call last):
            ...
            ValueError: all entries in list must be prime or -1 for
            infinite place

        ::

            sage: QQ.hilbert_symbol_negative_at_S([5, 7], 2)
            Traceback (most recent call last):
            ...
            ValueError: second argument must be a nonsquare with
            respect to every finite prime in the list

        ::

            sage: QQ.hilbert_symbol_negative_at_S([1, 3], sqrt(2))
            Traceback (most recent call last):
            ...
            TypeError: second argument must be a rational number

        ::

            sage: QQ.hilbert_symbol_negative_at_S([-1, 3], 2)
            Traceback (most recent call last):
            ...
            ValueError: if the infinite place is in the list, the second
            argument must be negative

        AUTHORS:

        - Simon Brandhorst, Juanita Duque, Anna Haensch, Manami Roy, Sandi Rudzinski (10-24-2017)

        """
        from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF
        from sage.rings.padics.factory import Qp
        from sage.modules.free_module import VectorSpace
        from sage.matrix.constructor import matrix
        from sage.sets.primes import Primes
        from sage.arith.misc import hilbert_symbol, is_prime

        # input checks
        if not type(S) is list:
            raise TypeError("first argument must be a list or integer")
        # -1 is used for the infinite place
        infty = -1
        for i in range(len(S)):
            if S[i] == self.places()[0]:
                S[i] = -1
        if not b in self:
            raise TypeError("second argument must be a rational number")
        b = self(b)
        if b == 0:
            raise ValueError("second argument must be nonzero")
        if len(S) % 2:
            raise ValueError("list should be of even cardinality")
        for p in S:
            if p != infty:
                if check and not is_prime(p):
                    raise ValueError("all entries in list must be prime"
                                     " or -1 for infinite place")
                R = Qp(p)
                if R(b).is_square():
                    raise ValueError(
                        "second argument must be a nonsquare with"
                        " respect to every finite prime in the list")
            elif b > 0:
                raise ValueError("if the infinite place is in the list, "
                                 "the second argument must be negative")
        # L is the list of primes that we need to consider, b must have
        # nonzero valuation for each prime in L, this is the set S'
        # in Kirschmer's algorithm
        L = []
        L = [p[0] for p in b.factor() if p[0] not in S]
        # We must also consider 2 to be in L
        if 2 not in L and 2 not in S:
            L.append(2)
        # This adds the infinite place to L
        if b < 0 and infty not in S:
            L.append(infty)

        P = S + L
        # This constructs the vector v in the algorithm. This is the vector
        # that we are searching for. It represents the case when the Hilbert
        # symbol is negative for all primes in S and positive
        # at all primes in S'
        V = VectorSpace(GF(2), len(P))
        v = V([1] * len(S) + [0] * len(L))

        # Compute the map phi of Hilbert symbols at all the primes
        # in S and S'
        # For technical reasons, a Hilbert symbol of -1 is
        # respresented as 1 and a Hilbert symbol of 1
        # is represented as 0
        def phi(x):
            v = [(1 - hilbert_symbol(x, b, p)) // 2 for p in P]
            return V(v)

        M = matrix(GF(2), [phi(p) for p in P + [-1]])
        # We search through all the primes
        for q in Primes():
            # Only look at this prime if it is not in our list
            if q in P:
                continue

            # The algorithm terminates when the vector v is in the
            # subspace of V generated by the image of the phi map
            # on the set of generators
            w = phi(q)
            W = M.stack(matrix(w))
            if v in W.row_space():
                break
        Pq = P + [-1] + [q]
        l = W.solve_left(v)
        a = self.prod([Pq[i]**ZZ(l[i]) for i in range(l.degree())])
        if check:
            assert phi(a) == v, "oops"
        return a
Ejemplo n.º 41
0
    def padic_H_value(self, p, f, t, prec=None):
        """
        Return the `p`-adic trace of Frobenius, computed using the
        Gross-Koblitz formula.

        INPUT:

        - `p` -- a prime number

        - `f` -- an integer such that `q = p^f`

        - `t` -- a rational parameter

        - ``prec`` -- precision (optional, default 20)

        OUTPUT:

        an integer

        EXAMPLES:

        From Benasque report [Benasque2009]_, page 8::

            sage: from sage.modular.hypergeometric_motive import HypergeometricData as Hyp
            sage: H = Hyp(alpha_beta=([1/2]*4,[0]*4))
            sage: [H.padic_H_value(3,i,-1) for i in range(1,3)]
            [0, -12]
            sage: [H.padic_H_value(5,i,-1) for i in range(1,3)]
            [-4, 276]
            sage: [H.padic_H_value(7,i,-1) for i in range(1,3)]
            [0, -476]
            sage: [H.padic_H_value(11,i,-1) for i in range(1,3)]
            [0, -4972]

        From [Roberts2015]_ (but note conventions regarding `t`)::

            sage: H = Hyp(gamma_list=[-6,-1,4,3])
            sage: t = 189/125
            sage: H.padic_H_value(13,1,1/t)
            0

        REFERENCES:

        - [MagmaHGM]_
        """
        alpha = self._alpha
        beta = self._beta
        if 0 in alpha:
            H = self.swap_alpha_beta()
            return(H.padic_H_value(p, f, ~t, prec))
        t = QQ(t)
        gamma = self.gamma_array()
        q = p ** f

#        m = {r: beta.count(QQ((r, q - 1))) for r in range(q - 1)}
        m = defaultdict(lambda: 0)
        for r in range(q-1):
            u = QQ((r, q-1))
            if u in beta:
                m[r] = beta.count(u)
        M = self.M_value()
        D = -min(self.zigzag(x, flip_beta=True) for x in alpha + beta)
        # also: D = (self.weight() + 1 - m[0]) // 2

        if prec is None:
            prec = (self.weight()*f)//2 + ceil(log(self.degree(),p)) + 1
        # For some reason, working in Qp instead of Zp is much faster;
        # it appears to avoid some costly conversions.
        p_ring = Qp(p, prec=prec)
        teich = p_ring.teichmuller(M / t)

        gauss_table = [padic_gauss_sum(r, p, f, prec, factored=True, algorithm='sage', parent=p_ring)
                       for r in range(q-1)]

        sigma = sum( ((-p)**(sum(gauss_table[(v * r) % (q - 1)][0] * gv
                                for v, gv in gamma.items()) // (p - 1)) * 
                     prod(gauss_table[(v * r) % (q - 1)][1] ** gv
                          for v, gv in gamma.items()) * teich ** r)
                     << (f*(D+m[0]-m[r])) for r in range(q-1))
        resu = ZZ(-1) ** m[0] / (1 - q) * sigma
        return IntegerModRing(p**prec)(resu).lift_centered()