Path: blob/master/sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py
4156 views
"""1Hyperelliptic curves over a padic field.2"""34#*****************************************************************************5# Copyright (C) 2007 Robert Bradshaw <[email protected]>6# Distributed under the terms of the GNU General Public License (GPL)7# http://www.gnu.org/licenses/8#*****************************************************************************91011import hyperelliptic_generic1213from sage.rings.all import PowerSeriesRing, PolynomialRing, ZZ, QQ, O, pAdicField, GF, RR, RationalField, Infinity14from sage.misc.functional import log15from sage.modules.free_module import VectorSpace16from sage.matrix.constructor import matrix17from sage.modules.all import vector181920class HyperellipticCurve_padic_field(hyperelliptic_generic.HyperellipticCurve_generic):2122# The functions below were prototyped at the 2007 Arizona Winter School by23# Robert Bradshaw and Ralf Gerkmann, working with Miljan Brakovevic and24# Kiran Kedlaya25# All of the below is with respect to the Monsky Washnitzer cohomology.2627def local_analytic_interpolation(self, P, Q):28"""29For points $P$, $Q$ in the same residue disc,30this constructs an interpolation from $P$ to $Q$31(in homogeneous coordinates) in a power series in32the local parameter $t$, with precision equal to33the $p$-adic precision of the underlying ring.3435INPUT:3637- P and Q points on self in the same residue disc3839OUTPUT:4041Returns a point $X(t) = ( x(t) : y(t) : z(t) )$ such that4243(1) $X(0) = P$ and $X(1) = Q$ if $P, Q$ are not in the infinite disc44(2) $X(P[0]^g}/P[1]) = P$ and $X(Q[0]^g/Q[1]) = Q$ if $P, Q$ are in the infinite disc4546EXAMPLES::4748sage: R.<x> = QQ['x']49sage: H = HyperellipticCurve(x^3-10*x+9)50sage: K = Qp(5,8)51sage: HK = H.change_ring(K)5253A non-Weierstrass disc::5455sage: P = HK(0,3)56sage: 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))57sage: x,y,z, = HK.local_analytic_interpolation(P,Q)58sage: x(0) == P[0], x(1) == Q[0], y(0) == P[1], y(1) == Q[1]59(True, True, True, True)6061A finite Weierstrass disc::6263sage: P = HK.lift_x(1 + 2*5^2)64sage: Q = HK.lift_x(1 + 3*5^2)65sage: x,y,z = HK.local_analytic_interpolation(P,Q)66sage: x(0) == P[0], x(1) == Q[0], y(0) == P[1], y(1) == Q[1]67(True, True, True, True)6869The infinite disc::7071sage: P = HK.lift_x(5^-2)72sage: Q = HK.lift_x(4*5^-2)73sage: x,y,z = HK.local_analytic_interpolation(P,Q)74sage: x = x/z75sage: y = y/z76sage: x(P[0]/P[1]) == P[0]77True78sage: x(Q[0]/Q[1]) == Q[0]79True80sage: y(P[0]/P[1]) == P[1]81True82sage: y(Q[0]/Q[1]) == Q[1]83True8485An error if points are not in the same disc::8687sage: x,y,z = HK.local_analytic_interpolation(P,HK(1,0))88Traceback (most recent call last):89...90ValueError: (5^-2 + O(5^6) : 5^-3 + 4*5^2 + 5^3 + 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 disc9192AUTHORS:9394- Robert Bradshaw (2007-03)95- Jennifer Balakrishnan (2010-02)96"""97prec = self.base_ring().precision_cap()98if self.is_same_disc(P,Q) == False:99raise ValueError, "%s and %s are not in the same residue disc"%(P,Q)100disc = self.residue_disc(P)101t = PowerSeriesRing(self.base_ring(), 't', prec).gen(0)102if disc == self.change_ring(self.base_ring().residue_field())(0,1,0):103x,y = self.local_coordinates_at_infinity(2*prec)104g = self.genus()105return (x*t**(2*g+1),y*t**(2*g+1),t**(2*g+1))106if disc[1] !=0:107x = P[0]+t*(Q[0]-P[0])108pts = self.lift_x(x, all=True)109if pts[0][1][0] == P[1]:110return pts[0]111else:112return pts[1]113else:114S = self.find_char_zero_weier_point(P)115x,y = self.local_coord(S)116a = P[1]117b = Q[1] - P[1]118y = a + b*t119x = x(y)120return (x, y, 1)121122def weierstrass_points(self):123"""124Return the Weierstrass points of self defined over self.base_ring(),125that is, the point at infinity and those points in the support126of the divisor of $y$127128EXAMPLES::129130sage: K = pAdicField(11, 5)131sage: x = polygen(K)132sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16)133sage: C.weierstrass_points()134[(0 : 1 + O(11^5) : 0), (7 + 10*11 + 4*11^3 + O(11^5) : 0 : 1 + O(11^5))]135"""136f, h = self.hyperelliptic_polynomials()137if h != 0:138raise NotImplementedError()139return [self((0,1,0))] + [self((x, 0, 1)) for x in f.roots()]140141def is_in_weierstrass_disc(self,P):142"""143Checks if $P$ is in a Weierstrass disc144145EXAMPLES::146147sage: R.<x> = QQ['x']148sage: H = HyperellipticCurve(x^3-10*x+9)149sage: K = Qp(5,8)150sage: HK = H.change_ring(K)151sage: P = HK(0,3)152sage: HK.is_in_weierstrass_disc(P)153False154sage: Q = HK(0,1,0)155sage: HK.is_in_weierstrass_disc(Q)156True157sage: S = HK(1,0)158sage: HK.is_in_weierstrass_disc(S)159True160sage: T = HK.lift_x(1+3*5^2); T161(1 + 3*5^2 + O(5^8) : 2*5 + 4*5^3 + 3*5^4 + 5^5 + 3*5^6 + O(5^7) : 1 + O(5^8))162sage: HK.is_in_weierstrass_disc(T)163True164165AUTHOR:166167- Jennifer Balakrishnan (2010-02)168"""169if (P[1].valuation() == 0 and P != self(0,1,0)):170return False171else:172return True173174def is_weierstrass(self,P):175"""176Checks if $P$ is a Weierstrass point (i.e., fixed by the hyperelliptic involution)177178EXAMPLES::179180sage: R.<x> = QQ['x']181sage: H = HyperellipticCurve(x^3-10*x+9)182sage: K = Qp(5,8)183sage: HK = H.change_ring(K)184sage: P = HK(0,3)185sage: HK.is_weierstrass(P)186False187sage: Q = HK(0,1,0)188sage: HK.is_weierstrass(Q)189True190sage: S = HK(1,0)191sage: HK.is_weierstrass(S)192True193sage: T = HK.lift_x(1+3*5^2); T194(1 + 3*5^2 + O(5^8) : 2*5 + 4*5^3 + 3*5^4 + 5^5 + 3*5^6 + O(5^7) : 1 + O(5^8))195sage: HK.is_weierstrass(T)196False197198AUTHOR:199200- Jennifer Balakrishnan (2010-02)201202"""203if (P[1] == 0 or P[2] ==0):204return True205else:206return False207208def find_char_zero_weier_point(self, Q):209"""210Given $Q$ a point on self in a Weierstrass disc, finds the211center of the Weierstrass disc (if defined over self.base_ring())212213EXAMPLES::214215sage: R.<x> = QQ['x']216sage: H = HyperellipticCurve(x^3-10*x+9)217sage: K = Qp(5,8)218sage: HK = H.change_ring(K)219sage: P = HK.lift_x(1 + 2*5^2)220sage: Q = HK.lift_x(5^-2)221sage: S = HK(1,0)222sage: T = HK(0,1,0)223sage: HK.find_char_zero_weier_point(P)224(1 + O(5^8) : 0 : 1 + O(5^8))225sage: HK.find_char_zero_weier_point(Q)226(0 : 1 + O(5^8) : 0)227sage: HK.find_char_zero_weier_point(S)228(1 + O(5^8) : 0 : 1 + O(5^8))229sage: HK.find_char_zero_weier_point(T)230(0 : 1 + O(5^8) : 0)231232AUTHOR:233234- Jennifer Balakrishnan235"""236if self.is_in_weierstrass_disc(Q) == False:237raise ValueError, "%s is not in a Weierstrass disc"%Q238points = self.weierstrass_points()239for P in points:240if self.is_same_disc(P,Q):241return P242243def residue_disc(self,P):244"""245Gives the residue disc of $P$246247EXAMPLES::248249sage: R.<x> = QQ['x']250sage: H = HyperellipticCurve(x^3-10*x+9)251sage: K = Qp(5,8)252sage: HK = H.change_ring(K)253sage: P = HK.lift_x(1 + 2*5^2)254sage: HK.residue_disc(P)255(1 : 0 : 1)256sage: Q = HK(0,3)257sage: HK.residue_disc(Q)258(0 : 3 : 1)259sage: S = HK.lift_x(5^-2)260sage: HK.residue_disc(S)261(0 : 1 : 0)262sage: T = HK(0,1,0)263sage: HK.residue_disc(T)264(0 : 1 : 0)265266AUTHOR:267268- Jennifer Balakrishnan269"""270xPv = P[0].valuation()271yPv = P[1].valuation()272F = self.base_ring().residue_field()273HF = self.change_ring(F)274if P == self(0,1,0):275return HF(0,1,0)276elif yPv > 0:277if xPv > 0:278return HF(0,0,1)279if xPv == 0:280return HF(P[0].list()[0], 0,1)281elif yPv ==0:282if xPv > 0:283return HF(0, P[1].list()[0],1)284if xPv == 0:285return HF(P[0].list()[0], P[1].list()[0],1)286else:287return HF(0,1,0)288289def is_same_disc(self,P,Q):290"""291Checks if $P,Q$ are in same residue disc292293EXAMPLES::294295sage: R.<x> = QQ['x']296sage: H = HyperellipticCurve(x^3-10*x+9)297sage: K = Qp(5,8)298sage: HK = H.change_ring(K)299sage: P = HK.lift_x(1 + 2*5^2)300sage: Q = HK.lift_x(5^-2)301sage: S = HK(1,0)302sage: HK.is_same_disc(P,Q)303False304sage: HK.is_same_disc(P,S)305True306sage: HK.is_same_disc(Q,S)307False308"""309if self.residue_disc(P) == self.residue_disc(Q):310return True311else:312return False313314def tiny_integrals(self, F, P, Q):315r"""316Evaluate the integrals of $f_i dx/2y$ from $P$ to $Q$ for each $f_i$ in $F$317by formally integrating a power series in a local parameter $t$318319$P$ and $Q$ MUST be in the same residue disc for this result to make sense.320321INPUT:322323- F a list of functions $f_i$324- P a point on self325- Q a point on self (in the same residue disc as P)326327OUTPUT:328329The integrals $\int_P^Q f_i dx/2y$330331EXAMPLES::332333sage: K = pAdicField(17, 5)334sage: E = EllipticCurve(K, [-31/3, -2501/108]) # 11a335sage: P = E(K(14/3), K(11/2))336sage: TP = E.teichmuller(P);337sage: x,y = E.monsky_washnitzer_gens()338sage: E.tiny_integrals([1,x],P, TP) == E.tiny_integrals_on_basis(P,TP)339True340341::342343sage: K = pAdicField(11, 5)344sage: x = polygen(K)345sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16)346sage: P = C.lift_x(11^(-2))347sage: Q = C.lift_x(3*11^(-2))348sage: C.tiny_integrals([1],P,Q)349(3*11^3 + 7*11^4 + 4*11^5 + 7*11^6 + 5*11^7 + O(11^8))350351Note that this fails if the points are not in the same residue disc::352353sage: S = C(0,1/4)354sage: C.tiny_integrals([1,x,x^2,x^3],P,S)355Traceback (most recent call last):356...357ValueError: (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 disc358359"""360x, y, z = self.local_analytic_interpolation(P, Q) #homogeneous coordinates361x = x/z362y = y/z363dt = x.derivative() / (2*y)364integrals = []365g = self.genus()366for f in F:367try:368f_dt = f(x,y)*dt369except TypeError: #if f is a constant, not callable370f_dt = f*dt371if x.valuation() != -2:372I = sum([f_dt[n]/(n+1) for n in xrange(f_dt.degree()+1)]) # \int_0^1 f dt373else:374If_dt = f_dt.integral()375I = If_dt(Q[0]**g/Q[1]) - If_dt(P[0]**g/P[1])376integrals.append(I)377return vector(integrals)378379def tiny_integrals_on_basis(self, P, Q):380r"""381Evaluate the integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$382by formally integrating a power series in a local parameter $t$.383$P$ and $Q$ MUST be in the same residue disc for this result to make sense.384385INPUT:386387- P a point on self388- Q a point on self (in the same residue disc as P)389390OUTPUT:391392The integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$393394EXAMPLES::395396sage: K = pAdicField(17, 5)397sage: E = EllipticCurve(K, [-31/3, -2501/108]) # 11a398sage: P = E(K(14/3), K(11/2))399sage: TP = E.teichmuller(P);400sage: E.tiny_integrals_on_basis(P, TP)401(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))402403::404405sage: K = pAdicField(11, 5)406sage: x = polygen(K)407sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16)408sage: P = C.lift_x(11^(-2))409sage: Q = C.lift_x(3*11^(-2))410sage: C.tiny_integrals_on_basis(P,Q)411(3*11^3 + 7*11^4 + 4*11^5 + 7*11^6 + 5*11^7 + O(11^8), 3*11 + 10*11^2 + 8*11^3 + 9*11^4 + 7*11^5 + O(11^6), 4*11^-1 + 2 + 6*11 + 6*11^2 + 7*11^3 + O(11^4), 11^-3 + 6*11^-2 + 2*11^-1 + 2 + O(11^2))412413414Note that this fails if the points are not in the same residue disc::415416sage: S = C(0,1/4)417sage: C.tiny_integrals_on_basis(P,S)418Traceback (most recent call last):419...420ValueError: (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 disc421422"""423if P == Q:424V = VectorSpace(self.base_ring(), 2*self.genus())425return V(0)426R = PolynomialRing(self.base_ring(), ['x', 'y'])427x, y = R.gens()428return self.tiny_integrals([x**i for i in range(2*self.genus())], P, Q)429430def teichmuller(self, P):431r"""432Find a Teichm\:uller point in the same residue class of $P$.433434Because this lift of frobenius acts as $x \mapsto x^p$,435take the Teichmuller lift of $x$ and then find a matching $y$436from that.437438EXAMPLES::439440sage: K = pAdicField(7, 5)441sage: E = EllipticCurve(K, [-31/3, -2501/108]) # 11a442sage: P = E(K(14/3), K(11/2))443sage: E.frobenius(P) == P444False445sage: TP = E.teichmuller(P); TP446(0 : 2 + 3*7 + 3*7^2 + 3*7^4 + O(7^5) : 1 + O(7^5))447sage: E.frobenius(TP) == TP448True449sage: (TP[0] - P[0]).valuation() > 0, (TP[1] - P[1]).valuation() > 0450(True, True)451"""452K = P[0].parent()453x = K.teichmuller(P[0])454pts = self.lift_x(x, all=True)455p = K.prime()456if (pts[0][1] - P[1]).valuation() > 0:457return pts[0]458else:459return pts[1]460461def coleman_integrals_on_basis(self, P, Q, algorithm=None):462r"""463Computes the Coleman integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$464465INPUT:466467- P point on self468- Q point on self469- algorithm (optional) = None (uses Frobenius) or teichmuller (uses Teichmuller points)470471OUTPUT:472473the Coleman integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$474475EXAMPLES::476477sage: K = pAdicField(11, 5)478sage: x = polygen(K)479sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16)480sage: P = C.lift_x(2)481sage: Q = C.lift_x(3)482sage: C.coleman_integrals_on_basis(P, Q)483(10*11 + 6*11^3 + 2*11^4 + O(11^5), 11 + 9*11^2 + 7*11^3 + 9*11^4 + O(11^5), 3 + 10*11 + 5*11^2 + 9*11^3 + 4*11^4 + O(11^5), 3 + 11 + 5*11^2 + 4*11^4 + O(11^5))484sage: C.coleman_integrals_on_basis(P, Q, algorithm='teichmuller')485(10*11 + 6*11^3 + 2*11^4 + O(11^5), 11 + 9*11^2 + 7*11^3 + 9*11^4 + O(11^5), 3 + 10*11 + 5*11^2 + 9*11^3 + 4*11^4 + O(11^5), 3 + 11 + 5*11^2 + 4*11^4 + O(11^5))486487::488489sage: K = pAdicField(11,5)490sage: x = polygen(K)491sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16)492sage: P = C.lift_x(11^(-2))493sage: Q = C.lift_x(3*11^(-2))494sage: C.coleman_integrals_on_basis(P, Q)495(3*11^3 + 7*11^4 + 4*11^5 + 7*11^6 + 5*11^7 + O(11^8), 3*11 + 10*11^2 + 8*11^3 + 9*11^4 + 7*11^5 + O(11^6), 4*11^-1 + 2 + 6*11 + 6*11^2 + 7*11^3 + O(11^4), 11^-3 + 6*11^-2 + 2*11^-1 + 2 + O(11^2))496497::498499sage: R = C(0,1/4)500sage: a = C.coleman_integrals_on_basis(P,R) # long time (7s on sage.math, 2011)501sage: b = C.coleman_integrals_on_basis(R,Q) # long time (9s on sage.math, 2011)502sage: c = C.coleman_integrals_on_basis(P,Q) # long time503sage: a+b == c # long time504True505506::507508sage: R.<x> = QQ['x']509sage: H = HyperellipticCurve(x^3-10*x+9)510sage: K = Qp(5,8)511sage: HK = H.change_ring(K)512sage: S = HK(1,0)513sage: P = HK(0,3)514sage: T = HK(0,1,0)515sage: Q = HK.lift_x(5^-2)516sage: R = HK.lift_x(4*5^-2)517sage: HK.coleman_integrals_on_basis(S,P)518(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))519sage: HK.coleman_integrals_on_basis(T,P)520(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))521sage: HK.coleman_integrals_on_basis(P,S) == -HK.coleman_integrals_on_basis(S,P)522True523sage: HK.coleman_integrals_on_basis(S,Q)524(4*5 + 4*5^2 + 4*5^3 + O(5^4), 5^-1 + O(5^3))525sage: HK.coleman_integrals_on_basis(Q,R)526(4*5 + 2*5^2 + 2*5^3 + 2*5^4 + 5^5 + 5^6 + 5^7 + 3*5^8 + O(5^9), 2*5^-1 + 4 + 4*5 + 4*5^2 + 4*5^3 + 2*5^4 + 3*5^5 + 2*5^6 + O(5^7))527sage: HK.coleman_integrals_on_basis(S,R) == HK.coleman_integrals_on_basis(S,Q) + HK.coleman_integrals_on_basis(Q,R)528True529sage: HK.coleman_integrals_on_basis(T,T)530(0, 0)531sage: HK.coleman_integrals_on_basis(S,T)532(0, 0)533534AUTHORS:535536- Robert Bradshaw (2007-03): non-Weierstrass points537- Jennifer Balakrishnan and Robert Bradshaw (2010-02): Weierstrass points538"""539import sage.schemes.elliptic_curves.monsky_washnitzer as monsky_washnitzer540from sage.misc.profiler import Profiler541prof = Profiler()542prof("setup")543K = self.base_ring()544p = K.prime()545prec = K.precision_cap()546g = self.genus()547dim = 2*g548V = VectorSpace(K, dim)549#if P or Q is Weierstrass, use the Frobenius algorithm550if self.is_weierstrass(P):551if self.is_weierstrass(Q):552return V(0)553else:554PP = None555QQ = Q556TP = None557TQ = self.frobenius(Q)558elif self.is_weierstrass(Q):559PP = P560QQ = None561TQ = None562TP = self.frobenius(P)563elif self.is_same_disc(P,Q):564return self.tiny_integrals_on_basis(P,Q)565elif algorithm == 'teichmuller':566prof("teichmuller")567PP = TP = self.teichmuller(P)568QQ = TQ = self.teichmuller(Q)569evalP, evalQ = TP, TQ570else:571prof("frobPQ")572TP = self.frobenius(P)573TQ = self.frobenius(Q)574PP, QQ = P, Q575prof("tiny integrals")576if TP == None:577P_to_TP = V(0)578else:579if TP!=None:580TPv = (TP[0]**g/TP[1]).valuation()581xTPv = TP[0].valuation()582else:583xTPv = TPv = +Infinity584if TQ!=None:585TQv = (TQ[0]**g/TQ[1]).valuation()586xTQv = TQ[0].valuation()587else:588xTQv = TQv = +Infinity589offset = (2*g-1)*max(TPv, TQv)590if offset == +Infinity:591offset = (2*g-1)*min(TPv,TQv)592if (offset > prec and (xTPv <0 or xTQv <0) and (self.residue_disc(P) == self.change_ring(GF(p))(0,1,0) or self.residue_disc(Q) == self.change_ring(GF(p))(0,1,0))):593newprec = offset + prec594K = pAdicField(p,newprec)595A = PolynomialRing(RationalField(),'x')596f = A(self.hyperelliptic_polynomials()[0])597from sage.schemes.hyperelliptic_curves.constructor import HyperellipticCurve598self = HyperellipticCurve(f).change_ring(K)599xP = P[0]600xPv = xP.valuation()601xPnew = K(sum(xP.list()[i]*p**(xPv + i) for i in range(len(xP.list()))))602PP = P = self.lift_x(xPnew)603TP = self.frobenius(P)604xQ = Q[0]605xQv = xQ.valuation()606xQnew = K(sum(xQ.list()[i]*p**(xQv + i) for i in range(len(xQ.list()))))607QQ = Q = self.lift_x(xQnew)608TQ = self.frobenius(Q)609V = VectorSpace(K,dim)610P_to_TP = V(self.tiny_integrals_on_basis(P, TP))611if TQ == None:612TQ_to_Q = V(0)613else:614TQ_to_Q = V(self.tiny_integrals_on_basis(TQ, Q))615prof("mw calc")616try:617M_frob, forms = self._frob_calc618except AttributeError:619M_frob, forms = self._frob_calc = monsky_washnitzer.matrix_of_frobenius_hyperelliptic(self)620prof("eval f")621R = forms[0].base_ring()622try:623prof("eval f %s"%R)624if PP is None:625L = [-f(R(QQ[0]), R(QQ[1])) for f in forms] ##changed626elif QQ is None:627L = [f(R(PP[0]), R(PP[1])) for f in forms]628else:629L = [f(R(PP[0]), R(PP[1])) - f(R(QQ[0]), R(QQ[1])) for f in forms]630except ValueError:631prof("changing rings")632forms = [f.change_ring(self.base_ring()) for f in forms]633prof("eval f %s"%self.base_ring())634if PP is None:635L = [-f(QQ[0], QQ[1]) for f in forms] ##changed636elif QQ is None:637L = [f(PP[0], PP[1]) for f in forms]638else:639L = [f(PP[0], PP[1]) - f(QQ[0], QQ[1]) for f in forms]640b = V(L)641if PP is None:642b -= TQ_to_Q643elif QQ is None:644b -= P_to_TP645elif algorithm != 'teichmuller':646b -= P_to_TP + TQ_to_Q647prof("lin alg")648M_sys = matrix(K, M_frob).transpose() - 1649TP_to_TQ = M_sys**(-1) * b650prof("done")651# print prof652if algorithm == 'teichmuller':653return P_to_TP + TP_to_TQ + TQ_to_Q654else:655return TP_to_TQ656657coleman_integrals_on_basis_hyperelliptic = coleman_integrals_on_basis658659660# def invariant_differential(self):661# """662# Returns the invariant differential $dx/2y$ on self663#664# EXAMPLES::665#666# sage: R.<x> = QQ['x']667# sage: H = HyperellipticCurve(x^3+1)668# sage: K = Qp(5,8)669# sage: HK = H.change_ring(K)670# sage: w = HK.invariant_differential(); w671# (((1+O(5^8)))*1) dx/2y672#673# ::674#675# sage: K = pAdicField(11, 6)676# sage: x = polygen(K)677# sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16)678# sage: C.invariant_differential()679# (((1+O(11^6)))*1) dx/2y680#681# """682# import sage.schemes.elliptic_curves.monsky_washnitzer as monsky_washnitzer683# S = monsky_washnitzer.SpecialHyperellipticQuotientRing(self)684# MW = monsky_washnitzer.MonskyWashnitzerDifferentialRing(S)685# return MW.invariant_differential()686687def coleman_integral(self, w, P, Q, algorithm = 'None'):688r"""689Returns the Coleman integral $\int_P^Q w$690691INPUT:692693- w differential (if one of P,Q is Weierstrass, w must be odd)694- P point on self695- Q point on self696- algorithm (optional) = None (uses Frobenius) or teichmuller (uses Teichmuller points)697698OUTPUT:699700the Coleman integral $\int_P^Q w$701702EXAMPLES::703704Example of Leprevost from Kiran Kedlaya705The first two should be zero as $(P-Q) = 30(P-Q)$ in the Jacobian706and $dx/2y$ and $x dx/2y$ are holomorphic.707708sage: K = pAdicField(11, 6)709sage: x = polygen(K)710sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16)711sage: P = C(-1, 1); P1 = C(-1, -1)712sage: Q = C(0, 1/4); Q1 = C(0, -1/4)713sage: x, y = C.monsky_washnitzer_gens()714sage: w = C.invariant_differential()715sage: w.coleman_integral(P, Q)716O(11^6)717sage: C.coleman_integral(x*w, P, Q)718O(11^6)719sage: C.coleman_integral(x^2*w, P, Q)7207*11 + 6*11^2 + 3*11^3 + 11^4 + 5*11^5 + O(11^6)721722::723724sage: p = 71; m = 4725sage: K = pAdicField(p, m)726sage: x = polygen(K)727sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16)728sage: P = C(-1, 1); P1 = C(-1, -1)729sage: Q = C(0, 1/4); Q1 = C(0, -1/4)730sage: x, y = C.monsky_washnitzer_gens()731sage: w = C.invariant_differential()732sage: w.integrate(P, Q), (x*w).integrate(P, Q)733(O(71^4), O(71^4))734sage: R, R1 = C.lift_x(4, all=True)735sage: w.integrate(P, R)73621*71 + 67*71^2 + 27*71^3 + O(71^4)737sage: w.integrate(P, R) + w.integrate(P1, R1)738O(71^4)739740A simple example, integrating dx::741742sage: R.<x> = QQ['x']743sage: E= HyperellipticCurve(x^3-4*x+4)744sage: K = Qp(5,10)745sage: EK = E.change_ring(K)746sage: P = EK(2, 2)747sage: Q = EK.teichmuller(P)748sage: x, y = EK.monsky_washnitzer_gens()749sage: EK.coleman_integral(x.diff(), P, Q)7505 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10)751sage: Q[0] - P[0]7525 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10)753754Yet another example::755756sage: R.<x> = QQ['x']757sage: H = HyperellipticCurve(x*(x-1)*(x+9))758sage: K = Qp(7,10)759sage: HK = H.change_ring(K)760sage: import sage.schemes.elliptic_curves.monsky_washnitzer as mw761sage: M_frob, forms = mw.matrix_of_frobenius_hyperelliptic(HK)762sage: w = HK.invariant_differential()763sage: x,y = HK.monsky_washnitzer_gens()764sage: f = forms[0]765sage: S = HK(9,36)766sage: Q = HK.teichmuller(S)767sage: P = HK(-1,4)768sage: b = x*w*w._coeff.parent()(f)769sage: HK.coleman_integral(b,P,Q)7707 + 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)771772::773774sage: R.<x> = QQ['x']775sage: H = HyperellipticCurve(x^3+1)776sage: K = Qp(5,8)777sage: HK = H.change_ring(K)778sage: w = HK.invariant_differential()779sage: P = HK(0,1)780sage: Q = HK.lift_x(5)781sage: x,y = HK.monsky_washnitzer_gens()782sage: (2*y*w).coleman_integral(P,Q)7835 + O(5^9)784sage: xloc,yloc,zloc = HK.local_analytic_interpolation(P,Q)785sage: I2 = (xloc.derivative()/(2*yloc)).integral()786sage: I2(1)-I2(0)7873*5 + 2*5^2 + 2*5^3 + 5^4 + 4*5^6 + 5^7 + O(5^9)788sage: HK.coleman_integral(w,P,Q)7893*5 + 2*5^2 + 2*5^3 + 5^4 + 4*5^6 + 5^7 + O(5^9)790791Integrals involving Weierstrass points::792793sage: R.<x> = QQ['x']794sage: H = HyperellipticCurve(x^3-10*x+9)795sage: K = Qp(5,8)796sage: HK = H.change_ring(K)797sage: S = HK(1,0)798sage: P = HK(0,3)799sage: negP = HK(0,-3)800sage: T = HK(0,1,0)801sage: w = HK.invariant_differential()802sage: x,y = HK.monsky_washnitzer_gens()803sage: HK.coleman_integral(w*x^3,S,T)8040805sage: HK.coleman_integral(w*x^3,T,S)8060807sage: HK.coleman_integral(w,S,P)8082*5^2 + 5^4 + 5^5 + 3*5^6 + 3*5^7 + 2*5^8 + O(5^9)809sage: HK.coleman_integral(w,T,P)8102*5^2 + 5^4 + 5^5 + 3*5^6 + 3*5^7 + 2*5^8 + O(5^9)811sage: HK.coleman_integral(w*x^3,T,P)8125^2 + 2*5^3 + 3*5^6 + 3*5^7 + O(5^8)813sage: HK.coleman_integral(w*x^3,S,P)8145^2 + 2*5^3 + 3*5^6 + 3*5^7 + O(5^8)815sage: HK.coleman_integral(w, P, negP, algorithm='teichmuller')8165^2 + 4*5^3 + 2*5^4 + 2*5^5 + 3*5^6 + 2*5^7 + 4*5^8 + O(5^9)817sage: HK.coleman_integral(w, P, negP)8185^2 + 4*5^3 + 2*5^4 + 2*5^5 + 3*5^6 + 2*5^7 + 4*5^8 + O(5^9)819820AUTHORS:821822- Robert Bradshaw (2007-03)823- Kiran Kedlaya (2008-05)824- Jennifer Balakrishnan (2010-02)825826"""827# TODO: implement Jacobians and show the relationship directly828import sage.schemes.elliptic_curves.monsky_washnitzer as monsky_washnitzer829K = self.base_ring()830prec = K.precision_cap()831S = monsky_washnitzer.SpecialHyperellipticQuotientRing(self, K)832MW = monsky_washnitzer.MonskyWashnitzerDifferentialRing(S)833w = MW(w)834f, vec = w.reduce_fast()835basis_values = self.coleman_integrals_on_basis(P, Q, algorithm)836dim = len(basis_values)837x,y = self.local_coordinates_at_infinity(2*prec)838if self.is_weierstrass(P):839if self.is_weierstrass(Q):840return 0841elif f == 0:842return sum([vec[i] * basis_values[i] for i in range(dim)])843elif w._coeff(x,-y)*x.derivative()/(-2*y)+w._coeff(x,y)*x.derivative()/(2*y) == 0:844return self.coleman_integral(w,self(Q[0],-Q[1]), self(Q[0],Q[1]), algorithm)/2845else:846raise ValueError, "The differential is not odd: use coleman_integral_from_weierstrass_via_boundary"847848elif self.is_weierstrass(Q):849if f == 0:850return sum([vec[i] * basis_values[i] for i in range(dim)])851elif w._coeff(x,-y)*x.derivative()/(-2*y)+w._coeff(x,y)*x.derivative()/(2*y) == 0:852return -self.coleman_integral(w,self(P[0],-P[1]), self(P[0],P[1]), algorithm)/2853else:854raise ValueError, "The differential is not odd: use coleman_integral_from_weierstrass_via_boundary"855else:856return f(Q[0], Q[1]) - f(P[0], P[1]) + sum([vec[i] * basis_values[i] for i in range(dim)]) # this is just a dot product...857858def frobenius(self, P=None):859"""860Returns the $p$-th power lift of Frobenius of $P$861862EXAMPLES::863864sage: K = Qp(11, 5)865sage: R.<x> = K[]866sage: E = HyperellipticCurve(x^5 - 21*x - 20)867sage: P = E.lift_x(2)868sage: E.frobenius(P)869(2 + 10*11 + 5*11^2 + 11^3 + O(11^5) : 5 + 9*11 + 2*11^2 + 2*11^3 + O(11^5) : 1 + O(11^5))870sage: Q = E.teichmuller(P); Q871(2 + 10*11 + 4*11^2 + 9*11^3 + 11^4 + O(11^5) : 5 + 9*11 + 6*11^2 + 11^3 + 6*11^4 + O(11^5) : 1 + O(11^5))872sage: E.frobenius(Q)873(2 + 10*11 + 4*11^2 + 9*11^3 + 11^4 + O(11^5) : 5 + 9*11 + 6*11^2 + 11^3 + 6*11^4 + O(11^5) : 1 + O(11^5))874875::876877sage: R.<x> = QQ[]878sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x)879sage: Q = H(0,0)880sage: u,v = H.local_coord(Q,prec=100)881sage: K = Qp(11,5)882sage: L.<a> = K.extension(x^20-11)883sage: HL = H.change_ring(L)884sage: S = HL(u(a),v(a))885sage: HL.frobenius(S)886(8*a^22 + 10*a^42 + 4*a^44 + 2*a^46 + 9*a^48 + 8*a^50 + a^52 + 7*a^54 +8877*a^56 + 5*a^58 + 9*a^62 + 5*a^64 + a^66 + 6*a^68 + a^70 + 6*a^74 +8882*a^76 + 2*a^78 + 4*a^82 + 5*a^84 + 2*a^86 + 7*a^88 + a^90 + 6*a^92 +889a^96 + 5*a^98 + 2*a^102 + 2*a^106 + 6*a^108 + 8*a^110 + 3*a^112 +890a^114 + 8*a^116 + 10*a^118 + 3*a^120 + O(a^122) :891a^11 + 7*a^33 + 7*a^35 + 4*a^37 + 6*a^39 + 9*a^41 + 8*a^43 + 8*a^45 +892a^47 + 7*a^51 + 4*a^53 + 5*a^55 + a^57 + 7*a^59 + 5*a^61 + 9*a^63 +8934*a^65 + 10*a^69 + 3*a^71 + 2*a^73 + 9*a^75 + 10*a^77 + 6*a^79 +89410*a^81 + 7*a^85 + a^87 + 4*a^89 + 8*a^91 + a^93 + 8*a^95 + 2*a^97 +8957*a^99 + a^101 + 3*a^103 + 6*a^105 + 7*a^107 + 4*a^109 + O(a^111) :8961 + O(a^100))897898AUTHORS:899900- Robert Bradshaw and Jennifer Balakrishnan (2010-02)901"""902try:903_frob = self._frob904except AttributeError:905K = self.base_ring()906p = K.prime()907x = K['x'].gen(0)908909f, f2 = self.hyperelliptic_polynomials()910if f2 != 0:911raise NotImplementedError, "Curve must be in weierstrass normal form."912h = (f(x**p) - f**p)913914def _frob(P):915if P == self(0,1,0):916return P917x0 = P[0]918y0 = P[1]919try:920uN = (1 + h(x0)/y0**(2*p)).sqrt()921yres=y0**p * uN922xres=x0**p923if (yres-y0).valuation() == 0:924yres=-yres925return self.point([xres,yres, K(1)])926except (TypeError, NotImplementedError):927uN2 = 1 + h(x0)/y0**(2*p)928#yfrob2 = f(x)929c = uN2.list()[0]930v = uN2.valuation()931a = uN2.parent().gen()932uN = self.newton_sqrt(uN2,c.sqrt()*a**(v//2),K.precision_cap())933yres = y0**p *uN934xres = x0**p935if (yres - y0).valuation() == 0:936yres = -yres937try:938return self(xres,yres)939except ValueError:940return self._curve_over_ram_extn(xres,yres)941942self._frob = _frob943944if P is None:945return _frob946else:947return _frob(P)948949def newton_sqrt(self,f,x0, prec):950r"""951Takes the square root of the power series $f$ by Newton's method952953NOTE:954955this function should eventually be moved to $p$-adic power series ring956957INPUT:958959- f power series wtih coefficients in $\Q_p$ or an extension960- x0 seeds the Newton iteration961- prec precision962963OUTPUT:964965the square root of $f$966967EXAMPLES::968969sage: R.<x> = QQ['x']970sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x)971sage: Q = H(0,0)972sage: u,v = H.local_coord(Q,prec=100)973sage: K = Qp(11,5)974sage: HK = H.change_ring(K)975sage: L.<a> = K.extension(x^20-11)976sage: HL = H.change_ring(L)977sage: S = HL(u(a),v(a))978sage: f = H.hyperelliptic_polynomials()[0]979sage: y = HK.newton_sqrt( f(u(a)^11), a^11,5)980sage: y^2 - f(u(a)^11)981O(a^122)982983AUTHOR:984985- Jennifer Balakrishnan986987"""988z = x0989try:990x = f.parent().variable_name()991if x!='a' : #this is to distinguish between extensions of Qp that are finite vs. not992S = f.base_ring()[[x]]993x = S.gen()994except ValueError:995pass996z = x0997loop_prec = (log(RR(prec))/log(RR(2))).ceil()998for i in range(loop_prec):999z = (z+f/z)/21000try:1001return z + O(x**prec)1002except (NameError,ArithmeticError,TypeError):1003return z10041005def curve_over_ram_extn(self,deg):1006r"""1007Returns self over $\Q_p(p^(1/deg))$10081009INPUT:10101011- deg: the degree of the ramified extension10121013OUTPUT:10141015self over $\Q_p(p^(1/deg))$10161017EXAMPLES::10181019sage: R.<x> = QQ['x']1020sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x)1021sage: K = Qp(11,5)1022sage: HK = H.change_ring(K)1023sage: HL = HK.curve_over_ram_extn(2)1024sage: HL1025Hyperelliptic Curve over Eisenstein Extension of 11-adic Field with capped relative precision 5 in a defined by (1 + O(11^5))*x^2 + (O(11^6))*x + (10*11 + 10*11^2 + 10*11^3 + 10*11^4 + 10*11^5 + O(11^6)) 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))*x10261027AUTHOR:10281029- Jennifer Balakrishnan10301031"""1032from sage.schemes.hyperelliptic_curves.constructor import HyperellipticCurve1033K = self.base_ring()1034p = K.prime()1035A = PolynomialRing(QQ,'x')1036x = A.gen()1037J = K.extension(x**deg-p,names='a')1038pol = self.hyperelliptic_polynomials()[0]1039H = HyperellipticCurve(A(pol))1040HJ = H.change_ring(J)1041self._curve_over_ram_extn = HJ1042self._curve_over_ram_extn._curve_over_Qp = self1043return HJ10441045def get_boundary_point(self, curve_over_extn, P):1046"""1047Given self over an extension field, find a point in the disc of $P$ near the boundary10481049INPUT:10501051- curve_over_extn: self over a totally ramified extension1052- P: Weierstrass point10531054OUTPUT:10551056a point in the disc of $P$ near the boundary10571058EXAMPLES::10591060sage: R.<x> = QQ['x']1061sage: H = HyperellipticCurve(x^3-10*x+9)1062sage: K = Qp(3,6)1063sage: HK = H.change_ring(K)1064sage: P = HK(1,0)1065sage: J.<a> = K.extension(x^30-3)1066sage: HJ = H.change_ring(J)1067sage: S = HK.get_boundary_point(HJ,P)1068sage: S1069(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^181) : 1 + O(a^180))10701071AUTHOR:10721073- Jennifer Balakrishnan10741075"""1076J = curve_over_extn.base_ring()1077a = J.gen()1078prec2 = J.precision_cap()1079x,y = self.local_coord(P,prec2)1080return curve_over_extn(x(a),y(a))10811082def P_to_S(self, P, S):1083r"""1084Given a finite Weierstrass point $P$ and a point $S$1085in the same disc, computes the Coleman integrals $\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}$10861087INPUT:10881089- P: finite Weierstrass point1090- S: point in disc of P10911092OUTPUT:10931094Coleman integrals $\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}$10951096EXAMPLES::10971098sage: R.<x> = QQ['x']1099sage: H = HyperellipticCurve(x^3-10*x+9)1100sage: K = Qp(5,4)1101sage: HK = H.change_ring(K)1102sage: P = HK(1,0)1103sage: HJ = HK.curve_over_ram_extn(10)1104sage: S = HK.get_boundary_point(HJ,P)1105sage: HK.P_to_S(P, S)1106(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 + 3*a^33 + O(a^35))11071108AUTHOR:11091110- Jennifer Balakrishnan11111112"""1113prec = self.base_ring().precision_cap()1114deg = (S[0]).parent().defining_polynomial().degree()1115prec2= prec*deg1116x,y = self.local_coord(P,prec2)1117g = self.genus()1118integrals = [((x**k*x.derivative()/(2*y)).integral()) for k in range(2*g)]1119val = [I(S[1]) for I in integrals]1120return vector(val)11211122def coleman_integral_P_to_S(self,w,P,S):1123r"""1124Given a finite Weierstrass point $P$ and a point $S$1125in the same disc, computes the Coleman integral $\int_P^S w$11261127INPUT:11281129- w: differential1130- P: Weierstrass point1131- S: point in the same disc of P (S is defined over an extension of $\Q_p$; coordinates1132of S are given in terms of uniformizer $a$)11331134OUTPUT:11351136Coleman integral $\int_P^S w$ in terms of $a$11371138EXAMPLES::11391140sage: R.<x> = QQ['x']1141sage: H = HyperellipticCurve(x^3-10*x+9)1142sage: K = Qp(5,4)1143sage: HK = H.change_ring(K)1144sage: P = HK(1,0)1145sage: J.<a> = K.extension(x^10-5)1146sage: HJ = H.change_ring(J)1147sage: S = HK.get_boundary_point(HJ,P)1148sage: x,y = HK.monsky_washnitzer_gens()1149sage: S[0]-P[0] == HK.coleman_integral_P_to_S(x.diff(),P,S)1150True1151sage: HK.coleman_integral_P_to_S(HK.invariant_differential(),P,S) == HK.P_to_S(P,S)[0]1152True11531154AUTHOR:11551156- Jennifer Balakrishnan11571158"""1159prec = self.base_ring().precision_cap()1160deg = S[0].parent().defining_polynomial().degree()1161prec2= prec*deg1162x,y = self.local_coord(P,prec2)1163g = self.genus()1164int_sing = (w.coeff()(x,y)*x.derivative()/(2*y)).integral()1165int_sing_a = int_sing(S[1])1166return int_sing_a11671168def S_to_Q(self,S,Q):1169r"""1170Given $S$ a point on self over an extension field, computes the1171Coleman integrals $\{\int_S^Q x^i dx/2y \}_{i=0}^{2g-1}$11721173**one should be able to feed $S,Q$ into coleman_integral,1174but currently that segfaults**11751176INPUT:11771178- S: a point with coordinates in an extension of $\Q_p$ (with unif. a)1179- Q: a non-Weierstrass point defined over $\Q_p$11801181OUTPUT:11821183the Coleman integrals $\{\int_S^Q x^i dx/2y \}_{i=0}^{2g-1}$ in terms of $a$11841185EXAMPLES::11861187sage: R.<x> = QQ['x']1188sage: H = HyperellipticCurve(x^3-10*x+9)1189sage: K = Qp(5,6)1190sage: HK = H.change_ring(K)1191sage: J.<a> = K.extension(x^20-5)1192sage: HJ = H.change_ring(J)1193sage: w = HK.invariant_differential()1194sage: x,y = HK.monsky_washnitzer_gens()1195sage: P = HK(1,0)1196sage: Q = HK(0,3)1197sage: S = HK.get_boundary_point(HJ,P)1198sage: P_to_S = HK.P_to_S(P,S)1199sage: S_to_Q = HJ.S_to_Q(S,Q)1200sage: P_to_S + S_to_Q1201(2*a^40 + a^80 + a^100 + O(a^105), a^20 + 2*a^40 + 4*a^60 + 2*a^80 + O(a^105))1202sage: HK.coleman_integrals_on_basis(P,Q)1203(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))12041205AUTHOR:12061207- Jennifer Balakrishnan12081209"""1210FS = self.frobenius(S)1211FS = (FS[0],FS[1])1212FQ = self.frobenius(Q)1213import sage.schemes.elliptic_curves.monsky_washnitzer as monsky_washnitzer1214try:1215M_frob, forms = self._frob_calc1216except AttributeError:1217M_frob, forms = self._frob_calc = monsky_washnitzer.matrix_of_frobenius_hyperelliptic(self)1218try:1219HJ = self._curve_over_ram_extn1220K = HJ.base_ring()1221except AttributeError:1222HJ = S.scheme()1223K = self.base_ring()1224g = self.genus()1225prec2 = K.precision_cap()1226p = K.prime()1227dim = 2*g1228V = VectorSpace(K,dim)1229if S == FS:1230S_to_FS = V(dim*[0])1231else:1232P = self(ZZ(FS[0][0]),ZZ(FS[1][0]))1233x,y = self.local_coord(P,prec2)1234integrals = [(x**i*x.derivative()/(2*y)).integral() for i in range(dim)]1235S_to_FS = vector([I(FS[1])-I(S[1]) for I in integrals])1236if HJ(Q[0],Q[1]) == HJ(FQ):1237FQ_to_Q = V(dim*[0])1238else:1239FQ_to_Q = V(self.tiny_integrals_on_basis(FQ, Q))1240try:1241L = [f(K(S[0]), K(S[1])) - f(K(Q[0]), K(Q[1])) for f in forms]1242except ValueError:1243forms = [f.change_ring(K) for f in forms]1244L = [f(S[0], S[1]) - f(Q[0], Q[1]) for f in forms]1245b = V(L)1246M_sys = matrix(K, M_frob).transpose() - 11247B = (~M_sys)1248v = [B.list()[i].valuation() for i in range(len(B.list()))]1249vv= min(v)1250B = (p**(-vv)*B).change_ring(K)1251B = p**(vv)*B1252return B*(b-S_to_FS-FQ_to_Q)12531254def coleman_integral_S_to_Q(self,w,S,Q):1255r"""1256Computes the Coleman integral $\int_S^Q w$12571258**one should be able to feed $S,Q$ into coleman_integral,1259but currently that segfaults**12601261INPUT:12621263- w: a differential1264- S: a point with coordinates in an extension of $\Q_p$1265- Q: a non-Weierstrass point defined over $\Q_p$12661267OUTPUT:12681269the Coleman integral $\int_S^Q w$12701271EXAMPLES::12721273sage: R.<x> = QQ['x']1274sage: H = HyperellipticCurve(x^3-10*x+9)1275sage: K = Qp(5,6)1276sage: HK = H.change_ring(K)1277sage: J.<a> = K.extension(x^20-5)1278sage: HJ = H.change_ring(J)1279sage: x,y = HK.monsky_washnitzer_gens()1280sage: P = HK(1,0)1281sage: Q = HK(0,3)1282sage: S = HK.get_boundary_point(HJ,P)1283sage: P_to_S = HK.coleman_integral_P_to_S(y.diff(),P,S)1284sage: S_to_Q = HJ.coleman_integral_S_to_Q(y.diff(),S,Q)1285sage: P_to_S + S_to_Q12863 + O(a^120)1287sage: HK.coleman_integral(y.diff(),P,Q)12883 + O(5^6)12891290AUTHOR:12911292- Jennifer Balakrishnan12931294"""1295import sage.schemes.elliptic_curves.monsky_washnitzer as monsky_washnitzer1296K = self.base_ring()1297R = monsky_washnitzer.SpecialHyperellipticQuotientRing(self, K)1298MW = monsky_washnitzer.MonskyWashnitzerDifferentialRing(R)1299w = MW(w)1300f, vec = w.reduce_fast()1301g = self.genus()1302const = f(Q[0],Q[1])-f(S[0],S[1])1303if vec == vector(2*g*[0]):1304return const1305else:1306basis_values = self.S_to_Q(S, Q)1307dim = len(basis_values)1308dot = sum([vec[i] * basis_values[i] for i in range(dim)])1309return const + dot13101311def coleman_integral_from_weierstrass_via_boundary(self, w, P, Q, d):1312r"""1313Computes the Coleman integral $\int_P^Q w$ via a boundary point1314in the disc of $P$, defined over a degree $d$ extension13151316INPUT:13171318- w: a differential1319- P: a Weierstrass point1320- Q: a non-Weierstrass point1321- d: degree of extension where coordinates of boundary point lie13221323OUTPUT:13241325the Coleman integral $\int_P^Q w$, written in terms of the uniformizer1326$a$ of the degree $d$ extension13271328EXAMPLES::13291330sage: R.<x> = QQ['x']1331sage: H = HyperellipticCurve(x^3-10*x+9)1332sage: K = Qp(5,6)1333sage: HK = H.change_ring(K)1334sage: P = HK(1,0)1335sage: Q = HK(0,3)1336sage: x,y = HK.monsky_washnitzer_gens()1337sage: HK.coleman_integral_from_weierstrass_via_boundary(y.diff(),P,Q,20)13383 + O(a^120)1339sage: HK.coleman_integral(y.diff(),P,Q)13403 + O(5^6)1341sage: w = HK.invariant_differential()1342sage: HK.coleman_integral_from_weierstrass_via_boundary(w,P,Q,20)13432*a^40 + a^80 + a^100 + O(a^105)1344sage: HK.coleman_integral(w,P,Q)13452*5^2 + 5^4 + 5^5 + 3*5^6 + O(5^7)13461347AUTHOR:13481349- Jennifer Balakrishnan13501351"""1352HJ = self.curve_over_ram_extn(d)1353S = self.get_boundary_point(HJ,P)1354P_to_S = self.coleman_integral_P_to_S(w,P,S)1355S_to_Q = HJ.coleman_integral_S_to_Q(w,S,Q)1356return P_to_S + S_to_Q135713581359