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 dab_filltree(Test **test,int irun) { int size = (ntuple == 0) ? 32 : ntuple; uint target = sizeof(targetData)/sizeof(double); int startVal = (size / 2) - 1; double *array = (double *) malloc(sizeof(double) * size); double *counts, *expected; int i, j; double x; uint start = 0; uint end = 0; uint rotAmount = 0; double *positionCounts; counts = (double *) malloc(sizeof(double) * target); expected = (double *) malloc(sizeof(double) * target); memset(counts, 0, sizeof(double) * target); positionCounts = (double *) malloc(sizeof(double) * size/2); memset(positionCounts, 0, sizeof(double) * size/2); test[0]->ntuple = size; test[1]->ntuple = size; /* Calculate expected counts. */ for (i = 0; i < target; i++) { expected[i] = targetData[i] * test[0]->tsamples; if (expected[i] < 4) { if (end == 0) start = i; } else if (expected[i] > 4) end = i; } start++; for (j = 0; j < test[0]->tsamples; j++) { int ret; memset(array, 0, sizeof(double) * size); i = 0; do { uint v = gsl_rng_get(rng); x = ((double) RotL(v, rotAmount)) / rmax_mask; i++; if (i > size * 2) { test[0]->pvalues[irun] = 0; return(0); } ret = insert(x, array, startVal); } while (ret == -1); positionCounts[ret/2]++; counts[i-1]++; if (j % (test[0]->tsamples/CYCLES) == 0) rotAmount++; } test[0]->pvalues[irun] = chisq_pearson(counts + start, expected + start, end - start); for (i = 0; i < size/2; i++) expected[i] = test[0]->tsamples/(size/2); test[1]->pvalues[irun] = chisq_pearson(positionCounts, expected, size/2); nullfree(positionCounts); nullfree(expected); nullfree(counts); nullfree(array); return(0); }