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); }
double diehard_rank_6x8(QVector<double> const &sample) { rng = gsl_rng_alloc(gsl_rng_taus); int i = 0; int t = 0; int rank = 0; uint bitstring; Vtest vtest; uint **mtx; mtx = new uint * [6]; for (i = 0; i < 6; i++){ mtx[i] = new uint [8]; } Vtest_create(&vtest, 7); vtest.cutoff = 5.0; for (i = 0; i < 2; i++){ vtest.x[i] = 0.0; vtest.y[i] = 0.0; } vtest.x[2] = 0.0; vtest.y[2] = sample[1]; vtest.x[3] = 0.0; vtest.y[3] = sample[2]; vtest.x[4] = 0.0; vtest.y[4] = sample[3]; vtest.x[5] = 0.0; vtest.y[5] = sample[4]; vtest.x[6] = 0.0; vtest.y[6] = sample[5]; double r = 0; for (t = 0; t < 6; t++) { /* * We generate 6 random rmax_bits-bit integers and put a * randomly chosen byte into the LEFTMOST byte position * of the row/slot of mtx. */ for (i = 0; i < 6; i++){ bitstring = get_rand_bits_uint(32, 0xffffffff, rng); mtx[i][0] = bitstring; } rank = binary_rank(mtx, 6, 8); r += rank; //MYDEBUG(D_DIEHARD_RANK_6x8){ // printf("binary rank = %d\n", rank); //} if (rank <= 2) { vtest.x[2]++; } else { vtest.x[rank]++; } } Vtest_eval(&vtest); int result = vtest.pvalue; Vtest_destroy(&vtest); for (i = 0; i < 6; i++) { delete [] mtx[i]; } delete [] mtx; gsl_rng_free(rng); return r / 6.0 ; }
int diehard_squeeze(Test **test, int irun) { int i,j,k; Vtest vtest; /* * Squeeze counts the iterations required to reduce 2^31 to * to 1 with k = ceiling(k*U) where U is a uniform deviate. It * does this test[0]->tsamples times, binning the result in a vector from * <= 6 to >= 48 (where it has nontrivial support). A chisq test * on the vector (Vtest) then yields a pvalue for the test run. */ /* * for display only. 0 means "ignored". */ test[0]->ntuple = 0; /* * Allocate memory for Vtest struct vector (length 51) and initialize * it with the expected values. */ Vtest_create(&vtest,43); /* * Initialize the expected value vector */ vtest.cutoff = 5.0; for(i=0;i<43;i++){ vtest.y[i] = test[0]->tsamples*sdata[i]; } memset(vtest.x,0,43*sizeof(double)); /* * Test this. */ MYDEBUG(D_DIEHARD_SQUEEZE) { for(i=0;i<43;i++){ printf("%d: %f %f\n",i+6,vtest.x[i],vtest.y[i]); } } /* * We now squeeze test[0]->tsamples times. */ for(i=0;i<test[0]->tsamples;i++){ k = 2147483647; j = 0; /* printf("%d: %d\n",j,k); */ while((k != 1) && (j < 48)){ k = ceil(k*gsl_rng_uniform(rng)); j++; /* printf("%d: %d\n",j,k); */ } /* * keep j in range 6-48 inclusive and increment the test/counting vector. */ j = (j<6)?6:j; vtest.x[j-6]++; } MYDEBUG(D_DIEHARD_SQUEEZE) { for(i=0;i<43;i++){ printf("%d: %f %f\n",i+6,vtest.x[i],vtest.y[i]); } } Vtest_eval(&vtest); test[0]->pvalues[irun] = vtest.pvalue; MYDEBUG(D_DIEHARD_SQUEEZE) { printf("# diehard_squeeze(): test[0]->pvalues[%u] = %10.5f\n",irun,test[0]->pvalues[irun]); } Vtest_destroy(&vtest); return(0); }
int rgb_permutations(Test **test,int irun) { uint i,j,k,permindex=0,t; Vtest vtest; double *testv; size_t ps[4096]; gsl_permutation** lookup; MYDEBUG(D_RGB_PERMUTATIONS){ printf("#==================================================================\n"); printf("# rgb_permutations: Debug with %u\n",D_RGB_PERMUTATIONS); } /* * Number of permutations. Note that the minimum ntuple value for a * valid test is 2. If ntuple is less than 2, we choose the default * test size as 5 (like operm5). */ if(ntuple<2){ test[0]->ntuple = 5; } else { test[0]->ntuple = ntuple; } k = test[0]->ntuple; nperms = gsl_sf_fact(k); /* * A vector to accumulate rands in some sort order */ testv = (double *)malloc(k*sizeof(double)); MYDEBUG(D_RGB_PERMUTATIONS){ printf("# rgb_permutations: There are %u permutations of length k = %u\n",nperms,k); } /* * Create a test, initialize it. */ Vtest_create(&vtest,nperms); vtest.cutoff = 5.0; for(i=0;i<nperms;i++){ vtest.x[i] = 0.0; vtest.y[i] = (double) test[0]->tsamples/nperms; } MYDEBUG(D_RGB_PERMUTATIONS){ printf("# rgb_permutations: Allocating permutation lookup table.\n"); } lookup = (gsl_permutation**) malloc(nperms*sizeof(gsl_permutation*)); for(i=0;i<nperms;i++){ lookup[i] = gsl_permutation_alloc(k); } for(i=0;i<nperms;i++){ if(i == 0){ gsl_permutation_init(lookup[i]); } else { gsl_permutation_memcpy(lookup[i],lookup[i-1]); gsl_permutation_next(lookup[i]); } } MYDEBUG(D_RGB_PERMUTATIONS){ for(i=0;i<nperms;i++){ printf("# rgb_permutations: %u => ",i); gsl_permutation_fprintf(stdout,lookup[i]," %u"); printf("\n"); } } /* * We count the order permutations in a long string of samples of * rgb_permutation_k non-overlapping rands. This is done by: * a) Filling testv[] with rgb_permutation_k rands. * b) Using gsl_sort_index to generate the permutation index. * c) Incrementing a counter for that index (a-c done tsamples times) * d) Doing a straight chisq on the counter vector with nperms-1 DOF * * This test should be done with tsamples > 30*nperms, easily met for * reasonable rgb_permutation_k */ for(t=0;t<test[0]->tsamples;t++){ /* * To sort into a perm, test vector needs to be double. */ for(i=0;i<k;i++) { testv[i] = (double) gsl_rng_get(rng); MYDEBUG(D_RGB_PERMUTATIONS){ printf("# rgb_permutations: testv[%u] = %u\n",i,(uint) testv[i]); } } gsl_sort_index(ps,testv,1,k); MYDEBUG(D_RGB_PERMUTATIONS){ for(i=0;i<k;i++) { printf("# rgb_permutations: ps[%u] = %lu\n",i,ps[i]); } } for(i=0;i<nperms;i++){ if(memcmp(ps,lookup[i]->data,k*sizeof(size_t))==0){ permindex = i; MYDEBUG(D_RGB_PERMUTATIONS){ printf("# Found permutation: "); gsl_permutation_fprintf(stdout,lookup[i]," %u"); printf(" = %u\n",i); } break; } } vtest.x[permindex]++; MYDEBUG(D_RGB_PERMUTATIONS){ printf("# rgb_permutations: Augmenting vtest.x[%u] = %f\n",permindex,vtest.x[permindex]); } }