def matrix_of_frobenius(self, p, prec=20): # BUG: should get this method from HyperellipticCurve_generic def my_chage_ring(self, R): from constructor import HyperellipticCurve f, h = self._hyperelliptic_polynomials y = self._printing_ring.gen() x = self._printing_ring.base_ring().gen() return HyperellipticCurve(f.change_ring(R), h, "%s,%s"%(x,y)) import sage.schemes.elliptic_curves.monsky_washnitzer as monsky_washnitzer if is_pAdicField(p) or is_pAdicRing(p): K = p else: K = pAdicField(p, prec) frob_p, forms = monsky_washnitzer.matrix_of_frobenius_hyperelliptic(my_chage_ring(self, K)) return frob_p
def matrix_of_frobenius(self, p, prec=20): # BUG: should get this method from HyperellipticCurve_generic def my_chage_ring(self, R): from constructor import HyperellipticCurve f, h = self._hyperelliptic_polynomials y = self._printing_ring.gen() x = self._printing_ring.base_ring().gen() return HyperellipticCurve(f.change_ring(R), h, "%s,%s" % (x, y)) import sage.schemes.elliptic_curves.monsky_washnitzer as monsky_washnitzer if is_pAdicField(p) or is_pAdicRing(p): K = p else: K = pAdicField(p, prec) frob_p, forms = monsky_washnitzer.matrix_of_frobenius_hyperelliptic( my_chage_ring(self, K)) return frob_p
def coleman_integrals_on_basis(self, P, Q, algorithm=None): r""" 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) (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)) sage: C.coleman_integrals_on_basis(P, Q, algorithm='teichmuller') (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)) :: 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.coleman_integrals_on_basis(P, Q) (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)) :: 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(0,1,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) (4*5 + 4*5^2 + 4*5^3 + O(5^4), 5^-1 + O(5^3)) sage: HK.coleman_integrals_on_basis(Q,R) (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)) 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 """ import sage.schemes.hyperelliptic_curves.monsky_washnitzer as monsky_washnitzer from sage.misc.profiler import Profiler prof = Profiler() prof("setup") K = self.base_ring() p = K.prime() prec = K.precision_cap() g = self.genus() dim = 2 * g V = VectorSpace(K, dim) #if P or Q is Weierstrass, use the Frobenius algorithm if self.is_weierstrass(P): if self.is_weierstrass(Q): return V(0) else: PP = None QQ = Q TP = None TQ = self.frobenius(Q) elif self.is_weierstrass(Q): PP = P QQ = None TQ = None TP = self.frobenius(P) elif self.is_same_disc(P, Q): return self.tiny_integrals_on_basis(P, Q) elif algorithm == 'teichmuller': prof("teichmuller") PP = TP = self.teichmuller(P) QQ = TQ = self.teichmuller(Q) evalP, evalQ = TP, TQ else: prof("frobPQ") TP = self.frobenius(P) TQ = self.frobenius(Q) PP, QQ = P, Q prof("tiny integrals") if TP is None: P_to_TP = V(0) else: if TP is not None: TPv = (TP[0]**g / TP[1]).valuation() xTPv = TP[0].valuation() else: xTPv = TPv = +Infinity if TQ is not None: TQv = (TQ[0]**g / TQ[1]).valuation() xTQv = TQ[0].valuation() else: xTQv = TQv = +Infinity offset = (2 * g - 1) * max(TPv, TQv) if offset == +Infinity: offset = (2 * g - 1) * min(TPv, TQv) if (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))): newprec = offset + prec K = pAdicField(p, newprec) A = PolynomialRing(RationalField(), 'x') f = A(self.hyperelliptic_polynomials()[0]) from sage.schemes.hyperelliptic_curves.constructor import HyperellipticCurve self = HyperellipticCurve(f).change_ring(K) xP = P[0] xPv = xP.valuation() xPnew = K( sum(c * p**(xPv + i) for i, c in enumerate(xP.expansion()))) PP = P = self.lift_x(xPnew) TP = self.frobenius(P) xQ = Q[0] xQv = xQ.valuation() xQnew = K( sum(c * p**(xQv + i) for i, c in enumerate(xQ.expansion()))) QQ = Q = self.lift_x(xQnew) TQ = self.frobenius(Q) V = VectorSpace(K, dim) P_to_TP = V(self.tiny_integrals_on_basis(P, TP)) if TQ is None: TQ_to_Q = V(0) else: TQ_to_Q = V(self.tiny_integrals_on_basis(TQ, Q)) prof("mw calc") try: M_frob, forms = self._frob_calc except AttributeError: M_frob, forms = self._frob_calc = monsky_washnitzer.matrix_of_frobenius_hyperelliptic( self) prof("eval f") R = forms[0].base_ring() try: prof("eval f %s" % R) if PP is None: L = [-f(R(QQ[0]), R(QQ[1])) for f in forms] ##changed elif QQ is None: L = [f(R(PP[0]), R(PP[1])) for f in forms] else: L = [ f(R(PP[0]), R(PP[1])) - f(R(QQ[0]), R(QQ[1])) for f in forms ] except ValueError: prof("changing rings") forms = [f.change_ring(self.base_ring()) for f in forms] prof("eval f %s" % self.base_ring()) if PP is None: L = [-f(QQ[0], QQ[1]) for f in forms] ##changed elif QQ is None: L = [f(PP[0], PP[1]) for f in forms] else: L = [f(PP[0], PP[1]) - f(QQ[0], QQ[1]) for f in forms] b = V(L) if PP is None: b -= TQ_to_Q elif QQ is None: b -= P_to_TP elif algorithm != 'teichmuller': b -= P_to_TP + TQ_to_Q prof("lin alg") M_sys = matrix(K, M_frob).transpose() - 1 TP_to_TQ = M_sys**(-1) * b prof("done") # print prof if algorithm == 'teichmuller': return P_to_TP + TP_to_TQ + TQ_to_Q else: return TP_to_TQ
def coleman_integrals_on_basis(self, P, Q, algorithm=None): r""" 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) (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)) sage: C.coleman_integrals_on_basis(P, Q, algorithm='teichmuller') (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)) :: 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.coleman_integrals_on_basis(P, Q) (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)) :: 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(0,1,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) (4*5 + 4*5^2 + 4*5^3 + O(5^4), 5^-1 + O(5^3)) sage: HK.coleman_integrals_on_basis(Q,R) (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)) 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 """ import sage.schemes.hyperelliptic_curves.monsky_washnitzer as monsky_washnitzer from sage.misc.profiler import Profiler prof = Profiler() prof("setup") K = self.base_ring() p = K.prime() prec = K.precision_cap() g = self.genus() dim = 2*g V = VectorSpace(K, dim) #if P or Q is Weierstrass, use the Frobenius algorithm if self.is_weierstrass(P): if self.is_weierstrass(Q): return V(0) else: PP = None QQ = Q TP = None TQ = self.frobenius(Q) elif self.is_weierstrass(Q): PP = P QQ = None TQ = None TP = self.frobenius(P) elif self.is_same_disc(P,Q): return self.tiny_integrals_on_basis(P,Q) elif algorithm == 'teichmuller': prof("teichmuller") PP = TP = self.teichmuller(P) QQ = TQ = self.teichmuller(Q) evalP, evalQ = TP, TQ else: prof("frobPQ") TP = self.frobenius(P) TQ = self.frobenius(Q) PP, QQ = P, Q prof("tiny integrals") if TP is None: P_to_TP = V(0) else: if TP is not None: TPv = (TP[0]**g/TP[1]).valuation() xTPv = TP[0].valuation() else: xTPv = TPv = +Infinity if TQ is not None: TQv = (TQ[0]**g/TQ[1]).valuation() xTQv = TQ[0].valuation() else: xTQv = TQv = +Infinity offset = (2*g-1)*max(TPv, TQv) if offset == +Infinity: offset = (2*g-1)*min(TPv,TQv) if (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))): newprec = offset + prec K = pAdicField(p,newprec) A = PolynomialRing(RationalField(),'x') f = A(self.hyperelliptic_polynomials()[0]) from sage.schemes.hyperelliptic_curves.constructor import HyperellipticCurve self = HyperellipticCurve(f).change_ring(K) xP = P[0] xPv = xP.valuation() xPnew = K(sum(xP.list()[i]*p**(xPv + i) for i in range(len(xP.list())))) PP = P = self.lift_x(xPnew) TP = self.frobenius(P) xQ = Q[0] xQv = xQ.valuation() xQnew = K(sum(xQ.list()[i]*p**(xQv + i) for i in range(len(xQ.list())))) QQ = Q = self.lift_x(xQnew) TQ = self.frobenius(Q) V = VectorSpace(K,dim) P_to_TP = V(self.tiny_integrals_on_basis(P, TP)) if TQ is None: TQ_to_Q = V(0) else: TQ_to_Q = V(self.tiny_integrals_on_basis(TQ, Q)) prof("mw calc") try: M_frob, forms = self._frob_calc except AttributeError: M_frob, forms = self._frob_calc = monsky_washnitzer.matrix_of_frobenius_hyperelliptic(self) prof("eval f") R = forms[0].base_ring() try: prof("eval f %s"%R) if PP is None: L = [-f(R(QQ[0]), R(QQ[1])) for f in forms] ##changed elif QQ is None: L = [f(R(PP[0]), R(PP[1])) for f in forms] else: L = [f(R(PP[0]), R(PP[1])) - f(R(QQ[0]), R(QQ[1])) for f in forms] except ValueError: prof("changing rings") forms = [f.change_ring(self.base_ring()) for f in forms] prof("eval f %s"%self.base_ring()) if PP is None: L = [-f(QQ[0], QQ[1]) for f in forms] ##changed elif QQ is None: L = [f(PP[0], PP[1]) for f in forms] else: L = [f(PP[0], PP[1]) - f(QQ[0], QQ[1]) for f in forms] b = V(L) if PP is None: b -= TQ_to_Q elif QQ is None: b -= P_to_TP elif algorithm != 'teichmuller': b -= P_to_TP + TQ_to_Q prof("lin alg") M_sys = matrix(K, M_frob).transpose() - 1 TP_to_TQ = M_sys**(-1) * b prof("done") # print prof if algorithm == 'teichmuller': return P_to_TP + TP_to_TQ + TQ_to_Q else: return TP_to_TQ