void rgb_lmn_test() { uint t,i,lag; Xtest ptest; /* * ptest.x = actual sum of tsamples lagged samples from rng * ptest.y = tsamples*0.5 is the expected mean value of the sum * ptest.sigma = sqrt(tsamples/12.0) is the standard deviation */ ptest.x = 0.0; /* Initial value */ ptest.y = (double) tsamples*0.5; ptest.sigma = sqrt(tsamples/12.0); /* * sample only every lag returns from the rng, discard the rest. * We have to get the (float) value from the user input and set * a uint */ if(x_user){ lag = x_user; } else { lag = 2; /* Why not? Anything but 0, really... */ } if(verbose == D_USER_TEMPLATE || verbose == D_ALL){ printf("# rgb_lmn(): Doing a test on lag %u\n",lag); } for(t=0;t<tsamples;t++){ /* * A VERY SIMPLE test (probably not too sensitive) */ /* Throw away lag-1 per sample */ for(i=0;i<(lag-1);i++) gsl_rng_uniform(rng); /* sample only every lag numbers, reset counter */ ptest.x += gsl_rng_uniform(rng); } Xtest_eval(&ptest); ks_pvalue[kspi] = ptest.pvalue; if(verbose == D_USER_TEMPLATE || verbose == D_ALL){ printf("# rgb_lmn(): ks_pvalue[%u] = %10.5f\n",kspi,ks_pvalue[kspi]); } kspi++; }
int user_template(Test **test,int irun) { unsigned int t,i,lag; Xtest ptest; /* * Get the lag from ntuple. Note that a lag of zero means * "don't throw any away". */ lag = test[0]->ntuple; /* * ptest.x = actual sum of tsamples lagged samples from rng * ptest.y = tsamples*0.5 is the expected mean value of the sum * ptest.sigma = sqrt(tsamples/12.0) is the standard deviation */ ptest.x = 0.0; /* Initial value */ ptest.y = (double) test[0]->tsamples*0.5; ptest.sigma = sqrt(test[0]->tsamples/12.0); if(verbose == D_USER_TEMPLATE || verbose == D_ALL){ printf("# user_template(): Doing a test with lag %u\n",lag); } for(t=0;t<test[0]->tsamples;t++){ /* * A VERY SIMPLE test, but sufficient to demonstrate the * weaknesses in e.g. mt19937. */ /* Throw away lag per sample */ for(i=0;i<lag;i++) gsl_rng_uniform(rng); /* sample only every lag numbers, reset counter */ ptest.x += gsl_rng_uniform(rng); } Xtest_eval(&ptest); test[0]->pvalues[irun] = ptest.pvalue; if(verbose == D_USER_TEMPLATE || verbose == D_ALL){ printf("# user_template(): ks_pvalue[%u] = %10.5f\n",irun,test[0]->pvalues[irun]); } return(0); }
int dab_dct(Test **test,int irun) { double *dct; unsigned int *input; double *pvalues = NULL; unsigned int i, j; unsigned int len = (ntuple == 0) ? 256 : ntuple; int rotAmount = 0; unsigned int v = 1<<(rmax_bits-1); double mean = (double) len * (v - 0.5); /* positionCounts is only used by the primary test, and not by the * fallback test. */ double *positionCounts; /* The primary method is a chisq; we want expected counts of at least * five. If the number of tsamples is too low for that, use the * fallback method, which is doing kstest across the pvalues. */ int useFallbackMethod = (test[0]->tsamples > 5 * len) ? 0 : 1; /* ptest, v, and sd are only used in the fall-back method, when * tsamples is too small compared to ntuple. */ Xtest ptest; double sd = sqrt((1.0/6.0) * len) * v; dct = (double *) malloc(sizeof(double) * len); input = (unsigned int *) malloc(sizeof(unsigned int) * len); positionCounts = (double *) malloc(sizeof(double) * len); if (useFallbackMethod) { pvalues = (double *) malloc(sizeof(double) * len * test[0]->tsamples); } /* Zero out the counts initially. */ memset(positionCounts, 0, sizeof(double) * len); test[0]->ntuple = len; /* When used, the data is normalized first. */ ptest.y = 0.0; ptest.sigma = 1.0; /* Main loop runs tsamples times. During each iteration, a vector * of length ntuple will be read from the generator, so a total of * (tsamples * ntuple) words will be read from the RNG. */ for (j=0; j<test[0]->tsamples; j++) { unsigned int pos = 0; double max = 0; /* Change the rotation amount after each quarter of the samples * have been used. */ if (j != 0 && (j % (test[0]->tsamples / 4) == 0)) { rotAmount += rmax_bits/4; } /* Read (and rotate) the actual rng words. */ for (i=0; i<len; i++) { input[i] = gsl_rng_get(rng); input[i] = RotL(input[i], rotAmount); } /* Perform the DCT */ fDCT2_fft(input, dct, len); /* Adjust the first value (the DC coefficient). */ dct[0] -= mean; dct[0] /= sqrt(2); // Experimental + guess; seems to be correct. if (!useFallbackMethod) { /* Primary method: find the position of the largest value. */ for (i=0; i<len; i++) { if (fabs(dct[i]) > max) { pos = i; max = fabs(dct[i]); } } /* And record it. */ positionCounts[pos]++; } else { /* Fallback method: convert all values to pvalues. */ for (i=0; i<len; i++) { ptest.x = dct[i] / sd; Xtest_eval(&ptest); pvalues[j*len + i] = ptest.pvalue; } } } if (!useFallbackMethod) { /* Primary method: perform a chisq test for uniformity * of discrete counts. */ double p; double *expected = (double *) malloc(sizeof(double) * len); for (i=0; i<len; i++) { expected[i] = (double) test[0]->tsamples / len; } p = chisq_pearson(positionCounts, expected, len); test[0]->pvalues[irun] = p; free(expected); } else { /* Fallback method: perform a ks test for uniformity of the * continuous p-values. */ test[0]->pvalues[irun] = kstest(pvalues, len * test[0]->tsamples); } nullfree(positionCounts); nullfree(pvalues); /* Conditional; only used in fallback */ nullfree(input); nullfree(dct); return(0); }
int diehard_count_1s_byte(Test **test, int irun) { uint i,j,k,index5=0,index4,letter,t; uint boffset; uint count5[3125],count4[625]; Vtest vtest4,vtest5; Xtest ptest; /* * count_1s in specific bytes is straightforward after looking over * count_1s in a byte. The statistic is identical; we just have to * cycle the offset of the bytes selected and generate 1 random uint * per digit. */ /* * I'm leaving this in so the chronically bored can validate that * the table exists and is correctly loaded and addressable. */ if(verbose == -1){ for(i=0;i<256;i++){ printf("%u, ",b5b[i]); /* dumpbits(&i,8); */ if((i+1)%16 == 0){ printf("\n"); } } exit(0); } /* * for display only. 0 means "ignored". */ test[0]->ntuple = 0; /* * This is basically a pair of parallel vtests, with a final test * statistic generated from their difference (somehow). We therefore * create two vtests, one for four digit base 5 integers and one for * five digit base 5 integers, and generate their expected values for * test[0]->tsamples trials. */ ptest.y = 2500.0; ptest.sigma = sqrt(5000.0); Vtest_create(&vtest4,625); vtest4.cutoff = 5.0; for(i=0;i<625;i++){ j = i; vtest4.y[i] = test[0]->tsamples; vtest4.x[i] = 0.0; /* * Digitize base 5, compute expected value for THIS integer i. */ /* printf("%u: ",j); */ for(k=0;k<4;k++){ /* * Take the least significant "letter" of j in range 0-4 */ letter = j%5; /* * multiply by the probability of getting this letter */ vtest4.y[i] *= pb[letter]; /* * Right shift j to get next digit. */ /* printf("%1u",letter); */ j /= 5; } /* printf(" = %f\n",vtest4.y[i]); */ } Vtest_create(&vtest5,3125); vtest5.cutoff = 5.0; for(i=0;i<3125;i++){ j = i; vtest5.y[i] = test[0]->tsamples; vtest5.x[i] = 0.0; /* * Digitize base 5, compute expected value for THIS integer i. */ for(k=0;k<5;k++){ /* * Take the least significant "letter" of j in range 0-4 */ letter = j%5; /* * multiply by the probability of getting this letter */ vtest5.y[i] *= pb[letter]; /* * Right shift j to get next digit. */ j /= 5; } } /* * Here is the test. We cycle boffset through test[0]->tsamples */ boffset = 0; for(t=0;t<test[0]->tsamples;t++){ boffset = t%32; /* Remember that get_bit_ntuple periodic wraps the uint */ /* * Get the next five bytes and make an index5 out of them, no * overlap. */ for(k=0;k<5;k++){ i = get_rand_bits_uint(32, 0xFFFFFFFF, rng); if(verbose == D_DIEHARD_COUNT_1S_STREAM || verbose == D_ALL){ dumpbits(&i,32); } /* * get next byte from the last rand we generated. * Bauer fix - * Cruft: j = get_bit_ntuple_from_uint(i,8,0x000000FF,boffset); */ j = get_bit_ntuple_from_whole_uint(i,8,0x000000FF,boffset); index5 = LSHIFT5(index5,b5b[j]); if(verbose == D_DIEHARD_COUNT_1S_STREAM || verbose == D_ALL){ printf("b5b[%u] = %u, index5 = %u\n",j,b5b[j],index5); dumpbits(&j,8); } } /* * We use modulus to throw away the sixth digit in the left-shifted * base 5 index value, keeping the value of the 5-digit base 5 number * in the range 0 to 5^5-1 or 0 to 3124 decimal. We repeat for the * four digit index. At this point we increment the counts for index4 * and index5. Tres simple, no? */ index5 = index5%3125; index4 = index5%625; vtest4.x[index4]++; vtest5.x[index5]++; } /* * OK, all that is left now is to figure out the statistic. */ if(verbose == D_DIEHARD_COUNT_1S_BYTE || verbose == D_ALL){ for(i = 0;i<625;i++){ printf("%u: %f %f\n",i,vtest4.y[i],vtest4.x[i]); } for(i = 0;i<3125;i++){ printf("%u: %f %f\n",i,vtest5.y[i],vtest5.x[i]); } } Vtest_eval(&vtest4); Vtest_eval(&vtest5); if(verbose == D_DIEHARD_COUNT_1S_BYTE || verbose == D_ALL){ printf("vtest4.chisq = %f vtest5.chisq = %f\n",vtest4.chisq,vtest5.chisq); } ptest.x = vtest5.chisq - vtest4.chisq; Xtest_eval(&ptest); test[0]->pvalues[irun] = ptest.pvalue; MYDEBUG(D_DIEHARD_COUNT_1S_BYTE) { printf("# diehard_count_1s_byte(): test[0]->pvalues[%u] = %10.5f\n",irun,test[0]->pvalues[irun]); } Vtest_destroy(&vtest4); Vtest_destroy(&vtest5); return(0); }
void diehard_oqso(Test **test, int irun) { uint i,j,k,l,i0,j0,k0,l0,t,boffset; Xtest ptest; char ****w; /* * p = 141909, with sigma 295, FOR tsamples 2^21 2 letter words. * These cannot be varied unless one figures out the actual * expected "missing works" count as a function of sample size. SO: * * ptest.x = number of "missing words" given 2^21 trials * ptest.y = 141909 * ptest.sigma = 295 */ ptest.x = 0.0; /* Initial value */ ptest.y = 141909.0; ptest.sigma = 295.0; /* * We now make tsamples measurements, as usual, to generate the * missing statistic. We proceed exactly as we did in opso, but * with a 4d 32x32x32x32 matrix and 5 bit indices. This should * basically be strongly related to a Knuth hyperplane test in * four dimensions. Equally obviously there is a sequence of * tests, all basically identical, that can be done here much * as rgb_bitdist tries to do them. I'll postpone thinking about * this in detail until I'm done with diehard and some more of STS * and maybe have implemented the REAL Knuth tests from the Art of * Programming. */ w = (char ****)malloc(32*sizeof(char ***)); for(i=0;i<32;i++){ w[i] = (char ***)malloc(32*sizeof(char **)); for(j=0;j<32;j++){ w[i][j] = (char **)malloc(32*sizeof(char *)); for(k=0;k<32;k++){ w[i][j][k] = (char *)malloc(32*sizeof(char)); /* Zero the column */ memset(w[i][j][k],0,32*sizeof(char)); } } } /* * To minimize the number of rng calls, we use each j and k mod 32 * to determine the offset of the 10-bit long string (with * periodic wraparound) to be used for the next iteration. We * therefore have to "seed" the process with a random l */ l = gsl_rng_get(rng); for(t=0;t<test[0]->tsamples;t++){ if(overlap){ /* * Let's do this the cheap/easy way first, sliding a 20 bit * window along each int for the 32 possible starting * positions a la birthdays, before trying to slide it all * the way down the whole random bitstring implicit in a * long sequence of random ints. That way we can exit * the tsamples loop at tsamples = 2^15... */ if(t%32 == 0) { i0 = gsl_rng_get(rng); j0 = gsl_rng_get(rng); k0 = gsl_rng_get(rng); l0 = gsl_rng_get(rng); boffset = 0; } /* * Get four "letters" (indices into w) */ i = get_bit_ntuple(&i0,1,5,boffset); j = get_bit_ntuple(&j0,1,5,boffset); k = get_bit_ntuple(&k0,1,5,boffset); l = get_bit_ntuple(&l0,1,5,boffset); /* printf("%u: %u %u %u %u %u\n",t,i,j,k,l,boffset); */ w[i][j][k][l]++; boffset++; } else { /* * Get four "letters" (indices into w) */ boffset = l%32; i = gsl_rng_get(rng); i = get_bit_ntuple(&i,1,5,boffset); boffset = i%32; j = gsl_rng_get(rng); j = get_bit_ntuple(&j,1,5,boffset); boffset = j%32; k = gsl_rng_get(rng); k = get_bit_ntuple(&k,1,5,boffset); boffset = k%32; l = gsl_rng_get(rng); l = get_bit_ntuple(&l,1,5,boffset); w[i][j][k][l]++; } } /* * Now we count the holes, so to speak */ ptest.x = 0.0; for(i=0;i<32;i++){ for(j=0;j<32;j++){ for(k=0;k<32;k++){ for(l=0;l<32;l++){ if(w[i][j][k][l] == 0){ ptest.x += 1.0; /* printf("ptest.x = %f Hole: w[%u][%u][%u][%u] = %u\n",ptest.x,i,j,k,l,w[i][j][k][l]); */ } } } } } MYDEBUG(D_DIEHARD_OQSO){ printf("%f %f %f\n",ptest.y,ptest.x,ptest.x-ptest.y); } Xtest_eval(&ptest); test[0]->pvalues[irun] = ptest.pvalue; MYDEBUG(D_DIEHARD_OQSO) { printf("# diehard_oqso(): ks_pvalue[%u] = %10.5f\n",irun,test[0]->pvalues[irun]); } /* * Don't forget to free w when done, in reverse order */ for(i=0;i<32;i++){ for(j=0;j<32;j++){ for(k=0;k<32;k++){ free(w[i][j][k]); } free(w[i][j]); } free(w[i]); } free(w); }
void diehard_dna(Test **test, int irun) { uint i,j,k,l,m,n,o,p,q,r,t,boffset; uint i0,j0,k0,l0,m0,n0,o0,p0,q0,r0; Xtest ptest; char **********w; /* * p = 141909, with sigma 339, FOR tsamples 2^21+1 2 letter words. * These cannot be varied unless one figures out the actual * expected "missing works" count as a function of sample size. SO: * * ptest.x = number of "missing words" given 2^21+1 trials * ptest.y = 141909 * ptest.sigma = 339 */ ptest.x = 0.0; /* Initial value */ ptest.y = 141909.0; ptest.sigma = 339.0; /* * We now make tsamples measurements, as usual, to generate the missing * statistic. Wow! 10 dimensions! I don't think even my tensor() * package will do that...;-) */ w = (char **********)malloc(4*sizeof(char *********)); for(i=0;i<4;i++){ w[i] = (char *********)malloc(4*sizeof(char ********)); for(j=0;j<4;j++){ w[i][j] = (char ********)malloc(4*sizeof(char *******)); for(k=0;k<4;k++){ w[i][j][k] = (char *******)malloc(4*sizeof(char******)); for(l=0;l<4;l++){ w[i][j][k][l] = (char ******)malloc(4*sizeof(char*****)); for(m=0;m<4;m++){ w[i][j][k][l][m] = (char *****)malloc(4*sizeof(char****)); for(n=0;n<4;n++){ w[i][j][k][l][m][n] = (char ****)malloc(4*sizeof(char***)); for(o=0;o<4;o++){ w[i][j][k][l][m][n][o] = (char ***)malloc(4*sizeof(char**)); for(p=0;p<4;p++){ w[i][j][k][l][m][n][o][p] = (char **)malloc(4*sizeof(char*)); for(q=0;q<4;q++){ w[i][j][k][l][m][n][o][p][q] = (char *)malloc(4*sizeof(char)); /* Zero the column */ memset(w[i][j][k][l][m][n][o][p][q],0,4*sizeof(char)); } } } } } } } } } /* * To minimize the number of rng calls, we use each j and k mod 32 * to determine the offset of the 10-bit long string (with * periodic wraparound) to be used for the next iteration. We * therefore have to "seed" the process with a random l */ q = gsl_rng_get(rng); for(t=0;t<test[0]->tsamples;t++){ if(overlap){ /* * Let's do this the cheap/easy way first, sliding a 20 bit * window along each int for the 32 possible starting * positions a la birthdays, before trying to slide it all * the way down the whole random bitstring implicit in a * long sequence of random ints. That way we can exit * the tsamples loop at tsamples = 2^15... */ if(t%32 == 0) { i0 = gsl_rng_get(rng); j0 = gsl_rng_get(rng); k0 = gsl_rng_get(rng); l0 = gsl_rng_get(rng); m0 = gsl_rng_get(rng); n0 = gsl_rng_get(rng); o0 = gsl_rng_get(rng); p0 = gsl_rng_get(rng); q0 = gsl_rng_get(rng); r0 = gsl_rng_get(rng); boffset = 0; } /* * Get four "letters" (indices into w) */ i = get_bit_ntuple(&i0,1,2,boffset); j = get_bit_ntuple(&j0,1,2,boffset); k = get_bit_ntuple(&k0,1,2,boffset); l = get_bit_ntuple(&l0,1,2,boffset); m = get_bit_ntuple(&m0,1,2,boffset); n = get_bit_ntuple(&n0,1,2,boffset); o = get_bit_ntuple(&o0,1,2,boffset); p = get_bit_ntuple(&p0,1,2,boffset); q = get_bit_ntuple(&q0,1,2,boffset); r = get_bit_ntuple(&r0,1,2,boffset); /* printf("%u: %u %u %u %u %u\n",t,i,j,k,l,boffset); */ w[i][j][k][l][m][n][o][p][q][r]++; boffset++; } else { /* * Get two "letters" (indices into w) */ boffset = q%32; i = gsl_rng_get(rng); i = get_bit_ntuple(&i,1,2,boffset); boffset = i%32; j = gsl_rng_get(rng); j = get_bit_ntuple(&j,1,2,boffset); boffset = j%32; k = gsl_rng_get(rng); k = get_bit_ntuple(&k,1,2,boffset); boffset = k%32; l = gsl_rng_get(rng); l = get_bit_ntuple(&l,1,2,boffset); boffset = l%32; m = gsl_rng_get(rng); m = get_bit_ntuple(&m,1,2,boffset); boffset = m%32; n = gsl_rng_get(rng); n = get_bit_ntuple(&n,1,2,boffset); boffset = n%32; o = gsl_rng_get(rng); o = get_bit_ntuple(&o,1,2,boffset); boffset = o%32; p = gsl_rng_get(rng); p = get_bit_ntuple(&p,1,2,boffset); boffset = p%32; q = gsl_rng_get(rng); q = get_bit_ntuple(&q,1,2,boffset); boffset = q%32; r = gsl_rng_get(rng); r = get_bit_ntuple(&r,1,2,boffset); w[i][j][k][l][m][n][o][p][q][r]++; } } /* * Now we count the holes, so to speak */ ptest.x = 0; for(i=0;i<4;i++){ for(j=0;j<4;j++){ for(k=0;k<4;k++){ for(l=0;l<4;l++){ for(m=0;m<4;m++){ for(n=0;n<4;n++){ for(o=0;o<4;o++){ for(p=0;p<4;p++){ for(q=0;q<4;q++){ for(r=0;r<4;r++){ if(w[i][j][k][l][m][n][o][p][q][r] == 0){ ptest.x += 1.0; /* printf("ptest.x = %f Hole: w[%u][%u][%u][%u] = %u\n",ptest.x,i,j,k,l,w[i][j][k][l]); */ } } } } } } } } } } } MYDEBUG(D_DIEHARD_DNA) { printf("%f %f %f\n",ptest.y,ptest.x,ptest.x-ptest.y); } Xtest_eval(&ptest); test[0]->pvalues[irun] = ptest.pvalue; MYDEBUG(D_DIEHARD_DNA) { printf("# diehard_dna(): test[0]->pvalues[%u] = %10.5f\n",irun,test[0]->pvalues[irun]); } /* * Don't forget to free w when done, in reverse order */ for(i=0;i<4;i++){ for(j=0;j<4;j++){ for(k=0;k<4;k++){ for(l=0;l<4;l++){ for(m=0;m<4;m++){ for(n=0;n<4;n++){ for(o=0;o<4;o++){ for(p=0;p<4;p++){ for(q=0;q<4;q++){ free(w[i][j][k][l][m][n][o][p][q]); } free(w[i][j][k][l][m][n][o][p]); } free(w[i][j][k][l][m][n][o]); } free(w[i][j][k][l][m][n]); } free(w[i][j][k][l][m]); } free(w[i][j][k][l]); } free(w[i][j][k]); } free(w[i][j]); } free(w[i]); } free(w); }
int sts_runs(Test **test, int irun) { int b,t; uint value; uint *rand_int; Xtest ptest; double pones,c00,c01,c10,c11;; /* * for display only. 2 means sts_runs tests 2-tuples. */ test[0]->ntuple = 2; /* * Allocate the space needed by the test. */ rand_int = (uint *)malloc(test[0]->tsamples*sizeof(uint)); /* * Number of total bits from -t test[0]->tsamples = size of rand_int[] */ bits = rmax_bits*test[0]->tsamples; /* * We have to initialize these a bit differently this time */ ptest.x = 0.0; /* * Create entire bitstring to be tested */ for(t=0;t<test[0]->tsamples;t++){ rand_int[t] = gsl_rng_get(rng); } /* * Fill vector of "random" integers with selected generator. * NOTE WELL: This can also be done by reading in a file! */ pones = 0.0; c00 = 0.0; c01 = 0.0; c10 = 0.0; /* Equal to c01 by obvious periodic symmetry */ c11 = 0.0; for(b=0;b<bits;b++){ /* * This gets the integer value of the ntuple at index position * n in the current bitstring, from a window with cyclic wraparound. */ value = get_bit_ntuple(rand_int,test[0]->tsamples,2,b); switch(value){ case 0: /* 00 no new ones */ c00++; break; case 1: /* 01 no new ones */ c01++; ptest.x++; break; case 2: /* 10 one new one (from the left) */ c10++; ptest.x++; pones++; break; case 3: /* 11 one new one (from the left) */ c11++; pones++; break; } MYDEBUG(D_STS_RUNS) { printf("# sts_runs(): ptest.x = %f, pone = %f\n",ptest.x,pones); } } /* * form the probability of getting a one in the entire sample */ pones /= (double) test[0]->tsamples*rmax_bits; c00 /= (double) test[0]->tsamples*rmax_bits; c01 /= (double) test[0]->tsamples*rmax_bits; c10 /= (double) test[0]->tsamples*rmax_bits; c11 /= (double) test[0]->tsamples*rmax_bits; /* * Now we can finally compute the targets for the problem. */ ptest.y = 2.0*bits*pones*(1.0-pones); ptest.sigma = 2.0*sqrt(bits)*pones*(1.0-pones); MYDEBUG(D_STS_RUNS) { printf(" p = %f c00 = %f c01 = %f c10 = %f c11 = %f\n",pones,c00,c01,c10,c11); } Xtest_eval(&ptest); test[0]->pvalues[irun] = ptest.pvalue; MYDEBUG(D_STS_RUNS) { printf("# sts_runs(): test[0]->pvalues[%u] = %10.5f\n",irun,test[0]->pvalues[irun]); } free(rand_int); return(0); }
int diehard_parking_lot(Test **test, int irun) { /* * This is the most that could under any circumstances be parked. */ Cars parked[12000]; uint k,n,i,crashed; double xtry,ytry; Xtest ptest; /* * for display only. 0 means "ignored". */ test[0]->ntuple = 0; test[0]->tsamples = 12000; /* * ptest.x = (double) k * ptest.y = 3523.0 * ptest.sigma = 21.9 * This will generate ptest->pvalue when Xtest(ptest) is called */ ptest.y = 3523.0; ptest.sigma = 21.9; /* * Clear the parking lot the fast way. */ memset(parked,0,12000*sizeof(Cars)); /* * Park a single car to have something to avoid and count it. */ parked[0].x = 100.0*gsl_rng_uniform(rng); parked[0].y = 100.0*gsl_rng_uniform(rng); k = 1; /* * This is now a really simple test. Park them cars! We try to park * 12000 times, and increment k (the number successfully parked) on * successes. We brute force the crash test. */ for(n=1;n<12000;n++){ xtry = 100.0*gsl_rng_uniform(rng); ytry = 100.0*gsl_rng_uniform(rng); crashed = 0; for(i=0;i<k;i++){ /* * We do this REASONABLY efficiently. As soon as we know we didn't * crash we move on until we learn that we crashed, trying to skip * arithmetic. Once we've crashed, we break out of the loop. * Uncrashed survivors join the parked list. */ if( (fabs(parked[i].x - xtry) <= 1.0) && (fabs(parked[i].y - ytry) <= 1.0)){ crashed = 1; /* We crashed! */ break; /* So quit the loop here */ } } /* * Save uncrashed helicopter coordinates. */ if(crashed == 0){ parked[k].x = xtry; parked[k].y = ytry; crashed = 0; k++; } } ptest.x = (double)k; Xtest_eval(&ptest); test[0]->pvalues[irun] = ptest.pvalue; MYDEBUG(D_DIEHARD_PARKING_LOT) { printf("# diehard_parking_lot(): test[0]->pvalues[%u] = %10.5f\n",irun,test[0]->pvalues[irun]); } return(0); }