/*CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C C COMPUTE MERTENS FUNCTION (sum of M(x/i)^2 where i|x, find local maxima) C C 10/30/15 (DKC) (maxima based on j(x)) C C C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC*/ #include <stdio.h> #include <math.h> #include "table3.h" extern char *malloc(); int newmobl(unsigned long long a, unsigned long long b, int *out, unsigned int *table); unsigned long long MAXN=3500000000; // (2^31-1=4294967295) unsigned long long BEGINN=2; // beginning N unsigned long long Msize=3500000000; // for 16 GB of RAM, 64-bit OS // void main() { int t,*temp; int *M; unsigned int total,count,tindex,p,h; unsigned int pritab[1000],prind,delta,joff,newind; unsigned int j,k; int savet; unsigned long long i,tz,pz; unsigned long long *oldtmp,*newtmp; unsigned long long N,ta,tb,index; unsigned long long ut; double sum,maxt; FILE *Outfp; Outfp = fopen("out1ap.dat","w"); temp=(int *) malloc(4004); if (temp==NULL) { printf("not enough memory \n"); return; } oldtmp=(unsigned long long*) malloc(64000); if (oldtmp==NULL) { printf("not enough memory \n"); return; } newtmp=(unsigned long long*) malloc(64000); if (newtmp==NULL) { printf("not enough memory \n"); return; } M=(int*) malloc((Msize+1)*4); if (M==NULL) { printf("not enough memory \n"); return; } printf("computing Mobius function \n"); index=0; ta=1; tb=1001; for (i=0; i<(Msize/1000); i++) { t=newmobl(ta,tb,temp,table); if (t!=1) { printf("error \n"); goto zskip; } ta=tb; tb=tb+1000; for (j=0; j<1000; j++) M[j+index]=temp[j]; index=index+1000; } // // compute Mertens function // printf("computing Mertens function \n"); for (i=1; i<=Msize; i++) M[i]=M[i-1]+M[i]; // printf("finding maxima \n"); maxt=0.0; for (N=BEGINN; N<=MAXN; N++) { if ((N>13)&&((N&1)==1)) // Note! Maxima appear to be even for N>13. continue; // // factor N // ut=N; prind=0; tindex=0; total=0; h=(unsigned int)(sqrt((double)ut)+0.001); // For p>2, the difference between for (i=0; i<41538; i++) { // successive primes is greater p=table[i]; // than 1, so adding 0.001 is okay. if (p>h) goto fskip; count=0; while (ut==(ut/p)*p) { if (count==0) oldtmp[tindex]=p; else oldtmp[tindex]=oldtmp[tindex-1]*p; tindex=tindex+1; if (tindex>7999) { printf("divisor table not big enough: N=%d \n",N); goto zskip; } ut=ut/p; count=count+1; } if (count!=0) { total=total*(count+1); pritab[prind]=count; prind=prind+1; if (prind>1000) { printf("prime table not big enough: N=%d \n",N); goto zskip; } } if (ut==1) goto askip; } printf("error: prime look-up table not big enough \n"); goto zskip; // // compute combinations of factors // fskip: oldtmp[tindex]=ut; tindex=tindex+1; if (tindex>7999) { printf("divisor table not big enough: N=%d \n",N); goto zskip; } count=1; total=total*(count+1); pritab[prind]=count; prind=prind+1; if (prind>1000) { printf("prime table not big enough: N=%d \n",N); goto zskip; } askip: if (prind==1) { newind=tindex; goto cskip; } delta=0; pritab[prind]=0; pritab[prind+1]=0; bskip: joff=0; delta=0; newind=0; for (i=0; i<(prind+1)/2; i++) { count=pritab[2*i]; for (j=0; j<count; j++) { newtmp[newind]=oldtmp[j+joff]; newind=newind+1; } for (j=0; j<pritab[2*i+1]; j++) { newtmp[newind]=oldtmp[j+joff+count]; newind=newind+1; } for (j=0; j<count; j++) { tz=oldtmp[j+joff]; for (k=0; k<pritab[2*i+1]; k++) { pz=tz*oldtmp[k+count+joff]; newtmp[newind]=pz; newind=newind+1; if (newind>3999) { printf("divisor table not big enough \n"); goto zskip; } } } joff=joff+pritab[2*i]+pritab[2*i+1]; pritab[delta]=pritab[2*i]*pritab[2*i+1]+pritab[2*i]+pritab[2*i+1]; delta=delta+1; } for (i=0; i<newind; i++) oldtmp[i]=newtmp[i]; pritab[delta]=0; pritab[delta+1]=0; prind=delta; if (delta>1) goto bskip; // // compute j(x) // cskip: sum=1.0; for (i=0; i<newind; i++) { tz=oldtmp[i]; t=M[tz-1]; if (tz==N) savet=t; sum=sum+(double)t*(double)t; } if (sum>maxt) { maxt=sum; printf(" %d %I64x %d %I64x %d %d \n",N,N,(unsigned int)sum,(unsigned long long)sum,newind+1,savet); fprintf(Outfp," %I64x, %I64x, %d, %d, \n",N,(unsigned long long)sum,newind+1,savet); } } zskip: fclose(Outfp); return; }