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'])[source]¶
Bases:
HyperellipticCurve_genericClass 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: 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)
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: 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)
- P_to_S(P, S)[source]¶
Given a finite Weierstrass point
Pand a pointSin the same disc, compute the Coleman integrals \(\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}\)INPUT:
P: finite Weierstrass pointS: point in disc ofP
OUTPUT:
Coleman integrals \(\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}\)
EXAMPLES:
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))
AUTHOR:
Jennifer Balakrishnan
- S_to_Q(S, Q)[source]¶
Given
Sa point onselfover 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: 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))
AUTHOR:
Jennifer Balakrishnan
- coleman_integral(w, P, Q, algorithm='None')[source]¶
Return the Coleman integral \(\int_P^Q w\).
INPUT:
wdifferential (if one of P,Q is Weierstrass, w must be odd)Ppoint on selfQpoint on selfalgorithm (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: 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)
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)
A simple example, integrating dx:
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)
Yet another example:
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)
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)
Integrals involving Weierstrass points:
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)
AUTHORS:
Robert Bradshaw (2007-03)
Kiran Kedlaya (2008-05)
Jennifer Balakrishnan (2010-02)
- coleman_integral_P_to_S(w, P, S)[source]¶
Given a finite Weierstrass point
Pand a pointSin the same disc, compute the Coleman integral \(\int_P^S w\)INPUT:
w: differentialP: Weierstrass pointS: point in the same disc ofP(Sis defined over an extension of \(\QQ_p\); coordinates ofSare given in terms of uniformizer \(a\))
OUTPUT:
Coleman integral \(\int_P^S w\) in terms of \(a\)
EXAMPLES:
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
AUTHOR:
Jennifer Balakrishnan
- coleman_integral_S_to_Q(w, S, Q)[source]¶
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 differentialS: 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: 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)
AUTHOR:
Jennifer Balakrishnan
- coleman_integral_from_weierstrass_via_boundary(w, P, Q, d)[source]¶
Computes the Coleman integral \(\int_P^Q w\) via a boundary point in the disc of
P, defined over a degreedextensionINPUT:
w: a differentialP: a Weierstrass pointQ: a non-Weierstrass pointd: 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: 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)
AUTHOR:
Jennifer Balakrishnan
- coleman_integrals_on_basis(P, Q, algorithm=None)[source]¶
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: 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))
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))
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
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)
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)[source]¶
alias of
coleman_integrals_on_basis().
- curve_over_ram_extn(deg)[source]¶
Return
selfover \(\QQ_p(p^(1/deg))\).INPUT:
deg: the degree of the ramified extension
OUTPUT:
selfover \(\QQ_p(p^(1/deg))\)EXAMPLES:
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
AUTHOR:
Jennifer Balakrishnan
- find_char_zero_weierstrass_point(Q)[source]¶
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: 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)
An example for a hyperelltiptic curve with split model:
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))
The input needs to be a point in a Weierstrass disc, otherwise an error is returned:
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.
AUTHOR:
Jennifer Balakrishnan
- frobenius(P=None)[source]¶
Returns the \(p\)-th power lift of Frobenius of \(P\)
EXAMPLES:
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))
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))
AUTHORS:
Robert Bradshaw and Jennifer Balakrishnan (2010-02)
- get_boundary_point(curve_over_extn, P)[source]¶
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: 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))
AUTHOR:
Jennifer Balakrishnan
- is_in_weierstrass_disc(P)[source]¶
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: 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
The method is also implemented for general models of hyperelliptic curves:
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
Note that \(y = - y - h(x)\) for Weierstrass points. We check that this relation is satisfied for the point above (mod p):
sage: f,h = H.hyperelliptic_polynomials() sage: (2*P[1] + h(P[0])).valuation() > 0 True
AUTHOR:
Jennifer Balakrishnan (2010-02)
- is_same_disc(P, Q)[source]¶
Checks if \(P,Q\) are in same residue disc
EXAMPLES:
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
- local_analytic_interpolation(P, Q)[source]¶
For points
P,Qin the same residue disc, construct an interpolation fromPtoQ(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:
PandQpoints onselfin the same residue disc
OUTPUT:
Returns a point \(X(t) = ( x(t) : y(t) : z(t) )\) such that:
\(X(0) = P\) and \(X(1) = Q\) if \(P, Q\) are not in the infinite disc
\(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: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) sage: K = Qp(5,8) sage: HK = H.change_ring(K)
A non-Weierstrass disc:
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)
A finite Weierstrass disc:
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)
The infinite disc:
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
An error if points are not in the same disc:
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
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)[source]¶
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 extensionx0– seeds the Newton iterationprec– precision
OUTPUT: the square root of \(f\)
EXAMPLES:
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)
AUTHOR:
Jennifer Balakrishnan
- residue_disc(P)[source]¶
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: 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)
We can also compute residue discs for points on curves with a split or inert model:
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)
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)[source]¶
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: 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)
- tiny_integrals(F, P, Q)[source]¶
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: 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
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))
Note that this fails if the points are not in the same residue disc:
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
- tiny_integrals_on_basis(P, Q)[source]¶
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: 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))
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))
Note that this fails if the points are not in the same residue disc:
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