lprint(`Reading menuF ..`); Menu:=proc() local i,l,x,y; #Print details of apecs command specified by args l:=proc();lprint(args);end: if nargs=0 then l(`Menu, unlike menu, requires the name of an apecs command`); l(`e.g. Menu(eadd) or Menu(Eadd), even Menu(Menu)`);RETURN(); fi; x:=args:i:='i': if member(x,[AgM,agM,'Allp','allp',App,app,Comb,comb,Eadd,eadd,'Eadp',\ 'eadp',Ein0,ein0,ein,Ein,Ell,ell,Emod,emod,Emods,emods,Ford,ford,\ Gcub,gcub,Genj,genj,Ht,ht,Sub,sub,Isog,isog,'Menu','Mulp','mulp',Mult,mult,\ Om,om,Omp,omp,Quar,quar,Quar0,quar0,Rk,rk,Rk0,rk0,Seek,seek,Sfe,sfe,Sh\ a,sha,Trcw,trcw,Trwc,trwc,Tw,tw,FnL,fnL,Mest,mest,Trf,trf,On,on,'Onp','onp',\ Rk1,rk1,Neg,neg,Bas,bas,Ind,ind,Lin,lin,Gram,gram,Abel,abel,Roha,roha,Absc,\ absc,'Negp','negp',Search,search,Seek1,seek1,Raf,raf,We,we,Div,div,Tri,tri\ ,Velu,velu,'Exam','exam',Hdif_Sik,hdif_Sik,Hdif_Sil,hdif_Sil,RkNC,rkNC,Expr,\ expr,Store,store,Trans,trans,Cubic_fit,cubic_fit,Third_pt,third_pt,Weier_fit,\ weier_fit,Tor,tor,'Qfin','qfin',Minf,minf,Fact,fact,Crem,crem,Om2,om2,Subg,subg\ ,Torq,torq,Ub_tor,ub_tor,Go,go,Fundunit,fundunit,Cld,cld,Isom,isom,Seekb\ ,seekb,qv,`q.v.`,Quarm,quarm,Ypecs,ypecs,Zpecs,zpecs,Afac,afac,Heeg,heeg],i) then if i<3 then l(`agM(x1,y1)=(x+y)/2`);l(`AgM(x1,y1)=NULL`); l(` where x1,y1 are positive reals (either integers, rationals or floats)`); l(`The arithmetic-geometric mean (denoted agM by Gauss) of x1 and x2 is the`); l(`common limit of x=lim(xn) and y=lim(yn) where x.(n+1)=(xn+yn)/2,`); l(`y.(n+1)=sqrt(xn*yn). These procedures calculate until x and y agree to`); l(`"Digits" digits of accuracy.`); l(`The Maple global variable "Digits" can be set at any time during an apecs`); l(`session, e.g. Digits:=150;. The apecs default value is 20.`); elif i<5 then l(`allp(p1)=Np`); l(`Allp(p1)=NULL`); l(`Np=order of group of non-singular points of E mod p1`); l(`Other variables: if E mod p1 is singular then qs=node or cusp and`); l(`singular point=[xs,ys].`); l(`These procedures work for any weierstrass curve with rational coeff.'s`); l(`whose denominators are prime to p1, even one input via the command Ell`); l(`(Ell doesn't put E in min. Weier. form - sometimes desirable).`); l(`Here's how we calculate square roots mod p: srqt(f)=f^w*t^i mod p`); l(`where, if p=2^k*u+1, u odd, w=(u+1)/2, t=r^u, r any quadratic`); l(`non-residue mod p, and we try in succession i=0,1,.. (some i<2^(k-1)`); l(`will work). E.g. when p=-1 mod 4, sqrt=f^((p+1)/4); when p=5 mod 8,`); l(`sqrt=f^((p+3)/8)*{1 or 2^((p-1)/4)}. For other p one has to find an r`); l(`but on average it's worth it since there are quite a few sqrt's to find.`); elif i<7 then l(`app(args)=NULL`);l(`App(args)=NULL`); l(` where args is either x or x,y or [x,y]`); l(`If args is x then app calls the procedure absc(x) to calculate y.`); l(`This procedure joins [x,y] to the list RR (if its not already there)`); l(`with the following provisos:`); l(` If [x,y] is not a point on E the procedure is aborted.`); l(` If K_=1, so E is defined over Q (see Menu(ell) for the defn. of K_),`); l(`then [x,y] must be defined over Q and either be independent mod torsion`); l(`of the points already in RR, or improve RR by replacing one of the points\ .`); l(`Note that when K_=1 the members of RR are arranged in order of increasing`); l(`canonical height. Any improvement to RR will be carried over to known`); l(`isogenous curves when feasible.`); l(` If K_=T, so E is defined over the function field K=Q(T) and at least one`); l(`of the coefficients a1,..,a6 is not in Q (N.B: the transcendental must`); l(`be T, not another name), or if K_=m_, so K=Q(sqrt(m_) (see Menu(Qfin)),`); l(`app checks that [x,y] is defined over K, then`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`makes a modest check that the point is not already in the group generated`); l(`by RR and torsion. This involves calculating the torsion subgroup, if`); l(`that hasn't already been done. If lin (see Menu(Lin)) indicates that`); l(`it is independent, then it is joined to RR.`); l(` For all other K_, [x,y] is checked not to be of finite order (well`); l(`at least not of order <11) and not to be an "obvious" lin. comb.`); l(`of points already in RR (i.e., not in the auxilliary set uR). If so,`); l(`it is joined to RR and uR is enlarged accordingly.`); elif i<9 then l(`comb(args)=suM`);l(`Comb(args)=NULL`); l(` Find a linear combination of points on E:`); l(` args is a sequence of pairs n1,z1,n2,z2,.. , each ni in Z (pos. or n\ eg.)`); l(`and each zi is a point on E in the form x,y or [x,y] or [x,y,n].`); l(`These procedures calculate suM:=[xc,yc] which is the linear combination`); l(`n1*z1+n2*z2+.. ,with the convention O=[NULL,NULL]=[], and they invoke`); l(`on and mult. If some on(zi)=false then xc='xc' is returned.`); l(`However this on test is disabled if hastype(zi,float) is true.`); elif i<11 then l(`eadd(args)=[x3,y3]`);l(`Eadd(args)=NULL`); l(` where args=z1,z2 and for i=1,2, zi=xi,yi or [xi,yi] or, if zi has finite`); l(`order n, [xi,yi,n]`); l(`Calculate [x3,y3]=z1+z2 on E with the convention that O=[NULL,NULL]=[].`); l(`This procedure works "in general"; some examples are`); l(`Ein(F14);Eadd(-121/4,117/8,-91/3,(132+4*sqrt(-3))/9);===>`); l(`[x3,y3]=[-25,12+28*(-3)**(1/2)]`); l(`n:='n';Ell(0,0,0,n^2-1,0);Eadd(1,n,0,0);===>[n^2-1,n-n^3]`); l(`For the next example recall that al3 is the 3-division poly. -- see N\ ota();`); l(`and for absc, see Menu(absc);`); l(`Ein(1);sols:=fsolve(al3);for i to 2 do P.i:=absc(sols[i]):od:===>`); l(`cur=A11 with approximate points P1, P2 of order 3, one real, the other`); l(`with a complex y-coord. Thus eadd(P1,P2) is another (approx.) pt.`); l(`of order 3. eadd(P1,[0,0]) has order 15 since [0,0] has order 5.`); elif i<13 then l(`eadp(args)=[x3,y3]`);l(`Eadp(args)=NULL`); l(` where args=z1,z2 and for i=1,2, zi=xi,yi or [xi,yi] and zi are points on`); l(`E mod p (they don't have to be rational points in E(Q)). The value of p`); l(`must be preset.`); l(`Calculate [x3,y3]=z1+z2 on E mod p with the convention that O=[NULL,N\ ULL]=[].`); l(`These procedures work for any weierstrass curve with rational coeff.'s`); l(`whose denominators are prime to p, even one input via the command Ell`); l(`(Ell doesn't put E in min. Weier. form - sometimes desirable).`); elif i<15 then l(`ein0(args)=NULL`);l(`Ein0(args)=NULL`); l(` args=a0,a1,a2,a3,a4,a6`); l(`Input the curve V^2+a1*U*V+a3*V=a0*U^3+a2*U^2+a4*U+a6, make the`); l(`transformation U=X/a0, V=Y/a0 and invoke ein. Also append this curve to`); l(`the list bec and the transformations between this curve and the min. w\ eier.`); l(`as calculated by ein to the list bic.`); l(`bec and bic are used by the commands Trcw and Trwc.`); l(` An EXAMPLE illustrating the convenience of this command based on the`); l(`internet posting of Apr. 26/00 by Andrej Dujella: He considers curves`); l(`(*) y^2=(ax+1)(bx+1)(cx+1)`); l(`where a,b,c are rational numbers such that ab+1, bc+1 and ca+1 are`); l(`squares, for example when b=-1/a and c=a-1/a. Then (*) becomes`); l(`(**) y^2=(1/a-a)x^3 + (a^2+1/a^2-3)x^2 + 2(a-1/a)x + 1.`); l(`To investigate the curves for various values of a one could define`); print(`Duj:=proc(a) Ein0(1/a-a,0,a^2+1/a^2-3,0,2*(a-1/a),1);...;end;`); l(`Dujella discovered that a=145/408 gives a curve E with torsion/Q of`); l(`order 16 and rank(E(Q))=3. This is the curve in the table displayed by`); l(`the apecs command Exam(4).`); elif i<17 then l(`ein(args)=curve is, cur`);l(`Ein(args)=NULL`); l(` where cur is the catalog name of the curve inputted by this ein`); l(` command (the name is assigned by ein if the curve is new) and`); l(` args is one of`); l(` (i) five rational weierstrass coefficients as a sequence a1,a2,a3,a4\ ,a6`); l(` or as a list [a1,a2,a3,a4,a6]`); l(` (ii) an existing catalog name, e.g. A11`); l(` (iii) an existing catalog number, e.g. 3 (which specifies C11)`); l(`This is the "Elliptic curve/Q input" command: it stores the data of the p\ resent`); l(`curve (if there is one) in the catalog and the stack, (unless switched to`); l(`"storage off" -- see below; "storage on" is the default; the command N\ ota();`); l(`lists the variables stored) and makes the curve specified by args the`); l(`present curve.In cases (ii) and (iii) apecs is now pointing to that c\ atalog`); l(`curve. In case (i) it finds the min. Weier. form/Z by the Laska-Kraus a\ lgor.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`and, if the curve isn't itself min., checks whether the min. form is in t\ he`); l(`catalog and updates bec and bic for possible later use by Trcw and Trwc.`); l(`When the curve is "new" it goes through Tate's algorithm to determine the`); l(`conductor etc., assigns a catalog name, and makes note in the catalog of`); l(`any twists.`); l(` For example if all 28 curves of conductor 448 are introduced (typically`); l(`Ein is followed by the command Isog which can introduce as many as 8 c\ urves)`); l(`they are assigned in succession the catalog names A448,..,Z448,A&448,B&\ 448..`); l(`To permute the names, for instance to make them agree with some other`); l(`list, use Inch. To stop (and restart) curves being entered into the`); l(`stack and catalog (which may be advisable when large families of`); l(`curves are generated) use the command Store().`); elif i<19 then l(`ell(args)=NULL`);l(`Ell(args)=NULL`); l(` where args can have any one of the following 7 forms`); l(` (a1--a6 stands for the sequence a1,a2,a3,a4,a6):`); l(` a1--a6 a1--a6,K_`); l(` [a1--a6] [a1--a6],K_ [a1--a6,K_]`); l(` ncur ncur,K_`); l(` cur cur,K_`); l(`This is the general input command of the Weierstrass equation `); x:='x':y:='y':print(y^2+'a1'*x*y+'a3'*y=x^3+'a2'*x^2+'a4'*x+'a6'); l(`regarded as being defined over a field K of characteristic 0, and`); l(`the optional parameter K_ is a label identifying K, as we will explain.`); l(`The ai can have any values --- they can be rational, irrational or lit\ eral,`); l(`but may be restricted when K_ is specified --- see below.`); l(`ncur is the number of a catalog curve; thus Ell and ell, like Ein and ei\ n,`); l(`have the facility of calling up curves that are already in the catalog.`); l(`However any curve introduced by Ell or ell is not put in the catalog, an\ d`); l(`the curve's name cur has the "generic" value 'cur'. When args=cur or`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`args=cur,K_, then cur can be either a catalog name, and then serves the`); l(`same purpose as ncur (e.g.,`); l(`Ell(A11) and Ell(1) are the same), or the "generic" cur='cur', and then`); l(`Ell will understand this as a handy way of specifying the current values`); l(`of a1--a6, i.e., a handy way of keeping the same a1--a6 while changin\ g K_.`); l(` The field label K_, if absent from args, is assigned the default valu\ e 0;`); l(`otherwise it can be given any numerical or literal value, including the`); l(`following which are reserved by apecs to have special meaning:`); l(` K_ = 0 : general (unspecified) field`); l(` K_ = 1 : the rational field Q --- this is reserved for use by ein`); l(` (see Menu(ein)), and ell will replace it with K_:=0;`); l(` K_ = m, a square-free integer <>1 : the quadratic field Q(sqrt(m))`); l(` K_ = T : the function field Q(T) (the variable must be T)`); l(`For example, Ell(G15,-5); points apecs to the curve E with Weier.`); l(`coeff.'s a1--a6=1,1,1,-110,-880 and also points apecs to the field`); l(`K=Q(sqrt(-5)) whose label is K_=-5. Tor(); now determines the torsion`); l(`subgroup of E(K) to be of order 4 -- O and the point of order 2 in E(Q)`); l(`already known to the catalog, plus 2 new points of order 2 defined over`); l(`Q(sqrt(-5)). E could have been introduced by Ell(17,-5), since G15 is in`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`position ncur=17 in the cat. (confirmed by ein(cur):ncur; ==> 17) or by`); l(`Ell(1,1,1,-110,-880,-5) or ...`); l(`Ell(cur,5); keeps the same a1--a6=1--(-880), but shifts apecs's attention`); l(`to K=Q(sqrt(5)).`); l(` For all curves input via Ell, the basic arith. commands`); l(`Eadd, Sub, Neg, Comb, Ford, .. and certain others On, Subg, Velu, Tw, ..`); l(`are available, but some, such as Rk, Bas, Isog, .. , are restricted to`); l(`catalog curves --- those with field label K_=1. Tor works when K_=m_ or T,`); l(`and whenever all a1--a6 are rational (any K_).`); l(` The restrictions on a1--a6 are as follows: (if a1--a6 are not in`); l(`conformity, K_ will be set to 0)`); l(`K_ not specified: no restrictions, e.g.`); print(`Ell(5/2,-(sqrt(2)+log(3))^4,0,A,B^2/C)`); l(` and K_ is given the default value 0.`); l(`K_=0: same as no K_.`); l(`K_=1: K_ will be reset to 0 (since K_=1 is reserved for exclusive use by`); l(` Ein and ein), hence no restrictions on a1--a6.`); l(`K=a squarefree integer m<> 0 or 1: ell will call qfin(m) (see Menu(qfin))`); l(` which sets m_:=m and focuses apecs attention on the quadratic field`); l(` Q(sqrt(m_)). a1--a6 must be in Q(w_,sqrt(m_)), where w_ has been`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` defined by qfin to be an alias for sqrt(m_) or (sqrt(m_)-1)/2,`); l(` depending. E.g.,`); print(`Ell(3/2,0,(2*w_+3/sqrt(5))^6,w_,sqrt(5),5)`); l(` Since Ell insists that a1--a6 be algebraic integers in the form`); l(` a+b*w_ with a,b in Z, Ell will clear denominators and annnounce`); l(` that the actual ai is the input'd ai times uV^i where, in this`); l(` example,`); print(` uV`=10); l(` The command Ell(cur,-10); will keep the same a1--a6 but will point`); l(` apecs to Q(sqrt(-10)) and w_ will be interpreted as sqrt(-10).`); l(` Go(psn) returns to the curve/Q(sqrt(5).`); l(` See the Menu entries for Qfin, Fundunit, Minf and Go.`); l(`K_=T: a1--a6 must be in the rational function field Q(T), and the`); l(` variable must be T. As in the previous case, ell will clear`); l(` denominators so that a1--a6 are in Z[T].`); l(`Other K_: no restrictions on a1--16.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` The user may wish to tag other fields with his own labels K_, but it`); l(`is only for K_=1,m_,T as above that apecs has special procedures.`); l(` In a little more detail, ell does the following:`); l(` --- check args`); l(` --- store the present curve which is about to be replaced (if there is`); l(`one) in the stack along with pertinent data, also in the catalog if K_=1`); l(`(Note: these storages can be toggled off and on; see Menu(ein);)`); l(` --- calculate b2,b4,b6,b8,c4,c6,DD,jay`); l(` --- if K_ indicates a quadratic field call qfin(K_); (see Menu(qfin);)`); l(`EXAMPLE: Looking at the output from the following sequence of commands`); l(`shows apecs engaged in a variety of activities (in particular, quar0`); l(`calls ell):`);l(); print(`Quar0(1,0,0,3,1);Ein(cur);Bas();Crem();`); elif i<21 then l(`emod(p)=card`);l(`Emod(p)=NULL`); l(` where p is a prime and card is the cardinality of the set of points of`); l(`E mod p including the singular point if p is bad. The variable spur,`); l(`which is often denoted a_p, is p+1-card; when p is good, spur is`); l(`the trace of Frobenius and is a Legendre symbol times T[jay mod p]`); l(`where T is one of the tables froB0,tFr,tFr2 or tFr3 according as p<100,`); l(`100>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`equivalently, non-singular (hence irreducible), a birational`); l(`transformation to weierstrass form E in which the chosen point is`); l(`transformed to the point O at infinity is calculated and stored in bic.`); l(`C is stored in bec (see Trcw and Trwc which use bec and bic).`); l(` In the rational case ein is invoked, so the weier. equation is`); l(`Z-minimal and E is added to the catalog, if not already there. Otherwise`); l(`Ell is called with field label K_ usually = 0, but if gcub sees that`); l(`C and the point are defined over the rational function field Q(T), or`); l(`over the quadratic field Q(sqrt(m_)) (see Menu(Qfin) for m_), then`); l(`K_ is set to T, m_ respectively.`); l(` The birational transf. is a composition of a varying`); l(`number of changes of variables. The subprocedures unk and xnk calculate`); l(`(formally) the composition of functions and inverse functions respec\ tively.`); l(` EXAMPLE: John McKay wanted a quick way to calculate the j-invariant`); l(`of various E/Q(T), the simplest example being`); print(U^3+V^3+T^2*U*V+1=0); l(`A convenient answer is given by`); print(` Gcub(1,0,0,1,0,T^2,0,0,0,1,0,-1);factor(jay);`); l(`Noticing that [+-T,-1] are points on C, one can follow this up with,`); l(`e.g., Trcw(T,-1);Trcw(-T,1);`); elif i<28 then l(`Genj(args)=NULL where args=j or j,k; j is required, k is optional`); l(` If absent from args, k is set=1;`); l(` if j=0 call Ein(A27,k) (see Menu(ell) for purpose of k);`); l(` if j=1728 call Ein(A32,k);`); l(` otherwise put a1=1, a2=a3=0, a4=-36/(j-1728), a6=-1/(j-1728) and then`); l(` if j is rational call Ein(a1,..,a6,k), otherwise Ell(a1,..,a6,k)`); elif i<29 then l(`genj(args)=curve is, cur #if j is rational`); l(` = yo #a list of the 5 Weierstrass coef.'s if j not in Q`); l(` where args=j or j,k; j is required, k is optional`); l(` If absent from args, k is set=1;`); l(` if j=0 call ein(A27,k) (see Menu(ell) for purpose of k)`); l(` if j=1728 call ein(A32,k);`); l(` otherwise put a1=1, a2=a3=0, a4=-36/(j-1728), a6=-1/(j-1728) and then`); l(` if j is rational invoke ein(a1,..,a6,k), otherwise ell(a1,..,a6,k)`); elif i<31 then l(`ht(args)=ght`);l(`Ht(args)=NULL`); l(` where args is a point on E in the form x,y or [x,y], or even just x --`); l(`after all, the canon. ht. depends only on x -- and ght is the`); l(`point's (global) canonical height as calculated by Silverman's modification`); l(`of Tate's algorithm to "Digits" digits of accuracy. The maple variable`); l(`"Digits" can be reset at any time in apecs (default=20).`); l(`Note: sw = number of switches (b<-->1-b) used in Silverman's algorithm.`); elif i<33 then l(`sub(z1,z2)=z3 Sub(z1,z2)=NULL`); l(` calculate z3=z1-z2 where zi=[xi,yi] or [xi,yi,ni] are points on E`); l(`Like Eadd and eadd, Sub and sub work for "general" points.`); elif i<35 then l(`isog()=nisog,disog`);l(`Isog()=NULL`); l(` where nisog is a list of the catalog numbers of all isogenous curves`); l(`(this command enters into the catalog any of these curves that are not`); l(`already there) and disog is a list of the corresponding degrees.`); l(`Note the convention: a degree is listed as negative when the kernel`); l(`contains irrational points; of course the kernel as a whole is rationally`); l(`defined. For visog see below.`); l(`Find all isogenous curves and set the flag qR=0. For later, higher values`); l(`of qR see Bas.`); l(`If there is any twist whose isogeny network is already worked out then`); l(`twist that network to give the network of the present curve. Otherwise`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`check for the existence of isogenies`); l(` (i) in the cases where the modular curve has genus 0 see if the Fricke`); l(`polynomial has a rational root (these polynomials are listed by the`); l(`command Nota), using common sense to cut the amount of checking; e.g.,`); l(`since there are no non-cuspidal rational points on the mod. curve of`); l(`level 35, E can't have both an isogeny of degree 5 and another of degree 7`); l(`or if E is semistable then it can't have an isog. of degree 13, by a`); l(`theorem of Serre;`); l(` (ii) in the cases of higher genus see if jay is in the list ljay of`); l(`of special values - this includes the higher CM cases, although they`); l(`will have already been spotted by the twist check - unless the examples`); l(`of curves with the conductors 11^2,..,163^2 have been forcibly removed`); l(`from the catalog (this is not recommended).`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` In any case calculate E/each finite cyclic subroup G by formulas`); l(`derived from Velu's and store the details in visog. In apecs versions<2.5`); l(`these details were restricted to isogenies with G consisting of rational`); l(`points --- then the entry in visog was a coded list of these points.`); l(`(This also involved entering info. in the catalog variable tuQ).`); l(`Otherwise the visog entry was left blank (except for certain cases |G|=\ 3..)`); l(`Now the entry has the form [k,x,y] (and tuQ is no longer used) where`); l(`k is a poly. in X of degree trunc(|G|/2) and whose roots are the `); l(`unduplicated X-coordinates of the non-zero points in G; x and y are`); l(`rational functions in X and Y --- the coordinate transformations from E`); l(`to E/G. (Old style entries of visog are upgraded as the occasion arises.)`); l(`visog is used by Tri (see Menu(tri)) and Velu (also internally by apecs`); l(`e.g. when the visog entry is in place by apq to improve the list of`); l(`independent points of infinite order on E/G when such are found on E.)`); elif i<36 then l(`If xxx represents an apecs command then the command Menu(xxx) first prints`); l(`the value of xxx. For example, Menu(isog) first says that`); l(`isog()=nisog,disog which means that a command of the form var:=isog();`); l(`will assign the value nisog,disog to the variable var (the name var is not`); l(`used by apecs and so is available; nisog and disog are apecs variables`); l(`whose meaning is explained by the apecs command Nota();). Menu(xxx) then`); l(`describes the parameters, if any, required by xxx, then further details.`); elif i<40 then l(`mulp(args)=Nz`);l(`Mulp(args)=NULL`); l(`mult(args)=Nz`);l(`Mult(args)=NULL`); l(` where args=N,z where N is in Z and z is a point on E, or on E mod p`); l(`in the cases Mulp,mulp (the value of p must be preset to a prime), and`); l(`Nz=[xm,ym] is N*z on E in the cases Mult,mult and on E mod p in the cases`); l(`Mulp,mulp. Notice that mulp and mult (but not Mulp, Mult) can be`); l(`concatenated with other commands e.g., Trwc(mult(-3,xx)).`); l(`These commands work "in general" e.g. with a curve introduced by ell,`); l(`except Mulp and mulp require the Weier. coeff.'s at least to be rational`); l(`with denominators prime to p.`); l(`Like Eadd and eadd, Mult and mult accept points with irrational coord.'s`); l(`also floating point coord.'s for approximate calc.'s`); elif i<42 then l(`om()=Omega`);l(`Om()=NULL`); l(` The present curve must have all Weierstrass coeff.'s a1,..,a6 real`); l(`(rational or float), and so isn't necess. a catalog curve intro. by ein.`); l(`and with discriminant DD<>0. The following are calculated:`); l(`The lattice periods omega[1],omega[2] (omega is a table) where omega[1]`); l(`is real and positive, and omega[2] is such that omega[2]/omega[1] has`); l(`positive imaginary part and real part=0 (when DD>0) or -1/2 (when DD<0).`); l(`In the former case Omega (the factor in the Birch, Swinnerton-Dyer conj.)`); l(`= 2*omega[1], and in the latter case Omega=omega[1]. Set`); l(`omegA:=[[Omega,omega,Digits],..] where ,.. represents the sequence`); l(`(usually empty) of p-adic periods calc. by omp, each a list of length>3.`); l(`Thus nops(omegA)>0 and nops(omegA[1])=3 signal that om has been called`); l(`previously.`); l(` If Digits is set to a higher value than that stored in omegA, and`); l(`om is called again then the data will be recalculated to the higher`); l(`accuracy. For omegA[2],.. see Menu(omp).`); elif i<44 then l(`omp(args)=NULL`);l(`Omp(args)=NULL`); l(` where args is either n or p,n; the absence of p in the first case`); l(`means do omp(p,n) for all relevant p, namely those primes that occur in`); l(`the denominator of jay: calculate the "p-adic periods" (a misnomer) and`); l(`store succesively in positions 2,3,.. in the list omegA. (For omegA[1]`); l(`see Menu(om).) For such p the curve E is isomorphic over the p-adic field`); l(`Q_p(sqrt(-c6)) to Tate's curve Gm/q^Z and denoting by u the ratio of their`); l(`canonical differentials, as explained by Henniart and Mestre in their 1989`); l(`C.R.Acad.Sci. Paris paper, q and u^2 are in Q_p^*. These procedures calc\ ulate`); l(`q and u^2 to n p-adic digits and store the results in the first available`); l(`omegA[i] in the format p,n,[c,d0,d1,..,dn],[e,f0,f1,..,fn] where`); l(`q=p^c*(d0+d1*p+..+dn*p^n), u^2=p^e*(f0+..).`); l(`#### haven't yet got around to programming p=2 and additive type I* ####`); elif i<48 then l(`quar(args)=(one of) -2,-1,0,P__,[],[0],[S6,S7],or FAIL -- see table below`); l(`Quar(args)=NULL`); l(`quar0(args)= same as quar`);l(`Quar0(args)=NULL`); l(` where args is a sequence S1,S2,.. of 5, 6 or 7 arguments.`); l(`S1,..,S5 are the coefficients in V^2=S1*U^4+S2*U^3+S3*U^2+S4*U+S5;`); l(`if both S6,S7 are present, they are the coordinates of a point [U,V]`); l(`on the curve.`); l(`If S6 is present, but not S7, where S6 can have any value (e.g. 5 or X)`); l(`then the point at infinity is taken as the "rational" point on the`); l(`quartic, i.e., the point [0,sqrt(S1)] on (V/U^2)^2=S5*(1/U)^4+..+S1.`); l(`Quar0 is same as Quar except it treats rational Si as irrat. -- see below.`); l(` If S6 is not present the procedure attempts to supply a point,`); l(`as follows.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` If S1..S5 are rational, it first checks whether S5 is a square;`); l(`if so, it takes the point [0,sqrt(S5)]. Failing that, it asks: are the`); l(`places at infinity rational, i.e. is S1 a square. If so it proceeds`); l(`appropriately. Next, if the quartic has a rational root r then it takes`); l(`[S6,S7]=[r,0]. Otherwise, at this point if one of S1,..,S5 has denom.>1,`); l(`then the denom.'s of S1,..,S5 are cleared by a suitable substitution`); l(`V/uV for V and quar is re-called with new, integral S1,..,S5. It then`); l(`tests the quartic for local solvability. If it is not solvable over some`); l(`rational P__-adic field, then P__ is returned by quar; or if not solv.`); l(`over the reals then P__=infinity is returned. If the quartic survives,`); l(`quar searches for [U,V] with numer(U)+denom(U)<=lquar+1 where lquar=100`); l(`and can be reset at any time; e.g., lquar:=200; prior to calling quar.`); l(`Also, clock can be used.`); l(` If some S1..S5 is irrat. and no point [S6,S7] is supplied by the \ user,`); l(`then quar supplies [S6,S7]=[0,sqrt(S5)]. Quar0 acts the same way even`); l(`when all S1..S5 are rational.`); l(` In any case the procedure checks that the curve is irreducible of`); l(`genus 1 and then finds a birationally equiv. Weierstrass equation in`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`the variables X,Y. If the Si are rational it then finds the min. Weier.`); l(`equation. (To inhibit the transformation to minimal Weier. when the Si`); l(`are rational, use Quar0 instead of Quar.) As in the case of Gcub, the`); l(`original U-V curve is stored in bec and the transformations between it`); l(`and the X-Y Weier. curve are stored in bic --- see Menu(Gcub) for more`); l(`details. Also see Menu(Trcw) for transfering points between these curves.`); l(`The value of quar has the following meaning:`); l(` -2 wrong args`); l(` -1 [S6,S7] not on curve`); l(` 0 discriminant of quartic DD_=0`); l(` P__ quartic not locally sol. at P__ = infinity or a rational prime`); l(` [] point at infinity taken as O --- called quar(S5,..,S1,0,sqrt(S1))`): l(` [0] S1=0 so called ein0 or ell`); l(`[S6,S7] =point taken as O`); l(` FAIL couldn't find rational point, or timed out by clock`); l(` --- increase lquar and/or don't use clock`); l(); l(`Thus if quar (or quar0) returns a list then the quartic is "elliptic",`); l(`but if it returns FAIL then the nature of the quartic is undetermined.`); elif i<50 then l(`rk(args)=NULL N.B. when the conductor Nc is large it may be`); l(`Rk(args)=NULL advisable to use Rk0, Rk1 or RkNC instead (qv.).`); l(` args is optional; if present, rk sets dil:=args, otherwise dil:=30`); l(`Usually args is absent --- one usually calls Rk(); see below.`); l(` Calculate r4=the rank, rc=the "quality index" of r4, and r1=`); l(`a conjecture-free upper bound for the rank.`); l(` N.B. the value of r4 is reliable only when rc>=0; otherwise rc=-1`); l(`and r4 is either -1 (its default) or an upper bound for the rank which`); l(`is conjectural unless r4=r1`); l(` Note that MM=card(RR) is always a lower bound for the rank: RR is a`); l(`list of points that are lin. indep. mod torsion. (Possib. better lower`); l(`bound: MN=max{card(RR of E') : E' isog. to E}.) RR can be augmented`); l(`independently of Rk by the command Seek which looks for points, or`); l(`by Tri which transfers points between isogenous curves, or by`); l(`App which appends points known from some other source.`); l(` Whenever apecs finds a new point P, whether in Rk, Seek,...,`); l(`either P is added to RR (when independent of the points already in RR),`); l(`or P replaces some point (if that gives a smaller grammian -- height`); l(`pairing -- determinant) or P is added to the list uR of redundant points.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` r4 (when>=0) in general has been determined with the aid of conjectures`); l(`depending on the value of rc, as we explain in a moment. On the other`); l(`hand, r1 is a firm upper bound for the rank, independent of any conj.`); l(`unless it has its default value of -1`); l(` The value of rc indicates the "quality" of r4:`); l(`T stands for the Taniyama conj.; T-p means T and parity of r4`); l(`as determined by a root number calc. by the procedure roha() or (inadvisabl\ y)`); l(`analytically from the sign of the functional equation by the proc. sfe().`); l(`B-SD stands for the Birch, Swinnerton-Dyer conjecture and R.H.for the`); l(`Riemann Hypothesis: all zeros s+it of L(s) with 1<=s<=2 have s=1.`); l(` In the following table the values of rc with an asterisk are`); l(`obsolescent: they persist in earlier entries in the catalog, but since`); l(`version 5.5, the trio rc,r4,r1 is treated equitably among all members of`); l(`the isogeny class --- rk calls isog and then (and later when there is`); l(`any change in the trio) for all the curves updates the cat. entries to`); l(`their best currently available values. Thus once rk is called (either`); l(`directly or indirectly by one of bas,rk0,rk1,rkNC,Rk,Bas..) rc will not`); l(`be any one of 0,1,4,6, and will be the same for all curves isogenous to`); l(`the present curve --- referred to as "new rc" in the table.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` |new|`); l(` rc |rc | provenance of r4`); l(` -1 |-1 | no firm value yet for the rank; if r4>0 it is an upper bound`); l(` | | for the rank which is conjectural unless r4=r1`); l(` *0 | 2 | from r4 of isogenous curve which used (at least some of)`); l(` | | T, B-SD, R.H.`); l(` *1 | 3 | from r4 of isogenous curve which used only T-p`); l(` 2 | 2 | used (at least some of) T, B-SD, R.H.`); l(` 3 | 3 | used only T-p`); l(` *4 | 5 | from r4 of isogenous curve using no conjectures`); l(` 5 | 5 | used no conjectures`); l(` *6 | 7 | from an isogenous curve for which MM (the cardinality of the`); l(` | | list RR of independent points) = r1.`); l(` | | Thus r4 is the conjecture-free value of the rank.`); l(` 7 | 7 | as in *6: MM=r1 either for the present curve or an isog. one`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` Rk tries to get r4 using as few conjectures as possible.`); l(`The procedure terminates as soon as rc>=0 (or rc>=a higher value if rk`); l(`has been called by Rk1, Rk0 or RkNC --- see Menu(Rk1) etc.); thus not`); l(`all the following steps are necessarily carried out. When called by`); l(`Rk1, Rk0 or RkNC, the proc. may terminate to report failure: rc=-1.`); l(`In principal Rk itself will aways succeed, but in practice it may bog`); l(`down in the final L-series step.`); l(` Let E denote the present curve and let C denote the set of all E'`); l(`(rationally) isogenous to E, including E'=E.`); l(` Step 1. Find the best (smallest) value for r1 among Mazur's upper`); l(`bounds (description below) for all E' in C to which Mazur applies.`); l(`E.g: Rk applied to the example Exam(3,124,67) (see Menu(Exam)) gets`); l(`r1=0 and so rk exits with r4=0 and rc=7. Of course usually C consists of`); l(`E alone, so no Mazur, and this step leaves r1=-1.`); l(` Step 2. This step is also applied to all E' in C. If NN=card(torsion)`); l(`is odd then seek(dil) is applied, i.e., search for points on E' up to`); l(`naive height dil; usually rk is called without args, so dil has its`); l(`default value 30, and the search is modest --- so as not to miss any`); l(`obvious points.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` In NN is even, then 2-descent, including 2-nd descent when necess.`); l(`(see Elliptic curve Handbook, 3.6.6, available by anon. ftp from same`); l(`site as apecs) is performed on each E'. Of course if a particular`); l(`2-descent E'--->E'' is performed then E''--->E' is skipped over.`); l(`E.g. Rusin's examples Ein(0,0,0,-34225,0) and Ein(0,0,0,-(29*61)^2,0)`); l(`find r4=0, and nicely show the importance of not just looking at a`); l(`single E--->E'. Sometimes even looking at all 2-descents out of E is`); l(`not enough, and other E'--->E'' are considered. However, if at the end`); l(`of all this rk has not reached a conclusion, then the uncertain quartics`); l(`(homogeneous spaces or torsors) are searched for points "up to dil". `); l(`These quartics are stored (with other info) in the list dolt.`); l(`The latest (completed) search limit dil is stored as dill.`); l(` Step 2 bis. The following example illustates repeated calls to`); l(`rk in the case when NN is even and rk leaves dolt unempty; it is`); l(`necessary to use RkNC in the subsequent calls since a second call to`); l(`rk itself would merely produce "already found r4=1 with rc=3".`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` Exam(6,78);Rk(); ===> r4=1, rc=3 (hence RR=[], MM=0)`); l(` RkNC(50); ===> nada, i.e. continuing the search up to dil=50`); l(` on the quartics in dolt finds no points`); l(` RkNc(100); ===> finds a point on one of the quartics, hence`); l(` MM=1 (check out RR), r4=1 with rc=7.`); l(` Step 3. (permitted by Rk, Rk0, and Rk1, but not by RkNC):`); l(`roha() is invoked to find the root number SFE (which stands`); l(`for Sign of the Functional Equation) hence the parity of the rank`); l(`conjecturally -- (-1)^r4=SFE -- to be used if needed.`); l(` Step 4. (permitted by Rk and Rk1 but not by Rk0 and RkNC):`); l(`Mestre's upper bound for the rank is calculated by mest(args), followed by`); l(`seek(args); these proc.'s are repeated up to 4 times with successively`); l(`higher args. Mestre uses the analog of Weil's exact formula which`); l(`necessitates assuming T, B-SD and R.H.`); l(`After an inconclusive run of Rk1, one can call (repeatedly)`); l(`Mest(args) with args > the current value of mstR.`); l(` Step 5. (not permitted by Rk0, Rk1 or RkNC): As a "last resort"`); l(`rank is determined as the smallest r such that L^{r}(1)<>0.`); l(`(See Menu(FnL)). For "large" E this step can take forever.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`A few more details :---`);l(); l(` Mazur's upper bound:`); l(` Simplifying slightly results of [B. Mazur, Rational points of`); l(`abelian varieties with values in towers of number fields, Invent.`); l(`Math. 18(1972), 183--266], if p is a prime where E is good or`); l(`mult. and E(Q) is divisible by Z/pZ, i.e. E(Q) contains a point of order p`); l(`with integral Weierstrass coord.'s (which is automatic when p>2)`); l(`or divisible by mu_2, i.e. there is a point of order 2 with coordinates`); l(`of the form [a/4,b/8], a and b odd integers)`); l(`then a value for r1 is a+m-1 which can be improved to a+m-1-u-e`); l(`when E(Q) is div. by Z/pZ, where:`); l(`a=the number of additive primes;`); l(`m=the total number of bad primes (not just the number of mult. ones);`); l(`u is the number of primes s such that`); l(` (i) E has mult. red. at s;`); l(` (ii) p does not divide the exponent of s in DD; and`); l(` (iii) s is not 1 mod p;`); l(`e=0 except when p=2 and there is a prime s satisfying (i), (ii) and`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` (iii') s is not 1 mod 4`); l(`and then e=1.`); l(`If there is more than one such p, the min. upper bound is taken for r1.`); l();l(`2-descent:`); l(` If E has a point of order 2 the usual simple 2-descent is used. The`); l(`homogeneous spaces are sieved by Hensel (preceeded by a quad. norm res. t\ est).`); l(`For the homog. spaces A*U^4+B*U^2*V^2+C*V^4=W^2 that remain, 2nd \ 2-descent`); l(`is performed. The descendant quartics are Hensel sieved, and those that`); l(`survive are stored along with the original homog. spaces in dolt.`); l(`Then all the quartics in dolt are searched for rational points up to`); l(`naive height dil. The default value of dil is 30; it can be given a`); l(`different value by using args: Rk(args) (or rk(args)) sets dil=args;`); l(`dil will revert to its value 30 next time rk is called --- unless args`); l(`again specifies another value. If rk has already found a value for r4`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`with rc>=0, use RkNC(args) instead of Rk(args) to extend the search`); l(`on dolt.`); l(` Any points found on a quartic are transformed into points on E and`); l(`stored (if not "redundant") in the list RR. Any time a decision about`); l(`the rank can be made, the search is called off.`); l(` If rk deems it appropriate,`); l(`a direct search for points on E up to naive height dil is made.`); l(` Depending on circumstances, not all the isogenous E' have their RR`); l(`necessarily updated following improvements in the RR of E: the primary`); l(`mandate of rk is to determine r4. In such cases one can use Tri, qv.`); elif i<52 then l(`rk0(args)="rank = r4" or "rank not determined"`); l(`Rk0(args)=NULL`); l(` invoke rk(args) with rflag=2 which means disallow use of the procedures`); l(`mest(); and fnL(); I.e., no conjectures are used except possib.`); l(`parity of rank = that determined by roha(); To disallow even that,`); l(`use RkNC(); (q.v.)`); elif i<54 then l(`seek(args)=NULL`); l(`Seek(args)=NULL See also Seek1 and Search.`); l(` These proc.'s look for points on E defined over Q or over Q(T):`); l(`--When E is defined over Q(T) (with K_=T) then args is not used (take`); l(`args=NULL) and seek is a one-shot deal: a modest search is made, and a`); l(`second call to seek will give "already done".`); l(`--When E is defined over Q, either by Ein (so K_=1) or Ell (so K_<>1),`); l(`then args is either l (a positive integer) or l,seekn (both positive`); l(`integers).`); l(` Assuming for the moment that seekn is absent, E is searched for`); l(`rational points [x,y] where the naive height max{|numer(x)|,denom(x)}`); l(`ranges between sB+f and l+f, then set sB:=l, where f is 0 or an adjust-`); l(`ment because of the location of the real point(s) [x_i,y_i] of order 2.`); l(`Thus when seek is called again it remembers where it left off.`); l(` When seekn is given a positive integer value by a 2nd args, seek`); l(`proceeds as usual but is terminated as soon as RR (="best so far known"`); l(`list of points that are independent mod torsion) contains seekn points,`); l(`and sB is given the value approriate to the cut off point. For example,`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`when rk gives positive values for r4 and rc (this would be for an E with`); l(`K_=1; see Menu(rk)), the call Seek(10^6,r4) might find r4 independent`); l(`points quickly, and not "waste time" searching further. An example is`); l(`given in Menu(Heeg).`); l(`IN MORE DETAIL:`); l(` --- calc. the sequence PP of torsion points, if not already done;`); l(` --- when e:=max{x_i}>0, also look for integral points with e>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` *** To do a straight search with no "f" adjustment and no "ap1_"`); l(` processing see the procedure Search. To search for integral points`); l(` only use Seek1.`); l(`The case E/Q with K_<>1 (usually K_=0, the default value given by Ell)`); l(` can be useful, e.g. when a1,a2,a3 are large and a4=a6=0. The points`); l(` found are stored in the list searchl, besides the usual "RR and uR`); l(` work". Note that RR is not lost when E is converted to another K_,`); l(` as the following example illustrates.`); l(` Ell(0,0,7,0,0);`); l(`The curve is y^2+7y=x^3 with K_=0; in this discussion let's call it C.`); l(` Seek(10);`); l(`first calculates PP=[0,0,3],[0,-7,3], so the order of the tor. subgroup`); l(`is NN=3. Then it discovers [0,0],[2,1],[-7/4,-7/8], notes the first is a`); l(`torsion pt., sets RR=[[2,1]], and finds that the third is redundant,`); l(`i.e. of the form n*[2,1]+T, T a tor. pt. To determine n and T we cannot`); l(`call Expr directly (because the canonical height function ht works only`); l(`for Z-minimal E..). Instead we invoke`); l(` Ein(cur);`); l(`This calls Ein(0,0,7,0,0) which produces the Z-minimal curve`); l(`y^2+y=x^3+12 --- let us call it W. W is now the "present curve" and both`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`PP and RR have been transformed from C to W: now PP=[0,3,3],[0,-4,3],`); l(`and RR=[[2,4]]. (If desired, Go(psn) would return to C and of course`); l(`PP,RR (and uR..) would be restored to the correct values.) Let us define`); l(` P1:=trcw(-7/4,-7/8);`); l(`This sets P1=[-7/4,17/8], the transf. of [-7/4,-7/8] in the birational`); l(`map C-->W. (Note that trcw and trwc are available only when present`); l(`curve is W. See Menu(trwc) for more detail.) Now`); l(` Expr(P1);===>`); l(` [-7/4,17/8]=-[2,4]+[0,-4] ([0,-4] is a torsion point)`); l(`Since the birat. maps C-->W and W-->C map O to O, they are elliptic`); l(`curve morphisms and so preserve + and -. Thus, since trwc(0,-4)=`); l(`[0,-7], etc., we deduce that on C`); l(` [-7/4,-7/8]=-[2,1]+[0,-7]`); l(`which of course can be verified, e.g. by`); l(` Go(psn); Eadd([-7/4,-7/8],[2,1]);`); l(` Final note: If all that is wanted is a set of independent points,`); l(`say to confirm a value of the rank, or to obtain a lower bound, then`); l(`provided there are sufficiently many integral points Seek1 can be much`); l(`quicker. A good example of this is Ein(623); Seek1(50000) quickly finds`); l(`10 independent points, while Seek(50000) grinds on for a long time.`); elif i<56 then l(`sfe()=SFE`);l(`Sfe()=NULL`); l(`Optional argument: hyy --- use at most hyy terms in the series.`); l(` Calculate the sign SFE of the functional equation of the cusp form f(t)=`); l(`sum(an*exp(2*pi*i*n*t)), assuming the Taniyama conjecture, as the sign`); l(`of f(2*i/r)/f(i/(2*r)) where r=sqrt(Nc)=the square root of the conductor`); l(`the series being calculated to about 4 digits of accuracy (usually to`); l(`about 1*r or 2*r terms). Also compare with the parity of the rank if that`); l(`has already been determined by other means (now assuming also the Birch,`); l(`Swinnerton-Dyer conjecture), and transfer the value of SFE to all`); l(`isogenous curves`); l(` Clock can be used.`); l(`NOTE: the procedures Roha, roha are much quicker and not dependent on`); l(`approx. sums of infinite series.`); elif i<58 then l(`sha(args)=NULL`);l(`Sha(args)=NULL --- usually args is absent`); l(` Calculate the order shaf of the Shafarevich-Tate group, assuming the`); l(`Birch, Swinnerton-Dyer conjecture. If args is absent, Bas must be done`); l(`beforehand so that RR is a Mordell-Weil basis, well at least a "probable`); l(`basis", i.e., qR>=3; see Menu(bas) for details about qR. If possible, the`); l(`value of shaf will be inferred from that of an isogenous curve, otherwise`); l(`r4-th derivative of the L-function is calc. to appropriate accuracy.`); l(` However if args<>NULL`); l(`then, provided that the sign of the functional equation SFE is known i.e.`); l(`SFE has one of the values 1,-1, and not its default value 0, and this \ value`); l(`is in agreement with the parity of the number of points`); l(`in RR, then it is assumed that RR is a basis and shaf is calculated.`); l(` Clock can be used.`); elif i<62 then l(`trcw(args)=p, p_at_inf_w[n] or NULL trwc(args)=p or NULL`); l(`Trcw(args)=NULL Trwc(args)=NULL`); l(`Let C be curve #n listed in bec (see below for details).`); l(` Trwc(z,n) transfers point z on E to point p on C (w is for Weierstrass)`); l(` Trcw(z,n) transfers point z on C to point p on E`); l(` Trwc(n) and Trcw(n) both display C and the transformations between C a\ nd E`); l(`In any of the above n may be absent -- then it is given the value 1.`); l(`z has one of the forms`); l(` [x,y] or just x,y (an affine point);`); l(` [x,y,0] (a point at infinity in homogeneous coord.s);`); l(` [] which stands for the set of point(s) at infinity ---`); l(`apecs understands: E has a unique point at infinity, often denoted O;`); l(`a cubic introduced by Gcub has 3 (perhaps with repetition); a quartic`); l(`introduced by Quar has two places at infinity, both centered at the`); l(`same point. We will explain trcw([]) and trwc([]) in a moment.`); l(` x and y are not required to be rational; they will typically be`); l(`irrational in the case of a curve with irrat. coeff.'s introduced by`); l(`Quar or Gcub.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` bec is a list of polynomials in the variables U,V; the equation`); l(`bec[n]=0 describes a curve C birationally equiv. to E, whose Weier.`); l(`equation has X,Y as variables. bic[n] is a list whose entries are`); l(`8 polynomials that describe the birat. transform.'s, and the point`); l(`on C that corresponds to O on E; the first 4 are poly.'s in X,Y`); l(`and the second 4 in U,V.`); l(`The birat. transf's are: U=B1/B2, V=B3/B4, X=B5/B6, Y=B7/B8 where Bi`); l(`denotes (in this discussion only) bic[n][i].`); l(` Entries in bec, bic are generated by the commands Quar, Gcub, Genj,`); l(`Ein0 and also may be generated "internally", e.g. a call to Rk may`); l(`result in one or more entries.`); l(` Any new (nonredundant) points of infinite order that show up on E`); l(`are saved in RR. Note that bec and bic are available only during the`); l(`present apecs session - they are saved only in the stack, not the cat.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` When trcw([]) or trwc([]) is called, apecs creates two lists, which`); l(`for convenience we call A and B. A is the list of points at infinity`); l(`on C (in the case of the quartic, A=[[0,1,0],[0,1,0]], representing`); l(`the two places at inf.), and B is the list of the images of the points`); l(`in A under the birat. trans. A and B become the n-th entries in (the`); l(`list of lists) p_at_inf_c and p_at_inf_w respectively. Trcw([],n)`); l(`displays all of A, while if [x,y,0]=A[i] then Trcw(x,y,0,n) displays`); l(`B[i]; Trwc([],n) displays bic[n][9].`); l(`Example: Trwc(mult(-2,RR[3])); will find the image p in C #1 of`); l(`-2 times point no. 3 of E's list RR.`); elif i<64 then l(`tw(a)=[a1,..,a6], or the statement curve is cur`);l(`Tw(a)=NULL`); l(` where cur is the new curve obtained by twisting the present curve by a:`); l(` cur becomes the present curve, and its Weier. coeff.'s are a1,.. .`); l(` ** If tw or Tw is called when the present curve is a catalog curve`); l(` (so that cur = the curve's cat. name, such as A11, and the base field`); l(` is Q, so the code K_=1 -- see Menu(Ell)), then tw calls`); l(` ein(0,0,0,-27*c4*a^2,-54*c6*a^3);`); l(` Note that since the twist becomes the present curve, for example the`); l(` sequence Tw(-3/7);Tw(-14); ends up with the same present curve as Tw(6)\ ;`); l(` In this case tw evaluates to "curve is",cur.`); l(` ** If tw or Tw is called when the present curve is not a cat. curve`); l(` (so that cur='cur' -- cur is unevaluated, equivalently, K_<>1), or`); l(` if a is not rational, then tw calls`); l(` ell(a1,sex_(a*a2+(a-1)*a1^2/4),a3,sex_(a^2*a4+(a^2-1)*a1*a3/2),`); l(` sex_(a^3*a6+(a^3-1)*a3^2/4),K_)`); l(` where sex_ is defined in apecs by`); l(` sex_:=proc(z) simplify(expand(z)):end:`); l(` Re the above args. in ell, see Elliptic Curve Handbook, p.410.`); l(` tw evaluates to [a1,..], a list of the new present curve's coeff.'s.`); elif i<66 then l(`fnL(args)=L^{r}(1)`);l(`FnL(args)=NULL`); l(` where args=r`); l(` or args=r,de`); l(` or args=r,de,hyy`); l(`Estimate the r-th derivative of the L function at s=1.`); l(` For technical reasons the parity of r must be the same as that of`); l(`SFE (the sign of the functional equation); if SFE is not known FnL will`); l(`call Roha first.`); l(` The optional parameter de must be a pos. integer: it specifies that`); l(`L^{r}(1) is to be calc. to within +-10^(-de). Default de=4.`); l(` The optional parameter hyy must also be a pos. integer, and the param\ . de`); l(`must be present: it specifies that L^{r} is to be calc. using at most hyy`); l(`terms in the series. Of course the accuracy indicated by de is only assure\ d`); l(`when the calc. is terminated with fewer than hyy terms. The purpose of hyy`); l(`is to limit the length of the calc. in difficult cases; FnL can be called`); l(`again with a larger hyy.`); elif i<68 then l(`mest(args)=Mestre's upper bound for the rank`); l(`Mest(args)=NULL`); l(` This uses the analog of Weil's exact formula for L(s) and so depends on`); l(`assuming T, B-SD and R.H. Used by rk if it can't determine the rank`); l(`without these conjectures. Series is summed for prime powers10^6).`); l(`Otherwise Rk1 is the same procedure as Rk.`); elif i<78 then l(`neg(z)=nz Neg(z)=NULL`); l(` calculate -z where z=[x,y] or [x,y,n] is a point on E`); l(`Like Eadd and eadd, Neg and neg accept a "general" point.`); elif i<82 then l(`bas(args)=qR Bas(args)=NULL --- args is optional`); l(` note: the old names ind,Ind are no longer used.`); l(`If nargs=0 then BASL:=2000;else BASL:=args; BASL limits the range of the`); l(`search procedure ouu which is called by bas, to avoid excessively long`); l(`searches. Clock can also be used.`); l(`Bas attempts to find Mordell-Weil basis of E(Q) (mod torsion), as itemized`); l(`below. When successful (qR=5) or possibly successful (qR=3 or 4), bas`); l(`invokes shaf_tr which inspects all available values of shaf (=order of `); l(`Shaf.-Tate group) of isogenous curves. When at least one such shaf is`); l(`available, this gives a value of shaf of the present curve. When the`); l(`latter is not (approx.) the square of an integer the putative basis is`); l(`not in fact a basis, and qR is set = 5/2 or 9/4: see the table of qR`); l(`below. In any case RETURN(qR). `); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` 1. Determine the rank r4, if not already done. Bas may choose to call`); l(`respectively, rkNC, rk, rk1 or rk2 (resp., to improve rc, if Nc<10^6,`); l(`if Nc<10^20, if Nc>10^20). RETURN(qR) if unsuccessful. For rc see Menu(rk)\ .`); l(` 2. If r4=0 then set qR:=5 and wrap up with a call to shaf_tr as `); l(`described above, and RETURN(qR);`); l(` 3. Search for independent points. These are stored in the list RR`); l(`in order of increasing canonical height: ht(RR[1])=1. If RRsm=0 then RETURN(qR).`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` 5. Calc. the height pairing matrix B of RR[1],..,RR[r4]. If during this`); l(`calc. an example of ht(RR[i]+RR[j])RRsm the lower bound ht(RR[RRsm]) for the i-th succ.`); l(`min., and standard constants from the theory of pos. def. quad. forms`); l(`--- for this I can only refer to sec. 3.5.2 of ECH.`); l(` 8. If ub_index=1 bas wraps up with qR:=5;shaf_tr();RETURN(qR);`); l(`Otherwise apply Siksek's sieve (sec. 3.6 ECH). If that eliminates all`); l(`prime divisors of ub_index then bas wraps up as above.`); l(` 9. If the sieve is inconclusive then apply half() to linear comb.'s`); l(`of members of RR. If this discovers an improvement to RR then the`); l(`process is begun anew at step 5.`); l(` 10. If BASL allows further searching, bas tries to improve RR and`); l(`RRsm. If successful then back to step 5. Otherwise RETURN(qR);`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`The (higher) values of qR denote the outcome of bas:`); l(` -1 | isogenous curves not determined therefore rk and bas not done`); l(` 0 | isogenous curves are known from a twist of E (data for E but`); l(` | not for isog. E'=E/~ stored in nisog, etc.)`); l(` 1 | isog done but bas not yet called`); l(` 2 | bas done (hence rk hence isog done) but short of indep. points`); l(` 9/4 | with existing RR, sha has calc. shaf=1/n^2 ==> RR union PP`); l(` | generates subgroup of index n or 2n,..`); l(` 5/2 | bas done and have right number of ind. points - but not a basis`); l(` | because yR is not empty (yR = list of points rationally but not`); l(` | integrally dependent on RR)`); l(` 3 | RR is possib. a basis and reg is possib. the regulator`); l(` 4 | RR consists of successive minima--prob. a basis (rank>4 ---`); l(` | when rank<5, qR can be bumped to 5 by a thm. of Minkowski)`); l(` 5 | RR "certified" as a basis. But note that if rc<4 this certification`); l(` | depends on one or more of the standard conj.'s --- used to obtain \ an`); l(` | upper bound for the rank r4 (see Menu(rk) for details about rc).`); l(` | In feasible cases rc can be increased by the command Crem.`); elif i<86 then l(`lin(args)=adet Lin(args)=NULL`); l(` note: the old names gram, Gram are no longer used.`); l(`args is a sequence or list of points P1,.. on the present curve E.`); l(`E must be defined over a field K for which tor is programmed:`); l(`K=Q, Q(T) or Q(sqrt(m_)), i.e., the field label K_ (which is an actual`); l(`apecs variable --- see Menu(Ell)) has the value K_=1 (or K_=0 and`); l(`a1,..,a6 are in Q), K_=T or K_=m_. The Pi are required to be defined`); l(`over K.`); l(`The RETURN value of lin is adet; this is a global variable, available`); l(`after either Lin or lin:`); l(`--- adet=-1 means the proc was aborted either because E is not of the`); l(`right type or something is wrong with args.`); l(`--- adet=0 means the points are dependent mod torsion: there exists a`); l(`linear relation c1*P1+c2*P2+..+ci*Pi=TP, a torsion point, where the ci`); l(`are integers, not all 0. (When K_=1, c1,c2,.. are available as the apecs`); l(`global variables num1,num2,.. and TP as TP, which may = O; but these`); l(`data are not available when K_<>1. In any case the capitalized command`); l(`Lin displays the relation).`); l(`--- adet=a positive number means that the Pi are independent mod torsion.`); l(`In the case K_=1, adet=the canonical height-pairing grammian determinant`); l(`||.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`When K_<>1 and lin detects independence mod torsion, adet is given the`); l(`symbolic value 1. `); l(`Lin will not fail when K_=1 or when K_<>1 and the Pi are in fact indep.`); l(`mod torsion. However lin may be uncertain of dependence in some examples `); l(`when K_<>1:`); l(`--- adet=infinity means that the result is inconclusive --- the Pi `); l(`may or may not be dependent mod torsion.`); l(` Specifically, when the Pi are dep. then there exists a relation`); l(`sum_{j in b}P_j=T+2*Q where b is nonempty, T is a torsion point and`); l(`Q is a lin comb. of (all) the P_i; lin only tests those comb's`); l(`whose coeff.'s are from {-1,0,1}. Canon. height is not programmed for`); l(`Q(T) and Q(sqrt(m_))!`); l(` For all E over any K a list RR of points that one hopes are indep.`); l(`mod torsion is maintained by apecs. When K_=1 the independence is`); l(`guaranteed. In the cases K_=T, K_=m_ and K_=0 with the ai in Q, RR is`); l(`at least lin-tested with adet>0, possibly infinity. In all other cases`); l(`a modest attempt is made to prevent dependence: a new candidate point`); l(`is checked not to be a member of the auxilliary list uR which consists`); l(`of lin. comb.'s, "within reason", of Pi already in RR.`); elif i<88 then l(`abel(args)=nabel`);l(`Abel(args)=NULL`); l(` args is one of: NULL, a rational number, a sequence of five rational`); l(`Weierstrass coeff's a1,..,a6 or a list [a1,..,a6] of such.`); l(`Correspondingly j is set = the j-invariant of the present curve,`); l(`(denoted jay in apecs), args, or the j-invariant of the curve with`); l(`the given Weier. coeff's.`); l(`This procedure tells you whether there exists or not (nabel=[] or [[p,\ n]..])`); l(`an abelian extension of Q over which E acquires everywhere good or`); l(`multiplicative reduction; this only depends on j -- the answer is the`); l(`same for twists. It is also for the same for isogenous curves,`); l(`even tho' they have different j (unless there's CM).`); l(`The response is yes (resp. no) iff`); l(`the answer is yes for all local fields Q_p (resp. no for some`); l(`local field), and we say correspondingly that j is abelian or non-abel.`); l(`(at p) -- the analog of the Hasse principle applies here.`); l(`When non-abel, nabel is a list of pairs [p,n] where p is a prime`); l(`at which E is non-abel. and the type of failure at p is coded by n:`); l(`v(x) denotes the p-adic value of x (the value v of the procedure val(x)`); l(`when p is preset), and j' denotes j-1728.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` n | p | non-abel. behavior at p`); l(`___|_________|____________________________________________________`); l(`-2 | 2 | j=1728`); l(`-1 | 3 | j=0`); l(` 1 | 3 mod 4 | v(j)=0, v(j')=1 mod 2`); l(` 2 | 5 mod 6 | v(j)>0, v(j)<>0 mod 3`); l(` 3 | 3 | v(j)>0, v(j')=1 mod 2`); l(` 4 | 3 | v(j)=2, j/9<>1 mod 3`); l(` 5 | 3 | v(j)=3, j/27<>4,10,13 or 22 mod 27`); l(` 6 | 2 | v(j)>0, v(j)<>0 mod 3`); l(` 7 | 2 | 06 or`); l(` | | v(j)=6 and j/64<>1 mod 8`); elif i<90 then l(`Roha()=NULL, roha()=roh=1 or -1`); l(` roh = the sign of the functional equation calculated as a product of lo\ cal`); l(`root numbers.`); l(`The variable SFE, when <>0, denotes an earlier determination of this`); l(`sign either analytically by Sfe() or by SFE=(-1)^rank. Of course all of`); l(`this is conjectural. When both roh and SFE are nonzero they are compared`); l(`-- they should be equal -- alarm bells if not. At the end roha() sets`); l(`SFE:=roh.`); l(` The value of SFE is transferred to isogenous curves when these have`); l(`been determined by apecs.`); l(` The procedures Roha and roha, which determine the root number in all`); l(`cases, supersede the earlier procedures Rohr and rohr which often failed`); l(`when there was additive reduction at 2 or 3.`); elif i<92 then l(`Absc(x) = NULL absc(x) = [x,y]`); l(` Find a point [x,y] on E with given abscissa x; x needn't be rational.`); l(`Of course this simply requires solving a quadratic equation for y.`); l(`Only one of the (usually) two possibilities is given.`); l(`Examples: with cur=A11, Absc(1) ===> [1,0], Absc(2) ===>`); l(`[2,-1/2+1/2 17^(1/2), and t:='t':gpt:=absc(t); makes gpt a generic point.`); elif i<94 then l(`Negp(pz)=NULL negp(pz)=nz`); l(` Calculate the negative nz of a point pz on E mod p. The prime p`); l(`must be preset.`); elif i<96 then l(`Search(args)=NULL`); l(`search(args)=searchl See also Seek and Seek1.`); l(` Let E be defined over Q either by Ein (so K_=1) or Ell (so K_<>1).`); l(` Search for rational points [x,y] on E with max(|numer(x)|,denom(x))`); l(`between args[1] and args[2] (or between 1 and args if nargs=1) and`); l(`store all points found in list searchl. No x-axis adjustment is made as`); l(`in Seek and, when K_=1, no regard is paid to the list RR of independent`); l(`points or the list uR of misc. points --- to save any possibly independent`); l(`points use map(App,searchl). Note that only one of a pair +-P is included,`); l(`and another call to Search will start from scratch.`); elif i<98 then l(`Seek1(args)=IP`); l(`seek1(args)=nops(IP) See also Seek and Search`); l(` Let E be defined over Q either by Ein (so K_=1) or Ell (so K_<>1).`); l(` Look for integral points [x,y] on E with |x| (adjusted by "f" as in`); l(`Seek) between args[1] and args[2] (or up to args if nargs=1) and`); l(`store points found in list IP.`); l(`When K_=1: also include in IP any integral points`); l(` accumulated in the "misc." list uR -- this may include some with |x|`); l(` outside the range specified by args. Also process these points by "ap1_"`); l(` as in Seek, but don't increase the "Seek limit" parameter sB since`); l(` possible points with denom(x)=4,9,16... haven't been checked.`); l(`When the Weier. coeff.'s ai are not all integral (hence K_<>1), seek1`); l(`clears denom.'s by transforming (temporarily) ai|-->ai*uV^i where the`); l(`pos. integer uV is minimal. This amounts to substituting in the Weier.`); l(`equation x=X/uV^2, y=Y/uV^3. Then seek1 puts in the list searchl the`); l(`[x,y] found such that [X,Y] is integral, whereas the list IP contains only`); l(`[x,y] that are actually integral (together with their negatives when`); l(`integral). Thus one would use`); l(` ein(cur);for z in searchl do trcw(z);od`); l(`when looking for indep. points on the Ein curve.`); elif i<100 then l(`Raf()=NULL`); l(`raf()=raF`); l(` Calculate list raF of x-coordinates of real (resp. all) points of`); l(`order 2 when E is a catalog curve, i.e. the variable cur has a value`); l(` such as A11 (resp. not a cat. curve and cur='cur').`); elif i<102 then l(`We() or We(args)=NULL`); l(`we() or we(args)=wec`); l(` args specifies a catalog curve; no args means take present curve.`); l(`args (if present) may have any of the forms C33 (a catalog name), 65`); l(`(a cat. number),[1,1,0,44,55] or 1,1,0,44,55 (a list or seq.of coef.'s).`); l(`The 5 Weierstrass coef.'s of the specified curve are put in the list`); l(`wec. Thus in the case nargs=0, wec=[a1,a2,a3,a4,a6].`); l(`We displays the Weierstrass equation; we displays wec.`); elif i<104 then l(`Div(args)=NULL, div(args)=al.args`); l(` Calculate the polynomial al.args e.g. if args=6 then calculate al6.`); l(`These polynomials are essentially the division poly.'s psi_n`); l(` al.n=psi_n (n odd), al.n=psi_n/(2y+a1x+a3) (n even)`); l(`They are calculated recursively (see op(div)); the variable aln is the`); l(`highest n for which al.n has been calculated. However not all lower al.i`); l(`will have been calculated in general --- only up to i=trunc(n/2)+2`); l(`since that's all that's needed to calculate al.n by the recurrence.`); l(` apecs begins with aln:=4 and`); l(` al1:=1: al2:=1:`); l(` al3:=3*x^4+b2*x^3+3*b4*x^2+3*b6*x+b8:`); l(`al4:=2*x^6+b2*x^5+5*b4*x^4+10*b6*x^3+10*b8*x^2+(b2*b8-b4*b6)*x+b4*b8-b6^2:`); l(`also al0:=(4*x^3+b2*x^2+2*b4*x+b6)^2: (a constant used in the recursions).`); elif i<106 then l(`Tri(args)=NULL tri(args)=trz`); l(` where args is either a pair z,oc or just oc where z is a point on E`); l(`and oc is a curve isogenous to E: calculate the image point trz on oc`); l(`E.g. Ein(D91);Tri([15,24],C91); Equivalently, since C91 has catalog number`); l(`ncur=271, Tri([15,24],271);.`); l(` This has now been implemented for all cyclic isogenies of degree<=27;`); l(`for composite degrees the "cheapest" path through prime degrees is taken.`); l(`Calculate the transformation equations of the isogeny and store them in`); l(`visog (see Menu(isog)) if they are not already there; then use these`); l(`equations to calculate the image trz of the point z. This last`); l(`calculation is omitted if z is absent from args, and then trz='trz'.`); l(`When trz is calculated it is adjoined to RR when that is appropriate,`); l(`as described in Menu(App).`); elif i<108 then l(`Velu(args)=NULL velu(args)=ncur`); l(` Determine the isogenous curve E'=E/G which becomes the present curve`); l(` where G is the subgroup determined by args.`); l(`We have begun to make velu robust so that E can be defined over`); l(`"any" field K of char. 0. args is either a sequence,list or set`); l(`of points, in which case G is the subgroup of E(K) generated by these`); l(`points, or args is a polynomial in X defined over K whose roots(possibly`); l(`algebraic over K) are distinct and are the X-coordinates of the points`); l(`in G. Thus if args=(X-x1)*..(X-xn) then |G| is 2n or 2n+1 and`); l(`G={O,+-[x1,y1],..}`); l(` It is convenient to describe separately two cases:`); l(` CASE: E is a catalog curve (old or new). Then necessarily K=Q, and`); l(`the value of velu(args) is the catalog number of E'. Also calculate`); l(`the transf. equations of the isogeny and store in the variable visog`); l(`(see Menu(isog)) attached to E.`); l(`Examples: The torsion subgroup/Q of E=A80 consists of O and PP=[0,0,2].`); l(`Velu(z) where z is any one of [0,0,2], [0,0], 0,0, or X produces E'=B80.`); l(`But to get the 3-isogenous curve C80 we can only take z=X+1. (The kernel`); l(`is {O,[-1,I],[-1,-I]}, as we see by the command factor(al3) ---`); l(`as explained by Nota(), al.n is essentially the n-division polynomial.)`); l(` Of course in this case, Isog() determines all curves Q-isogenous to E.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` CASE: E is not a catalog curve. This case is characterized by`); l(`cur='cur' is unevaluated. K=Q is not precluded --- E/Q can be introduced`); l(`by Ell. |G| is bounded by Nsubg, whose default value is 16, and if`); l(`exceeded the procedure is aborted. This variable can be assigned another`); l(`value at any time. The image under the isogeny of the general point [X,Y]`); l(`of E is [x7,y7] in E'(K), where x7, y7 are rational functions in X, Y.`); l(`Thus to obtain the image of a point [a,b] one puts X:=a;Y:=b; so the`); l(`image point is [x7,y7]; DON'T FORGET to finish up with X:='X';Y:='Y';`); l(`x7,y7 are not saved in anything like visog as in the catalog curve case,`); l(`so its best to store their values in other variables if they will be`); l(`needed later.`); elif i<110 then l(`Exam() or Exam(args) =NULL; exam() or exam(args)=NULL`); l(` Exam is a repository for examples and formulas, and also an input`); l(`procedure for curves with specified torsion.`); l(`Exam(); displays an index of the various Exam topics/functions.`); l(`Exam(i); displays the data for topic #i. exam(i); is a shortened form.`); l(`Exam(n,t); (resp. Exam(2n,1,t)) inputs a curve with torsion group`); l(`Cn (resp. C2xCn) determined by the parameter t -- with slightly`); l(`different args for C3 and C2xC2:`); l(` For C3 use Exam(3,a1,a3);`); l(` For C2xC2 use Exam(4,a2,a);`); l(`See Exam(1) for further details and examples.`); elif i<114 then l(`Hdif_Sik()=NULL; hdif_Sik()=lowB`); l(`Hdif_Sil()=NULL; hdif_Sil()=[lowB_Sil,uppB]`); l(`Let P be any rational point on E, let h denote its logarithmic height`); l(`i.e. if P=[x,y] and x=a/b with gcd(a,b)=1, then h=log(max(|a|,|b|)),`); l(`and h^ its canonical (Weil-Neron-Tate) height (as can be calculated by`); l(`the procedure ht(x)). Then for all P,`); l(` max{lowB,lowB_Sil} < h^ - (1/2)h < uppB`); l(`It seems lowB is usually better (bigger) and so the procedure`); l(`bas calls hdif_Sik().`); l(`Ref's: J. Silverman, "Difference between Weil..", Math. Comp. 1990, 723-\ 743;`); l(`S. Siksek, "Infinite descent on ell. curves", Rocky Mountain J. Math.,`); l(`25(1995), 1501--1538.`); elif i<116 then l(`RkNC(args)=NULL; rkNC(args)=NULL; -- usually args is absent`); l(`Call rk(args) to calculate the rank with rflag=3 so that No Conjectures`); l(`are used -- no use of Mest(), FnL() or (-1)^r4=SFE.`); l(`This can be used, e.g., when 0<=rc<4 (which means that r4 is only a`); l(`conjectural value of the rank -- see Menu(bas) for more details about rc)`); l(`to attempt to increase rc; of course it can also be used when rc=-1.`); elif i<118 then l(`Expr(z)=NULL expr(z)=[num1,..,num.MM],TP or z or NULL`); l(`Express z=num1*P1+.. as a linear combination of the points P1,.. in RR`); l(`+ TP, a torsion point -- when possible. When z itself is a torsion point`); l(`expr returns z; when only a multiple of z, denoted den*z, is expressible`); l(`thus, expr returns [num1/den,..],TP and then calls ap1_(z) which attempts`); l(`to improve RR, i.e. smaller height pair. det. -- so the fractions`); l(`num1/den,.. will not be relevent to the new RR; when z is indep. of RR`); l(`mod torsion expr returns NULL, and in this case also calls ap1_(z) which`); l(`results in a new RR of length one greater.`); elif i<120 then l(`Store()=NULL store()=stORe`); l(`This command toggles the storage mode of apecs between "store all curves`); l(`in the stack and also, when K_=1 (see Menu(ell) for K_), in the catalog"`); l(`(then the variable stORe=1 --- apecs begins this way),`); l(`and "store only the present curve and possibly some isogenous`); l(`curves" (then stORe=0, and these will be overwritten when a new curve`); l(`is introduced). This is useful when large families of curves are`); l(`being processed so that maple does not become bogged down. One can`); l(`toggle Store() to keep only the interesting curves in the catalog.`); l(`Of course one must remember to use Zpecs(); or Ypecs(); to save the`); l(`enlarged catalog if these curves are wanted for another session.`); elif i<122 then l(`Trans(r,s,t,u)=NULL trans(r,s,t,u)=NULL or`); l(`Trans(r,s,t,u,k)=NULL trans(r,s,t,u,k)=NULL`); l(`5-th arg is optional `); l(` Transform the present Weierstrass equation`); l(` y^2+a1*xy+a3*y=x^3+a2*x^2+a4*x+a6`); l(`by substituting`); l(` x=u^2*x'+r, y=u^3*y'+s*u^2*x'+t`); l(`and then invoking Ell(or ell)(a1',..,a6',K_) (see Menu(ell) for K_)`); l(`where K_ has either its present value or, when there is a 5-th arg, is set`); l(` := k. (Exceptions: 1. When present K_=1 then K_ is set = 0 since the`); l(`transformed E is not Weier. reduced. 2. If the transformed curve is not`); l(`defined over the field with label K_ then K_ reverts to 0.)`); l(`The coefficients a1',.. of the resulting Weierstrass equation are`); l(` u*a1'= a1+2*s`); l(` u^2*a2'= a2-s*a1+3*r-s^2`); l(` u^3*a3'= a3+r*a1+2*t`); l(` u^4*a4'= a4-s*a3+2*r*a2-(t+r*s)*a1+3*r^2-2*s*t`); l(` u^6*a6'= a6+r*a4+r^2*a2+r^3-t*a3-t^2-r*t*a1`); l(`Both the original and the transformed E are in the stack and Trwc and`); l(`Trcw (see Menu(Trcw)) are available for both.`); l(`Note also that Trans and trans automatically transfer points from RR`); l(`of the original E to RR of the transformed E.`); elif i<124 then l(`Cubic_fit(args)=NULL, cubic_fit(args)=f_`); l(`***** These commands may result in an ERROR message ---`); l(` then simply repeat the command verbatim, or precede the`); l(` the cubic_fit command with prep_(); see below for explan.*****`); l(` where args consists of two parts, both optional:`); l(`part 1 is a sequence of points [u1,v1],...,[un,vn] (n >= 0)`); l(`in the affine plane, and part 2 (if present) is either a single`); l(`equation, or a set or a list of equations involving the variables`); l(`s_1,..,s_9 of the form s_i=... . These procedures calculate a cubic`); l(`f_:=s_1*u^3+s_2*u^2*v+_s_3*u*v^2+s_4v^3+s_5*u^2+s_6*u*v+s_7*v^2+s_8*u+s_\ 9*v`); l(`passing through the points [u,v]=[0,0] and [ui,vi], i=1..n,`); l(`and whose coefficients satisfy the equations in part 2 of args.`); l(`EXAMPLE: Cubic_fit([0,1],[1,1],[1,2],[2,-1],[3,-1],{s_1=1,s_7=s_8,s_9=\ 1/3})`); l(`The result may be "no solution" -- then f_=NULL -- or some of the s_i`); l(`may be left as undetermined (parameters). One can leave them as param.'s`); l(`or give them values by commands (e.g. s_5:=0; s_6:=my_s6;..)`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` Now one can use Third_pt (see Menu(third_pt)). If all the s_i are`); l(`rational one can get the birationally equivalent min. Weierstrass equation`); l(`by invoking Gcub(s_||(1..10)); (or Gcub(s_.(1..10)) in MapleV and`); l(`earlier). s_10 has automatically been set = 0.`); l(`Remember that the variable bic contains the details of the birat.`); l(`correspondence --- see Menu(gcub), and the commands Trwc and Trcw can be`); l(`used to translate points between Cubic and Weier.`); l(`***** When cubic_fit is called more than once then (probably) some of`); l(`the s_i have been assigned values which may collide with equations`); l(`in "part 2" of args --- and I can't program around this because the`); l(`args are evaluated before anything in the procedure is carried out.`); l(`Repeating the command clears out the confusion because cubic_fit`); l(`initially sets all s_i to unevaluated.`); l(` Alternatively one can precede the cubic_fit command with prep_();`); l(`which is an internal apecs procedure that sets s_1:='s_1': etc.`); l(` --- e.g. in a loop in your own program calling cubic_fit you should`); l(`have ... prep_();cubic_fit(...); ... .`); elif i<126 then l(`Third_pt(z1,z2)=NULL, third_pt(z1,z2)=[u3,v3]`); l(` Calculate the third point z3 = [u3,v3] of intersection of the line`); l(`joining the two given zi = [ui,vi] (z1 = z2 is allowed) with the`); l(`cubic f_=s_1*u^3+...+s_9v (s_10=0) which is normally preset by the`); l(`command Cubic_fit (see Menu(cubic_fit);). These commands encompass`); l(`only affine points, and so one cannot have z1=[], for instance.`); l(`On the other hand the result may be "at infinity" --- then z3 = [].`); elif i<128 then l(`Weier_fit(args)=NULL weier_fit(args)=f_`); l(`***** These commands may result in an ERROR message ---`); l(` then simply repeat the command verbatim. Alternatively,`); l(` precede the Weier_fit command with the apecs command wprep_();`); l(` The situation is similar to that of Cubic_fit.`); l(` See Menu(cubic_fit) for explan.*****`); l(` where args consists of two parts, both optional:`); l(`part 1 is a sequence of points [u1,v1],...,[un,vn] (n >= 0)`); l(`in the affine plane, and part 2 (if present) is either a single`); l(`equation, or a set or a list of equations involving the variables`); l(`a_1,a_2,a_3,a_4,a_6 of the form a_i=... . These procedures calculate`); l(` f_:=x_^3+a_2*x_^2+a_4*x_+a_6-y_^2-a_1*x_*y_-a_3*y_`); l(`passing through the points [ui,vi], i=1..n, and whose coefficients`); l(`satisfy the equations in part 2 of args.`); l(`There may be no solution, and then f_=NULL is returned, or some of the`); l(`a_i may be left as parameters. When the parameters (if any) are given`); l(`rational values, one can, e.g., call Ein(a_||(1..5)); (or a.(1..5) in`); l(`MapleV and earlier). a_5 is auto. set = a_6 by weier_fit.`); l(`EXAMPLE: Here is how the examples of T (torsion subgroup) = C2 and`); l(`r (rank of E(Q)) = 4 and 5 in the table displayed by Exam(4) were found:`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`The Weierstrass equation`); print(Y^2+a1XY=X^3+a2X^2+a4X); l(`has the point [0,0] of order 2. We use weier_fit to make this curve go`); l(`thro' 3 integral points, which often gives r>=3, and look for cases r>3:`); l(` ppts:=NULL:#ppts will be set of all integral points [x,y] with`); l(` #-2<=x,y<=2, [0,0] excluded`); l(` for x from -2 to 2 do for y from -2 to 2 do ppts:=ppts,[x,y]:od:od:`); l(` ppts:={ppts} minus {[0,0]}:`); l(` with(combinat):pts3:=choose(ppts,3):#pts3 is set of triples of`); l(` #distinct points from ppts`); l(` r4l:=[]:#r4l will be list of cases with (probably) r>3`); l(` for pt3 in pts3 do`); l(` wprep_():weier_fit(op(pt3),{a_3=0,a_6=0}):`); l(` if f_<>NULL and type(f_,polynom(rational)) then ein(a_||(1..5)):`); l(` if DD<>0 then rkNC():`); l(` if r4>3 then r4l:=[op(r4l),pt3]:fi:`); l(` fi:fi:`); l(` od:`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`Sometimes different triples pt3 give the same curve E. For r=4 we`); l(`found 11 different E -- Ein(625) is the one with smallest conductor`); l(`Nc -- and one E with r=5, namely Ein(626).`); elif i<130 then l(`Tor()=NULL tor()=NN`); l(`Tor(z)=NULL tor(z)=NN`); l(`Determine the torsion subgroup of E(K) where E is an elliptic curve`); l(`defined over the field K in the following cases:`); l(`--- K=Q, any field label K_ (see Menu(ell) for K_)`); l(`--- K=Q(sqrt(m_)) with K_=m_ (see Menu(qfin))`); l(`--- K=Q(T) with K_=T (the variable must be T)`); l(`Normally E/Q are introduced by Ein (or Ein0), and in the other cases by`); l(`Ell with the extra parameter K_=m or T (again see Menu(Ell) for details).`); l(`Other venues for the intro. of E are Genj, Quar, Gcub, Velu,.. .`); l(` The seldom used optional param. z -- available only in the case K=Q --`); l(`is z = a torsion point [x,y] that is somehow known beforehand.`); l(`(This feature is exploited by the commands exam(n,t), etc.)`); l(`Notation: NN=order of torsion subgroup`); l(` PP=sequence of non-O torsion points in the format [x,y,n]`); l(`where n=the order of the point. Thus PP=NULL when NN=1.`); l(` ouP=[...,[x,y],...] list of members of PP with n dropped`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`NN=0 signals that tor is not programmed for the present curve, e.g. when`); l(`K_=0 and some ai is irrational. NN=-1 means that tor has not yet been`); l(`called. Even when NN=0, PP and ouP are maintained: tor finds the points`); l(`of order 2 defined over the field generated over Q by the Weier. coeff.'s`); l(`a1,..a6. (but NN remains 0); and PP, ouP are augmented`); l(`by any point of finite order and its multiples that happens to be`); l(`discovered (perhaps by a call App(x,y)).`); l(` The general approach is to find the roots in K first of prac for`); l(`points of order 2, then of the division poly.'s ali for appropriate`); l(`i=3,4,.. guided by an upper bound for NN usually obtained by reduction`); l(`of E mod "primes", i.e., principal prime ideals. Note that these`); l(`reductions usually involve internal calls to ein or ell which result in`); l(`unexpected entries in the stack; see Menu(Go). tor calls torq when K_=m_`); l(`(see Menu(Qfin)) or torT when K_=T. In the latter case, the higher`); l(`division poly.'s easily get out of control, and so torT is based on the`); l(`Nagell-Lutz approach.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` In the case K_=1, various techniques are potentially employed by tor:`); l(`clues from the Tate alg. or from isog. curves; reduction mod good and`); l(`bad p; etc. Nagell-Lutz is there as a last resort, but is seldom used`); l(`because with even moderately sized coeff.'s, there can be an impractically`); l(`long list of candidate divisors.`); l(`EXAMPLE 1: Ein(F112);Tor();# the catalog curve F112 has torsion group/Q`); l(` # C2 = cylic order 2`); l(` Ell(cur,2);Tor();# F112 has torsion group/Q(sqrt(2)) C2xC2`); l(`EXAMPLE 2: Ell(0,sqrt(8),0,3/2,0);Tor(); ===> NN=0 and`); l(` PP:=[-3sqrt(2)/2,0,2],[-sqrt(2)/2,0,2],[0,0,2]`); l(` ("possibly incomplete").`); elif i<132 then l(`Qfin(m)=NULL qfin(m)=m_`); l(` Point apecs to the quadratic field Q(sqrt(m)); m must be a squarefree`); l(`integer <>1. qfin (which stands for quadratic field initialization)`); l(`causes apecs to:`); l(`set m_:=m (also K_:=m, cf. Menu(ell);) and initialize apecs to treat ell\ iptic curves defined ov\ er Q(sqrt(m_)). (Many of the names used in this package end in an under\ line _ to make them distinctive). An integral basis is 1,w_ where w_= s\ qrt(m_) or (-1+sqrt(m_))/2. w_ is a root of pol_. ram_ is the set of ramifi\ ed primes. h_ is the class number "indicator": h_=1 means class no.=1, h_=2 \ means class no. >1, h_=0 means class no. unknown. Some tables of soln.'s to c\ ertain congruences (e.g.x^4==a+b*w_ mod 8) are set up.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` In practice, often qfin is only invoked implicitly by the command Ell`); l(`That is, when Ell is given appropriate args, it automatically calls qfin.`); l(`See Menu(ell);.`); l(` Other procedures in this package are (all in the apecs file QF_):`); l(`--- Fundunit(): when m_>0 calculates the fundamental unit, i.e., the`); l(`smallest unit > 1, in the notation unit_+vnit_*w_ with approx. real value`); l(`enit_ and with norm nnit_ = +-1.`); l(`(fundunit is called automatically by minf when m_>0.)`); l(`--- nm_(z) calculates the norm of z`); l(`--- Fact(z) factorizes the alg. integer z; see Menu(fact)`); l(`--- Minf(): After a curve E defined over Z[w_] has been introduced by`); l(`Ell, this proc. transforms E to global minimal Weierstrass form ---`); l(`programmed ONLY FOR h_ = 1. See Menu(minf).)`); l(`--- Torq() calculates the torsion subgroup of E(Q(sqrt(m_)))`); l(` (any h_); but usually one calls Tor() (which calls torq) --- see`); l(` Menu(torq); or, less ambitiously,`); l(`--- Ub_tor(args) calculates an upper bound for the order of the torsion`); l(` subgroup by reducing E mod p for the first n primes p which do not`); l(` divide nm_(DD) and which are either ramified or split, where n=args`); l(` (default n=4 when args is absent). ub_tor is called by torq, and`); l(` and Torq/torq can have an args which is passed to ub_tor.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`Here is a sample session:`); l(` Ell(0,2*w_,0,3-7*w_,0,5);Minf();Tor();`); l(`The 6-th arg of Ell, 5, causes ell to call qfin(5); see Menu(ell);.`); l(`Ell allows the args a1,..,a6 to be any members of Q(w_,sqrt(m_)). In`); l(`the above example, since sqrt(5)=2*w_+1, 2*w_ could be replaced by`); l(`-w_+3*(5/sqrt(5)-1)/2; for more detail, again see Menu(ell).`); elif i<134 then l(`Minf()=NULL minf()=NULL`); l(`The prerequisites to using these commands are: apecs is pointing to a`); l(`quadratic field Q(sqrt(m_) with h_ =1, i.e., class number = 1, and the`); l(`present curve is defined over the ring of integers Z[w_] of that field.`); l(`For notation see Menu(qfin). Usually these prerequisites are met by the`); l(`Ell command with appropriate args, as explained in Menu(Ell). For example`); l(`Ell(0,-2,w_,(5-2*sqrt(17))^7,0,17);. Then minf finds a global minimal`); l(`form E' of E over Z[w_] (existence guaranteed when the class number h_=1)`); l(`and calls ell(new_,m_) where new_ is the list of Weierstrass coefficients`); l(`of E' (old_ is the list for E), and calculates the transformation`); l(`tau_=[r_,s_,t_,u_] from E to E.'`); l(`For the theory see Chapter 5, section 5.6.2 of Elliptic Curve Handbook.`); elif i<136 then l(`Fact(args)=NULL fact(args)=facs_`); l(` It is necessary that K_= some m_ as explained in Menu(ell); see also`); l(`Menu(Qfin); args must be an algebraic integer in Z[w_], and so (after`); l(`simplification) has the form a+b*w_ where a,b are integers.`); l(` Find the factorization product(p_^{v_}) in Z[w_] of args and put`); l(`results in the list facs_=[..,[p_,v_],..]. p_ denotes a prime ideal`); l(`and is actually an alg. integer when the ideal is principal; or may`); l(`be literal, when [p_,v_] has one of the forms [P.p,v_] (when the`); l(`rational prime p ramifies as pZ[w_]=(P.p)^2, P.p non-principal), or`); l(`[P.p,N] or [Q.p,v_-N] where v_ is an actual integer and N is an`); l(`undetermined integer in the case when p splits as (P.p)(Q.p) into two`); l(`non-princ. prime ideals.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`EXAMPLES: Qfin(5);Fact(20-30*w_); ==>`); print(`The factorization of .. up to a unit factor is`); print([[2,1],[1+2*w_,2]]); l(`meaning that 20-30*w_=u*2*(1+2*w_)^2 where u is a unit; in fact,`); l(`(1+2*w_)^2=5 and u=2-3*w_. Since sqrt(5)=2*w_+1, Fact(35-15*sqrt(5))`); l(`would give the same result. In general, args can be any rational`); l(`function in w_ and sqrt(m_), as long as it simplifies to the form`); l(`a+b*w_ with a,b in Z.`); l(` On the other hand, Qfin(-5);Fact(20-30*w_); prints out`); print([[P_2,2],[w_,2],[P_7,N],[Q_7,2-N]]); l(`meaning that the factorization of the principal ideal (20-30*w_)Z[w_]`); l(`is P_2^2*(w_)^2*P_7^N*Q_7^(2-N) where P_2 is the unique ramified ideal`); l(`of norm 2 and P_7, Q_7 are the two ideals of norm 7; N is an undeter-`); l(`mined integer (one of 0,1,2), and of course depends on how one might`); l(`explicitly identify P_7 and Q_7.`); elif i<138 then l(`Crem(args)=NULL crem(args)=r1`); l(` with either no args, or args=dil, or args=A or args=A,dil or args=dil,A`); l(` where A is the actual letter A. dil has the default value 30.`); l(`For E defined over Q, the steps performed by Crem are as follows.`); l(` 1. If E has a rational point P of order 2 then call RkNC(dil) which`); l(`carries out 2-descent via the 2-isogeny E-->E/

(see Menu(RkNC)) ---`); l(`unless args includes A and then overide this and go to step 2.`); l(` 2. Apply the algorithm of Birch & Swinnerton-Dyer`); l(`[J. reine angew. Math. 212(1963)] as refined by Cremona [Algorithms for`); l(`modular elliptic curves], especially his recently discovered test for`); l(`the isomorphism of quartics to appear in the new edition of his book,`); l(`to enumerate the iso. classes of associated quartics V^2=a_*X^4+..+e_`); l(`hence get an upper bound r1 for the rank.`); l(` 3. Attempt to find which of these quartics is an elliptic curve`); l(`(necess. iso./Q to E) i.e. either a_ is a square or there is a rational`); l(`point. Search these quartics for rational points with X=n/d up to`); l(`max(|n|,d)<=dil. Sometimes the rank is determined before this search is`); l(`completed and then the procedure is terminated --- unless the letter A is`); l(`one of the args and then the search is carried through. The latter can be`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`useful to discover new independent points: the first point found on a`); l(`quartic is used by the "subroutine" quar to set up an iso. between the`); l(`quartic and E. Then points found subsequently are mapped to E and`); l(`processed appropriately. Cf. the apecs command App.`); l(` 4. The elliptic quartics are stored in eq_, while the undecided`); l(`quartics are stored in q_. These and other relevant data are stored in`); l(`the "stack" (but not in cat) so that one can call Crem repeatedly`); l(`(even after returning to E after considering other curves, e.g. by the`); l(`command Go): a subsequent call to Crem(dil) will resume the search for`); l(`rational points (on the quartics in both eq_ and q_) starting at the place`); l(`left off by the previous dil, without redoing Birch,Swinnerton-Dyer,Cremona.`); l(`It is not necess. to include A in args -- A is deemed to be present. Note`); l(`that the stack is preserved only in the present apecs session, so that in a`); l(`subsequent session Crem will start from scratch.`); elif i<140 then l(`Om2()=NULL om2()=omegA[1]`); l(`This command no longer exists --- all the work is done by Om.`); elif i<142 then l(`Subg(args)=op(GG) subg(args)=diso`); l(` Calc. the subgroup of E(K) generated by args where args is a sequence,`); l(`list or set of one or more points and where E is defined over`); l(`the field K of char. 0, e.g. K=Q, Q(T) or an alg. number field. GG is the`); l(`set of nonzero elements of the subgroup and diso:=nops(GG)+1 is the`); l(`subgroup order. If during the calc. the set GG obtained so far has`); l(`cardinality >= the apecs variable Nsubg then the procedure is aborted,`); l(`though GG is still available`); l(`Nsubg has the default value 16 (since when K=Q, diso>16 indicates that GG`); l(`is infinite) and can be assigned another value at any time. The notation`); l(`used for a point P=[x,y] in GG is [x,y,n] where n is the order of P, or`); l(`n=0 when the order is infinite or at least > Nsubg.`); elif i<144 then l(`Torq(args)=NULL torq(args)=NN`); l(` Calculate the torsion subgroup of E defined over the quadratic field`); l(`Q(sqrt(m_)) by first calling ub_tor(args) (args may be absent --- see`); l(`Menu(ub_tor)), and then finding roots of appropriate division poly.'s.`); l(`For more details about quad. fields, see Menu(qfin); and for more about`); l(`the methods for calculating torsion, see Menu(tor);.`); l(` Tor automatically calls torq when apecs is pointing to an`); l(`E/Q(sqrt(m_)), and in that case one may as well simply call Tor();`); l(`instead of Torq(); the only purpose of keeping torq available as a user`); l(`command is to allow the possibility of passing args to ub_tor.`); elif i<146 then l(`Ub_tor(args)=NULL ub_tor(args)=ubNN args(= pos. integer) optional`); l(` Set hex:=args (default hex:=4 if args is absent).`); l(` Find upper bound ubNN for torsion of E defined over quadratic field`); l(`Q(sqrt(m_)) by reducing E mod p for hex successive appropriate primes p.`); l(`See Menu(qfin) for notation and more details. For the possible kernels`); l(`of reduction mod p, see Corollary 2.10.5 in Elliptic Curve Handbook.`); elif i<148 then l(`Go()=NULL go()=NULL`); l(`Go(args)=NULL go(args)=NULL`); l(`With no args, Go displays the current stack, each line of the display`); l(`consisting of the curve's stack number (called stac in apecs) and either`); l(`the curve's name if K_=1, which is stored in ft1[stac], or the 5`); l(`Weierstrass coeff.'s if K_<>1, which are stored in ft2[stac], and finally`); l(`the field label K_. (See Menu(ell) for details about K_.)`); l(`Data pertinent to the curve is stored in ft[stac] to be retrieved if`); l(`apecs returns to that curve, but is not displayed by Go. (See Menu(Dat);`); l(`to display the curve's data.)`); l(` Go(n) returns apecs to the curve with stac=n, along with previously`); l(`calculated data that was saved in ft[stac].`); elif i<150 then l(`Fundunit()=NULL fundunit()=enit_`); l(` It is necessary that K_ = some positive m_, as explained in Menu(ell).`); l(`See also Menu(qfin); for more on the notation.`); l(` Calculate the fundamental unit, unit_+vnit_*w_, of Q(sqrt(m_), and its`); l(`absolute value (i.e., a real approx.) enit_ and its norm nnit_= +-1.`); l(`"Fundamental" means the smallest unit with enit_>1.`); elif i<152 then l(`Cld()=NULL cld()=uV`); l(`For an E/Q, clear denominators of Weier. coeff.'s by ai|-->ai*uV^i`); l(`where pos. integer uV is minimal. The resulting curve/Z becomes the`); l(`present curve with field label K_=0. To have this curve treated as a`); l(`catalog curve, use the command Ein(cur); it will then be put in min.`); l(`Weier. form and will have field label K_=1.`); elif i<154 then l(`Isom(args)=NULL isom(args)=isom_list or false`); l(`args=n1 or n1,n2 --- one or two stack numbers (see below)`); l(` Given one curve (or two curves) over the field K where K is either`); l(`Q or Q(sqrt(m)) or the rational function field Q(T), i.e., the field label`); l(`of the curve (or of both curves) K_=1, m or T (see Menu(ell)), find all`); l(`the automorphisms (or the isomorhisms) defined over K. In the latter case`); l(`RETURN(false) if there are none; else list all the auto.'s (or isom.'s)`); l(`in the variable isom_list in the standard notation [r,s,t,u]`); l(`(so u*a1'=a1+2s, etc.). Cf. Menu(Trans). Isom allows a mix of K_=1 for`); l(`one curve and K_=m or T for the other, and then lets the latter define K.`); l(` The curve(s) are specified as follows. Each curve in the present apecs`); l(`session has a place in the "stack" which consists of the lists ft1,`); l(`ft2,ft. These contain info. about these curves --- unless stack storage`); l(`has been toggled off by the command Store() (see Menu(Store)). Thus`); l(`ft1[n] etc. contain the info. of the curve with stack number n. The args`); l(`n1 (and n2 if present) must be pos. integer(s) <=nops(ft1). The stack`); l(`number of the present curve is stac. Thus Isom(stac) or Isom(n1) where`); l(`n1=stac finds the auto.'s of the present curve. If n1<>stac then Isom(n1)`); l(`finds the isom.'s of curve #n1 to the present curve. Isom(n1,n2) finds`); l(`the isom.'s of curve #n1 to curve #n2, auto.'s if n1=n2.`); elif i<156 then l(`Seekb(args)=NULL seekb(args)=sBb`); l(`If K_=1, so the present curve E is defined over Q (see Menu(Ell) for K_),`); l(`search for rational points on the curves birationally equiv. to E listed`); l(`in bec with naive height <= args, transfer any points found to E and`); l(`adjoin to RR when appropriate (as described in Menu(App)), then set`); l(`sBb:=args. The search starts from the previous sBb (initially sBb:=0).`); l(`This is occasionally useful when Seek with large args doesn't find a`); l(`point on E itself; the procedure bas may call seekb.`); l(` Whenever a new curve is added to bec sBb is reset to 0.`); elif i<158 then l(`qv is an abbreviation of the Latin quod vide, meaning look there to`); l(`find out something.`); elif i<160 then l(`Quarm(args), quarm(args) --- same args and RETURN values as Quar, quar`); l(` These procs call Quar or quar, passing args unchanged, and with`); l(`quarm_flag set = true, which is a signal to quar to regard the resulting`); l(`weierstrass equation as being defined over the quadratic field`); l(`Q(sqrt(m_)) to which apecs is currently pointing. Thus Quarm and quarm`); l(`require the following two things:`); l(` --- Qfin has been previously called so that apecs is pointing to`); l(`some Q(sqrt(m_)); and`); l(` --- args consists of numbers from the field Q(sqrt(m_)).`); l(` These procs are principally used when args are rational numbers,`); l(`since then Quar or quar alone would automatically have quarm_flag=false`); l(`and would process args in the usual manner over Q.`); l(`EXAMPLES: `); l(` Qfin(3);Quarm(2,0,1,1,3); Apecs notices that [U,V]=[0,w_]`); l(`(where w_=sqrt(3) --- see Menu(Qfin)) lies on the quartic`); print(V^2=U^4+U^2+U+3); l(`and uses this as the "rational point" to transform to a weier. equation.`); l(`Another point on the quartic is [0,-w_] and apecs doesn't miss the`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`opportunity to apply trcw(0,-w_) (see Menu(trcw)) which in this example`); l(`results in a contribution to the list RR of (independent) torsion free`); l(`points.`); l(` Qfin(3);Quar(2,0,1,1,3,0,w_); would have the same result --- quarm`); l(`isn't needed (but still could be used) since apecs detects the`); l(`presence of w_ in args and automatically sets quarm_flag=true.`); l(` Now consider the same quartic over Q(sqrt(2)):`); l(`Qfin(2);Quarm(2,0,1,1,3);. Apecs notices that the coeff. of U^4`); l(`is a square in Q(sqrt(2)), hence the two places at infinity on`); l(`the quartic are rational (over Q(sqrt(2)) of course), and uses one of`); l(`them to transform to weier. form. trcw applied to the other place at`); l(`infinity results in a contribution to RR.`); l(` Since the class number of the quad. fields in these examples is 1,`); l(`one can call Minf to convert the equation into a minimal weier.`); l(`equation. Note that RR and the torsion subgroup are transformed`); l(`appropriately, and so are not lost.`); elif i<162 then l(`Ypecs()=NULL ypecs()=NULL`); l(`Zpecs()=NULL zpecs()=NULL`); l(`Store the present catalog (which presumably was enlarged in the present`); l(`apecs session either by adding new curves or improving the info. of`); l(`existing catalog curves) on the hard disk, and`); l(`--- in the case of Ypecs or ypecs, return to the present apecs session,`); l(`--- in the case of Zpecs or zpecs, quit Maple.`); l(` What is saved to hard disk are the lists et1, et2, etj and the table`); l(`eT. The command Nota() provides descriptions of these data.`); l(` If you wish to quit without saving the catalog simply type in the`); l(`Maple command quit or click on File then on Exit. Of course the catalog`); l(`as it was at the beginning of this session is still on disk, and`); l(`available for the next session.`); l(` Exceptionally you may receive a message that there was trouble`); l(`along with the value of the list trou, and a request to type in "yes"`); l(`or "no" --- whether or not to save the catalog anyway. This indicates a`); l(`programming fault in apecs, and it would help me if you would e-mail`); l(`the value of trou and, if possible, the input that gave rise to the`); l(`trouble at`); print(`connell@math.mcgill.ca`); elif i<166 then l(`Afac(n)=NULL afac(n)=[u,[[p1,e1],..,[pk,ek]]]`); l(`n is a nonzero rational whose unique factorization is`); print(`n = u*p1^e1* .. *pk^ek`); l(`where u is in {1,-1} and the pi are primes.`); l(` afac is like ifactors (but enhanced -- see last paragraph below)`); l(`with the additional option remember, the point of which is to offer`); l(`the user the facility of informing apecs of difficult, time consuming`); l(`factorizations (e.g. of large DD and denom(jay)): at any time in an`); l(`apecs session one can enter a statement of the form`); print(`afac(133581487356257425101351408665453450):=[1, [[2, 1], [5, 2], [4\ 21, 1], [369137, 1], [35171526301168303, 1], [234653, 1], [2083, 1]]];`); l(`afac does not check the correctness of the factorization. Also,`); l(`afac knows the factorization of -n once it knows that of n. The verbose`); l(`command Afac knows all that afac knows, but afac, not Afac, must be`); l(`used to inform apecs of factorizations such as the example above.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` To take a simpler (trivial) example, if one enters`); print(`afac(-3/2):=[-1,[[3,1],[2,-1]]];`); l(`then any subsequent call to either afac(+-3/2) made by apecs (or the`); l(`user) will elicit an immediate response --- afac will not have to`); l(`"sweat through" the factorization. Afac(n) is like afac(n) except it`); l(`also displays the remember table of afac; Afac() simply displays`); l(`the table. This table is lost when apecs is quit, so if you expect to`); l(`encounter some of the same factorizations in future apecs sessions,`); l(`you could put the required afac(n):=[u,[[..]]] statements in a file,`); l(`say my_afacs, and then in any session you can enter read my_afacs;,`); l(`of course after read apecs;.`); l(` afac calls afactor which is modelled on Maple's ifactor but which`); l(`also maintains a set (called afacprimes) of the primes > 1600 that are`); l(`encountered. Thus if apecs has already factored DD (or -DD), perhaps`); l(`with the aid of the user by an afac(DD):=... entry, then apecs can`); l(`quickly factor, e.g., denom(jay) since its prime factors are in`); l(`the set afacprimes. This feature can be turned off by setting`); l(`afacflag:=false, or turned back on by afacflag:=true.`); else l(`Heeg(args)=NULL`); l(`heeg(args)=NULL`); l(`args (a positive integer) is optional; if present, n:=args, or in`); l(`default, n:=50000 -- see below`); l(`For these proc.'s the present curve must have the`); l(`field label K_=1 (so most likely was introduced by the Ein command)`); l(`and have (probable) rank r4=1. Heeg checks that K_=1 and at least that`); l(`the Sign of the Functional Equation SFE=-1, by calling roha if necessary.`); l(`It also checks that MM (number of indep. points in RR) is <=1.`); l(` The canonical height of a Heegner point is calculated; this is`); l(`available as the (global) variable hht:`); print(`hht = (approx.) eyy*NN^2/(2*Omega*cP)`); l(`where eyy is L'(1), the 1st deriv. of the L function as calculated by`); l(`FnL(4,n) (see Menu(fnL)), NN is the order of the torsion subgroup,`); l(`Omega is the real period (*2 if the discrim. DD>0 -- see Menu(om)),`); l(`and cP is the product of the local Tamagawa numbers as calc. in Tate's`); l(`algorithm. This formula is from Silverman, Computing rational points,..`); l(`Math. of Comp., 68(1999), 835--858.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(` If the number of terms in the L-series was not sufficient to`); l(`determine eyy to 4 figures, a suggestion to call Heeg(n+50000) is made.`); l(`On the other hand, if eyy is deemed to be 0 then Heeg infers that`); l(`the rank >= 3.`); l(` Heeg (but not heeg) displays an upper bound x for the naive height,`); l(`using hdif_Sik, which suggests calling Seek(x,1) to find the Heegner`); l(`point.`); l(`EXAMPLE: Ein(0,0,0,33,37);Heeg(); ===>`); l(`Heegner point has canon. height approx. 4.707 and naive ht. < 17200.`); l(` Seek(17200,1); ===>`); print('RR'=[[924/1849,582173/79507]]); l(`sB is set = 1848, so a subsequent call to seek will start there.`); fi; elif member(x,[Clock,clock,'Dat','dat',Half,half,Inch,inch,'menu','\ Nota','nota',Pad,pad,Szp,szp,Tate,tate,Ver,ver]) then print(cat(`Menu(`,x,`) not programmed; the brief description given by m\ enu();`)); l(`should be of some help.`); else print(cat(x,` is not an apecs command.`)); fi; end: menu:=proc() local l; #print list of apecs commands, minimal details l:=proc();lprint(args);end: l(`Note: A capitalized command, e.g. Isog(); gives detailed output, w\ hile`); l(`the uncapitalized version isog(); gives only bottom line results.`); l(`In partic., Menu(Ell); e.g., gives more detail than menu(); about Ell`); l(`Commands accept a point as an argument either as a list [x,y],or s\ equence`); l(`x,y and also, in the case of a point of finite order n, the form [x,\ y,n].`); l(`[] denotes point at infinity. In args column, -- stands for \ "nothing"`); l(`The args "curve" stands for any of: (i) a sequence a1,a2,a3,a4,a\ 6 of five`); l(`rational Weierstrass coefficients, e.g. 0,-2/3,10,0,1, (ii) a cat\ alog`); l(`name e.g. A11, (iii) a catalog number e.g. 2 (this specifies curv\ e B11).`); l(`The args "CUR" stands for 5 possibly irrational Weierstrass coeffici\ ents.`); l(`E stands for the present curve (whose catalog name and number are c\ ur,ncur`); l(`except that when cur='cur'--i.e. cur has no value--then E was input \ in`); l(`"general format" and may have irrational coefficients).`); print(` `); l(`Apecs |args |description`); l(`command| |`); l(`__________________________________________________________________\ ________`); l(`Abel | -- or curve| For which p is there an abelian ext. of Q_p \ over`); l(` | | which E acquires good or mult. reduction?`); l(`Absc | x | find point [x,y] on E with given abscissa`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`Afac | n | =ifactor(n) with option remember`); l(`AgM | x,y | arithmetic-geometric mean`); l(`Allp | p | all points and group structure of E mod p`); l(`App | [x,y] | append [x,y] to RR(=list of points indep. mo\ d torsion)`); l(`Bas | -- or BASL | seek("up to BASL") basis RR of E(Q) and regulat\ or reg`); l(`Cld | -- | clear denom.'s of Weier. coeff.'s of E/Q`); l(`Clock | -- | give status of Clock (uncapital. clock(x) must \ have x)`); l(`Clock | x | allow at most x seconds for infinite series & s\ earches`); l(`Comb | n1,z1,n2, | calc. n1*z1+n2*z2+..+nk*zk any k, any ni in Z,`); l(` | z2,.. | where each zi=[xi,yi] is a point on E`); l(`Crem |0,1 or 2 of A,dil| rank (or upper b.) by Birch+Sw.-Dyer+Cre\ mona alg.`); l(`Cubic_fit| args | find general cubic f_=s_1*x_^3+.. satisfying args.`); l(` | | See Menu(Cubic_fit).`); l(`Dat | -- or curve| data of E or curve; to display only the`); l(` | | Weierstrass equation use We`); l(`Div | n | calc. al.n as poly in X (essent. the n-divi\ sion poly.`); l(`Eadd | z1,z2 | add two points zi=[xi,yi] on E`); l(`Eadp | z1,z2 | " " " " " " mod p`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`Ein | curve | use Laska's alg. and Tate's alg. to find min. w\ eier.`); l(` | | form/Z, Kodaira types etc., list all twists i\ n catalog`); l(` | | also assign catalog name if curve is new`); l(`Ein0 | a0,..,a6 | as Ein except also coef. a0 of x^3`); l(`Ell |curve or CUR| input any ((ir)rational, literal, ..) weier.\ coef.'s`); l(` |&(optional)K_| & (opt.) field label K_. Calc. b's, c's, DD, jay`); l(`Emod | p | count number of points on E mod p (see also A\ llp)`); l(`Emods | p1,p2 | for all primes between p1, p2 list Emod, cos t\ heta,`); l(` | | state if supersing., anomalous, split mult. o\ r ..`); l(`Exam | -- or i | display index for Exam topics/functions or topi\ c #i`); l(`Exam | n,t | input curve with torsion Cn or C2xCn for param.`); l(` | or n,t,x | t (or t,x); to see details call Exam(1); .`); l(`Expr | z | express z=n1*P1+n2*P2+..+tor. point where RR=[P\ 1,..]`); l(`Fact | a+b*w_ | factorize args in Z[w_]; see Menu(Qfin).`); l(`FnL | r | calc. L^{r}(1) (r same parity as sign of func. \ eqn.)`); l(` " | r,de | optional param.: calc. series to within +-10^(-d\ e)`); l(` " | r,de,hyy | optional param.: use at most hyy terms of serie\ s.`); l(`Ford | x,y,t | list multiples of z=[x,y] up to min{t,ord z}`); l(`Fundunit| -- | smallest unit >1 of real Q(sqrt(m_)); see Menu(Qfin)`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`Gcub | s1,..,sn | cubic s1*U^3+s2*U^2*V+..+s9*V+s10 with point [s11,\ s12]`); l(` | n=10,12 or | or [s11,s12,0] at infinity or search for such`); l(` | 13 | provided all args rational, ----> Weierstrass form.`); l(`Genj | j | invoke Ein (Ell for non-rat. j) for "generi\ c j" curve`); l(`Go | -- | list stack(=list of curves of this apecs s\ ession)`); l(`Go | n or psn | go to #n in stack or to previous E`); l(`Half | z | q=list of points w such that 2*w=z`); l(`Hdif_Sik| -- | l. bound lowB for ht(x)-h(x)/2 (h=log. n\ aive height)`); l(`Hdif_Sil| -- | lowB_Sil,uppB for ht(x)-h(x)/2 (h=log. n\ aive height)`); l(`Heeg | -- or n | Canon. ht. of Heegner pt. using<50000 (or n)`); l(` | | terms in series for L'(1)`); l(`Ht | x,y | canon. height of [x,y] (Silverman-Tate alg.)`); l(`Inch | x | interchange catalog names (but not numbers)`); l(` | | of E and curve named x in catalog`); l(`Isog | -- | find all curves isogenous to E`); l(`Lin | z1,.. | find lin. reln. among zi mod torsion or`); l(` | | find them indep. Also adet:=height pairing`); l(` | | determinant when E and zi are /Q`); l(`Menu | x | help for apecs command x (x stripped of (args\ );`); l(` | | maple's help(); still available`); l(`menu | -- | this display`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`Mest | mL | calc. Mestre's upper bound for rank with param.\ =ln(mL)`); l(` " | -- | state result of last call to mest`); l(`Minf | -- | min. Weier. form of E/Z[w_]; see Menu(Qfin).`); l(`Mulp | N,z | with p preset, find N*z on E mod p, any N in Z`); l(`Mult | N,z | find N*z on E, any N in Z`); l(`Neg | z | calculate -z`); l(`Negp | pz | negative nz of point pz on E mod p, prime p pr\ eset`); l(`Nota | -- | list most important notation used by apecs`); l(`Om | -- | lattice periods omega[i], i=1,2 (using AgM)`); l(`Omp | n | p-adic period (Tate's q) and u^2 (Henniart-Me\ stre)`); l(` | | to n p-adic digits for all relevant p`); l(`Omp | p,n | as Omp(n) but only for specified p`); l(`On | x,y | point on E? - true or false`); l(`Onp | x,y | point on E mod p? - true or false (p preset)`); l(`Pad | a,p,n | p-adic expansion of a mod p^n`); l(`Qfin | m | point apecs to Q(sqrt(m_)); but see Menu(ell)`); l(`Quar | S1,..,Sn | birat. transf. V^2=quartic S1*U^4+..+S5 with \ point`); l(` | n=5,7 or 8 | [U,V]=[S6,S7] or at inf. if n=8 (or poss. search`); l(` | | for such if nargs=5) to weier. form and invoke`); l(` | | Ein or Ell depending on K_`); l(`Quar0 | S1,.. | as Quar but treat Si as irrational even if rat.`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`Quarm | S1,.. | with Si in Q call Quar treating Si in Q(sqrt(m_)`); l(` | | Qfin(m_) must be called previously.`); l(`Raf | -- | raF=[x-coord.('s) of real point(s) of order 2] o\ r`); l(` | | x-coord's. of all pts. of order 2 when cur='c\ ur'.`); l(`Rk | -- | rank (use Mazur's upper b. or 2-descent if poss\ . or`); l(` | | parity of rank from roha(), or`); l(` | | Mestre's upper b. - assume R.H. for L - or`); l(` | | by eval. of L^{r}(1)) - assuming B-Sw.D)`); l(`Rk | d | as Rk(); but search limit for homog. spaces = d\ `); l(`Rk0 | -- or d | as Rk but no Mest() or L^{r}(1)`); l(`Rk1 | -- or d | as Rk but no L^{r}(1)`); l(`RkNC | -- or d | as Rk but use of No Conjectures allowed`); l(`Roha | -- | SFE as root number.`); l(`Search | l or l1,l2 | simplif. Seek--no adjust. to naive ht.,no add's\ to RR`); l(`Seek | l | search for [x,y] up to (modified) naive h\ eight l`); l(`Seek1 | l or l1,l2 | IP=list integral [x,y] "up to" l or betw. l1 & l2`); l(`Seekb | l | search for points with naive ht<=l on curves in bec`); l(`Sfe | -- | sign of functional equation analytically`); l(` " | hyy | " but use at most hyy terms of series for cusp \ form`); l(`Sha | -- or X | order of Shafarevich-Tate group (assuming B-\ Sw.D)`); l(`Store | -- | toggle between store/no store curves in cat & s\ tack`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`Sub | z1,z2 | calculate z1-z2`); l(`Subg | z1,.. | subgroup of E generated by {z1,..}`); l(`Szp | -- | Szpiro ratio (log(abs(DD))/log(Nc))`); l(`Tate | -- | Tate's alg. for Neron model (auto. called by e\ in`); l(` | | so not normally invoked by user)`); l(`Third_pt| z1,z2 | find 3rd pt. of intersection with cubic f_`); l(`Tor | -- | torsion subgroup of E over Q or Q(T) or Q(sqrt(m_)`); l(` " | z | " " with known torsion point z to speed up Tor`); l(`Torq | -- or n | " " /Q(sqrt(m_)), but largely superseded by Tor`); l(`Trans | r,s,t,u | call Ell or ell(a1',..,a6'), a1'=(a1+2s)/u^2, etc.`); l(`Trcw | u,v,n | transfer point [u,v] (eg. []) from curve #n in \ bec`); l(` " | or [u,v],n | (ie. curve as orig. input by Ein,Ein0,Quar\ ,Gcub, or`); l(` " |u,v or [u,v]| Genj) to E, the Weier. form. n absent===>n=1`); l(` " | n or -- | Display curve #n of bec & transf's. n absent===\ >n=1`); l(`Tri | z,tric | image of point z on isog. curve tric(=cat nam\ e or no.)`); l(`Trwc | x,y,n or | as Trcw except transfer [x,y] on weier. to curv\ e`); l(` | [x,y] etc | #n in bec`); l(`Tw | a | twist E by a and invoke ell or ein`); l(`>>>>>HIT SEMICOLON KEY ; FOR NEXT SCREEN`);readstat(); l(`Ub_tor | -- or n | upper b. for torsion of E/Q(sqrt(m));see Menu(qfin)`); l(`Velu | z1,.. | divide E by subgroup generated by {z1,..}, inv\ oke ein`); l(` | or poly. | If args=(X-x1)*.. then subg.={O,+-[x1,y1],..}.\ `); l(`Ver | -- | version number, author's address..`); l(`We | -- or curve| print Weierstrass equation`); l(`Weier_fit| args | find general Weier. eqn. f_=x_^3..-a_3y sat. ar\ gs`); l(`Ypecs | -- | as Zpecs(); but don't quit - return to ape\ cs prompt`); l(`Zpecs | -- | store updated/enlarged catalog of elliptic cur\ ves`); l(` | | and data, then quit apecs. To leave apecs wi\ thout`); l(` | | saving this session's curves+data use maple'\ s quit`); end: