/*****************************************************************************/
/* */
/* COMPUTE 3N+1 SEQUENCE (probabilities) */
/* 12/26/08 (dkc) */
/* */
/* This C program determines the number of jumps required to reach an even */
/* natural number. */
/* */
/*****************************************************************************/
#include <stdio.h>
#include <math.h>
unsigned int lmbd(unsigned int mode, unsigned int a);
void mul64_32(unsigned int a, unsigned int b, unsigned int c, unsigned int *p);
void div64_32(unsigned int *a, unsigned int *b, unsigned int);
void add64(unsigned int *a, unsigned int *b);
void sub64(unsigned int *c, unsigned int *d);
int main () {
unsigned int i,j,k,m,n,out[2000],flag,count,total,iters;
unsigned int V[2],W[2],X[3],Y[2],g[1000],h[1000];
double r;
FILE *Outfp;
Outfp = fopen("out1.dat","w");
for (i=0; i<1000; i++) {
h[i]=0; // clear histogram of k values
g[i]=0; // clear histogram of iteration values
}
iters=0; // number of starting values
total=0; // number of k values
W[0]=0; // load 1
W[1]=1;
for (i=3; i<6000003; i+=6) { // odd n values divisible by 3
iters=iters+1; // increment number of starting values
V[0]=0; // load n
V[1]=i;
m=0; // clear output array pointer
out[0]=V[0]; // save n value
out[1]=V[1];
m=1; // increment output array pointer
n=1; // number of terms in sequence (not used)
for (j=1; j<100000000; j++) {
mul64_32(V[0], V[1], 3, X);
V[0]=X[1];
V[1]=X[2];
add64(W, V); // 3n+1
if (m<1000) {
out[2*m]=V[0]; // save n value
out[2*m+1]=V[1];
m=m+1; // increment output array pointer
}
else {
printf("error: output array not big enough \n");
goto zskip;
}
n=n+1; // increment number of terms in sequence
div64_32(V, Y, 8); // (3n+1)/8
mul64_32(Y[0], Y[1], 8, X);
Y[0]=X[1]; // [(3n+1)/8]*8
Y[1]=X[2];
sub64(V, Y);
if ((Y[0]==0)&&(Y[1]==0)) { // 8 divides 3n+1
div64_32(V, V, 2); // n=n/2
if (m<1000) {
out[2*m]=V[0]; // save n value
out[2*m+1]=V[1];
m=m+1; // increment output array pointer
}
n=n+1; // increment number of terms in sequence
div64_32(V, V, 2); // n=n/2
if (m<1000) {
out[2*m]=V[0]; // save n value
out[2*m+1]=V[1];
m=m+1; // increment output array pointer
}
else {
printf("error: output array not big enough \n");
goto zskip;
}
n=n+1; // increment number of terms in sequence
goto askip;
}
div64_32(V, Y, 2); // n/2
mul64_32(Y[0], Y[1], 2, X); // (n/2)*2
Y[0]=X[1];
Y[1]=X[2];
sub64(V, Y); // n-(n/2)*2
while ((Y[0]==0)&&(Y[1]==0)) { // 2 divides n
div64_32(V, V, 2); // n=n/2
if (m<1000) {
out[2*m]=V[0]; // save n value
out[2*m+1]=V[1];
m=m+1; // increment output array pointer
}
else {
printf("error: output array not big enough \n");
goto zskip;
}
n=n+1; // increment number of terms in sequence
div64_32(V, Y, 2); // n/2
mul64_32(Y[0], Y[1], 2, X); // (n/2)*2
Y[0]=X[1];
Y[1]=X[2];
sub64(V, Y); // n-(n/2)*2
}
}
fprintf(Outfp,"error \n");
askip:
flag=0; // clear k iteration count
count=1; // initialize k value
for (k=1; k<m-1; k++) {
V[0]=out[2*k-2]; // load n'
V[1]=out[2*k-1];
div64_32(V, Y, 2); // n'/2
mul64_32(Y[0], Y[1], 2, X); // (n'/2)*2
Y[0]=X[1];
Y[1]=X[2];
sub64(V, Y); // n'-(n'/2)*2
if ((Y[0]==0)&&(Y[1]==0)) { // 2 divides n'
V[0]=out[2*k]; // load n
V[1]=out[2*k+1];
div64_32(V, Y, 2); // n/2
mul64_32(Y[0], Y[1], 2, X); // (n/2)*2
Y[0]=X[1];
Y[1]=X[2];
sub64(V, Y); // n-(n/2)*2
if ((Y[0]==0)&&(Y[1]==0)) { // 2 divides n
count=count/2; // k=k/2
// fprintf(Outfp," %d \n",count);
h[count]=h[count]+1; // histogram k value
count=0; // clear k value
flag=flag+1; // increment k iteration count
}
}
count=count+1; // k=k+1
}
// fprintf(Outfp,"\n");
g[flag]=g[flag]+1; // histogram k iteration count
total=total+flag; // increment total number of k values
}
fprintf(Outfp,"histogram of k values, total=%d \n",total);
for (i=0; i<100; i++) {
r=(double)h[i];
r=r/(double)total;
fprintf(Outfp," %d %f \n",h[i],r);
}
fprintf(Outfp,"\n");
fprintf(Outfp,"histogram of iteration values, total=%d \n",iters);
for (i=0; i<100; i++) {
r=(double)g[i];
r=r/(double)iters;
fprintf(Outfp," %d %f \n",g[i],r);
}
zskip:
fclose(Outfp);
return(0);
}