def to_polredabs(K): """ INPUT: * "K" - a number field OUTPUT: * "phi" - an isomorphism K -> L, where L = QQ['x']/f and f a polynomial such that f = polredabs(f) """ R = PolynomialRing(QQ, 'x') x = R.gen(0) if K == QQ: L = QQ.extension(x, 'w') return QQ.hom(L) L = K.absolute_field('a') m1 = L.structure()[1] f = L.absolute_polynomial() g = pari(f).polredabs(1) g, h = g[0].sage(locals={'x': x}), g[1].lift().sage(locals={'x': x}) if debug: print('f', f) print('g', g) print('h', h) M = QQ.extension(g, 'w') m2 = L.hom([h(M.gen(0))]) return m2 * m1
def to_polredabs(K): """ INPUT: * "K" - a number field OUTPUT: * "phi" - an isomorphism K -> L, where L = QQ['x']/f and f a polynomial such that f = polredabs(f) """ R = PolynomialRing(QQ,'x') x = R.gen(0) if K == QQ: L = QQ.extension(x,'w') return QQ.hom(L) L = K.absolute_field('a') m1 = L.structure()[1] f = L.absolute_polynomial() g = pari(f).polredabs(1) g,h = g[0].sage(locals={'x':x}),g[1].lift().sage(locals={'x':x}) if debug: print 'f',f print 'g',g print 'h',h M = QQ.extension(g,'w') m2 = L.hom([h(M.gen(0))]) return m2*m1
def compute_alpha_point(g, iaj, alpha, P0, digits, power, verbose, aggressive=True, append=""): # input: # * g, defining polynomial of the hyperelliptic curve # * iaj = InvertAJglobal class # * alpha = analytic representation of the endomorphism acting on the tangent space # * digits = how many digits to work with # * power, we will divide by 2**power before inverting the abel jacobi map # * P0, a point in the curve for which we will compute alpha*2(P - \infty) = P1 + P2 - \infty # * verbose # * agressive, raise ZeroDivisionError if we get a P1[0] = P2[0] or one of the points is infty # * append, a string to append to the numberfield generators # # output: a dictionary with the following keys # TODO add the keys output = {} K = alpha.base_ring() CCap = iaj.C prec = CCap.precision() output['prec'] = prec x0, y0 = P0 Kz = PolynomialRing(K, "z") z = Kz.gen() if verbose: print "compute_alpha_point()" print "P0 = %s" % (P0, ) #deal with the field of definition if y0 in K: if K is QQ: L = K from_K_to_L = QQ.hom(1, QQ) else: L = K.change_names("b" + append) from_K_to_L = L.structure()[1] else: L, from_K_to_L = (z**2 - g(x0)).splitting_field("b" + append, simplify_all=True, map=True) output['L'] = L # output['L_str'] = sage_str_numberfield(L, 'x','b'+append); output['from_K_to_L'] = from_K_to_L # output['L_gen'] = toCCap(L.gen(), 53); # figure out y0 in L y0_ap = toCCap(y0, prec) y0s = [elt for elt, _ in (z**2 - g(x0)).roots(L)] assert len(y0s) == 2 y0s_ap = [toCCap(elt, prec) for elt in y0s] if norm(y0_ap - y0s_ap[0]) < norm(y0_ap - y0s_ap[1]): y0 = y0s[0] else: y0 = y0s[1] P0 = vector(L, [x0, y0]) alpha_L = Matrix(L, [[from_K_to_L(elt) for elt in row] for row in alpha.rows()]) alpha_ap = Matrix(CCap, [toCCap_list(row, prec) for row in alpha_L.rows()]) output['P'] = P0 output['alpha'] = alpha_L if verbose: print "L = %s" % L print "%s = %s" % (L.gen(), toCCap(L.gen(), 53)) print "P0 = %s" % (P0, ) print "alpha = %s" % ([[elt for elt in row] for row in alpha_L.rows()], ) P0_ap = vector(CCap, toCCap_list(P0, prec + 192)) if verbose: print "P0_ap = %s" % (vector(CC, P0_ap), ) if verbose: print "Computing AJ of P0..." c, w = cputime(), walltime() ajP0 = vector(CCap, AJ1_digits(g, P0_ap, digits)) print "Time: CPU %.2f s, Wall: %.2f s" % ( cputime(c), walltime(w), ) print else: ajP0 = vector(CCap, AJ1_digits(g, P0_ap, digits)) output['ajP'] = ajP0 aj2P0 = 2 * ajP0 alpha2P0_an = alpha_ap * aj2P0 if verbose: print "Working over %s" % CCap invertAJ_tries = 3 for i in range(invertAJ_tries): #try invertAJ_tries times to invertAJ try: if verbose: print "\n\ninverting AJ..." c, w = cputime(), walltime() alpha2P0_div = iaj.invertAJ(alpha2P0_an, power) print "Time: CPU %.2f s, Wall: %.2f s" % ( cputime(c), walltime(w), ) print "\n\n" else: alpha2P0_div = iaj.invertAJ(alpha2P0_an, power) break except AssertionError as error: print error if verbose: print "an assertion failed while inverting AJ.." if i == invertAJ_tries - 1: if verbose: print "retrying with a new P0" print raise ZeroDivisionError else: iaj.iajlocal.set_basepoints() if verbose: print "retrying again with a new set of base points" if verbose: print "Computing the Mumford coordinates of alpha(2*P0 - 2*W)" c, w = cputime(), walltime() R0, R1 = alpha2P0_div.coordinates() print "Time: CPU %.2f s, Wall: %.2f s" % ( cputime(c), walltime(w), ) else: R0, R1 = alpha2P0_div.coordinates() points = [R0, R1] x_poly = alpha2P0_div.x_coordinates() output['R'] = points output['x_poly'] = x_poly if (R0 in [+Infinity, -Infinity]) or (R1 in [+Infinity, -Infinity]): if aggressive: # we want to avoid these situations if verbose: print "One of the coordinates is at infinity" if R0 in [+Infinity, -Infinity]: print "R0 = %s" % (R0, ) else: print "R1 = %s" % (R1, ) print "retrying with a new P0" print raise ZeroDivisionError else: return output buffer = "# R0 = %s\n" % (vector(CC, R0), ) buffer += "# R1 = %s\n" % (vector(CC, R1), ) buffer += "# and \n# x_poly = %s\n" % (vector(CC, x_poly), ) if verbose: print buffer assert len(x_poly) == 3 algx_poly = [NF_embedding(coeff, L) for coeff in x_poly] buffer = "algx_poly = %s;\n" % (algx_poly, ) if L != QQ: buffer += "#where %s ~ %s\n" % (L.gen(), L.gen().complex_embedding()) buffer += "\n" if verbose: print buffer sys.stdout.flush() sys.stderr.flush() output['algx_poly'] = algx_poly if None in algx_poly: if aggressive: if verbose: print "No algebraic expression for the polynomial" print "retrying with a new P0" sys.stdout.flush() sys.stderr.flush() raise ZeroDivisionError else: return output #c, b, a = algx_poly #if aggressive and b**2 - 4*a*c == 0: # raise ZeroDivisionError if verbose: print "Done compute_alpha_point()" return output