sympow-1.019/0000755017361200001450000000000011020051773012733 5ustar tabbottcrontabsympow-1.019/analrank.c0000644017361200001450000000562510442324213014675 0ustar tabbottcrontab#include "sympow.h" #define DEBUG (FALSE || GLOBAL_DEBUG) static int primes_upper_bound(llint x) {double X=(double) x; return (int) (X/Log(X)*(1.0+1.2762/Log(X)));} void prep_analrank(llint UB,int sl) {char STR[128]="1w0s0p06D0",S[128]; llint NU,NT; double f; int l,w1; l=(int) Floor(Log10(REAL_PERIOD[0])); if (l>0) l=0; if (l<-10-sl) {l=-10-sl; printf("*WARNING* possible precision truncation\n");} STR[7]-=l; while (STR[7]>'9') {STR[7]-=10; STR[6]++;} STR[4]+=sl; w1=global_rootno(1); if (w1==-1) STR[9]++; NT=preparation(CURR_MAX,STR,UB); if (NT==0) errorit("Too many terms needed to compute the analytic rank"); if (NT>(1<<30)) {ANAL_RANK=-1; NUM_SUMS=0; WHICH=0; sprintf(S,"%s,%s,%s,%s,%s",STR,STR,STR,STR,STR); S[20]+=2; S[31]+=4; S[42]+=6; S[53]+=8; NT=process_string(S,UB); go(NT,NT); return;} else {AP_SAVE=1; apsave=malloc(primes_upper_bound(NT)*sizeof(int));} if (NT0.0001) {if (w1==1) printf("Analytic Rank is 0 : L-value %.5e\n",f); else printf("Analytic Rank is 1 : L'-value %.5e\n",f); return;} if (VERBOSE) {if (w1==1) printf("L(E,1) appears to be zero %.5e\n",f); else printf("L'(E,1) appears to be zero %.5e\n",f);} NUM_SUMS=0; WHICH=0; STR[9]+=2; NU=process_string(STR,UB); f=go(NU,NT); free_data(); if (Abs(f)/REAL_PERIOD[0]>0.0001) {if (w1==1) printf("Analytic Rank is 2 : leading L-term %.5e\n",f); else printf("Analytic Rank is 3 : leading L-term %.5e\n",f); return;} if (VERBOSE) {if (w1==1) printf("L''(E,1) appears to be zero %.5e\n",f); else printf("L'''(E,1) appears to be zero %.5e\n",f);} NUM_SUMS=0; WHICH=0; STR[9]+=2; NU=process_string(STR,UB); f=go(NU,NT); free_data(); if (Abs(f)/REAL_PERIOD[0]>0.0001) {if (w1==1) printf("Analytic Rank is 4 : leading L-term %.5e\n",f); else printf("Analytic Rank is 5 : leading L-term %.5e\n",f); return;} if (VERBOSE) {if (w1==1) printf("4th deriv of L(E,s) at s=1 appears to be zero %.5e\n",f); else printf("5th deriv of L(E,s) at s=1 appears to be zero %.5e\n",f);} NUM_SUMS=0; WHICH=0; STR[9]+=2; NU=process_string(STR,UB); f=go(NU,NT); free_data(); if (Abs(f)/REAL_PERIOD[0]>0.0001) {if (w1==1) printf("Analytic Rank is 6 : leading L-term %.5e\n",f); else printf("Analytic Rank is 7 : leading L-term %.5e\n",f); return;} if (VERBOSE) {if (w1==1) printf("6th deriv of L(E,s) at s=1 appears to be zero %.5e\n",f); else printf("7th deriv of L(E,s) at s=1 appears to be zero %.5e\n",f);} NUM_SUMS=0; WHICH=0; STR[9]+=2; NU=process_string(STR,UB); f=go(NU,NT); free_data(); if (Abs(f)/REAL_PERIOD[0]>0.0001) {if (w1==1) printf("Analytic Rank is 8 : leading L-term %.5e\n",f); else printf("Analytic Rank is 9 : leading L-term %.5e\n",f); return;} if (VERBOSE) {if (w1==1) printf("8th deriv of L(E,s) at s=1 appears to be zero %.5e\n",f); else printf("9th deriv of L(E,s) at s=1 appears to be zero %.5e\n",f);} errorit("Analytic Rank is too big!!");} sympow-1.019/analytic.c0000644017361200001450000000561710442324213014713 0ustar tabbottcrontab#include "sympow.h" #define DEBUG (FALSE || GLOBAL_DEBUG) static void compute_local_powser(QD h,QD *P,QD R,int NUM,int W) {int i; if (W==1) for (i=NUM;i>=0;i--) {R[0]*=h[0]; R[0]+=P[i][0];} else for (i=NUM;i>=0;i--) {QD_mul(W,R,h,R); QD_add(W,R,P[i],R);}} static void loopit(x,left_point,step,index,which,result,W,S) double *x,left_point,step; int index,which; double *result; int W,S; {double Y; QD z,*P; int n; QD_copy(W,x,z); z[0]-=left_point; Y=Floor(0.5+z[0]/step); z[0]-=step*Y; n=(int) Y; QD_self_renorm(W,z); P=TABLE[which][index+n]; QD_copy(W,QD_zero,result); compute_local_powser(z,P,result,3+wprec[S]/2,W);} void get_wt_large(int which,QD x,QD R,int W,int S) {int i=0; double y,tb=TOO_BIG[which],B=EXPAND0_LIM[which]; double STEP=STEP_SIZE[which],LP=STEP*32.0; y=x[0]; if (y>tb) {QD_copy(W,QD_zero,R); return;} while (1) {if (y=0;l--) {Q=P[l]; QD_mul(W,R,L,R); QD_copy(W,QD_zero,T); if ((l==NUM_LOGS[which]) && HALF_ZERO[which]) {for(i=A0PT/2-1;i>=0;i--) {QD_mul(W,T,xs,T); QD_add(W,T,Q[i],T);} if (HALF_ZERO[which]==2) QD_mul(W,T,x,T); } else {for(i=A0PT-1;i>=0;i--) {QD_mul(W,T,x,T); QD_add(W,T,Q[i],T);}} QD_add(W,R,T,R);} if (TACKON[which]) ps_tackon(W,R,L,which);} #define FCHECK FALSE void get_weight(llint n,QD WEIGHT,int S) {QD nQD,nQDi,x1,x2,L1,L2,r1,r2,t; int wh1=whi[S],wh2=wlo[S],sp=SYMPOW[wh1],W=w[S]; QD_copy(W,QD_zero,nQD); nQD[0]=(double) n; QD_div(W,QD_one,nQD,nQDi); QD_mul(W,nQD,DECAY[sp],x1); if (WIGGLE[S][0]!=1.0) QD_mul(W,x1,WIGGLE[S],x1); if (x1[0]<=EXPAND0_LIM[wh1]) {QD_log(W,x1,L1); get_wt_powser(wh1,x1,L1,r1,W);} else get_wt_large(wh1,x1,r1,W,S); if ((FCHECK) && (r1[0]!=0.0)) {printf("v="); QD_output(W,16*W,x1); printf("r="); QD_output(W,16*W,r1); printf("u=ev(PH,v,600)-r; if (abs(u)>1.0e-50,[v,r,u]);\n");} QD_powi(W,nQDi,evalpt[wh1],t); QD_mul(W,r1,t,r1); if ((HECKE) && (sp&1)==0) QD_mul1(W,r1,(double) (sp/2),r1); if (DEBUG>=2) printf("MID %f %f\n",r1[0],WIGSQI[S][0]); if ((sp&1) && (WIGGLE[S][0]==1.0)) {QD_mulall(W,r1,2.0,WEIGHT); return;} if (WIGGLE[S][0]!=1.0) QD_mul(W,x1,WIGSQI[S],x2); else QD_copy(W,x1,x2); if (x2[0]<=EXPAND0_LIM[wh2]) {QD_log(W,x2,L2); get_wt_powser(wh2,x2,L2,r2,W);} else get_wt_large(wh2,x2,r2,W,S); if ((FCHECK) && (r2[0]!=0.0)) {printf("v="); QD_output(W,16*W,x2); printf("r="); QD_output(W,16*W,r2); printf("u=ev(PL,v,600)-r; if (abs(u)>1.0e-50,[v,r,u]);\n");} if ((sp&1)==0) QD_mul(W,r2,DECAY[sp],r2); QD_powi(W,nQDi,evalpt[wh2],t); QD_mul(W,r2,t,r2); QD_add(W,r1,r2,WEIGHT);} sympow-1.019/compute2.c0000644017361200001450000002023510442324213014636 0ustar tabbottcrontab#include "sympow.h" #define DEBUG (FALSE || GLOBAL_DEBUG) void special_value(int p,QD s,int sp) {QD t,u,rp,ip,C; int k,rpp=0,ipp=0; QD_copy(wmax,REAL_PERIOD,rp); QD_copy(wmax,IMAG_PERIOD,ip); QD_copy(wmax,COND[sp],C); if (VERBOSE>=2) {printf("rp: "); QD_output(wmax,16*wmax,rp); printf("ip: "); QD_output(wmax,16*wmax,ip);} if (HECKE) {switch (sp&3) /* L*(2*Pi)^[(sp-1)/2]/(ip)^(sp) for 3mod4 and ip->rp for 1*/ {case 0: QD_powi(p,rp,sp+2,t); QD_powi(p,QD_twopi,sp/2-1,u); QD_div(p,u,t,t); QD_mul(p,rp,t,t); QD_mul(p,ip,t,t); QD_powi(p,COND[sp],1+sp/4,u); QD_mul(p,t,u,t); QD_mul(p,s,t,s); return; /* L*(2*Pi)^(sp/2-1)/rp^(sp+2) * (rp*ip)*N^(1+sp/4) */ case 1: QD_powi(p,rp,sp,t); QD_powi(p,QD_twopi,(sp-1)/2,u); QD_div(p,u,t,t); QD_mul(p,s,t,s); return; case 2: QD_powi(p,ip,sp,t); QD_powi(p,QD_twopi,sp/2-1,u); QD_div(p,u,t,t); QD_mul(p,s,t,s); return; case 3: QD_powi(p,ip,sp,t); QD_powi(p,QD_twopi,(sp-1)/2,u); QD_div(p,u,t,t); QD_mul(p,s,t,s); return;}} switch(sp) {case 2: QD_mul(p,rp,ip,t); QD_mul(p,t,QD_twopi,t); QD_div(p,s,t,s); QD_mul1(p,s,(double) COND0,s); return; case 3: QD_powi(p,ip,3,t); QD_mul(p,t,rp,t); QD_div(p,s,t,s); QD_mul1(p,s,(double) COND0,s); QD_mul(p,s,QD_twopi,s); return; case 5: QD_sqr(p,rp,t); QD_mul(p,t,ip,t); QD_mul1(p,QD_twopi,(double) COND0,t); QD_sqr(p,rp,u); QD_mul(p,u,ip,u); QD_div(p,t,u,t); QD_powi(p,t,3,t); QD_mul(p,s,t,s); return; case 6: QD_mul(p,s,QD_twopi,s); QD_mul(p,s,QD_twopi,s); QD_mul(p,rp,ip,t); QD_div1(p,t,(double) COND0,t); QD_powi(p,t,6,t); QD_div(p,s,t,s); return; case 7: QD_mul1(p,QD_twopi,(double) COND0,t); QD_div(p,t,rp,t); QD_powi(p,t,6,t); QD_powi(p,ip,10,u); QD_div(p,t,u,t); QD_mul(p,s,t,s); return; case 9: QD_sqr(p,ip,t); QD_sqr(p,rp,u); QD_mul(p,u,rp,u); QD_mul(p,t,u,t); QD_mul1(p,QD_twopi,(double) COND0,u); QD_sqr(p,u,u); QD_div(p,u,t,t); QD_powi(p,t,5,t); QD_mul(p,s,t,s); return; default: switch(sp&3) {case 0: return; case 1: k=(sp+1)/2; rpp=(k*(k+1))/2; ipp=(k*(k-1))/2; QD_mul1(p,QD_twopi,(double) COND0,u); QD_div(p,u,ip,u); QD_powi(p,u,ipp,u); QD_powi(p,rp,rpp,t); QD_div(p,u,t,t); QD_mul(p,s,t,s); return; case 2: k=((sp/2)*(sp/2+1))/2; QD_mul(p,rp,ip,t); QD_div1(p,t,(double) COND0,t); QD_powi(p,t,k,t); QD_powi(p,QD_twopi,3*k-(sp/2+1)*(sp/2+1),u); QD_div(p,u,t,t); QD_mul(p,s,t,s); return; case 3: k=(sp+1)/2; rpp=(k*(k-1))/2; ipp=(k*(k+1))/2; QD_mul1(p,QD_twopi,(double) COND0,u); QD_div(p,u,rp,u); QD_powi(p,u,rpp,u); QD_powi(p,ip,ipp,t); QD_div(p,u,t,t); QD_mul(p,s,t,s); return;}}} static int sbinom(int a,int b) {int i; llint s; if (b&1) s=-1; else s=1; if (a==b) return (int) s; if (b>a/2) b=a-b; for (i=0;ia/2) b=a-b; for (i=0;i0) && (SYMPOW[whi[S]]==SYMPOW[whi[S-1]])) QD_copy(w[S],bn[S-1],bn[S]); else QD_mul(w[S],bp[S],bq[S],bn[S]); QD_mul(w[S],bn[S],WT,WT); QD_add(w[S],SUM[S],WT,SUM[S]); if (n500)) return ec_bsgs_ap_AB((-27*Ec4ll)%p,(-54*Ec6ll)%p,p); return ec_ap(Ec4,Ec6,p);} static void get_large_coeffs(llint p,int pnum) {int S,ap; if ((COND0%p)==0) {make_primep_coeffs(0,p,p+64); return;} if (pnum0) && (SYMPOW[whi[S]]==SYMPOW[whi[S-1]])) QD_copy(w[S],coeff_primepower[0][1][S-1],coeff_primepower[0][1][S]); else pth_coeff_from_ap(w[S],p,ap,SYMPOW[whi[S]],coeff_primepower[0][1][S]);} if (AP_SAVE) {apsave[pnum]=ap; if (pnum>AP_SAVE) AP_SAVE=pnum;}} static void addup(llint n,QD *bp,QD *bq) {int S; QD WT,t; for(S=0;SY) Y=Abs(X[0]);} if ((NUM_WIGS[S]) && (Log10(Y)<(double) -digits(wprec[S]))) sum_print(S,1); if (Log10(Abs(SUM[S][0]))<(double) -digits(wprec[S])) ZERO[z++]=S+1;} printf("\n"); if ((ZERO[0]!=0) && !ZEROCHECK) {printf("Near Zero: "); for(i=0;i=2) printf("BOUNDS %lli %i\n",BOUND,SQBND); for(S=0;S=2) printf("made pp\n"); for (s=0;sSQBND) {PSIZE=(llint) SQBND; PSIZE=PSIZE*PSIZE/2;} get_primes_ll(pi,PSIZE,auxp); PMAX=pi+PSIZE; pnum=0; ptotal=0; while (piPMAX) {get_primes_ll(pi+2,PSIZE,auxp); pnum=0; PMAX+=PSIZE; if (VERBOSE) printf("At prime %lli %.16f\n",pi,SUM[0][0]); fflush(stdout);} get_large_coeffs(pi,ptotal); mult=1; multpi=pi; while (multpiNEXT)) {NEXT+=BOUND/32; QD_copy(wmax,QD_zero,CHECK); QD_mul(w[0],SUM[0],SCALE,CHECK); if (MANIN_TWIST!=1) QD_mul1(w[0],CHECK,(double) MANIN_TWIST,CHECK); QD_mul1(w[0],CHECK,(double) EVEN_TOP,CHECK); QD_div1(w[0],CHECK,(double) EVEN_BOTTOM,CHECK); if (VERBOSE) {printf("At %lli: ",pi); QD_output(w[0],wprec[0],CHECK);} QD_round(wmax,CHECK,NOW); QD_sub(wmax,CHECK,NOW,DIFF); if (Abs(DIFF[0])<0.01) {QD_sub(wmax,NOW,LAST,DIFF); if (DIFF[0]!=0.0) {QD_copy(wmax,NOW,LAST); last=1;} else {last++; if ((last==3) && (MD_SPEED!=0.0)) {QD_mul(wmax,TW_EFF,NOW,CHECK); if (MANIN_TWIST!=1) QD_div1(wmax,CHECK,(double) MANIN_TWIST,CHECK); if (MANIN!=1) QD_mul1(wmax,CHECK,(double) MANIN,CHECK); QD_round(wmax,CHECK,CHECK); printf("Modular Degree is "); QD_intout_noplus(CHECK); printf("\n"); goto DONE;}}} else {QD_copy(wmax,QD_zero,LAST); last=0;}}} if (MODDEG) {QD_copy(wmax,QD_zero,CHECK); QD_mul(w[0],SUM[0],SCALE,CHECK); if (MANIN_TWIST!=1) QD_mul1(w[0],CHECK,(double) MANIN_TWIST,CHECK); QD_mul1(w[0],CHECK,(double) EVEN_TOP,CHECK); QD_div1(w[0],CHECK,(double) EVEN_BOTTOM,CHECK); if (VERBOSE) {printf("At end "); QD_output(w[0],wprec[0],CHECK);} QD_round(wmax,CHECK,NOW); QD_sub(wmax,CHECK,NOW,DIFF); if (Abs(DIFF[0])<0.05) {QD_mul(wmax,TW_EFF,NOW,CHECK); if (MANIN_TWIST!=1) QD_div1(wmax,CHECK,(double) MANIN_TWIST,CHECK); if (MANIN!=1) QD_mul1(wmax,CHECK,(double) MANIN,CHECK); QD_round(wmax,CHECK,CHECK); printf("Modular Degree is "); QD_intout_noplus(CHECK); printf("\n"); goto DONE;} errorit("Not converging to an integer in modular degree\n");} else if (!ANAL_RANK) results(); if (ANAL_RANK==-1) {results(); errorit("Not programmed to test if 0\n");} DONE: f=SUM[0][0]; free(QD_one_array); free(auxp); free_arrays(SQBND,NUM_PRIMES); return f;} sympow-1.019/conductors.c0000644017361200001450000002650610442324213015272 0ustar tabbottcrontab#include "sympow.h" #define DEBUG (FALSE || GLOBAL_DEBUG) #define tlc tame_local_conductor #define wlc wild_local_conductor int tame_local_conductor(int type,int sympow) {if (sympow<=0) return 0; switch(type) {case 0: errorit("case 0 in tame_local_conductor"); /* good */ case 1: return sympow; /* multiplicative */ case 29: case 30: case 31: /* potentially multiplicative */ if (sympow&1) return sympow+1; else return sympow; case 2: case 16: case 17: /* C2 */ if (sympow&1) return sympow+1; else return 0; case 3: case 14: case 18: /* C3 */ switch(sympow%3) {case 0: return (sympow*2)/3; case 1: return sympow+1-(sympow-1)/3; case 2: return sympow+1-(sympow+1)/3;} case 4: case 22: case 23: /* C4 */ switch(sympow&3) {case 1: case 3: return sympow+1; case 0: return sympow/2; case 2: return 1+sympow/2;} case 6: case 15: case 19: case 20: case 21: /* C6 */ switch(sympow%6) {case 1: case 3: case 5: return sympow+1; case 0: return (sympow*2)/3; case 4: return sympow+1-(sympow-1)/3; case 2: return sympow+1-(sympow+1)/3;} case 8: case 9: case 10: /* Q8 */ switch(sympow&3) {case 1: case 3: return (sympow+1); case 0: return (3*sympow)/4; case 2: return (3*sympow+6)/4;} case 12: case 13: /* C3x|C4 */ switch(sympow%12) {case 1: case 3: case 5: case 7: case 9: case 11: return sympow+1; case 0: return (5*sympow)/6; case 2: return (5*sympow+8)/6; case 4: return (5*sympow+4)/6; case 6: return (5*sympow)/6+1; case 8: return (5*sympow+2)/6; case 10: return (5*sympow+10)/6;} case 24: case 25: case 26: case 27: /* SL2F3 */ switch(sympow%12) {case 1: case 3: case 5: case 7: case 9: case 11: return sympow+1; case 0: return (11*sympow)/12; case 2: return (11*sympow+14)/12; case 4: return (11*sympow+16)/12; case 6: return (11*sympow+6)/12; case 8: return (11*sympow+8)/12; case 10: return (11*sympow+22)/12;} default: printf("%i ",type); errorit("Bad type in tame_local_conductor");} return -1;} int wild_local_conductor(int type,int m) {if (m<=0) return 0; switch(type) {case 0: case 1: case 2: case 3: case 4: case 6: case 31: return 0; /* p>5 */ case 8: return tlc(8,m)+tlc(2,m)/2; case 9: return tlc(8,m)+tlc(2,m); case 10: return tlc(8,m)+tlc(4,m)+tlc(2,m); case 12: return tlc(3,m)/2; case 13: return 3*tlc(3,m)/2; case 14: case 15: case 18: case 19: return tlc(3,m); case 16: case 20: return tlc(2,m); case 17: case 21: return 2*tlc(2,m); case 22: case 23: return 2*tlc(4,m)+tlc(2,m); case 24: return (2*tlc(8,m)+tlc(2,m))/6; case 25: return (tlc(8,m)+2*tlc(2,m))/3; case 26: return (tlc(8,m)+5*tlc(2,m))/3; case 27: return (10*tlc(8,m)+5*tlc(2,m))/6; case 29: return 2*tlc(2,m); case 30: return tlc(2,m); default: printf("%i ",type); errorit("Bad type in wild_local_conductor");} return -1;} void badprimetype_output(int x,llint p) {switch(x) {case 0: printf("C1 ADDITIVE REDUCTION\n"); break; case 1: printf("C1 MULTIPLICATIVE REDUCTION\n"); break; case 2: case 3: case 4: case 6: {if ((p%x)==1) printf("C%i abelian\n",x); else printf("C%i nonabelian\n",x); break;} case 8: printf("Q8 v2(N)=5\n"); break; case 9: printf("Q8 v2(N)=6\n"); break; case 10: printf("Q8 v2(N)=8\n"); break; case 12: printf("C3x|C4 v3(N)=3\n"); break; case 13: printf("C3x|C4 v3(N)=5\n"); break; case 14: printf("C3 p=3 abelian\n"); break; case 15: printf("C6 p=3 abelian\n"); break; case 16: printf("C2 p=2 v2(N)=4\n"); break; case 17: printf("C2 p=2 v2(N)=6\n"); break; case 18: printf("C3 p=3 nonabelian\n"); break; case 19: printf("C6 p=3 nonabelian\n"); break; case 20: printf("C6 p=2 v2(N)=4\n"); break; case 21: printf("C6 p=2 v2(N)=6\n"); break; case 22: printf("C4 p=2 abelian\n"); break; case 23: printf("C4 p=2 nonabelian\n"); break; case 24: printf("SL2F3 v2(N)=3\n"); break; case 25: printf("SL2F3 v2(N)=4\n"); break; case 26: printf("SL2F3 v2(N)=6\n"); break; case 27: printf("SL2F3 v2(N)=7\n"); break; case 29: printf("C2 p=2 MULTIPLICATIVE v2(N)=6\n"); break; case 30: printf("C2 p=2 MULTIPLICATIVE v2(N)=4\n"); break; case 31: printf("C2 MULTIPLICATIVE\n"); break; default: errorit("Unknown badprime type");}} static int bpt_at(double p)/* p>3.0 */ {int v4,v6,vd; if (p<=3.0) errorit("prime too small in bpt_at"); if (!QD_is_divisible(Edisc,p)) return 0; if (!QD_is_divisible(Ec4,p)) return 1; v4=QD_valuation(Ec4,p); v6=QD_valuation(Ec6,p); vd=QD_valuation(Edisc,p); if ((v4==2) && (v6==3) && (vd>6)) return 31; if (vd==6) return 2; if ((vd==2) || (vd==10)) return 6; if ((vd==3) || (vd==9)) return 4; if ((vd==4) || (vd==8)) return 3; errorit("bad valuation in bpt_ap"); return -1;} static int ecfp3(int c4t,int c6t,int Dt) {int c4r,c6r; if (DEBUG) printf("ecfp3 %i %i %i\n",c4t,c6t,Dt); if ((Dt%3)!=0) return 0; if ((c6t%27)!=0) return 1; c4r=(c4t/9)%3; c6r=(c6t/27)%9; if (c4r==0) {if (c6r==0) {if ((c4t%81)==0) return 5; return 4;} switch (c6r) {case 1: case 2: case 7: case 8: return 3; case 3: case 6: return 5; case 4: case 5: return 2;}} if (c4r==1) {switch(c6r) {case 0: return 2; case 1: case 3: case 6: case 8: return 3; case 2: case 4: case 5: case 7: return 4;}} if (c4r==2) {switch(c6r) {case 0: return 2; case 2: case 7: return 2; case 1: case 3: case 4: case 5: case 6: case 8: return 3;}} return 0; } static int bpt_at3() {int v4,v6,vd,t,u,c4,c6,D,c4t,c6t,Dt; if (DEBUG) printf("bpt_at3\n"); if (!QD_is_divisible(Edisc,3.0)) return 0; if (!QD_is_divisible(Ec4,3.0)) {fp3=1; return 1;} v4=QD_valuation(Ec4,3.0); v6=QD_valuation(Ec6,3.0); vd=QD_valuation(Edisc,3.0); c4=QD_modi(Ec4,387420489); c6=QD_modi(Ec6,387420489); D=QD_modi(Edisc,387420489); if (DEBUG) printf("%i %i %i\n",c4,c6,D); if ((v4==2) && (v6==3) && (v6!=5) && (vd>6)) {fp3=2; return 31;} if ((v4>=2) && ((v6>=3) && (v6!=5)) && (vd==6)) {fp3=2; return 2;} if ((v4<2) || (v6<3) || (v6==5) || (vd<6)) {c4t=c4; c6t=c6; Dt=D;} else {c4t=c4/9; c6t=(c6-387420489)/(-27); Dt=D/729;} fp3=ecfp3(c4t,c6t,Dt); ASSERT(fp3>=2); if (fp3==2) return 4; if (fp3==3) return 12; if (fp3==5) return 13; if (vd&3) t=15; else t=14; if (((c6t%243)==0) && ((c4t%81)==54)) t+=4; if ((c4t%27)==9) {u=c6t%243; if ((u==54) || (u==189)) t+=4;} return t; } static int ecfp2(int c4,int c6) {int c4r,c6r; c4r=c4&15; c6r=c6&15; if ((c4r&3)==1) {switch(c6r&3) {case 0: return 6; case 1: return 4; case 3: return 3; case 2: {if (c4r==1) switch(c6r) {case 2: return 4; case 6: case 10: return 5; case 14: return 3;} if (c4r==5) switch(c6r) {case 2: return 3; case 6: return 2; case 10: case 14: return 4;} if (c4r==9) switch(c6r) {case 2: case 14: return 5; case 6: return 3; case 10: return 4;} if (c4r==13) switch(c6r) {case 2: case 6: return 4; case 10: return 3; case 14: return 2;}}}} if ((c4r&3)==2) {switch(c6r&3) {case 1: return 3; case 2: return 6; case 3: return 4; case 0: if (c6r&7) return 7; else return 8;}} if ((c4r&3)==3) {switch(c6r&3) {case 0: return 5; case 1: return 2; case 2: return 7; case 3: return 4;}} if (((c4r&3)==0) && ((c6r&3)!=0)) {switch(c6r&3) {case 1: return 2; case 3: return 4;}} c4r=(c4/4)&1; c6r=(c6/4)&3; if (c6r==3) return 4; if (c4r) return 3; return 2; } static int bpt_at2() {int v4,v6,vd,e,c4,c6,D,c4t,c6t,Dt,t1=FALSE; if (!QD_is_divisible(Edisc,2.0)) {fp2=0; return 0;} if (!QD_is_divisible(Ec4,2.0)) {fp2=1; return 1;} v6=QD_valuation(Ec6,2.0); if (v6==3) {fp2=0; return 0;} vd=QD_valuation(Edisc,2.0); e=minimum(v6/3,vd/6); v4=QD_valuation(Ec4,2.0); c4=QD_modi(Ec4,1<<27); c6=QD_modi(Ec6,1<<27); D=QD_modi(Edisc,1<<27); v4-=2*e; v6-=3*e; if ((v4==2) || (v4==3) || (v6==4)) e--; c4t=c4>>(2*e); c6t=c6>>(3*e); Dt=D>>(6*e); if ((c6t&31)!=0) {if ((Dt&1)==0) {if (e&1) {fp2=6; return 29;} fp2=4; return 30;} else {if (e&1) {fp2=6; return 17;} fp2=4; return 16;}} fp2=ecfp2(c4t/16,c6t/32); if (fp2==4) {fp2=ecfp2(c4t/16,-c6t/32); t1=TRUE;} ASSERT(fp2>=2); ASSERT(fp2!=4); if (fp2==2) {if ((e&1)==0) {if (t1) {fp2=4; return 20;} return 3;} fp2=6; return 21;} if (fp2==3) {if ((e&1)==0) {if (t1) {fp2=4; return 25;} return 24;} fp2=6; return 26;} if (fp2==5) {if ((e&1)==0) return 8; fp2=6; return 9;} if (fp2==6) {if ((e&1)==1) {fp2=5; return 8;} return 9;} if (fp2==7) return 27; if (fp2==8) {if ((c6t&511)==0) return 10; if ((c4t&127)==32) return 23; return 22;} return -1; } static void CMUL(llint p) /* multiply COND0 by p and check if overflow */ {if (((COND0*p)/p)!=COND0) errorit("Curve conductor is too large"); COND0*=p;} int do_badprime(llint p) /* E is a minimal model */ {int f=0,i; if (p>3) {f=bpt_at((double) p); if (f==1) CMUL(p); else CMUL(p*p);} if (p==3) {f=bpt_at3(); for (i=0;i=10) && (m<=20)) return 0; m=m%10; if (m>=4) return 0; return m;} void compute_conductor(int m) {int i,T,W; llint P; QD A; QDpoly v; char STR[4][4]={"th","st","nd","rd"}; QD_copy(wmax,QD_one,COND[m]); for (i=0;badprimes[i]!=0;i++) {T=tlc(badprimetype[i],m); P=badprimes[i]; W=wlc(badprimetype[i],m); if (VERBOSE) printf("sp %i: Conductor at %lli is %i+%i, root number is %i\n", m,P,T,W,local_rootno(i,badprimes[i],m)); QD_copy(wmax,QD_zero,A); A[0]=(double) P; QD_powi(wmax,A,T+W,A); QD_mul(wmax,COND[m],A,COND[m]); if (VERBOSE) {printf("sp %i: Euler factor at %lli is ",m,P); euler_factor(P,m,&v); QDpoly_intout(v); delQDpoly(&v);}} if (VERBOSE) {printf("%i%s sym power conductor is ",m,STR[lkup(m)]); QD_intout_noplus(COND[m]); printf(", global root number is %i\n",global_rootno(m));}} static int prim_part(int CM) {if ((CM==-27) || (CM== -12)) return 3; if (CM==-28) return 7; if ((CM==-16) || (CM==-4) || (CM==-8)) return 2; return -CM;} static int f(int CM) {if ((CM==-16) || (CM==-4)) return 2; if (CM==-8) return 3; return 1;} void compute_conductor_hecke(int m) {int i,T,W,u; llint P=0; QD A; QDpoly v; char STR[4][4]={"th","st","nd","rd"}; if (!CM_CASE) errorit("not CM case in compute_conductor_hecke\n"); QD_copy(wmax,QD_one,COND[m]); for (i=0;badprimes[i]!=0;i++) {T=tlc(badprimetype[i],m)-tlc(badprimetype[i],m-2); W=wlc(badprimetype[i],m)-wlc(badprimetype[i],m-2); P=badprimes[i]; if ((m&3)==0) {u=prim_part(CM_CASE); if (P==u) T+=f(CM_CASE);} if ((m&3)==2) {u=prim_part(CM_CASE); if (P==u) T-=f(CM_CASE);} if (VERBOSE) printf("sp %i: Conductor at %lli is %i+%i\n",m,P,T,W); QD_copy(wmax,QD_zero,A); A[0]=(double) P; QD_powi(wmax,A,T+W,A); QD_mul(wmax,COND[m],A,COND[m]); if (VERBOSE) {printf("sp %i: Euler factor at %lli is ",m,P); euler_factor(P,m,&v); QDpoly_intout(v); delQDpoly(&v);}} if (VERBOSE) {printf("%i%s sym power conductor is ",m,STR[lkup(m)]); QD_intout_noplus(COND[m]); printf("\n");}} int get_tame_conductor(llint p,int m) {int i; if ((COND0%p)!=0) return 0; if (HECKE) errorit("Tame conductor for Hecke?"); for (i=0;badprimes[i]!=p;i++); return(tlc(badprimetype[i],m));} int get_wild_conductor(llint p,int m) {int i; if ((COND0%p)!=0) return 0; if (HECKE) errorit("Wild conductor for Hecke?"); for (i=0;badprimes[i]!=p;i++); return(wlc(badprimetype[i],m));} int get_conductor(llint p,int m) {int T,W,i,u; if ((COND0%p)!=0) return 0; for (i=0;badprimes[i]!=p;i++); if (!HECKE) return(tlc(badprimetype[i],m)+wlc(badprimetype[i],m)); T=tlc(badprimetype[i],m)-tlc(badprimetype[i],m-2); W=wlc(badprimetype[i],m)-wlc(badprimetype[i],m-2); if ((m&3)==0) {u=prim_part(CM_CASE); if (p==u) T+=f(CM_CASE);} if ((m&3)==2) {u=prim_part(CM_CASE); if (p==u) T-=f(CM_CASE);} return T+W;} sympow-1.019/Configure0000755017361200001450000001052610442324213014605 0ustar tabbottcrontab#! /bin/sh if [ "$1" != "" ]; then echo "**ERROR**: Configure does not take any options for SYMPOW"; exit; fi FILE="Makefile.new" CONFIG="config.h" RM=`which \rm` if [ -z "$RM" ]; then echo "**ERROR**: Could not find rm"; exit; fi $RM -f $FILE $RM -f $CONFIG VERSION=1.019 echo "#define VERSION \"$VERSION\"" >> $CONFIG echo "VERSION = $VERSION" >> $FILE echo "#define RM \"$RM\"" >> $CONFIG GREP=`which \grep` && echo "#define GREP \"$GREP\"" >> $CONFIG if [ -z "$GREP" ]; then echo "*WARNING*: Could not find grep --- will not be able to build new_data"; echo "#define GREP grep" >> $CONFIG fi GP=`which \gp` && echo "#define GP \"$GP\"" >> $CONFIG if [ -z "$GP" ]; then echo "*WARNING*: Could not find gp --- will not be able to build new_data"; echo "#define GP gp" >> $CONFIG fi SED=`which \sed` && echo "#define SED \"$SED\"" >> $CONFIG if [ -z "$SED" ]; then echo "*WARNING*: Could not find sed --- will not be able to build new_data"; echo "#define SED sed" >> $CONFIG fi [ -n "$GREP" ] && [ -n "$GP" ] && [ -n "$SED" ]\ && echo "#define NEW_DATA" >> $CONFIG SH=`which \sh` && echo "#define SH \"$SH\"" >> $CONFIG if [ -z "$SH" ]; then echo "**ERROR**: Could not find sh"; exit; fi CC=`which \cc` && echo "CC = $CC" >> $FILE if [ -z "$CC" ]; then echo "**ERROR**: Could not find cc"; exit; fi UNAME=`which \uname` if [ -z "$UNAME" ]; then echo "**ERROR**: Could not find uname"; exit; fi MACH=`"$UNAME" -m` for x in ix86 i386 i486 i586 i686 x86_64 ia64 do if [ "$MACH" = "$x" ]; then echo "You appear to have a $x based system --- using fpu.c" DEFS="-Dx86" fi done if [ -z "$DEFS" ]; then echo "You do not appear to have an x86 based system --- not using fpu.c" fi echo "DEFS = $DEFS" >> $FILE OPT="-O3" && echo "OPT = $OPT" >> $FILE echo "SRCS1 = analrank.c analytic.c compute.c compute2.c fpu.c help.c" >> $FILE echo "SRCS2 = conductors.c disk.c ec_ap.c ec_ap_bsgs.c ec_ap_large.c" >> $FILE echo "SRCS3 = eulerfactors.c factor.c generate.c init_curve.c main.c" >> $FILE echo "SRCS4 = moddeg.c periods.c prepare.c QD.c rootno.c util.c" >> $FILE echo "SRCS = \$(SRCS1) \$(SRCS2) \$(SRCS3) \$(SRCS4)" >> $FILE echo "OBJS = \$(SRCS:.c=.o)" >> $FILE echo "OTHERS = new_data *.gp COPYING README Configure" >> $FILE echo "HEADERS = sympow.h" >> $FILE echo "SRC = \$(SRCS) \$(HEADERS) \$(OTHERS)" >> $FILE echo "TILDES = *~ datafiles/*~" >> $FILE df="datafiles" echo "DATAFILES = $df/*M.txt $df/*S.txt $df/param_data" >> $FILE echo "RM = $RM" >> $FILE CP=`which \cp` && echo "CP = $CP" >> $FILE if [ -z "$CP" ]; then echo "**ERROR**: Could not find cp"; exit; fi MKDIR=`which \mkdir` && echo "MKDIR = $MKDIR" >> $FILE if [ -z "$MKDIR" ]; then echo "**ERROR**: Could not find mkdir"; exit; fi TOUCH=`which \touch` && echo "TOUCH = $TOUCH" >> $FILE if [ -z "$TOUCH" ]; then echo "**ERROR**: Could not find touch"; exit; fi TAR=`which \tar` && echo "TAR = $TAR" >> $FILE if [ -z "$TAR" ]; then echo "*WARNING*: Could not find tar --- source/archive omitted from Makefile"; else echo "TARS = sympow.tar sympow.src.tar" >> $FILE echo "WDIR = SYMPOW-\$(VERSION)" >> $FILE && echo "" >> $FILE fi echo "all: sympow" >> $FILE echo "sympow: \$(OBJS)" >> $FILE echo " \$(MKDIR) -p datafiles" >> $FILE echo " \$(TOUCH) datafiles/param_data" >> $FILE LINE="\$(CC) \$(OPT) \$(CFLAGS) -o \$@ \$(DEFS) \$(OBJS) \$(LIBS)" echo " $LINE" >> $FILE echo "%.o : %.c \$(HEADERS) Makefile" >> $FILE echo " \$(CC) \$(OPT) \$(CFLAGS) \$(DEFS) -c -o \$@ \$<" >> $FILE echo "clean:" >> $FILE echo " \$(RM) -f \$(OBJS) sympow \$(TILDES) \$(TARS)" >> $FILE if [ -n "$TAR" ]; then echo "source:" >> $FILE echo " \$(MKDIR) \$(WDIR)" >> $FILE echo " \$(CP) -f \$(SRC) \$(WDIR)" >> $FILE echo " \$(TAR) cf sympow.src.tar \$(WDIR)/*" >> $FILE echo " \$(RM) -rf \$(WDIR)" >> $FILE echo "archive:" >> $FILE echo " \$(MKDIR) \$(WDIR)" >> $FILE echo " \$(CP) -f \$(SRC) \$(WDIR)" >> $FILE echo " \$(MKDIR) \$(WDIR)/datafiles" >> $FILE echo " \$(CP) -f \$(DATAFILES) \$(WDIR)/datafiles" >> $FILE echo " \$(TAR) cf sympow.tar \$(WDIR)/*" >> $FILE echo " \$(RM) -rf \$(WDIR)" >> $FILE fi $RM -f Makefile $CP -f Makefile.new Makefile $RM -f Makefile.new echo "Makefile has been re-made. Use make if you wish to build SYMPOW" echo "" echo "**ATTENTION** If you wish build SYMPOW, please ensure beforehand" echo "that the various licenses of your C compiler, linker, assembler, etc." echo "allow you to create a derived work based on SYMPOW and your C libraries" sympow-1.019/COPYING0000644017361200001450000000346210442324213013772 0ustar tabbottcrontab Copyright (c) 2005-6, Mark Watkins, Institut Henri Poincare, University of Bristol. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistribution of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistribution in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * If redistribution is done as a part of a compilation that has a more restrictive license (such as the GPL), then the fact that SYMPOW has a less restrictive license must be made clear to the recipient. For example, a line like (include bracketed text if SYMPOW is modified): "This compilation includes [a modification of] SYMPOW whose [original] code has a less-restrictive license than the entire compilation." should appear in a suitable place in the COPYING and/or LICENSE file. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. sympow-1.019/disk.c0000644017361200001450000001315710442324213014037 0ustar tabbottcrontab#include "sympow.h" #define DEBUG (FALSE || GLOBAL_DEBUG) int CHEAT=FALSE; static void read_file_mesh_bin(FILE *A,int which) {int i,j; QD **P,*Q; if (!GLOBAL) return; P=TABLE[which]=malloc(MESH_COUNT[which]*sizeof(QD*)); for(i=0;i>=1; Q=P[i]=malloc(AB*sizeof(QD)); for(j=0;j1) S[3]='0'+dv;} else if (((sp&3)==0) && CM_CASE) {if (2*ep==sp) S[3]='l'; else S[3]='h';} else {if (2*ep==sp) S[3]='L'; else S[3]='H';} if (HECKE && dv) {TACKS[which]=malloc(dv*sizeof(QD)); TACKON[which]=dv;} else if (dv<=sp/2) TACKON[which]=0; else {TACKS[which]=malloc((dv-sp/2)*sizeof(QD)); TACKON[which]=dv-sp/2;} S[4]=0; F=fopen("datafiles/param_data","r"); strcpy(U,S); if (ANAL_RANK) {if (dv>0) U[0]='A'; else U[0]='m';} if (MODDEG) {if (HECKE) U[0]='m'; else U[0]='M';} while (1) {if (!getline0(F,LINE,64)) {printf("**ERROR** %s not found in param_data file\n",S); if (!HECKE) printf("It can be added with './sympow -new_data %i",sp); else printf("It can be added with './sympow -new_data %i",ep); if ((sp&1) || HECKE) printf("d%i",dv); if ((HECKE) && (sp>1)) printf("h"); if ((CM_CASE) && ((sp&3)==0)) printf("c"); printf("'\n"); exit(-1);} if ((S[0]==LINE[0]) && (S[1]==LINE[1]) && (S[2]==LINE[2]) && (S[3]==LINE[3]) && !assure_line(LINE)) {printf("Problem with datafiles/param_data for %s\n",S); errorit("datafiles/param_data entry corrupted!");} STR=strtok(LINE,TOK); if (!strcmp(STR,S)) {if (VERBOSE>=2) printf("S Found: %s\n",S); TOO_BIG[which]=atof(strtok(NULL,TOK)); STEP_SIZE[which]=QD_2pow(atoi(strtok(NULL,TOK))); ms=atoi(strtok(NULL,TOK)); CHEAT=FALSE; break;} if (!strcmp(STR,U)) {if (VERBOSE>=2) printf("U Found: %s\n",U); TOO_BIG[which]=atof(strtok(NULL,TOK)); STEP_SIZE[which]=QD_2pow(atoi(strtok(NULL,TOK))); ms=atoi(strtok(NULL,TOK)); CHEAT=TRUE; break;}} EXPAND0_LIM[which]=31.5*STEP_SIZE[which]; fclose(F); return 32*ms;} void load_files(int which,int sp,int ep,int dv) {FILE *A,*N; char NM[32],NAME[32]="datafiles/P"; int dl=9; if (DEBUG) printf("load_files %i %i %i %i\n",which,sp,ep,dv); SYMPOW[which]=sp; evalpt[which]=ep; derivative[which]=dv; if (!GLOBAL) return; MESH_COUNT[which]=get_params(which,sp,ep,dv); if (sp<10) {NAME[2+dl]='0'; NAME[3+dl]='0'+sp;} else {NAME[2+dl]='0'+sp/10; NAME[3+dl]='0'+(sp%10);} NAME[5+dl]='M'; if (CHEAT) {if (ANAL_RANK) {if (dv>0) NAME[1+dl]='A'; else NAME[1+dl]='m';} else if (HECKE) NAME[1+dl]='m'; else NAME[1+dl]='M';} if (sp&1) {if (dv==0) NAME[4+dl]='E'; if (dv==1) NAME[4+dl]='O'; if (dv>1) NAME[4+dl]='0'+dv;} else {if (2*ep==sp) NAME[4+dl]='L'; else NAME[4+dl]='H';} NAME[6+dl]='.'; NAME[7+dl]='b'; NAME[8+dl]='i'; NAME[9+dl]='n'; NAME[10+dl]=0; if (((sp&3)==0) && CM_CASE) NAME[4+dl]+=('a'-'A'); if (VERBOSE>=2) printf("%i Reading %s\n",which,NAME); A=fopen(NAME,"r"); if (!A) {strcpy(NM,NAME); NM[7+dl]='t'; NM[8+dl]='x'; NM[9+dl]='t'; N=fopen(NM,"r"); if (VERBOSE) printf("Creating %s from %s\n",NAME,NM); txt2bin(MESH_COUNT[which],NAME,N); A=fopen(NAME,"r"); fclose(N);} read_file_mesh_bin(A,which); fclose(A); NAME[5+dl]='S'; NAME[7+dl]='t'; NAME[8+dl]='x'; NAME[9+dl]='t'; if (VERBOSE>=2) printf("%i Reading %s\n",which,NAME); A=fopen(NAME,"r"); read_file_series(A,which); fclose(A);} void load_files_hecke(int which,int sp,int ep,int dv) {FILE *A,*N; char NM[32],NAME[32]="datafiles/H"; int dl=9; if (DEBUG) printf("load_files_hecke %i %i %i %i\n",which,sp,ep,dv); if (ep==1) {load_files(which,1,1,dv); return;} SYMPOW[which]=sp; evalpt[which]=ep; derivative[which]=dv; if (!GLOBAL) return; MESH_COUNT[which]=get_params(which,sp,ep,dv); if (ep<10) {NAME[2+dl]='0'; NAME[3+dl]='0'+ep;} else {NAME[2+dl]='0'+ep/10; NAME[3+dl]='0'+(ep%10);} NAME[5+dl]='M'; if (CHEAT) NAME[1+dl]='m'; if (dv==0) NAME[4+dl]='E'; if (dv==1) NAME[4+dl]='O'; if (dv>1) NAME[4+dl]='0'+dv; NAME[6+dl]='.'; NAME[7+dl]='b'; NAME[8+dl]='i'; NAME[9+dl]='n'; NAME[10+dl]=0; if (VERBOSE>=2) printf("%i Reading %s\n",which,NAME); A=fopen(NAME,"r"); if (!A) {strcpy(NM,NAME); NM[7+dl]='t'; NM[8+dl]='x'; NM[9+dl]='t'; N=fopen(NM,"r"); if (VERBOSE) printf("Creating %s from %s\n",NAME,NM); txt2bin(MESH_COUNT[which],NAME,N); A=fopen(NAME,"r"); fclose(N);} read_file_mesh_bin(A,which); fclose(A); NAME[5+dl]='S'; NAME[7+dl]='t'; NAME[8+dl]='x'; NAME[9+dl]='t'; if (VERBOSE>=2) printf("%i Reading %s\n",which,NAME); A=fopen(NAME,"r"); read_file_series(A,which); fclose(A);} int getline0(FILE *F,char *v,int l) {GET=fgets(v,l,F); if (NULL==GET) return(0); return(1);} sympow-1.019/ec_ap_bsgs.c0000644017361200001450000001602710442324213015171 0ustar tabbottcrontab#include "sympow.h" #define DEBUG (FALSE || GLOBAL_DEBUG) typedef struct {int x,y; int i;} AP_pt; #define MUL(x,y,z,p) z=(((llint) x)*((llint) y))%p #define INV(x,i,p)\ {int rr=0,ss=1,cc,aa=p,bb=x; while (1)\ {cc=aa/bb; aa-=bb*cc;\ if (aa==0) {if (bb>0) i=ss; else i=-ss; break;} rr-=cc*ss;\ cc=bb/aa; bb-=aa*cc;\ if (bb==0) {if (aa>0) i=rr; else i=-rr; break;} ss-=cc*rr;}} #define NORMALISE(x,p) while ((x)>=(p)) (x)-=(p); while ((x)<0) (x)+=(p) #define FROM_LINE(P,Q,R,s,p)\ {int T,x1; AP_pt V;\ MUL(s,s,T,p); V.x=T-(P.x+Q.x); NORMALISE(V.x,p);\ x1=P.x-V.x; MUL(x1,s,T,p); V.y=T-P.y; NORMALISE(V.y,p); *(R)=V;} static int ec_AP_pt_double(int a4,AP_pt P,AP_pt *R,int p) {int T,n,i,s,tt; /* NORMALISE(P.x,p); NORMALISE(P.y,p); */ if (P.y==0) return TRUE; MUL(P.x,P.x,T,p); n=T+T+T+a4; NORMALISE(n,p); tt=P.y+P.y; INV(tt,i,p); MUL(n,i,s,p); FROM_LINE(P,P,R,s,p); return FALSE;} static int ec_AP_pt_add(int a4,AP_pt P,AP_pt Q,AP_pt *R,int p) {int Ld,Ln,i,s; /* NORMALISE(P.x,p); NORMALISE(P.y,p); etc. */ if (P.x==Q.x) {if (P.y==Q.y) return ec_AP_pt_double(a4,P,R,p); return TRUE;} Ld=P.x-Q.x; Ln=P.y-Q.y; /* allow Ld to be negative */ INV(Ld,i,p); MUL(Ln,i,s,p); FROM_LINE(P,Q,R,s,p); return FALSE;} #define ADDI(P,Q,R,p,i) {int s; MUL(P.y-Q.y,i,s,p); FROM_LINE(P,Q,R,s,p);} #define DOUBLEI(a4,P,R,p,i)\ {int TT,nn,s; MUL(P.x,P.x,TT,p); nn=TT+TT+TT+a4;\ MUL(nn,i,s,p); FROM_LINE(P,P,R,s,p);} static int ec_AP_pt_mult(int a4,AP_pt P,int n,AP_pt *R,int p) {int m=n; AP_pt Q=P,T,U; int z=TRUE; /* P is not O */ if (n==0) return TRUE; if (n==1) {*R=P; return FALSE;} if (m&1) {U=Q; z=FALSE;} while (m) {m=m>>1; if (ec_AP_pt_double(a4,Q,&T,p)) break; Q=T; if (m&1) {if (z) {U=Q; z=FALSE;} else {z=ec_AP_pt_add(a4,Q,U,&T,p); if (!z) U=T;}}} if (!z) *R=U; return z;} static int ec_AP_pt_order_from_mult(int a4,AP_pt P,int m,int pr) {int i,e,k,t; int o=1,n=m,p,pe; AP_pt Q=P,R; LIST f; f.p[0]=0; ifactor(n,&f,1,1000); NORMALISE(Q.x,pr); NORMALISE(Q.y,pr); for (i=0;f.p[i]!=0;i++) {p=f.p[i]; e=f.e[i]; for (t=0;tx>B->x) #define SWAP_VARS(type,A,B) {type _ttemmp; _ttemmp=A; A=B; B=_ttemmp;} #define SWAP_DATA(A,B) {SWAP_VARS(int,A->x,B->x);\ SWAP_VARS(int,A->y,B->y); SWAP_VARS(int,A->i,B->i);} static void NAME(TYPE *ARR,int n) {TYPE *left,*right,*ip,*jp,*last,*mid; int l; if (DEBUG) printf("ec_AP_qsort %i\n",n); if (n<=1) return; left=ARR; if (n==2) {ip=left+1; if (CMP(left,ip)) SWAP_DATA(left,ip); return;} right=left+(n-1); if (n<=5) {for (ip=left;ip>1; if (A[w].x=2) printf("heap_search %i %i %i\n",HH,A[HH].x,n);\ if ((HH0;i--) {MUL(u,S[i-1],t,p); MUL(u,B[i],u,p); B[i]=t;} B[0]=u; if (DEBUG) printf("Montgomery done %i\n",bs-n-1); for (i=0;i=1) for (i=0;i=1) printf("T.x:%i T.y:%i\n",T.x,T.y); HEAP_SEARCH(T.x,ARR,bs,k); if (k!=-1) {i=ARR[k].i; if (T.y==ARR[k].y) k=L-i; else k=L+i; if (k) DONE(k);} for (j=1;j*(2*bs-1)<=ns;j++) {if (ec_AP_pt_add(a4,T,GS,&U,p)) {DDONE(L+gs*j); j++; T=GS;} else T=U; HEAP_SEARCH(T.x,ARR,bs,k); if (k!=-1) /* idea of Geoff Bailey; avoid computing exact order */ {i=ARR[k].i; if (T.y==ARR[k].y) k=L-i; else k=L+i; if (DEBUG) printf("FOUND %i %i %i %i\n",i,k,j,gs); DDONE(k+gs*j);}} ASSERT(mo!=0); free(ARR); return -mo;} llint ec_bsgs_ap(QD C4,QD C6,llint pr) {int aa,bb; if (DEBUG) printf("ec_bsgs_ap %lli\n",pr); if (pr>(1<<29)) return ec_bsgs_ap_large(C4,C6,pr); aa=(int) ((-27*QD_modll(C4,pr))%pr); bb=(int) ((-54*QD_modll(C6,pr))%pr); return ec_bsgs_ap_AB(aa,bb,pr);} llint ec_bsgs_ap_AB(int aa,int bb,llint pr) {int a4,L,U,WIDTH,v,S,k,ko,x,m,o; AP_pt P; S=(int) Floor(2.0*Sqrt(pr)); L=(int) pr+1-S; U=(int) pr+1+S; WIDTH=U-L+1; if (DEBUG) printf("a4:%i a6:%i\n",aa,bb); if (DEBUG) printf("L:%i U:%i W:%i\n",L,U,WIDTH); v=bb; NORMALISE(aa,pr); NORMALISE(v,pr); k=kron(v,(int) pr); ko=-k; x=0; while (1) {while (!k || (k==ko)) {x++; v=(int) ((((llint) aa+(llint) (x*x))*(llint) x+(llint) bb)%pr); k=kron(v,pr);} ko=k; if (DEBUG) printf("x:%i k:%i v:%i\n",x,k,v); MUL(x,v,P.x,pr); MUL(v,v,P.y,pr); MUL(aa,P.y,a4,pr); NORMALISE(P.x,pr); NORMALISE(P.y,pr); NORMALISE(a4,pr); if (DEBUG) printf("a4:%i Px:%i Py:%i\n",a4,P.x,P.y); m=ec_AP_bsgs(a4,P,pr,L); if (DEBUG) printf("multiple of order is %i\n",m); if (m>0) {if (m0.0) i=ss; else i=-ss; break;} rr-=cc*ss;\ ROUND(bb/aa,cc); bb-=aa*cc;\ if (bb==0.0) {if (aa>0.0) i=rr; else i=-rr; break;} ss-=cc*rr;}} #define NORMALISE(x,p) while ((x)>=(p)) (x)-=(p); while ((x)<0) (x)+=(p) typedef struct {llint U; llint V;} PERALTA; static void PMUL(PERALTA i1,PERALTA i2,PERALTA *o,llint d,llint p) {double A,B,P=(double) p,D=(double) d,E,x,y; llint rU,rV; if (DEBUG>=2) printf("PMUL %lli %lli %lli %lli\n",i1.U,i1.V,i2.U,i2.V); x=(double) i1.V; y=(double) i2.U; MUL(x,y,A,P); x=(double) i2.V; y=(double) i1.U; MUL(x,y,B,P); rV=(llint) (A+B); while (rV<0) rV+=p; while (rV>=p) rV-=p; x=(double) i2.U; y=(double) i1.U; MUL(x,y,A,P); x=(double) i1.V; y=(double) i2.V; MUL(x,y,B,P); MUL(B,D,E,P); rU=(llint) (A+E); while (rU<0) rU+=p; while (rU>=p) rU-=p; (*o).U=rU; (*o).V=rV; if (DEBUG>=2) printf("RET %lli %lli\n",rU,rV);} static void mod_exp_peralta(llint r,llint d,llint p,llint e,llint* u,llint *v) {PERALTA c,m,o; llint le; o.U=r; o.V=1; m.U=1; m.V=0; c=o; le=e; for (e>>=1;e>0;e>>=1) {PMUL(c,c,&c,d,p); if (e&1) PMUL(m,c,&m,d,p);} if (le&1) PMUL(m,o,&m,d,p); (*u)=m.U; (*v)=m.V;} static llint mod_sqrt_peralta(int d,llint p) {llint r=314159,u,v; QD P,R,S; double V,i; if (DEBUG>=2) printf("mod_sqrt_peralta %i %lli\n",d,p); QD_copy(wmax,QD_zero,P); P[0]=(double) p; while (1) {r=(r+1)%p; R[0]=(double) r; QD_sqr(wmax,R,S); if (QD_modll(S,p)==p-d) return r; mod_exp_peralta(r,d,p,(p-1)/2,&u,&v); if (u==0) {V=(double) v; INV(V,i,P[0]); return (llint) i;}}} static llint mod_sqrt(int d,llint p) {QD P,M; QD_copy(wmax,QD_zero,P); P[0]=(double) p; if ((p&3)==3) {modular_exponentiation(d,P,(p+1)/4,M); return (llint) Round(M[0]);} else return mod_sqrt_peralta(d,p);} static void cornaccia2(int d,llint p,llint *x,llint *y) /* x^2+d*y^2=4p */ {llint a,b,L,r; if (DEBUG>=2) printf("cornaccia2 %i %lli\n",d,p); a=p+p; b=mod_sqrt(-d,p); if ((b&1)!=(d&1)) b-=p; L=(llint) Floor(2.0*Sqrt((double) p)); while ((b>L) || (b<-L)) {r=a%b; a=b; b=r;} *y=(llint) Round(Sqrt((((p<<2)-b*b)/d))); *x=b; if (*x<0) *x=-(*x); if (*y<0) *y=-(*y);} static llint ap_j0(QD C6,llint pr) {llint x,y,d,ap; QD P,R; if ((pr%3)!=1) return 0; cornaccia2(27,pr,&x,&y); if ((x%3)==1) x=-x; d=(8*QD_modll(C6,pr))%pr; QD_copy(wmax,QD_zero,P); P[0]=(double) pr; modular_exponentiation(d,P,(pr-1)/6,R); P[0]=(double) x; QD_mul(wmax,R,P,R); ap=QD_modll(R,pr); if (ap>pr/2) ap-=pr; return ap;} static llint ap_j1728(QD C4,llint pr) {llint x,y,d,ap; QD P,R; if ((pr&3)!=1) return 0; cornaccia2(4,pr,&x,&y); if ((x&3)==0) x=y; if ((x&1)==1) x=(x<<1); if ((x&7)==6) x=-x; d=(-27*QD_modll(C4,pr))%pr; QD_copy(wmax,QD_zero,P); P[0]=(double) pr; modular_exponentiation(d,P,(pr-1)/4,R); P[0]=(double) x; QD_mul(wmax,R,P,R); ap=QD_modll(R,pr); if (ap>pr/2) ap-=pr; return ap;} static llint ap_j8000(llint pr) {llint x,y; if (((pr&7)==5) || ((pr&7)==7)) return 0; cornaccia2(8,pr,&x,&y); if (((x&15)==2) || ((x&15)==6)) {if ((y&3)!=0) x=-x;} if (((x&15)==10) || ((x&15)==14)) {if ((y&3)==0) x=-x;} if (kronll(CM_TWIST,pr)==-1) x=-x; return x;} static llint ap_j287496(llint pr) {llint x,y; if ((pr&3)!=1) return 0; cornaccia2(4,pr,&x,&y); if ((x&3)==0) x=y; if ((x&1)==1) x=(x<<1); if ((x&7)==6) x=-x; if (kronll(2,pr)==-1) x=-x; if (kronll(CM_TWIST,pr)==-1) x=-x; return x;} static llint ap_cm(int CM,llint pr) {llint x,y; if (kronll((llint) CM,pr)!=1) return 0; cornaccia2(-CM,pr,&x,&y); if ((CM&3)==0) CM>>=2; if ((kronll(x,(llint) -CM)>0)^(CM==-7)) x=-x; if (kronll(CM_TWIST,pr)==-1) x=-x; return x;} static llint ec_ap_cm(QD C4,QD C6,llint pr) {switch (CM_CASE) {case -3: return ap_j0(C6,pr); case -4: return ap_j1728(C4,pr); case -8: return ap_j8000(pr); case -16: return ap_j287496(pr); case -28: return ap_cm(-7,pr); default: return ap_cm(CM_CASE,pr);}} static llint ec_ap2(QD C4,QD C6) {int a1,a2,a3,a4,a6,b2,b4,b6,c4,c6,ap; if (DEBUG) printf("ec_ap2\n"); c4=QD_modi(C4,10077696); c6=QD_modi(C6,10077696); b2=-(c6%12); if (b2<-5) b2+=12; b4=(b2*b2-c4)/24; b6=(-b2*b2*b2+36*b2*b4-c6)/216; a1=b2%2; if (a1<0) a1=-a1; a2=(b2-a1)/4; a3=(b6%2); if (a3<0) a3=-a3; a4=(b4-a1*a3)/2; a6=(b6-a3)/4; a2=a2%2; if (a2<0) a2=-a2; a4=a4%2; if (a4<0) a4=-a4; a6=a6%2; if (a6<0) a6=-a6; ap=a1; if (DEBUG) printf("ec_ap2: %i %i %i %i %i\n",a1,a2,a3,a4,a6); if (a1==a3) ap=-ap; else if (a2!=a4) ap-=2; if (a6!=0) ap=-ap; return ap;} static llint ec_ap3(QD C4,QD C6) {int b2,b4,b6,c4,c6; if (DEBUG) printf("ec_ap3\n"); c4=QD_modi(C4,10077696); c6=QD_modi(C6,10077696); b2=-(c6%12); if (b2<-5) b2+=12; b4=(b2*b2-c4)/24; b6=(-b2*b2*b2+36*b2*b4-c6)/216; b2=b2%3; b4=b4%3; b6=b6%3; if (DEBUG) printf("ec_ap3: %i %i %i\n",b2,b4,b6); return -(kron(b6,3)+kron(1+b2-b4+b6,3)+kron(-1+b2+b4+b6,3));} static llint ec_ap_kron(QD C4,QD C6,llint pr) {llint ap=0; int a4,a6,x; if (DEBUG) printf("ec_ap_kron %lli\n",pr); if (pr==2) return ec_ap2(C4,C6); if (pr==3) return ec_ap3(C4,C6); a4=(-27*QD_modi(C4,(double) pr))%pr; a6=(-54*QD_modi(C6,(double) pr))%pr; for (x=0;x0.0) i=ss; else i=-ss; break;} rr-=cc*ss;\ ROUND(bb/aa,cc); bb-=aa*cc;\ if (bb==0.0) {if (aa>0.0) i=rr; else i=-rr; break;} ss-=cc*rr;}} #define NORMALISE(x,p) while ((x)>=(p)) (x)-=(p); while ((x)<0) (x)+=(p) #define FROM_LINE(P,Q,R,s,p)\ {double T,x1; ap_pt V;\ MUL(s,s,T,p); V.x=T-(P.x+Q.x); NORMALISE(V.x,p);\ x1=P.x-V.x; MUL(x1,s,T,p); V.y=T-P.y; NORMALISE(V.y,p); *(R)=V;} static int ec_ap_large_pt_double(double a4,ap_pt P,ap_pt *R,double p) {double T,n,i,s,tt; if (P.y==0.0) return TRUE; MUL(P.x,P.x,T,p); n=T+T+T+a4; /*NORMALISE(n,p);*/ tt=P.y+P.y; INV(tt,i,p); MUL(n,i,s,p); FROM_LINE(P,P,R,s,p); return FALSE;} static int ec_ap_large_pt_add(double a4,ap_pt P,ap_pt Q,ap_pt *R,double p) {double Ld,Ln,i,s; if (P.x==Q.x) {if (P.y==Q.y) return ec_ap_large_pt_double(a4,P,R,p); return TRUE;} Ld=P.x-Q.x; Ln=P.y-Q.y; /* allow Ld to be negative */ INV(Ld,i,p); MUL(Ln,i,s,p); FROM_LINE(P,Q,R,s,p); return FALSE;} #define ADDI(P,Q,R,p,i) {double s; MUL(P.y-Q.y,i,s,p); FROM_LINE(P,Q,R,s,p);} #define DOUBLEI(a4,P,R,p,i)\ {double TT,nn,s; MUL(P.x,P.x,TT,p); nn=TT+TT+TT+a4;\ MUL(nn,i,s,p); FROM_LINE(P,P,R,s,p);} static int ec_ap_large_pt_mult(double a4,ap_pt P,llint n,ap_pt *R,double p) {llint m=n; ap_pt Q=P,T,U; int z=TRUE; /* P is not O */ if (n==0) return TRUE; if (n==1) {*R=P; return FALSE;} if (m&1) {U=Q; z=FALSE;} while (m) {m=m>>1; if (ec_ap_large_pt_double(a4,Q,&T,p)) break; Q=T; if (m&1) {if (z) {U=Q; z=FALSE;} else {z=ec_ap_large_pt_add(a4,Q,U,&T,p); if (!z) U=T;}}} if (!z) *R=U; return z;} static llint ec_ap_large_order_from_mult(double a4,ap_pt P,llint m,double pr) {int i,e,k,t; llint o=1,n=m,p,pe; ap_pt Q=P,R; LIST f; f.p[0]=0; ifactor(n,&f,1,1000); for (i=0;f.p[i]!=0;i++) {p=f.p[i]; e=f.e[i]; for (t=0;tx>B->x) #define SWAP_VARS(type,A,B) {type _ttemmp; _ttemmp=A; A=B; B=_ttemmp;} #define SWAP_DATA(A,B) {SWAP_VARS(double,A->x,B->x);\ SWAP_VARS(double,A->y,B->y); SWAP_VARS(int,A->i,B->i);} static void NAME(TYPE *ARR,int n) {TYPE *left,*right,*ip,*jp,*last,*mid; int l; if (DEBUG) printf("ec_ap_large_qsort %i\n",n); if (n<=1) return; left=ARR; if (n==2) {ip=left+1; if (CMP(left,ip)) SWAP_DATA(left,ip); return;} right=left+(n-1); if (n<=5) {for (ip=left;ip>1; if (A[w].x0;i--) {MUL(u,S[i-1],t,p); MUL(u,B[i],u,p); B[i]=t;} B[0]=u; if (DEBUG) printf("Montgomery done %i\n",bs-n-1); for (i=0;i=1) for (i=0;i=1) printf("T.x:%f T.y:%f\n",T.x,T.y); HEAP_SEARCH(T.x,ARR,bs,k); if (k!=-1) {i=ARR[k].i; if (T.y==ARR[k].y) K=L-i; else K=L+i; if (K) DONE(K);} for (j=1;;j++) {if (ec_ap_large_pt_add(a4,T,GS,&U,p)) DONE((L+(gs*j))); T=U; HEAP_SEARCH(T.x,ARR,bs,k); if (k!=-1) /* Don't use the GB trick, as it probably isn't faster */ {i=ARR[k].i; if (T.y==ARR[k].y) K=L-i; else K=L+i; if (DEBUG) printf("FOUND %i %lli %i %i\n",i,K,j,gs); DONE((K+(gs*j)));}} errorit("ec_bsgs_bsgs error"); return -1;} llint ec_bsgs_ap_large(QD C4,QD C6,llint pr) {llint aa,bb,v,U,L,S,WIDTH,m,o; QD AA,BB; int x; double V; int k,ko; double a4,p=(double) pr; ap_pt P; if (DEBUG) printf("ec_bsgs_ap_large %lli\n",pr); if (pr<500) errorit("p<500 in ec_bsgs_ap\n"); QD_mul1(wmax,C4,-27.0,AA); aa=QD_modll(AA,p); QD_mul1(wmax,C6,-54.0,BB); bb=QD_modll(BB,p); v=bb; S=(llint) Floor(Sqrt(4*p)); L=pr+1-S; U=pr+1+S; WIDTH=U-L+1; if (DEBUG) printf("a4:%lli a6:%lli\n",aa,bb); if (DEBUG) printf("L:%lli U:%lli W:%lli\n",L,U,WIDTH); k=kronll(v,pr); ko=-k; x=0; while (1) {while (!k || (k==ko)) {x++; v=((aa+x*x)*x+bb)%pr; k=kronll(v,pr);} ko=k; if (DEBUG) printf("x:%i k:%i v:%lli\n",x,k,v); P.x=(double) ((x*v)%pr); V=(double) v; MUL(V,V,P.y,p); MUL(P.y,(double) aa,a4,p); if (a4+a4>p) a4-=p; if (DEBUG) printf("a4:%f Px:%f Py:%f\n",a4,P.x,P.y); m=ec_ap_large_bsgs(a4,P,p,L); if (DEBUG) printf("mult of order is %lli\n",m); o=ec_ap_large_order_from_mult(a4,P,m,p); if (DEBUG) printf("ord %lli\n",o); if (o2) && (p<=3)) {cyclic_abelian_ap(p,p,m,d,v); return;} if ((d>1) && (p>3)) {QD_copy(wmax,QD_zero,Et4); QD_copy(wmax,QD_zero,Et6); v4=QD_valuation(Ec4,P); v6=QD_valuation(Ec6,P); if (3*v4>=2*v6) {QD_copy(wmax,Ec6,Et6); for (i=1;i<=v6;i++) QD_div1(wmax,Et6,P,Et6);} if (3*v4<=2*v6) {QD_copy(wmax,Ec4,Et4); for (i=1;i<=v4;i++) QD_div1(wmax,Et4,P,Et4);}} if ((d==2) && (p==2)) /* need to worry here */ {if (bpt==16) {QD_div1(wmax,Ec4,16.0,Et4); QD_div1(wmax,Ec6,64.0,Et6);} else {QD_div1(wmax,Ec4,4.0,Et4); QD_div1(wmax,Ec6,8.0,Et6); c4=QD_modi(Et4,1<<29); c6=QD_modi(Et6,1<<29); if ((((c4&31)==16) && ((c6&255)==192)) || (((c4&255)==0) && ((c6&2047)==512))) {QD_div1(wmax,Et4,16.0,Et4); QD_div1(wmax,Et6,64.0,Et6);} else if ((((c4&31)==16) && ((c6&255)==64)) || (((c4&255)==0) && ((c6&2047)==1536))) {QD_div1(wmax,Et4,16.0,Et4); QD_div1(wmax,Et6,-64.0,Et6);} } } if ((d==2) && (p==3)) /* think this is OK */ {QD_div1(wmax,Ec4,9.0,Et4); QD_div1(wmax,Ec6,-27.0,Et6);} if (d==1) ap=(int) ec_do(p); else ap=(int) ec_ap(Et4,Et6,p); if ((HECKE) && (d==1)) return hecke_good(p,ap,m,v); cyclic_abelian_ap(p,ap,m,d,v);} static void euler_factor_good(llint p,int m,QDpoly *v) {cyclic_abelian(p,m,1,v,0);} void euler_factor_bad(llint p,int bpt,int m,QDpoly *v) {int ap,eps,lc; if (DEBUG) printf("euler_factor_bad %lli %i %i\n",p,bpt,m); lc=tame_local_conductor(bpt,m); eps=m+1-lc; if (lc==m+1) {initQDpoly(v,0); QD_copy(wmax,QD_one,(*v).coeff[0]); return;} if ((bpt==1) || (bpt>=29)) {ap=ec_ap(Ec4,Ec6,p); initQDpoly(v,1); QD_copy(wmax,QD_one,(*v).coeff[0]); if ((ap>=0) || !(m&1)) QD_neg(wmax,(*v).coeff[0],(*v).coeff[1]); else QD_copy(wmax,QD_one,(*v).coeff[1]); return;} if ((bpt>=2) && (bpt<=6)) {if ((p%bpt)!=1) cyclic_nonabelian(p,m,eps,v); else cyclic_abelian(p,m,bpt,v,bpt); return;} if (((bpt>=8) && (bpt<=10)) || ((bpt>=24) && (bpt<=27))) {if (((m&7)==2) || ((m&7)==4)) generic_plusminus(2,m,eps/2,eps/2,v); if ((m&7)==6) generic_plusminus(2,m,(eps+1)/2,(eps-1)/2,v); if ((m&7)==0) generic_plusminus(2,m,(eps-1)/2,(eps+1)/2,v); return; } if (bpt==22) {cyclic_abelian(2,m,4,v,bpt); return;} if (bpt==23) {cyclic_nonabelian(p,m,eps,v); return;} if ((bpt==12) || (bpt==13)) {if ((eps&1)==0) generic_plusminus(3,m,eps/2,eps/2,v); else if ((m&3)==0) generic_plusminus(3,m,(eps-1)/2,(eps+1)/2,v); else if ((m&3)==2) generic_plusminus(3,m,(eps+1)/2,(eps-1)/2,v);} if ((bpt==16) || (bpt==17)) cyclic_abelian(2,m,2,v,bpt); if (bpt==14) cyclic_abelian(3,m,3,v,bpt); if (bpt==15) cyclic_abelian(3,m,6,v,bpt); if ((bpt==18) || (bpt==19)) cyclic_nonabelian(p,m,eps,v); if ((bpt==20) || (bpt==21)) cyclic_nonabelian(p,m,eps,v); return;} static int deflate(int CM) {if ((CM==-27) || (CM== -12)) return 3; if (CM==-28) return 7; if (CM==-16) return 4; return -CM;} void euler_factor_hecke_bad(llint p,int bpt,int m,QDpoly *v) {QDpoly ef1,ef2,poly,R; int i,k; QD P,T; int A[8]={0,1,0,-1,0,-1,0,1}; if (DEBUG) printf("euler_factor_hecke_bad p:%lli bpt:%i sp:%i\n",p,bpt,m); QD_copy(wmax,QD_zero,P); P[0]=(double) p; euler_factor_bad(p,bpt,m,&ef1); if (m>2) euler_factor_bad(p,bpt,m-2,&ef2); else {initQDpoly(&ef2,0); QD_copy(wmax,QD_one,ef2.coeff[0]);} if ((m&1)==0) {initQDpoly(&poly,1); QD_copy(wmax,QD_one,poly.coeff[0]); k=-deflate(CM_CASE); if (p>2) k=kronll((llint) k,p); else k=A[k&7]; if ((m&3)==2) {QD_powi(wmax,P,m/2-1,T); if (k==1) QD_neg(wmax,T,T); if (k==0) poly.deg=0; else QD_copy(wmax,T,poly.coeff[1]); QDpoly_mul(ef2,poly,&R,-1); delQDpoly(&ef2); delQDpoly(&poly); ef2=R;} if ((m&3)==0) {QD_powi(wmax,P,m/2,T); if (k==1) QD_neg(wmax,T,T); if (k==0) poly.deg=0; else QD_copy(wmax,T,poly.coeff[1]); QDpoly_mul(ef1,poly,&R,-1); delQDpoly(&ef1); delQDpoly(&poly); ef1=R;} initQDpoly(&poly,1); QD_copy(wmax,QD_one,poly.coeff[0]); if ((m&3)==0) {QD_powi(wmax,P,m/2-1,T); QD_neg(wmax,T,poly.coeff[1]); QDpoly_mul(ef2,poly,&R,-1); delQDpoly(&ef2); delQDpoly(&poly); ef2=R;} if ((m&3)==2) {if (m<=2) delQDpoly(&poly); else {QD_powi(wmax,P,m/2,T); QD_neg(wmax,T,poly.coeff[1]); QDpoly_mul(ef1,poly,&R,-1); delQDpoly(&ef1); delQDpoly(&poly); ef1=R;}}} QD_copy(wmax,P,T); for (i=1;i<=ef2.deg;i++) {QD_mul(wmax,ef2.coeff[i],T,ef2.coeff[i]); QD_mul(wmax,T,P,T);} QDpoly_inv(ef2,ef1.deg-ef2.deg,&R); QDpoly_mul(ef1,R,v,ef1.deg-ef2.deg); delQDpoly(&R); delQDpoly(&ef1); delQDpoly(&ef2);} void euler_factor(llint p,int m,QDpoly *v) {int i; if ((COND0%p)!=0) {euler_factor_good(p,m,v);} else {for (i=0;p!=badprimes[i];i++); if (HECKE) euler_factor_hecke_bad(p,badprimetype[i],m,v); else euler_factor_bad(p,badprimetype[i],m,v);} QDpoly_intround(v);} static void localinfo(llint p,int sp) {QDpoly v; printf("Euler factor at %lli is ",p); euler_factor(p,sp,&v); QDpoly_intout(v); delQDpoly(&v); if ((!HECKE) && (p<=3)) {printf("Tame cond exponent at %lli is %i\n",p,get_tame_conductor(p,sp)); printf("Wild cond exponent at %lli is %i\n",p,get_wild_conductor(p,sp));} else printf("Conductor exponent at %lli is %i\n",p,get_conductor(p,sp));} static int primetest(llint x) {int i; llint p; if (x==1) return FALSE; for(i=0;PRIMES[i]!=0;i++) {p=PRIMES[i]; if (x==p) return 1; if ((x%p)==0) return 0;} return 1;} void localinfos(char *p,char *sp) {int k=0; llint prl=0,prh=0,pr; int ml=0,mh=0,m; while ((p[k]!='-') && (p[k]!=0)) {prl*=10; ASSERT(ISA_NUMBER(p[k])); prl+=p[k]-'0'; k++;} if (p[k]=='-') k++; else prh=prl; while (p[k]!=0) {prh*=10; ASSERT(ISA_NUMBER(p[k])); prh+=p[k]-'0'; k++;} k=0; while ((sp[k]!='-') && (sp[k]!=0)) {ml*=10; ASSERT(ISA_NUMBER(sp[k])); ml+=sp[k]-'0'; k++;} if (sp[k]=='-') k++; else mh=ml; while (sp[k]!=0) {mh*=10; ASSERT(ISA_NUMBER(sp[k])); mh+=sp[k]-'0'; k++;} if ((ml<=0) || (mh>99)) errorit("Symmetric power range invalid"); for (m=ml;m<=mh;m++) {if (HECKE) printf("Hecke "); printf("Symmetric power %i\n",m); for (pr=prl;pr<=prh;pr++) if (primetest(pr)) localinfo(pr,m);}} sympow-1.019/factor.c0000644017361200001450000001650010442324213014356 0ustar tabbottcrontab#include "sympow.h" #define DEBUG (FALSE || GLOBAL_DEBUG) static int my_primes[179]= {2,3,5,7,11,13,17,19,23,29,31,37, 41,43,47,53,59,61,67,71, 73,79,83,89,97,101,103,107,109,113, 127,131,137,139,149,151,157, 163,167,173,179,181,191,193,197,199, 211,223,227,229,233,239,241, 251,257,263,269,271,277,281,283,293, 307,311,313,317,331,337,347, 349,353,359,367,373,379,383,389,397, 401,409,419,421,431,433,439, 443,449,457,461,463,467,479,487,491, 499,503,509,521,523,541,547, 557,563,569,571,577,587,593,599,601, 607,613,617,619,631,641,643, 647,653,659,661,673,677,683,691,701, 709,719,727,733,739,743,751, 757,761,769,773,787,797,809,811,821, 823,827,829,839,853,857,859, 863,877,881,883,887,907,911,919,929, 937,941,947,953,967,971,977, 983,991,997,1009,1013,1019,1021,1031, 1033,1039,1049,1051,1061,1063}; static char *aux; static int get_primes_loop(int start,int size,int *A) {int i,l,j=0,k=0; int s,p=2; if (DEBUG>=2) printf("init_primesj %i %i\n",start,size); for (i=0;i=2) printf("init_primesi %i %i\n",start,sz); size+=1000; aux=malloc(u8((size/10)+72)); B=A; for (i=0;i<10;i++) {B=B+k; k=get_primes_loop(start,sz/10,B); start+=sz/10;} free(aux);} void init_primes() {int i; PRIMES=malloc(80000*sizeof(int)); for (i=0;i<80000;i++) PRIMES[i]=0; for (i=0;i<179;i++) PRIMES[i]=my_primes[i]; get_primes(1064,1000000,PRIMES+179); badprimes=malloc(32*sizeof(llint)); badprimetype=malloc(32*sizeof(llint));} static void add_to_list(LIST *L,llint P,int E) {int i=0; if (DEBUG>=2) printf("add_to_list %lli %i\n",P,E); while ((*L).p[i]!=0) i++; (*L).p[i]=P; (*L).e[i]=E; (*L).p[i+1]=0;} static int is_power(llint x,int n,llint *y) {int i; llint t=1; *y=Round(Root(x,n)); for (i=0;i=2) printf("squfof_internal %lli\n",n); if (n<=0) errorit("Non-positive number in squfof"); if (n>(((llint) 1)<<59)) errorit("Too large in squfof"); nS=Pnow=(int) Floor(Sqrt((double) n)); Qnow=(int) (n-(llint) Pnow*(llint) Pnow); Qprev=1; phase=1; nsmallden=0; den_bound=(int) Sqrt(2*nS+1); for (iter=1;;iter++) {Pprev=Pnow; Qback2=Qprev; Qprev=Qnow; if (nS+Pprev>=2*Qprev) {quot=(nS+Pprev)/Qprev; Pnow=quot*Qprev-Pprev; Qnow=Qback2+quot*(Pprev-Pnow);} else {Pnow=Qprev-Pprev; Qnow=Qback2+Pprev-Pnow;} den=Qprev; if ((den&1)==0) den>>=1; if (Pnow==Pprev) {(*y1)=den; (*y2)=n/(llint) den; return;} if (phase && den1) smalldens[++nsmallden]=den; if (phase && (iter&1) && ((root=is_square(Qnow))>0)) {j=nsmallden; smalldens[0]=root; while (smalldens[j]!=root) j--; if (j==0) {phase=0; Pnow=nS-(nS-Pnow)%root; Qnow=(int) ((n-(llint) Pnow*(llint) Pnow)/(llint) root); Qprev=root;}}}} static void squfof(llint n,llint *y1,llint *y2) {int i=1; llint m=1; if (DEBUG>=2) printf("squfof %lli\n",n); while (1) {squfof_internal(n*m,y1,y2); if (((*y1)%m)==0) (*y1)/=m; if (((*y2)%m)==0) (*y2)/=m; if (((*y1)!=1) && ((*y2)!=1)) return; else m=(llint) my_primes[i++];}} static short int *IFACT_TABLE; static void TABLE_FACTOR(int x,int s,LIST *L) {int p,l=0,e=1,f=0; if (DEBUG>=2) printf("TABLE_FACTOR %i %i\n",x,s); if (!(x&1)) {do {f++; x=x>>1;} while (!(x&1)); add_to_list(L,2,f*s);} while (1) {p=(int) IFACT_TABLE[(x-1)/2]; if (p==0) {if (x==l) {e++; x=1;} if (l>0) add_to_list(L,l,e*s); if (x>1) add_to_list(L,x,s); return;} if (p==l) {x=x/p; e++;} else {if (l>0) add_to_list(L,l,e*s); e=1; x=x/p; l=p;}}} static int primes_up_to(int B) {int i; for (i=0;PRIMES[i]<=B;i++); return i;} void modular_exponentiation(llint B,QD n,llint pow,QD M) {QD b; llint ll,l; if (DEBUG>=2) printf("mod_exp %lli %f %lli\n",B,n[0],pow); QD_copy(wmax,QD_zero,b); b[0]=(double) B; QD_copy(wmax,QD_one,M); ll=l=pow; for (l>>=1;l>0;l>>=1) {QD_sqr(wmax,b,b); QD_mod(b,n,b); if (l&1) {QD_mul(wmax,M,b,M); QD_mod(M,n,M);}} if (ll&1) {QD_mul1(wmax,M,(double) B,M); QD_mod(M,n,M);}} static int mod_test(int B,QD n,llint x) {QD M; modular_exponentiation(B,n,x-1,M); if (M[0]==1.0) return 1; return 0;} static int pp_test_QD(QD n,llint x) {if (n[0]<1.0e12) {if (!mod_test(2,n,x)) return 0; if (!mod_test(13,n,x)) return 0; if (!mod_test(23,n,x)) return 0; if (!mod_test(1662803,n,x)) return 0; return 1;} if (!mod_test(2,n,x)) return 0; if (!mod_test(3,n,x)) return 0; if (!mod_test(5,n,x)) return 0; if (!mod_test(7,n,x)) return 0; if (!mod_test(11,n,x)) return 0; if (!mod_test(13,n,x)) return 0; if (!mod_test(17,n,x)) return 0; if (!mod_test(19,n,x)) return 0; if (!mod_test(23,n,x)) return 0; if (!mod_test(29,n,x)) return 0; return 1;} static int pseudo_prime_test(llint x) {QD n; n[0]=(double) x; n[1]=(double) (x-(llint) n[0]); n[2]=0.0; n[3]=0.0; return pp_test_QD(n,x);} void QD_factor(QD x,LIST *L) {llint f,y1,y2; int i,e,s=1; QD y,z; QD_copy(wmax,x,y); for (i=0;PRIMES[i]!=0;i++) {e=0; while ((QD_is_divisible(y,(double) PRIMES[i])) && (y[0]!=1.0)) {e++; QD_div1(wmax,y,(double) PRIMES[i],y); QD_round(wmax,y,y);} if (e>0) add_to_list(L,PRIMES[i],e);} if (y[0]==1.0) return; while (QD_is_power(y,2,z)) {s*=2; QD_copy(wmax,z,y);} while (QD_is_power(y,3,z)) {s*=3; QD_copy(wmax,z,y);} while (QD_is_power(y,5,z)) {s*=5; QD_copy(wmax,z,y);} while (QD_is_power(y,7,z)) {s*=7; QD_copy(wmax,z,y);} if (y[0]>576460752303423488.0) errorit("Disc has a large prime factor"); f=(llint) y[0]+(llint) y[1]; if (pseudo_prime_test(f)) {add_to_list(L,f,s); return;} squfof(f,&y1,&y2); add_to_list(L,y1,s); add_to_list(L,y2,s);} static int TABLE_BOUND=0; void IFACT_INIT(llint B) {int i,j,num,p; if (DEBUG>=2) printf("IFACT_INIT %lli\n",B); if (B>MAX_TABLE) B=MAX_TABLE; if (B<=TABLE_BOUND) return; if (TABLE_BOUND!=0) free(IFACT_TABLE); TABLE_BOUND=B; IFACT_TABLE=(short int*) malloc((B/2)*sizeof(short int)); for (i=0;i0;i--) {p=PRIMES[i]; for (j=(p*p-1)/2;j=2) {printf("ifactor %lli\n",x); fflush(stdout);} if (x fpu_control_t fpu_control=0x027f; _FPU_SETCW(fpu_control); #endif } sympow-1.019/generate.c0000644017361200001450000002137510442324213014700 0ustar tabbottcrontab#include "sympow.h" #define DEBUG (FALSE || GLOBAL_DEBUG) char Mtxt1[16],Stxt1[16],Mtxt2[16],Stxt2[16],Mbin1[16],Mbin2[16]; int HECKE=FALSE,sp=0,dv=0,CM=FALSE,HILO=FALSE; int N,mx,prec; char *F1,*F2; static void procit(char *STR) {char TOK[8]=" "; char *INP; INP=strtok(STR,TOK); if (!strcmp(INP,"-hecke")) {HECKE=TRUE; INP=strtok(NULL,TOK);} if (!strcmp(INP,"-cm")) {CM=TRUE; INP=strtok(NULL,TOK);} if (strcmp(INP,"-sp")) errorit("No symmetric power specified"); INP=strtok(NULL,TOK); sp=atoi(INP); if ((sp<=0) || (sp>25)) errorit("Symmetric power not valid"); if ((HECKE) && (sp==1)) errorit("Hecke first power is redundant"); if (CM && ((sp&3) | HECKE)) errorit("CM specification invalid"); if ((sp&1) || (HECKE)) {INP=strtok(NULL,TOK); if (strcmp(INP,"-dv")) errorit("No derivative specified"); INP=strtok(NULL,TOK); dv=atoi(INP); if ((dv<0) || (dv>9)) errorit("Derivative not valid");} if (HECKE) {Mtxt1[0]=Stxt1[0]=Mtxt2[0]=Stxt2[0]=Mbin1[0]=Mbin2[0]='H';} else {Mtxt1[0]=Stxt1[0]=Mtxt2[0]=Stxt2[0]=Mbin1[0]=Mbin2[0]='P';} Mtxt1[1]=Stxt1[1]=Mtxt2[1]=Stxt2[1]=Mbin1[1]=Mbin2[1]='0'+sp/10; Mtxt1[2]=Stxt1[2]=Mtxt2[2]=Stxt2[2]=Mbin1[2]=Mbin2[2]='0'+sp%10; if ((sp&1) || (HECKE)) {if (dv==0) Mtxt1[3]=Stxt1[3]=Mtxt2[3]=Stxt2[3]=Mbin1[3]=Mbin2[3]='E'; if (dv==1) Mtxt1[3]=Stxt1[3]=Mtxt2[3]=Stxt2[3]=Mbin1[3]=Mbin2[3]='O'; if (dv>1) Mtxt1[3]=Stxt1[3]=Mtxt2[3]=Stxt2[3]=Mbin1[3]=Mbin2[3]='0'+dv;} else {if (CM) {Mtxt1[3]=Stxt1[3]=Mbin1[3]='h'; Mtxt2[3]=Stxt2[3]=Mbin2[3]='l';} else {Mtxt1[3]=Stxt1[3]=Mbin1[3]='H'; Mtxt2[3]=Stxt2[3]=Mbin2[3]='L';} HILO=TRUE;} Mtxt1[4]=Mtxt2[4]=Mbin1[4]=Mbin2[4]='M'; Stxt1[4]=Stxt2[4]='S'; Mtxt1[5]=Stxt1[5]=Mtxt2[5]=Stxt2[5]=Mbin1[5]=Mbin2[5]='.'; Mtxt1[6]=Mtxt2[6]=Stxt1[6]=Stxt2[6]='t'; Mbin1[6]=Mbin2[6]='b'; Mtxt1[7]=Mtxt2[7]=Stxt1[7]=Stxt2[7]='x'; Mbin1[7]=Mbin2[7]='i'; Mtxt1[8]=Mtxt2[8]=Stxt1[8]=Stxt2[8]='t'; Mbin1[8]=Mbin2[8]='n'; Mtxt1[9]=Stxt1[9]=Mtxt2[9]=Stxt2[9]=Mbin1[9]=Mbin2[9]=0;} static void pari_params() {int i; char F3[1024]; int NA[14]={0,1000,600,400,320,300,300,210,200,200,200,150,150,125}; F1=malloc(1024); F2=malloc(1024); prec=250; if (sp<14) N=NA[sp]; else N=200; if (HECKE) {N=1000; mx=dv; sprintf(F1,"F(k)=J(k-%i,X)*sinv(k,X)^%i/%i!",sp,dv+1,sp-1); return;} mx=sp/2; if (dv>mx) mx=dv; if (sp>15) prec+=(sp-15)*10; if (!HILO) {strcpy(F1,"F(k)="); for (i=1;i<=(1+sp)/2;i++) {sprintf(F3,"J(k-%i,X)/%i!*",i,i-1); strcat(F1,F3);} sprintf(F3,"sinv(k,X)^%i",dv+1); strcat(F1,F3);} else if (sp&3) {strcpy(F1,"F(k)=if(k%2==0,"); for (i=2;i<=1+sp/2;i++) {sprintf(F3,"J(k-%i,X)/%i!*",i,i-1); strcat(F1,F3);} strcat(F1,"J(k/2-1,X/2)*sinv(k,X),sqrt(Pi)/2*"); for (i=1;i<=1+sp/2;i++) {sprintf(F3,"J(k-%i,X)/%i!*",i,i-1); strcat(F1,F3);} strcat(F1,"1/J((k-1)/2,X/2)*two1ms(k,X)*sinv(k,X))"); strcpy(F2,"F(k)=if(k%2==1,"); for (i=1;i<=sp/2;i++) {sprintf(F3,"J(k-%i,X)/%i!*",i,i); strcat(F2,F3);} strcat(F2,"J((k-1)/2,X/2)*sinv(k,X),sqrt(Pi)/2*"); for (i=1;i<=sp/2;i++) {sprintf(F3,"J(k-%i,X)/%i!*",i,i); strcat(F2,F3);} strcat(F2,"J(k-1,X)/J(k/2-1,X/2)*two1ms(k,X)*sinv(k,X))");} else {strcpy(F1,"F(k)=if(k%2==1,"); for (i=2;i<=1+sp/2;i++) {sprintf(F3,"J(k-%i,X)/%i!*",i,i-1); strcat(F1,F3);} strcat(F1,"J((k-1)/2,X/2)*sinv(k,X)/sqrt(Pi),1/2*"); for (i=1;i<=1+sp/2;i++) {sprintf(F3,"J(k-%i,X)/%i!*",i,i-1); strcat(F1,F3);} strcat(F1,"1/J(k/2-1,X/2)*two1ms(k,X)*sinv(k,X))"); strcpy(F2,"F(k)=if(k%2==0,"); for (i=1;i<=sp/2;i++) {sprintf(F3,"J(k-%i,X)/%i!*",i,i); strcat(F2,F3);} strcat(F2,"J(k/2,X/2)*sinv(k,X)/sqrt(Pi),"); for (i=1;i<=sp/2;i++) {sprintf(F3,"J(k-%i,X)/%i!*",i,i); strcat(F2,F3);} strcat(F2,"J(k,X)/J((k-1)/2,X/2)*two1ms(k,X)*sinv(k,X))"); if (CM) strcat(F1,"*(X-k+1)*(X-k)"); if (CM) strcat(F2,"*(X-k)*(X-k-1)");}} int assure_line(char *STR) {int i,j,k,l=strlen(STR); if (DEBUG) printf("assure_line %s\n",STR); if ((STR[0]!='P') && (STR[0]!='H') && (STR[0]!='A') && (STR[0]!='M') && (STR[0]!='m')) return 0; if ((STR[1]>'2') || (STR[1]<'0')) return 0; if (!ISA_NUMBER(STR[2])) return 0; if ((!ISA_NUMBER(STR[3])) && (STR[3]!='E') && (STR[3]!='O') && (STR[3]!='h') && (STR[3]!='l') && (STR[3]!='H') && (STR[3]!='L')) return 0; if (STR[4]!=',') return 0; if (STR[l-1]!='\n') return 0; for (i=5;STR[i]!=',';i++) if ((STR[i]!='.') && !ISA_NUMBER(STR[i])) return 0; for (j=i+1;STR[j]!=',';j++) if ((STR[j]!='-') && !ISA_NUMBER(STR[j])) return 0; for (k=j+1;STR[k]!='\n';k++) if (!ISA_NUMBER(STR[k])) return 0; return 1;} void new_sympow_s1(char *A) {procit(A); printf("echo 'Removing any old data files'\n"); printf("cd datafiles\n"); printf("%s -f %s %s %s\n",RM,Mtxt1,Stxt1,Mbin1); if (HILO) printf("%s -f %s %s %s\n",RM,Mtxt2,Stxt2,Mbin2); printf("cd ..\n");} void new_sympow_pari(char *A) {int i; procit(A); pari_params(); printf("N=%i; dv=%i; mx=%i;\n\\p %i\n",N,dv,mx,prec); Stxt1[4]='\0'; printf("STR=\"%s\";\n",Stxt1); Stxt1[4]='S'; printf("\\r standard1.gp\n%s\n\\r standard2.gp\n",F1); printf("\\l datafiles/%s\n\\r standard3.gp\n",Mtxt1); printf("\\l datafiles/%s\n",Stxt1); if (!HECKE) for (i=0;i<(1+sp)/2;i++) printf("coeffs(%i);\n",i); else printf("coeffs(0);\n"); if (HECKE) {for (i=1;i<=dv;i++) printf("print(\"TACKS %i\");QD(polcoeff(polcoeff(P,%i,L),0,X));\n",i-1,i); return;} if (!HILO) {for (i=1+sp/2;i<=dv;i++) printf ("print(\"TACKS %i\");QD(polcoeff(polcoeff(P,%i,L),0,X));\n",i-1-sp/2,i); printf("\\q\n"); return;} if (sp&3) printf("coeffE(%i);\n",sp/2); else printf("coeffO(%i);\n",sp/2); Stxt2[4]='\0'; printf("STR=\"%s\";\n",Stxt2); Stxt2[4]='S'; printf("\\r standard1.gp\n%s\n\\r standard2.gp\n",F2); printf("\\l datafiles/%s\n\\r standard3.gp\n",Mtxt2); printf("\\l datafiles/%s\n",Stxt2); for (i=0;i<(1+sp)/2;i++) printf("coeffs(%i);\n",i); if (sp&3) printf("coeffO(%i);\n",sp/2); else printf("coeffE(%i);\n",sp/2); printf("\\q\n");} static void trimit(char *A) {printf("%s -v '^\?' %s | %s 's/ E/e/' > .tempfile.123\\\n",GREP,A,SED); printf(" && echo 'END' >> .tempfile.123 && mv .tempfile.123 %s\n",A);} void new_sympow_s2(char *A) {procit(A); printf("echo 'Trimming the data files'\n"); printf("cd datafiles\n"); trimit(Mtxt1); trimit(Stxt1); if (HILO) {trimit(Mtxt2); trimit(Stxt2);} printf("echo 'Turning the meshes into binaries'\n"); printf("NUM=`%s -c AT %s`\n",GREP,Mtxt1); printf("../sympow -txt2bin $NUM %s < %s\n",Mbin1,Mtxt1); if (HILO) {printf("NUM=`%s -c AT %s`\n",GREP,Mtxt2); printf("../sympow -txt2bin $NUM %s < %s\n",Mbin2,Mtxt2);} printf("cd ..\n");} void rewarp_params() {FILE *F; char PARAM[1024][64]; int j,i=0; char a0,a1,a2,a3; printf("Rewarping the param_data file\n"); F=fopen("datafiles/param_data","r"); while (1) {if (!getline0(F,PARAM[i],64)) break; if (!assure_line(PARAM[i])) {printf("Found bad param_data: %s\n",PARAM[i]); continue;} a0=PARAM[i][0]; a1=PARAM[i][1]; a2=PARAM[i][2]; a3=PARAM[i][3]; for (j=0;j void new_data(char *S) {char PATH[128]="new_data",ARGS[128]="",W[128]=""; int i=0,h=FALSE,c=FALSE,sp=0,dv=-1; if (ISA_NUMBER(S[i+1])) {sp=10*(S[i]-'0')+(S[i+1]-'0'); i=2;} else {sp=(S[i]-'0'); i=1;} if ((sp&1)) {ASSERT(S[i]=='d'); dv=(S[i+1]-'0'); i+=2;} else {if (S[i]=='d') {dv=(S[i+1]-'0'); ASSERT(S[i+2]=='h'); i+=2;}} if (S[i]=='h') {h=TRUE; strcpy(W,"Hecke");} if (S[i]=='c') {c=TRUE; strcpy(W,"CM");} if ((!h) && ((sp&1)==0) && (dv!=-1)) errorit("Derivative with even sympow?!"); if ((h) && (dv==-1)) errorit("Hecke powers must have a derivative"); printf("Make data for %s symmetric power %i",W,sp); if ((h) || (sp&1)) printf(" and derivative %i\n",dv); else printf("\n"); if ((h) && (sp==1)) errorit("First Hecke power is redundant"); if ((c) && ((sp&3)!=0)) errorit("CM power must have sp be 0 mod 4"); if (sp>25) errorit("Symmetric power is likely too large"); if (h) sprintf(ARGS,"-hecke -sp %i -dv %i",sp,dv); else if (c) sprintf(ARGS,"-cm -sp %i",sp); else if (sp&1) sprintf(ARGS,"-sp %i -dv %i",sp,dv); else sprintf(ARGS,"-sp %i",sp); execl(SH,SH,PATH,SH,GP,ARGS,NULL);} sympow-1.019/help.c0000644017361200001450000000550210442324213014030 0ustar tabbottcrontab#include "sympow.h" void help_message() {printf("\nsympow %s takes options:\n",VERSION); printf(" -bound # an upper BOUND for how many ap to compute\n"); printf(" -help print the help message and exit\n"); printf(" -info [] [] only report local information for primes/sympows\n"); printf(" 1st argument is prime range, 2nd is sympow range\n"); printf(" -local only report local information (bad primes)\n"); printf(" -curve [] input a curve in [a1,a2,a3,a4,a6] form\n"); printf(" -label [] get a label to the given curve\n"); printf(" -quiet turn off some messages\n"); printf(" -verbose turn on some messages\n"); printf(" -rootno # compute the root number of the #th symmetric power\n"); printf(" -moddeg compute the modular degree\n"); printf(" -analrank compute the analytic rank\n"); printf(" -sloppy [] for use with -analrank; have X sloppy digits\n"); printf(" -nocm abort if curve has complex multiplication\n"); printf(" -noqt ignore even powers of non-minimal quad twists\n"); printf(" -noqdcheck don't check if quad-double stuff works\n"); printf(" -mdspeed [] speed for moddeg; 2.0 is default, 0.0 is proof\n"); printf(" -hecke compute Hecke symmetric powers for a CM curve\n"); printf(" -maxtable set the max size of factor tables: 2^27 default\n" ); printf(" -sp [] argument to specify which powers\n"); printf(" this is a comma separated list\n"); printf(" in each entry, the 1st datum is the sympow\n"); printf(" then could come b which turns Bloch-Kato on\n"); printf(" then could come w# which specifies how many tests\n"); printf(" then could come s# which says # sloppy digits\n"); printf(" then must come p# which specifices the precision\n"); printf(" or P# which says ignore BOUND for this power\n"); printf(" then must come d# which says the derivative bound\n"); printf(" or D# which says do only this derivative\n"); printf(" (neither need be indicated for even powers)\n"); printf(" default is 2w3s1p32,3bp16d1,4p8\n"); printf(" -new_data [] will compute inverse Mellin transform mesh for\n"); printf(" the given data: the format is [sp]d[dv]{h,c}\n"); printf(" sp is the symmetric power, dv is the derivative,\n"); printf(" h indicates Hecke powers, and c indicates CM case\n"); printf(" d[dv] is given only for odd or Hecke powers\n"); printf(" Examples: 1d3 2 2d1h 3d2 4 4c 5d0 6 7d0h 11d1 12c\n"); printf(" NOTE: new_data runs a shell script that uses GP\n"); printf("Other options are used internally/recursively by -new_data\n\n"); exit(0);} sympow-1.019/init_curve.c0000644017361200001450000003310710442324213015251 0ustar tabbottcrontab#include "sympow.h" #define DEBUG (FALSE || GLOBAL_DEBUG) static void from_c4c6() {int b2; QD T,U; if (DEBUG) printf("from_c4c6\n"); QD_copy(wmax,QD_zero,Eb2); b2=-QD_modi(Ec6,12); if (b2<-5) b2+=12; Eb2[0]=(double) b2; QD_sqr(wmax,Eb2,T); QD_sub(wmax,T,Ec4,T); QD_div1(wmax,T,24.0,Eb4); QD_powi(wmax,Eb2,3,T); QD_add(wmax,T,Ec6,T); QD_mul(wmax,Eb2,Eb4,U); QD_mul1(wmax,U,36.0,U); QD_sub(wmax,U,T,T); QD_div1(wmax,T,216.0,Eb6); QD_copy(wmax,QD_zero,Ea1); QD_copy(wmax,QD_zero,Ea3); Ea1[0]=(double) QD_modi(Eb2,2); Ea3[0]=(double) QD_modi(Eb6,2); QD_sub(wmax,Eb2,Ea1,Ea2); QD_mul2n(wmax,Ea2,-2,Ea2); QD_sub(wmax,Eb6,Ea3,Ea6); QD_mul2n(wmax,Ea6,-2,Ea6); QD_mul(wmax,Ea1,Ea3,T); QD_sub(wmax,Eb4,T,Ea4); QD_mul2n(wmax,Ea4,-1,Ea4); QD_powi(wmax,Ec4,3,T); QD_sqr(wmax,Ec6,U); QD_sub(wmax,T,U,T); QD_div1(wmax,T,1728.0,U); QD_round(wmax,U,Edisc); if (Edisc[0]==0.0) errorit("Curve is singular");} static void from_a1a2a3a4a6() {QD T,U,V; if (DEBUG) printf("from_a1a2a3a4a6\n"); QD_sqr(wmax,Ea1,T); QD_mul2n(wmax,Ea2,2,U); QD_add(wmax,T,U,Eb2); QD_mul(wmax,Ea1,Ea3,T); QD_mul2n(wmax,Ea4,1,U); QD_add(wmax,T,U,Eb4); QD_sqr(wmax,Ea3,T); QD_mul2n(wmax,Ea6,2,U); QD_add(wmax,T,U,Eb6); QD_sqr(wmax,Eb2,T); QD_mul1(wmax,Eb4,24.0,U); QD_sub(wmax,T,U,Ec4); QD_mul(wmax,Eb2,Eb4,T); QD_mul1(wmax,T,36.0,V); QD_powi(wmax,Eb2,3,T); QD_mul1(wmax,Eb6,216.0,U); QD_add(wmax,T,U,T); QD_sub(wmax,V,T,Ec6); QD_powi(wmax,Ec4,3,T); QD_sqr(wmax,Ec6,U); QD_sub(wmax,T,U,T); QD_div1(wmax,T,1728.0,U); QD_round(wmax,U,Edisc); if (Edisc[0]==0.0) errorit("Curve is singular");} static void minimise_at(QD g,llint p) {QD s4,s6,P; int d,a,b; if (DEBUG) printf("minimise at %lli\n",p); QD_copy(wmax,QD_zero,P); P[0]=(double) p; d=QD_valuation(g,(double) p)/12; if ((p==3) && (QD_valuation(Ec6,3)==6*d+2)) d--; QD_powi(wmax,P,4*d,s4); QD_powi(wmax,P,6*d,s6); QD_div(wmax,Ec4,s4,Ec4); QD_div(wmax,Ec6,s6,Ec6); QD_round(wmax,Ec4,Ec4); QD_round(wmax,Ec6,Ec6); if (p!=2) return; a=QD_modi(Ec4,16); b=QD_modi(Ec6,32); if (((b&3)!=3) && !((a==0) && ((b==0) || (b==8)))) {QD_mul1(wmax,Ec4,16,Ec4); QD_mul1(wmax,Ec6,64,Ec6);}} static void minimal_model_c4c6() {QD T,g; LIST L; int i=0; if (DEBUG) printf("minimal_model_c4c6\n"); QD_sqr(wmax,Ec6,T); QD_intgcd(T,Edisc,g); L.p[0]=0; QD_factor(g,&L); for (i=0;L.p[i]!=0;i++) minimise_at(g,L.p[i]); C4C6LL=FALSE; if ((Abs(Ec4[0])<3.4e17) && (Abs(Ec6[0])<1.7e17)) {C4C6LL=TRUE; Ec4ll=((llint) Ec4[0])+((llint) Ec4[1]); Ec6ll=((llint) Ec6[0])+((llint) Ec6[1]);}} static int is_nonmintwist() {llint p; int v4,v6,vd; int i; for (i=0;badprimes[i]!=0;i++) {p=badprimes[i]; if (p>3) {if ((QD_valuation(Ec4,p)>=2) && (QD_valuation(Ec6,p)>=3)) return TRUE;} if (p==3) {v4=QD_valuation(Ec4,3.0); v6=QD_valuation(Ec6,3.0); vd=QD_valuation(Edisc,3.0); if ((v4>=2) && (v6>=3) && (vd>=6) && (v6!=5)) return TRUE;} if (p==2) {v4=QD_valuation(Ec4,2.0); v6=QD_valuation(Ec6,2.0); vd=QD_valuation(Edisc,2.0); if ((v4>=4) && (v6>=5) && (Ec6[0]<0.0)) return TRUE; /* twist by -1 */ if ((v4==4) && (v6==6) && (vd>=12)) return TRUE; /* twist by -1 drops */ if ((v4>=6) && (v6==6) && (vd>=6)) return TRUE; /* twist by pm2 */ if ((v4>=6) && (v6>=8) && (vd>=6)) return TRUE;}} /* twist by pm2 */ return FALSE;} void mintwist() {llint p; int v4,v6,vd; int i; double P; QD_copy(wmax,Ec4,Etw4); QD_copy(wmax,Ec6,Etw6); QD_copy(wmax,Edisc,EtwD); for (i=0;badprimes[i]!=0;i++) {p=badprimes[i]; P=(double) p; if ((p&3)==3) P=-P; if (p>3) {if ((QD_valuation(Ec4,p)>=2) && (QD_valuation(Ec6,p)>=3)) {QD_div1(wmax,Etw4,P,Etw4); QD_div1(wmax,Etw4,P,Etw4); QD_div1(wmax,Etw6,P,Etw6); QD_div1(wmax,Etw6,P,Etw6); QD_div1(wmax,Etw6,P,Etw6); QD_div1(wmax,EtwD,P,EtwD); QD_div1(wmax,EtwD,P,EtwD); QD_div1(wmax,EtwD,P,EtwD); QD_div1(wmax,EtwD,P,EtwD); QD_div1(wmax,EtwD,P,EtwD); QD_div1(wmax,EtwD,P,EtwD);}} if (p==3) {v4=QD_valuation(Ec4,3.0); v6=QD_valuation(Ec6,3.0); vd=QD_valuation(Edisc,3.0); if ((v4>=2) && (v6>=3) && (vd>=6) && (v6!=5)) {QD_div1(wmax,Etw4,9.0,Etw4); QD_div1(wmax,Etw6,-27.0,Etw6); QD_div1(wmax,EtwD,729.0,EtwD);}} if (p==2) {v4=QD_valuation(Ec4,2.0); v6=QD_valuation(Ec6,2.0); vd=QD_valuation(Edisc,2.0); if ((v4==4) && (v6==6) && (vd>=12)) /* twist by -1 to c4 odd */ {QD_div1(wmax,Etw4,16.0,Etw4); QD_div1(wmax,Etw6,-64.0,Etw6); if (QD_modi(Etw6,4)!=3) QD_neg(wmax,Etw6,Etw6); QD_div1(wmax,EtwD,4096.0,EtwD);} else if ((v4>=8) && (v6==9) && (vd==12)) /* tw by -1 to c6 8 mod32 drop */ {QD_div1(wmax,Etw4,16.0,Etw4); QD_div1(wmax,Etw6,-64.0,Etw6); if (QD_modi(Etw6,32)!=8) QD_neg(wmax,Etw6,Etw6); QD_div1(wmax,EtwD,4096.0,EtwD);} else if ((v4==6) && (v6==9) && (vd>=18)) /* twist by +-2 to c4 odd */ {QD_div1(wmax,Etw4,64.0,Etw4); QD_div1(wmax,Etw6,512.0,Etw6); if (QD_modi(Etw6,4)!=3) QD_neg(wmax,Etw6,Etw6); QD_div1(wmax,EtwD,262144.0,EtwD);} else if ((v4>=6) && (v6==6) && (vd==6)) /* tw by +-2 to c6 8 mod 32 dir */ {QD_div1(wmax,Etw4,4.0,Etw4); QD_div1(wmax,Etw6,8.0,Etw6); if (QD_modi(Etw6,32)!=8) QD_neg(wmax,Etw6,Etw6); QD_div1(wmax,EtwD,64.0,EtwD);} else if ((v4>=6) && (v6>=8)) /* twist by +-2 */ {QD_div1(wmax,Etw4,4.0,Etw4); QD_div1(wmax,Etw6,8.0,Etw6); QD_div1(wmax,EtwD,64.0,EtwD);}}} QD_round(wmax,Etw4,Etw4); QD_round(wmax,Etw6,Etw6); QD_round(wmax,EtwD,EtwD);} static void check_cm() {QD T,q,U; int n=0; if (DEBUG) printf("check_cm\n"); QD_powi(wmax,Ec4,3,T); QD_round(wmax,T,T); QD_div(wmax,T,Edisc,q); QD_round(wmax,q,q); QD_mul(wmax,q,Edisc,U); QD_round(wmax,U,U); QD_sub(wmax,T,U,U); if (U[0]!=0.0) return; QD_div(wmax,T,Edisc,T); QD_round(wmax,T,T); if (T[0]==0.0) CM_CASE=-3; else if (T[0]==1728.0) CM_CASE=-4; else if (T[0]==-3375.0) {CM_CASE=-7; QD_div1(wmax,Ec6,1323.0,T); if (T[0]<0.0) {n=1; QD_neg(wmax,T,T);} CM_TWIST=(int) Round(Root(T[0],3)); if (n==1) CM_TWIST=-CM_TWIST;} else if (T[0]==8000.0) {CM_CASE=-8; QD_div1(wmax,Ec6,-1792.0,T); if (T[0]<0.0) {n=1; QD_neg(wmax,T,T);} CM_TWIST=(int) Round(Root(T[0],3)); if (n==1) CM_TWIST=-CM_TWIST;} else if (T[0]==-32768.0) {CM_CASE=-11; QD_div1(wmax,Ec6,-6776.0,T); if (T[0]<0.0) {n=1; QD_neg(wmax,T,T);} CM_TWIST=(int) Round(Root(T[0],3)); if (n==1) CM_TWIST=-CM_TWIST;} else if (T[0]==54000.0) {CM_CASE=-12; QD_div1(wmax,Ec6,-19008.0,T); if (T[0]<0.0) {n=1; QD_neg(wmax,T,T);} CM_TWIST=(int) Round(Root(T[0],3)); if (n==1) CM_TWIST=-CM_TWIST;} else if (T[0]==287496.0) {CM_CASE=-16; QD_div1(wmax,Ec6,12096.0,T); if (T[0]<0.0) {n=1; QD_neg(wmax,T,T);} CM_TWIST=(int) Round(Root(T[0],3)); if (n==1) CM_TWIST=-CM_TWIST;} else if (T[0]==-884736.0) {CM_CASE=-19; QD_div1(wmax,Ec6,-77976.0,T); if (T[0]<0.0) {n=1; QD_neg(wmax,T,T);} CM_TWIST=(int) Round(Root(T[0],3)); if (n==1) CM_TWIST=-CM_TWIST;} else if (T[0]==-12288000.0) {CM_CASE=-27; QD_div1(wmax,Ec6,-54648.0,T); if (T[0]<0.0) {n=1; QD_neg(wmax,T,T);} CM_TWIST=(int) Round(Root(T[0],3)); if (n==1) CM_TWIST=-CM_TWIST;} else if (T[0]==16581375.0) {CM_CASE=-28; QD_div1(wmax,Ec6,75411.0,T); if (T[0]<0.0) {n=1; QD_neg(wmax,T,T);} CM_TWIST=(int) Round(Root(T[0],3)); if (n==1) CM_TWIST=-CM_TWIST;} else if (T[0]==-884736000.0) {CM_CASE=-43; QD_div1(wmax,Ec6,-8387064.0,T); if (T[0]<0.0) {n=1; QD_neg(wmax,T,T);} CM_TWIST=(int) Round(Root(T[0],3)); if (n==1) CM_TWIST=-CM_TWIST;} else if (T[0]==-147197952000.0) {CM_CASE=-67; QD_div1(wmax,Ec6,-210408408.0,T); if (T[0]<0.0) {n=1; QD_neg(wmax,T,T);} CM_TWIST=(int) Round(Root(T[0],3)); if (n==1) CM_TWIST=-CM_TWIST;} else if ((T[0]==-262537412640768000.0) && (T[1]==0.0)) {CM_CASE=-163; QD_div1(wmax,Ec6,-1066294102104.0,T); if (T[0]<0.0) {n=1; QD_neg(wmax,T,T);} CM_TWIST=(int) Round(Root(T[0],3)); if (n==1) CM_TWIST=-CM_TWIST;}} static void read_curve(char *S,int tw) {int i=0,n=0; QD T; if (DEBUG) printf("read_curve %s %i\n",S,tw); QD_copy(wmax,QD_zero,Ea1); QD_copy(wmax,QD_zero,T); ASSERT(S[0]=='['); QD_copy(wmax,QD_zero,Ea2); QD_copy(wmax,QD_zero,Ea3); QD_copy(wmax,QD_zero,Ea4); QD_copy(wmax,QD_zero,Ea6); i++; if (S[i]=='-') {n=1; i++;} while (S[i]!=',') {ASSERT(ISA_NUMBER(S[i])); T[0]=(double) (S[i]-'0'); QD_mul1(wmax,Ea1,10,Ea1); QD_add(wmax,Ea1,T,Ea1); i++;} if (n==1) QD_neg(wmax,Ea1,Ea1); n=0; i++; if (S[i]=='-') {n=1; i++;} while (S[i]!=',') {ASSERT(ISA_NUMBER(S[i])); T[0]=(double) (S[i]-'0'); QD_mul1(wmax,Ea2,10,Ea2); QD_add(wmax,Ea2,T,Ea2); i++;} if (n==1) QD_neg(wmax,Ea2,Ea2); n=0; i++; if (S[i]=='-') {n=1; i++;} while (S[i]!=',') {ASSERT(ISA_NUMBER(S[i])); T[0]=(double) (S[i]-'0'); QD_mul1(wmax,Ea3,10,Ea3); QD_add(wmax,Ea3,T,Ea3); i++;} if (n==1) QD_neg(wmax,Ea3,Ea3); n=0; i++; if (S[i]=='-') {n=1; i++;} while (S[i]!=',') {ASSERT(ISA_NUMBER(S[i])); T[0]=(double) (S[i]-'0'); QD_mul1(wmax,Ea4,10,Ea4); QD_add(wmax,Ea4,T,Ea4); i++;} if (n==1) QD_neg(wmax,Ea4,Ea4); n=0; i++; if (S[i]=='-') {n=1; i++;} while (S[i]!=']') {ASSERT(ISA_NUMBER(S[i])); T[0]=(double) (S[i]-'0'); QD_mul1(wmax,Ea6,10,Ea6); QD_add(wmax,Ea6,T,Ea6); i++;} if (n==1) QD_neg(wmax,Ea6,Ea6); n=0; from_a1a2a3a4a6(); QD_mul1(wmax,Ec4,(double) tw,Ec4); QD_mul1(wmax,Ec4,(double) tw,Ec4); QD_mul1(wmax,Ec6,(double) tw,Ec6); QD_mul1(wmax,Ec6,(double) tw,Ec6); QD_mul1(wmax,Ec6,(double) tw,Ec6); QD_mul1(wmax,Edisc,(double) tw,Edisc); QD_mul1(wmax,Edisc,(double) tw,Edisc); QD_mul1(wmax,Edisc,(double) tw,Edisc); QD_mul1(wmax,Edisc,(double) tw,Edisc); QD_mul1(wmax,Edisc,(double) tw,Edisc); QD_mul1(wmax,Edisc,(double) tw,Edisc); minimal_model_c4c6(); from_c4c6(); if (Abs(Ec4[0])>1e18) errorit("c4 invariant is too large"); if (Abs(Ec6[0])>1e27) errorit("c6 invariant is too large");} static void sn_curve(char *S,int tw) {char I[256],J[96],K[256]; int wh; llint sn; QD R,T,U; if (DEBUG) printf("sn_curve tw:%i %s",tw,S); sscanf(S,"%s %s %s",J,I,K); wh=atoi(I); sn=atoll(K); if ((sn>10000000) || (sn<-10000000)) errorit("Too large in sn_curve"); QD_copy(wmax,QD_zero,Ec4); QD_copy(wmax,QD_zero,Ec6); switch(wh) {case 1: Ec4[0]=(double) (sn*sn+48); if ((sn&3)==1) sn=-sn; Ec6[0]=(double) (sn*sn+72); QD_mul1(wmax,Ec6,(double) sn,Ec6); break; case 2: Ec4[0]=(double) (16*sn*sn+48); if ((sn&3)==1) sn=-sn; Ec6[0]=(double) (16*sn*sn+72); QD_mul1(wmax,Ec6,(double) (4*sn),Ec6); break; case 3: if ((sn&3)==1) sn=-sn; Ec4[0]=(double) (sn*sn+16*sn+16); Ec6[0]=(double) (sn*sn+16*sn-8); QD_mul1(wmax,Ec6,(double) (sn+8),Ec6); break; case 4: QD_copy(wmax,QD_zero,R); R[0]=(sn+3); QD_powi(wmax,R,4,T); QD_mul1(wmax,R,24.0,U); QD_sub(wmax,T,U,Ec4); QD_powi(wmax,R,6,T); QD_powi(wmax,R,3,U); QD_mul1(wmax,U,36.0,U); QD_sub(wmax,U,T,T); QD_copy(wmax,QD_zero,U); U[0]=216.0; QD_sub(wmax,T,U,Ec6); break; default: errorit("Unknown Neumann-Setzer type");} QD_round(wmax,Ec4,Ec4); QD_round(wmax,Ec6,Ec6); QD_round(wmax,Edisc,Edisc); QD_mul1(wmax,Ec4,(double) tw,Ec4); QD_mul1(wmax,Ec4,(double) tw,Ec4); QD_mul1(wmax,Ec6,(double) tw,Ec6); QD_mul1(wmax,Ec6,(double) tw,Ec6); QD_mul1(wmax,Ec6,(double) tw,Ec6); from_c4c6(); minimal_model_c4c6(); from_c4c6(); if (Abs(Ec4[0])>1e18) errorit("c4 invariant is too large"); if (Abs(Ec6[0])>1e27) errorit("c6 invariant is too large");} static void cm_curve(char *S,int tw) {char I[256],J[96]; int cm; if (DEBUG) printf("cm_curve tw:%i %s",tw,S); sscanf(S,"%s %s",J,I); cm=atoi(I); if (cm<0) cm=-cm; QD_copy(wmax,QD_zero,Ec4); QD_copy(wmax,QD_zero,Ec6); switch(cm) {case 3: Ec6[0]=-864.0; break; case 4: Ec4[0]=48.0; break; case 7: Ec4[0]=105.0; Ec6[0]=1323.0; break; case 8: Ec4[0]=160.0; Ec6[0]=-1792.0; break; case 11: Ec4[0]=352.0; Ec6[0]=-6776.0; break; case 12: Ec4[0]=720.0; Ec6[0]=-19008.0; break; case 16: Ec4[0]=528.0; Ec6[0]=-12096.0; break; case 19: Ec4[0]=1824.0; Ec6[0]=-77976.0; break; case 27: Ec4[0]=1440.0; Ec6[0]=-54648.0; break; case 28: Ec4[0]=1785.0; Ec6[0]=75411.0; break; case 43: Ec4[0]=41280.0; Ec6[0]=-8387064.0; break; case 67: Ec4[0]=353760.0; Ec6[0]=-210408408.0; break; case 163: Ec4[0]=104372160.0; Ec6[0]=-1066294102104.0; break; default: errorit("Unknown CM-type");} QD_mul1(wmax,Ec4,(double) tw,Ec4); QD_mul1(wmax,Ec4,(double) tw,Ec4); QD_mul1(wmax,Ec6,(double) tw,Ec6); QD_mul1(wmax,Ec6,(double) tw,Ec6); QD_mul1(wmax,Ec6,(double) tw,Ec6); from_c4c6(); minimal_model_c4c6(); from_c4c6(); if (Abs(Ec4[0])>1e18) errorit("c4 invariant is too large"); if (Abs(Ec6[0])>1e27) errorit("c6 invariant is too large");} static int get_twist(char *S) {char N[8],T[1024]; int u; sscanf(S,"%s %s",N,T); u=atoi(T); if (((u&3)==2) || ((u&3)==3)) return (4*u); return u;} void curve_init(char *S,char *LSTR) {char *T,*To,*U; int u,i=0,tw=1; QD X; LIST L; if (DEBUG) printf("curve_init %s %s\n",S,LSTR); T=malloc(1024); U=malloc(1024); strcpy(T,S); To=T; if (T[0]=='t') {tw=get_twist(T); sscanf(T+3,"%s",U); T+=(4+strlen(U));} if (T[0]=='[') read_curve(T,tw); else if (T[0]=='c') cm_curve(T,tw); else if (T[0]=='s') sn_curve(T,tw); else if (T[0]=='n') sn_curve(T,tw); else errorit("Input appears to be bogus"); free(To); free(U); printf("Minimal model of curve %s is [",LSTR); QD_intout_noplus(Ea1); printf(","); QD_intout_noplus(Ea2); printf(","); QD_intout_noplus(Ea3); printf(","); QD_intout_noplus(Ea4); printf(","); QD_intout_noplus(Ea6); printf("]\n"); if (Edisc[0]<0.0) QD_neg(wmax,Edisc,X); else QD_copy(wmax,Edisc,X); L.p[0]=0; COND0=1; QD_factor(X,&L); for (u=0;u<32;u++) badprimes[u]=0; for (u=0;u<32;u++) badprimetype[u]=0; for (i=0;L.p[i]!=0;i++) {badprimes[i]=L.p[i]; badprimetype[i]=do_badprime(L.p[i]); if (VERBOSE) {printf("At %lli: Inertia Group is ",badprimes[i]); badprimetype_output(badprimetype[i],badprimes[i]);}} if (VERBOSE) printf("Conductor is %lli\n",COND0); CM_CASE=0; check_cm(); mintwist(); NO_QT&=is_nonmintwist(); do_periods(); if (VERBOSE>=2) {printf("rp: "); QD_output(4,64,REAL_PERIOD); printf("ip: "); QD_output(4,64,IMAG_PERIOD);}} sympow-1.019/main.c0000644017361200001450000000727110442324213014031 0ustar tabbottcrontab#include "sympow.h" #define DEBUG (FALSE || GLOBAL_DEBUG) int main(int argc,char **argv) {char INSTRING[1024]="2w3s1p32,3bp16d1,4p8\0",CSTR[1024]="\0",LSTR[1024]="\0"; char TYPE[16]; int i=1; llint NT,UB=(((llint) 1)<<45); int NO_CM=FALSE,info=0,ROOTNO=FALSE,SLOPPY=0,QD_CHECK; NO_QT=FALSE; VERBOSE=TRUE; GLOBAL=TRUE; HECKE=FALSE; TWIST=FALSE; AP_SAVE=0; CM_CASE=FALSE; GET=malloc(1024); COND0=1; fp3=0; fp2=0; MAX_TABLE=1<<27; MODDEG=FALSE; ANAL_RANK=FALSE; ZEROCHECK=FALSE; RERUN=FALSE; QD_CHECK=TRUE; #ifdef x86 fpu_53bits(); #endif strcpy(TYPE,"RELEASE"); MD_SPEED=2.0; while(i=2) printf("NUM_SUMS is %i\n",NUM_SUMS); if (NUM_SUMS>CURR_MAX) errorit("Too many sums!"); if (NUM_SUMS==0) printf("Nothing to do!\n"); fflush(stdout); if (GLOBAL && NUM_SUMS) go(NT,NT); if (ZEROCHECK) {NUM_SUMS=0; WHICH=0; free_data(); RERUN=TRUE; NT=process_string(INSTRING,UB); go(NT,NT);} return 0;} sympow-1.019/moddeg.c0000644017361200001450000002007610442324213014342 0ustar tabbottcrontab#include "sympow.h" #define DEBUG (FALSE || GLOBAL_DEBUG) static void prep_moddeg_at2(int bpt) {double ap; int c4,c6,D,M=1<<29; QDpoly v; if ((bpt==3) || (bpt==20) || (bpt==21) || (bpt==23)) {EVEN_TOP=3; EVEN_BOTTOM=2;} if (bpt==22) {EVEN_TOP=1; EVEN_BOTTOM=2;} if ((bpt==1) || (bpt==3) || (bpt==8) || (bpt==9) || (bpt==24)) return; c4=QD_modi(Ec4,M); c6=QD_modi(Ec6,M); D=QD_modi(Edisc,M); if ((bpt==10) || (bpt==22) || (bpt==23)) {if (((c4&63)!=31) || ((c6&255)!=0)) {QD_mul1(wmax,VOLUME,2.0,VOLUME); QD_mul1(wmax,TW_EFF,2.0,TW_EFF);} return;} if (bpt==16) {CONDTW/=16; QD_mul1(wmax,VOLUME,4.0,VOLUME); euler_factor_bad(2,bpt,2,&v); ap=Round(Sqrt(-v.coeff[1][0]+2.0)); QD_mul1(wmax,TW_EFF,72.0-8.0*ap*ap,TW_EFF); delQDpoly(&v); return;} if (bpt==17) {CONDTW/=64; if (((c6&127)==64) && ((c4&63)==0)) QD_mul1(wmax,VOLUME,2.0,VOLUME); else QD_mul1(wmax,VOLUME,8.0,VOLUME); euler_factor_bad(2,bpt,2,&v); ap=Round(Sqrt(-v.coeff[1][0]+2.0)); QD_mul1(wmax,TW_EFF,9.0-ap*ap,TW_EFF); delQDpoly(&v); if (((c6&127)==64) && ((c4&63)==0)) QD_mul1(wmax,TW_EFF,16.0,TW_EFF); else QD_mul1(wmax,TW_EFF,64.0,TW_EFF); return;} if (bpt==20) {CONDTW/=4; QD_mul1(wmax,TW_EFF,4.0,TW_EFF); return;} if (bpt==21) {QD_mul1(wmax,VOLUME,2.0,VOLUME); CONDTW/=16; QD_mul1(wmax,TW_EFF,32.0,TW_EFF); return;} if (bpt==25) {CONDTW/=2; QD_mul1(wmax,TW_EFF,2.0,TW_EFF); return;} if (bpt==26) {QD_mul1(wmax,VOLUME,2.0,VOLUME); CONDTW/=8; QD_mul1(wmax,TW_EFF,16.0,TW_EFF); return;} if (bpt==27) {if (((c4&63)==0) && ((c6&255)==0)) {QD_mul1(wmax,VOLUME,2.0,VOLUME); QD_mul1(wmax,TW_EFF,2.0,TW_EFF);} return;} if (bpt==29) /* v2(N)=6 multiplicative twist */ {CONDTW/=32; QD_mul1(wmax,VOLUME,4.0,VOLUME); QD_mul1(wmax,TW_EFF,96.0,TW_EFF); return;} if (bpt==30) /* v2(N)=4 multiplicative twist */ {CONDTW/=8; QD_mul1(wmax,VOLUME,4.0,VOLUME); QD_mul1(wmax,TW_EFF,24.0,TW_EFF); return;} errorit("bad prime type at 2 in prep_moddeg_at2");} static llint is_square(llint x) {llint y; if (x<0) return 0; y=(llint) Round(Sqrt((double) x)); if (y*y==x) return y; return 0;} static void isogcheck3(int n) {int i,u=(n+3),v=0; QD U,V,W,R; llint p,q; if (DEBUG) printf("isogcheck3 %i\n",n); q=(llint) n; q=q*q+9*q+27; for (i=0;badprimes[i]!=0;i++) {p=badprimes[i]; if (((CONDTW%p)==0) && ((n%p)==0) && ((p%6)==1)) return; if ((q%p)==0) v++;} if (v!=1) return; QD_copy(wmax,QD_zero,U); U[0]=(double) u; QD_powi(wmax,U,4,V); QD_mul1(wmax,U,24.0,W); QD_sub(wmax,V,W,R); QD_round(wmax,R,R); QD_sub(wmax,Etw4,R,R); if (R[0]!=0.0) return; QD_powi(wmax,U,6,V); QD_powi(wmax,U,3,W); QD_mul1(wmax,W,36.0,W); QD_sub(wmax,W,V,W); QD_copy(wmax,QD_zero,V); V[0]=-216.0; QD_add(wmax,W,V,R); QD_sub(wmax,Etw6,R,R); if (R[0]!=0.0) return; MANIN_TWIST=9; if (Ec6[0]==Etw6[0]) MANIN=9; return;} static void check_manin() {QD T,U,R; llint p,bp[32]; int i,n,tau=0; if (DEBUG) printf("check_manin\n"); MANIN=1; MANIN_TWIST=1; if (CONDTW==11) {if (Etw4[0]==16.0) {MANIN_TWIST=25; if (Ec4[0]==16.0) MANIN=25;} return;} if (CONDTW==15) {if (Etw4[0]==1.0) {MANIN_TWIST=16; if (Ec4[0]==1.0) MANIN=16;} if (Etw4[0]==241.0) {MANIN_TWIST=4; if (Ec4[0]==241.0) MANIN=4;} if (Etw4[0]==3841.0) {MANIN_TWIST=4; if (Ec4[0]==3841.0) MANIN=4;} return;} if (CONDTW==17) {if (Etw6[0]==-81.0) {MANIN_TWIST=16; if (Ec6[0]==-81.0) MANIN=16;} if (Etw4[0]==273.0) {MANIN_TWIST=4; if (Ec4[0]==273.0) MANIN=4;} if (Etw4[0]==4353.0) {MANIN_TWIST=4; if (Ec4[0]==4353.0) MANIN=4;} return;} if (CONDTW==20) {if (Etw4[0]==64.0) {MANIN_TWIST=4; if (Ec4[0]==64.0) MANIN=4;} if (Etw4[0]==1984.0) {MANIN_TWIST=4; if (Ec4[0]==1984.0) MANIN=4;} return;} if (CONDTW==24) {if (Etw4[0]==-32.0) {MANIN_TWIST=4; if (Ec4[0]==-32.0) MANIN=4;} return;} if (CONDTW==32) {if (Ec6[0]==0.0) {MANIN_TWIST=4; if ((COND0==32) && (QD_modi(Ec4,32)==16)) MANIN=4;} else {MANIN_TWIST=4; if (COND0==32) MANIN=4;} return;} if (CONDTW==40) {if (Etw4[0]==96.0) {MANIN_TWIST=4; if (Ec4[0]==96.0) MANIN=4;} return;} if (CONDTW==64) {if (Ec6[0]==0.0) {MANIN_TWIST=4; if ((COND0==64) && (QD_modi(Ec4,32)==16)) MANIN=4;} return;} if (CONDTW==128) {if (Etw4[0]==112.0) {MANIN_TWIST=4; if ((COND0==128) && (QD_modi(Ec4,32)==16)) MANIN=4;} return;} /* 3-isog case */ for (n=-10;n<=10;n++) {if (EtwD[0]==(double) (n*(n*n+9*n+27))) isogcheck3(n);} QD_copy(wmax,QD_zero,R); if (EtwD[0]>0.0) R[0]=Round(Root(EtwD[0],3)-3); else R[0]=-Round(Root(-EtwD[0],3)+3); QD_sqr(wmax,R,T); QD_mul1(wmax,R,9.0,U); QD_add(wmax,T,U,T); QD_copy(wmax,QD_zero,U); U[0]=27.0; QD_add(wmax,T,U,T); QD_mul(wmax,T,R,T); QD_round(wmax,T,T); QD_sub(wmax,T,EtwD,U); if (U[0]==0.0) isogcheck3((int) R[0]); for (i=0;badprimes[i]!=0;i++) if ((CONDTW%badprimes[i])==0) bp[tau++]=badprimes[i]; if (tau>2) return; if (tau==1) /* original neumann-setzer case, don't check c6 */ {if (!(is_square(CONDTW-64))) return; if ((CONDTW-16)==(llint) Etw4[0]) {MANIN_TWIST=4; if (Ec4[0]==Etw4[0]) MANIN=4; return;} return;} if (CONDTW&1) /* Third NS case bad for curves with big Etw6 */ {if (Etw4[0]<-48.0) return; p=(llint) Round(Sqrt(Etw4[0]+48.0)); if ((p&3)!=3) p=-p; p-=8; if ((p*p+16*p+16)!=(llint) Etw4[0]) return; if ((p*p*p+24*p*p+120*p-64)!=(llint) Etw6[0]) return; if (((bp[0]&3)!=3) && ((bp[1]&3)!=3)) return; if (((p%bp[0])!=0) && ((p%bp[1])!=0)) return; if ((((p+16)%bp[0])!=0) && (((p+16)%bp[1])!=0)) return; MANIN_TWIST=4; if (Ec4[0]==Etw4[0]) MANIN=4; return;} if ((CONDTW&7)!=4) return; if (!(is_square(CONDTW/4-4))) return; if ((4*CONDTW-16)==(llint) Etw4[0]) /* second NS case, again ignore c6 */ {MANIN_TWIST=4; if (Ec4[0]==Etw4[0]) MANIN=4;}} void prepare_moddeg(char *IN) {int i,s,bpt,v4,v6,vd; llint p; QDpoly v; double ap,P; QD C; QD_mul(wmax,REAL_PERIOD,IMAG_PERIOD,VOLUME); QD_mul(wmax,VOLUME,QD_twopi,VOLUME); EVEN_TOP=1; EVEN_BOTTOM=1; QD_copy(wmax,QD_one,TW_EFF); CONDTW=COND0; for (i=0;badprimes[i]!=0;i++) {p=badprimes[i]; bpt=badprimetype[i]; P=(double) p; if (p>=3) {if (bpt==2) {QD_mul1(wmax,VOLUME,P,VOLUME); CONDTW/=(p*p); euler_factor_bad(p,bpt,2,&v); ap=Round(Sqrt(-v.coeff[1][0]+P)); QD_mul1(wmax,TW_EFF,P-1.0,TW_EFF); QD_mul1(wmax,TW_EFF,P+1.0-ap,TW_EFF); QD_mul1(wmax,TW_EFF,P+1.0+ap,TW_EFF); delQDpoly(&v);} else if (bpt==31) {QD_mul1(wmax,VOLUME,P,VOLUME); CONDTW/=p; QD_mul1(wmax,TW_EFF,P+1.0,TW_EFF); QD_mul1(wmax,TW_EFF,P-1.0,TW_EFF);} else if (bpt!=1) {v4=QD_valuation(Ec4,P); v6=QD_valuation(Ec6,P); vd=QD_valuation(Edisc,P); if ((v4>=2) && (v6>=3) && ((p!=3) || ((vd>=6) && (v6!=5)))) {QD_mul1(wmax,VOLUME,P,VOLUME); QD_mul1(wmax,TW_EFF,P,TW_EFF);}} if ((bpt>=3) && (bpt<=6)) {if ((p%bpt)==1) {EVEN_TOP*=(p-1); EVEN_BOTTOM*=p;} else {EVEN_TOP*=(p+1); EVEN_BOTTOM*=p;}} if ((bpt==14) || (bpt==15)) {EVEN_TOP*=2; EVEN_BOTTOM*=3;} if ((bpt==18) || (bpt==19)) {EVEN_TOP*=4; EVEN_BOTTOM*=3;}} if (p==2) prep_moddeg_at2(bpt);} IN[0]='2'; IN[1]='w'; IN[2]='0'; IN[3]='p'; QD_copy(wmax,QD_zero,C); C[0]=(double) CONDTW; QD_div(wmax,C,VOLUME,SCALE); if (CM_CASE==-3) {QD_mul(wmax,SCALE,QD_pi,SCALE); C[0]=27.0; QD_sqrt(wmax,C,C); QD_div(wmax,SCALE,C,SCALE); HECKE=TRUE;} if (CM_CASE==-4) {QD_mul(wmax,SCALE,QD_pi,SCALE); QD_mul2n(wmax,SCALE,-2,SCALE); HECKE=TRUE;} s=4+Ceil(Log10(SCALE[0])); if (s<6) s=6; if ((s>12) && (s<=16)) s=17; if (s>28) {s=28; printf("*WARNING* reducing moddeg precision to 28");} if (s<10) {IN[4]='0'+s; IN[5]=0;} else {IN[4]='0'+(s/10); IN[5]='0'+(s%10); IN[6]=0;} if (VERBOSE) {printf("Twist effect is "); QD_intout_noplus(TW_EFF); printf(", Even valuation gives %lli/%lli\n",EVEN_TOP,EVEN_BOTTOM);} if (VERBOSE) printf("Twist conductor is %lli\n",CONDTW); if (VERBOSE) printf("Using precision of %i digits\n",s); check_manin(); if (MANIN!=1) printf("Manin effect for curve is %i\n",MANIN); if (MANIN_TWIST!=1) printf("Manin effect for twist is %i\n",MANIN_TWIST);} llint postpare_moddeg() {QD C,D,W; double L; llint N=CONDTW/10; QD_copy(wmax,QD_zero,C); QD_copy(wmax,QD_zero,W); C[0]=(double) CONDTW; QD_div(wmax,C,VOLUME,C); while (1) {get_weight(N,W,0); QD_mul(wmax,C,W,D); L=Log((double) N); L*=L; QD_mul1(wmax,D,L,D); QD_mul1(wmax,D,(double) N,D); QD_mul1(wmax,D,(double) N,D); if (D[0]<0.5) break; N=(11*N)/10;} return(N);} sympow-1.019/new_data0000755017361200001450000000150110442324213014437 0ustar tabbottcrontab#! /bin/sh # # This script should not need to be run directly, # but will be automatically executed via "./sympow -new_data []" # # example direct usages # sh new_data /bin/sh /usr/bin/gp '-sp 3 -dv 2' # sh new_data /bin/sh /usr/bin/gp '-cm -sp 4' # sh new_data /bin/sh /usr/bin/gp '-sp 2' # sh new_data /bin/sh /usr/bin/gp '-hecke -sp 3 -dv 1' if [ $# != 3 ]; then echo "**ERROR**: Wrong number of input parameters"; exit; fi echo "Running the new_data script for $3" SH=$1 && GP=$2 echo "Making the datafiles for $3" && echo "" && ./sympow -rewarp && ./sympow -shell1 "$3" && ./sympow -shell1 "$3" | $SH && echo 'Running the gp script' && echo "" && ./sympow -pari "$3" && ./sympow -pari "$3" | $GP -q > /dev/null && echo "" && ./sympow -shell2 "$3" && ./sympow -shell2 "$3" | $SH && ./sympow -rewarp && echo "Finished with $3" sympow-1.019/periods.c0000644017361200001450000000517710442324213014555 0ustar tabbottcrontab#include "sympow.h" #define DEBUG (FALSE || GLOBAL_DEBUG) static void real_root(QD r1) {QD U,R,A3,sU,T,cS,cT,M,isU,O,V,S; if (DEBUG) printf("real root\n"); QD_div1(wmax,Edisc,-1728.0,U); QD_div1(wmax,Ec6,1728.0,R); QD_div1(wmax,Eb2,12.0,A3); if (U[0]>0.0) /* negative discriminant */ {QD_sqrt(wmax,U,sU); QD_add(wmax,R,sU,S); QD_sub(wmax,R,sU,T); QD_cbrt(wmax,S,cS); QD_cbrt(wmax,T,cT); QD_add(wmax,cS,cT,T); QD_sub(wmax,T,A3,r1); return;} QD_neg(wmax,U,U); QD_sqr(wmax,R,T); QD_add(wmax,T,U,T); QD_sqrt(wmax,T,M); if (R[0]==0.0) {QD_copy(wmax,QD_pi,O); QD_mul2n(wmax,O,-1,O);} else {QD_sqrt(wmax,U,isU); QD_div(wmax,isU,R,T); QD_atan(wmax,T,O); if (O[0]<0.0) QD_add(wmax,O,QD_pi,O);} QD_div1(wmax,O,3.0,O); QD_cos(wmax,O,T); QD_cbrt(wmax,M,U); QD_mul(wmax,T,U,V); QD_mul2n(wmax,V,1,T); QD_sub(wmax,T,A3,r1);} static void more_roots(QD r1,QD r2,QD r3) {QD A,b,Z,T,c,U,D,F,S; if (DEBUG) printf("more roots\n"); QD_mul2n(wmax,Eb2,-2,A); QD_add(wmax,A,r1,b); QD_mul2n(wmax,Eb4,-1,Z); QD_mul(wmax,b,r1,T); QD_add(wmax,T,Z,c); QD_sqr(wmax,b,T); QD_mul2n(wmax,c,2,U); QD_sub(wmax,T,U,D); QD_sqrt(wmax,D,S); QD_neg(wmax,b,F); QD_add(wmax,F,S,r2); QD_mul2n(wmax,r2,-1,r2); QD_sub(wmax,F,S,r3); QD_mul2n(wmax,r3,-1,r3);} void do_periods() {QD a,r1,r2,r3,r12,r13,r23,p1,p2,t; QD T,A,B,NB,P1,P2,E1,E2,E3; if (Edisc[0]>0.0) {real_root(r1); more_roots(r1,r2,r3); if (r1[0]=EXPAND0_LIM[which]) get_wt_large(which,x,R,1,NUM_SUMS); if (R[0]>TAR) x[0]=x[0]+x[0]; else break;} STEP=x[0]*0.25; R[0]=1.0; x[0]-=STEP; STEP*=0.5; for (i=0;i<10;i++) {if (x[0]>=EXPAND0_LIM[which]) get_wt_large(which,x,R,1,NUM_SUMS); if (R[0]1e15) return (((llint) 1)<<50); return (llint) (x[0]/DECAY[s][0]);} static llint prepare_decay_hecke(int s,int W,int sl) {QD o; if (DEBUG) printf("pdh %i %i %i\n",s,W,sl); if (!GLOBAL) return 0; QD_sqr(W,QD_twopi,o); QD_div(W,o,COND[s],o); QD_sqrt(W,o,DECAY[s]); if (VERBOSE>=2) {printf("DCY %i ",s); QD_output(W,wprec[NUM_SUMS],DECAY[s]);} return num_terms(s,sl);} llint prepare_decay(int s,int W,int sl) {QD o; if (DEBUG) printf("prepare_decay %i %i %i\n",s,W,sl); if (!GLOBAL) return 0; QD_powi(W,QD_twopi,s,o); if (s&1) QD_mul(W,o,QD_twopi,o); else QD_mul(W,o,QD_pi,o); QD_div(W,o,COND[s],o); QD_sqrt(W,o,DECAY[s]); if (VERBOSE>=2) {printf("DCY %i ",s); QD_output(W,wprec[NUM_SUMS],DECAY[s]);} return num_terms(s,sl);} static llint prepare_sympow_hecke(int sp,int dv,int sl) {llint NT=-1; ASSERT(CM_CASE!=0); if (DEBUG) printf("psh %i %i %i\n",sp,dv,sl); if (sp&1) {whi[NUM_SUMS]=wlo[NUM_SUMS]=WHICH; load_files_hecke(WHICH,sp,1+sp/2,dv); WHICH++;} else {wlo[NUM_SUMS]=WHICH; WHICH++; whi[NUM_SUMS]=WHICH; load_files_hecke(wlo[NUM_SUMS],sp,sp/2,dv); load_files_hecke(whi[NUM_SUMS],sp,1+sp/2,dv); WHICH++;} if (COND[sp][0]==0.0) compute_conductor_hecke(sp); NT=prepare_decay_hecke(sp,w[NUM_SUMS],sl); if (VERBOSE) printf("NT %id%i: %lli\n",sp,dv,NT); NUM_SUMS++; return NT;} static llint prepare_sympow_check_hecke (int sp,int dv,int prec,int nw,int sl,int bk) {int i,W; llint NT; QD wig; if (DEBUG) printf("psch %i %i %i %i %i %i\n",sp,dv,prec,nw,sl,bk); wprec[NUM_SUMS]=prec; W=w[NUM_SUMS]=1+((prec-1)>>4); NUM_WIGS[NUM_SUMS]=nw; QD_copy(W,QD_one,WIGGLE[NUM_SUMS]); QD_copy(W,QD_one,WIGSQI[NUM_SUMS]); BLOCH_KATO[NUM_SUMS]=bk; NT=prepare_sympow_hecke(sp,dv,sl); if (!GLOBAL) return NT; for (i=0;i=2) {printf("wiggle %i ",i); QD_output(W,16*W,wig);} whi[NUM_SUMS]=whi[NUM_SUMS-1]; wlo[NUM_SUMS]=wlo[NUM_SUMS-1]; BLOCH_KATO[NUM_SUMS]=BLOCH_KATO[NUM_SUMS-1]; QD_copy(W,wig,WIGGLE[NUM_SUMS]); QD_div(W,QD_one,wig,WIGSQI[NUM_SUMS]); QD_sqr(W,WIGSQI[NUM_SUMS],WIGSQI[NUM_SUMS]); NUM_WIGS[NUM_SUMS]=nw; if (VERBOSE>=2) {printf("wigsqi %i ",i); QD_output(W,16*W,WIGSQI[NUM_SUMS]);} NUM_SUMS++;} return NT;} static llint prepare_sympow(int sp,int dv,int sl) {llint NT=-1; if (DEBUG) printf("prepare_sympow %i %i %i\n",sp,dv,sl); if (sp&1) {whi[NUM_SUMS]=wlo[NUM_SUMS]=WHICH; load_files(WHICH,sp,(sp+1)>>1,dv); WHICH++;} else {wlo[NUM_SUMS]=WHICH; WHICH++; whi[NUM_SUMS]=WHICH; load_files(wlo[NUM_SUMS],sp,sp>>1,dv); load_files(whi[NUM_SUMS],sp,1+(sp>>1),dv); WHICH++;} if (COND[sp][0]==0.0) compute_conductor(sp); NT=prepare_decay(sp,w[NUM_SUMS],sl); if (VERBOSE) printf("NT %id%i: %lli\n",sp,dv,NT); NUM_SUMS++; return NT;} static llint prepare_sympow_check(int sp,int dv,int prec,int nw,int sl,int bk) {int i,W; llint NT; QD wig; if (DEBUG) printf("psc %i %i %i %i %i %i\n",sp,dv,prec,nw,sl,bk); if (HECKE) return prepare_sympow_check_hecke(sp,dv,prec,nw,sl,bk); wprec[NUM_SUMS]=prec; W=w[NUM_SUMS]=1+((prec-1)>>4); NUM_WIGS[NUM_SUMS]=nw; QD_copy(W,QD_one,WIGGLE[NUM_SUMS]); QD_copy(W,QD_one,WIGSQI[NUM_SUMS]); BLOCH_KATO[NUM_SUMS]=bk; NT=prepare_sympow(sp,dv,sl); if (!GLOBAL) return NT; for (i=0;i=2) {printf("wiggle %i ",i); QD_output(W,16*W,wig);} whi[NUM_SUMS]=whi[NUM_SUMS-1]; wlo[NUM_SUMS]=wlo[NUM_SUMS-1]; BLOCH_KATO[NUM_SUMS]=BLOCH_KATO[NUM_SUMS-1]; QD_copy(W,wig,WIGGLE[NUM_SUMS]); QD_div(W,QD_one,wig,WIGSQI[NUM_SUMS]); QD_sqr(W,WIGSQI[NUM_SUMS],WIGSQI[NUM_SUMS]); NUM_WIGS[NUM_SUMS]=nw; if (VERBOSE>=2) {printf("wigsqi %i ",i); QD_output(W,16*W,WIGSQI[NUM_SUMS]);} NUM_SUMS++;} return NT;} llint process_string(char *IN,llint UB) {llint NT=0,nt,CP; char LAST[256],*NEXT,*CURR,*c,*n,COMMA[2]=",\0"; int i,prec,sp,lim=0,nwigs,dvs=0,sl,bk,DO; c=CURR=malloc(256); n=NEXT=malloc(256); strcpy(CURR,IN); do {strcpy(LAST,CURR); ASSERT(ISA_NUMBER(CURR[0])); if (!ISA_NUMBER(CURR[1])) sp=(int) (CURR[0]-'0'); else {sp=(int) ((CURR[0]-'0')*10+(CURR[1]-'0')); CURR++;} nwigs=1; CURR++; CP=NT; sl=0; bk=0; DO=FALSE; if (CURR[0]=='b') {bk=1; CURR++;} if (CURR[0]=='w') {nwigs=CURR[1]-'0'; CURR+=2;} if (CURR[0]=='s') {sl=CURR[1]-'0'; CURR+=2;} if (CURR[0]=='P') {DO=TRUE;} else ASSERT(CURR[0]=='p'); if (CURR[1]=='z') {if (!RERUN) {prec=6; ZEROCHECK=1;} else {prec=12; ZEROCHECK=0;} CURR+=2;} else {if (ISA_NUMBER(CURR[2])) {prec=10*(CURR[1]-'0')+(CURR[2]-'0'); CURR+=3;} else {prec=(CURR[1]-'0'); CURR+=2;}} if ((sp&1)==0) {if ((CURR[0]=='d') || (CURR[0]=='D')) errorit("Derivative with even power"); dvs=1; nt=prepare_sympow_check(sp,0,prec,nwigs,sl,bk); if (nt>NT) NT=nt;} else {if (CURR[0]=='D') {lim=CURR[1]-'0'; CURR+=2; dvs=1; nt=prepare_sympow_check(sp,lim,prec,nwigs,sl,bk); if (nt>NT) NT=nt;} else {ASSERT(CURR[0]=='d'); lim=CURR[1]-'0'; CURR+=2; dvs=(lim+1); for (i=0;i<=lim;i++) {nt=prepare_sympow_check(sp,i,prec,nwigs,sl,bk); if (nt>NT) NT=nt;}}} if ((NT>UB) && (DO)) UB=NT; if ((NT>UB) || (((sp&1)==0) && NO_QT)) {for (i=0;((LAST[i]!=0) && (LAST[i]!=','));i++); LAST[i]=0; if (VERBOSE) {if (NT>UB) printf("Ignoring %s due to bound\n",LAST); else printf("Ignoring %s since curve is non qtwist-minimal\n",LAST);} NT=CP; NUM_SUMS-=dvs*(1+nwigs);} else CP=NT; NEXT=strstr(CURR,COMMA); CURR=NEXT+1; } while(NEXT); free(c); free(n); return(NT);} llint preparation(int K,char *IN,llint UB) {int i; llint NT; POWSER=malloc(K*sizeof(QD**)); TABLE=malloc(K*sizeof(QD**)); SYMPOW=malloc(K*sizeof(int)); evalpt=malloc(K*sizeof(int)); BLOCH_KATO=malloc(K*sizeof(int)); MESH_COUNT=malloc(K*sizeof(int)); whi=malloc(K*sizeof(int)); wlo=malloc(K*sizeof(int)); derivative=malloc(K*sizeof(int)); HALF_ZERO=malloc(K*sizeof(QD)); WIGGLE=malloc(K*sizeof(QD)); WIGSQI=malloc(K*sizeof(QD)); EXPAND0_LIM=malloc(K*sizeof(QD)); STEP_SIZE=malloc(K*sizeof(QD)); TOO_BIG=malloc(K*sizeof(QD)); NUM_LOGS=malloc(K*sizeof(QD)); TACKON=malloc(K*sizeof(int)); TACKS=malloc(K*sizeof(QD*)); w=malloc(K*sizeof(int)); wprec=malloc(K*sizeof(int)); DECAY=malloc(K*sizeof(QD)); NUM_WIGS=malloc(K*sizeof(QD)); for (i=0;i0.0) NT=(llint) ((double) NT/MD_SPEED); else NT=postpare_moddeg();} printf("Maximal number of terms is %lli\n",NT); if (NT0) {ll=l; C=2.0; for (l>>=1;l>0;l>>=1) {C*=C; if (l&1) M=M*C;} if (ll&1) M*=2.0;} else if (l<0) {l=-l; ll=l; C=0.5; for (l>>=1;l>0;l>>=1) {C*=C; if (l&1) M=M*C;} if (ll&1) M/=2.0;} return M;} void QD_add(int n,QD a,QD b,QD c) {switch(n) {case 1: {c[0]=a[0]+b[0]; return;} case 2: {QD_add_22(a,b,c); return;} case 3: {QD_add_33(a,b,c); return;} case 4: {QD_add_44(a,b,c); return;}}} void QD_sub(int n,QD a,QD b,QD c) {switch(n) {case 1: {c[0]=a[0]-b[0]; return;} case 2: {QD_sub_22(a,b,c); return;} case 3: {QD_sub_33(a,b,c); return;} case 4: {QD_sub_44(a,b,c); return;}}} void QD_mul(int n,QD a,QD b,QD c) {switch(n) {case 1: {c[0]=a[0]*b[0]; return;} case 2: {QD_mul_22(a,b,c); return;} case 3: {QD_mul_33(a,b,c); return;} case 4: {QD_mul_44(a,b,c); return;}}} void QD_div(int n,QD a,QD b,QD c) {switch(n) {case 1: {c[0]=a[0]/b[0]; return;} case 2: {QD_div_22(a,b,c); return;} case 3: {QD_div_33(a,b,c); return;} case 4: {QD_div_44(a,b,c); return;}}} void QD_mul1(int n,QD a,double b,QD c) {switch(n) {case 1: {c[0]=a[0]*b; return;} case 2: {QD_mul_21(a,b,c); return;} case 3: {QD_mul_31(a,b,c); return;} case 4: {QD_mul_41(a,b,c); return;}}} void QD_div1(int n,QD a,double b,QD c) {switch(n) {case 1: {c[0]=a[0]/b; return;} case 2: {QD_div_21(a,b,c); return;} case 3: {QD_div_31(a,b,c); return;} case 4: {QD_div_41(a,b,c); return;}}} void QD_sqr(int n,QD i,QD o) {switch(n) {case 1: {o[0]=i[0]*i[0]; return;} case 2: {QD_sqr_2(i,o); return;} case 3: {QD_sqr_3(i,o); return;} case 4: {QD_sqr_4(i,o); return;}}} void QD_copy(int n,QD i,QD o) {int j; for (j=0;j=709.0) {QD_copy(n,QD_zero,b); return;} if (n==1) b[0]=Exp(a[0]); QD_div(n,a,QD_log2,t); l=(int) Round(t[0]); QD_mul1(n,QD_log2,(double) l,t); QD_sub(n,a,t,s); C=QD_2pow(2*n+2); for (i=0;iC); for (i=0;i<2*n+2;i++) QD_sqr(n,s,s); M=QD_2pow(l); for (i=0;i0.0) for (i=0;i0) QD_div(n,b,p,b); if (e<0) QD_mul(n,b,p,b); if (b[0]>10.0) {QD_div(n,b,T,b); e++;} else if (b[0]<1.0) {QD_mul(n,b,T,b); e--;} for (i=0;i<=d;i++) {Z[i]=(int) Floor(b[0]); U[0]=(double) Z[i]; QD_sub(n,b,U,b); QD_mul(n,b,T,b);} for (i=d;i>0;i--) if (Z[i]<0) {Z[i-1]--; Z[i]+=10;} if (Z[d]>=5) {Z[d-1]++; i=d-1; while (i>0 && Z[i]>=10) {Z[i]-=10; Z[--i]++;}} i=0; if (a[0]<0.0) S[i++]='-'; if (Z[0]==10) {S[i++]='1'; S[i++]='.'; S[i++]='0'; e++;} else {S[i++]=QD_digit[Z[0]]; S[i++]='.';} for (j=1;j=2.0) {a/=2.0; e++;} printf("1."); y=a-1.0; y=y*16.0; for (i=0;i<13;i++) {l=(int) Floor(y); printf("%c",QD_digit[l]); y=y-(double) l; y=y*16.0;} printf("E%i\n",e);} void QD_floorQD(int n,QD i,QD o) {double x0,x1=0.0,x2=0.0,x3=0.0; x0=Floor(i[0]); if (x0==i[0] && n>1) {x1=Floor(i[1]); if (x1==i[1] && n>2) {x2=Floor(i[2]); if (x2==i[2] && n>3) x3=Floor(i[3]);}} if (n==1) o[0]=x0; if (n==2) QD_qsum(x0,x1,o[0],o[1]); if (n==3) QD_renorm_3(x0,x1,x2,o); if (n==4) QD_renorm_4(x0,x1,x2,x3,o);} void QD_round(int n,QD i,QD o) {double x0,x1=0.0,x2=0.0,x3=0.0; x0=Round(i[0]); if (x0==i[0] && n>1) {x1=Round(i[1]); if (x1==i[1] && n>2) {x2=Round(i[2]); if (x2==i[2] && n>3) x3=Round(i[3]);}} if (n==1) o[0]=x0; if (n==2) QD_qsum(x0,x1,o[0],o[1]); if (n==3) QD_renorm_3(x0,x1,x2,o); if (n==4) QD_renorm_4(x0,x1,x2,x3,o);} void QD_self_renorm(int w,QD A) {double t; if (w==2) {QD_qsum(A[0],A[1],t,A[1]); A[0]=t;} if (w==3) QD_renorm_3(A[0],A[1],A[2],A); if (w==4) QD_renorm_4(A[0],A[1],A[2],A[3],A);} void QD_powi(int n,QD i,int p,QD o) {QD c,t; int l=p,ll; switch(p) {case 0: QD_copy(n,QD_one,o); return; case 1: QD_copy(n,i,o); return; case 2: QD_sqr(n,i,o); return; case 3: QD_sqr(n,i,c); QD_mul(n,c,i,o); return; case 4: QD_sqr(n,i,c); QD_sqr(n,c,o); return; case 5: QD_sqr(n,i,c); QD_sqr(n,c,c); QD_mul(n,c,i,o); return; case 6: QD_sqr(n,i,c); QD_mul(n,c,i,c); QD_sqr(n,c,o); return; default: QD_copy(n,i,c); QD_copy(n,QD_one,t); ll=l; for (l>>=1;l>0;l>>=1) {QD_sqr(n,c,c); if (l&1) QD_mul(n,t,c,t);} if (ll&1) QD_mul(n,t,i,o); else QD_copy(n,t,o);}} void QD_sqrt(int n,QD a,QD b) {QD q,s,t,u,v; if (DEBUG) printf("QD_sqrt %i %f\n",n,a[0]); if (a[0]<0.0) errorit("negative number in QD_sqrt"); if (a[0]==0.0) {QD_copy(n,QD_zero,b); return;} if (n==1) {b[0]=Sqrt(a[0]); return;} QD_copy(n,QD_zero,q); q[0]=1.0/Sqrt(a[0]); QD_sqr(2,q,s); QD_mul(2,a,s,t); QD_sub(2,QD_one,t,u); QD_mul(2,q,u,v); QD_mulall(2,v,0.5,v); QD_add(2,q,v,q); QD_sqr(n,q,s); QD_mul(n,a,s,t); QD_sub(n,QD_one,t,u); QD_mul(n,q,u,v); QD_mulall(n,v,0.5,v); QD_add(n,q,v,q); if (n==4) {QD_sqr(n,q,s); QD_mul(n,a,s,t); QD_sub(n,QD_one,t,u); QD_mul(n,q,u,v); QD_mulall(n,v,0.5,v); QD_add(n,q,v,q);} QD_mul(n,q,a,b);} void QD_cbrt(int n,QD i,QD o) {QD q,s,t,u,v; int b=FALSE; if (DEBUG) printf("QD_cbrt %i %f\n",n,i[0]); if (i[0]==0.0) {QD_copy(n,QD_zero,o); return;} if (n==1) {o[0]=Root(i[0],3); return;} if (i[0]<0.0) {QD_neg(n,i,i); b=TRUE;} QD_copy(n,QD_zero,q); q[0]=1.0/Root(i[0],3); QD_powi(2,q,3,s); QD_mul(2,i,s,t); QD_sub(2,QD_one,t,u); QD_mul(2,q,u,v); QD_div1(2,v,3.0,v); QD_add(2,q,v,q); QD_powi(n,q,3,s); QD_mul(n,i,s,t); QD_sub(n,QD_one,t,u); QD_mul(n,q,u,v); QD_div1(n,v,3.0,v); QD_add(n,q,v,q); if (n==4) {QD_powi(n,q,3,s); QD_mul(n,i,s,t); QD_sub(n,QD_one,t,u); QD_mul(n,q,u,v); QD_div1(n,v,3.0,v); QD_add(n,q,v,q);} QD_div(n,QD_one,q,o); if (b==TRUE) {QD_neg(n,i,i); QD_neg(n,o,o);}} void QD_cos(int n,QD i,QD o) {QD t,f,s,I,q,N,D,T; int k; if (DEBUG) printf("QD_cos %i %f\n",n,i[0]); if (n==1) {o[0]=Cos(i[0]); return;} QD_div(n,i,QD_pi,t); QD_floorQD(n,t,f); QD_mul(n,i,f,s); QD_sub(n,i,s,I); QD_sqr(n,I,I); QD_neg(n,I,I); QD_copy(n,I,N); QD_copy(n,QD_one,q); QD_copy(n,QD_one,D); D[0]=2.0; for (k=3;k<48;k+=2) {QD_div(n,N,D,T); QD_mul(n,N,I,N); QD_add(n,q,T,q); QD_mul1(n,D,(double) k,D); QD_mul1(n,D,(double) (k+1),D);} QD_copy(n,q,o);} void QD_agm(int n,QD i1,QD i2,QD o) {QD a,g,ap,gp; int i,D; if (DEBUG) printf("QD_agm %i %f %f\n",n,i1[0],i2[0]); if (i1[0]<=0.0) errorit("non-positive first input in QD_agm"); if (i2[0]<=0.0) errorit("non-positive second input in QD_agm"); QD_add(n,i1,i2,a); QD_mulall(n,a,0.5,a); QD_mul(n,i1,i2,g); QD_sqrt(n,g,g); while (1) {D=TRUE; for (i=0;i1.0) QD_div(n,QD_one,i,u); else QD_copy(n,i,u); if (i[0]<0.0) QD_neg(n,u,u); QD_copy(n,QD_zero,q); q[0]=Atan(u[0]); QD_cos(2,q,c); QD_sqr(2,c,c2); QD_sub(2,QD_one,c2,T); QD_sqrt(2,T,N); QD_div(2,N,c,t); QD_sub(2,t,u,f); QD_mul(2,f,c2,T); QD_sub(2,q,T,q); QD_cos(n,q,c); QD_sqr(n,c,c2); QD_sub(n,QD_one,c2,T); QD_sqrt(n,T,N); QD_div(n,N,c,t); QD_sub(n,t,u,f); QD_mul(n,f,c2,T); QD_sub(n,q,T,q); if (n==4) {QD_cos(n,q,c); QD_sqr(n,c,c2); QD_sub(n,QD_one,c2,T); QD_sqrt(n,T,N); QD_div(n,N,c,t); QD_sub(n,t,u,f); QD_mul(n,f,c2,T); QD_sub(n,q,T,q);} if (Abs(i[0])>1.0) {QD_mulall(n,QD_pi,0.5,hpi); QD_sub(n,hpi,q,o);} else QD_copy(n,q,o); if (i[0]<0.0) QD_neg(n,o,o);} int QD_modi(QD A,double p) {QD T; int w=4; if (A[0]==0.0) return 0; if (Abs(A[0])<4.5e15) w=1; else if (Abs(A[0])<2e31) w=2; else if (Abs(A[0])<9e46) w=3; QD_div1(w,A,p,T); QD_floorQD(w,T,T); QD_mul1(w,T,p,T); QD_sub(w,A,T,T); return (int) Round(T[0]);} llint QD_modll(QD A,double p) {QD T; QD_div1(wmax,A,p,T); QD_floorQD(wmax,T,T); QD_mul1(wmax,T,p,T); QD_sub(wmax,A,T,T); return (llint) Round(T[0]);} int QD_is_divisible(QD B,double p) {if (QD_modi(B,p)==0) return 1; return 0;} int QD_valuation(QD A,double p) {QD B; int v=0; if (A[0]==0.0) return (1<<28); QD_copy(wmax,A,B); while (QD_is_divisible(B,p)) {QD_div1(wmax,B,p,B); v++;} return v;} void QD_mod(QD x,QD m,QD r) {QD T; QD_div(wmax,x,m,T); QD_floorQD(wmax,T,T); QD_mul(wmax,T,m,T); QD_sub(wmax,x,T,T); QD_round(wmax,T,r);} void QD_intout(QD x) {char S[128]; int e,i=0,j; if (x[0]==0.0) {printf("+0"); return;} if (x[0]>1e60) {printf("+BIG"); return;} if (x[0]<-1e60) {printf("-BIG"); return;} e=QD_outputi(wmax,16*wmax,x,S); if (S[0]!='-') printf("+"); while (S[i]!='.') printf("%c",S[i++]); j=i+1; while (j-i<=e) printf("%c",S[j++]);} void QD_intout_noplus(QD x) {char S[128]; int e,i=0,j; if (x[0]==0.0) {printf("0"); return;} if (x[0]>1e60) {printf("+BIG"); return;} if (x[0]<-1e60) {printf("-BIG"); return;} e=QD_outputi(wmax,16*wmax,x,S); while (S[i]!='.') printf("%c",S[i++]); j=i+1; while (j-i<=e) printf("%c",S[j++]);} void initQDpoly(QDpoly *v,int d) {int i; (*v).coeff=malloc((d+1)*sizeof(QD)); (*v).deg=d; for (i=0;i<=d;i++) QD_copy(wmax,QD_zero,(*v).coeff[i]);} void delQDpoly(QDpoly *v) {free((*v).coeff);} void QDpoly_add(QDpoly a,QDpoly b,QDpoly *c) {int d,maxd,mind; if (a.deg>b.deg) {maxd=a.deg; mind=b.deg;} else {maxd=b.deg; mind=a.deg;} initQDpoly(c,maxd); for (d=0;d<=mind;d++) QD_add(wmax,a.coeff[d],b.coeff[d],(*c).coeff[d]); if (a.deg==maxd) for (d=mind+1;d<=maxd;d++) QD_copy(wmax,a.coeff[d],(*c).coeff[d]); else for (d=mind+1;d<=maxd;d++) QD_copy(wmax,b.coeff[d],(*c).coeff[d]);} void QDpoly_mul(QDpoly a,QDpoly b,QDpoly *c,int maxd) {int at,bt; QD T; /* if (DEBUG) printf("QDpoly_mul %i\n",maxd); */ if (maxd==-1) maxd=a.deg+b.deg; initQDpoly(c,maxd); for (at=0;at<=a.deg;at++) for (bt=0;at+bt<=maxd && bt<=b.deg;bt++) {QD_mul(wmax,a.coeff[at],b.coeff[bt],T); QD_add(wmax,(*c).coeff[at+bt],T,(*c).coeff[at+bt]);}} void QDpoly_pow(QDpoly a,int m,QDpoly *c,int maxd) /* lazy */ {int i; QDpoly s; /* if (DEBUG) printf("QDpoly_pow %i %i\n",m,maxd); */ if (maxd==-1) maxd=a.deg*m; initQDpoly(&s,0); QD_copy(wmax,QD_one,s.coeff[0]); for (i=1;i<=m;i++) {QDpoly_mul(a,s,c,maxd); delQDpoly(&s); s=*c;} if (m==0) *c=s;} void QDpoly_inv(QDpoly a,int m,QDpoly *c) {int i,j; QDpoly s,t,A; if (m==0) {initQDpoly(c,0); QD_copy(wmax,QD_one,(*c).coeff[0]); return;} initQDpoly(&s,a.deg); initQDpoly(&A,0); QD_copy(wmax,QD_one,A.coeff[0]); for (i=1;i<=a.deg;i++) QD_neg(wmax,a.coeff[i],s.coeff[i]); for (j=1;j<=m;j++) {QDpoly_pow(s,j,&t,m); QDpoly_add(A,t,c); delQDpoly(&A); delQDpoly(&t); A=*c;} delQDpoly(&s);} void QDpoly_intout(QDpoly v) {int i; for (i=0;i<=v.deg;i++) {if (v.coeff[i][0]!=0.0) {if (i==0) QD_intout_noplus(v.coeff[i]); else QD_intout(v.coeff[i]); if (i==1) printf("*x"); if (i>=2) printf("*x^%i",i);}} printf("\n");} void QDpoly_intround(QDpoly *v) {int i; for (i=0;i<=(*v).deg;i++) QD_round(wmax,(*v).coeff[i],(*v).coeff[i]);} static void QD_intgcdi(QD i1,QD i2,QD o) {QD T; if (DEBUG>=2) printf("QD_intgcdi %f %f\n",i1[0],i2[0]); if (i1[0]==0.0) return QD_copy(wmax,i2,o); if (i2[0]==0.0) return QD_copy(wmax,i1,o); if (i1[0]>i2[0]) return QD_intgcdi(i2,i1,o); if (i1[0]==i2[0]) {if (i1[1]>i2[1]) return QD_intgcdi(i2,i1,o); if (i1[1]==i2[1]) {if (i1[2]>i2[2]) return QD_intgcdi(i2,i1,o); if (i1[2]==i2[2]) {if (i1[3]>i2[3]) return QD_intgcdi(i2,i1,o); if (i1[3]==i2[3]) return QD_copy(wmax,i1,o);}}} QD_div(wmax,i2,i1,T); QD_floorQD(wmax,T,T); QD_mul(wmax,i1,T,T); QD_sub(wmax,i2,T,T); QD_intgcd(T,i1,o);} void QD_intgcd(QD i1,QD i2,QD o) {QD I1,I2; if (DEBUG) printf("QD_intgcd\n"); QD_round(wmax,i1,I1); QD_round(wmax,i2,I2); if (I1[0]<0.0) QD_neg(wmax,I1,I1); if (I2[0]<0.0) QD_neg(wmax,I2,I2); QD_intgcdi(I1,I2,o);} int QD_is_power(QD y,int m,QD z) /* only works for small-sized QD */ {int i; QD t; QD_copy(wmax,QD_zero,t); QD_copy(wmax,QD_zero,z); z[0]=t[0]=Round(Root(y[0],m)); QD_powi(wmax,t,m,t); QD_round(wmax,y,y); QD_round(wmax,t,t); for (i=0;i<4;i++) if (t[0]!=y[0]) return 0; return 1;} void QD_check() {QD x; QD_mul(wmax,QD_pi,QD_e,x); if (x[0]!=8.53973422267356774285) errorit("QD_check failed at x[0]"); if (x[1]!=-6.7738152905024242803e-16) errorit("QD_check failed at x[1]"); if (x[2]!=1.6082340642907151632e-32) errorit("QD_check failed at x[2]");} /********************* MATH LIB REPLACEMENTS ***********************/ #define PI 3.14159265358979323846264338 #define TWOPI 6.283185307179586476925286767 #define HALFPI 1.570796326794896619231321692 #define QUARTERPI 0.7853981633974483096156608458 #define LOG2 0.6931471805599453094172321215 #define LOG10 2.302585092994045684017991455 #define SQRT2 1.414213562373095048801688724 #define SQRT2I 0.7071067811865475244008443622 double Abs(double x) {if (x<0.0) return -x; return x;} double Round(double x) /* to even */ {if (x>=0) {if (x>=4503599627370496.0) return x; return ((x+4503599627370496.0)-(4503599627370496.0));} if (x<=-4503599627370496.0) return x; return ((x-4503599627370496.0)+(4503599627370496.0));} double Floor(double x) {double y; if (x<0) return -Ceil(-x); y=Round(x-0.5); if (x-y==1.0) return x; return y;} double Ceil(double x) {double y; if (x<0) return -Floor(-x); y=Round(x+0.5); if (y-x==1.0) return x; return y;} double Cos(double x) {int n=0; double s,p,b,u,E,S,d; printf("Cos %.16e\n",x); x=x-TWOPI*Floor(x/TWOPI); if (x>PI) x=TWOPI-x; if (x>HALFPI) {n=1; x=PI-x;} if (x>QUARTERPI) /* expand cos(Pi/2-x) as s-s^3/3!+s^5/120 + ... */ {s=HALFPI-x; u=-s*s; p=s; d=1.0; b=2.0; S=s; E=Abs(s)*(1e-17); while ((p>E) || (p<-E)) {d*=b; b+=1.0; d*=b; b+=1.0; p*=u; S+=p/d;} if (n==1) return -S; return S;} s=x; u=-s*s; p=1.0; d=1.0; b=1.0; S=1.0; E=Abs(s)*(1e-17); while ((p>E) || (p<-E)) {d*=b; b+=1.0; d*=b; b+=1.0; p*=u; S+=p/d;} if (n==1) return -S; return S;} double Exp(double x) {double l,s,p,d,b,S,E; if (DEBUG>=2) printf("Exp %.16e\n",x); if (x==0) return 1; if (x>709.0) errorit("Overflow in Exp"); if (x<-709.0) return 0.0; l=Round(x/LOG2); x-=l*LOG2; s=x; p=1.0; d=1.0; b=1.0; S=1.0; E=Abs(s)*(1e-17); while ((p>E) || (p<-E)) {d*=b; b+=1.0; p*=s; S+=p/d;} return S*QD_2pow(l);} double Log(double x) {int e=0; double s,p,d,S,E; if (DEBUG>=2) printf("Log %.16e\n",x); if (x==0.0) return -1e300; if (x<=0.0) errorit("must be positive in Log"); if (x==1.0) return 0.0; while (x>4.0) {x*=0.25; e+=4;} while (x>2.0) {x*=0.5; e+=2;} while (x>SQRT2) {x*=SQRT2I; e+=1;} while (x<0.25) {x*=4.0; e-=4;} while (x<0.5) {x*=2.0; e-=2;} while (xE) || (p<-E)) {d+=1.0; p*=s; S+=p/d;} return (S+0.5*e*LOG2);} double Log10(double x) {return Log(x)/LOG10;} double Atan(double x) {int r=0; double s,u,p,d,S,E; if (DEBUG>=2) printf("Atan %.16e\n",x); if (x==0.0) return x; if ((x>1.0) || (x<-1.0)) {x=1.0/x; r=1;} x=(Sqrt(4.0+4.0*x*x)-2)/(2.0*x); /* reduction */ s=x; u=-s*s; p=s; d=1.0; S=s; E=Abs(s)*(1e-17); while ((p>E) || (p<-E)) {p*=u; d+=2.0; S+=p/d;} S*=2.0; if (r==1) {if (x>0.0) return (HALFPI-S); return (-HALFPI-S);} return S;} double Root(double x,int n) {double c,z; int i; if (DEBUG>=2) printf("Root %.16e %i\n",x,n); if (n<=0) errorit("bad Root"); z=Pow(x,1.0/(double) n); while (1) {c=1.0; for (i=0;ix) z-=z/4503599627370496.0; else break;} return z;} double Sqrt(double y) {double z,r=1.0,g=1.0,x=y; int i; if (x<0.0) errorit("Sqrt of neg"); if (x==0.0) return 0.0; while (x>2.0) {x=x*0.25; r=r+r;} while (x<0.5) {x=x*4.0; r=r*0.5;} for (i=0;i<5;i++) g=g-(g*g-x)/(g+g); z=g*r; while (1) {if (z*zy) z-=z/4503599627370496.0; else break;} return z;} double Pow(double x,double y) {if (x==0.0) {if (y==0.0) return 1.0; if (y>0.0) return 0.0;} if (x<=0.0) errorit("must be nonnegative in Pow"); return Exp(y*Log(x));} sympow-1.019/README0000644017361200001450000001513110442324213013613 0ustar tabbottcrontab SYMPOW is a package to compute special values of symmetric power elliptic curve L-functions. It can compute up to about 64 digits of precision. ======================================================================== The quad-double package was modified from David Bailey's package: crd.lbl.gov/~dhbailey/mpdist/ The squfof implementation was modified from Allan Steel's version of Arjen Lenstra's original LIP-based code. The ec_ap code was originally written for the kernel of MAGMA, but was modified to use small integers when possible. SYMPOW was originally developed using PARI, but due to licensing difficulties, this was eliminated. SYMPOW also does not use the standard math libraries, thus eliminating possible license conflicts. However, ths user should ensure that there are no C library license issues. SYMPOW still can use GP to compute the meshes of inverse Mellin transforms (this is done when a new symmetric power is added to datafiles), but the datafiles can alternatively be downloaded from the SYMPOW website. The current license for GP appears to allow this usage. Please ensure that the GP you have allows this. ======================================================================== Basic Usages: ./sympow -sp 2p16 -curve "[1,2,3,4,5]" will compute L(Sym^2 E,edge) for E=[1,2,3,4,5] to 16 digits of precision The result 2n0: 8.370510845377639E-01 2w0: 8.370510845377586E-01 consists of two calculations using different parameters to test the functional equation (to see if these are sufficiently close). ./sympow -sp 3p12d2,4p8 -curve "[1,2,3,4,5]" will compute the 0th-2nd derivatives of L(Sym^3 E,center) to 12 digits and L(Sym^4 E,edge) to 8 digits Special cases: When a curve has CM, Hecke power can be used instead ./sympow -sp 7p12d1 -hecke -curve "[0,0,1,-16758,835805]" will compute the 0th-1st derivatives of L(Sym^7 psi,special) to 12 digits Bloch-Kato numbers can be obtained for powers not congruent to 0 mod 4: ./sympow -sp 2bp16 -curve "[1,2,3,4,5]" should return 2n0: 4.640000000000006E+02 2w0: 4.639999999999976E+02 which can be seen to be very close to the integer 464. Modular degrees can be computed with the -moddeg option. ./sympow -curve "[1,2,3,4,5]" -moddeg should return Modular Degree is 464 Analytic ranks can be computed with the -analrank option. ./sympow -curve "[1,2,3,4,5]" -analrank should return Analytic Rank is 1 : L'-value 3.51873e+00 and (if the mesh file for the fifth derivative is present) ./sympow -curve "[0,0,1,-79,342]" -analrank should return Analytic Rank is 5 : leading L-term 3.02857e+01 ======================================================================== Adding new symmetric powers: SYMPOW keeps data for symmetric powers in the directory datafiles If a pre-computed mesh of inverse Mellin transform values is not available for a given symmetric power, SYMPOW will fail. If GP is available, the command ./sympow -new_data 2 will add the data the 2nd symmetric power, while ./sympow -new_data 3d2 will add the data for the 2nd derivative and 3rd symmetric power, ./sympow -new_data 6d0h will add the data for the 0th derivative of the 6th Hecke power, and ./sympow -new_data 4c will add data for the 4th symmetric power for curves with CM (these need to be done separately for powers divisible by 4). The mesh files are stored in binary form, and thus endian-ness is a worry when moving from one platform to another. To enable modular degree computations, the 2nd symmetric powers must be extant, and analytic rank requires derivatives of the 1st power. There are lower-precision datafiles in the sympow.tar distribution to expedite the computation of analytic rank and modular degree. For Hecke powers, the (2N-1)st power is computed using the Nth files, and the (2N)th power requires the Nth and (N+1)st. ======================================================================== INSTALLATION: You will need to have sh and make, or their equivalents and rm, mkdir, tar, uname, cp, touch, and cc [or equivalents, but these must be modified in Configure] to build sympow. The shell commands cd, echo and which are also needed. The usage should just be: sh Configure make sympow will create a directory 'datafiles' of data for symmetric powers. New symmetric powers can be added as above, if grep, gp, and sed were available during the Configure. Needed header files are: stdio.h, stdlib.h, string.h, strings.h, unistd.h ======================================================================== NOTES: * Calculation of periods should not be trusted to the full 64 digits. * Analytic rank does not save the ap when more than 10^9 terms are needed: in such a case, it is probably easier to run sympow as ./sympow -sp 1w0p6D0,1w0p6D2,1w0p6D4,1w0p6D6,1w0p6D8 [for even signed curves, and however many derivatives are deemed relevant, and to a desired precision] and parse the output. ======================================================================== ChangeLog/BugFixes: * VERSION 1.000 --- released [30 Nov 2005] * VERSION 1.001 --- release version with data included, so change generate.c compute moddeg with Hecke in CM case [5 Dec 2005] * VERSION 1.002 --- add multiplier to squfof (fix oo loop) [7 Dec 2005] * VERSION 1.003 --- moved some Configure stuff to config.h [10 Dec 2005] * VERSION 1.004 --- bug: QD_atan (mul by cos^2) & llint in binom [14 Dec 2005] * VERSION 1.005 --- binom and sbinom improved, *.gp's changed [16 Dec 2005] * VERSION 1.006 --- *.gp fixes, get_weight(llint), rootno.c [21 Dec 2005] * VERSION 1.007 --- fix TACKS bug for Hecke, change BK for Hecke [22 Dec 2005] * VERSION 1.008 --- removed mathlib support to try to help protect user from possible license violations [13 Jan 2006] * VERSION 1.009 --- added (conjectural) root numbers for higher powers, fixed analrank bug for precision of 9 [16 Jan 2006] * VERSION 1.010 --- moddeg bugs {v3(N)=4, M=32,64,128, 3-isog} [19 Jan 2006] * VERSION 1.011 --- reduce size of ar/md tables, fix kronll [23 Jan 2006] * VERSION 1.012 --- Fix new_data typo, add higher Hecke derivs, add zero check option (undocumented) [20 Feb 2006] * VERSION 1.013 --- Fix llint probs in ec_ap_large [23 Feb 2006] * VERSION 1.014 --- Fix years in ChangeLog, allocatemem(2^28) in standard1.gp (needed for 64-bit machines), add --help, etc. [1 Mar 2006] * VERSION 1.018 --- speed up ec_ap via idea of Geoff Bailey, use lesser prec in QD computations when possible, new fpu.c, -mdspeed option, -noqdcheck option [24 Apr 2006] * VERSION 1.019 --- getline -> getline0, 'which \cp' in config [11 May 2006] sympow-1.019/rootno.c0000644017361200001450000002002710442324213014417 0ustar tabbottcrontab#include "sympow.h" #define DEBUG (FALSE || GLOBAL_DEBUG) static int local_rootno_at2(int b) {int c4,c6,D,v4,v6,vd,t,i; QD T; if (DEBUG) printf("local_rootno_at2\n"); if (b==1) return -ec_ap(Ec4,Ec6,2); v4=QD_valuation(Ec4,2.0); v6=QD_valuation(Ec6,2.0); vd=QD_valuation(Edisc,2.0); if (v4>100) v4=100; if (v6>100) v6=100; if (vd>100) vd=100; QD_copy(wmax,Ec6,T); for (i=0;i=29) return ((c6%4)==3) ? 1:-1; QD_copy(wmax,Ec4,T); for (i=0;i=6) && (v6==5) && (vd==4)) return -1; /* cases 2,14 */ if ((v4==4) && (v6>=7) && (vd==6)) /* case 3 and 9 it seems */ {if ((COND0%64)==0) return (v6==7) ? 1:-1; /* case 3 */ QD_mulall(wmax,Ec6,0.0078125,T); t=(c4-4*QD_modi(T,16))%16; if (t<0) t+=16; if ((t==7) || (t==11)) return 1; return -1;} /* case 9 */ if ((v4==4) && (v6==6) && (vd==7)) /* case 4 */ {if (((c6%8)==5) || ((c6%8)==((5*c4)%8))) return 1; return -1;} if ((v4==5) && (v6==6) && (vd==6)) return ((c4%4)==3) ? 1:-1; /* case 5 */ if ((v4>=6) && (v6==6) && (vd==6)) return ((c6%4)==1) ? 1:-1; /* case 6 */ if ((v4==5) && (v6==7) && (vd==8)) /* case 10 */ {if (((c6%8)==3) || (((2*c4+c6)%8)==7)) return 1; return -1;} if ((v4==5) && (v6==8) && (vd==9)) /* case 11 */ {if ((((2*c6+c4)%8)==1) || (((2*c6+c4)%8)==7)) return 1; return -1;} if ((v4==5) && (v6>=9) && (vd==9)) return (((c4%8)==1) || ((c4%8)==3)) ? 1:-1; if ((v4==4) && (v6==6) && (vd==8)) /* cases 15,25,30 */ {t=(2*c6+c4)%16; if (t==11) return -1; /* case 15 */ if (t==7) return (((2*c6+c4)%32)==23) ? 1:-1; /* case 30 */ return (((2*c6+c4)%16)==3) ? 1:-1;} /* case 25 */ if ((v4==6) && (v6==7) && (vd==8)) /* cases 27,31 */ {if ((c6%4)==3) return 1; return (((2*c4+c6)%8)==3) ? 1:-1;} if ((v4>=7) && (v6==7) && (vd==8)) return -1; /* cases 16,27 */ if ((v4==4) && (v6==6) && (vd==10)) /* cases 17,32 */ {if ((c6%4)==1) return 1; t=(c4-2*c6)%64; if (t<0) t+=64; if ((t==3) || (t==19)) return 1; return -1;} if ((v4==7) && (v6==9) && (vd==12)) /* case 18 */ {if (((c4%4)==1) && (((c6%8)==1)||((c6%8)==7))) return 1; if (((c4%4)==3) && (((c6%8)==1)||((c6%8)==3))) return 1; return -1;} if ((v4==7) && (v6==10) && (vd==14)) /* case 19 */ {if (((c4%4)==1) && ((((c4*c6)%8)==5)||(((c4*c6)%8)==7))) return 1; return (((c4%4)==3) && ((((c4*c6)%8)==1)||(((c4*c6)%8)==7))) ? 1:-1;} if ((v4==7) && (v6==11) && (vd==15)) /* case 20 */ {if ((((2*c6+c4)%8)==1) || (((2*c6+c4)%8)==3)) return 1; return -1;} if ((v4==7) && (v6>=12) && (vd==15)) return (((c4%8)==5)||((c4%8)==7)) ? 1:-1; if ((v4==4) && (v6==6) && (vd==11)) return ((c6%8)!=7) ? 1:-1; /* 22,35! */ if ((v4>=8) && (v6==9) && (vd==12)) return ((c6%4)==1) ? 1:-1; /* case 23 */ if ((v4>=8) && (v6==10) && (vd==14)) return ((c6%4)==1) ? 1:-1; /* case 24 */ if ((v4==4) && (v6==6) && (vd==9)) /* case 26 */ {if ((c6%8)==7) return 1; if (((2*c6+c4)%32)==11) return 1; return -1;} if ((v4==6) && (v6==8) && (vd==10)) return (((c4*c6)%4)==3) ? 1:-1; /* 28 */ if ((v4>=7) && (v6==8) && (vd==10)) return ((c6%4)==1) ? 1:-1; /* case 29 */ if ((v4==6) && (v6==10) && (vd==12)) /* cases 33,36 */ {if ((c4%4)==3) return 1; t=(c4+4*c6)%16; if ((t==9) || (t==13)) return 1; return -1;} if ((v4==6) && (v6>=11) && (vd==12)) /* cases 33,37 */ {if ((c4%4)==3) return -1; /* case 33 */ QD_mulall(wmax,Ec6,0.0009765625,T); t=(c4-4*QD_modi(T,16))%16; if (t<0) t+=16; if ((t==5) || (t==9)) return 1; return -1;} if ((v4==6) && (v6==9) && (vd==13)) /* case 34 */ {if ((c4%16)==11) return 1; if (((c4+4*c6)%16)==3) return 1; return -1;} if ((v4==4) && (v6==6) && (vd==12) && ((c6%4)==1)) return -1; /* case 38 */ if ((v4==6) && (v6==9) && (vd==14)) return ((D%4)==(c6%4)) ? 1:-1; /* 39 */ if ((v4==6) && (v6==9) && (vd==15)) return ((D%4)==3) ? 1:-1; /* case 40 */ if ((v4==6) && (v6==9) && (vd>=16)) return ((c6%4)==3) ? 1:-1; /* case 41 */ errorit("Problem in local_rootno_at2"); return 0;} static int local_rootno_at3(int b) {int c4,c6,D,v4,v6,vd,i; QD T; if (DEBUG) printf("local_rootno_at3\n"); if (b==1) return -kronll(-QD_modll(Ec6,3.0),3); if (b==31) return -1; v4=QD_valuation(Ec4,3.0); v6=QD_valuation(Ec6,3.0); vd=QD_valuation(Edisc,3.0); if (v4>100) v4=100; if (v6>100) v6=100; if (vd>100) vd=100; QD_copy(wmax,Ec4,T); for (i=0;i=2) && (v6==3) && (vd==3)) /* cases 1 and 5 */ {if ((COND0%27)!=0) return 1; if ((c6==4) || (c6==7) || (c6==8)) return 1; return -1;} if ((v4==2) && (v6==4) && (vd==3)) {if ((c4%3)!=(c6%3)) return 1; return -1;} if ((v4==2) && (v6==3) && (vd==4)) return 1; /* case 3 */ if ((v4>=2) && (v6==4) && (vd==5)) {if ((c6%3)==2) return 1; return -1;} if ((v4==2) && (v6>=5) && (vd==3)) return 1; /* case 6 */ if ((v4==2) && (v6==3) && (vd==5)) {if ((D%3)==(c6%3)) return 1; return -1;} if ((v4==3) && (v6==5) && (vd==6)) {if ((c4%3)==2) return 1; return -1;} if ((v4>=4) && (v6==5) && (vd==7)) {if ((c6%3)==2) return 1; return -1;} if ((v4==4) && (v6==6) && (vd==9)) /* cases 10,15 */ {if ((COND0%27)!=0) return 1; /* case 15 */ if (((c6%9)==4) || ((c6%9)==8)) return 1; return -1;} /* case 10 */ if ((v4>=5) && (v6==6) && (vd==9)) /* cases 11,15 */ {if ((COND0%27)!=0) return 1; /* case 15 */ if (((c6%9)==1) || ((c6%9)==2)) return 1; return -1;} /* case 11 */ if ((v4==4) && (v6==7) && (vd==9)) {if ((c6%3)==2) return 1; return -1;} if ((v4==4) && (v6==6) && (vd==10)) /* case 13 */ {if (((c6%9)==2) || ((c6%9)==7)) return 1; return -1;} if ((v4>=5) && (v6==7) && (vd==11)) {if ((c6%3)==1) return 1; return -1;} if ((v4==4) && (v6>=8) && (vd==9)) return 1; /* case 16 */ if ((v4==4) && (v6==6) && (vd==11)) {if ((c6%3)==1) return 1; return -1;} if ((v4==5) && (v6==8) && (vd==12)) return 1; /* case 18 */ if ((v4>=6) && (v6==8) && (vd==13)) {if ((c6%3)==1) return 1; return -1;} if ((v4==2) && (v6==3) && (vd==6)) return -1; if ((v4==3) && (v6>=6) && (vd==6)) return -1; errorit("Problem in local_rootno_at3"); return 0;} static int local_rootno1(int i,llint p) {int b=badprimetype[i],e; if (p==2) return local_rootno_at2(b); if (p==3) return local_rootno_at3(b); if (b==1) return -kronll(-QD_modll(Ec6,p),p); if (b==31) return kronll(-1,p); e=QD_valuation(Edisc,p)%12; if (e>6) e=12-e; e=12/e; /* e is 2,3,4,6 */ if (e==4) return kronll(-2,p); if (e==3) return kronll(-3,p); return kronll(-1,p);} int local_rootno(int i,llint p,int sp) {int w1,b=badprimetype[i]; if ((sp&1)==0) return 1; if (sp==1) return local_rootno1(i,p); w1=local_rootno1(i,p); if (p==2) {if (b==1) return w1; if ((b==29) || (b==30)) return ((sp&3)==3) ? 1:w1; if (((tame_local_conductor(b,sp)/2)&1)==0) w1=1; if (((sp&7)==3) && (fp2&1)) return -w1; return w1;} if (b==31) return ((sp&3)==3) ? 1:w1; if (p==3) {if ((b==4) || (b==14) || (b==18)) return 1; if (b==2) return ((sp&3)==3) ? 1:-1; if (b==1) return w1; if (((b==15)||(b==19)) && (w1==-1)) return ((sp&3)==3) ? 1:-1; sp=sp%12; if ((b==15)||(b==19)) return ((sp==3)||(sp==5)||(sp==7)) ? -1:1; if (w1==1) return (sp==5) ? -1:1; return (sp==11) ? 1:-1;} if (w1==1) return 1; if (b==1) return -1; if (b!=3) {if ((sp&3)==1) return -1; return 1;} if ((tame_local_conductor(b,sp)/2)&1) return -1; return 1;} int global_rootno(int m) {int i,e; if (((m&7)==1) || ((m&7)==3)) e=-1; else e=1; for (i=0;badprimes[i]!=0;i++) e*=local_rootno(i,badprimes[i],m); return e;} sympow-1.019/standard1.gp0000644017361200001450000000150610442324213015145 0ustar tabbottcrontaballocatemem(2^28); \\ need 2^28 for 64-bit machines; else 2^27 L; X; SP=mx+2; default(seriesprecision,SP+1); H=vector(SP); {for(i=1,SP,H[i]=vector(N); for(j=1,N,if(i==1,if(j==1,H[1][1]=1,H[i][j]=H[i][j-1]+1.0/j), if(j==1,H[i][1]=H[i-1][1],H[i][j]=H[i][j-1]+H[i-1][j]/j*1.0))));} Hf(n,k)=if(k==0,0,H[n][k]) ZETA(n)=if(n==1,Euler,zeta(n)) J(k,v)=if(k<0,(v-k-1)*J(k+1,v),\ 1.0*(-1)^k/k!/v*\ exp(sum(n=1,SP,(-1)^n*(ZETA(n)/n)*v^n))*\ (1+sum(n=1,SP,Hf(n,k)*v^n))) sinv(k,v)=if(k==0,1/v,-1/k-sum(l=1,SP,v^l/k^(l+1))) two1ms(k,v)=2^(1+k)*sum(l=0,SP,log(1/2)^l/l!*v^l) {DERIV(M)= sum(i=0,poldegree(M,L), (deriv(polcoeff(M,i,L),X)+(i+1)*polcoeff(M,i+1,L)/X)*L^i)} {ev(T,v,C)=U=0; for(i=0,mx,U+=(truncate(polcoeff(T,i,L)+O(X^C))*L^i)); subst(subst(U,L,log(v)),X,v);} sympow-1.019/standard2.gp0000644017361200001450000000203610442324213015145 0ustar tabbottcrontab P=sum(k=0,N,sum(l=1,mx+1,-(-1)^l/(l-1)!*polcoeff(F(k),-l,X)*L^(l-1))*X^k); K=40; Ds=vector(K); Ds[1]=DERIV(P); for(i=2,K,Ds[i]=DERIV(Ds[i-1])); ieee(x)=(round(x<<53)*1.0)>>53 {IEEE(x)=if(x==0,return(0));if(length(x)<2,return(0)); y=ceil(log(abs(x))/log(2));ieee(x/2^y)*2^y;} {QD(x)=local(A);A=[IEEE(x),0,0,0];A[2]=IEEE(x-A[1]);A[3]=IEEE(x-A[1]-A[2]); A[4]=IEEE(x-A[1]-A[2]-A[3]); A=precision(A,18); print(A[1]); print(A[2]); print(A[3]); print(A[4]);} {doit(x,C)=print("AT ",x); QD(ev(P,x,C)); for(d=1,35,print("DERIV ",d); QD(ev(Ds[d]/d!,x,C)));} ch(x,C)=ev(P,x,C)-ev(P,x,C+20) setup(a,b)=for(i=0,31,doit(2^a+2^a*i/32,b)); print("About to find TOO_BIG"); \\ ends up in /dev/null MM=100; while(log(10^(-70)+abs(ev(P,MM,N)))>-148,MM*=1.1); write1("datafiles/param_data",STR,",",precision(IEEE(MM),18)); print("Now working backwards..."); \\ ends up in /dev/null l=-10; while(log(10^(-70)+abs(ch(2^l,20)))<-148,l+=1); l-=1; s=l; write1("datafiles/param_data",",",l-5); n=20; print("Starting to write mesh files"); \\ ends up in /dev/null sympow-1.019/standard3.gp0000644017361200001450000000053610442324213015151 0ustar tabbottcrontabwhile(2^l-148,n+=5);setup(l,n);l+=1); write("datafiles/param_data",",",l-s); coeffs(j)=for(i=0,19,print("PS ",i);QD(polcoeff(polcoeff(P,j,L),i,X))); coeffO(j)=\ for(i=0,9,print("PSL ",2*i+1);QD(polcoeff(polcoeff(P,j,L),2*i+1,X))); coeffE(j)=\ for(i=0,9,print("PSL ",2*i);QD(polcoeff(polcoeff(P,j,L),2*i,X))); sympow-1.019/sympow.h0000644017361200001450000001170710442324213014447 0ustar tabbottcrontab#include #include #include #include #include "config.h" #define TRUE 1 #define FALSE 0 #define GLOBAL_DEBUG FALSE #define llint long long int #define ASSERT(x) {if (!(x)) errorit("Assertion failed");} #define wmax 4 #define CURR_MAX 60 #define MIN_TERMS 2000 #define MIN_SQRT 1000 #define STEPS 32 #define LPT 35 /* Local power series terms */ #define A0PT 20 /* about zero power series terms */ #define minimum(a,b) ((a)<(b))?(a):(b) #define ISA_NUMBER(x) ((x>='0') && (x<='9')) typedef double QD[4]; extern QD QD_pi,QD_twopi,QD_sqrtpi,QD_log2,QD_one,QD_e,QD_zero; typedef struct {int deg; QD *coeff;} QDpoly; typedef struct {llint p[16]; int e[16];} LIST; QD ***TABLE,***POWSER,*DECAY,**TACKS,*WIGGLE,*WIGSQI; double *TOO_BIG,*EXPAND0_LIM,*STEP_SIZE,MD_SPEED; int *evalpt,*derivative,*NUM_LOGS,*HALF_ZERO; int *TACKON,SLOPPY[CURR_MAX],*MESH_COUNT; QD VOLUME,SCALE,TW_EFF; llint CONDTW,EVEN_TOP,EVEN_BOTTOM; int MANIN,MANIN_TWIST,ZEROCHECK,RERUN,MODDEG; int VERBOSE,GLOBAL,HECKE,NO_QT,TWIST,AP_SAVE,CM_CASE,CM_TWIST,ANAL_RANK; int *w,*wprec; /* precision indicator */ llint *badprimes; int *badprimetype; QD COND[CURR_MAX],REAL_PERIOD,IMAG_PERIOD; llint COND0; QD Ea1,Ea2,Ea3,Ea4,Ea6,Eb2,Eb4,Eb6,Ec4,Ec6,Edisc,Etw4,Etw6,EtwD; int C4C6LL; llint Ec4ll,Ec6ll; int WHICH,NUM_SUMS,fp3,fp2,*PRIMES,*RN; int *whi,*wlo,*SYMPOW,*NUM_WIGS,*BLOCH_KATO,*apsave; char *GET; int MAX_TABLE; /* analrank.c */ void prep_analrank(llint,int); /* analytic.c */ void get_wt_large(int,QD,QD,int,int); void get_weight(llint,QD,int); /* compute.c */ double go(llint,llint); llint ec_do(llint); /* compute2.c */ void special_value(int,QD,int); void pth_coeff_from_ap(int,llint,int,int,QD); void power_trace_from_ap(int,llint,int,int,QD); /* conductors.c */ int tame_local_conductor(int,int); int wild_local_conductor(int,int); void badprimetype_output(int,llint); int do_badprime(llint); void compute_conductor(int); void compute_conductor_hecke(int); int get_tame_conductor(llint,int); int get_wild_conductor(llint,int); int get_conductor(llint,int); /* disk.c */ void load_files(int,int,int,int); void load_files_hecke(int,int,int,int); int getline0(FILE*,char*,int); /* ec_ap_bsgs.c */ llint ec_bsgs_ap(QD,QD,llint); llint ec_bsgs_ap_AB(int,int,llint); /* ec_ap.c */ llint ec_ap(QD,QD,llint); llint ec_ap_with_disc(QD,QD,QD,llint); /* ec_ap_large.c */ llint ec_bsgs_ap_large(QD,QD,llint); /* eulerfactors.c */ void euler_factor_bad(llint,int,int,QDpoly*); void euler_factor_hecke_bad(llint,int,int,QDpoly*); void euler_factor(llint,int,QDpoly*); void localinfos(char*,char*); /* factor.c */ void init_primes(); void QD_factor(QD,LIST*); void modular_exponentiation(llint,QD,llint,QD); void IFACT_INIT(llint); void ifactor(llint,LIST*,int,int); /* fpu.s */ void fpu_53bits(); /* generate.c */ int assure_line(char*); void new_sympow_s1(char*); void new_sympow_pari(char*); void new_sympow_s2(char*); void rewarp_params(); void txt2bin(int,char*,FILE*); void new_data(char*); /* help.c */ void help_message(); /* init_curve.c */ void curve_init(char*,char*); /* moddeg.c */ void prepare_moddeg(char*); llint postpare_moddeg(); /* periods.c */ void do_periods(); /* prepare.c */ llint prepare_decay(int,int,int); llint process_string(char*,llint); llint preparation(int,char*,llint); /* QD.c */ void QD_add(int,QD,QD,QD); void QD_sub(int,QD,QD,QD); void QD_mul(int,QD,QD,QD); void QD_div(int,QD,QD,QD); void QD_mul1(int,QD,double,QD); void QD_div1(int,QD,double,QD); void QD_sqr(int,QD,QD); void QD_copy(int,QD,QD); void QD_neg(int,QD,QD); void QD_mulall(int,QD,double,QD); void QD_mul2n(int,QD,int,QD); void QD_exp(int,QD,QD); void QD_log(int,QD,QD); void QD_round(int,QD,QD); void QD_floorQD(int,QD,QD); void QD_self_renorm(int,QD); void QD_powi(int,QD,int,QD); void QD_sqrt(int,QD,QD); void QD_output(int,int,QD); void QD_ddump53(double); void errorit(char*); void QD_agm(int,QD,QD,QD); void QD_cos(int,QD,QD); void QD_cbrt(int,QD,QD); void QD_atan(int,QD,QD); void QD_intout(QD); void QD_intout_noplus(QD); double QD_2pow(int); int QD_modi(QD,double); llint QD_modll(QD,double); int QD_is_divisible(QD,double); int QD_valuation(QD,double); void QD_mod(QD,QD,QD); void initQDpoly(QDpoly*,int); void delQDpoly(QDpoly*); void QDpoly_add(QDpoly,QDpoly,QDpoly*); void QDpoly_mul(QDpoly,QDpoly,QDpoly*,int); void QDpoly_pow(QDpoly,int,QDpoly*,int); void QDpoly_inv(QDpoly,int,QDpoly*); void QDpoly_intout(QDpoly); void QDpoly_intround(QDpoly*); void QD_intgcd(QD,QD,QD); int QD_is_power(QD,int,QD); void QD_check(); double Abs(double); double Atan(double); double Ceil(double); double Cos(double); double Exp(double); double Floor(double); double Log(double); double Log10(double); double Pow(double,double); double Root(double,int); double Round(double); double Sqrt(double); /* rootno.c */ int local_rootno(int,llint,int); int global_rootno(int); /* util.c */ void errorit(char*); int u8(int); void get_primes_ll(llint,llint,llint*); void free_data(); int kron(int,int); int kronll(llint,llint); int gcd(int,int); sympow-1.019/util.c0000644017361200001450000000363610442324213014063 0ustar tabbottcrontab#include "sympow.h" #define DEBUG (FALSE || GLOBAL_DEBUG) void errorit(S) char *S; {printf("**ERROR** %s\n",S); exit(-1);} int u8(int x) {return(((x+7)>>3)<<3);} static unsigned char *auxp; static int get_primesll_loop(llint start,llint size,llint *A) {llint i,l,j=0,k=0,s,p=2; if (DEBUG>=2) printf("get_primesll_loop %lli %lli\n",start,size); for (i=0;i=2) printf("get_primes_ll %lli %lli\n",st,sz); sz+=1000; auxp=malloc(u8((sz/10)+72)); B=A; for (i=0;i<10;i++) {B=B+k; k=get_primesll_loop(st,sz/10,B); st+=sz/10;} if (DEBUG>=2) printf("Done with get_primes_ll\n"); free(auxp);} void free_data() {QD **P; int i; if (DEBUG) printf("free_data\n"); free(TACKS[0]); P=TABLE[0]; for (i=0;i>=1;} if ((e&1) && (((b&7)==3) || ((b&7)==5))) e=-1; else e=1; if (a==1) return e; if (((a&3)==3) && ((b&3)==3)) return -e*kron(b,a); return e*kron(b,a);} int kronll(llint a,llint b) /* assumes b is odd and positive */ {int e=0; a=a%b; if (a<0) a+=b; if (a<=1) return a; if (b==1) return 1; while ((a&1)==0) {e++; a>>=1;} if ((e&1) && (((b&7)==3) || ((b&7)==5))) e=-1; else e=1; if (a==1) return e; if (((a&3)==3) && ((b&3)==3)) return -e*kronll(b,a); return e*kronll(b,a);} int gcd(int a,int b) {while (1) {a-=(a/b)*b; if (a==0) return b; b-=(b/a)*a; if (b==0) return a;}} llint gcdll(llint a,llint b) {while (1) {a-=(a/b)*b; if (a==0) return b; b-=(b/a)*a; if (b==0) return a;}}