def local_coordinates_at_nonweierstrass(self, P, prec=20, name='t'): """ For a non-Weierstrass point `P = (a,b)` on the hyperelliptic curve `y^2 = f(x)`, return `(x(t), y(t))` such that `(y(t))^2 = f(x(t))`, where `t = x - a` is the local parameter. INPUT: - ``P = (a, b)`` -- a non-Weierstrass point on self - ``prec`` -- desired precision of the local coordinates - ``name`` -- gen of the power series ring (default: ``t``) OUTPUT: `(x(t),y(t))` such that `y(t)^2 = f(x(t))` and `t = x - a` is the local parameter at `P` EXAMPLES:: sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) sage: P = H(1,6) sage: x,y = H.local_coordinates_at_nonweierstrass(P,prec=5) sage: x 1 + t + O(t^5) sage: y 6 + t - 7/2*t^2 - 1/2*t^3 - 25/48*t^4 + O(t^5) sage: Q = H(-2,12) sage: x,y = H.local_coordinates_at_nonweierstrass(Q,prec=5) sage: x -2 + t + O(t^5) sage: y 12 - 19/2*t - 19/32*t^2 + 61/256*t^3 - 5965/24576*t^4 + O(t^5) AUTHOR: - Jennifer Balakrishnan (2007-12) """ d = P[1] if d == 0: raise TypeError( "P = %s is a Weierstrass point. Use local_coordinates_at_weierstrass instead!" % P) pol = self.hyperelliptic_polynomials()[0] L = PowerSeriesRing(self.base_ring(), name) t = L.gen() L.set_default_prec(prec) K = PowerSeriesRing(L, 'x') pol = K(pol) x = K.gen() b = P[0] f = pol(t + b) for i in range((RR(log(prec) / log(2))).ceil()): d = (d + f / d) / 2 return t + b + O(t**(prec)), d + O(t**(prec))
def local_coordinates_at_nonweierstrass(self, P, prec=20, name='t'): """ For a non-Weierstrass point `P = (a,b)` on the hyperelliptic curve `y^2 = f(x)`, return `(x(t), y(t))` such that `(y(t))^2 = f(x(t))`, where `t = x - a` is the local parameter. INPUT: - ``P = (a, b)`` -- a non-Weierstrass point on self - ``prec`` -- desired precision of the local coordinates - ``name`` -- gen of the power series ring (default: ``t``) OUTPUT: `(x(t),y(t))` such that `y(t)^2 = f(x(t))` and `t = x - a` is the local parameter at `P` EXAMPLES:: sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) sage: P = H(1,6) sage: x,y = H.local_coordinates_at_nonweierstrass(P,prec=5) sage: x 1 + t + O(t^5) sage: y 6 + t - 7/2*t^2 - 1/2*t^3 - 25/48*t^4 + O(t^5) sage: Q = H(-2,12) sage: x,y = H.local_coordinates_at_nonweierstrass(Q,prec=5) sage: x -2 + t + O(t^5) sage: y 12 - 19/2*t - 19/32*t^2 + 61/256*t^3 - 5965/24576*t^4 + O(t^5) AUTHOR: - Jennifer Balakrishnan (2007-12) """ d = P[1] if d == 0: raise TypeError("P = %s is a Weierstrass point. Use local_coordinates_at_weierstrass instead!"%P) pol = self.hyperelliptic_polynomials()[0] L = PowerSeriesRing(self.base_ring(), name) t = L.gen() L.set_default_prec(prec) K = PowerSeriesRing(L, 'x') pol = K(pol) x = K.gen() b = P[0] f = pol(t+b) for i in range((RR(log(prec)/log(2))).ceil()): d = (d + f/d)/2 return t+b+O(t**(prec)), d + O(t**(prec))
def local_coordinates_at_weierstrass(self, P, prec=20, name='t'): """ For a finite Weierstrass point on the hyperelliptic curve y^2 = f(x), returns (x(t), y(t)) such that (y(t))^2 = f(x(t)), where t = y is the local parameter. INPUT: - P a finite Weierstrass point on self - prec: desired precision of the local coordinates - name: gen of the power series ring (default: 't') OUTPUT: (x(t),y(t)) such that y(t)^2 = f(x(t)) and t = y is the local parameter at P EXAMPLES: sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) sage: A = H(4,0) sage: x,y = H.local_coordinates_at_weierstrass(A,prec =5) sage: x 4 + 1/360*t^2 - 191/23328000*t^4 + 7579/188956800000*t^6 + O(t^7) sage: y t + O(t^7) sage: B = H(-5,0) sage: x,y = H.local_coordinates_at_weierstrass(B,prec = 5) sage: x -5 + 1/1260*t^2 + 887/2000376000*t^4 + 643759/1587898468800000*t^6 + O(t^7) sage: y t + O(t^7) AUTHOR: - Jennifer Balakrishnan (2007-12) """ if P[1] != 0: raise TypeError, "P = %s is not a finite Weierstrass point. Use local_coordinates_at_nonweierstrass instead!" % P pol = self.hyperelliptic_polynomials()[0] L = PowerSeriesRing(self.base_ring(), name) t = L.gen() L.set_default_prec(prec + 2) K = PowerSeriesRing(L, 'x') pol = K(pol) x = K.gen() b = P[0] g = pol / (x - b) c = b + 1 / g(b) * t**2 f = pol - t**2 fprime = f.derivative() for i in range((RR(log(prec + 2) / log(2))).ceil()): c = c - f(c) / fprime(c) return c + O(t**(prec + 2)), t + O(t**(prec + 2))
def local_coordinates_at_weierstrass(self, P, prec=20, name="t"): """ For a finite Weierstrass point on the hyperelliptic curve y^2 = f(x), returns (x(t), y(t)) such that (y(t))^2 = f(x(t)), where t = y is the local parameter. INPUT: - P a finite Weierstrass point on self - prec: desired precision of the local coordinates - name: gen of the power series ring (default: 't') OUTPUT: (x(t),y(t)) such that y(t)^2 = f(x(t)) and t = y is the local parameter at P EXAMPLES: sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) sage: A = H(4,0) sage: x,y = H.local_coordinates_at_weierstrass(A,prec =5) sage: x 4 + 1/360*t^2 - 191/23328000*t^4 + 7579/188956800000*t^6 + O(t^7) sage: y t + O(t^7) sage: B = H(-5,0) sage: x,y = H.local_coordinates_at_weierstrass(B,prec = 5) sage: x -5 + 1/1260*t^2 + 887/2000376000*t^4 + 643759/1587898468800000*t^6 + O(t^7) sage: y t + O(t^7) AUTHOR: - Jennifer Balakrishnan (2007-12) """ if P[1] != 0: raise TypeError, "P = %s is not a finite Weierstrass point. Use local_coordinates_at_nonweierstrass instead!" % P pol = self.hyperelliptic_polynomials()[0] L = PowerSeriesRing(self.base_ring(), name) t = L.gen() L.set_default_prec(prec + 2) K = PowerSeriesRing(L, "x") pol = K(pol) x = K.gen() b = P[0] g = pol / (x - b) c = b + 1 / g(b) * t ** 2 f = pol - t ** 2 fprime = f.derivative() for i in range((RR(log(prec + 2) / log(2))).ceil()): c = c - f(c) / fprime(c) return c + O(t ** (prec + 2)), t + O(t ** (prec + 2))
def double_integral_zero_infty(Phi, tau1, tau2): p = Phi.parent().prime() K = tau1.parent() R = PolynomialRing(K, 'x') x = R.gen() R1 = PowerSeriesRing(K, 'r1') r1 = R1.gen() try: R1.set_default_prec(Phi.precision_absolute()) except AttributeError: R1.set_default_prec(Phi.precision_relative()) level = Phi._map._manin.level() E0inf = [M2Z([0, -1, level, 0])] E0Zp = [M2Z([p, a, 0, 1]) for a in range(p)] predicted_evals = num_evals(tau1, tau2) a, b, c, d = find_center(p, level, tau1, tau2).list() h = M2Z([a, b, c, d]) E = [h * e0 for e0 in E0Zp + E0inf] resadd = 0 resmul = 1 total_evals = 0 percentage = QQ(0) ii = 0 f = (x - tau2) / (x - tau1) while len(E) > 0: ii += 1 increment = QQ((100 - percentage) / len(E)) verbose( 'remaining %s percent (and done %s of %s evaluations)' % (RealField(10)(100 - percentage), total_evals, predicted_evals)) newE = [] for e in E: a, b, c, d = e.list() assert ZZ(c) % level == 0 try: y0 = f((a * r1 + b) / (c * r1 + d)) val = y0(y0.parent().base_ring()(0)) if all([xx.valuation(p) > 0 for xx in (y0 / val - 1).list()]): if total_evals % 100 == 0: Phi._map._codomain.clear_cache() pol = val.log(p_branch=0) + ( (y0.derivative() / y0).integral()) V = [0] * pol.valuation() + pol.shift( -pol.valuation()).list() try: phimap = Phi._map(M2Z([b, d, a, c])) except OverflowError: print(a, b, c, d) raise OverflowError, 'Matrix too large?' # mu_e0 = ZZ(phimap.moment(0).rational_reconstruction()) mu_e0 = ZZ(Phi._liftee._map(M2Z([b, d, a, c])).moment(0)) mu_e = [mu_e0] + [ phimap.moment(o).lift() for o in range(1, len(V)) ] resadd += sum(starmap(mul, izip(V, mu_e))) resmul *= val**mu_e0 percentage += increment total_evals += 1 else: newE.extend([e * e0 for e0 in E0Zp]) except ZeroDivisionError: #raise RuntimeError,'Probably not enough working precision...' newE.extend([e * e0 for e0 in E0Zp]) E = newE verbose('total evaluations = %s' % total_evals) val = resmul.valuation() return p**val * K.teichmuller(p**(-val) * resmul) * resadd.exp()