Hyperelliptic curves (smooth model) over a p-adic field - Elliptic curves

Skip to content
Back to top
View this page
Edit this page

# Hyperelliptic curves (smooth model) over a p-adic field

The functions in this module were prototyped at the 2007 Arizona Winter School by Robert Bradshaw and Ralf Gerkmann, working with Miljan Brakovevic and Kiran Kedlaya. They were adapted by Sabrina Kunzweiler, Gareth Ma, Giacomo Pope (2024) to work for hyperelliptic curves in weighted projective space.

All of the below is with respect to the Monsky Washnitzer cohomology.

AUTHORS:

- Robert Bradshaw, Ralf Gerkmann, Miljan Brakovevic, Kiran Kedlaya (2007): initial version

- Sabrina Kunzweiler, Gareth Ma, Giacomo Pope (2024): adapt to smooth model

class sage.schemes.hyperelliptic_curves.hyperelliptic_padic_field.HyperellipticCurve_padic_field(projective_model, f, h, genus: Integer, names=['x', 'y'])

  Bases: `HyperellipticCurve_generic`

  Class of hyperelliptic curves (smooth model) over a \(p\)-adic field. In particular this class implements the necessary functionality to compute Coleman integrals.

  EXAMPLES:

  This is the curve with LMFDB label 1091.a.1091.1

  Sage

      sage: K = pAdicField(7,10)
      sage: R.<x> = K[]
      sage: H = HyperellipticCurve(x^5 + 1/4*x^4 -3/2* x^3 -1/4*x^2 + 1/2*x +  1/4)
      sage: P0 = H(1,0,0)
      sage: Q = H(-1,-1/2)
      sage: P = H(0,1/2)

  Python

      >>> from sage.all import *
      >>> K = pAdicField(Integer(7),Integer(10))
      >>> R = K['x']; (x,) = R._first_ngens(1)
      >>> H = HyperellipticCurve(x**Integer(5) + Integer(1)/Integer(4)*x**Integer(4) -Integer(3)/Integer(2)* x**Integer(3) -Integer(1)/Integer(4)*x**Integer(2) + Integer(1)/Integer(2)*x +  Integer(1)/Integer(4))
      >>> P0 = H(Integer(1),Integer(0),Integer(0))
      >>> Q = H(-Integer(1),-Integer(1)/Integer(2))
      >>> P = H(Integer(0),Integer(1)/Integer(2))

  We note that \([P-P_0]\) has order \(7\) on the Jacobian, hence the Coleman integral \(\int_P^{P_0} dx/2y\) vanishes. On the other hand \([Q-Q_0]\) has infinite order, and the corresponding integral is nonzero:

  Sage

      sage: w = H.invariant_differential()
      sage: H.coleman_integral(w,P,P0)
      O(7^9)
      sage: H.coleman_integral(w,Q,P0)
      3*7 + 4*7^2 + 5*7^4 + 2*7^5 + 2*7^6 + 6*7^7 + 4*7^8 + O(7^9)

  [Python]

      >>> from sage.all import *
      >>> w = H.invariant_differential()
      >>> H.coleman_integral(w,P,P0)
      O(7^9)
      >>> H.coleman_integral(w,Q,P0)
      3*7 + 4*7^2 + 5*7^4 + 2*7^5 + 2*7^6 + 6*7^7 + 4*7^8 + O(7^9)

  P_to_S(P, S)

    Given a finite Weierstrass point `P` and a point `S` in the same disc, compute the Coleman integrals \(\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}\)

    INPUT:

    - `P`: finite Weierstrass point

    - `S`: point in disc of `P`

    OUTPUT:

    Coleman integrals \(\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}\)

    EXAMPLES:

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^3-10*x+9)
        sage: K = Qp(5,4)
        sage: HK = H.change_ring(K)
        sage: P = HK(1,0)
        sage: HJ = HK.curve_over_ram_extn(10)
        sage: S = HK.get_boundary_point(HJ,P)
        sage: HK.P_to_S(P, S)
        (2*a + 4*a^3 + 2*a^11 + 4*a^13 + 2*a^17 + 2*a^19 + a^21 + 4*a^23 + a^25 + 2*a^27 + 2*a^29 + 3*a^31 + 4*a^33 + O(a^35), a^-5 + 2*a + 2*a^3 + a^7 + 3*a^11 + a^13 + 3*a^15 + 3*a^17 + 2*a^19 + 4*a^21 + 4*a^23 + 4*a^25 + 2*a^27 + a^29 + a^31 + O(a^33))

    Python

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(3)-Integer(10)*x+Integer(9))
        >>> K = Qp(Integer(5),Integer(4))
        >>> HK = H.change_ring(K)
        >>> P = HK(Integer(1),Integer(0))
        >>> HJ = HK.curve_over_ram_extn(Integer(10))
        >>> S = HK.get_boundary_point(HJ,P)
        >>> HK.P_to_S(P, S)
        (2*a + 4*a^3 + 2*a^11 + 4*a^13 + 2*a^17 + 2*a^19 + a^21 + 4*a^23 + a^25 + 2*a^27 + 2*a^29 + 3*a^31 + 4*a^33 + O(a^35), a^-5 + 2*a + 2*a^3 + a^7 + 3*a^11 + a^13 + 3*a^15 + 3*a^17 + 2*a^19 + 4*a^21 + 4*a^23 + 4*a^25 + 2*a^27 + a^29 + a^31 + O(a^33))

    AUTHOR:

    - Jennifer Balakrishnan

  S_to_Q(S, Q)

    Given `S` a point on `self` over an extension field, compute the Coleman integrals \(\{\int_S^Q x^i dx/2y \}_{i=0}^{2g-1}\)

    one should be able to feed ``S,Q`` into coleman_integral, but currently that segfaults

    INPUT:

    - `S`: a point with coordinates in an extension of \(\QQ_p\) (with unif. \(a\))

    - `Q`: a non-Weierstrass point defined over \(\QQ_p\)

    OUTPUT:

    the Coleman integrals \(\{\int_S^Q x^i dx/2y \}_{i=0}^{2g-1}\) in terms of \(a\)

    EXAMPLES:

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^3-10*x+9)
        sage: K = Qp(5,6)
        sage: HK = H.change_ring(K)
        sage: J.<a> = K.extension(x^20-5)
        sage: HJ  = H.change_ring(J)
        sage: w = HK.invariant_differential()
        sage: x,y = HK.monsky_washnitzer_gens()
        sage: P = HK(1,0)
        sage: Q = HK(0,3)
        sage: S = HK.get_boundary_point(HJ,P)
        sage: P_to_S = HK.P_to_S(P,S)
        sage: S_to_Q = HJ.S_to_Q(S,Q)
        sage: P_to_S + S_to_Q
        (2*a^40 + a^80 + a^100 + O(a^105), a^20 + 2*a^40 + 4*a^60 + 2*a^80 + O(a^103))
        sage: HK.coleman_integrals_on_basis(P,Q)
        (2*5^2 + 5^4 + 5^5 + 3*5^6 + O(5^7), 5 + 2*5^2 + 4*5^3 + 2*5^4 + 5^6 + O(5^7))

    Python

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(3)-Integer(10)*x+Integer(9))
        >>> K = Qp(Integer(5),Integer(6))
        >>> HK = H.change_ring(K)
        >>> J = K.extension(x**Integer(20)-Integer(5), names=('a',)); (a,) = J._first_ngens(1)
        >>> HJ  = H.change_ring(J)
        >>> w = HK.invariant_differential()
        >>> x,y = HK.monsky_washnitzer_gens()
        >>> P = HK(Integer(1),Integer(0))
        >>> Q = HK(Integer(0),Integer(3))
        >>> S = HK.get_boundary_point(HJ,P)
        >>> P_to_S = HK.P_to_S(P,S)
        >>> S_to_Q = HJ.S_to_Q(S,Q)
        >>> P_to_S + S_to_Q
        (2*a^40 + a^80 + a^100 + O(a^105), a^20 + 2*a^40 + 4*a^60 + 2*a^80 + O(a^103))
        >>> HK.coleman_integrals_on_basis(P,Q)
        (2*5^2 + 5^4 + 5^5 + 3*5^6 + O(5^7), 5 + 2*5^2 + 4*5^3 + 2*5^4 + 5^6 + O(5^7))

    AUTHOR:

    - Jennifer Balakrishnan

  coleman_integral(w, P, Q, algorithm='None')

    Return the Coleman integral \(\int_P^Q w\).

    INPUT:

    - `w` differential (if one of P,Q is Weierstrass, w must be odd)

    - `P` point on self

    - `Q` point on self

    - algorithm (optional) = None (uses Frobenius) or teichmuller (uses Teichmuller points)

    OUTPUT:

    the Coleman integral \(\int_P^Q w\)

    EXAMPLES:

    Example of Leprevost from Kiran Kedlaya The first two should be zero as \((P-Q) = 30(P-Q)\) in the Jacobian and \(dx/2y\) and \(x dx/2y\) are holomorphic.

    Sage

        sage: K = pAdicField(11, 6)
        sage: x = polygen(K)
        sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16)
        sage: P = C(-1, 1); P1 = C(-1, -1)
        sage: Q = C(0, 1/4); Q1 = C(0, -1/4)
        sage: x, y = C.monsky_washnitzer_gens()
        sage: w = C.invariant_differential()
        sage: w.coleman_integral(P, Q)
        O(11^6)
        sage: C.coleman_integral(x*w, P, Q)
        O(11^6)
        sage: C.coleman_integral(x^2*w, P, Q)
        7*11 + 6*11^2 + 3*11^3 + 11^4 + 5*11^5 + O(11^6)

    Python

        >>> from sage.all import *
        >>> K = pAdicField(Integer(11), Integer(6))
        >>> x = polygen(K)
        >>> C = HyperellipticCurve(x**Integer(5) + Integer(33)/Integer(16)*x**Integer(4) + Integer(3)/Integer(4)*x**Integer(3) + Integer(3)/Integer(8)*x**Integer(2) - Integer(1)/Integer(4)*x + Integer(1)/Integer(16))
        >>> P = C(-Integer(1), Integer(1)); P1 = C(-Integer(1), -Integer(1))
        >>> Q = C(Integer(0), Integer(1)/Integer(4)); Q1 = C(Integer(0), -Integer(1)/Integer(4))
        >>> x, y = C.monsky_washnitzer_gens()
        >>> w = C.invariant_differential()
        >>> w.coleman_integral(P, Q)
        O(11^6)
        >>> C.coleman_integral(x*w, P, Q)
        O(11^6)
        >>> C.coleman_integral(x**Integer(2)*w, P, Q)
        7*11 + 6*11^2 + 3*11^3 + 11^4 + 5*11^5 + O(11^6)

    Sage

        sage: p = 71; m = 4
        sage: K = pAdicField(p, m)
        sage: x = polygen(K)
        sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16)
        sage: P = C(-1, 1); P1 = C(-1, -1)
        sage: Q = C(0, 1/4); Q1 = C(0, -1/4)
        sage: x, y = C.monsky_washnitzer_gens()
        sage: w = C.invariant_differential()
        sage: w.integrate(P, Q), (x*w).integrate(P, Q)
        (O(71^4), O(71^4))
        sage: R, R1 = C.lift_x(4, all=True)
        sage: w.integrate(P, R)
        50*71 + 3*71^2 + 43*71^3 + O(71^4)
        sage: w.integrate(P, R) + w.integrate(P1, R1)
        O(71^4)

    [Python]

        >>> from sage.all import *
        >>> p = Integer(71); m = Integer(4)
        >>> K = pAdicField(p, m)
        >>> x = polygen(K)
        >>> C = HyperellipticCurve(x**Integer(5) + Integer(33)/Integer(16)*x**Integer(4) + Integer(3)/Integer(4)*x**Integer(3) + Integer(3)/Integer(8)*x**Integer(2) - Integer(1)/Integer(4)*x + Integer(1)/Integer(16))
        >>> P = C(-Integer(1), Integer(1)); P1 = C(-Integer(1), -Integer(1))
        >>> Q = C(Integer(0), Integer(1)/Integer(4)); Q1 = C(Integer(0), -Integer(1)/Integer(4))
        >>> x, y = C.monsky_washnitzer_gens()
        >>> w = C.invariant_differential()
        >>> w.integrate(P, Q), (x*w).integrate(P, Q)
        (O(71^4), O(71^4))
        >>> R, R1 = C.lift_x(Integer(4), all=True)
        >>> w.integrate(P, R)
        50*71 + 3*71^2 + 43*71^3 + O(71^4)
        >>> w.integrate(P, R) + w.integrate(P1, R1)
        O(71^4)

    A simple example, integrating dx:

    Sage

        sage: R.<x> = QQ['x']
        sage: E= HyperellipticCurve(x^3-4*x+4)
        sage: K = Qp(5,10)
        sage: EK = E.change_ring(K)
        sage: P = EK(2, 2)
        sage: Q = EK.teichmuller(P)
        sage: x, y = EK.monsky_washnitzer_gens()
        sage: EK.coleman_integral(x.diff(), P, Q)
        5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10)
        sage: Q[0] - P[0]
        5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10)

    Python

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> E= HyperellipticCurve(x**Integer(3)-Integer(4)*x+Integer(4))
        >>> K = Qp(Integer(5),Integer(10))
        >>> EK = E.change_ring(K)
        >>> P = EK(Integer(2), Integer(2))
        >>> Q = EK.teichmuller(P)
        >>> x, y = EK.monsky_washnitzer_gens()
        >>> EK.coleman_integral(x.diff(), P, Q)
        5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10)
        >>> Q[Integer(0)] - P[Integer(0)]
        5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10)

    Yet another example:

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x*(x-1)*(x+9))
        sage: K = Qp(7,10)
        sage: HK = H.change_ring(K)
        sage: from sage.schemes.hyperelliptic_curves import monsky_washnitzer as mw
        sage: M_frob, forms = mw.matrix_of_frobenius_hyperelliptic(HK)
        sage: w = HK.invariant_differential()
        sage: x,y = HK.monsky_washnitzer_gens()
        sage: f = forms[0]
        sage: S = HK(9,36)
        sage: Q = HK.teichmuller(S)
        sage: P = HK(-1,4)
        sage: b = x*w*w._coeff.parent()(f)
        sage: HK.coleman_integral(b,P,Q)
        7 + 7^2 + 4*7^3 + 5*7^4 + 3*7^5 + 7^6 + 5*7^7 + 3*7^8 + 4*7^9 + 4*7^10 + O(7^11)

    [Python]

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x*(x-Integer(1))*(x+Integer(9)))
        >>> K = Qp(Integer(7),Integer(10))
        >>> HK = H.change_ring(K)
        >>> from sage.schemes.hyperelliptic_curves import monsky_washnitzer as mw
        >>> M_frob, forms = mw.matrix_of_frobenius_hyperelliptic(HK)
        >>> w = HK.invariant_differential()
        >>> x,y = HK.monsky_washnitzer_gens()
        >>> f = forms[Integer(0)]
        >>> S = HK(Integer(9),Integer(36))
        >>> Q = HK.teichmuller(S)
        >>> P = HK(-Integer(1),Integer(4))
        >>> b = x*w*w._coeff.parent()(f)
        >>> HK.coleman_integral(b,P,Q)
        7 + 7^2 + 4*7^3 + 5*7^4 + 3*7^5 + 7^6 + 5*7^7 + 3*7^8 + 4*7^9 + 4*7^10 + O(7^11)

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^3+1)
        sage: K = Qp(5,8)
        sage: HK = H.change_ring(K)
        sage: w = HK.invariant_differential()
        sage: P = HK(0,1)
        sage: Q = HK(5, 1 + 3*5^3 + 2*5^4 + 2*5^5 + 3*5^7)
        sage: x,y = HK.monsky_washnitzer_gens()
        sage: (2*y*w).coleman_integral(P,Q)
        5 + O(5^9)
        sage: xloc,yloc,zloc = HK.local_analytic_interpolation(P,Q)
        sage: I2 = (xloc.derivative()/(2*yloc)).integral()
        sage: I2.polynomial()(1) - I2(0)
        3*5 + 2*5^2 + 2*5^3 + 5^4 + 4*5^6 + 5^7 + O(5^9)
        sage: HK.coleman_integral(w,P,Q)
        3*5 + 2*5^2 + 2*5^3 + 5^4 + 4*5^6 + 5^7 + O(5^9)

    Python

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(3)+Integer(1))
        >>> K = Qp(Integer(5),Integer(8))
        >>> HK = H.change_ring(K)
        >>> w = HK.invariant_differential()
        >>> P = HK(Integer(0),Integer(1))
        >>> Q = HK(Integer(5), Integer(1) + Integer(3)*Integer(5)**Integer(3) + Integer(2)*Integer(5)**Integer(4) + Integer(2)*Integer(5)**Integer(5) + Integer(3)*Integer(5)**Integer(7))
        >>> x,y = HK.monsky_washnitzer_gens()
        >>> (Integer(2)*y*w).coleman_integral(P,Q)
        5 + O(5^9)
        >>> xloc,yloc,zloc = HK.local_analytic_interpolation(P,Q)
        >>> I2 = (xloc.derivative()/(Integer(2)*yloc)).integral()
        >>> I2.polynomial()(Integer(1)) - I2(Integer(0))
        3*5 + 2*5^2 + 2*5^3 + 5^4 + 4*5^6 + 5^7 + O(5^9)
        >>> HK.coleman_integral(w,P,Q)
        3*5 + 2*5^2 + 2*5^3 + 5^4 + 4*5^6 + 5^7 + O(5^9)

    Integrals involving Weierstrass points:

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^3-10*x+9)
        sage: K = Qp(5,8)
        sage: HK = H.change_ring(K)
        sage: S = HK(1,0)
        sage: P = HK(0,3)
        sage: negP = HK(0,-3)
        sage: T = HK(1,0,0)
        sage: w = HK.invariant_differential()
        sage: x,y = HK.monsky_washnitzer_gens()
        sage: HK.coleman_integral(w*x^3,S,T)
        0
        sage: HK.coleman_integral(w*x^3,T,S)
        0
        sage: HK.coleman_integral(w,S,P)
        2*5^2 + 5^4 + 5^5 + 3*5^6 + 3*5^7 + 2*5^8 + O(5^9)
        sage: HK.coleman_integral(w,T,P)
        2*5^2 + 5^4 + 5^5 + 3*5^6 + 3*5^7 + 2*5^8 + O(5^9)
        sage: HK.coleman_integral(w*x^3,T,P)
        5^2 + 2*5^3 + 3*5^6 + 3*5^7 + O(5^8)
        sage: HK.coleman_integral(w*x^3,S,P)
        5^2 + 2*5^3 + 3*5^6 + 3*5^7 + O(5^8)
        sage: HK.coleman_integral(w, P, negP, algorithm='teichmuller')
        5^2 + 4*5^3 + 2*5^4 + 2*5^5 + 3*5^6 + 2*5^7 + 4*5^8 + O(5^9)
        sage: HK.coleman_integral(w, P, negP)
        5^2 + 4*5^3 + 2*5^4 + 2*5^5 + 3*5^6 + 2*5^7 + 4*5^8 + O(5^9)

    [Python]

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(3)-Integer(10)*x+Integer(9))
        >>> K = Qp(Integer(5),Integer(8))
        >>> HK = H.change_ring(K)
        >>> S = HK(Integer(1),Integer(0))
        >>> P = HK(Integer(0),Integer(3))
        >>> negP = HK(Integer(0),-Integer(3))
        >>> T = HK(Integer(1),Integer(0),Integer(0))
        >>> w = HK.invariant_differential()
        >>> x,y = HK.monsky_washnitzer_gens()
        >>> HK.coleman_integral(w*x**Integer(3),S,T)
        0
        >>> HK.coleman_integral(w*x**Integer(3),T,S)
        0
        >>> HK.coleman_integral(w,S,P)
        2*5^2 + 5^4 + 5^5 + 3*5^6 + 3*5^7 + 2*5^8 + O(5^9)
        >>> HK.coleman_integral(w,T,P)
        2*5^2 + 5^4 + 5^5 + 3*5^6 + 3*5^7 + 2*5^8 + O(5^9)
        >>> HK.coleman_integral(w*x**Integer(3),T,P)
        5^2 + 2*5^3 + 3*5^6 + 3*5^7 + O(5^8)
        >>> HK.coleman_integral(w*x**Integer(3),S,P)
        5^2 + 2*5^3 + 3*5^6 + 3*5^7 + O(5^8)
        >>> HK.coleman_integral(w, P, negP, algorithm='teichmuller')
        5^2 + 4*5^3 + 2*5^4 + 2*5^5 + 3*5^6 + 2*5^7 + 4*5^8 + O(5^9)
        >>> HK.coleman_integral(w, P, negP)
        5^2 + 4*5^3 + 2*5^4 + 2*5^5 + 3*5^6 + 2*5^7 + 4*5^8 + O(5^9)

    AUTHORS:

    - Robert Bradshaw (2007-03)

    - Kiran Kedlaya (2008-05)

    - Jennifer Balakrishnan (2010-02)

  coleman_integral_P_to_S(w, P, S)

    Given a finite Weierstrass point `P` and a point `S` in the same disc, compute the Coleman integral \(\int_P^S w\)

    INPUT:

    - `w`: differential

    - `P`: Weierstrass point

    - `S`: point in the same disc of `P` (`S` is defined over an extension of \(\QQ_p\); coordinates of `S` are given in terms of uniformizer \(a\))

    OUTPUT:

    Coleman integral \(\int_P^S w\) in terms of \(a\)

    EXAMPLES:

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^3-10*x+9)
        sage: K = Qp(5,4)
        sage: HK = H.change_ring(K)
        sage: P = HK(1,0)
        sage: J.<a> = K.extension(x^10-5)
        sage: HJ  = H.change_ring(J)
        sage: S = HK.get_boundary_point(HJ,P)
        sage: x,y = HK.monsky_washnitzer_gens()
        sage: S[0]-P[0] == HK.coleman_integral_P_to_S(x.diff(),P,S)
        True
        sage: HK.coleman_integral_P_to_S(HK.invariant_differential(),P,S) == HK.P_to_S(P,S)[0]
        True

    Python

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(3)-Integer(10)*x+Integer(9))
        >>> K = Qp(Integer(5),Integer(4))
        >>> HK = H.change_ring(K)
        >>> P = HK(Integer(1),Integer(0))
        >>> J = K.extension(x**Integer(10)-Integer(5), names=('a',)); (a,) = J._first_ngens(1)
        >>> HJ  = H.change_ring(J)
        >>> S = HK.get_boundary_point(HJ,P)
        >>> x,y = HK.monsky_washnitzer_gens()
        >>> S[Integer(0)]-P[Integer(0)] == HK.coleman_integral_P_to_S(x.diff(),P,S)
        True
        >>> HK.coleman_integral_P_to_S(HK.invariant_differential(),P,S) == HK.P_to_S(P,S)[Integer(0)]
        True

    AUTHOR:

    - Jennifer Balakrishnan

  coleman_integral_S_to_Q(w, S, Q)

    Compute the Coleman integral \(\int_S^Q w\)

    one should be able to feed ``S,Q`` into coleman_integral, but currently that segfaults

    INPUT:

    - `w`: a differential

    - `S`: a point with coordinates in an extension of \(\QQ_p\)

    - `Q`: a non-Weierstrass point defined over \(\QQ_p\)

    OUTPUT:

    the Coleman integral \(\int_S^Q w\)

    EXAMPLES:

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^3-10*x+9)
        sage: K = Qp(5,6)
        sage: HK = H.change_ring(K)
        sage: J.<a> = K.extension(x^20-5)
        sage: HJ  = H.change_ring(J)
        sage: x,y = HK.monsky_washnitzer_gens()
        sage: P = HK(1,0)
        sage: Q = HK(0,3)
        sage: S = HK.get_boundary_point(HJ,P)
        sage: P_to_S = HK.coleman_integral_P_to_S(y.diff(),P,S)
        sage: S_to_Q = HJ.coleman_integral_S_to_Q(y.diff(),S,Q)
        sage: P_to_S  + S_to_Q
        3 + O(a^119)
        sage: HK.coleman_integral(y.diff(),P,Q)
        3 + O(5^6)

    Python

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(3)-Integer(10)*x+Integer(9))
        >>> K = Qp(Integer(5),Integer(6))
        >>> HK = H.change_ring(K)
        >>> J = K.extension(x**Integer(20)-Integer(5), names=('a',)); (a,) = J._first_ngens(1)
        >>> HJ  = H.change_ring(J)
        >>> x,y = HK.monsky_washnitzer_gens()
        >>> P = HK(Integer(1),Integer(0))
        >>> Q = HK(Integer(0),Integer(3))
        >>> S = HK.get_boundary_point(HJ,P)
        >>> P_to_S = HK.coleman_integral_P_to_S(y.diff(),P,S)
        >>> S_to_Q = HJ.coleman_integral_S_to_Q(y.diff(),S,Q)
        >>> P_to_S  + S_to_Q
        3 + O(a^119)
        >>> HK.coleman_integral(y.diff(),P,Q)
        3 + O(5^6)

    AUTHOR:

    - Jennifer Balakrishnan

  coleman_integral_from_weierstrass_via_boundary(w, P, Q, d)

    Computes the Coleman integral \(\int_P^Q w\) via a boundary point in the disc of `P`, defined over a degree `d` extension

    INPUT:

    - `w`: a differential

    - `P`: a Weierstrass point

    - `Q`: a non-Weierstrass point

    - `d`: degree of extension where coordinates of boundary point lie

    OUTPUT:

    the Coleman integral \(\int_P^Q w\), written in terms of the uniformizer \(a\) of the degree \(d\) extension

    EXAMPLES:

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^3-10*x+9)
        sage: K = Qp(5,6)
        sage: HK = H.change_ring(K)
        sage: P = HK(1,0)
        sage: Q = HK(0,3)
        sage: x,y = HK.monsky_washnitzer_gens()
        sage: HK.coleman_integral_from_weierstrass_via_boundary(y.diff(),P,Q,20)
        3 + O(a^119)
        sage: HK.coleman_integral(y.diff(),P,Q)
        3 + O(5^6)
        sage: w = HK.invariant_differential()
        sage: HK.coleman_integral_from_weierstrass_via_boundary(w,P,Q,20)
        2*a^40 + a^80 + a^100 + O(a^105)
        sage: HK.coleman_integral(w,P,Q)
        2*5^2 + 5^4 + 5^5 + 3*5^6 + O(5^7)

    Python

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(3)-Integer(10)*x+Integer(9))
        >>> K = Qp(Integer(5),Integer(6))
        >>> HK = H.change_ring(K)
        >>> P = HK(Integer(1),Integer(0))
        >>> Q = HK(Integer(0),Integer(3))
        >>> x,y = HK.monsky_washnitzer_gens()
        >>> HK.coleman_integral_from_weierstrass_via_boundary(y.diff(),P,Q,Integer(20))
        3 + O(a^119)
        >>> HK.coleman_integral(y.diff(),P,Q)
        3 + O(5^6)
        >>> w = HK.invariant_differential()
        >>> HK.coleman_integral_from_weierstrass_via_boundary(w,P,Q,Integer(20))
        2*a^40 + a^80 + a^100 + O(a^105)
        >>> HK.coleman_integral(w,P,Q)
        2*5^2 + 5^4 + 5^5 + 3*5^6 + O(5^7)

    AUTHOR:

    - Jennifer Balakrishnan

  coleman_integrals_on_basis(P, Q, algorithm=None)

    Computes the Coleman integrals \(\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}\)

    INPUT:

    - P point on self

    - Q point on self

    - algorithm (optional) = None (uses Frobenius) or teichmuller (uses Teichmuller points)

    OUTPUT:

    the Coleman integrals \(\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}\)

    EXAMPLES:

    Sage

        sage: K = pAdicField(11, 5)
        sage: x = polygen(K)
        sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16)
        sage: P = C.lift_x(2)
        sage: Q = C.lift_x(3)
        sage: C.coleman_integrals_on_basis(P, Q)
        (9*11^2 + 7*11^3 + 5*11^4 + O(11^5), 11 + 3*11^2 + 7*11^3 + 11^4 + O(11^5), 10*11 + 11^2 + 5*11^3 + 5*11^4 + O(11^5), 3 + 9*11^2 + 6*11^3 + 11^4 + O(11^5))
        sage: C.coleman_integrals_on_basis(P, Q, algorithm='teichmuller')
        (9*11^2 + 7*11^3 + 5*11^4 + O(11^5), 11 + 3*11^2 + 7*11^3 + 11^4 + O(11^5), 10*11 + 11^2 + 5*11^3 + 5*11^4 + O(11^5), 3 + 9*11^2 + 6*11^3 + 11^4 + O(11^5))

    Python

        >>> from sage.all import *
        >>> K = pAdicField(Integer(11), Integer(5))
        >>> x = polygen(K)
        >>> C = HyperellipticCurve(x**Integer(5) + Integer(33)/Integer(16)*x**Integer(4) + Integer(3)/Integer(4)*x**Integer(3) + Integer(3)/Integer(8)*x**Integer(2) - Integer(1)/Integer(4)*x + Integer(1)/Integer(16))
        >>> P = C.lift_x(Integer(2))
        >>> Q = C.lift_x(Integer(3))
        >>> C.coleman_integrals_on_basis(P, Q)
        (9*11^2 + 7*11^3 + 5*11^4 + O(11^5), 11 + 3*11^2 + 7*11^3 + 11^4 + O(11^5), 10*11 + 11^2 + 5*11^3 + 5*11^4 + O(11^5), 3 + 9*11^2 + 6*11^3 + 11^4 + O(11^5))
        >>> C.coleman_integrals_on_basis(P, Q, algorithm='teichmuller')
        (9*11^2 + 7*11^3 + 5*11^4 + O(11^5), 11 + 3*11^2 + 7*11^3 + 11^4 + O(11^5), 10*11 + 11^2 + 5*11^3 + 5*11^4 + O(11^5), 3 + 9*11^2 + 6*11^3 + 11^4 + O(11^5))

    Sage

        sage: K = pAdicField(11,5)
        sage: x = polygen(K)
        sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16)
        sage: P = C(11^-2, 10*11^-5 + 10*11^-4 + 10*11^-3 + 2*11^-2 + 10*11^-1)
        sage: Q = C(3*11^-2, 11^-5 + 11^-3 + 10*11^-2 + 7*11^-1)
        sage: C.coleman_integrals_on_basis(P, Q)
        (6*11^3 + 3*11^4 + 8*11^5 + 4*11^6 + 9*11^7 + O(11^8), 11 + 10*11^2 + 8*11^3 + 7*11^4 + 5*11^5 + O(11^6), 6*11^-1 + 2 + 6*11 + 3*11^3 + O(11^4), 9*11^-3 + 9*11^-2 + 9*11^-1 + 2*11 + O(11^2))

    [Python]

        >>> from sage.all import *
        >>> K = pAdicField(Integer(11),Integer(5))
        >>> x = polygen(K)
        >>> C = HyperellipticCurve(x**Integer(5) + Integer(33)/Integer(16)*x**Integer(4) + Integer(3)/Integer(4)*x**Integer(3) + Integer(3)/Integer(8)*x**Integer(2) - Integer(1)/Integer(4)*x + Integer(1)/Integer(16))
        >>> P = C(Integer(11)**-Integer(2), Integer(10)*Integer(11)**-Integer(5) + Integer(10)*Integer(11)**-Integer(4) + Integer(10)*Integer(11)**-Integer(3) + Integer(2)*Integer(11)**-Integer(2) + Integer(10)*Integer(11)**-Integer(1))
        >>> Q = C(Integer(3)*Integer(11)**-Integer(2), Integer(11)**-Integer(5) + Integer(11)**-Integer(3) + Integer(10)*Integer(11)**-Integer(2) + Integer(7)*Integer(11)**-Integer(1))
        >>> C.coleman_integrals_on_basis(P, Q)
        (6*11^3 + 3*11^4 + 8*11^5 + 4*11^6 + 9*11^7 + O(11^8), 11 + 10*11^2 + 8*11^3 + 7*11^4 + 5*11^5 + O(11^6), 6*11^-1 + 2 + 6*11 + 3*11^3 + O(11^4), 9*11^-3 + 9*11^-2 + 9*11^-1 + 2*11 + O(11^2))

    Sage

        sage: R = C(0,1/4)
        sage: a = C.coleman_integrals_on_basis(P,R)  # long time (7s on sage.math, 2011)
        sage: b = C.coleman_integrals_on_basis(R,Q)  # long time (9s on sage.math, 2011)
        sage: c = C.coleman_integrals_on_basis(P,Q)  # long time
        sage: a+b == c  # long time
        True

    Python

        >>> from sage.all import *
        >>> R = C(Integer(0),Integer(1)/Integer(4))
        >>> a = C.coleman_integrals_on_basis(P,R)  # long time (7s on sage.math, 2011)
        >>> b = C.coleman_integrals_on_basis(R,Q)  # long time (9s on sage.math, 2011)
        >>> c = C.coleman_integrals_on_basis(P,Q)  # long time
        >>> a+b == c  # long time
        True

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^3-10*x+9)
        sage: K = Qp(5,8)
        sage: HK = H.change_ring(K)
        sage: S = HK(1,0)
        sage: P = HK(0,3)
        sage: T = HK(1,0,0)
        sage: Q = HK.lift_x(5^-2)
        sage: R = HK.lift_x(4*5^-2)
        sage: HK.coleman_integrals_on_basis(S,P)
        (2*5^2 + 5^4 + 5^5 + 3*5^6 + 3*5^7 + 2*5^8 + O(5^9), 5 + 2*5^2 + 4*5^3 + 2*5^4 + 3*5^6 + 4*5^7 + 2*5^8 + O(5^9))
        sage: HK.coleman_integrals_on_basis(T,P)
        (2*5^2 + 5^4 + 5^5 + 3*5^6 + 3*5^7 + 2*5^8 + O(5^9), 5 + 2*5^2 + 4*5^3 + 2*5^4 + 3*5^6 + 4*5^7 + 2*5^8 + O(5^9))
        sage: HK.coleman_integrals_on_basis(P,S) == -HK.coleman_integrals_on_basis(S,P)
        True
        sage: HK.coleman_integrals_on_basis(S,Q)
        (5 + O(5^4), 4*5^-1 + 4 + 4*5 + 4*5^2 + O(5^3))
        sage: HK.coleman_integrals_on_basis(Q,R)
        (5 + 2*5^2 + 2*5^3 + 2*5^4 + 3*5^5 + 3*5^6 + 3*5^7 + 5^8 + O(5^9), 3*5^-1 + 2*5^4 + 5^5 + 2*5^6 + O(5^7))
        sage: HK.coleman_integrals_on_basis(S,R) == HK.coleman_integrals_on_basis(S,Q) + HK.coleman_integrals_on_basis(Q,R)
        True
        sage: HK.coleman_integrals_on_basis(T,T)
        (0, 0)
        sage: HK.coleman_integrals_on_basis(S,T)
        (0, 0)

    [Python]

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(3)-Integer(10)*x+Integer(9))
        >>> K = Qp(Integer(5),Integer(8))
        >>> HK = H.change_ring(K)
        >>> S = HK(Integer(1),Integer(0))
        >>> P = HK(Integer(0),Integer(3))
        >>> T = HK(Integer(1),Integer(0),Integer(0))
        >>> Q = HK.lift_x(Integer(5)**-Integer(2))
        >>> R = HK.lift_x(Integer(4)*Integer(5)**-Integer(2))
        >>> HK.coleman_integrals_on_basis(S,P)
        (2*5^2 + 5^4 + 5^5 + 3*5^6 + 3*5^7 + 2*5^8 + O(5^9), 5 + 2*5^2 + 4*5^3 + 2*5^4 + 3*5^6 + 4*5^7 + 2*5^8 + O(5^9))
        >>> HK.coleman_integrals_on_basis(T,P)
        (2*5^2 + 5^4 + 5^5 + 3*5^6 + 3*5^7 + 2*5^8 + O(5^9), 5 + 2*5^2 + 4*5^3 + 2*5^4 + 3*5^6 + 4*5^7 + 2*5^8 + O(5^9))
        >>> HK.coleman_integrals_on_basis(P,S) == -HK.coleman_integrals_on_basis(S,P)
        True
        >>> HK.coleman_integrals_on_basis(S,Q)
        (5 + O(5^4), 4*5^-1 + 4 + 4*5 + 4*5^2 + O(5^3))
        >>> HK.coleman_integrals_on_basis(Q,R)
        (5 + 2*5^2 + 2*5^3 + 2*5^4 + 3*5^5 + 3*5^6 + 3*5^7 + 5^8 + O(5^9), 3*5^-1 + 2*5^4 + 5^5 + 2*5^6 + O(5^7))
        >>> HK.coleman_integrals_on_basis(S,R) == HK.coleman_integrals_on_basis(S,Q) + HK.coleman_integrals_on_basis(Q,R)
        True
        >>> HK.coleman_integrals_on_basis(T,T)
        (0, 0)
        >>> HK.coleman_integrals_on_basis(S,T)
        (0, 0)

    AUTHORS:

    - Robert Bradshaw (2007-03): non-Weierstrass points

    - Jennifer Balakrishnan and Robert Bradshaw (2010-02): Weierstrass points

  coleman_integrals_on_basis_hyperelliptic(P, Q, algorithm=None)

    alias of `coleman_integrals_on_basis()`.

  curve_over_ram_extn(deg)

    Return `self` over \(\QQ_p(p^(1/deg))\).

    INPUT:

    - deg: the degree of the ramified extension

    OUTPUT:

    `self` over \(\QQ_p(p^(1/deg))\)

    EXAMPLES:

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x)
        sage: K = Qp(11,5)
        sage: HK = H.change_ring(K)
        sage: HL = HK.curve_over_ram_extn(2)
        sage: HL
        Hyperelliptic Curve over 11-adic Eisenstein Extension Field in a defined by x^2 - 11 defined by (1 + O(a^10))*y^2 = (1 + O(a^10))*x^5 + (10 + 8*a^2 + 10*a^4 + 10*a^6 + 10*a^8 + O(a^10))*x^3 + (7 + a^2 + O(a^10))*x^2 + (7 + 3*a^2 + O(a^10))*x

    Python

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(5)-Integer(23)*x**Integer(3)+Integer(18)*x**Integer(2)+Integer(40)*x)
        >>> K = Qp(Integer(11),Integer(5))
        >>> HK = H.change_ring(K)
        >>> HL = HK.curve_over_ram_extn(Integer(2))
        >>> HL
        Hyperelliptic Curve over 11-adic Eisenstein Extension Field in a defined by x^2 - 11 defined by (1 + O(a^10))*y^2 = (1 + O(a^10))*x^5 + (10 + 8*a^2 + 10*a^4 + 10*a^6 + 10*a^8 + O(a^10))*x^3 + (7 + a^2 + O(a^10))*x^2 + (7 + 3*a^2 + O(a^10))*x

    AUTHOR:

    - Jennifer Balakrishnan

  find_char_zero_weierstrass_point(Q)

    Given \(Q\) a point on self in a Weierstrass disc, finds the center of the Weierstrass disc (if defined over self.base_ring())

    EXAMPLES:

    Examples for a hyperelliptic curve with odd degree model:

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^3-10*x+9)
        sage: K = Qp(5,8)
        sage: HK = H.change_ring(K)
        sage: P = HK.lift_x(1 + 2*5^2)
        sage: Q = HK.lift_x(5^-2)
        sage: S = HK(1,0)
        sage: T = HK(1,0,0)
        sage: HK.find_char_zero_weierstrass_point(P)
        (1 + O(5^8) : 0 : 1 + O(5^8))
        sage: HK.find_char_zero_weierstrass_point(Q)
        (1 + O(5^8) : 0 : 0)
        sage: HK.find_char_zero_weierstrass_point(S)
        (1 + O(5^8) : 0 : 1 + O(5^8))
        sage: HK.find_char_zero_weierstrass_point(T)
        (1 + O(5^8) : 0 : 0)

    Python

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(3)-Integer(10)*x+Integer(9))
        >>> K = Qp(Integer(5),Integer(8))
        >>> HK = H.change_ring(K)
        >>> P = HK.lift_x(Integer(1) + Integer(2)*Integer(5)**Integer(2))
        >>> Q = HK.lift_x(Integer(5)**-Integer(2))
        >>> S = HK(Integer(1),Integer(0))
        >>> T = HK(Integer(1),Integer(0),Integer(0))
        >>> HK.find_char_zero_weierstrass_point(P)
        (1 + O(5^8) : 0 : 1 + O(5^8))
        >>> HK.find_char_zero_weierstrass_point(Q)
        (1 + O(5^8) : 0 : 0)
        >>> HK.find_char_zero_weierstrass_point(S)
        (1 + O(5^8) : 0 : 1 + O(5^8))
        >>> HK.find_char_zero_weierstrass_point(T)
        (1 + O(5^8) : 0 : 0)

    An example for a hyperelltiptic curve with split model:

    Sage

        sage: H = HyperellipticCurve(x^6+3, x^2+1)
        sage: HK = H.change_ring(K)
        sage: P = HK.lift_x(1+3*5+4*5^2+4*5^3)
        sage: HK.find_char_zero_weierstrass_point(P)
        (1 + 3*5 + 4*5^2 + 4*5^3 + 3*5^4 + 2*5^6 + 4*5^7 + O(5^8) : 4 + 5 + 3*5^2 + 4*5^3 + 2*5^5 + 4*5^6 + 4*5^7 + O(5^8) : 1 + O(5^8))

    [Python]

        >>> from sage.all import *
        >>> H = HyperellipticCurve(x**Integer(6)+Integer(3), x**Integer(2)+Integer(1))
        >>> HK = H.change_ring(K)
        >>> P = HK.lift_x(Integer(1)+Integer(3)*Integer(5)+Integer(4)*Integer(5)**Integer(2)+Integer(4)*Integer(5)**Integer(3))
        >>> HK.find_char_zero_weierstrass_point(P)
        (1 + 3*5 + 4*5^2 + 4*5^3 + 3*5^4 + 2*5^6 + 4*5^7 + O(5^8) : 4 + 5 + 3*5^2 + 4*5^3 + 2*5^5 + 4*5^6 + 4*5^7 + O(5^8) : 1 + O(5^8))

    The input needs to be a point in a Weierstrass disc, otherwise an error is returned:

    Sage

        sage: Q = HK.point([1,1,0])
        sage: HK.find_char_zero_weierstrass_point(Q)
        Traceback (most recent call last):
        ...
        ValueError: (1 + O(5^8) : 1 + O(5^8) : 0) is not in a Weierstrass disc.

    Python

        >>> from sage.all import *
        >>> Q = HK.point([Integer(1),Integer(1),Integer(0)])
        >>> HK.find_char_zero_weierstrass_point(Q)
        Traceback (most recent call last):
        ...
        ValueError: (1 + O(5^8) : 1 + O(5^8) : 0) is not in a Weierstrass disc.

    AUTHOR:

    - Jennifer Balakrishnan

  frobenius(P=None)

    Returns the \(p\)-th power lift of Frobenius of \(P\)

    EXAMPLES:

    Sage

        sage: K = Qp(11, 5)
        sage: R.<x> = K[]
        sage: E = HyperellipticCurve(x^5 - 21*x - 20)
        sage: P = E.lift_x(2)
        sage: E.frobenius(P)
        (2 + 10*11 + 5*11^2 + 11^3 + O(11^5) : 6 + 11 + 8*11^2 + 8*11^3 + 10*11^4 + O(11^5) : 1 + O(11^5))
        sage: Q = E.teichmuller(P); Q
        (2 + 10*11 + 4*11^2 + 9*11^3 + 11^4 + O(11^5) : 6 + 11 + 4*11^2 + 9*11^3 + 4*11^4 + O(11^5) : 1 + O(11^5))
        sage: E.frobenius(Q)
        (2 + 10*11 + 4*11^2 + 9*11^3 + 11^4 + O(11^5) : 6 + 11 + 4*11^2 + 9*11^3 + 4*11^4 + O(11^5) : 1 + O(11^5))

    Python

        >>> from sage.all import *
        >>> K = Qp(Integer(11), Integer(5))
        >>> R = K['x']; (x,) = R._first_ngens(1)
        >>> E = HyperellipticCurve(x**Integer(5) - Integer(21)*x - Integer(20))
        >>> P = E.lift_x(Integer(2))
        >>> E.frobenius(P)
        (2 + 10*11 + 5*11^2 + 11^3 + O(11^5) : 6 + 11 + 8*11^2 + 8*11^3 + 10*11^4 + O(11^5) : 1 + O(11^5))
        >>> Q = E.teichmuller(P); Q
        (2 + 10*11 + 4*11^2 + 9*11^3 + 11^4 + O(11^5) : 6 + 11 + 4*11^2 + 9*11^3 + 4*11^4 + O(11^5) : 1 + O(11^5))
        >>> E.frobenius(Q)
        (2 + 10*11 + 4*11^2 + 9*11^3 + 11^4 + O(11^5) : 6 + 11 + 4*11^2 + 9*11^3 + 4*11^4 + O(11^5) : 1 + O(11^5))

    Sage

        sage: R.<x> = QQ[]
        sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x)
        sage: Q = H(0,0)
        sage: u,v = H.local_coord(Q,prec=100)
        sage: K = Qp(11,5)
        sage: L.<a> = K.extension(x^20-11)
        sage: HL = H.change_ring(L)
        sage: S = HL(u(a),v(a))
        sage: HL.frobenius(S)
        (8*a^22 + 10*a^42 + 4*a^44 + 2*a^46 + 9*a^48 + 8*a^50 + a^52 + 7*a^54 +
        7*a^56 + 5*a^58 + 9*a^62 + 5*a^64 + a^66 + 6*a^68 + a^70 + 6*a^74 +
        2*a^76 + 2*a^78 + 4*a^82 + 5*a^84 + 2*a^86 + 7*a^88 + a^90 + 6*a^92 +
        a^96 + 5*a^98 + 2*a^102 + 2*a^106 + 6*a^108 + 8*a^110 + 3*a^112 +
        a^114 + 8*a^116 + 10*a^118 + 3*a^120 + O(a^122) :
        a^11 + 7*a^33 + 7*a^35 + 4*a^37 + 6*a^39 + 9*a^41 + 8*a^43 + 8*a^45 +
        a^47 + 7*a^51 + 4*a^53 + 5*a^55 + a^57 + 7*a^59 + 5*a^61 + 9*a^63 +
        4*a^65 + 10*a^69 + 3*a^71 + 2*a^73 + 9*a^75 + 10*a^77 + 6*a^79 +
        10*a^81 + 7*a^85 + a^87 + 4*a^89 + 8*a^91 + a^93 + 8*a^95 + 2*a^97 +
        7*a^99 + a^101 + 3*a^103 + 6*a^105 + 7*a^107 + 4*a^109 + O(a^111) :
        1 + O(a^100))

    [Python]

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(5)-Integer(23)*x**Integer(3)+Integer(18)*x**Integer(2)+Integer(40)*x)
        >>> Q = H(Integer(0),Integer(0))
        >>> u,v = H.local_coord(Q,prec=Integer(100))
        >>> K = Qp(Integer(11),Integer(5))
        >>> L = K.extension(x**Integer(20)-Integer(11), names=('a',)); (a,) = L._first_ngens(1)
        >>> HL = H.change_ring(L)
        >>> S = HL(u(a),v(a))
        >>> HL.frobenius(S)
        (8*a^22 + 10*a^42 + 4*a^44 + 2*a^46 + 9*a^48 + 8*a^50 + a^52 + 7*a^54 +
        7*a^56 + 5*a^58 + 9*a^62 + 5*a^64 + a^66 + 6*a^68 + a^70 + 6*a^74 +
        2*a^76 + 2*a^78 + 4*a^82 + 5*a^84 + 2*a^86 + 7*a^88 + a^90 + 6*a^92 +
        a^96 + 5*a^98 + 2*a^102 + 2*a^106 + 6*a^108 + 8*a^110 + 3*a^112 +
        a^114 + 8*a^116 + 10*a^118 + 3*a^120 + O(a^122) :
        a^11 + 7*a^33 + 7*a^35 + 4*a^37 + 6*a^39 + 9*a^41 + 8*a^43 + 8*a^45 +
        a^47 + 7*a^51 + 4*a^53 + 5*a^55 + a^57 + 7*a^59 + 5*a^61 + 9*a^63 +
        4*a^65 + 10*a^69 + 3*a^71 + 2*a^73 + 9*a^75 + 10*a^77 + 6*a^79 +
        10*a^81 + 7*a^85 + a^87 + 4*a^89 + 8*a^91 + a^93 + 8*a^95 + 2*a^97 +
        7*a^99 + a^101 + 3*a^103 + 6*a^105 + 7*a^107 + 4*a^109 + O(a^111) :
        1 + O(a^100))

    AUTHORS:

    - Robert Bradshaw and Jennifer Balakrishnan (2010-02)

  get_boundary_point(curve_over_extn, P)

    Given self over an extension field, find a point in the disc of \(P\) near the boundary

    INPUT:

    - curve_over_extn: self over a totally ramified extension

    - P: Weierstrass point

    OUTPUT:

    a point in the disc of \(P\) near the boundary

    EXAMPLES:

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^3-10*x+9)
        sage: K = Qp(3,6)
        sage: HK = H.change_ring(K)
        sage: P = HK(1,0)
        sage: J.<a> = K.extension(x^30-3)
        sage: HJ  = H.change_ring(J)
        sage: S = HK.get_boundary_point(HJ,P)
        sage: S
        (1 + 2*a^2 + 2*a^6 + 2*a^18 + a^32 + a^34 + a^36 + 2*a^38 + 2*a^40 + a^42 + 2*a^44 + a^48 + 2*a^50 + 2*a^52 + a^54 + a^56 + 2*a^60 + 2*a^62 + a^70 + 2*a^72 + a^76 + 2*a^78 + a^82 + a^88 + a^96 + 2*a^98 + 2*a^102 + a^104 + 2*a^106 + a^108 + 2*a^110 + a^112 + 2*a^116 + a^126 + 2*a^130 + 2*a^132 + a^144 + 2*a^148 + 2*a^150 + a^152 + 2*a^154 + a^162 + a^164 + a^166 + a^168 + a^170 + a^176 + a^178 + O(a^180) : a + O(a^180) : 1 + O(a^180))

    Python

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(3)-Integer(10)*x+Integer(9))
        >>> K = Qp(Integer(3),Integer(6))
        >>> HK = H.change_ring(K)
        >>> P = HK(Integer(1),Integer(0))
        >>> J = K.extension(x**Integer(30)-Integer(3), names=('a',)); (a,) = J._first_ngens(1)
        >>> HJ  = H.change_ring(J)
        >>> S = HK.get_boundary_point(HJ,P)
        >>> S
        (1 + 2*a^2 + 2*a^6 + 2*a^18 + a^32 + a^34 + a^36 + 2*a^38 + 2*a^40 + a^42 + 2*a^44 + a^48 + 2*a^50 + 2*a^52 + a^54 + a^56 + 2*a^60 + 2*a^62 + a^70 + 2*a^72 + a^76 + 2*a^78 + a^82 + a^88 + a^96 + 2*a^98 + 2*a^102 + a^104 + 2*a^106 + a^108 + 2*a^110 + a^112 + 2*a^116 + a^126 + 2*a^130 + 2*a^132 + a^144 + 2*a^148 + 2*a^150 + a^152 + 2*a^154 + a^162 + a^164 + a^166 + a^168 + a^170 + a^176 + a^178 + O(a^180) : a + O(a^180) : 1 + O(a^180))

    AUTHOR:

    - Jennifer Balakrishnan

  is_in_weierstrass_disc(P)

    Checks if \(P\) is in a Weierstrass disc.

    EXAMPLES:

    For odd degree models, the points with \(y\)-coordinate equivalent to zero are contained in a Weierstrass discs:

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^3-10*x+9)
        sage: K = Qp(5,8)
        sage: HK = H.change_ring(K)
        sage: P = HK(0,3)
        sage: HK.is_in_weierstrass_disc(P)
        False
        sage: Q = HK(1,0,0)
        sage: HK.is_in_weierstrass_disc(Q)
        True
        sage: S = HK(1,0)
        sage: HK.is_in_weierstrass_disc(S)
        True
        sage: T = HK.lift_x(1+3*5^2); T
        (1 + 3*5^2 + O(5^8) : 3*5 + 4*5^2 + 5^4 + 3*5^5 + 5^6 + O(5^7) : 1 + O(5^8))
        sage: HK.is_in_weierstrass_disc(T)
        True

    Python

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(3)-Integer(10)*x+Integer(9))
        >>> K = Qp(Integer(5),Integer(8))
        >>> HK = H.change_ring(K)
        >>> P = HK(Integer(0),Integer(3))
        >>> HK.is_in_weierstrass_disc(P)
        False
        >>> Q = HK(Integer(1),Integer(0),Integer(0))
        >>> HK.is_in_weierstrass_disc(Q)
        True
        >>> S = HK(Integer(1),Integer(0))
        >>> HK.is_in_weierstrass_disc(S)
        True
        >>> T = HK.lift_x(Integer(1)+Integer(3)*Integer(5)**Integer(2)); T
        (1 + 3*5^2 + O(5^8) : 3*5 + 4*5^2 + 5^4 + 3*5^5 + 5^6 + O(5^7) : 1 + O(5^8))
        >>> HK.is_in_weierstrass_disc(T)
        True

    The method is also implemented for general models of hyperelliptic curves:

    Sage

        sage: H = HyperellipticCurve(x^6+3, x^2+1)
        sage: HK = H.change_ring(K)
        sage: P = HK.lift_x(1+3*5+4*5^2+4*5^3); P
        (1 + 3*5 + 4*5^2 + 4*5^3 + O(5^8) : 4 + 5 + 4*5^2 + 5^3 + 3*5^4 + 5^5 + O(5^6) : 1 + O(5^8))
        sage: HK.is_in_weierstrass_disc(P)
        True

    [Python]

        >>> from sage.all import *
        >>> H = HyperellipticCurve(x**Integer(6)+Integer(3), x**Integer(2)+Integer(1))
        >>> HK = H.change_ring(K)
        >>> P = HK.lift_x(Integer(1)+Integer(3)*Integer(5)+Integer(4)*Integer(5)**Integer(2)+Integer(4)*Integer(5)**Integer(3)); P
        (1 + 3*5 + 4*5^2 + 4*5^3 + O(5^8) : 4 + 5 + 4*5^2 + 5^3 + 3*5^4 + 5^5 + O(5^6) : 1 + O(5^8))
        >>> HK.is_in_weierstrass_disc(P)
        True

    Note that \(y = - y - h(x)\) for Weierstrass points. We check that this relation is satisfied for the point above (mod p):

    Sage

        sage: f,h = H.hyperelliptic_polynomials()
        sage: (2*P[1] + h(P[0])).valuation() > 0
        True

    Python

        >>> from sage.all import *
        >>> f,h = H.hyperelliptic_polynomials()
        >>> (Integer(2)*P[Integer(1)] + h(P[Integer(0)])).valuation() > Integer(0)
        True

    AUTHOR:

    - Jennifer Balakrishnan (2010-02)

  is_same_disc(P, Q)

    Checks if \(P,Q\) are in same residue disc

    EXAMPLES:

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^3-10*x+9)
        sage: K = Qp(5,8)
        sage: HK = H.change_ring(K)
        sage: P = HK.lift_x(1 + 2*5^2)
        sage: Q = HK.lift_x(5^-2)
        sage: S = HK(1,0)
        sage: HK.is_same_disc(P,Q)
        False
        sage: HK.is_same_disc(P,S)
        True
        sage: HK.is_same_disc(Q,S)
        False

    Python

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(3)-Integer(10)*x+Integer(9))
        >>> K = Qp(Integer(5),Integer(8))
        >>> HK = H.change_ring(K)
        >>> P = HK.lift_x(Integer(1) + Integer(2)*Integer(5)**Integer(2))
        >>> Q = HK.lift_x(Integer(5)**-Integer(2))
        >>> S = HK(Integer(1),Integer(0))
        >>> HK.is_same_disc(P,Q)
        False
        >>> HK.is_same_disc(P,S)
        True
        >>> HK.is_same_disc(Q,S)
        False

  local_analytic_interpolation(P, Q)

    For points `P`, `Q` in the same residue disc, construct an interpolation from `P` to `Q` (in weighted homogeneous coordinates) in a power series in the local parameter \(t\), with precision equal to the \(p\)-adic precision of the underlying ring.

    INPUT:

    - `P` and `Q` points on `self` in the same residue disc

    OUTPUT:

    Returns a point \(X(t) = ( x(t) : y(t) : z(t) )\) such that:

    1. \(X(0) = P\) and \(X(1) = Q\) if \(P, Q\) are not in the infinite disc

    2. \(X(P[1]/P[0]^(g+1)) = P\) and \(X(Q[1]/Q[0]^(g+1)) = Q\) if \(P, Q\) are in the infinite disc

    EXAMPLES:

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^3-10*x+9)
        sage: K = Qp(5,8)
        sage: HK = H.change_ring(K)

    Python

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(3)-Integer(10)*x+Integer(9))
        >>> K = Qp(Integer(5),Integer(8))
        >>> HK = H.change_ring(K)

    A non-Weierstrass disc:

    Sage

        sage: P = HK(0,3)
        sage: Q = HK(5, 3 + 3*5^2 + 2*5^3 + 3*5^4 + 2*5^5 + 2*5^6 + 3*5^7 + O(5^8))
        sage: x,y,z, = HK.local_analytic_interpolation(P,Q)
        sage: x(0) == P[0], x(1) == Q[0], y(0) == P[1], y.polynomial()(1) == Q[1]
        (True, True, True, True)

    [Python]

        >>> from sage.all import *
        >>> P = HK(Integer(0),Integer(3))
        >>> Q = HK(Integer(5), Integer(3) + Integer(3)*Integer(5)**Integer(2) + Integer(2)*Integer(5)**Integer(3) + Integer(3)*Integer(5)**Integer(4) + Integer(2)*Integer(5)**Integer(5) + Integer(2)*Integer(5)**Integer(6) + Integer(3)*Integer(5)**Integer(7) + O(Integer(5)**Integer(8)))
        >>> x,y,z, = HK.local_analytic_interpolation(P,Q)
        >>> x(Integer(0)) == P[Integer(0)], x(Integer(1)) == Q[Integer(0)], y(Integer(0)) == P[Integer(1)], y.polynomial()(Integer(1)) == Q[Integer(1)]
        (True, True, True, True)

    A finite Weierstrass disc:

    Sage

        sage: P = HK.lift_x(1 + 2*5^2)
        sage: Q = HK.lift_x(1 + 3*5^2)
        sage: x,y,z = HK.local_analytic_interpolation(P,Q)
        sage: x(0) == P[0], x.polynomial()(1) == Q[0], y(0) == P[1], y(1) == Q[1]
        (True, True, True, True)

    Python

        >>> from sage.all import *
        >>> P = HK.lift_x(Integer(1) + Integer(2)*Integer(5)**Integer(2))
        >>> Q = HK.lift_x(Integer(1) + Integer(3)*Integer(5)**Integer(2))
        >>> x,y,z = HK.local_analytic_interpolation(P,Q)
        >>> x(Integer(0)) == P[Integer(0)], x.polynomial()(Integer(1)) == Q[Integer(0)], y(Integer(0)) == P[Integer(1)], y(Integer(1)) == Q[Integer(1)]
        (True, True, True, True)

    The infinite disc:

    Sage

        sage: g = HK.genus()
        sage: P = HK.lift_x(5^-2)
        sage: Q = HK.lift_x(4*5^-2)
        sage: x,y,z = HK.local_analytic_interpolation(P,Q)
        sage: x = x/z
        sage: y = y/z^(g+1)
        sage: x(P[1]/P[0]^(g+1)) == P[0]
        True
        sage: x(Q[1]/Q[0]^(g+1)) == Q[0]
        True
        sage: y(P[1]/P[0]^(g+1)) == P[1]
        True
        sage: y(Q[1]/Q[0]^(g+1)) == Q[1]
        True

    [Python]

        >>> from sage.all import *
        >>> g = HK.genus()
        >>> P = HK.lift_x(Integer(5)**-Integer(2))
        >>> Q = HK.lift_x(Integer(4)*Integer(5)**-Integer(2))
        >>> x,y,z = HK.local_analytic_interpolation(P,Q)
        >>> x = x/z
        >>> y = y/z**(g+Integer(1))
        >>> x(P[Integer(1)]/P[Integer(0)]**(g+Integer(1))) == P[Integer(0)]
        True
        >>> x(Q[Integer(1)]/Q[Integer(0)]**(g+Integer(1))) == Q[Integer(0)]
        True
        >>> y(P[Integer(1)]/P[Integer(0)]**(g+Integer(1))) == P[Integer(1)]
        True
        >>> y(Q[Integer(1)]/Q[Integer(0)]**(g+Integer(1))) == Q[Integer(1)]
        True

    An error if points are not in the same disc:

    Sage

        sage: x,y,z = HK.local_analytic_interpolation(P,HK(1,0))
        Traceback (most recent call last):
        ...
        ValueError: (5^-2 + O(5^6) : 4*5^-3 + 4*5^-2 + 4*5^-1 + 4 + 4*5 + 3*5^3 + 5^4 + O(5^5) : 1 + O(5^8)) and (1 + O(5^8) : 0 : 1 + O(5^8)) are not in the same residue disc

    Python

        >>> from sage.all import *
        >>> x,y,z = HK.local_analytic_interpolation(P,HK(Integer(1),Integer(0)))
        Traceback (most recent call last):
        ...
        ValueError: (5^-2 + O(5^6) : 4*5^-3 + 4*5^-2 + 4*5^-1 + 4 + 4*5 + 3*5^3 + 5^4 + O(5^5) : 1 + O(5^8)) and (1 + O(5^8) : 0 : 1 + O(5^8)) are not in the same residue disc

    AUTHORS:

    - Robert Bradshaw (2007-03)

    - Jennifer Balakrishnan (2010-02)

    - Sabrina Kunzweiler, Gareth Ma, Giacomo Pope (2024): adapt to smooth model

  newton_sqrt(f, x0, prec)

    Takes the square root of the power series \(f\) by Newton’s method

    NOTE:

    this function should eventually be moved to \(p\)-adic power series ring

    INPUT:

    - `f` – power series with coefficients in \(\QQ_p\) or an extension

    - `x0` – seeds the Newton iteration

    - `prec` – precision

    OUTPUT: the square root of \(f\)

    EXAMPLES:

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x)
        sage: Q = H(0,0)
        sage: u,v = H.local_coord(Q,prec=100)
        sage: K = Qp(11,5)
        sage: HK = H.change_ring(K)
        sage: L.<a> = K.extension(x^20-11)
        sage: HL = H.change_ring(L)
        sage: S = HL(u(a),v(a))
        sage: f = H.hyperelliptic_polynomials()[0]
        sage: y = HK.newton_sqrt( f(u(a)^11), a^11,5)
        sage: y^2 - f(u(a)^11)
        O(a^122)

    Python

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(5)-Integer(23)*x**Integer(3)+Integer(18)*x**Integer(2)+Integer(40)*x)
        >>> Q = H(Integer(0),Integer(0))
        >>> u,v = H.local_coord(Q,prec=Integer(100))
        >>> K = Qp(Integer(11),Integer(5))
        >>> HK = H.change_ring(K)
        >>> L = K.extension(x**Integer(20)-Integer(11), names=('a',)); (a,) = L._first_ngens(1)
        >>> HL = H.change_ring(L)
        >>> S = HL(u(a),v(a))
        >>> f = H.hyperelliptic_polynomials()[Integer(0)]
        >>> y = HK.newton_sqrt( f(u(a)**Integer(11)), a**Integer(11),Integer(5))
        >>> y**Integer(2) - f(u(a)**Integer(11))
        O(a^122)

    AUTHOR:

    - Jennifer Balakrishnan

  residue_disc(P)

    Gives the residue disc of \(P\)

    TODO: Really, this gives the reduction over the residue field. Isn’t the residue disc a disc over the p-adics? Maybe rename to residue_point or reduction ?

    EXAMPLES:

    We compute the residue discs for diffferent points on the elliptic curve \(y^2 = x^3 = 10*x + 9\) over the \(5\)-adics:

    Sage

        sage: R.<x> = QQ['x']
        sage: H = HyperellipticCurve(x^3-10*x+9)
        sage: K = Qp(5,8)
        sage: HK = H.change_ring(K)
        sage: P = HK.lift_x(1 + 2*5^2)
        sage: HK.residue_disc(P)
        (1 : 0 : 1)
        sage: Q = HK(0,3)
        sage: HK.residue_disc(Q)
        (0 : 3 : 1)
        sage: S = HK.lift_x(5^-2)
        sage: HK.residue_disc(S)
        (1 : 0 : 0)
        sage: T = HK(1,0,0)
        sage: HK.residue_disc(T)
        (1 : 0 : 0)

    Python

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(3)-Integer(10)*x+Integer(9))
        >>> K = Qp(Integer(5),Integer(8))
        >>> HK = H.change_ring(K)
        >>> P = HK.lift_x(Integer(1) + Integer(2)*Integer(5)**Integer(2))
        >>> HK.residue_disc(P)
        (1 : 0 : 1)
        >>> Q = HK(Integer(0),Integer(3))
        >>> HK.residue_disc(Q)
        (0 : 3 : 1)
        >>> S = HK.lift_x(Integer(5)**-Integer(2))
        >>> HK.residue_disc(S)
        (1 : 0 : 0)
        >>> T = HK(Integer(1),Integer(0),Integer(0))
        >>> HK.residue_disc(T)
        (1 : 0 : 0)

    We can also compute residue discs for points on curves with a split or inert model:

    Sage

        sage: H = HyperellipticCurve(x^6+3, x^2+1)
        sage: H.is_split()
        True
        sage: HK = H.change_ring(K)
        sage: P = HK.lift_x(1+3*5+4*5^2+4*5^3)
        sage: Pbar = HK.residue_disc(P); Pbar
        (1 : 4 : 1)

    [Python]

        >>> from sage.all import *
        >>> H = HyperellipticCurve(x**Integer(6)+Integer(3), x**Integer(2)+Integer(1))
        >>> H.is_split()
        True
        >>> HK = H.change_ring(K)
        >>> P = HK.lift_x(Integer(1)+Integer(3)*Integer(5)+Integer(4)*Integer(5)**Integer(2)+Integer(4)*Integer(5)**Integer(3))
        >>> Pbar = HK.residue_disc(P); Pbar
        (1 : 4 : 1)

    We note that \(P\) is in a Weierstrass disc and its reduction is indeed a Weierstrass point.

    > sage: HK.is_in_weierstrass_disc(P) True sage: HF = HK.change_ring(FiniteField(5)) sage: HF.is_weierstrass_point(Pbar) True

    AUTHOR:

    - Jennifer Balakrishnan

  teichmuller(P)

    Find a Teichm:uller point in the same residue class of \(P\).

    Because this lift of frobenius acts as \(x \mapsto x^p\), take the Teichmuller lift of \(x\) and then find a matching \(y\) from that.

    EXAMPLES:

    Sage

        sage: K = pAdicField(7, 5)
        sage: R.<x> = K[]
        sage: E = HyperellipticCurve(x^3 - 31/3*x - 2501/108) # 11a
        sage: P = E(K(14/3), K(11/2))
        sage: E.frobenius(P) == P
        False
        sage: TP = E.teichmuller(P); TP
        (0 : 2 + 3*7 + 3*7^2 + 3*7^4 + O(7^5) : 1 + O(7^5))
        sage: E.frobenius(TP) == TP
        True
        sage: (TP[0] - P[0]).valuation() > 0, (TP[1] - P[1]).valuation() > 0
        (True, True)

    Python

        >>> from sage.all import *
        >>> K = pAdicField(Integer(7), Integer(5))
        >>> R = K['x']; (x,) = R._first_ngens(1)
        >>> E = HyperellipticCurve(x**Integer(3) - Integer(31)/Integer(3)*x - Integer(2501)/Integer(108)) # 11a
        >>> P = E(K(Integer(14)/Integer(3)), K(Integer(11)/Integer(2)))
        >>> E.frobenius(P) == P
        False
        >>> TP = E.teichmuller(P); TP
        (0 : 2 + 3*7 + 3*7^2 + 3*7^4 + O(7^5) : 1 + O(7^5))
        >>> E.frobenius(TP) == TP
        True
        >>> (TP[Integer(0)] - P[Integer(0)]).valuation() > Integer(0), (TP[Integer(1)] - P[Integer(1)]).valuation() > Integer(0)
        (True, True)

  tiny_integrals(F, P, Q)

    Evaluate the integrals of \(f_i dx/2y\) from \(P\) to \(Q\) for each \(f_i\) in \(F\) by formally integrating a power series in a local parameter \(t\)

    \(P\) and \(Q\) MUST be in the same residue disc for this result to make sense.

    INPUT:

    - F a list of functions \(f_i\)

    - P a point on self

    - Q a point on self (in the same residue disc as P)

    OUTPUT:

    The integrals \(\int_P^Q f_i dx/2y\)

    EXAMPLES:

    Sage

        sage: K = pAdicField(17, 5)
        sage: E = EllipticCurve(K, [-31/3, -2501/108]) # 11a
        sage: P = E(K(14/3), K(11/2))
        sage: TP = E.teichmuller(P);
        sage: x,y = E.monsky_washnitzer_gens()
        sage: E.tiny_integrals([1,x],P, TP) == E.tiny_integrals_on_basis(P,TP)
        True

    Python

        >>> from sage.all import *
        >>> K = pAdicField(Integer(17), Integer(5))
        >>> E = EllipticCurve(K, [-Integer(31)/Integer(3), -Integer(2501)/Integer(108)]) # 11a
        >>> P = E(K(Integer(14)/Integer(3)), K(Integer(11)/Integer(2)))
        >>> TP = E.teichmuller(P);
        >>> x,y = E.monsky_washnitzer_gens()
        >>> E.tiny_integrals([Integer(1),x],P, TP) == E.tiny_integrals_on_basis(P,TP)
        True

    Sage

        sage: K = pAdicField(11, 5)
        sage: x = polygen(K)
        sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16)
        sage: P = C.lift_x(11^(-2))
        sage: Q = C.lift_x(3*11^(-2))
        sage: C.tiny_integrals([1],P,Q)
        (5*11^3 + 7*11^4 + 2*11^5 + 6*11^6 + 11^7 + O(11^8))

    [Python]

        >>> from sage.all import *
        >>> K = pAdicField(Integer(11), Integer(5))
        >>> x = polygen(K)
        >>> C = HyperellipticCurve(x**Integer(5) + Integer(33)/Integer(16)*x**Integer(4) + Integer(3)/Integer(4)*x**Integer(3) + Integer(3)/Integer(8)*x**Integer(2) - Integer(1)/Integer(4)*x + Integer(1)/Integer(16))
        >>> P = C.lift_x(Integer(11)**(-Integer(2)))
        >>> Q = C.lift_x(Integer(3)*Integer(11)**(-Integer(2)))
        >>> C.tiny_integrals([Integer(1)],P,Q)
        (5*11^3 + 7*11^4 + 2*11^5 + 6*11^6 + 11^7 + O(11^8))

    Note that this fails if the points are not in the same residue disc:

    Sage

        sage: S = C(0,1/4)
        sage: C.tiny_integrals([1,x,x^2,x^3],P,S)
        Traceback (most recent call last):
        ...
        ValueError: (11^-2 + O(11^3) : 11^-5 + 8*11^-2 + O(11^0) : 1 + O(11^5)) and
         (0 : 3 + 8*11 + 2*11^2 + 8*11^3 + 2*11^4 + O(11^5) : 1 + O(11^5)) are not in the same residue disc

    Python

        >>> from sage.all import *
        >>> S = C(Integer(0),Integer(1)/Integer(4))
        >>> C.tiny_integrals([Integer(1),x,x**Integer(2),x**Integer(3)],P,S)
        Traceback (most recent call last):
        ...
        ValueError: (11^-2 + O(11^3) : 11^-5 + 8*11^-2 + O(11^0) : 1 + O(11^5)) and
         (0 : 3 + 8*11 + 2*11^2 + 8*11^3 + 2*11^4 + O(11^5) : 1 + O(11^5)) are not in the same residue disc

  tiny_integrals_on_basis(P, Q)

    Evaluate the integrals \(\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}\) by formally integrating a power series in a local parameter \(t\). \(P\) and \(Q\) MUST be in the same residue disc for this result to make sense.

    INPUT:

    - P a point on self

    - Q a point on self (in the same residue disc as P)

    OUTPUT:

    The integrals \(\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}\)

    EXAMPLES:

    Sage

        sage: K = pAdicField(17, 5)
        sage: E = EllipticCurve(K, [-31/3, -2501/108]) # 11a
        sage: P = E(K(14/3), K(11/2))
        sage: TP = E.teichmuller(P);
        sage: E.tiny_integrals_on_basis(P, TP)
        (17 + 14*17^2 + 17^3 + 8*17^4 + O(17^5), 16*17 + 5*17^2 + 8*17^3 + 14*17^4 + O(17^5))

    Python

        >>> from sage.all import *
        >>> K = pAdicField(Integer(17), Integer(5))
        >>> E = EllipticCurve(K, [-Integer(31)/Integer(3), -Integer(2501)/Integer(108)]) # 11a
        >>> P = E(K(Integer(14)/Integer(3)), K(Integer(11)/Integer(2)))
        >>> TP = E.teichmuller(P);
        >>> E.tiny_integrals_on_basis(P, TP)
        (17 + 14*17^2 + 17^3 + 8*17^4 + O(17^5), 16*17 + 5*17^2 + 8*17^3 + 14*17^4 + O(17^5))

    Sage

        sage: K = pAdicField(11, 5)
        sage: x = polygen(K)
        sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16)
        sage: P = C.lift_x(11^(-2))
        sage: Q = C.lift_x(3*11^(-2))
        sage: C.tiny_integrals_on_basis(P,Q)
        (5*11^3 + 7*11^4 + 2*11^5 + 6*11^6 + 11^7 + O(11^8), 10*11 + 2*11^3 + 3*11^4 + 5*11^5 + O(11^6), 5*11^-1 + 8 + 4*11 + 10*11^2 + 7*11^3 + O(11^4), 2*11^-3 + 11^-2 + 11^-1 + 10 + 8*11 + O(11^2))

    [Python]

        >>> from sage.all import *
        >>> K = pAdicField(Integer(11), Integer(5))
        >>> x = polygen(K)
        >>> C = HyperellipticCurve(x**Integer(5) + Integer(33)/Integer(16)*x**Integer(4) + Integer(3)/Integer(4)*x**Integer(3) + Integer(3)/Integer(8)*x**Integer(2) - Integer(1)/Integer(4)*x + Integer(1)/Integer(16))
        >>> P = C.lift_x(Integer(11)**(-Integer(2)))
        >>> Q = C.lift_x(Integer(3)*Integer(11)**(-Integer(2)))
        >>> C.tiny_integrals_on_basis(P,Q)
        (5*11^3 + 7*11^4 + 2*11^5 + 6*11^6 + 11^7 + O(11^8), 10*11 + 2*11^3 + 3*11^4 + 5*11^5 + O(11^6), 5*11^-1 + 8 + 4*11 + 10*11^2 + 7*11^3 + O(11^4), 2*11^-3 + 11^-2 + 11^-1 + 10 + 8*11 + O(11^2))

    Note that this fails if the points are not in the same residue disc:

    Sage

        sage: S = C(0,1/4)
        sage: C.tiny_integrals_on_basis(P,S)
        Traceback (most recent call last):
        ...
        ValueError: (11^-2 + O(11^3) : 11^-5 + 8*11^-2 + O(11^0) : 1 + O(11^5)) and (0 : 3 + 8*11 + 2*11^2 + 8*11^3 + 2*11^4 + O(11^5) : 1 + O(11^5)) are not in the same residue disc

    Python

        >>> from sage.all import *
        >>> S = C(Integer(0),Integer(1)/Integer(4))
        >>> C.tiny_integrals_on_basis(P,S)
        Traceback (most recent call last):
        ...
        ValueError: (11^-2 + O(11^3) : 11^-5 + 8*11^-2 + O(11^0) : 1 + O(11^5)) and (0 : 3 + 8*11 + 2*11^2 + 8*11^3 + 2*11^4 + O(11^5) : 1 + O(11^5)) are not in the same residue disc