/*CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C C COMPUTE MERTENS FUNCTION (using half-order Farey series) C C 05/16/14 (DKC) C C C C This C program computes the sum of cos(2*pi*r_v) where r_v is a fraction C C in the Farey series. C C C C C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC*/ #include <stdio.h> #include <math.h> unsigned int haros1(unsigned int N, unsigned int M, unsigned int *R, unsigned int H, unsigned int K, unsigned int HP, unsigned int KP); unsigned int lagrange1(unsigned int N, unsigned int D, unsigned int O); unsigned int out=0; // select upper curve, lower curve, or sum // void main() { unsigned int O,OP,S[150000],U[25000]; unsigned int H,K,N,D,NP,DP,NDEL,DDEL,HSAV,KSAV; unsigned int L,I,J,f,del2,count,R,tind,maxzig,zig,ozig,tzig,oflag; int del1; double sum,sum2,temp,tmpsum,total,oldtot,T[25000],delta; double pi; FILE *Outfp; Outfp = fopen("out1o.dat","w"); pi=3.141592654; // // ORDER OF FAREY SERIES // OP=57; // full order O=OP/2; // half-order J=O; oflag=0; if ((O*2)!=OP) { O=O+1; oflag=1; } if (O>250) { printf("order too big \n"); goto zskip; } tind=0; // index of output array maxzig=0; ozig=0; tzig=0; L=haros1(O,0,S,0,1,1,O); // generate half-order Farey series S[L]=0; sum=0.0; // half-order sum of cosines sum2=0.0; // full order sum of cosines for (I=0; I<=J; I++) sum2=sum2+cos(2.0*pi/(double)(O+I)); oldtot=sum2; for (I=1; I<(L-1); I++) { H=S[I]>>16; K=S[I]&0xffff; HSAV=H; KSAV=K; tmpsum=0.0; zig=0; // // begin loop // aloop: f=lagrange1(H,K,OP); // compute next fraction N=f>>16; D=f&0xffff; if (f==S[I+1]) { tmpsum=tmpsum+cos(2.0*pi*(double)N/(double)D); goto bskip; } R=(OP+K)/D; // compute next fraction NP=R*N-H; DP=R*D-K; temp=cos(2.0*pi*(double)N/(double)D)+cos(2.0*pi*(double)NP/(double)DP); if (D>DP) { del1=(int)(2*DP)-(int)OP-1; if (del1<=0) goto askip; del2=D-DP; count=(unsigned int)del1/del2; if ((unsigned int)del1!=((unsigned int)del1/del2)*del2) count=count+1; count=count/2; NDEL=N-NP; DDEL=D-DP; for (J=0; J<count; J++) { NP=NP-NDEL; DP=DP-DDEL; temp=temp+cos(2.0*pi*(double)NP/(double)DP); } } else { del1=(int)OP-(int)DP; del2=DP-D; count=(unsigned int)del1/del2; NDEL=NP-N; DDEL=DP-D; for (J=0; J<count; J++) { NP=NP+NDEL; DP=DP+DDEL; temp=temp+cos(2.0*pi*(double)NP/(double)DP); } } askip: tmpsum=tmpsum+temp; if (((NP<<16)|DP)!=S[I+1]) { H=NP; K=DP; zig=zig+1; if (zig==2) tzig=tzig+1; else ozig=ozig+1; goto aloop; } // // end loop // bskip: if (zig>maxzig) maxzig=zig; sum2=sum2+tmpsum; temp=cos(2.0*pi*(double)HSAV/(double)KSAV); sum=sum+temp; total=oldtot; oldtot=sum2; printf(" %d %d/%d %e %e \n",I,HSAV,KSAV,sum,total); // fprintf(Outfp," %d %d/%d %e %e \n",I,HSAV,KSAV,sum,total); T[tind]=total; U[tind]=(HSAV<<16)|KSAV; tind=tind+1; } if (oflag==0) J=O; else J=O-1; for (I=0; I<J; I++) total=total+cos(2.0*pi*(double)(O+I)/(double)(O+I+1)); printf("order=%d, sums=%e, %e \n",O,sum,total); //fprintf(Outfp,"order=%d, sums=%e, %e \n",O,sum,total); // // check results // printf("number of fractions (half order)=%d, maximum zigzags=%d \n",tind,maxzig); printf("number of zigzag types=%d, %d \n",ozig,tzig); J=0; L=haros1(OP,0,S,0,1,1,OP); sum=0.0; for (I=0; I<L; I++) { H=S[I]>>16; K=S[I]&0xffff; sum=sum+cos(2.0*pi*(double)H/(double)K); if ((out==0)&&((double)H/(double)K<=0.5)&&(I<1000)) fprintf(Outfp," %e\n",sum); if (S[I]!=U[J]) continue; if ((out==1)&&((double)H/(double)K<=0.5)&&(I<1000)) fprintf(Outfp," %e\n",T[J]); delta=sum-1.0-T[J]; if (delta<0) delta=-delta; if (delta>0.000001) { printf("error: J=%d, fraction=%d/%d, sums=%e, %e \n",J,H,K,sum,T[J]); break; } J=J+1; } printf("number of fractions (full order)=%d \n",L); zskip: return; }