/*--------------------------------------------------------------------*/ /* */ /* http://members.aol.com/golomb20 */ /* */ /* This program is a pre-program for use */ /* with GARSP, a routine to find Optimal */ /* Golomb Rulers. Please see the OGR */ /* home page for more details. */ /* */ /* */ /* Precompiled outputs are available for download */ /* */ /*--------------------------------------------------------------------*/ /* Choose.c ...creates CHOOSE.DAT file of MAXBITS bits/map for GARSP */ /* */ /* Usage: */ /* If you already have a good "choose.dat" keep it there! */ /* Change the MAXBITS to what you need, and compile this source */ /* Run choose.c (It builds from the old choose.dat as needed!) */ /* If you stop the run at any point, just restart it to finish */ /* */ /* When done: */ /* * delete the "choose.ck1" file */ /* * move your old choose.dat file to a safe place */ /* * rename choose.new to choose.dat */ /*--------------------------------------------------------------------*/ /* */ /* choose[0][N] = OGR length of N segments, with no bits preset */ /* */ /* Version 5, Alexey Guzeev (aga@permonline.ru) & M.Garry 4/98 */ /* Added ability to shrink or grow existing choose file. */ /* Added ability to generate choose.dat in several runs */ /* Added idle priority code for OS/2 and Win32 */ /* Added AMD K5 specific optimization */ /* */ /* Version 4 modified by Geoffrey Faivre-Malloy 3/5/98 */ /* Added parens around 4 "<<" and ">>" operations so this */ /* compiles correctly on Borland c++ v5.0 "x< "(x<=32 which allowed an undefined */ /* (non-ansi) x<<32 operation. This error was already */ /* fixed in GARSP 5.06, but not in CHOOSE. */ /* */ /*--------------------------------------------------------------------*/ /*-----INCLUDES----*/ #include #include #include #ifdef OS2 #define INCL_DOSPROCESS #include #endif #ifdef WIN32 #include #endif #ifdef AMDK5 # ifndef __GNUC__ # error K5 optimization designed to be compiled using GCC # endif # ifndef __i386__ # error K5 optimization is not accessible at non-x86 machines # endif #endif /*-----TYPEDEFs----*/ typedef unsigned long U; /*-----DEFINES-----*/ /* Fill choose array up to choose[10][ffff] */ #define MAXDEPTH 11 /* we fill choose array to MAXDEPTH-1 */ #define MAXBITS 20 /* we fill choose array to MAXBITS */ #define MAXFILE (1< #endif /* DOUBLE_CHECKPOINT */ /*-----GLOBALS-----*/ int max; /* maximum length of ruler */ int depth; /* current number of marks in ruler */ int maxdepth; /* maximum number of marks in ruler */ unsigned char choose[MAXDEPTH][MAXFILE]; /* array of ruler lengths */ int half_length; /* half of max */ int half_length2; /* half of max using 2nd center mark */ int half_depth; /* half of maxdepth */ int half_depth2; /* half of maxdepth, adjusted for 2nd mark */ int count[MAXDEPTH+1]; /* current length */ #ifndef AMDK5 int first[0x10000]; /* first open bit in a 16 bit bitmap */ #endif int newbit[MAXBITS+1]; int new; int counter; int diff,diffs[333],bit[333]; char BUILDUP = 0; /* used to make big choose from small one */ /*---------------------------------*/ /* GOLOMB Workhorse routine */ /*---------------------------------*/ #ifdef WIN32 __fastcall golomb(U bitmap) #else void golomb(U bitmap) #endif { U c[MAXDEPTH]; /* comparison bitmap */ U list[MAXDEPTH]; /* ruler bitmap */ U dist[MAXDEPTH]; /* distance bitmap */ U t; /* temp bitmap */ int limit[MAXDEPTH]; /* limit for this mark */ int i,s; depth = 1; /* 1st mark @ left edge begin placing 2nd mark */ c[1] = dist[1] = bitmap; list[1] = count[1] = 0; limit[1] = max-choose[maxdepth-2][0]; start: t = ~c[depth]; #ifdef AMDK5 __asm__ (" movl $33, %%ebx bsrl %%eax, %%eax jz 0f subl %%eax, %%ebx decl %%ebx 0: " : "=b"(s) : "a"(t) : "%eax", "%ebx", "cc"); #else /* AMDK5 */ if( t > 0x0000ffff ) { s = first[t>>16]; } else { if( t > 0 ) { s = 16 + first[t]; } else { s = 33; } } #endif /* AMDK5 */ if( (count[depth] += s) > limit[depth] ) goto up_level; if (depth == maxdepth-1) { for( i=1; i= 0; s-- ) { diff = count[i]-count[s]; if( diff > 32 ) { /* only need check 32 count[depth] ) break; if( diffs[diff] ) goto skip; diffs[diff] = 1; } } } new=count[depth]; max=new-1; /* reset the limits for when we go back down! */ for( i=1; i>(32-MAXBITS)]; } if( maxdepth > 5 ) { half_length = ((max + 1) >> 1) - 1; limit[half_depth] = (limit[half_depth] > half_length) ? half_length : limit[half_depth]; if(half_depth2-half_depth) { half_length2 = max - count[half_depth] - 1; limit[depth] = (limit[depth] > half_length2) ? half_length2 : limit[depth]; } } skip: for( i=33; i <= count[depth]>>1; i++ ) diffs[i]=0; goto up_level; } if( s > 31 ) { c[depth] = 0; list[depth] = 0; } else { c[depth] <<= s; list[depth] >>= s; } depth++; count[depth] = count[depth-1]; list[depth] = list[depth-1] | bit[count[depth-1]-count[depth-2]]; dist[depth] = dist[depth-1] | list[depth]; c[depth] = c[depth-1] | dist[depth]; limit[depth] = max-choose[maxdepth - depth - 1][(dist[depth])>>(32-MAXBITS)]; if (depth <= half_depth2) { if (depth <= half_depth) { limit[depth] = (limit[depth] > half_length) ? half_length : limit[depth]; } else { half_length2 = max - count[half_depth] - 1; limit[depth] = (limit[depth] > half_length2) ? half_length2 : limit[depth]; } } goto start; up_level: if (--depth == 0) return; goto start; } void bitwise( int nummax, int numbits, U bitmap, int bit ){ int m1,n; if( numbits ) { for( n = bit; n <= MAXBITS-numbits; n++ ) { newbit[numbits]=n; bitwise(nummax,numbits-1,bitmap+(1<> 1) - 1; new = 0; if( BUILDUP==0 || bitmap%(1<= 0; j--) if( i & (1<= MAXBITS) { if ((length_file = fopen("choose.new","wb")) == NULL) { printf("\n\nError: Cannot open output file\n\n"); exit(1); } printf("Reading %d bits/map from the choose.dat (%d bits/map)\n\n", MAXBITS, maxb); { unsigned char data[22]; /* data being copied */ unsigned char maxbb=MAXBITS; fwrite(&version, sizeof(char), 1, length_file); fwrite(&maxd , sizeof(char), 1, length_file); fwrite(&maxbb , sizeof(char), 1, length_file); for (j=0; j<1<>1)-1; if ( !(maxdepth%2) ) half_depth2++; if (maxdepth < 5) half_depth = half_depth2 = 0; for (numbits = MAXBITS; numbits >= 0; numbits--) { printf("%d",numbits); fflush(stdout); if ( (maxdepth=load_bits)) ) { printf(" "); fflush(stdout); continue; } bitwise(numbits,numbits,0l,0); /* write checkpoint */ if ( (MIN_CHECKPOINT_INTERVAL==0) || (time(NULL)-last_checkpoint_save