def BigArithGroup(p,quat_data,level,base = None, grouptype = None,seed = None,use_sage_db = False,outfile = None, magma = None, timeout = 0, logfile = None, use_shapiro = True, character = None, nscartan = None, matrix_group = False): if magma is None: from sage.interfaces.magma import Magma magma = Magma(logfile = logfile) page_path = os.path.dirname(__file__) + '/KleinianGroups-1.0/klngpspec' if seed is not None: magma.eval('SetSeed(%s)'%seed) magma.attach_spec(page_path) magma.eval('Page_initialized := true') a, b = None, None if logfile is not None: magma.eval('SetVerbose("Kleinian",2)') try: discriminant = ZZ(quat_data) if base is not None: assert base == QQ else: base = QQ fname = 'arithgroup%s_%s_%s_%s.sobj'%(seed,p,discriminant,level) # Fix this name except TypeError: a,b = quat_data if base is None: base = a.parent() discriminant = QuaternionAlgebra(base,a,b).discriminant() fname = 'arithgroup%s_%s_%s_%s.sobj'%(seed,p,discriminant,level) # Fix this name if base != QQ: use_sage_db = False # This is not implemented yet if grouptype is None: if base == QQ: grouptype = 'PSL2' else: grouptype = 'PGL2' if use_sage_db: try: newobj = db(fname) except IOError: verbose('Group not found in database. Computing from scratch.') newobj = BigArithGroup_class(base,p,discriminant,level,seed,outfile = outfile,grouptype = grouptype,magma = magma,timeout = timeout, use_shapiro = use_shapiro, character = character, nscartan = nscartan, matrix_group = matrix_group) newobj.save_to_db() else: if a is not None: newobj = BigArithGroup_class(base,p,discriminant,abtuple = (a,b),level = level,seed = seed,outfile = outfile,grouptype = grouptype,magma = magma,timeout = timeout, use_shapiro = use_shapiro, character = character, nscartan = nscartan, matrix_group = matrix_group) else: newobj = BigArithGroup_class(base,p,discriminant,level = level,seed = seed,outfile = outfile,grouptype = grouptype,magma = magma,timeout = timeout, use_shapiro = use_shapiro, character = character, nscartan = nscartan, matrix_group = matrix_group) return newobj
def benchmark(pbound=[3, 2**10], nbound=[3, 2**8], cbound=[1, Infinity], obound=[1, Infinity], loops=10, tloop=Infinity, tmax=Infinity, prime=False, even=False, check=False, fname=None, write=False, overwrite=False, verbose=True, skip_pari=False, skip_magma=False, skip_rains=False, skip_kummer=False): if write: mode = 'w' if overwrite else 'a' f = open(fname, mode, 0) else: f = sys.stdout pmin, pmax = pbound nmin, nmax = nbound omin, omax = obound cmin, cmax = cbound M = Magma() for p in xrange(pmin, pmax): p = ZZ(p) if not p.is_prime(): continue for n in xrange(nmin, nmax): n = ZZ(n) if (prime == 1 and not is_prime(n)) or (prime == 2 and not is_prime_power(n)): continue if n < 2: continue if n % p == 0: continue if (not even) and (n % 2 == 0): continue o, G = find_root_order(p, [n, n], n, verbose=False) m = G[0][0].parent().order() c = Mod(p, n).multiplicative_order() if verbose: sys.stdout.write("\r" + " " * 79) print("\rp = {}, n = {}, (o = {}, c = {})".format(p, n, o, c)) if verbose: t = mytime() sys.stdout.write("Constructing fields ({})".format( time.strftime("%c"))) sys.stdout.flush() q = p**n k = GF(q, name='z') k_rand = GF(q, modulus='random', name='z') k_flint = GF_flint(p, k.modulus(), name='z') if verbose > 1: sys.stdout.write("\ntotal: {}s\n".format(mytime(t))) sys.stdout.flush() # Magma if verbose: sys.stdout.write("\r" + " " * 79) sys.stdout.write("\rMagma ({})".format(time.strftime("%c"))) sys.stdout.flush() tloops = 0 for l in xrange(loops): if skip_magma: break if (o > omax) or (o == p): break # let's assume that launching a new Magma instance is cheaper # than computing random irreducible polynomials try: M._start() except OSError as err: # but it can also cause fork issues... # let's accept this # and fail as the situation will only worsen # unless it is "just" a memory issue # which should be mitigated by COW but is not #print(err) if err.errno == errno.ENOMEM: break else: raise try: k_magma = M(k) k_rand_magma = M(k_rand) if tloop is not Infinity: alarm(tloop) t = mytime() k_magma.Embed(k_rand_magma, nvals=0) #M._eval_line("Embed(k_magma, k_rand_magma);", wait_for_prompt=False) tloops += mytime(t) except TypeError: # sage/magma interface sometimes gets confused pass except (KeyboardInterrupt, AlarmInterrupt): # sage interface eats KeyboardInterrupt # and AlarmInterrupt derives from it tloops = 0 break finally: if tloop is not Infinity: cancel_alarm() M.quit() # sage pexpect interface leaves zombies around try: while os.waitpid(-1, os.WNOHANG)[0]: pass # but sometimes every child is already buried # and we get an ECHILD error... except OSError: pass if tloops > tmax: break tmagma = tloops / (l + 1) if verbose > 1: sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format( tloops, tloops / (l + 1))) sys.stdout.flush() # Rains algorithms if verbose: sys.stdout.write("\r" + " " * 79) sys.stdout.write("\rCyclotomic Rains ({})".format( time.strftime("%c"))) sys.stdout.flush() trains = [] tloops = 0 for l in xrange(loops): if skip_rains: break if (o > omax) or (o == p): break try: if tloop is not Infinity: alarm(tloop) t = mytime() a, b = find_gens_cyclorains(k_flint, k_flint, use_lucas=False) tloops += mytime(t) except (KeyboardInterrupt, AlarmInterrupt): tloops = 0 break finally: if tloop is not Infinity: cancel_alarm() if check and (l == 0 or check > 1): g = a.minpoly() if g.degree() != n: raise RuntimeError("wrong degree") if g != b.minpoly(): raise RuntimeError("different minpolys") if tloops > tmax: break trains.append(tloops / (l + 1)) if verbose > 1: sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format( tloops, tloops / (l + 1))) sys.stdout.flush() # Conic Rains if verbose: sys.stdout.write("\r" + " " * 79) sys.stdout.write("\rConic Rains ({})".format( time.strftime("%c"))) sys.stdout.flush() tloops = 0 for l in xrange(loops): if skip_rains: break if (o != 2) or (o > omax) or (o == p): break try: if tloop is not Infinity: alarm(tloop) t = mytime() a, b = find_gens_cyclorains(k_flint, k_flint, use_lucas=True) tloops += mytime(t) except (KeyboardInterrupt, AlarmInterrupt): tloops = 0 break finally: if tloop is not Infinity: cancel_alarm() if check and (l == 0 or check > 1): g = a.minpoly() if g.degree() != n: raise RuntimeError("wrong degree") if g != b.minpoly(): raise RuntimeError("different minpolys") if tloops > tmax: break trains.append(tloops / (l + 1)) if verbose > 1: sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format( tloops, tloops / (l + 1))) sys.stdout.flush() # Elliptic Rains if verbose: sys.stdout.write("\r" + " " * 79) sys.stdout.write("\rElliptic Rains ({})".format( time.strftime("%c"))) sys.stdout.flush() tloops = 0 for l in xrange(loops): if skip_rains: break try: if tloop is not Infinity: alarm(tloop) t = mytime() a, b = find_gens_ellrains(k_flint, k_flint) tloops += mytime(t) except RuntimeError: # sometimes no suitable elliptic curve exists pass except (KeyboardInterrupt, AlarmInterrupt): tloops = 0 break finally: if tloop is not Infinity: cancel_alarm() if check and (l == 0 or check > 1): g = a.minpoly() if g.degree() != n: raise RuntimeError("wrong degree") if g != b.minpoly(): raise RuntimeError("different minpolys") if tloops > tmax: break trains.append(tloops / (l + 1)) if verbose > 1: sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format( tloops, tloops / (l + 1))) sys.stdout.flush() # PARI/GP if verbose: sys.stdout.write("\r" + " " * 79) sys.stdout.write("\rPARI/GP ({})".format(time.strftime("%c"))) sys.stdout.flush() tloops = 0 for l in xrange(loops): if skip_pari: break if c < cmin or c > cmax: break try: if tloop is not Infinity: alarm(tloop) t = mytime() a, b = find_gens_pari(k, k) tloops += mytime(t) except (KeyboardInterrupt, AlarmInterrupt): tloops = 0 break finally: if tloop is not Infinity: cancel_alarm() if check and (l == 0 or check > 1): g = a.minpoly() if g.degree() != n: raise RuntimeError("wrong degree") if g != b.minpoly(): raise RuntimeError("different minpolys") if tloops > tmax: break tpari = tloops / (l + 1) # Kummer algorithms tkummer = [] # only linalg and modcomp implemented for c==1 for i, algo in enumerate(kummer_algolist[2 * (c == 1):-2 * (c == 1) - 1]): if verbose: sys.stdout.write("\r" + " " * 79) sys.stdout.write("\rKummer {} ({})".format( kummer_namelist[2 * (c == 1) + i], time.strftime("%c"))) sys.stdout.flush() tloops = 0 for l in xrange(loops): if skip_kummer: break if c < cmin or c > cmax: break try: if tloop is not Infinity: alarm(tloop) t = mytime() a, b = find_gens_kummer(k_flint, k_flint, n, algo) tloops += mytime(t) except (KeyboardInterrupt, AlarmInterrupt): tloops = 0 break finally: if tloop is not Infinity: cancel_alarm() if check and (l == 0 or check > 1): g = a.minpoly() if g.degree() != n: raise RuntimeError("wrong degree") if g != b.minpoly(): raise RuntimeError("different minpolys") if tloops > tmax: break tkummer.append(tloops / (l + 1)) if verbose > 1: sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format( tloops, tloops / (l + 1))) sys.stdout.flush() tkummer = 2 * (c == 1) * [0] + tkummer + 2 * (c == 1) * [0] if verbose: sys.stdout.write("\r") sys.stdout.flush() f.write(("{} {} ({}, {})" + " {}" + " {}" * len(trains) + " {}" + " {}" * len(tkummer) + "\n").format( p, n, o, c, *([tmagma] + trains + [tpari] + tkummer))) if write: f.close()
from pymongo.mongo_client import MongoClient import pymongo import yaml from bson import ObjectId from sage.interfaces.magma import Magma from sets import Set magma = Magma() C = MongoClient(port=int(27017)) cap = C.curve_automorphisms.passports helper_code = ''' /* helper functions for orbits */ /* L is list of IDs */ PrtOrbit:=function(L); prtstring:=" - ["; for i in [1..#L-1] do prtstring:=prtstring cat "'" cat L[i] cat "'"; prtstring:=prtstring cat ","; end for; prtstring:=prtstring cat "'" cat L[#L] cat "'" cat "]"; return prtstring; end function; Qi:=function(k,L); left_unchanged:=[L[i] : i in [1..k-1]]; braid:=[L[k]*L[k+1]*L[k]^-1,L[k]]; right_unchanged:=[L[i]: i in [k+2..#L] ]; return left_unchanged cat braid cat right_unchanged; end function; BrdOrbit:=function(L,r);
def find_curve(P, DB, NE, prec, sign_ap = None, magma = None, return_all = False, initial_data = None, ramification_at_infinity = None, **kwargs): r''' EXAMPLES: First example:: sage: from darmonpoints.findcurve import find_curve sage: find_curve(5,6,30,20) # long time # optional - magma # B = F<i,j,k>, with i^2 = -1 and j^2 = 3 ... '(1, 0, 1, -289, 1862)' A second example, now over a real quadratic:: sage: from darmonpoints.findcurve import find_curve sage: F.<r> = QuadraticField(5) sage: P = F.ideal(3/2*r + 1/2) sage: D = F.ideal(3) sage: find_curve(P,D,P*D,30,ramification_at_infinity = F.real_places()[:1]) # long time # optional - magma ... Now over a cubic of mixed signature:: sage: from darmonpoints.findcurve import find_curve sage: F.<r> = NumberField(x^3 -3) sage: P = F.ideal(r-2) sage: D = F.ideal(r-1) sage: find_curve(P,D,P*D,30) # long time # optional - magma ... ''' config = ConfigParser.ConfigParser() config.read('config.ini') param_dict = config_section_map(config, 'General') param_dict.update(config_section_map(config, 'FindCurve')) param_dict.update(kwargs) param = Bunch(**param_dict) # Get general parameters outfile = param.get('outfile') use_ps_dists = param.get('use_ps_dists',False) use_shapiro = param.get('use_shapiro',True) use_sage_db = param.get('use_sage_db',False) magma_seed = param.get('magma_seed',1515316) parallelize = param.get('parallelize',False) Up_method = param.get('up_method','naive') use_magma = param.get('use_magma',True) progress_bar = param.get('progress_bar',True) sign_at_infinity = param.get('sign_at_infinity',ZZ(1)) # Get find_curve specific parameters grouptype = param.get('grouptype') hecke_bound = param.get('hecke_bound',3) timeout = param.get('timeout',0) check_conductor = param.get('check_conductor',True) if initial_data is None: page_path = os.path.dirname(__file__) + '/KleinianGroups-1.0/klngpspec' if magma is None: from sage.interfaces.magma import Magma quit_when_done = True magma = Magma() else: quit_when_done = False if magma_seed is not None: magma.eval('SetSeed(%s)'%magma_seed) magma.attach_spec(page_path) magma.eval('Page_initialized := true') else: quit_when_done = False sys.setrecursionlimit(10**6) # global qE, Linv, G, Coh, phiE, xgen, xi1, xi2, Phi try: F = P.ring() Fdisc = F.discriminant() if not (P*DB).divides(NE): raise ValueError,'Conductor (NE) should be divisible by P*DB' p = ZZ(P.norm()).abs() except AttributeError: F = QQ P = ZZ(P) p = ZZ(P) Fdisc = ZZ(1) if NE % (P*DB) != 0: raise ValueError,'Conductor (NE) should be divisible by P*DB' Ncartan = kwargs.get('Ncartan',None) Np = NE / (P * DB) if Ncartan is not None: Np = Np / Ncartan**2 if use_ps_dists is None: use_ps_dists = False # More efficient our own implementation if not p.is_prime(): raise ValueError,'P (= %s) should be a prime, of inertia degree 1'%P working_prec = max([2 * prec + 10, 100]) sgninfty = 'plus' if sign_at_infinity == 1 else 'minus' fname = 'moments_%s_%s_%s_%s_%s_%s.sobj'%(Fdisc,p,DB,NE,sgninfty,prec) if outfile == 'log': outfile = '%s_%s_%s_%s_%s.log'%(P,NE,sgninfty,prec,datetime.datetime.now().strftime("%Y%m%d-%H%M%S")) outfile = outfile.replace('/','div') outfile = '/tmp/findcurve_' + outfile if F != QQ and ramification_at_infinity is None: if F.signature()[0] > 1: if F.signature()[1] == 1: ramification_at_infinity = F.real_places(prec = Infinity) # Totally 'definite' else: raise ValueError,'Please specify the ramification at infinity' elif F.signature()[0] == 1: if len(F.ideal(DB).factor()) % 2 == 0: ramification_at_infinity = [] # Split at infinity else: ramification_at_infinity = F.real_places(prec = Infinity) # Ramified at infinity else: ramification_at_infinity = None if outfile is not None: print("Partial results will be saved in %s"%outfile) if initial_data is not None: G,phiE = initial_data else: # Define the S-arithmetic group try: if F == QQ: abtuple = QuaternionAlgebra(DB).invariants() else: abtuple = quaternion_algebra_invariants_from_ramification(F,DB,ramification_at_infinity) G = BigArithGroup(P, abtuple, Np, use_sage_db = use_sage_db, grouptype = grouptype, magma = magma, seed = magma_seed, timeout = timeout, use_shapiro = use_shapiro, nscartan = Ncartan) except RuntimeError as e: if quit_when_done: magma.quit() mystr = str(e) if len(mystr) > 30: mystr = mystr[:14] + ' ... ' + mystr[-14:] if return_all: return ['Error when computing G: ' + mystr] else: return 'Error when computing G: ' + mystr # Define phiE, the cohomology class associated to the system of eigenvalues. Coh = ArithCoh(G) try: phiE = Coh.get_rational_cocycle(sign = sign_at_infinity,bound = hecke_bound,return_all = return_all,use_magma = True) except Exception as e: if quit_when_done: magma.quit() if return_all: return ['Error when finding cohomology class: ' + str(e)] else: return 'Error when finding cohomology class: ' + str(e) if use_sage_db: G.save_to_db() fwrite('Cohomology class found', outfile) try: ker = [G.inverse_shapiro(o) for o in G.get_homology_kernel()] except Exception as e: if quit_when_done: magma.quit() if return_all: return ['Problem calculating homology kernel: ' + str(e)] else: return 'Problem calculating homology kernel: ' + str(e) if not return_all: phiE = [phiE] ret_vals = [] for phi in phiE: try: Phi = get_overconvergent_class_quaternionic(P,phi,G,prec,sign_at_infinity,sign_ap,use_ps_dists,method = Up_method, progress_bar = progress_bar) except ValueError as e: ret_vals.append('Problem when getting overconvergent class: ' + str(e)) continue fwrite('Done overconvergent lift', outfile) # Find an element x of Gpn for not in the kernel of phi, # and such that both x and wp^-1 * x * wp are trivial in the abelianization of Gn. try: found = False for o in ker: phi_o = sum( [phi.evaluate(t**a) for t, a in o], 0 ) if use_shapiro: phi_o = phi_o.evaluate_at_identity() if phi_o != 0: found = True break if not found: raise RuntimeError('Cocycle evaluates always to zero') except Exception as e: ret_vals.append('Problem when choosing element in kernel: ' + str(e)) continue xgenlist = o found = False while not found: try: xi1, xi2 = lattice_homology_cycle(G,xgenlist,working_prec,outfile = outfile) found = True except PrecisionError: working_prec = 2 * working_prec verbose('Setting working_prec to %s'%working_prec) except Exception as e: ret_vals.append('Problem when computing homology cycle: ' + str(e)) verbose('Exception occurred: ' + str(e)) break if not found: continue try: qE1 = integrate_H1(G,xi1,Phi,1,method = 'moments',prec = working_prec, twist = False,progress_bar = progress_bar) qE2 = integrate_H1(G,xi2,Phi,1,method = 'moments',prec = working_prec, twist = True,progress_bar = progress_bar) except Exception as e: ret_vals.append('Problem with integration: %s'%str(e)) continue qE = qE1/qE2 qE = qE.add_bigoh(prec + qE.valuation()) Linv = qE.log(p_branch = 0)/qE.valuation() fwrite('Integral done. Now trying to recognize the curve', outfile) fwrite('F.<r> = NumberField(%s)'%(F.gen(0).minpoly()),outfile) fwrite('N_E = %s = %s'%(NE,factor(NE)),outfile) fwrite('D_B = %s = %s'%(DB,factor(DB)),outfile) fwrite('Np = %s = %s'%(Np,factor(Np)),outfile) if Ncartan is not None: fwrite('Ncartan = %s'%(Ncartan),outfile) fwrite('Calculation with p = %s and prec = %s+%s'%(P,prec,working_prec-prec),outfile) fwrite('qE = %s'%qE,outfile) fwrite('Linv = %s'%Linv,outfile) curve = discover_equation(qE,G._F_to_local,NE,prec,check_conductor = check_conductor) if curve is None: if quit_when_done: magma.quit() ret_vals.append('None') else: try: curve = curve.global_minimal_model() except AttributeError,NotImplementedError: pass fwrite('EllipticCurve(F, %s )'%(list(curve.a_invariants())), outfile) fwrite('=' * 60, outfile) ret_vals.append(str(curve.a_invariants()))
def find_curve(P, DB, NE, prec, sign_ap=None, magma=None, return_all=False, initial_data=None, ramification_at_infinity=None, implementation=None, **kwargs): r''' EXAMPLES: First example:: sage: from darmonpoints.findcurve import find_curve sage: find_curve(5,6,30,20) # long time # optional - magma # B = F<i,j,k>, with i^2 = -1 and j^2 = 3 ... '(1, 0, 1, -289, 1862)' A second example, now over a real quadratic:: sage: from darmonpoints.findcurve import find_curve sage: F.<r> = QuadraticField(5) sage: P = F.ideal(3/2*r + 1/2) sage: D = F.ideal(3) sage: find_curve(P,D,P*D,30,ramification_at_infinity = F.real_places()[:1]) # long time # optional - magma ... Now over a cubic of mixed signature:: sage: from darmonpoints.findcurve import find_curve sage: F.<r> = NumberField(x^3 -3) sage: P = F.ideal(r-2) sage: D = F.ideal(r-1) sage: find_curve(P,D,P*D,30) # long time # optional - magma ... ''' config = ConfigParser.ConfigParser() config.read('config.ini') param_dict = config_section_map(config, 'General') param_dict.update(config_section_map(config, 'FindCurve')) param_dict.update(kwargs) param = Bunch(**param_dict) # Get general parameters outfile = param.get('outfile') use_ps_dists = param.get('use_ps_dists', False) use_shapiro = param.get('use_shapiro', False) use_sage_db = param.get('use_sage_db', False) magma_seed = param.get('magma_seed', 1515316) parallelize = param.get('parallelize', False) Up_method = param.get('up_method', 'naive') use_magma = param.get('use_magma', True) progress_bar = param.get('progress_bar', True) sign_at_infinity = param.get('sign_at_infinity', ZZ(1)) # Get find_curve specific parameters grouptype = param.get('grouptype') hecke_bound = param.get('hecke_bound', 3) timeout = param.get('timeout', 0) check_conductor = param.get('check_conductor', True) if initial_data is None: page_path = os.path.dirname(__file__) + '/KleinianGroups-1.0/klngpspec' if magma is None: from sage.interfaces.magma import Magma quit_when_done = True magma = Magma() else: quit_when_done = False if magma_seed is not None: magma.eval('SetSeed(%s)' % magma_seed) magma.attach_spec(page_path) magma.eval('Page_initialized := true') else: quit_when_done = False sys.setrecursionlimit(10**6) # global qE, Linv, G, Coh, phiE, xgen, xi1, xi2, Phi try: F = P.ring() Fdisc = F.discriminant() if not (P * DB).divides(NE): raise ValueError('Conductor (NE) should be divisible by P*DB') p = ZZ(P.norm()).abs() except AttributeError: F = QQ P = ZZ(P) p = ZZ(P) Fdisc = ZZ(1) if NE % (P * DB) != 0: raise ValueError('Conductor (NE) should be divisible by P*DB') Ncartan = kwargs.get('Ncartan', None) param_dict['nscartan'] = Ncartan Np = NE / (P * DB) if Ncartan is not None: Np = Np / Ncartan**2 if use_ps_dists is None: use_ps_dists = False # More efficient our own implementation if not p.is_prime(): raise ValueError('P (= %s) should be a prime, of inertia degree 1' % P) working_prec = max([2 * prec + 10, 100]) sgninfty = 'plus' if sign_at_infinity == 1 else 'minus' fname = 'moments_%s_%s_%s_%s_%s_%s.sobj' % (Fdisc, p, DB, NE, sgninfty, prec) if outfile == 'log': outfile = '%s_%s_%s_%s_%s.log' % ( P, NE, sgninfty, prec, datetime.datetime.now().strftime("%Y%m%d-%H%M%S")) outfile = outfile.replace('/', 'div') outfile = '/tmp/findcurve_' + outfile if F != QQ and ramification_at_infinity is None: if F.signature()[0] > 1: if F.signature()[1] == 1: ramification_at_infinity = F.real_places( prec=Infinity) # Totally 'definite' else: raise ValueError('Please specify the ramification at infinity') elif F.signature()[0] == 1: if len(F.ideal(DB).factor()) % 2 == 0: ramification_at_infinity = [] # Split at infinity else: ramification_at_infinity = F.real_places( prec=Infinity) # Ramified at infinity else: ramification_at_infinity = None if outfile is not None: print("Partial results will be saved in %s" % outfile) if initial_data is not None: G, phiE = initial_data else: # Define the S-arithmetic group try: if F == QQ: abtuple = QuaternionAlgebra(DB).invariants() else: abtuple = quaternion_algebra_invariants_from_ramification( F, DB, ramification_at_infinity, magma=magma) G = BigArithGroup(P, abtuple, Np, magma=magma, seed=magma_seed, **param_dict) except RuntimeError as e: if quit_when_done: magma.quit() mystr = str(e) if len(mystr) > 30: mystr = mystr[:14] + ' ... ' + mystr[-14:] if return_all: return ['Error when computing G: ' + mystr] else: return 'Error when computing G: ' + mystr # Define phiE, the cohomology class associated to the system of eigenvalues. Coh = ArithCoh(G) try: phiE = Coh.get_rational_cocycle(sign=sign_at_infinity, bound=hecke_bound, return_all=return_all, use_magma=True) except Exception as e: if quit_when_done: magma.quit() if return_all: return ['Error when finding cohomology class: ' + str(e)] else: return 'Error when finding cohomology class: ' + str(e) if use_sage_db: G.save_to_db() fwrite('Cohomology class found', outfile) try: ker = [G.inverse_shapiro(o) for o in G.get_homology_kernel()] except Exception as e: if quit_when_done: magma.quit() if return_all: return ['Problem calculating homology kernel: ' + str(e)] else: return 'Problem calculating homology kernel: ' + str(e) if not return_all: phiE = [phiE] ret_vals = [] for phi in phiE: try: Phi = get_overconvergent_class_quaternionic( P, phi, G, prec, sign_at_infinity, sign_ap, use_ps_dists, method=Up_method, progress_bar=progress_bar) except ValueError as e: ret_vals.append('Problem when getting overconvergent class: ' + str(e)) continue fwrite('Done overconvergent lift', outfile) # Find an element x of Gpn for not in the kernel of phi, # and such that both x and wp^-1 * x * wp are trivial in the abelianization of Gn. try: found = False for o in ker: phi_o = sum([phi.evaluate(t**a) for t, a in o], 0) if use_shapiro: phi_o = phi_o.evaluate_at_identity() if phi_o != 0: found = True break if not found: raise RuntimeError('Cocycle evaluates always to zero') except Exception as e: ret_vals.append('Problem when choosing element in kernel: ' + str(e)) continue xgenlist = o found = False while not found: try: xi1, xi2 = lattice_homology_cycle(p, G.Gn, G.wp(), xgenlist, working_prec, outfile=outfile) found = True except PrecisionError: working_prec = 2 * working_prec verbose('Setting working_prec to %s' % working_prec) except Exception as e: ret_vals.append('Problem when computing homology cycle: ' + str(e)) verbose('Exception occurred: ' + str(e)) break if not found: continue try: qE1 = integrate_H1(G, xi1, Phi, 1, method='moments', prec=working_prec, twist=False, progress_bar=progress_bar) qE2 = integrate_H1(G, xi2, Phi, 1, method='moments', prec=working_prec, twist=True, progress_bar=progress_bar) except Exception as e: ret_vals.append('Problem with integration: %s' % str(e)) continue qE = qE1 / qE2 qE = qE.add_bigoh(prec + qE.valuation()) Linv = qE.log(p_branch=0) / qE.valuation() fwrite('Integral done. Now trying to recognize the curve', outfile) fwrite('F.<r> = NumberField(%s)' % (F.gen(0).minpoly()), outfile) fwrite('N_E = %s = %s' % (NE, factor(NE)), outfile) fwrite('D_B = %s = %s' % (DB, factor(DB)), outfile) fwrite('Np = %s = %s' % (Np, factor(Np)), outfile) if Ncartan is not None: fwrite('Ncartan = %s' % (Ncartan), outfile) fwrite( 'Calculation with p = %s and prec = %s+%s' % (P, prec, working_prec - prec), outfile) fwrite('qE = %s' % qE, outfile) fwrite('Linv = %s' % Linv, outfile) curve = discover_equation(qE, G._F_to_local, NE, prec, check_conductor=check_conductor) if curve is None: if quit_when_done: magma.quit() ret_vals.append('None') else: try: curve = curve.global_minimal_model() except AttributeError, NotImplementedError: pass fwrite('EllipticCurve(F, %s )' % (list(curve.a_invariants())), outfile) fwrite('=' * 60, outfile) ret_vals.append(str(curve.a_invariants()))
def BigArithGroup(p, quat_data, level, base=None, grouptype=None, seed=None, use_sage_db=False, magma=None, logfile=None, **kwargs): if magma is None: from sage.interfaces.magma import Magma magma = Magma(logfile=logfile) if seed is not None: magma.eval('SetSeed(%s)' % seed) if not is_page_initialized(magma): attach_kleinian_code(magma) a, b = None, None if logfile is not None: magma.eval('SetVerbose("Kleinian",2)') try: discriminant = ZZ(quat_data) if base is not None: assert base == QQ else: base = QQ fname = 'arithgroup%s_%s_%s_%s.sobj' % (seed, p, discriminant, level ) # Fix this name except TypeError: a, b = quat_data if base is None: base = a.parent() discriminant = QuaternionAlgebra(base, a, b).discriminant() fname = 'arithgroup%s_%s_%s_%s.sobj' % (seed, p, discriminant, level ) # Fix this name if base != QQ: use_sage_db = False # This is not implemented yet if grouptype is None: if base == QQ: grouptype = 'PSL2' else: grouptype = 'PSL2' # DEBUG, was PGL2 if use_sage_db: try: newobj = db(fname) except IOError: verbose('Group not found in database. Computing from scratch.') newobj = BigArithGroup_class(base, p, discriminant, level, seed, grouptype=grouptype, magma=magma, **kwargs) newobj.save_to_db() else: if a is not None: newobj = BigArithGroup_class(base, p, discriminant, abtuple=(a, b), level=level, seed=seed, grouptype=grouptype, magma=magma, **kwargs) else: newobj = BigArithGroup_class(base, p, discriminant, level=level, seed=seed, grouptype=grouptype, magma=magma, **kwargs) return newobj
def Lpvalue(f,g,h,p,prec,N = None,modformsring = False, weightbound = False, eps = None, orthogonal_form = None, data_idx=None, magma_args = None,force_computation=False, algorithm='threestage', derivative_order=1, lauders_advice = False, use_magma = True, magma = None, num_coeffs_qexpansion = 20000, max_primes=5, outfile = None): if magma_args is None: magma_args = {} if algorithm not in ['twostage','threestage']: raise ValueError('Algorithm should be one of "twostage" (default) or "threestage"') if magma is None: from sage.interfaces.magma import Magma magma = Magma(**magma_args) if hasattr(g,'j_invariant'): elliptic_curve = g g = g.modular_form() else: elliptic_curve = None data = None if h is None: if hasattr(f, 'modulus'): # Assume we need to create f and h from Dirichlet character kronecker_character = f f, _, h = define_qexpansions_from_dirichlet_character(p, prec, kronecker_character, num_coeffs_qexpansion, magma) else: kronecker_character = None # Assume that f contains a list of lines of text to initialize both f and h data = f f, h = get_magma_qexpansions(data, data_idx, max(prec,200), Qp(p,prec), magma=magma) eps = f.character_full() ll,mm = g.weight(),h.weight() t = 0 # Assume t = 0 here kk = ll + mm - 2 * (1 + t) # Is this correct? p = ZZ(p) if N is None: N = lcm([ZZ(f.level()),ZZ(g.level()),ZZ(h.level())]) nu = N.valuation(p) N = N.prime_to_m_part(p) else: N = ZZ(N) nu = N.valuation(p) if outfile is None: outfile = "output_iterated_integral_%s_%s_%s_%s.txt"%(p,g.level(), h.level(), prec) print("Writing output to file %s"%outfile) fwrite("######### STARTING COMPUTATION OF Lp ###########", outfile) if elliptic_curve is not None: fwrite("E = EllipticCurve(%s)"%list(elliptic_curve.ainvs()), outfile) fwrite(" cond(E) = %s"%elliptic_curve.conductor(), outfile) if kronecker_character is not None: fwrite("kronecker_character = %s"%kronecker_character, outfile) fwrite(" conductor = %s"%kronecker_character.conductor(), outfile) if data is not None: fwrite("Data for weight-1 forms:", outfile) for line in data: fwrite(line, outfile) fwrite("Tame level N = %s, prime p = %s, nu = %s"%(N,p,nu), outfile) fwrite("precision = %s"%prec, outfile) fwrite("------ parameters --------------------", outfile) fwrite("modformsring = %s"%modformsring, outfile) fwrite("weightbound = %s"%weightbound, outfile) fwrite("eps = %s"%eps, outfile) fwrite("orthogonal_form = %s"%orthogonal_form, outfile) fwrite("magma_args = %s"%magma_args, outfile) fwrite("force_computation = %s"%force_computation, outfile) fwrite("algorithm = %s"%algorithm, outfile) fwrite("derivative_order = %s"%derivative_order, outfile) fwrite("lauders_advice = %s"%lauders_advice, outfile) fwrite("use_magma = %s"%use_magma, outfile) fwrite("num_coeffs_qexpansion = %s"%num_coeffs_qexpansion, outfile) fwrite("##########################################", outfile) prec = ZZ(prec) fwrite("Step 1: Compute the Up matrix", outfile) if algorithm == "twostage": computation_name = '%s_%s_%s_%s_%s_%s_%s'%(p,N,nu,kk,prec,'triv' if eps is None else 'char',algorithm) else: computation_name = '%s_%s_%s_%s_%s_%s'%(p,N,nu,kk,prec,'triv' if eps is None else 'char') if use_magma: tmp_filename = '/tmp/magma_mtx_%s.tmp'%computation_name import os.path from sage.misc.persist import db, db_save try: if force_computation: raise IOError V = db('Lpvalue_Apow_ordbasis_eimat_%s'%computation_name) ord_basis, eimat, zetapm, elldash, mdash = V[:5] Apow_data = V[5:] except IOError: if force_computation or not os.path.exists(tmp_filename): if eps is not None: eps_magma = sage_character_to_magma(eps,N,magma=magma) magma.load("overconvergent_alan.m") # Am, zetapm, eimatm, elldash, mdash = magma.UpOperatorData(p, eps_magma, kk, prec,WeightBound=weightbound,nvals=5) Am, zetapm, eimatm, elldash, mdash = magma.HigherLevelUpGj(p, kk, prec, weightbound, eps_magma,'"B"',nvals=5) else: # Am, zetapm, eimatm, elldash, mdash = magma.UpOperatorData(p, N, kk, prec,WeightBound=weightbound,nvals=5) magma.load("overconvergent_alan.m") Am, zetapm, eimatm, elldash, mdash = magma.HigherLevelUpGj(p, kk, prec, weightbound, N,'"B"',nvals=5) fwrite(" ..Converting to Sage...", outfile) Amodulus = Am[1,1].Parent().Modulus().sage() Aprec = Amodulus.valuation(p) Arows = Am.NumberOfRows().sage() Acols = Am.NumberOfColumns().sage() Emodulus = eimatm[1,1].Parent().Modulus().sage() Eprec = Emodulus.valuation(p) Erows = eimatm.NumberOfRows().sage() Ecols = eimatm.NumberOfColumns().sage() magma.load("get_qexpansions.m") magma.eval('F := Open("%s", "w");'%tmp_filename) magma.eval('fprintf F, "%s, %s, %s, %s \\n"'%(p,Aprec,Arows,Acols)) # parameters magma.eval('save_matrix(%s, F)'%(Am.name())) # for i in range(1,Arows+1): # magma.eval('fprintf F, "%%o\\n", %s[%s]'%(Am.name(),i)) magma.eval('fprintf F, "%s, %s, %s, %s \\n"'%(p,Eprec,Erows,Ecols)) # parameters magma.eval('save_matrix(%s, F)'%(eimatm.name())) # for i in range(1,Erows+1): # magma.eval('fprintf F, "%%o\\n", %s[%s]'%(eimatm.name(),i)) magma.eval('fprintf F, "%s\\n"'%zetapm) magma.eval('fprintf F, "%s\\n"'%elldash) magma.eval('fprintf F, "%s\\n"'%mdash) magma.eval('delete F;') magma.quit() # Read A and eimat from file from sage.structure.sage_object import load from sage.misc.sage_eval import sage_eval with open(tmp_filename,'r') as fmagma: A = read_matrix_from_file(fmagma) eimat = read_matrix_from_file(fmagma) zetapm= sage_eval(fmagma.readline()) elldash = sage_eval(fmagma.readline()) mdash = sage_eval(fmagma.readline()) fwrite("Step 3b: Apply Up^(r-1) to H", outfile) if algorithm == 'twostage': V0 = list(find_Apow_and_ord_two_stage(A, eimat, p, prec)) else: V0 = list(find_Apow_and_ord_three_stage(A,eimat,p,prec)) ord_basis = V0[0] Apow_data = V0[1:] V = [ord_basis] V.extend([eimat, zetapm, elldash, mdash]) V.extend(Apow_data) db_save(V,'Lpvalue_Apow_ordbasis_eimat_%s'%computation_name) from posix import remove remove(tmp_filename) else: A, eimat, elldash, mdash = UpOperator(p,N,kk,prec, modformsring = False, weightbound = 6) fwrite("Step 2: p-depletion, Coleman primitive, and multiply", outfile) fwrite(".. Need %s coefficients of the q-expansion..."%(p**(nu+1) * elldash), outfile) if data is not None: f, h = get_magma_qexpansions(data, data_idx, (p**(nu+1) * elldash) + 200, Qp(p,prec), magma=magma) H = depletion_coleman_multiply(g, h, p, p**(nu+1) * elldash, t=0) fwrite("Step 3a: Compute ordinary projection", outfile) if len(Apow_data) == 1: Hord = compute_ordinary_projection_two_stage(H, Apow_data, eimat, elldash,p) else: Hord = compute_ordinary_projection_three_stage(H, [ord_basis] + Apow_data, eimat, elldash,p,nu) fwrite('Changing Hord to ring %s'%g[1].parent(), outfile) Hord = Hord.change_ring(h[1].parent()) print [Hord[i] for i in range(30)] fwrite("Step 4: Project onto f-component", outfile) while True: try: ell, piHord, epstwist = project_onto_eigenspace(f, ord_basis, Hord, kk, N * p, p = p, derivative_order=derivative_order, max_primes=max_primes) break except RuntimeError: derivative_order += 1 verbose("Increasing experimental derivative order to %s"%derivative_order) except ValueError: verbose("Experimental derivative order (%s) seems too high"%derivative_order) fwrite("Experimental derivative_order = %s"%derivative_order, outfile) fwrite("Seems too high...", outfile) fwrite("######################################", outfile) assert 0 n = 1 while f[n] == 0: n = next_prime(n) if lauders_advice == True or orthogonal_form is None: Lpa = piHord[n] / (f[n] * epstwist(n)) fwrite("Experimental derivative_order = %s"%derivative_order, outfile) fwrite("Checking Lauder's coincidence... (following should be a bunch of 'large' valuations)", outfile) fwrite(str([(i,(Lpa * f[i] * epstwist(i) - piHord[i]).valuation(p)) for i in prime_range(50)]), outfile) fwrite("Done", outfile) else: gplus, gminus = f, orthogonal_form l1 = 2 while N*p*ell % l1 == 0 or gplus[l1] == 0: l1 = next_prime(l1) proj_mat = matrix([[gplus[l1],gplus[p]],[gminus[l1],gminus[p]]]) Lpalist = (matrix([piHord[l1],piHord[p]]) * proj_mat**-1).list() Lpa = Lpalist[0] if Lpa.valuation() > prec / 2: # this is quite arbitrary! Lpa = Lpalist[1] Lpa = Lpa / f[n] fwrite("ell = %s"%ell, outfile) fwrite("######### FINISHED COMPUTATION ###########", outfile) fwrite("Lp = %s"%Lpa, outfile) fwrite("##########################################", outfile) return Lpa, ell
def Lpvalue(f, g, h, p, prec, N=None, modformsring=False, weightbound=6, eps=None, orthogonal_form=None, magma_args=None, force_computation=False, algorithm='twostage'): if magma_args is None: magma_args = {} if algorithm not in ['twostage', 'threestage']: raise ValueError( 'Algorithm should be one of "twostage" (default) or "threestage"') from sage.interfaces.magma import Magma magma = Magma(**magma_args) ll, mm = g.weight(), h.weight() t = 0 # Assume t = 0 here kk = ll + mm - 2 * (1 + t) # Is this correct? p = ZZ(p) if N is None: N = LCM([ZZ(f.level()), ZZ(g.level()), ZZ(h.level())]) N = N.prime_to_m_part(p) print("Tame level N = %s, prime p = %s" % (N, p)) prec = ZZ(prec) print("Step 1: Compute the Up matrix") computation_name = '%s_%s_%s_%s_%s_%s' % ( p, N, kk, prec, 'triv' if eps is None else 'char', algorithm) tmp_filename = '/tmp/magma_mtx_%s.tmp' % computation_name import os.path from sage.misc.persist import db, db_save try: if force_computation: raise IOError V = db('Lpvalue_Apow_ordbasis_eimat_%s' % computation_name) ord_basis, eimat, zetapm, elldash, mdash = V[:5] Apow_data = V[5:] except IOError: if force_computation or not os.path.exists(tmp_filename): if eps is not None: eps_magma = sage_character_to_magma(eps, magma=magma) Am, zetapm, eimatm, elldash, mdash = magma.UpOperatorData( p, eps_magma, kk, prec, nvals=5) else: Am, zetapm, eimatm, elldash, mdash = magma.UpOperatorData( p, N, kk, prec, nvals=5) print(" ..Converting to Sage...") Amodulus = Am[1, 1].Parent().Modulus().sage() Arows = Am.NumberOfRows().sage() Acols = Am.NumberOfColumns().sage() Emodulus = eimatm[1, 1].Parent().Modulus().sage() Erows = eimatm.NumberOfRows().sage() Ecols = eimatm.NumberOfColumns().sage() magma.eval('F := Open("%s", "w");' % tmp_filename) magma.eval('fprintf F, "Matrix(Zmod(%s),%s, %s, "' % (Amodulus, Arows, Acols)) magma.eval('fprintf F, "%%o", ElementToSequence(%s)' % Am.name()) magma.eval('fprintf F, ") \\n"') magma.eval('fprintf F, "Matrix(Zmod(%s),%s, %s, "' % (Emodulus, Erows, Ecols)) magma.eval('fprintf F, "%%o", ElementToSequence(%s)' % eimatm.name()) magma.eval('fprintf F, ") \\n"') magma.eval('fprintf F, "%%o\\n", %s' % zetapm.name()) magma.eval('fprintf F, "%%o\\n", %s' % elldash.name()) magma.eval('fprintf F, "%%o\\n", %s' % mdash.name()) magma.eval('delete F;') magma.quit() # Read A and eimat from file from sage.structure.sage_object import load from sage.misc.sage_eval import sage_eval with open(tmp_filename, 'r') as fmagma: A = sage_eval(fmagma.readline(), preparse=False) eimat = sage_eval(fmagma.readline(), preparse=False) zetapm = sage_eval(fmagma.readline()) elldash = sage_eval(fmagma.readline()) mdash = sage_eval(fmagma.readline()) print("Step 3b: Apply Up^(r-1) to H") if algorithm == 'twostage': V0 = list(find_Apow_and_ord(A, eimat, p, prec)) else: V0 = list(find_Apow_and_ord_three_stage(A, eimat, p, prec)) ord_basis = V0[0] Apow_data = V0[1:] V = [ord_basis] V.extend([eimat, zetapm, elldash, mdash]) V.extend(Apow_data) db_save(V, 'Lpvalue_Apow_ordbasis_eimat_%s' % computation_name) from posix import remove remove(tmp_filename) print("Step 2: p-depletion, Coleman primitive, and multiply") H = depletion_coleman_multiply(g, h, p, p * elldash, t=0) print("Step 3a: Compute Up(H)") UpH = vector([H(p * n) for n in range(elldash)]) if len(Apow_data) == 1: Hord = compute_ordinary_projection_two_stage(UpH, Apow_data, eimat, elldash) else: Hord = compute_ordinary_projection_three_stage(UpH, [ord_basis] + Apow_data, eimat, elldash) Hord = Hord.change_ring(Apow_data[0].parent().base_ring()) print("Step 4: Project onto f-component") R = Qp(p, prec) if orthogonal_form is None: ell, piHord = project_onto_eigenspace(f, ord_basis, Hord.change_ring(R), kk, N * p, eps) n = 1 while f[n] == 0: n += 1 Lpa = R(piHord[n]) / R(f[n]) else: ell, piHord = project_onto_eigenspace(f, ord_basis, Hord.change_ring(R), kk, N * p, eps, derivative_order=2) gplus, gminus = f, orthogonal_form l1 = 2 while N * p * ell % l1 == 0 or gplus[l1] == 0: l1 = next_prime(l1) proj_mat = matrix([[gplus[l1], gplus[p]], [gminus[l1], gminus[p]]]) Lpalist = (matrix([piHord[l1], piHord[p]]) * proj_mat**-1).list() Lpa = Lpalist[0] if Lpa.valuation() > prec / 2: # this is quite arbitrary! Lpa = Lpalist[1] n = 1 while f[n] == 0: n += 1 Lpa = Lpa / f[n] return Lpa, ell
def get_magma_qexpansions(filename, i1, prec, base_ring, magma=None): if magma is None: from sage.interfaces.magma import Magma magma = Magma() magma.set('prec',prec) magma.load("get_qexpansions.m") if i1 is None: for line in filename: print line magma.eval(line) magma.eval("f := g") # In case text is reversed f = 'f' eps_data_f = 'eps_on_gens' else: magma.load(filename) f = 'eigenforms_list[%s][1]'%i1 eps_data_f = 'eigenforms_list[%s][2]'%i1 qexpm = magma.extend_qexpansion(f, eps_data_f, prec) F0 = [0] * qexpm.Valuation().sage() + [o.sage() for o in qexpm.ElementToSequence()] K = F0[-1].parent() a = K.gen() phi = find_embeddings(K,base_ring)[0] F = [phi(o) for o in F0] eps_f = magma.get_character(f, eps_data_f).ValueList().sage() eps_f_full = magma.get_character_full(f, eps_data_f).ValueList().sage() N = len(eps_f) Geps = DirichletGroup(N, base_ring = K) eps_f = Geps([eps_f[i - 1] for i in Geps.unit_gens()]) Geps_full = DirichletGroup(N) psi = eps_f_full[0].parent().embeddings(Geps_full.base_ring())[0] eps_f_full = Geps_full([psi(eps_f_full[i - 1]) for i in Geps_full.unit_gens()]) if a == 1: sigma = lambda x:x else: try: sigma = next((s for s in K.automorphisms() if s(a)*a == 1)) except StopIteration: raise NotImplementedError G = [phi(sigma(o)) for o in F0] eps_g = eps_f**-1 eps_g_full = eps_f_full**-1 F = ModFormqExp(F, base_ring, weight=1, level = N, character = eps_f, character_full = eps_f_full) G = ModFormqExp(G, base_ring, weight=1, level = N, character = eps_g, character_full = eps_g_full) return F, G
def BigArithGroup(p, quat_data, level, base=None, grouptype=None, seed=None, use_sage_db=False, outfile=None, magma=None, timeout=0, logfile=None, use_shapiro=True, character=None, nscartan=None, matrix_group=False): if magma is None: from sage.interfaces.magma import Magma magma = Magma(logfile=logfile) page_path = os.path.dirname(__file__) + '/KleinianGroups-1.0/klngpspec' if seed is not None: magma.eval('SetSeed(%s)' % seed) magma.attach_spec(page_path) magma.eval('Page_initialized := true') a, b = None, None if logfile is not None: magma.eval('SetVerbose("Kleinian",2)') try: discriminant = ZZ(quat_data) if base is not None: assert base == QQ else: base = QQ fname = 'arithgroup%s_%s_%s_%s.sobj' % (seed, p, discriminant, level ) # Fix this name except TypeError: a, b = quat_data if base is None: base = a.parent() discriminant = QuaternionAlgebra(base, a, b).discriminant() fname = 'arithgroup%s_%s_%s_%s.sobj' % (seed, p, discriminant, level ) # Fix this name if base != QQ: use_sage_db = False # This is not implemented yet if grouptype is None: if base == QQ: grouptype = 'PSL2' else: grouptype = 'PGL2' if use_sage_db: try: newobj = db(fname) except IOError: verbose('Group not found in database. Computing from scratch.') newobj = BigArithGroup_class(base, p, discriminant, level, seed, outfile=outfile, grouptype=grouptype, magma=magma, timeout=timeout, use_shapiro=use_shapiro, character=character, nscartan=nscartan, matrix_group=matrix_group) newobj.save_to_db() else: if a is not None: newobj = BigArithGroup_class(base, p, discriminant, abtuple=(a, b), level=level, seed=seed, outfile=outfile, grouptype=grouptype, magma=magma, timeout=timeout, use_shapiro=use_shapiro, character=character, nscartan=nscartan, matrix_group=matrix_group) else: newobj = BigArithGroup_class(base, p, discriminant, level=level, seed=seed, outfile=outfile, grouptype=grouptype, magma=magma, timeout=timeout, use_shapiro=use_shapiro, character=character, nscartan=nscartan, matrix_group=matrix_group) return newobj
def darmon_point(P, E, beta, prec, ramification_at_infinity=None, input_data=None, magma=None, working_prec=None, recognize_point=True, **kwargs): r''' EXAMPLES: We first need to import the module:: sage: from darmonpoints.darmonpoints import darmon_point A first example (Stark--Heegner point):: sage: from darmonpoints.darmonpoints import darmon_point sage: darmon_point(7,EllipticCurve('35a1'),41,20, cohomological=False, use_magma=False, use_ps_dists = True) Starting computation of the Darmon point ... (-70*alpha + 449 : 2100*alpha - 13444 : 1) A quaternionic (Greenberg) point:: sage: darmon_point(13,EllipticCurve('78a1'),5,20) # long time # optional - magma A Darmon point over a cubic (1,1) field:: sage: F.<r> = NumberField(x^3 - x^2 - x + 2) sage: E = EllipticCurve([-r -1, -r, -r - 1,-r - 1, 0]) sage: N = E.conductor() sage: P = F.ideal(r^2 - 2*r - 1) sage: beta = -3*r^2 + 9*r - 6 sage: darmon_point(P,E,beta,20) # long time # optional - magma ''' # global G, Coh, phiE, Phi, dK, J, J1, cycleGn, nn, Jlist config = ConfigParser.ConfigParser() config.read('config.ini') param_dict = config_section_map(config, 'General') param_dict.update(config_section_map(config, 'DarmonPoint')) param_dict.update(kwargs) param = Bunch(**param_dict) # Get general parameters outfile = param.get('outfile') use_ps_dists = param.get('use_ps_dists', False) use_shapiro = param.get('use_shapiro', False) use_sage_db = param.get('use_sage_db', False) magma_seed = param.get('magma_seed', 1515316) parallelize = param.get('parallelize', False) Up_method = param.get('up_method', 'naive') use_magma = param.get('use_magma', True) progress_bar = param.get('progress_bar', True) sign_at_infinity = param.get('sign_at_infinity', ZZ(1)) # Get darmon_point specific parameters idx_orientation = param.get('idx_orientation') idx_embedding = param.get('idx_embedding', 0) algorithm = param.get('algorithm') quaternionic = param.get('quaternionic') cohomological = param.get('cohomological', True) if Up_method == "bigmatrix" and use_shapiro == True: import warnings warnings.warn( 'Use of "bigmatrix" for Up iteration is incompatible with Shapiro Lemma trick. Using "naive" method for Up.' ) Up_method = 'naive' if working_prec is None: working_prec = max([2 * prec + 10, 30]) if use_magma: page_path = os.path.dirname(__file__) + '/KleinianGroups-1.0/klngpspec' if magma is None: from sage.interfaces.magma import Magma magma = Magma() quit_when_done = True else: quit_when_done = False magma.attach_spec(page_path) else: quit_when_done = False sys.setrecursionlimit(10**6) F = E.base_ring() beta = F(beta) DB, Np, Ncartan = get_heegner_params(P, E, beta) if quaternionic is None: quaternionic = (DB != 1) if cohomological is None: cohomological = quaternionic if quaternionic and not cohomological: raise ValueError( "Need cohomological algorithm when dealing with quaternions") if use_ps_dists is None: use_ps_dists = False if cohomological else True try: p = ZZ(P) except TypeError: p = ZZ(P.norm()) if not p.is_prime(): raise ValueError('P (= %s) should be a prime, of inertia degree 1' % P) if F == QQ: dK = ZZ(beta) extra_conductor_sq = dK / fundamental_discriminant(dK) assert ZZ(extra_conductor_sq).is_square() extra_conductor = extra_conductor_sq.sqrt() dK = dK / extra_conductor_sq assert dK == fundamental_discriminant(dK) if dK % 4 == 0: dK = ZZ(dK / 4) beta = dK else: dK = beta # Compute the completion of K at p x = QQ['x'].gen() K = F.extension(x * x - dK, names='alpha') if F == QQ: dK = K.discriminant() else: dK = K.relative_discriminant() hK = K.class_number() sgninfty = 'plus' if sign_at_infinity == 1 else 'minus' if hasattr(E, 'cremona_label'): Ename = E.cremona_label() elif hasattr(E, 'ainvs'): Ename = E.ainvs() else: Ename = 'unknown' fname = 'moments_%s_%s_%s_%s.sobj' % (P, Ename, sgninfty, prec) if use_sage_db: print("Moments will be stored in database as %s" % (fname)) if outfile == 'log': outfile = '%s_%s_%s_%s_%s_%s.log' % ( P, Ename, dK, sgninfty, prec, datetime.datetime.now().strftime("%Y%m%d-%H%M%S")) outfile = outfile.replace('/', 'div') outfile = '/tmp/darmonpoint_' + outfile fwrite("Starting computation of the Darmon point", outfile) fwrite('D_B = %s %s' % (DB, factor(DB)), outfile) fwrite('Np = %s' % Np, outfile) if Ncartan is not None: fwrite('Ncartan = %s' % Ncartan, outfile) fwrite('dK = %s (class number = %s)' % (dK, hK), outfile) fwrite('Calculation with p = %s and prec = %s' % (P, prec), outfile) fwrite('Elliptic curve %s: %s' % (Ename, E), outfile) if outfile is not None: print("Partial results will be saved in %s" % outfile) if input_data is None: if cohomological: # Define the S-arithmetic group if F != QQ and ramification_at_infinity is None: if F.signature()[0] > 1: if F.signature()[1] == 1: ramification_at_infinity = F.real_places( prec=Infinity) # Totally 'definite' else: raise ValueError( 'Please specify the ramification at infinity') elif F.signature()[0] == 1: if len(F.ideal(DB).factor()) % 2 == 0: ramification_at_infinity = [] # Split at infinity else: ramification_at_infinity = F.real_places( prec=Infinity) # Ramified at infinity else: ramification_at_infinity = None if F == QQ: abtuple = QuaternionAlgebra(DB).invariants() else: abtuple = quaternion_algebra_invariants_from_ramification( F, DB, ramification_at_infinity, magma=magma) G = BigArithGroup(P, abtuple, Np, base=F, outfile=outfile, seed=magma_seed, use_sage_db=use_sage_db, magma=magma, use_shapiro=use_shapiro, nscartan=Ncartan) # Define the cycle ( in H_1(G,Div^0 Hp) ) Coh = ArithCoh(G) while True: try: cycleGn, nn, ell = construct_homology_cycle( p, G.Gn, beta, working_prec, lambda q: Coh.hecke_matrix(q).minpoly(), outfile=outfile, elliptic_curve=E) break except PrecisionError: working_prec *= 2 verbose( 'Encountered precision error, trying with higher precision (= %s)' % working_prec) except ValueError: fwrite( 'ValueError occurred when constructing homology cycle. Returning the S-arithmetic group.', outfile) if quit_when_done: magma.quit() return G except AssertionError as e: fwrite( 'Assertion occurred when constructing homology cycle. Returning the S-arithmetic group.', outfile) fwrite('%s' % str(e), outfile) if quit_when_done: magma.quit() return G eisenstein_constant = -ZZ(E.reduction(ell).count_points()) fwrite( 'r = %s, so a_r(E) - r - 1 = %s' % (ell, eisenstein_constant), outfile) fwrite('exponent = %s' % nn, outfile) phiE = Coh.get_cocycle_from_elliptic_curve(E, sign=sign_at_infinity) if hasattr(E, 'ap'): sign_ap = E.ap(P) else: try: sign_ap = ZZ(P.norm() + 1 - E.reduction(P).count_points()) except ValueError: sign_ap = ZZ(P.norm() + 1 - Curve(E).change_ring( P.residue_field()).count_points(1)[0]) Phi = get_overconvergent_class_quaternionic( P, phiE, G, prec, sign_at_infinity, sign_ap, use_ps_dists=use_ps_dists, use_sage_db=use_sage_db, parallelize=parallelize, method=Up_method, progress_bar=progress_bar, Ename=Ename) # Integration with moments tot_time = walltime() J = integrate_H1(G, cycleGn, Phi, 1, method='moments', prec=working_prec, parallelize=parallelize, twist=True, progress_bar=progress_bar) verbose('integration tot_time = %s' % walltime(tot_time)) if use_sage_db: G.save_to_db() else: # not cohomological nn = 1 eisenstein_constant = 1 if algorithm is None: if Np == 1: algorithm = 'darmon_pollack' else: algorithm = 'guitart_masdeu' w = K.maximal_order().ring_generators()[0] r0, r1 = w.coordinates_in_terms_of_powers()(K.gen()) QQp = Qp(p, working_prec) Cp = QQp.extension(w.minpoly().change_ring(QQp), names='g') v0 = K.hom([r0 + r1 * Cp.gen()]) # Optimal embeddings of level one fwrite("Computing optimal embeddings of level one...", outfile) Wlist = find_optimal_embeddings(K, use_magma=use_magma, extra_conductor=extra_conductor) fwrite("Found %s such embeddings." % len(Wlist), outfile) if idx_embedding is not None: if idx_embedding >= len(Wlist): fwrite( 'There are not enough embeddings. Taking the index modulo %s' % len(Wlist), outfile) idx_embedding = idx_embedding % len(Wlist) fwrite('Taking only embedding number %s' % (idx_embedding), outfile) Wlist = [Wlist[idx_embedding]] # Find the orientations orients = K.maximal_order().ring_generators()[0].minpoly().roots( Zmod(Np), multiplicities=False) fwrite("Possible orientations: %s" % orients, outfile) if len(Wlist) == 1 or idx_orientation == -1: fwrite("Using all orientations, since hK = 1", outfile) chosen_orientation = None else: fwrite("Using orientation = %s" % orients[idx_orientation], outfile) chosen_orientation = orients[idx_orientation] emblist = [] for i, W in enumerate(Wlist): tau, gtau, sign, limits = find_tau0_and_gtau( v0, Np, W, algorithm=algorithm, orientation=chosen_orientation, extra_conductor=extra_conductor) fwrite( 'n_evals = %s' % sum( (num_evals(t1, t2) for t1, t2 in limits)), outfile) emblist.append((tau, gtau, sign, limits)) # Get the cohomology class from E Phi = get_overconvergent_class_matrices(P, E, prec, sign_at_infinity, use_ps_dists=use_ps_dists, use_sage_db=use_sage_db, parallelize=parallelize, progress_bar=progress_bar) J = 1 Jlist = [] for i, emb in enumerate(emblist): fwrite( "Computing %s-th period, attached to the embedding: %s" % (i, Wlist[i].list()), outfile) tau, gtau, sign, limits = emb n_evals = sum((num_evals(t1, t2) for t1, t2 in limits)) fwrite( "Computing one period...(total of %s evaluations)" % n_evals, outfile) newJ = prod((double_integral_zero_infty(Phi, t1, t2) for t1, t2 in limits))**ZZ(sign) Jlist.append(newJ) J *= newJ else: # input_data is not None Phi, J = input_data[1:3] fwrite('Integral done. Now trying to recognize the point', outfile) fwrite('J_psi = %s' % J, outfile) fwrite('g belongs to %s' % J.parent(), outfile) #Try to recognize a generator if quaternionic: local_embedding = G.base_ring_local_embedding(working_prec) twopowlist = [ 4, 3, 2, 1, QQ(1) / 2, QQ(3) / 2, QQ(1) / 3, QQ(2) / 3, QQ(1) / 4, QQ(3) / 4, QQ(5) / 2, QQ(4) / 3 ] else: local_embedding = Qp(p, working_prec) twopowlist = [ 4, 3, 2, 1, QQ(1) / 2, QQ(3) / 2, QQ(1) / 3, QQ(2) / 3, QQ(1) / 4, QQ(3) / 4, QQ(5) / 2, QQ(4) / 3 ] known_multiple = QQ( nn * eisenstein_constant ) # It seems that we are not getting it with present algorithm. while known_multiple % p == 0: known_multiple = ZZ(known_multiple / p) if not recognize_point: fwrite('known_multiple = %s' % known_multiple, outfile) if quit_when_done: magma.quit() return J, Jlist candidate, twopow, J1 = recognize_J(E, J, K, local_embedding=local_embedding, known_multiple=known_multiple, twopowlist=twopowlist, prec=prec, outfile=outfile) if candidate is not None: HCF = K.hilbert_class_field(names='r1') if hK > 1 else K if hK == 1: try: verbose('candidate = %s' % candidate) Ptsmall = E.change_ring(HCF)(candidate) fwrite('twopow = %s' % twopow, outfile) fwrite( 'Computed point: %s * %s * %s' % (twopow, known_multiple, Ptsmall), outfile) fwrite('(first factor is not understood, second factor is)', outfile) fwrite( '(r satisfies %s = 0)' % (Ptsmall[0].parent().gen().minpoly()), outfile) fwrite('================================================', outfile) if quit_when_done: magma.quit() return Ptsmall except (TypeError, ValueError): verbose("Could not recognize the point.") else: verbose('candidate = %s' % candidate) fwrite('twopow = %s' % twopow, outfile) fwrite( 'Computed point: %s * %s * (x,y)' % (twopow, known_multiple), outfile) fwrite('(first factor is not understood, second factor is)', outfile) try: pols = [HCF(c).relative_minpoly() for c in candidate[:2]] except AttributeError: pols = [HCF(c).minpoly() for c in candidate[:2]] fwrite('Where x satisfies %s' % pols[0], outfile) fwrite('and y satisfies %s' % pols[1], outfile) fwrite('================================================', outfile) if quit_when_done: magma.quit() return candidate else: fwrite('================================================', outfile) if quit_when_done: magma.quit() return []
def darmon_point(P, E, beta, prec, ramification_at_infinity = None, input_data = None, magma = None, working_prec = None, **kwargs): r''' EXAMPLES: We first need to import the module:: sage: from darmonpoints.darmonpoints import darmon_point A first example (Stark--Heegner point):: sage: from darmonpoints.darmonpoints import darmon_point sage: darmon_point(7,EllipticCurve('35a1'),41,20, cohomological=False, use_magma=False, use_ps_dists = True) Starting computation of the Darmon point ... (-70*alpha + 449 : 2100*alpha - 13444 : 1) A quaternionic (Greenberg) point:: sage: darmon_point(13,EllipticCurve('78a1'),5,20) # long time # optional - magma A Darmon point over a cubic (1,1) field:: sage: F.<r> = NumberField(x^3 - x^2 - x + 2) sage: E = EllipticCurve([-r -1, -r, -r - 1,-r - 1, 0]) sage: N = E.conductor() sage: P = F.ideal(r^2 - 2*r - 1) sage: beta = -3*r^2 + 9*r - 6 sage: darmon_point(P,E,beta,20) # long time # optional - magma ''' # global G, Coh, phiE, Phi, dK, J, J1, cycleGn, nn, Jlist config = ConfigParser.ConfigParser() config.read('config.ini') param_dict = config_section_map(config, 'General') param_dict.update(config_section_map(config, 'DarmonPoint')) param_dict.update(kwargs) param = Bunch(**param_dict) # Get general parameters outfile = param.get('outfile') use_ps_dists = param.get('use_ps_dists',False) use_shapiro = param.get('use_shapiro',True) use_sage_db = param.get('use_sage_db',False) magma_seed = param.get('magma_seed',1515316) parallelize = param.get('parallelize',False) Up_method = param.get('up_method','naive') use_magma = param.get('use_magma',True) progress_bar = param.get('progress_bar',True) sign_at_infinity = param.get('sign_at_infinity',ZZ(1)) # Get darmon_point specific parameters idx_orientation = param.get('idx_orientation') idx_embedding = param.get('idx_embedding',0) algorithm = param.get('algorithm') quaternionic = param.get('quaternionic') cohomological = param.get('cohomological',True) if Up_method == "bigmatrix" and use_shapiro == True: import warnings warnings.warn('Use of "bigmatrix" for Up iteration is incompatible with Shapiro Lemma trick. Using "naive" method for Up.') Up_method = 'naive' if working_prec is None: working_prec = max([2 * prec + 10, 30]) if use_magma: page_path = os.path.dirname(__file__) + '/KleinianGroups-1.0/klngpspec' if magma is None: from sage.interfaces.magma import Magma magma = Magma() quit_when_done = True else: quit_when_done = False magma.attach_spec(page_path) else: quit_when_done = False sys.setrecursionlimit(10**6) F = E.base_ring() beta = F(beta) DB,Np,Ncartan = get_heegner_params(P,E,beta) if quaternionic is None: quaternionic = ( DB != 1 ) if cohomological is None: cohomological = quaternionic if quaternionic and not cohomological: raise ValueError("Need cohomological algorithm when dealing with quaternions") if use_ps_dists is None: use_ps_dists = False if cohomological else True try: p = ZZ(P) except TypeError: p = ZZ(P.norm()) if not p.is_prime(): raise ValueError,'P (= %s) should be a prime, of inertia degree 1'%P if F == QQ: dK = ZZ(beta) extra_conductor_sq = dK/fundamental_discriminant(dK) assert ZZ(extra_conductor_sq).is_square() extra_conductor = extra_conductor_sq.sqrt() dK = dK / extra_conductor_sq assert dK == fundamental_discriminant(dK) if dK % 4 == 0: dK = ZZ(dK/4) beta = dK else: dK = beta # Compute the completion of K at p x = QQ['x'].gen() K = F.extension(x*x - dK,names = 'alpha') if F == QQ: dK = K.discriminant() else: dK = K.relative_discriminant() hK = K.class_number() sgninfty = 'plus' if sign_at_infinity == 1 else 'minus' if hasattr(E,'cremona_label'): Ename = E.cremona_label() elif hasattr(E,'ainvs'): Ename = E.ainvs() else: Ename = 'unknown' fname = 'moments_%s_%s_%s_%s.sobj'%(P,Ename,sgninfty,prec) if use_sage_db: print("Moments will be stored in database as %s"%(fname)) if outfile == 'log': outfile = '%s_%s_%s_%s_%s_%s.log'%(P,Ename,dK,sgninfty,prec,datetime.datetime.now().strftime("%Y%m%d-%H%M%S")) outfile = outfile.replace('/','div') outfile = '/tmp/darmonpoint_' + outfile fwrite("Starting computation of the Darmon point",outfile) fwrite('D_B = %s %s'%(DB,factor(DB)),outfile) fwrite('Np = %s'%Np,outfile) if Ncartan is not None: fwrite('Ncartan = %s'%Ncartan,outfile) fwrite('dK = %s (class number = %s)'%(dK,hK),outfile) fwrite('Calculation with p = %s and prec = %s'%(P,prec),outfile) fwrite('Elliptic curve %s: %s'%(Ename,E),outfile) if outfile is not None: print("Partial results will be saved in %s"%outfile) if input_data is None: if cohomological: # Define the S-arithmetic group if F != QQ and ramification_at_infinity is None: if F.signature()[0] > 1: if F.signature()[1] == 1: ramification_at_infinity = F.real_places(prec = Infinity) # Totally 'definite' else: raise ValueError,'Please specify the ramification at infinity' elif F.signature()[0] == 1: if len(F.ideal(DB).factor()) % 2 == 0: ramification_at_infinity = [] # Split at infinity else: ramification_at_infinity = F.real_places(prec = Infinity) # Ramified at infinity else: ramification_at_infinity = None if F == QQ: abtuple = QuaternionAlgebra(DB).invariants() else: abtuple = quaternion_algebra_invariants_from_ramification(F, DB, ramification_at_infinity) G = BigArithGroup(P,abtuple,Np,base = F,outfile = outfile,seed = magma_seed,use_sage_db = use_sage_db,magma = magma, use_shapiro = use_shapiro, nscartan=Ncartan) # Define the cycle ( in H_1(G,Div^0 Hp) ) Coh = ArithCoh(G) while True: try: cycleGn,nn,ell = construct_homology_cycle(G,beta,working_prec,lambda q: Coh.hecke_matrix(q).minpoly(), outfile = outfile, elliptic_curve = E) break except PrecisionError: working_prec *= 2 verbose('Encountered precision error, trying with higher precision (= %s)'%working_prec) except ValueError: fwrite('ValueError occurred when constructing homology cycle. Returning the S-arithmetic group.', outfile) if quit_when_done: magma.quit() return G except AssertionError as e: fwrite('Assertion occurred when constructing homology cycle. Returning the S-arithmetic group.', outfile) fwrite('%s'%str(e), outfile) if quit_when_done: magma.quit() return G eisenstein_constant = -ZZ(E.reduction(ell).count_points()) fwrite('r = %s, so a_r(E) - r - 1 = %s'%(ell,eisenstein_constant), outfile) fwrite('exponent = %s'%nn, outfile) phiE = Coh.get_cocycle_from_elliptic_curve(E, sign = sign_at_infinity) if hasattr(E,'ap'): sign_ap = E.ap(P) else: try: sign_ap = ZZ(P.norm() + 1 - E.reduction(P).count_points()) except ValueError: sign_ap = ZZ(P.norm() + 1 - Curve(E).change_ring(P.residue_field()).count_points(1)[0]) Phi = get_overconvergent_class_quaternionic(P,phiE,G,prec,sign_at_infinity,sign_ap,use_ps_dists = use_ps_dists,use_sage_db = use_sage_db,parallelize = parallelize,method = Up_method, progress_bar = progress_bar,Ename = Ename) # Integration with moments tot_time = walltime() J = integrate_H1(G,cycleGn,Phi,1,method = 'moments',prec = working_prec,parallelize = parallelize,twist = True,progress_bar = progress_bar) verbose('integration tot_time = %s'%walltime(tot_time)) if use_sage_db: G.save_to_db() else: # not cohomological nn = 1 eisenstein_constant = 1 if algorithm is None: if Np == 1: algorithm = 'darmon_pollack' else: algorithm = 'guitart_masdeu' w = K.maximal_order().ring_generators()[0] r0,r1 = w.coordinates_in_terms_of_powers()(K.gen()) QQp = Qp(p,working_prec) Cp = QQp.extension(w.minpoly().change_ring(QQp),names = 'g') v0 = K.hom([r0 + r1 * Cp.gen()]) # Optimal embeddings of level one fwrite("Computing optimal embeddings of level one...", outfile) Wlist = find_optimal_embeddings(K,use_magma = use_magma, extra_conductor = extra_conductor) fwrite("Found %s such embeddings."%len(Wlist), outfile) if idx_embedding is not None: if idx_embedding >= len(Wlist): fwrite('There are not enough embeddings. Taking the index modulo %s'%len(Wlist), outfile) idx_embedding = idx_embedding % len(Wlist) fwrite('Taking only embedding number %s'%(idx_embedding), outfile) Wlist = [Wlist[idx_embedding]] # Find the orientations orients = K.maximal_order().ring_generators()[0].minpoly().roots(Zmod(Np),multiplicities = False) fwrite("Possible orientations: %s"%orients, outfile) if len(Wlist) == 1 or idx_orientation == -1: fwrite("Using all orientations, since hK = 1", outfile) chosen_orientation = None else: fwrite("Using orientation = %s"%orients[idx_orientation], outfile) chosen_orientation = orients[idx_orientation] emblist = [] for i,W in enumerate(Wlist): tau, gtau,sign,limits = find_tau0_and_gtau(v0,Np,W,algorithm = algorithm,orientation = chosen_orientation,extra_conductor = extra_conductor) fwrite('n_evals = %s'%sum((num_evals(t1,t2) for t1,t2 in limits)), outfile) emblist.append((tau,gtau,sign,limits)) # Get the cohomology class from E Phi = get_overconvergent_class_matrices(P,E,prec,sign_at_infinity,use_ps_dists = use_ps_dists,use_sage_db = use_sage_db,parallelize = parallelize,progress_bar = progress_bar) J = 1 Jlist = [] for i,emb in enumerate(emblist): fwrite("Computing %s-th period, attached to the embedding: %s"%(i,Wlist[i].list()), outfile) tau, gtau,sign,limits = emb n_evals = sum((num_evals(t1,t2) for t1,t2 in limits)) fwrite("Computing one period...(total of %s evaluations)"%n_evals, outfile) newJ = prod((double_integral_zero_infty(Phi,t1,t2) for t1,t2 in limits))**ZZ(sign) Jlist.append(newJ) J *= newJ else: # input_data is not None Phi,J = input_data[1:3] fwrite('Integral done. Now trying to recognize the point', outfile) fwrite('J_psi = %s'%J,outfile) fwrite('g belongs to %s'%J.parent(),outfile) #Try to recognize a generator if quaternionic: local_embedding = G.base_ring_local_embedding(working_prec) twopowlist = [4, 3, 2, 1, QQ(1)/2, QQ(3)/2, QQ(1)/3, QQ(2)/3, QQ(1)/4, QQ(3)/4, QQ(5)/2, QQ(4)/3] else: local_embedding = Qp(p,working_prec) twopowlist = [4, 3, 2, 1, QQ(1)/2, QQ(3)/2, QQ(1)/3, QQ(2)/3, QQ(1)/4, QQ(3)/4, QQ(5)/2, QQ(4)/3] known_multiple = QQ(nn * eisenstein_constant) # It seems that we are not getting it with present algorithm. while known_multiple % p == 0: known_multiple = ZZ(known_multiple / p) candidate,twopow,J1 = recognize_J(E,J,K,local_embedding = local_embedding,known_multiple = known_multiple,twopowlist = twopowlist,prec = prec, outfile = outfile) if candidate is not None: HCF = K.hilbert_class_field(names = 'r1') if hK > 1 else K if hK == 1: try: verbose('candidate = %s'%candidate) Ptsmall = E.change_ring(HCF)(candidate) fwrite('twopow = %s'%twopow,outfile) fwrite('Computed point: %s * %s * %s'%(twopow,known_multiple,Ptsmall),outfile) fwrite('(first factor is not understood, second factor is)',outfile) fwrite('(r satisfies %s = 0)'%(Ptsmall[0].parent().gen().minpoly()),outfile) fwrite('================================================',outfile) if quit_when_done: magma.quit() return Ptsmall except (TypeError,ValueError): verbose("Could not recognize the point.") else: verbose('candidate = %s'%candidate) fwrite('twopow = %s'%twopow,outfile) fwrite('Computed point: %s * %s * (x,y)'%(twopow,known_multiple),outfile) fwrite('(first factor is not understood, second factor is)',outfile) try: pols = [HCF(c).relative_minpoly() for c in candidate[:2]] except AttributeError: pols = [HCF(c).minpoly() for c in candidate[:2]] fwrite('Where x satisfies %s'%pols[0],outfile) fwrite('and y satisfies %s'%pols[1],outfile) fwrite('================================================',outfile) if quit_when_done: magma.quit() return candidate else: fwrite('================================================',outfile) if quit_when_done: magma.quit() return []
def benchmark(pbound = [3, 2**10], nbound = [3, 2**8], cbound = [1, Infinity], obound = [1, Infinity], loops = 10, tloop = Infinity, tmax = Infinity, prime = False, even = False, check = False, fname = None, write = False, overwrite = False, verbose = True, skip_pari = False, skip_magma = False, skip_rains = False, skip_kummer = False): if write: mode = 'w' if overwrite else 'a' f = open(fname, mode, 0) else: f = sys.stdout pmin, pmax = pbound nmin, nmax = nbound omin, omax = obound cmin, cmax = cbound M = Magma() for p in xrange(pmin, pmax): p = ZZ(p) if not p.is_prime(): continue for n in xrange(nmin, nmax): n = ZZ(n) if (prime == 1 and not is_prime(n)) or (prime == 2 and not is_prime_power(n)): continue if n < 2: continue if n % p == 0: continue if (not even) and (n % 2 == 0): continue o, G = find_root_order(p, [n, n], n, verbose=False) m = G[0][0].parent().order() c = Mod(p,n).multiplicative_order() if verbose: sys.stdout.write("\r"+" "*79) print("\rp = {}, n = {}, (o = {}, c = {})".format(p, n, o, c)) if verbose: t = mytime() sys.stdout.write("Constructing fields ({})".format(time.strftime("%c"))) sys.stdout.flush() q = p**n k = GF(q, name='z') k_rand = GF(q, modulus='random', name='z') k_flint = GF_flint(p, k.modulus(), name='z') if verbose > 1: sys.stdout.write("\ntotal: {}s\n".format(mytime(t))) sys.stdout.flush() # Magma if verbose: sys.stdout.write("\r"+" "*79) sys.stdout.write("\rMagma ({})".format(time.strftime("%c"))) sys.stdout.flush() tloops = 0 for l in xrange(loops): if skip_magma: break if (o > omax) or (o == p): break # let's assume that launching a new Magma instance is cheaper # than computing random irreducible polynomials try: M._start() except OSError as err: # but it can also cause fork issues... # let's accept this # and fail as the situation will only worsen # unless it is "just" a memory issue # which should be mitigated by COW but is not #print(err) if err.errno == errno.ENOMEM: break else: raise try: k_magma = M(k) k_rand_magma = M(k_rand) if tloop is not Infinity: alarm(tloop) t = mytime() k_magma.Embed(k_rand_magma, nvals=0) #M._eval_line("Embed(k_magma, k_rand_magma);", wait_for_prompt=False) tloops += mytime(t) except TypeError: # sage/magma interface sometimes gets confused pass except (KeyboardInterrupt, AlarmInterrupt): # sage interface eats KeyboardInterrupt # and AlarmInterrupt derives from it tloops = 0 break finally: if tloop is not Infinity: cancel_alarm() M.quit() # sage pexpect interface leaves zombies around try: while os.waitpid(-1, os.WNOHANG)[0]: pass # but sometimes every child is already buried # and we get an ECHILD error... except OSError: pass if tloops > tmax: break tmagma = tloops / (l+1) if verbose > 1: sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format(tloops, tloops/(l+1))) sys.stdout.flush() # Rains algorithms if verbose: sys.stdout.write("\r"+" "*79) sys.stdout.write("\rCyclotomic Rains ({})".format(time.strftime("%c"))) sys.stdout.flush() trains = [] tloops = 0 for l in xrange(loops): if skip_rains: break if (o > omax) or (o == p): break try: if tloop is not Infinity: alarm(tloop) t = mytime() a, b = find_gens_cyclorains(k_flint, k_flint, use_lucas = False) tloops += mytime(t) except (KeyboardInterrupt, AlarmInterrupt): tloops = 0 break finally: if tloop is not Infinity: cancel_alarm() if check and (l == 0 or check > 1): g = a.minpoly() if g.degree() != n: raise RuntimeError("wrong degree") if g != b.minpoly(): raise RuntimeError("different minpolys") if tloops > tmax: break trains.append(tloops / (l+1)) if verbose > 1: sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format(tloops, tloops/(l+1))) sys.stdout.flush() # Conic Rains if verbose: sys.stdout.write("\r"+" "*79) sys.stdout.write("\rConic Rains ({})".format(time.strftime("%c"))) sys.stdout.flush() tloops = 0 for l in xrange(loops): if skip_rains: break if (o != 2) or (o > omax) or (o == p): break try: if tloop is not Infinity: alarm(tloop) t = mytime() a, b = find_gens_cyclorains(k_flint, k_flint, use_lucas = True) tloops += mytime(t) except (KeyboardInterrupt, AlarmInterrupt): tloops = 0 break finally: if tloop is not Infinity: cancel_alarm() if check and (l == 0 or check > 1): g = a.minpoly() if g.degree() != n: raise RuntimeError("wrong degree") if g != b.minpoly(): raise RuntimeError("different minpolys") if tloops > tmax: break trains.append(tloops / (l+1)) if verbose > 1: sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format(tloops, tloops/(l+1))) sys.stdout.flush() # Elliptic Rains if verbose: sys.stdout.write("\r"+" "*79) sys.stdout.write("\rElliptic Rains ({})".format(time.strftime("%c"))) sys.stdout.flush() tloops = 0 for l in xrange(loops): if skip_rains: break try: if tloop is not Infinity: alarm(tloop) t = mytime() a, b = find_gens_ellrains(k_flint, k_flint) tloops += mytime(t) except RuntimeError: # sometimes no suitable elliptic curve exists pass except (KeyboardInterrupt, AlarmInterrupt): tloops = 0 break finally: if tloop is not Infinity: cancel_alarm() if check and (l == 0 or check > 1): g = a.minpoly() if g.degree() != n: raise RuntimeError("wrong degree") if g != b.minpoly(): raise RuntimeError("different minpolys") if tloops > tmax: break trains.append(tloops / (l+1)) if verbose > 1: sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format(tloops, tloops/(l+1))) sys.stdout.flush() # PARI/GP if verbose: sys.stdout.write("\r"+" "*79) sys.stdout.write("\rPARI/GP ({})".format(time.strftime("%c"))) sys.stdout.flush() tloops = 0 for l in xrange(loops): if skip_pari: break if c < cmin or c > cmax: break try: if tloop is not Infinity: alarm(tloop) t = mytime() a, b = find_gens_pari(k, k) tloops += mytime(t) except (KeyboardInterrupt, AlarmInterrupt): tloops = 0 break finally: if tloop is not Infinity: cancel_alarm() if check and (l == 0 or check > 1): g = a.minpoly() if g.degree() != n: raise RuntimeError("wrong degree") if g != b.minpoly(): raise RuntimeError("different minpolys") if tloops > tmax: break tpari = tloops / (l+1) # Kummer algorithms tkummer = [] # only linalg and modcomp implemented for c==1 for i, algo in enumerate(kummer_algolist[2*(c==1):-2*(c==1)-1]): if verbose: sys.stdout.write("\r"+" "*79) sys.stdout.write("\rKummer {} ({})".format(kummer_namelist[2*(c==1)+i], time.strftime("%c"))) sys.stdout.flush() tloops = 0 for l in xrange(loops): if skip_kummer: break if c < cmin or c > cmax: break try: if tloop is not Infinity: alarm(tloop) t = mytime() a, b = find_gens_kummer(k_flint, k_flint, n, algo) tloops += mytime(t) except (KeyboardInterrupt, AlarmInterrupt): tloops = 0 break finally: if tloop is not Infinity: cancel_alarm() if check and (l == 0 or check > 1): g = a.minpoly() if g.degree() != n: raise RuntimeError("wrong degree") if g != b.minpoly(): raise RuntimeError("different minpolys") if tloops > tmax: break tkummer.append(tloops / (l+1)) if verbose > 1: sys.stdout.write("\ntotal: {}s, per loop: {}s\n".format(tloops, tloops/(l+1))) sys.stdout.flush() tkummer = 2*(c == 1)*[0] + tkummer + 2*(c == 1)*[0] if verbose: sys.stdout.write("\r") sys.stdout.flush() f.write(("{} {} ({}, {})" + " {}" + " {}"*len(trains) + " {}" + " {}"*len(tkummer)+"\n").format(p, n, o, c, *([tmagma] + trains + [tpari] + tkummer))) if write: f.close()