/*****************************************************************************/ /* */ /* FIND CYCLES IN THE 3N+C SEQUENCE */ /* 03/22/11 (dkc) */ /* */ /* This C program finds cycles in the 3n+c sequence. Attachment points in */ /* cycles and t values (odd integers divisible by 3) of the extended */ /* sequences are output. Cycles not having attachment points are also */ /* found (in this case, odd elements of the cycles are output). Lengths of */ /* the cycles (where the element after an odd element i in the 3n+c */ /* sequence is defined to be 3i+c) are also output. Domains of the */ /* exponential functions for the primary attachment points and t values are */ /* also output. The number of even elements in the cycle (denoted by L) */ /* and the number of odd elements in the cycle (denoted by K) are also */ /* output. (In this case, the element after an odd element i is defined */ /* to be (3i+c)/2.) */ /* */ /*****************************************************************************/ #include <stdio.h> #include <math.h> /*****************************************************************************/ /* */ /* regenerate cycles */ /* */ /*****************************************************************************/ int regen(int c, int s, int flag, int *w) { int k,tres; unsigned int j,count; // // find odd natural number divisible by 3 // k=s; while (k!=(k/3)*3) { if ((k&1)==0) { if ((k-c)==((k-c)/3)*3) k=(k-c)/3; else k=k*2; } else k=k*2; } tres=k; // k=s; count=2; if (flag==0) goto zskip; w[1]=k; while ((k&1)==0) { k=k/2; w[count]=k; count=count+1; } for (j=1; j<1000000; j++) { k=3*k+c; w[count]=k; count=count+1; if (count>32767) { tres=0; goto zskip; } while ((k&1)==0) { if (k==s) goto zskip; k=k/2; w[count]=k; count=count+1; if (count>32767) { tres=0; goto zskip; } } } tres=0; zskip: w[0]=count-1; return(tres); } int main () { // int cstart=1103; // beginning c value int cend=1199; // ending c value unsigned int iters=2; // number of "jumps" from the initial value // // usually set to 1 or 2 // unsigned int d,e,f,g,h,j,m,n,o,count,sume,sumo,ne,no,ma,mi,delta,numb; int limit,temp,max,i,k,save[32],v[32768],w[32768],t,u,tres,saves,oldk,bsave; int out[4000*2]; int factor[200],t1,t2,c,maxodd,minodd,tmpodd; unsigned int x[2000],kx[2000],levens,lodds,first,cmin,cmax; unsigned int table[167]={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}; double lambdae,lambdao,y,tmax,tmin,kmax,kmin,maxdel,mindel; FILE *Outfp; Outfp = fopen("out0a.dat","w"); if (cstart==(cstart/3)*3) { printf("c divisible by 3 \n"); goto zskip; } if (cstart==(cstart/2)*2) { printf("c divisible by 2 \n"); goto zskip; } if (cstart<0) { printf("negative c value \n"); goto zskip; } if (cstart>5045) { printf("warning: Cycle may not be primitive. \n"); goto zskip; } if (cend==(cend/3)*3) { printf("c divisible by 3 \n"); goto zskip; } if (cend==(cend/2)*2) { printf("c divisible by 2 \n"); goto zskip; } if (cend<0) { printf("negative c value \n"); goto zskip; } if (cend>5045) { printf("warning: Cycle may not be primitive. \n"); goto zskip; } maxdel=-1000000.0; mindel=1000000.0; for (c=cstart; c<=cend; c+=2) { if (c==(c/3)*3) continue; printf("c=%d \n",c); printf("\n"); fprintf(Outfp,"c=%d \n",c); fprintf(Outfp,"\n"); count=0; if (c!=1) { factor[0]=c; count=1; } for (i=0; i<167; i++) { t=(int)table[i]; if (c==(c/t)*t) { factor[count]=t; count=count+1; } } limit=1500000; // must be a multiple of 6 max=1<<29; m=0; for (i=3-limit; i<limit; i+=6) { k=(int)i; // initial sequence value for (e=0; e<iters; e++) { k=k+c; n=0; // clear count while ((k&1)==0) { k=k/2; n=n+1; } temp=k; if (temp<0) temp=-temp; for (j=0; j<n; j++) { if (temp>max) // check for overflow goto askip; temp=temp*3; k=k*3; } k=(k-c)/2; // sequence value after a "jump" if ((k&1)==0) goto bskip; } temp=k; if (temp<0) temp=-temp; if (temp>max) // check for overflow goto askip; k=3*k+c; bskip: h=0; // clear index n=0; // clear index while ((k&1)==0) { v[n]=k; // save sequence value n=n+1; // increment index if (h<32) { // check index save[h]=k; // save even sequence value h=h+1; // increment index } else { // array too small printf("error: array too small \n"); goto zskip; } k=k/2; } bsave=k; // save odd sequence value for (j=1; j<1000000; j++) { v[n]=k; // save sequence value n=n+1; // increment index if (n>32767) // array full goto askip; temp=k; if (temp<0) temp=-temp; if (temp>max) goto askip; k=3*k+c; while ((k&1)==0) { for (g=0; g<h; g++) { if (k==save[g]) { for (f=g; f<n; f++) { if ((v[f]&7)==0) { for (e=0; e<m; e++) { if (((int)(n-g)==out[2*e])&&((v[f]/4)==out[2*e+1])) { goto askip; } } t=v[f]/4; if (t<0) t=-t; for (e=0; e<count; e++) { u=factor[e]; if (t==(t/u)*u) goto askip; } tres=regen(c, v[f]/4, 1, w); if (tres==0) { printf("return value equals 0 \n"); goto zskip; } t1=tres; first=1; temp=v[f]/4; if (temp<0) temp=-temp; kx[0]=temp; sume=temp; temp=tres; if (temp<0) temp=-temp; x[0]=temp; sumo=temp; ne=1; no=1; printf("n=%d k=%d t=%d \n",n-g,v[f]/4,tres); fprintf(Outfp,"n=%d k=%d t=%d \n",n-g,v[f]/4,tres); out[2*m]=n-g; out[2*m+1]=v[f]/4; m=m+1; if (m>=4000) { printf("output array full \n"); goto zskip; } o=w[0]; saves=v[f]/4; delta=0; while ((saves&3)==0) { saves=saves/4; delta=delta+2; if ((saves&1)==1) goto qskip; tres=regen(c, saves, 0, w); if (tres==0) { printf("return value equals 0 \n"); goto zskip; } if (first==1) { t2=tres; first=0; } temp=tres; if (temp<0) temp=-temp; x[no]=temp; sumo=sumo+temp; no=no+1; if (no>999) { printf("array not big enough \n"); goto zskip; } printf(" k=%d t=%d \n",saves,tres); fprintf(Outfp," k=%d t=%d \n",saves,tres); out[2*m]=n-g; out[2*m+1]=saves; m=m+1; if (m>=4000) { printf("output array full \n"); goto zskip; } e=0; } if ((saves&1)==0) { saves=saves/2; delta=delta+1; } qskip: saves=3*saves+c; delta=delta+1; oldk=0; for (d=2+delta; d<o; d++) { if (((w[d]&1)==0)&&(w[d]!=saves)&&((w[d]-c)==((w[d]-c)/3)*3)) { tres=regen(c, w[d], 0, w); if (tres==0) { printf("return value equals 0 \n"); goto zskip; } if (first==1) { t2=tres; first=0; } temp=tres; if (temp<0) temp=-temp; x[no]=temp; sumo=sumo+temp; no=no+1; if (no>999) { printf("array not big enough \n"); goto zskip; } if ((w[d]*4)!=oldk) { temp=w[d]; if (temp<0) temp=-temp; kx[ne]=temp; sume=sume+temp; ne=ne+1; } oldk=w[d]; printf(" k=%d t=%d \n",w[d],tres); fprintf(Outfp," k=%d t=%d \n",w[d],tres); out[2*m]=n-g; out[2*m+1]=w[d]; m=m+1; if (m>=4000) { printf("output array full \n"); goto zskip; } } if ((w[d]&1)==1) saves=3*w[d]+c; e=0; } if (o>3) { if (w[1]==(w[o-2]*4)) { printf("unexpected duplicate: w=%d %d %d %d \n",w[1],w[2],w[o-2],w[o-1]); temp=w[o-2]; if (temp<0) temp=-temp; sume=sume-temp; ne=ne-1; } if (((w[1]*4)==w[o-2])&&((w[o-3]&1)!=1)) { temp=w[1]; if (temp<0) temp=-temp; sume=sume-temp; ne=ne-1; } } lambdae=(double)sume/ne; lambdao=(double)sumo/no; if (ne==1) goto mskip; printf("lambda (k)=%e n=%d, lambda (t)=%e n=%d \n",lambdae,ne,lambdao,no); fprintf(Outfp,"lambda (k)=%e n=%d, lambda (t)=%e n=%d\n",lambdae,ne,lambdao,no); ma=0; mi=0x7fffffff; for (e=0; e<(int)ne; e++) { y=-log((double)kx[e]/lambdae)/lambdae; if (kx[e]>ma) { ma=kx[e]; kmax=y; } if (kx[e]<mi) { mi=kx[e]; kmin=y; } } printf("max/min (k)=(%d, %d), domain=(%e, %e) \n",ma,mi,kmax,kmin); fprintf(Outfp,"max/min (k)=(%d, %d), domain=(%e, %e) \n",ma,mi,kmax,kmin); if (kmin<-kmax) { printf("warning: Maximum x not greater than absolute value of minimum. \n"); } mskip: if (no==1) goto nskip; if ((no==2)&&(t1==-t2)) { printf("Count equals 2 and absolute values of t values same.\n"); goto nskip; } ma=0; mi=0x7fffffff; for (e=0; e<(int)no; e++) { y=-log((double)x[e]/lambdao)/lambdao; if (x[e]>ma) { ma=x[e]; tmax=y; } if (x[e]<mi) { mi=x[e]; tmin=y; } } y=tmin-tmax; if (y>maxdel) { maxdel=y; cmax=c; } if (y<mindel) { mindel=y; cmin=c; } printf("max/min (t)=(%d, %d), domain=(%e, %e), d=%e \n",ma,mi,tmax,tmin,y); fprintf(Outfp,"max/min (t)=(%d %d), domain=(%e, %e), d=%e \n",ma,mi,tmax,tmin,y); if (tmin<-tmax) { printf("warning: Maximum x not greater than absolute value of minimum. \n"); } if (ne!=1) { if (tmax>kmax) { printf("warning: Not within t domain. \n"); } if (tmin<kmin) { printf("warning: Not within t domain. \n"); } } nskip: k=w[1]; levens=0; while ((k&1)==0) { k=k/2; levens=levens+1; } lodds=1; maxodd=0; minodd=0x7fffffff; for (j=1; j<1000000; j++) { tmpodd=k; if (tmpodd<0) tmpodd=-tmpodd; if (tmpodd>maxodd) maxodd=tmpodd; if (tmpodd<minodd) minodd=tmpodd; k=3*k+c; while ((k&1)==0) { if (k==w[1]) { levens=levens-1; goto oskip; } k=k/2; levens=levens+1; } levens=levens-1; lodds=lodds+1; } printf("error \n"); goto zskip; oskip: printf("L=%d, K=%d, min=%d, max=%d \n",levens,lodds,minodd,maxodd); fprintf(Outfp,"L=%d, K=%d, min=%d, max=%d \n",levens,lodds,minodd,maxodd); if ((2*minodd>maxodd)&&(lodds!=1)) { printf("warning: Twice mininum odd element is greater than maximum odd element. \n"); fprintf(Outfp,"warning: Twice mininum odd element is greater than maximum odd element. \n"); } printf("\n"); fprintf(Outfp,"\n"); goto askip; } } for (e=0; e<m; e++) { if (((int)(n-g)==out[2*e])&&(bsave==out[2*e+1])) { goto askip; } } t=bsave; if (t<0) t=-t; for (e=0; e<count; e++) { u=factor[e]; if (t==(t/u)*u) goto askip; } printf("n=%d o=%d",n-g,bsave); fprintf(Outfp,"n=%d o=%d",n-g,bsave); out[2*m]=n-g; out[2*m+1]=(int)bsave; m=m+1; if (m>=4000) { printf("output array full \n"); goto zskip; } numb=2; levens=0; lodds=1; maxodd=bsave; if (maxodd<0) maxodd=-maxodd; minodd=bsave; if (minodd<0) minodd=-minodd; k=bsave; for (j=1; j<1000000; j++) { k=3*k+c; while ((k&1)==0) { k=k/2; levens=levens+1; } levens=levens-1; lodds=lodds+1; if (k==bsave) { lodds=lodds-1; goto pskip; } out[2*m]=n-g; out[2*m+1]=k; m=m+1; if (m>=4000) { printf("output array full \n"); goto zskip; } tmpodd=k; if (tmpodd<0) tmpodd=-tmpodd; if (maxodd<tmpodd) maxodd=tmpodd; if (minodd>tmpodd) minodd=tmpodd; printf(" %d",k); fprintf(Outfp," %d",k); numb=numb+1; if (numb>8) { printf("\n"); fprintf(Outfp,"\n"); numb=0; } } printf("error \n"); goto zskip; pskip: if (numb!=0) { printf("\n"); fprintf(Outfp,"\n"); } printf("L=%d, K=%d \n",levens,lodds); fprintf(Outfp,"L=%d, K=%d \n",levens,lodds); if (minodd!=maxodd) { if ((2*minodd)>maxodd) { printf("minodd=%d, maxodd=%d \n",minodd,maxodd); fprintf(Outfp,"minodd=%d, maxodd=%d \n",minodd,maxodd); } } printf("\n"); fprintf(Outfp,"\n"); goto askip; } } v[n]=k; n=n+1; if (n>32767) goto askip; k=k/2; } } askip: n=0; } printf("\n"); fprintf(Outfp,"\n"); } printf("\n"); fprintf(Outfp,"\n"); printf("maximum interval=%e, minimum interval=%e \n",maxdel,mindel); fprintf(Outfp,"maximum interval=%e, minimum interval=%e \n",maxdel,mindel); printf("c (for maximum)=%d, c (for minimum)=%d \n",cmax,cmin); fprintf(Outfp,"c (for maximum)=%d, c (for minimum)=%d \n",cmax,cmin); zskip: fclose(Outfp); return(0); }