{{{id=119| #import nosqlite import psage.modform.hilbert.sqrt5.tables as sqrt5 from psage.ellcurve.minmodel.sqrt5 import canonical_model from psage.ellcurve.lseries.lseries_nf import lseries_dokchitser /// }}}

This worksheet will do al computations pertaining to table 1(isogenous curves, rank, labels, etc.), table 3( ap list to a bound of choice), and table 4( values pertaining to the Birch Swinnerton-Dyer Conjecture).

In the next table, it will set the Number field to that of what is wanted, and creates local database, simply for storage. 

Lastly, there is a label , where one should input his/her method of finding the curves before continuing, as this is beefical to know how the curve was initially discovered.

One only has to evaluate all after setting what text file to open. The  file must have is the Norm of the conductor, the conductor, and the weierstrass equation, in that order.

{{{id=1| x = var('x') K.=NumberField(x^2-x-1) import psage.modform.hilbert.sqrt5.tables as sqrt5 import nosqlite db=nosqlite.Client(DATA+'localdb').db from psage.ellcurve.minmodel.sqrt5 import canonical_model label='MJ' g=open('/home/psharaba/MJ.txt') /// }}}

This is simply the list of all commands needed to compute the various isogenous curves. 

{{{id=2| def ap(E,p): return E.change_ring(p.residue_field()).trace_of_frobenius() R. = GF(2)[] def frob(E,p): t = ap(E,p) return ch^2 - ap(E, p)*ch + int(p.norm()) def disc(E, p): t = ap(E, p) return t^2 - 4*p.norm() def isogeny_primes(E, norm_bound, isog_degree_bound): #Returns prime for which E has an isogeny P = [p for p in sqrt5.ideals_of_bounded_norm(norm_bound) if p.is_prime() and E.has_good_reduction(p)] w = set(primes(isog_degree_bound+1)) i = 0 w.remove(2) while len(w) > 0 and i < len(P): d = disc(E, P[i]) w = [ell for ell in w if not (legendre_symbol(d,ell) == -1)] i = i +1 i = 0 while i < len(P): if frob(E,P[i]).is_irreducible(): break i = i+1 if i == len(P): w.insert(0,2) return w def closed_under_multiplication_by_m(E, f, m): """ INPUT: - E -- elliptic curve in *short* Weierstrass form - f -- a polynomial that defines a finite subset S of E[p] that is closed under [-1] - m -- integer m >= 2 coprime to p. We assume that p is odd. OUTPUT: - True if [m]*S = S, and False otherwise. """ K = E.base_field() h = E.multiplication_by_m(m, x_only=True) n = h.numerator(); d = h.denominator() S. = K[] psi = n.parent().hom([x,0]) tau = f.parent().hom([x]) r = tau(f).resultant(psi(n)-Z*psi(d), x) r0 = S.hom([0,f.parent().gen()])(r) return r0.monic() == f.monic() def is_subgroup(E, f, p): """ INPUT: - E -- elliptic curve in *short* Weierstrass form - f -- a polynomial that defines a finite subset S of E[p] that is closed under [-1] - p -- an odd prime OUTPUT: - True exactly if S union {0} is a group. """ m = primitive_root(p) return closed_under_multiplication_by_m(E, f, m) def isogeny_class_computation(E, p): if p != 2: E = E.short_weierstrass_model() F = E.division_polynomial(p).change_ring(K) candidates = [f for f in divisors(F) if f.degree() == (p-1)/2 and is_subgroup(E,f,p)] v = [] w = [] for f in candidates: try: v.append(E.change_ring(K).isogeny(f).codomain()) w.append(f) except ValueError: pass v = [F.change_ring(K).global_minimal_model() for F in v] return v else: w = [Q for Q in E.torsion_subgroup() if order(Q)==2] v = [E.isogeny(E(Q)).codomain() for Q in w] return v def curve_isogeny_vector(E): #Returns isogeny class and adjacency matrix curve_list = [E] i = 0 Adj = matrix(50) ins = 1 norm_bound, isog_degree_bound = 500,500 while i < len(curve_list): isolist = isogeny_primes(curve_list[i],norm_bound, isog_degree_bound) for p in isolist: for F in isogeny_class_computation(curve_list[i],p): bool = True for G in curve_list: if F.is_isomorphic(G): bool = False Adj[i,curve_list.index(G)]=p #if a curve in the isogeny class computation is isom Adj[curve_list.index(G),i]=p #to a curve already in the list, we want a line if bool: curve_list.append(F.global_minimal_model()) Adj[i,ins]=p Adj[ins,i]=p ins += 1 i+=1 Adj = Adj.submatrix(nrows=len(curve_list),ncols=len(curve_list)) return {'curve_list':curve_list, 'adjacency_matrix':Adj, 'norm_bound':norm_bound, 'isog_degree_bound':isog_degree_bound, 'subgroup_checked':True} /// }}}

This function simply reads in the text file(opened from the beginning, please make sure you specify the file to be opened above). This function will insert the Norm(N), conductor(cond), the weierstrass equation(weq), and the way the curve was discovered(found).

{{{id=5| for s in g.readlines(): A=s.split() db.curves.insert({'N':int(A[0]), 'cond': A[1], 'weq': A[2], 'found': label}) /// }}}

This function computes the isogenous curves to the curves read in from the file. It will then update the temporary database with a list of isogenous curves, and the corresponding adjancy matrix(that will be used to construct the graph of the isogeny class). 

{{{id=3| %time X = db('select weq,N from curves order by N') for r1 in range(len(X)): weq1=X[r1][0] weq2=eval(X[r1][0]) E = EllipticCurve(K, weq2) iso = curve_isogeny_vector(E) Tot=iso['curve_list'] India=iso['adjacency_matrix'] hotel=[] for g1 in range(len(Tot)): A=list(Tot[g1].a_invariants()) hotel.append(str(A).replace(' ','')) db.curves.update({'isoclass':str(hotel), 'mtrx': str(India)}, weq=str(weq1)) /// CPU time: 35.01 s, Wall time: 40.51 s }}}

This is simply defining the function to compute the L* value that is found in the Birch Swinnerton-Dyer (BSD) Conjecture. Since the L* value will be the same for curves in the same isogeny, it will be computed now to save time.

{{{id=94| def l_function(ainv): E=EllipticCurve(K,eval(ainv)) F=EllipticCurve(K,list(E.short_weierstrass_model().a_invariants())) v=F.lseries().dokchitser() f=v.taylor_series(1,6) r_an=0 while abs(f[r_an])<1e-10: r_an += 1 if r_an == 6: raise RuntimeError l=float(f[r_an]) return l /// }}}

This function will fix the adjancy matrix so that it will be compatible with the database, and easier to read. This function will also do the computation of the L* value and update the database with both the L* and the revised adjancy matrix.

{{{id=31| %time test=db('select weq,mtrx,isoclass from curves order by N') for s in range(len(test)): A=str(test[s][1]).replace('\n','') A=A.replace('][',',') A='('+A.replace(' ',',')+')' B=len(eval(test[s][2])) M=matrix(B,eval(A)) mat = "matrix(%s,%s)"%(M.nrows(),str(M.list()).replace(' ','')) Lstar=l_function(test[s][0]) db.curves.update({'mtrx':mat, 'L':Lstar},weq=test[s][0]) /// CPU time: 668.16 s, Wall time: 674.16 s }}}

This function now splits up each curve(i.e. the curves within the same isogeny class) and inserts them into another temporary database so that the computation below can calculate all information about each curve. This also adds on the I to the label to indicate that the curves found through isogeny are properly labeled.

{{{id=7| %time test=db('select N,cond,weq,isoclass,mtrx,found, L from curves order by N') for s in range(len(test)): A=test[s] db.curvesU.insert({'N':A[0], 'cond': A[1], 'weq': A[2], 'mtrx': A[4], 'found': A[5], 'L': A[6]}) B=eval(A[3]) for t in range(1,len(B)): E=EllipticCurve(K,eval(B[t])) F=canonical_model(E.global_minimal_model()).a_invariants() G=str([F[0],F[1],F[2],F[3],F[4]]).replace(' ','') db.curvesU.insert({'N':A[0], 'cond': A[1], 'weq': G, 'mtrx':A[4], 'found':A[5]+'I', 'L': A[6]}) /// CPU time: 0.87 s, Wall time: 1.03 s }}}

This function below will compute all necesary things for each curve. This includes the rank bounds, order of the torsion subgroup, the signs of the curve, the order of the discriminant, the order of the j-invaraint, the tamagawa numbers, and the kodiara symbols, while inserting the label, adjancy matrix, and the L* in the process.

{{{id=42| K.
=NumberField(x^2-x-1) embs=K.embeddings(RR) #def grabber(s): # return eval('['+s.split('[')[1].split(']')[0]+']') #returns a-invariants def list_maker(N,cond,eqn): ret = [N,cond,eqn] # #we want to add new text to each line, so we take off # ret = [s] #\n first and define our list to eventually be returned #now we create the elliptic curve over K defined by the a-invariants E = EllipticCurve(K,eval(eqn)) T = E.torsion_subgroup() # calculations for rank bounds TI = T.invariants() # t2 = len([a for a in TI if a%2 == 0]) # simon = E.simon_two_descent() # ret.append(str(simon[0])) #append upper rank bound ret.append(str(simon[1] - t2)) #append lower rank bound D=K(E.discriminant()) #calculate discriminant t='' #create string to add + or - for m in embs: e=m(D) if sgn(e)<0: t+='-' else: t+='+' t+=',' ret.append(t[:-1]) #append disc signs tor=E.torsion_order() ret.append(tor) fac=D.factor() k=[str(e) for p,e in fac] #calculate disc ord ret.append(','.join(k)) #append disc ord #the next section adds ord_(j). There are certain curves (eg N=729 #2) which have #j-invariant 0. The denominator_ideal function is not defined for j=0, so we set #the value to be 1 if this is the case. # try: # denfac = K(E.j_invariant()).denominator_ideal().factor() # except ValueError: # denfac = [(1,1)] z=K(E.j_invariant()) if z: denfac=z.denominator_ideal().factor() if denfac: ret.append(','.join([str(e) for p,e in denfac])) else: ret.append('0') else: ret.append('0') #we still want a value for the table if denfac == [] # l=[str(e) for p,e in denfac] # ret.append(','.join(l)) #append j-ord ret.append(','.join([str(e) for e in E.tamagawa_numbers()])) #append tamagawa z = E.conductor().factor() ret.append(','.join([str(E.kodaira_symbol(p)) for p,e in z])) #append kodaira ret.append(B[3]) ret.append(B[4]) ret.append(B[5]) return ret /// }}}

This function will do the computations listed above, and insert them into a local text file for safekeeping. If there is an issue with a particular curve, it will simply insert it into the "broken" list. Please check to make sure this list is an empty list before continuing, as one might miss computing the rest of the worksheet to this curve.

{{{id=38| %time november=db('select N,cond,weq,mtrx,found, L from curvesU ORDER BY N') data=[] broken=[] for s in range(len(november)): B=november[s] try: data.append(list_maker(B[0],B[1],B[2])) except TypeError: broken.append(B) g = open(DATA+'1.txt','w') for curr_data in data: for i,thing in enumerate(curr_data): curr_data[i] = str(thing) g.write(' '.join(curr_data)+'\n') #writes data to new file g ^^ g.close() /// CPU time: 4.17 s, Wall time: 7.94 s }}} {{{id=45| broken /// [] }}}

This is the function of one of many values needed to order the curves and provide proper labeling for. This is the eta function defined below, which will be implemented below.

{{{id=47| def eta(alpha): return (alpha*alpha).trace() def find_small(alpha): while True: plus=a*alpha minus=alpha/a if eta(plus)This function simply inserts all the information computed above, but with some additions and some ordering. This function will take a curve with the data given from the local textfile, and take the curve and preform both the global minimal model, and the canonical model of the curve, and checks the database to see if the curve exist. If it does exist already, then the curve won't be inserted (this ensures no doubles). If it is unique, then it will compute the curve that is the galois of the initial curve. Then it computes the second conductor for this galois curve. using the two conductors, we take the ideal of the conductors in our field, and check the integral basis of both. If the galois conductor has a smaller integral basis than the other, we reverse the order in which the conductors and weierstrass equations are displayed in the table/database. If we have to switch the order, than the signs will also switch as the periods switch. After determining this, all the information will be inputed into the database which will be used for the remainder of the worksheet.

{{{id=46| %time f=open(DATA+'1.txt') for t in f.readlines(): c=t.split() E = EllipticCurve(K,eval(c[2])) s=c[5] F = E.global_minimal_model() F = canonical_model(F).a_invariants() G1 = str([F[0],F[1],F[2],F[3],F[4]]).replace(' ','') H = list(db.N1k.find(weq1=G1))+list(db.N1k.find(weq2=G1)) L = len(H) if L==0: E = EllipticCurve(K, [galois_conjugate(K(alpha)) for alpha in F]) F = E.global_minimal_model() F = canonical_model(F).a_invariants() G2 = str([F[0],F[1],F[2],F[3],F[4]]).replace(' ','') J1 = K.ideal(eval(c[1])) J2 = K.ideal(galois_conjugate(K(eval(c[1])))) if J1.integral_basis()[1][0] > J2.integral_basis()[1][0]: J1,J2 = J2,J1 G1,G2 = G2,G1 s = s[2]+','+s[0] db.N1k.insert({'N': int(J1.norm()), 'eta': int(eta_ideal(J1)), 'cond1': str(J1.gen(0)).replace(' ',''), 'cond2': str(J2.gen(0)).replace(' ',''), 'weq1': G1, 'weq2': G2, 'rlow': int(c[3]), 'rhi': int(c[4]), 'T': int(c[6]), 's': s, 'ordD': c[7], 'ordj': c[8], 'c_p': c[9], 'K': c[10],'adj': c[11],'found': c[12], 'L': float(c[13])}) /// CPU time: 3.85 s, Wall time: 3.97 s }}}

This is simply the function to compute the periods of the curves using the weierstrass equation that appears first in each row. See above for explaination on how this is determined.

{{{id=83| def period_stuff(E): w = [] v = [] for phi in K.embeddings(RR): B = E.period_lattice(phi).basis() a = B[0].real() if abs(B[1].real()) <1e-20: a *= 2 v.append(float(a)) w.append(B) return v[0], v[1] /// }}}

This computes the periods and the omega value while inserting them into the database.

{{{id=80| %time temp=db('select N,cond1,weq1 from N1k ORDER BY N') for r in range(len(temp)): A=temp[r][2] p0,p1=period_stuff(EllipticCurve(K,eval(A))) db.N1k.update({'real1': float(p0), 'real2': float(p1),'omega':float(p0*p1)},weq1=A) /// CPU time: 10.44 s, Wall time: 10.65 s }}}

This function will compute ap values for the elliptic curve using the first weierstrass equation given a range. All one needs to do is to change the number that is called in the function primes_of_bounded_norm.

{{{id=103| import psage.modform.hilbert.sqrt5.sqrt5 as sq w = sq.primes_of_bounded_norm(100) from psage.ellcurve.minmodel.sqrt5 import canonical_model def ap(E,p): return E.change_ring(p.residue_field()).trace_of_frobenius() def ap_comp(E): q=[] for i in range(len(w)): u=w[i] if E.has_good_reduction(w[i])==True: if not E.conductor().norm()%norm(w[i])==0: try: q.append(ap(E,w[i])) except: q.append('?') else: q.append('?') else: q.append('?') return q /// }}}

This computes the ap values and makes a list and inserts them into the database. This will also take the weierstrass equation and embed it into the $\mathbb R^5$. This will be used for sorting purposes only. This will be explained below. Lastly, this function will take the computed ap lists and insert them into the list 'IO', while the other list thats the embedded weierstrass equations is called "NH'. These lists will be used below.

{{{id=102| %time IO=[] NH=[] embs=K.embeddings(RR)[1] temp=db('select weq1 from N1k ORDER BY N,eta') for r in range(len(temp)): A=temp[r][0] A1=eval(A) B=ap_comp(EllipticCurve(K,eval(A))) C=[embs(f) for f in A1] IO.append(B) NH.append(C) db.N1k.update({'a_p':str(B).replace(' ',''), 'remove': str(C).replace(' ','')},weq1=A) /// WARNING: Output truncated!
full_output.txt 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 ... 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 CPU time: 531.93 s, Wall time: 566.39 s }}}

This function takes the IO and NH and uses them and sorts them in lexigraphical order. This then assigns each ap list and embedded weierstrass an integer value which will serve for ordering isogeny classes via ap lists, and ordering within an isogeny class, i.e embedded weierstrass equations.

{{{id=106| %time IO=sorted(IO) NH=sorted(NH) for r in range(len(IO)): db.N1k.update({'R': int(r)}, a_p=str(IO[r]).replace(' ','')) for s in range(len(NH)): db.N1k.update({'U': int(s)}, remove=str(NH[s]).replace(' ','')) test=db('select weq1,omega from N1k order by N') for r in range(len(test)): O=1/float(test[r][1]) db.N1k.update({'V': float(O)},weq1=test[r][0]) /// CPU time: 3.54 s, Wall time: 80.17 s }}}

After determing the values from above, we compute the 2 sets of labels, a_lbl which is used to sort by norm of the conductor and the conductor(via the eta function). The second label, b_lbl, will be used to order isogeny classes and order within the same isogeny class. a_lbl uses the value from the norm of the conductor and the eta value to sort between those, in that order, while b_lbl uses the lexigraphical order of the ap values, the value of 1/omega, and the lexigraphical order of the embedded weierstrass equation(to break ties if 1/omega value is the same). This then inserts them into the database.

{{{id=107| temp=db('select N,eta,R,V,U, weq1 from N1k ORDER BY N,eta,R,V,U') N=0 lastchar1=ord('a') L=1 lastchar2=ord('a') test=[] for s in range(len(temp)): A=temp[s] if temp[s][0] != temp[s-1][0]: #this instance is a curve with a new norm than the previous entry N=int(temp[s][0]) lastchar1=ord('a') L=ord('a') lastchar2=1 else: if temp[s][1]==temp[s-1][1]: if temp[s][2]==temp[s-1][2]: lastchar2+=1 else: L+=1 lastchar2=1 else: lastchar1+=1 L=ord('a') lastchar2=1 i_lbl=str(N)+chr(lastchar1) l_lbl=chr(L)+str(lastchar2) db.N1k.update({'i_lbl': i_lbl, 'l_lbl': l_lbl}, weq1=temp[s][5]) /// WARNING: Output truncated! full_output.txt 31a a1 [1,a+1,a,31*a-75,141*a-303] 31a a2 [1,a+1,a,41*a-70,170*a-276] 31a a3 [1,a+1,a,a,0] 31a a4 [a,-1,a+1,-17*a-11,39*a+24] 31a a5 [a,a,a+1,32197*a-52096,3319586*a-5371204] 31a a6 [a+1,-a-1,a+1,-1788*a-1105,44001*a+27194] 36a a1 [a+1,a,a,-165*a-165,-1683*a-1221] 36a a2 [a+1,a,a,-10*a-10,10*a+10] 36a a3 [a+1,a,a,-5*a-5,-51*a-37] 36a a4 [a+1,a,a,0,0] 41a a1 [0,-a,a,0,0] 41a a2 [0,-a,a,10*a-40,31*a-113] 45a a1 [1,1,1,-135,-660] 45a a2 [1,1,1,-80,242] 45a a3 [1,1,1,-10,-10] 45a a4 [1,1,1,-5,2] 45a a5 [1,1,1,0,0] 45a a6 [1,1,1,35,-28] 45a a7 [1,1,1,-2160,-39540] 45a a8 [1,1,1,-110,-880] 45a a9 [1,a,a+1,-4976733*a-3075797,-6393196918*a-3951212998] 45a a10 [a,a+1,1,-4364*a-7739,-255406*a-296465] 49a a1 [0,-a+1,1,-30*a-29,-102*a-84] 49a a2 [0,-a+1,1,1,0] 55a a1 [1,-a+1,1,-21*a-25,-54*a-58] 55a a2 [1,-a+1,1,-26*a-15,-70*a-44] 55a a3 [1,-a+1,1,-6*a-5,10*a+6] 55a a4 [1,-a+1,1,-a,0] 55a a5 [1,-a+1,1,54*a,-374*a-198] 55a a6 [a,-a,1,-699*a-432,10856*a+6709] 55a a7 [a+1,0,a+1,599*a-1006,8816*a-14217] 55a a8 [a+1,0,a+1,94*a-156,-538*a+870] 64a a1 [0,-a,0,106*a-171,647*a-1050] 64a a2 [0,-a,0,11*a-16,-17*a+27] 64a a3 [0,a-1,0,-106*a-65,-647*a-403] 64a a4 [0,a-1,0,-11*a-5,17*a+10] 64a a5 [0,a-1,0,-6*a-5,-11*a-7] 64a a6 [0,a-1,0,-a,0] 71a a1 [a,a+1,a,-14*a-5,-42*a-27] 71a a2 [a,a+1,a,-4*a-20,-37*a-39] 71a a3 [a,a+1,a,a,0] 71a a4 [a,a+1,a,6*a-5,-2*a+7] 76a a1 [a+1,0,1,-a-1,0] 76a a2 [a+1,0,1,4*a+4,8*a-2] 76a a3 [a+1,0,1,44*a-196,264*a-1122] 76a a4 [a,0,1,54685*a-90021,7490886*a-12144063] 76a b1 [1,0,a,a-2,-a+1] 76a b2 [a,0,a,-134*a-80,-903*a-561] 79a a1 [a,-a,a+1,687*a-1115,10565*a-17095] 79a a2 [a+1,a-1,a,-5*a-15,-19*a-29] 79a a3 [a+1,a-1,a,5*a-10,5*a-10] 79a a4 [a+1,a-1,a,0,0] 80a a1 [0,-a-1,0,2025*a-3281,52269*a-84572] 80a a2 [0,1,0,-41,-116] 80a a3 [0,1,0,-5*a-11,17*a-1] 80a a4 [0,1,0,5*a-16,-17*a+16] 80a a5 [0,1,0,-1,0] 80a a6 [0,1,0,4,4] 80a a7 [0,a+1,0,-2023*a-1257,-54293*a-33560] ... 209a b5 [a+1,-a+1,a+1,-2*a,-a] 209a b6 [a+1,-a+1,a+1,133*a-190,851*a-1361] 209a c1 [0,-a-1,a+1,3*a-2,-3] 209a c2 [0,-a-1,a+1,143*a-242,1011*a-1645] 209b a1 [a+1,a+1,a+1,a,0] 209b a2 [a+1,a+1,a+1,6*a-5,-a+8] 209b b1 [1,0,a+1,2*a-6,-4*a+4] 209b b2 [1,0,a+1,7*a-11,4*a-11] 209b b3 [a,0,a+1,-355*a-229,-3979*a-2471] 209b b4 [1,0,a+1,422*a-801,5771*a-9836] 209b c1 [1,0,1,21*a-48,73*a-141] 209b c2 [1,0,1,a-3,-a+1] 209b c3 [a,0,1,-43*a-27,-171*a-106] 209b c4 [a+1,0,1,-4704*a-2907,-188363*a-116415] 220a a1 [1,1,0,-2733*a-1703,-83661*a-51718] 220a a2 [a,-a,a+1,2719*a-4427,-81534*a+131881] 220a a3 [a+1,a-1,a,-36*a+2,-79*a-76] 220a a4 [a+1,a-1,a,19*a-43,-94*a+131] 220a a5 [a+1,a-1,a,-a-3,-2*a+3] 220a a6 [a+1,a-1,a,39*a-33,-102*a+113] 220a a7 [a,a+1,0,-300414*a-185685,-95102489*a-58776542] 220a a8 [a+1,a-1,a,164*a-1158,2473*a-15012] 220a b1 [1,-1,a,-4*a-1,3*a+3] 220a b2 [1,-1,a,6*a-11,-3*a+23] 220a b3 [1,-1,a,-144*a-206,-1320*a-1288] 220a b4 [a+1,1,1,5772*a-9400,256067*a-414591] 220a c1 [a,-a+1,0,-67*a-70,-376*a-311] 220a c2 [a,-a+1,0,-2*a,0] 220a c3 [a,-a+1,0,8*a,4*a-6] 220a c4 [1,a,a+1,1439*a-2354,31583*a-51173] 225a a1 [0,-1,1,-8,-7] 225a a2 [0,1,1,2,4] 225a b1 [0,-a+1,1,-2*a-1,2*a+1] 225a b2 [0,-a+1,1,8*a+9,-76*a-55] 225a c1 [a,1,1,65146314*a-105408963,-302615596781*a+489642321128] 225a c2 [a,a,0,-9504680*a-5874303,16858314825*a+10419011887] 225a c3 [a+1,a,a+1,-10800*a-10800,758396*a+571497] 225a c4 [a+1,a,a+1,-675*a-675,11171*a+8547] 225a c5 [a+1,a,a+1,-550*a-550,15946*a+12097] 225a c6 [a+1,a,a+1,-400*a-400,-6044*a-4433] 225a c7 [a+1,a,a+1,-50*a-50,46*a+47] 225a c8 [a+1,a,a+1,-25*a-25,-119*a-83] Traceback (most recent call last): test=[] File "", line 1, in File "/tmp/tmpREJ7db/___code___.py", line 10, in exec compile(u"for s in range(len(temp)):\n A=temp[s]\n if temp[s][_sage_const_0 ] != temp[s-_sage_const_1 ][_sage_const_0 ]: #this instance is a curve with a new norm than the previous entry\n N=int(temp[s][_sage_const_0 ])\n lastchar1=ord('a')\n L=ord('a')\n lastchar2=_sage_const_1 \n else:\n if temp[s][_sage_const_1 ]==temp[s-_sage_const_1 ][_sage_const_1 ]:\n if temp[s][_sage_const_2 ]==temp[s-_sage_const_1 ][_sage_const_2 ]:\n lastchar2+=_sage_const_1 \n else:\n L+=_sage_const_1 \n lastchar2=_sage_const_1 \n else:\n lastchar1+=_sage_const_1 \n L=ord('a')\n lastchar2=_sage_const_1 \n i_lbl=str(N)+chr(lastchar1)\n l_lbl=chr(L)+str(lastchar2)\n print i_lbl, l_lbl, temp[s][_sage_const_5 ]\n db2.N1k.update({'i_lbl': i_lbl, 'l_lbl': l_lbl}, weq1=temp[s][_sage_const_5 ])" + '\n', '', 'single') File "", line 22, in File "/home/wstein/nosqlite/nosqlite.py", line 940, in update self.database(cmd, t) File "/home/wstein/nosqlite/nosqlite.py", line 592, in __call__ return self.client(cmds, t, file=self.name, many=many, coerce=coerce) File "/home/wstein/nosqlite/nosqlite.py", line 467, in __call__ return self.server.execute(cmd, t, file, many) File "/home/wstein/nosqlite/nosqlite.py", line 352, in execute db.commit() KeyboardInterrupt __SAGE__ }}}

These next two function serve as a way to ensure the ranks are correct. If a weierstrass equation has large integer coefficents, the simon_two_descent function sometimes cannot figure out the correct rank, usually within the same isogeny. To correct this, we know that the rank of the isogeny class is the same, so this function will pull the optimal curves from the database and check to see if the rank bound matches, and if it does, it inserts them into the database as "rank", not as the bounds which are already inserted.

{{{id=108| temp=db('select R,weq1,rlow,rhi from N1k WHERE l_lbl LIKE "_1" ORDER BY N') for r in range(len(temp)): if temp[r][2] == temp[r][3]: db.temp.insert({'rank':int(temp[r][2]), 'weq1':temp[r][1], 'value': int(temp[r][0])}) else: print temp[r] /// }}}

This function will make the rank of the curves within the same isogeny the same by using the ap list to match against. If there isn't an integer value for the rank(computed above), it will not insert a rank into the database, but simply leave the bounds for now.

{{{id=109| temp=db('select R,weq1 from N1k ORDER BY N') for r in range(len(temp)): A=temp[r][0] B=db.temp.find_one(value=A)['rank'] if type(B)==int(!): db.N1k.update({'rank': int(B)}, weq1=temp[r][1]) /// }}}

This function will define both the regulator and sha function, and a third function which will compute both at the same time. Disclaimer: the saturation bound is low purposely to speed up the calculatio of sha. If one wants, one can raise the saturation bound by changing the number in the function comp( see comment within the function to find where to change).

{{{id=53| def regulator_new(E,rank,sat_bound): if rank == 0: Q= 0 else: v = E.simon_two_descent() Q = v[-1][0] for p in prime_range(sat_bound): if len(Q.division_points(p)) != 0: Q = Q.division_points(p)[0] print Q if Q== 0: return int(1), [] else: return Q.height()/2, [Q] def conjectural_sha(E, omega, reg=1, Lstar=1): M = E.tamagawa_product_bsd() sha = RR(sqrt(5))*Lstar*(E.torsion_order())^2/((omega)*reg*M) return sha def comp(weq,lstar,rank,omega): E=EllipticCurve(K,eval(weq)) R=regulator_new(E,rank,10) #this is where one would change the value for saturation bound. Currently held at 10 if R[0] <= 0: return R[0], 'error with regulator' else: Sha=conjectural_sha(E,omega,R[0],lstar) return R[0],Sha /// }}}

This function actually tries to compute the value of sha and regulator. As seen above, the saturation bound is low for speed, so there might be errors when trying to compute. If the value of the regulator is negative or zero, it will append the curve to the broken2 list automatically. If the value of sha is below .5, it will also give an error and append to broken 2. Lastly, if a ValueError or IndexError, it will also append to broken2. One will look at these curves after the computation is done, which is evaluated immediately after this computation.

{{{id=92| %time broken2=[] temp=db('select weq1,L,rank,omega from N1k') for r in range(len(temp)): try: reg,S=comp(temp[r][0], temp[r][1], temp[r][2], temp[r][3]) if S>=.5: db.N1k.update({'Sha': float(S), 'Reg': float(reg)}, weq1=temp[r][0]) else: broken2.append((temp[r][0], reg, S)) except IndexError: broken2.append(temp[r][0]) except ValueError: broken2.append(temp[r][0]) /// 0 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 CPU time: 4.09 s, Wall time: 4.41 s }}} {{{id=96| broken2 /// [] }}}

This function will now create a permanant database that will be stored to a folder/file of your choice.  It will include all the data computed from this worksheet and insert it in. This will also include the values for the sorting: eta,R(lexigraphical order for ap list),V(value computed by 1/omega) ,U(lexigraphical order of the embedded weierstrass equation).

 

###NOTE: PLEASE CHANGE LOCATION OF DATABASE TO BE SAVED. CHANGE DATABASE NAME IF NEEDED ###

{{{id=110| db2=nosqlite.Client('/home/psharaba/ECdb').db temp=db('select N,cond1,cond2,weq1, weq2, rank,T,s,ordD,ordj,c_p, K, real1,real2,omega,L,Reg,Sha,adj,found,i_lbl,l_lbl, eta,R,V,U from N1k ORDER BY N,eta,R,V,U') for r in range(len(temp)): A=temp[r] db2.N1k.insert({'N':int(A[0]), 'cond1': A[1], 'cond2': A[2], 'weq1': A[3], 'weq2': A[4], 'rank': int(A[5]), 'T': int(A[6]), 's': A[7], 'ordD': A[8], 'ordj': A[9], 'c_p': A[10], 'K': A[11], 'real1': float(A[12]), 'real2': float(A[13]), 'omega': float(A[14]), 'L': float(A[15]), 'Reg': A[16], 'Sha': A[17], 'adj': A[18], 'found': A[19], 'a_lbl': A[20], 'b_lbl': A[21], 'eta': int(A[22]), 'R': int(A[23]), 'V': int(A[24]), 'U': int(A[25])}) /// }}}

These last two functions may look familiar, but these only need to be run if one is inserting new curves into already database.

###NOTE: YOUR DATABASE NAME MAYBE DIFFERENT. CHANGE ACCORDINGLY. ###

These functions will redo the sorting for the lexigraphical ordering for the ap lists and embedded weierstrass equations

{{{id=111| %time IO=[] NH=[] embs=K.embeddings(RR)[1] temp=db2('select weq1 from N1k ORDER BY N,eta') for r in range(len(temp)): A=temp[r][0] A1=eval(A) B=ap_comp(EllipticCurve(K,eval(A))) C=[embs(f) for f in A1] IO.append(B) NH.append(C) db2.N1k.update({'a_p':str(B).replace(' ',''), 'remove': str(C).replace(' ','')},weq1=A) /// }}} {{{id=118| %time IO=sorted(IO) NH=sorted(NH) for r in range(len(IO)): db2.N1k.update({'R': int(r)}, a_p=str(IO[r]).replace(' ','')) for s in range(len(NH)): db2.N1k.update({'U': int(s)}, remove=str(NH[s]).replace(' ','')) test=db2('select weq1,omega from N1k order by N') for r in range(len(test)): O=1/float(test[r][1]) db2.N1k.update({'V': float(O)},weq1=test[r][0]) /// }}}