/* Output from p2c, the Pascal-to-C translator */ /* From input file "kepler.pas" */ /* This is a Pascal program which allows to search numerically */ /* for local maxima of the packing */ /* density of almost periodic sphere packings. This implementation works */ /* for packings in dimensions 2,3,4,5 */ /* After having made experiments with this program, I conjectured */ /* that local maxima are */ /* rational alpha parameters. The program makes a guess for the best */ /* rational parameter. That critical points are indeed rational is proven */ /* in the paper: */ /* Oliver Knill, 'Maximizing the packing density on a class of almost */ /* periodic sphere packings' */ /* Expositiones Mathematicae, 14 (1996), p. 227-246, 1996 */ /* This Pascal program was written by Oliver Knill in 1995 at Caltech */ /* We had used more sophisticated programs when writing the paper */ /* The other programs are however in kind of a mess and I don't post them */ /* If you don't change any of the parameters and compile the program */ /* and run it, then the program will report critical points */ /* of almost periodic packings with spheres on the integer lattice */ /* in dimension 3. It will start with spheres of */ /* radius=Sqrt(25) and end the search with spheres of radius=sqrt(50). */ /* By adjusting the waiting parameter (now waitingparameter=3000), the */ /* scaling factor (now factor=5) and the number of resettings before in */ /* creasing the radius of the spheres */ /* (now numberoftries=3), one can search differently and more */ /* persistently, and looking for better local minima. */ /* We still have the hope that a more sophisticated version of such a */ /* program (when running on a more sophisticated computer) might find */ /* in some dimension (probably bigger than 5) a packing which will have */ /* record density. If you should decide to continue the search, I wish */ /* good luck. */ #include /* for INT_MAX */ #include #define pi 3.141592653589793 /* a well known constant */ #define np 20000 /* arraylength */ #define eee (1 / 10000000000.0) /* search treshold */ #define dimension 5 /* dimension must be 2,3,4 or 5 */ #define firstr 25 /* radius^2 for initial search */ #define lastr 50 /* radius^2, where the search ends */ #define numberoftries 3 /* number of times to start new */ /* with same parameters and on */ /* initial search level */ #define waitingparameter 300 /* time until the search is refined */ #define search1 1.0 /* initial search factor */ #define factor 5 /* scaling for adaptive search */ #define randseed 0.95532523948761234 /* a 'random number', used because */ /* because internal random number */ /* generator is deterministic */ typedef double realarray[np]; typedef long vector2[2]; typedef long vector3[3]; typedef long vector4[4]; typedef long vector5[5]; typedef double realvector3[3]; typedef double realvector4[4]; typedef double realvector5[5]; vector2 p2[np]; vector3 p[np]; vector4 p4[np]; vector5 p5[np]; long N; /*Number of balls */ double V; /*Scaling factor for computing */ /*packing density from interval */ /*length. Depends on the dimension*/ double max; /*best density */ double r; /* radius of balls */ long rn; /* sqrt(rn)=r */ double a1, a2, a3, a4, a5; /* middle search point */ double c1, c2, c3, c4, c5; /* search vectors */ double rec1, rec2, rec3; /* records */ double rec4, rec5; /* records */ double search; /* search size */ double display; /* density displayed if overcome */ realarray u; /* the set R(r) alpha */ double d; /* density */ long nosucc; /* number of nosuccess in loop */ int showintermed; /* show intermediate steps */ long den; /* denominator in rational search */ double bestdens; /* best density for batch run */ /* A horrible implementation of modulo which works in our case */ /* Never bothered to make this nice */ double modulo(s) double s; { return (s + 3000000 - (long)(s + 3000000)); } void initialisation2d() { long ll; vector2 vec; long rr; rr = (long)r + 1; ll = 1; vec[0] = -rr; vec[1] = -rr; while (vec[0] <= r) { while (vec[1] <= r) { if (vec[0] * vec[0] + vec[1] * vec[1] < rn && vec[0] * vec[0] + vec[1] * vec[1] > 0) { memcpy(p2[ll - 1], vec, sizeof(vector2)); ll++; } vec[1]++; } vec[0]++; vec[1] = -rr; } N = ll - 1; V = r * r * pi / 4; } void initialisation3d() { long ll; vector3 vec; long rr; rr = (long)r + 1; ll = 1; vec[0] = -rr; vec[1] = -rr; vec[2] = -rr; while (vec[0] <= r) { while (vec[1] <= r) { while (vec[2] <= r) { if (vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2] < rn && vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2] > 0) { memcpy(p[ll - 1], vec, sizeof(vector3)); ll++; } vec[2]++; } vec[1]++; vec[2] = -rr; } vec[0]++; vec[2] = -rr; vec[1] = -rr; } N = ll - 1; V = r * r * r * pi / 6; } void initialisation4d() { long l; vector4 vec; long rr; rr = (long)r; l = 1; vec[0] = -rr; vec[1] = -rr; vec[2] = -rr; vec[3] = -rr; while (vec[0] <= r) { while (vec[1] <= r) { while (vec[2] <= r) { while (vec[3] <= r) { if (vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2] + vec[3] * vec[3] < rn && vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2] + vec[3] * vec[3] > 0) { memcpy(p4[l - 1], vec, sizeof(vector4)); l++; } vec[3]++; } vec[2]++; vec[3] = -rr; } vec[1]++; vec[3] = -rr; vec[2] = -rr; } vec[0]++; vec[3] = -rr; vec[2] = -rr; vec[1] = -rr; } N = l - 1; V = r * r * r * r * pi * pi / 32; } void initialisation5d() { long l; vector5 vec; long rr; rr = (long)r; l = 1; vec[0] = -rr; vec[1] = -rr; vec[2] = -rr; vec[3] = -rr; vec[4] = -rr; while (vec[0] <= r) { while (vec[1] <= r) { while (vec[2] <= r) { while (vec[3] <= r) { while (vec[4] <= r) { if (vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2] + vec[3] * vec[3] + vec[4] * vec[4] < rn && vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2] + vec[3] * vec[3] + vec[4] * vec[4] > 0) { memcpy(p5[l - 1], vec, sizeof(vector5)); l++; } vec[4]++; } vec[3]++; vec[4] = -rr; } vec[2]++; vec[3] = -rr; vec[4] = -rr; } vec[1]++; vec[2] = -rr; vec[3] = -rr; vec[4] = -rr; } vec[0]++; vec[1] = -rr; vec[2] = -rr; vec[3] = -rr; vec[4] = -rr; } N = l - 1; V = r * r * r * r * r * pi * pi / 60; } /* The following sorting procedure is taken from the Numerical Receipes */ /* It is only used for coverings and not in this program. */ void sort(n, ra) long n; double *ra; { long lsort, j, i, ir; double rra; lsort = n / 2 + 1; ir = n; while (1==1) { if (lsort > 1) { lsort--; rra = ra[lsort - 1]; } else { rra = ra[ir - 1]; ra[ir - 1] = ra[0]; ir--; if (ir == 1) { ra[0] = rra; goto _L99; } } i = lsort; j = lsort + lsort; while (j <= ir) { if (j < ir) { if (ra[j - 1] < ra[j]) j++; } if (rra < ra[j - 1]) { ra[i - 1] = ra[j - 1]; i = j; j += j; } else j = ir + 1; } ra[i - 1] = rra; } _L99: ; } double min(n, ra) long n; double *ra; { long g; double m; m = ra[0]; for (g = 1; g < n; g++) { if (ra[g] < m) m = ra[g]; } return m; } double minimum(a, b) double a, b; { if (a < b) return a; else return b; } void showparameter() { if (showintermed != 1) return; if (dimension == 2) printf("{%12.10f,%12.10f}%12.10f\n", rec1, rec2, d); if (dimension == 3) printf("{%12.10f,%12.10f,%12.10f}%12.10f\n", rec1, rec2, rec3, d); if (dimension == 4) printf("{%12.10f,%12.10f,%12.10f,%12.10f}%12.10f\n", rec1, rec2, rec3, rec4, d); if (dimension == 5) printf("{%12.10f,%12.10f,%12.10f,%12.10f,%12.10f}%12.10f\n", rec1, rec2, rec3, rec4, rec5, d); } void findrational() { long k; double best, a; best = 1.0; for (k = 1; k <= 5000; k++) { a = minimum(modulo(k * a1), modulo(-k * a1)) + minimum(modulo(k * a2), modulo(-k * a2)); if (dimension > 2) a += minimum(modulo(k * a3), modulo(-k * a3)); if (dimension > 3) a += minimum(modulo(k * a4), modulo(-k * a4)); if (dimension > 4) a += minimum(modulo(k * a5), modulo(-k * a5)); if (a < best) { best = a; den = k; } } } void showresult() { if (d <= bestdens) return; bestdens = d; printf("dimension= %12ld r*r= %12ld"); printf("%d\n",rn); if (dimension == 2) { printf("alpha={%12.10f,%12.10f} \n", a1, a2); printf("The density is %12.10f\n", d); } if (dimension == 3) { printf("alpha={%12.10f,%12.10f,%12.10f} \n", a1, a2, a3); printf("The density is %12.10f\n", d); } if (dimension == 4) { printf("alpha={%12.10f,%12.10f,%12.10f,%12.10f} \n", a1, a2, a3, a4); printf("The density is %12.10f\n", d); } if (dimension == 5) { printf("alpha={%12.10f,%12.10f,%12.10f,%12.10f,%12.10f} \n", a1, a2, a3, a4, a5); printf("The density is %12.10f\n", d); } findrational(); printf("Best denominator guess:%12ld\n", den); printf("The nominators are then integers near:\n"); printf("%12.10f %12.10f ", a1 * den, a2 * den); if (dimension > 2) printf("%12.10f ", a3 * den); if (dimension > 3) printf("%12.10f ", a4 * den); if (dimension > 4) printf("%12.10f ", a5 * den); printf("\n***************************************************************\n"); } void run2d() { long l, FORLIM; c1 = modulo(a1 + rand()*1.0*pi/INT_MAX); c2 = modulo(a2 + rand()*1.0*pi/INT_MAX); nosucc = 0; while (1==1) { c1 = modulo(c1 + rand()*1.0*pi/INT_MAX); c2 = modulo(c2 + rand()*1.0*pi/INT_MAX); FORLIM = N; for (l = 0; l < FORLIM; l++) { u[l] = modulo((a1 + (c1 - 1.0 / 2) * search) * p2[l][0] + (a2 + (c2 - 1.0 / 2) * search) * p2[l][1]); if (u[l] < max) { nosucc++; goto _L96; } } d = min(N, u) * V; if (d > display) { nosucc = 0; rec1 = modulo(a1 + (c1 - 1.0 / 2) * search); rec2 = modulo(a2 + (c2 - 1.0 / 2) * search); showparameter(); max = d / V; display = d; } _L96: if (nosucc <= waitingparameter) continue; nosucc = 0; a1 = rec1; a2 = rec2; search /= factor; if (search < eee) goto _L95; if (showintermed == 1) printf(".\n"); } _L95: ; } void run3d() { long m, FORLIM; c1 = modulo(a1 + rand()*1.0*pi/INT_MAX); c2 = modulo(a2 + rand()*1.0*pi/INT_MAX); c3 = modulo(a3 + rand()*1.0*pi/INT_MAX); nosucc = 0; while (1==1) { c1 = modulo(c1 + rand()*1.0*pi/INT_MAX); c2 = modulo(c2 + rand()*1.0*pi/INT_MAX); c3 = modulo(c3 + rand()*1.0*pi/INT_MAX); FORLIM = N; for (m = 0; m < FORLIM; m++) { u[m] = modulo((a1 + (c1 - 1.0 / 2) * search) * p[m][0] + (a2 + (c2 - 1.0 / 2) * search) * p[m][1] + (a3 + (c3 - 1.0 / 2) * search) * p[m][2]); if (u[m] < max) { nosucc++; goto _L96; } } d = min(N, u) * V; if (d > display) { nosucc = 0; rec1 = modulo(a1 + (c1 - 1.0 / 2) * search); rec2 = modulo(a2 + (c2 - 1.0 / 2) * search); rec3 = modulo(a3 + (c3 - 1.0 / 2) * search); showparameter(); max = d / V; display = d; } _L96: if (nosucc <= waitingparameter) continue; nosucc = 0; a1 = rec1; a2 = rec2; a3 = rec3; search /= factor; if (search < eee) goto _L95; if (showintermed == 1) printf(".\n"); } _L95: ; } void run4d() { long l, FORLIM; c1 = modulo(a1 + rand()*1.0*pi/INT_MAX); c2 = modulo(a2 + rand()*1.0*pi/INT_MAX); c3 = modulo(a3 + rand()*1.0*pi/INT_MAX); c4 = modulo(a4 + rand()*1.0*pi/INT_MAX); nosucc = 0; while (1==1) { c1 = modulo(c1 + rand()*1.0*pi/INT_MAX); c2 = modulo(c2 + rand()*1.0*pi/INT_MAX); c3 = modulo(c3 + rand()*1.0*pi/INT_MAX); c4 = modulo(c4 + rand()*1.0*pi/INT_MAX); FORLIM = N; for (l = 0; l < FORLIM; l++) { u[l] = modulo((a1 + (c1 - 1.0 / 2) * search) * p4[l][0] + (a2 + (c2 - 1.0 / 2) * search) * p4[l][1] + (a3 + (c3 - 1.0 / 2) * search) * p4[l][2] + (a4 + (c4 - 1.0 / 2) * search) * p4[l][3]); if (u[l] < max) { nosucc++; goto _L96; } } d = min(N, u) * V; if (d > display) { nosucc = 0; rec1 = modulo(a1 + (c1 - 1.0 / 2) * search); rec2 = modulo(a2 + (c2 - 1.0 / 2) * search); rec3 = modulo(a3 + (c3 - 1.0 / 2) * search); rec4 = modulo(a4 + (c4 - 1.0 / 2) * search); showparameter(); max = d / V; display = d; } _L96: if (nosucc <= waitingparameter) continue; nosucc = 0; a1 = rec1; a2 = rec2; a3 = rec3; a4 = rec4; search /= factor; if (search < eee) goto _L95; if (showintermed == 1) printf(".\n"); } _L95: ; } void run5d() { long l, FORLIM; c1 = modulo(a1 + rand()*1.0*pi/INT_MAX); c2 = modulo(a2 + rand()*1.0*pi/INT_MAX); c3 = modulo(a3 + rand()*1.0*pi/INT_MAX); c4 = modulo(a4 + rand()*1.0*pi/INT_MAX); c5 = modulo(a5 + rand()*1.0*pi/INT_MAX); nosucc = 0; while (1==1) { c1 = modulo(c1 + rand()*1.0*pi/INT_MAX); c2 = modulo(c2 + rand()*1.0*pi/INT_MAX); c3 = modulo(c3 + rand()*1.0*pi/INT_MAX); c4 = modulo(c4 + rand()*1.0*pi/INT_MAX); c5 = modulo(c5 + rand()*1.0*pi/INT_MAX); FORLIM = N; for (l = 0; l < FORLIM; l++) { u[l] = modulo((a1 + (c1 - 1.0 / 2) * search) * p5[l][0] + (a2 + (c2 - 1.0 / 2) * search) * p5[l][1] + (a3 + (c3 - 1.0 / 2) * search) * p5[l][2] + (a4 + (c4 - 1.0 / 2) * search) * p5[l][3] + (a5 + (c5 - 1.0 / 2) * search) * p5[l][4]); if (u[l] < max) { nosucc++; goto _L96; } } d = min(N, u) * V; if (d > display) { nosucc = 0; rec1 = modulo(a1 + (c1 - 1.0 / 2) * search); rec2 = modulo(a2 + (c2 - 1.0 / 2) * search); rec3 = modulo(a3 + (c3 - 1.0 / 2) * search); rec4 = modulo(a4 + (c4 - 1.0 / 2) * search); rec5 = modulo(a5 + (c5 - 1.0 / 2) * search); showparameter(); max = d / V; display = d; } _L96: if (nosucc <= waitingparameter) continue; nosucc = 0; a1 = rec1; a2 = rec2; a3 = rec3; a4 = rec4; a5 = rec5; search /= factor; if (search < eee) goto _L95; if (showintermed == 1) printf(".\n"); } _L95: ; } void initialisation() { if (dimension == 2) initialisation2d(); if (dimension == 3) initialisation3d(); if (dimension == 4) initialisation4d(); if (dimension == 5) initialisation5d(); printf("\n################################################################\n"); printf(" The initialisation for the new radius is done! The program \n"); printf(" searches now for critical points with the parameters \n"); printf(" Square of the radius: r*r= %12ld \n", rn); printf(" Dimension: d= %12ld \n", (long)dimension); printf(" Info: Number of lattice points in Ball(r) is: N= %12ld \n", N); /* writeln(' Scaling factor: V= ',V:7:6); ')*/ printf("################################################################\n"); max = display / V; } void run() { if (dimension == 2) run2d(); if (dimension == 3) run3d(); if (dimension == 4) run4d(); if (dimension == 5) run5d(); } void shortinit() { a1 = modulo( rand()*1.0*pi/INT_MAX + randseed); a2 = modulo( rand()*1.0*pi/INT_MAX + 2 * randseed); a3 = modulo((double) rand()*1.0*pi/INT_MAX); a4 = modulo((double) rand()*1.0*pi/INT_MAX); a5 = modulo((double) rand()*1.0*pi/INT_MAX); search = search1; display = 0.0; max = 0.0; } void batchrun() { long i, irn; showintermed = 0; for (irn = firstr; irn <= lastr; irn++) { rn = irn; r = sqrt((double)rn); shortinit(); initialisation(); bestdens = 0.0; for (i = 1; i <= numberoftries; i++) { shortinit(); run(); showresult(); } } } main(argc, argv) int argc; char *argv[]; { batchrun(); } /* End. */