def test_sqlite_cached_function_2(): try: from sage.all import sleep, walltime import tempfile file = tempfile.mktemp() @sqlite_cached_function(file, compress=True) def f(a, b=10): sleep(1) return a + b f(2) f(2, b=4) t = walltime() assert f(2) == 12 assert f(b=4, a=2) == 6 assert walltime() - t < 1, "should be fast!" # Make new cached function, which will now use the disk cache first. @sqlite_cached_function(file, compress=True) def f(a, b=10): sleep(1) t = walltime() assert f(2) == 12 assert f(b=4, a=2) == 6 assert walltime() - t < 1, "should be fast!" finally: import os os.unlink(file)
def test_sqlite_cached_function_2(): try: from sage.all import sleep, walltime import tempfile file = tempfile.mktemp() @sqlite_cached_function(file, compress=True) def f(a, b=10): sleep(1) return a + b f(2) f(2,b=4) t = walltime() assert f(2) == 12 assert f(b=4,a=2) == 6 assert walltime() - t < 1, "should be fast!" # Make new cached function, which will now use the disk cache first. @sqlite_cached_function(file, compress=True) def f(a, b=10): sleep(1) t = walltime() assert f(2) == 12 assert f(b=4,a=2) == 6 assert walltime() - t < 1, "should be fast!" finally: import os; os.unlink(file)
def ker_im(self): T0 = walltime() S = diagonal_matrix([self.pq, self.pq, 1]) Si = ~S AUT = [S * M * Si for M in self.Delta_symmetry] pqDelta = self.pq * self.Delta pqDelta_fundam = self.pq * self.Delta_fundam fundam = fundamental_points(pqDelta_fundam, AUT) self.bidegrees = [] self.numsymm = {} for o in orbits(self.tensor_points(pqDelta), AUT): bideg = unique_intersection(o, fundam) if self.fd[bideg]: # Do not handle bidegrees where the domain is # 0-dimensional. These do not contribute to the kernel # or image. self.bidegrees.append(bideg) self.numsymm[bideg] = len(o) self.TM = 0 self.TR = 0 self.done = 0 self.results = {} # Bidegrees to handle in the computation, sorted according to # dimension of codomain (=> roughly by increasing difficulty) self._bidegrees_todo = sorted(self.bidegrees, key=lambda bideg: self.fc[bideg]) self.lock = Lock() T1 = walltime() if not self.threads: self._run() else: T = [Thread(target=self._run, args=(i,)) for i in range(self.threads)] for t in T: t.start() for t in T: t.join() TT = walltime() - T0 dimdomain = ZZ(sum(self.fd[bideg] * self.numsymm[bideg] for bideg in self.bidegrees)) rank = ZZ(sum(self.results[bideg][1] * self.numsymm[bideg] for bideg in self.bidegrees)) ker = dimdomain - rank if self.verbose: sys.stderr.flush() print("%-8s[%5i]:%10s (t = %.2fs + %.2fs + %.2fs = %.2fs)" % (str(self), len(self.bidegrees), ker, T1 - T0, self.TM, self.TR, TT)) sys.stdout.flush() return ker, rank
def create_database(f, db): global t0 t0 = walltime() P = Pool(NUMPROCESSES) it = P.imap_unordered(process_data, raw_data(f), chunksize=100) con = connect(db) con.execute(''' CREATE TABLE polygons( rowid INTEGER PRIMARY KEY, vertices TEXT, num_vertices INTEGER, volume REAL, num_points INTEGER, num_interior INTEGER, num_border INTEGER, width INTEGER, length INTEGER, symm INTEGER) ''') con.executemany('INSERT INTO polygons VALUES (?,?,?,?,?,?,?,?,?,?)', it) con.commit() con.close()
def run(inputfilename, outputfilename): HEADER = "id|origin|primitive|conductor|central_character|self_dual|motivic_weight|Lhash|degree|order_of_vanishing|algebraic|z1|gamma_factors|trace_hash|root_angle|prelabel|analytic_conductor|mu_real|mu_imag|nu_real_doubled|nu_imag|bad_primes".split("|") TYPES = "bigint|text|boolean|numeric|text|boolean|smallint|text|smallint|smallint|boolean|numeric|jsonb|bigint|double precision|text|double precision|smallint[]|numeric[]|smallint[]|numeric[]|bigint[]".split("|") start = walltime() previouslabel = None res = [] with open(inputfilename) as F: with open(outputfilename, 'w') as W: for i, line in enumerate(F.readlines(),1): if i == 1 and line.startswith('id|'): HEADER = line.strip().split('|') continue if i == 2 and line.startswith('bigint|'): TYPES = line.strip().split('|') continue if i == 3 and line == '\n': continue L = process_line(line, HEADER, TYPES) L['line'] = line.strip() if L['prelabel'] == previouslabel: res.append(L) else: compute_index(res) for r in res: W.write('%s|%s-%d|%d\n' % (r['line'], r['prelabel'], r['index'], r['index'],)) res = [L] previouslabel = L['prelabel'] if i % 24200 == 0: sys.stdout.write("%d (%.2f%%) lines done in %.2fs\tETA:%.2fs\n" % (i, i*100./24201375, walltime(start), (24201375 - i)*walltime(start)/i)) sys.stdout.flush() else: compute_index(res) for r in res: W.write('%s|%s-%d|%d\n' % (r['line'], r['prelabel'], r['index'], r['index'],))
def process_data(t): counter, vertices = t v = (counter,) + polygon_values(vertices) vstr = " ".join(repr(x) for x in v) t1 = walltime() sys.stdout.write("({:5.1f}Hz) {}\n".format(counter/float(t1 - t0), vstr)) return v
def process_curve_batch(folder, batch, digits=600, power=15): # cursor = list(C.genus2_curves.curves.find({'is_simple_geom': true,'real_geom_end_alg': u'R x R'}).sort([("cond", ASCENDING)])) totalcurves = len(batch) D = {} success = 0 total = 0 failed = [] for i, curve in enumerate(batch): label = curve['label'] stdout_filename = os.path.join(folder, label + ".stdout") output_filename = os.path.join(folder, label + ".sage") print "%d of %d : label = %s" % (i + 1, totalcurves, label) sys.stdout = open(stdout_filename, 'w') c, w = cputime(), walltime() data, sout = process_curve_lmfdb(curve, digits, power=power, verbose=True, internalverbose=False) print "Time: CPU %.2f s, Wall: %.2f s" % ( cputime(c), walltime(w), ) output_file = open(output_filename, 'w') output_file.write(sout) output_file.close() D[label] = True sys.stdout.flush() os.fsync(sys.stdout.fileno()) sys.stdout = sys.__stdout__ total += 1 if label in D.keys(): success += 1 print "Done: label = %s" % (label) print os.popen("tail -n 1 %s" % stdout_filename).read() else: failed += [label] print "ERROR: label = %s\n" % (label) print "Success rate: %.0f%%\n" % (100. * success / total) print "Failed so far %s" % failed
def _run(self, threadnum=0): while True: try: if threadnum < 1: # One thread for the easy cases bideg = self._bidegrees_todo.pop(0) else: # Other threads for the hard cases bideg = self._bidegrees_todo.pop() except IndexError: return gc.collect(0) t0 = walltime() M = bideg_map_points(self.base_ring, self.p, self.Delta_pts, self.Tensor1_pts, self.Tensor2_pts, bideg[0], bideg[1]) # Verify dimensions assert M.ncols() == self.fd[bideg] assert M.nrows() == self.fc[bideg] t1 = walltime() bideg_rank = M.rank() bideg_dimker = M.ncols() - bideg_rank t2 = walltime() del M self.lock.acquire() self.TM += (t1 - t0) self.TR += (t2 - t1) self.done += 1 if self.verbose >= 2: sys.stderr.write("%-8s%10s:%8i x %-8i ker=%-8iim=%-8i(t = %.2fs) %i/%i\n" % ( str(self), bideg, self.fc[bideg], self.fd[bideg], bideg_dimker, bideg_rank, t2 - t0, self.done, len(self.bidegrees))) sys.stderr.flush() self.results[bideg] = (bideg_dimker, bideg_rank) self.lock.release()
def process_curve_standalone(label, digits=600, power=15, verbose=True, internalverbose=False, folder=None): import os set_random_seed(1) import random random.seed(1) C = lmfdb.getDBconnection() curve = C.genus2_curves.curves.find_one({'label': label}) if curve is None: print "Wrong label" return 2 endo_alg = curve['real_geom_end_alg'] # deals with the default folders if folder is None: if not '__datadir__' in globals(): import os import inspect filename = inspect.getframeinfo(inspect.currentframe())[0] __datadir__ = os.path.dirname(filename) + "/data/" base_folder = __datadir__ if endo_alg == 'R': print "End = QQ, Nothing to do" return 0 elif endo_alg == 'R x R': if curve['is_simple_geom']: type_folder = 'simple/RM' else: type_folder = 'split/nonCM_times_nonCM' elif endo_alg == 'C x R': type_folder = 'split/CM_times_nonCM' elif endo_alg == 'C x C': if curve['is_simple_geom']: type_folder = 'simple/CM' else: type_folder = 'split/CM_times_CM' elif endo_alg == 'M_2(R)': if curve['is_simple_geom']: type_folder = 'simple/QM' else: type_folder = 'split/nonCM_square' elif endo_alg == 'M_2(C)': type_folder = 'split/CM_square' else: print "did I forget a case?" return 1 folder = os.path.join(base_folder, type_folder) if not os.path.exists(folder): print "Creating dir: %s" % folder os.makedirs(folder) assert os.path.exists(folder) #filenames stdout_filename = os.path.join(folder, label + ".stdout") stderr_filename = os.path.join(folder, label + ".stderr") output_filename = os.path.join(folder, label + ".sage") sys.stdout = open(stdout_filename, 'w', int(0)) sys.stderr = open(stderr_filename, 'w') c, w = cputime(), walltime() data, sout, verified = process_curve_lmfdb(curve, digits, power=power, verbose=True, internalverbose=False) print "Time: CPU %.2f s, Wall: %.2f s" % ( cputime(c), walltime(w), ) output_file = open(output_filename, 'w') output_file.write(sout) output_file.close() sys.stdout.flush() os.fsync(sys.stdout.fileno()) sys.stderr.flush() os.fsync(sys.stderr.fileno()) sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ print "Done: label = %s, verified = %s" % (label, verified) print os.popen("tail -n 1 %s" % stdout_filename).read() if verified: return 0 else: return 1
def certify_heuristic(g, label=None, digits=600, power=15, verbose=True, internalverbose=False): from heuristic_endomorphisms import EndomorphismData out = "" curve_dict = {} curve_dict['label'] = label curve_dict['digits'] = digits prec = ceil(log(10) / log(2) * digits) curve_dict['prec'] = prec buffer = "curve_dict = {};\n" for key in ['digits', 'prec']: buffer += "curve_dict['%s'] = %s;\n" % (key, curve_dict[key]) buffer += "curve_dict['%s'] = '%s';\n" % ('label', label) if verbose: print buffer out += buffer #Ambient ring buffer = "" buffer += "\n# basic rings\n" buffer += "curve_dict['%s'] = %s;\n" % ('QQx', 'PolynomialRing(QQ, \'x\')') buffer += "# curve_dict, x, and the number field's generator are the only variables are the only global variables\n\n" buffer += "x = curve_dict['QQx'].gen();\n\n" out += buffer Qx = PolynomialRing(QQ, "x") x = Qx.gen() curve_dict['QQx'] = Qx # force g in Qx g = Qx(g.list()) # Compute EndomorphismData # field of definition # and endomorphisms xsubs_list = [x, x + 1, x - 1, 1 - x, -1 - x, x + 2, x - 2, -x - 2, 2 - x] if label == '540800.a.540800.1': xsubs_list = xsubs_list[1:] for xsubs in xsubs_list: try: gtry = g(xsubs) if gtry.degree() == 5: gtry = Qx(gtry(x**(-1)) * x**6) if gtry.degree() == 5: gtry = Qx(gtry((x - 1) / x) * x**6) if verbose: print "Computing the EndomorphismData..." c, w = cputime(), walltime() End = EndomorphismData(gtry, prec=digits) print "Time: CPU %.2f s, Wall: %.2f s" % ( cputime(c), walltime(w), ) else: End = EndomorphismData(gtry, prec=digits) geo = End.geometric_representations() K = End.field_of_definition() g = gtry break except TypeError: pass if label == '810.a.196830.1': power += 2 buffer = "#working with the model y^2 = g(x)\n" buffer += "curve_dict['%s'] = %s;\n" % ('g', g.list()) curve_dict['g'] = g.list() out += buffer if verbose: print buffer # initialize numerical methods iaj = InvertAJglobal(g, prec, internalverbose) #CCap = iaj.C; buffer += "curve_dict['%s'] = %s;\n" % ('CCap', ' ComplexField(%s)' % curve_dict['prec']) #buffer += "CCap = curve_dict['CCap'];\n\n" # generator is r K = End.field_of_definition() if K.degree() == 1: K = QQ buffer = "# Field of definition of alpha\n" buffer += "curve_dict['%s'] = %s;\n" % ('K', sage_str_numberfield(K, 'x', 'r')) buffer += "K = %s\n" % ("curve_dict['K']") if K is not QQ: buffer += "r_approx = %s\n" % (K.gen().complex_embedding(), ) out += buffer out += "r = K.gen();\n" if verbose: print buffer #get the matrices over K geo = End.geometric_representations() #convert to sage # we also must take the transpose alphas = [convert_magma_matrix_to_sage(y, K).transpose() for y in geo[0]] alphas_geo = [y.sage() for y in geo[2]] d = len(alphas) out += "curve_dict['alphas_K'] = [None] * %d\n\n" % d out += "curve_dict['alphas_geo'] = [None] * %d\n\n" % d for i, _ in enumerate(alphas): alpha = alphas[i] alpha_geo = alphas_geo[i] buffer = "curve_dict['alphas_K'][%d] = Matrix(K, %s);\n" % ( i, alpha.rows(), ) buffer += "curve_dict['alphas_geo'][%d] = Matrix(%s);\n\n" % ( i, alpha_geo.rows(), ) out += buffer if verbose: print buffer curve_dict['alphas_K'] = alphas curve_dict['alphas_geo'] = alphas_geo out += "# where we stored all the data, for each alpha\n" out += "curve_dict['data'] = [{} for _ in range(%d) ] ;" % d curve_dict['data'] = [{} for _ in range(d)] for i in range(d): if alphas[i] == Matrix([[1, 0], [0, 1]]): curve_dict['data'][i] = None else: if verbose: print "Computing alpha(P + P)" print "where alpha = Matrix(K, %s)\n" % (alphas[i].rows(), ) # Pick a rational point, or a point over a quadratic extension with small discriminant for j, P0 in enumerate(find_rational_point(g)): if label in [ '540800.a.540800.1', '529.a.529.1', '1521.a.41067.1', '12500.a.12500.1', '18225.c.164025.1' ] and j < 2: pass elif label in ['810.a.196830.1'] and i == 2 and j == 0: pass else: if verbose: print "j = %s" % j sys.stdout.flush() sys.stderr.flush() try: output_alpha = compute_alpha_point(g, iaj, alphas[i], P0, digits, power, verbose=verbose, aggressive=True, append=str(i)) verified, trace_and_norm = add_trace_and_norm_ladic( g, output_alpha, alphas_geo[i], verbose=verbose) break except ZeroDivisionError: pass except OverflowError: if verbose: print "the mesh for numerical integral is too big" pass if verbose: print "trying with a new point\n" if verbose: print "\n\n\n" output_alpha['trace_and_norm'] = trace_and_norm output_alpha['verified'] = verified output_alpha['alphas_geo'] = alphas_geo[i] internal_out = "\n" #local_dict = {}\n\n"; # # the fields internal_out += "# L the field where P and the algx_poly are defined\n" internal_out += "curve_dict['data'][%d]['L'] = %s\n" % ( i, sage_str_numberfield(output_alpha['L'], 'x', 'b' + str(i)), ) if output_alpha['L'] is not QQ: internal_out += "b%d = curve_dict['data'][%d]['L'].gen()\n" % ( i, i) internal_out += "curve_dict['data'][%d]['Lgen_approx'] = %s\n" % ( i, output_alpha['L'].gen().complex_embedding()) internal_out += "\n" internal_out += "curve_dict['data'][%d]['alpha'] = Matrix(curve_dict['data'][%d]['L'], %s) \n\n" % ( i, i, [[elt for elt in row] for row in output_alpha['alpha'].rows()]) internal_out += "curve_dict['data'][%d]['alpha_geo'] = curve_dict['alphas_geo'][%d]\n\n" % ( i, i) internal_out += "curve_dict['data'][%d]['P'] = vector(curve_dict['data'][%d]['L'], %s)\n\n" % ( i, i, output_alpha['P']) internal_out += "# alpha(P + P) - \inf = R0 + R1 - \inf\n" internal_out += "\n\n\n" for key in [ 'algx_poly', 'R', 'x_poly', 'trace_and_norm', 'verified' ]: internal_out += "curve_dict['data'][%d]['%s'] = %s;\n" % ( i, key, output_alpha[key]) # this just clutters the file, # internal_out += "curve_dict['data'][%d]['ajP'] = vector(%s)\n\n" % (i, output_alpha['ajP']); # internal_out += "curve_dict['data'][%d]['alpha2P0'] = alphas_ap[%d] * 2 * local_dict['ajP']\n\n" % (i, i) internal_out += "\n\n\n" curve_dict['data'][i] = output_alpha out += internal_out verified = all( [elt['verified'] for elt in curve_dict['data'] if elt is not None]) out += "curve_dict['verified'] = %s\n\n" % verified return curve_dict, out, verified
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
def trace_and_norm_ladic(L, M, P0, P1, P2, f, alpha, degree_bound, primes=120, bits=62, verbose=True): if verbose: print "trace_and_norm_ladic()" print "primes = %d, bits = %d" % (primes, bits) # Input: # * L the number field where P0, alpha, norm and trace are defined over # * M a relative extension of L where P1 and P2 are defined over # * P0 initial point already embedded in M # * P1, P2 image points alpha(2 * P0 - \infty) = P1 + P2 - \infty # * alpha the matrix represing the endomorphism on the tangent space in M # * f the defining polynomial of the curve such that y^2 = f(x) # * degree bound for the trace and norm as rational maps # Note: Due to inconsistencies of the complex embeddings of L and M we require P0 and alpha to be given in M # Output: # * [trace_numberator, trace_denominator, norm_numberator, norm_denominator] # represented as lists of elements in L for arg in [P0, P1, P2, alpha]: assert arg.base_ring() is M hard_bound = 2 * degree_bound + 1 soft_bound = hard_bound + 10 if verbose: print "hard_bound = %d\nsoft_bound = %d" % (hard_bound, soft_bound) print "Generating split primes..." c, w = cputime(), walltime() ps_roots = random_split_primes(field=L, bits=bits, primes=primes, relative_ext=M.relative_polynomial()) print "Time: CPU %.2f s, Wall: %.2f s" % ( cputime(c), walltime(w), ) else: ps_roots = random_split_primes(field=L, bits=bits, primes=primes, relative_ext=M.relative_polynomial()) to_lift_raw = [] if verbose: print "Applying newton lift at each prime" for p_root in ps_roots: ell, root = p_root FF = FiniteField(ell) FF_xell = PolynomialRing(FF, "xell") Lpoly = FF_xell( reduce_list_split(M.relative_polynomial().list(), p_root)) assert Lpoly.degree() == len(Lpoly.roots()) Lroot = Lpoly.roots()[0][0].lift() PSring_ell = PowerSeriesRing(FF, "Tell", default_prec=soft_bound) P0_ell = vector(FF, reduce_list_split_relative(P0, p_root, Lroot)) P1_ell = vector(FF, reduce_list_split_relative(P1, p_root, Lroot)) P2_ell = vector(FF, reduce_list_split_relative(P2, p_root, Lroot)) f_ell = FF_xell(reduce_list_split(f.list(), p_root)) alpha_ell = reduce_matrix_split_relative(alpha, p_root, Lroot) x1_ell, x2_ell = newton_linear(P0_ell, P1_ell, P2_ell, f_ell, alpha_ell, PSring_ell, soft_bound) trace_series_ell = x1_ell + x2_ell norm_series_ell = x1_ell * x2_ell trace_numerator_ell, trace_denominator_ell = rational_reconstruct_poly( FF_xell(trace_series_ell.list()), FF_xell.gen()**trace_series_ell.prec()) norm_numerator_ell, norm_denominator_ell = rational_reconstruct_poly( FF_xell(norm_series_ell.list()), FF_xell.gen()**norm_series_ell.prec()) # shift the series back to zero shift = FF_xell.gen() - P0_ell[0] factors_ell = [ trace_numerator_ell(shift).list(), trace_denominator_ell(shift).list(), norm_numerator_ell(shift).list(), norm_denominator_ell(shift).list() ] degrees_ell = tuple([len(elt) for elt in factors_ell]) to_lift_raw.append((p_root, degrees_ell, factors_ell)) if verbose: print "Getting rid of bad primes..." # get rid of badprimes degrees_count = {} for _, degrees_ell, _ in to_lift_raw: if degrees_ell in degrees_count: degrees_count[degrees_ell] += 1 else: degrees_count[degrees_ell] = 1 max_value = 0 max_arg = None for degrees_ell, count in degrees_count.items(): if count > max_value: max_arg = degrees_ell max_value = count output = [None] * 4 for i, elt in enumerate(max_arg): output[i] = [0] * elt to_lift = [] ps_roots = [] for p_root, degrees_ell, factors_ell in to_lift_raw: if degrees_ell == max_arg: ps_roots.append(p_root) to_lift.append(factors_ell) extra_factor = to_lift[-1] extra_p_root = ps_roots[-1] to_lift = to_lift[:-1] ps_roots = ps_roots[:-1] OL = L.ring_of_integers() p_ideals = [OL.ideal(p, L.gen() - r) for p, r in ps_roots] I = prod(p_ideals) if L is QQ: BI_coordinates = None else: BI = I.basis() # basis as a ZZ-module BI_coordinates = [OL.coordinates(b) for b in BI] if verbose: print "Lifting everything" for i, lift in enumerate(output): for j, elt in enumerate(lift): residues = [residue[i][j] for residue in to_lift] output[i][j] = fractional_CRT_split(residues=residues, ps_roots=ps_roots, K=L, BI_coordinates=BI_coordinates) assert reduce_constant_split(output[i][j], extra_p_root) == extra_factor[i][j] if verbose: print "trace_and_norm_ladic() Done" return output
def solve(self, beta, max_iterations=100, tolerance=None, x0=None): # solve \sum_j (\int_bj ^{P_j} w_i)_i = beta # assumes beta is small if tolerance == None: tolerance = mpmath.mpf(2)**(-mpmath.mp.prec + 3) #print "tolerance = %s" % tolerance beta = mpmath.matrix([b for b in beta]) while True: try: basepoints = self.get_basepoints() if x0 is None: x = mpmath.matrix([b[0] for b in basepoints]) value = mpmath.matrix([0 for _ in range(self.genus)]) else: assert len(x0) == self.genus x = mpmath.matrix(x0) if self.verbose: c, w = cputime(), walltime() value = self.to_J_sum(x) print "Time: CPU %.2f s, Wall: %.2f s" % ( cputime(c), walltime(w), ) else: value = self.to_J_sum(x) previous_norm = 1 divg_bound = 3 divergingQ = 0 for k in range(max_iterations): J = self.jacobian(x) # J y = f(x) - beta y = mpmath.lu_solve(J, value - beta) x = x - y norm = mpmath.norm(y) / mpmath.norm(x) if self.verbose: print "k = %d norm = %.3e" % (k, norm) if norm < tolerance: return (x, y) if norm / previous_norm > 1.5: divergingQ += 1 else: divergingQ = 0 previous_norm = norm if divergingQ > divg_bound: raise RuntimeWarning( "method failed: the error diverged") if self.verbose: c, w = cputime(), walltime() value = self.to_J_sum(x) print "Time: CPU %.2f s, Wall: %.2f s" % ( cputime(c), walltime(w), ) else: value = self.to_J_sum(x) else: raise RuntimeWarning( "method failed: max number of iterations reached") except NotImplementedError as e: print e print "Generating new basepoints" self.set_basepoints()