1 /*
2  * See copyright in copyright.h and the accompanying file COPYING
3  */
4 
5 /*
6  *========================================================================
7  *                         RGB Lagged Sums Test
8  *
9  * This is a very simple test template for a test that generates a single
10  * trivial statistic -- in fact, it is the demo user test from the
11  * dieharder CLI sources.  Use a GSL-wrapped generator to generate the
12  * rands required to sample that number, obtaining an iid (independent,
13  * identically distributed) set of samples.  find their mean.  Determine
14  * the probability of obtaining that particular value by a random trial
15  * (from the erf of the associated normal distribution) -- this is the
16  * "p-value" of the trial.
17  *
18  * The interesting thing about this test is that -- simple as it is -- when
19  * it is run on an rng for a series of possible lags, it suffices to show
20  * that e.g. mt19937 is actually weak because it is TOO UNIFORM -- the set
21  * of pvalues that result from performing the lagged sum test for certain
22  * lags come out too uniformly distributed between 0 and 1 so that the
23  * final KS test yields a pvalue of e.g. 0.9995... -- a two in ten thousand
24  * chance -- for two or three lags in the range 0-32.  Similar weakness is
25  * actually observed for rgb_permutations.  This might not affect most
26  * simulations based on the generator -- many of them would if anything
27  * benefit from a slight "over-uniformity" of the random number stream,
28  * especially when it is only apparent for certain lags and seeds.  Others
29  * might fail altogether because certain tails in the space of random
30  * numbers aren't being sampled at the expected rate.  It is very much
31  * caveat emptor for users of pseudo-random number generators as all of them
32  * are likely weak SOMEWHERE -- dieharder just gives you a microscope to use
33  * to reveal their specific weaknesses and the likely bounds where they
34  * won't matter.
35  *========================================================================
36  */
37 
38 #include <dieharder/libdieharder.h>
39 
rgb_lagged_sums(Test ** test,int irun)40 int rgb_lagged_sums(Test **test,int irun)
41 {
42 
43  uint t,i,lag;
44  Xtest ptest;
45 
46  /*
47   * Get the lag from ntuple.  Note that a lag of zero means
48   * "don't throw any away".
49   */
50  test[0]->ntuple = ntuple;
51  lag = test[0]->ntuple;
52 
53  /*
54   * ptest.x = actual sum of tsamples lagged samples from rng
55   * ptest.y = tsamples*0.5 is the expected mean value of the sum
56   * ptest.sigma = sqrt(tsamples/12.0) is the standard deviation
57   */
58  ptest.x = 0.0;  /* Initial value */
59  ptest.y = (double) test[0]->tsamples*0.5;
60  ptest.sigma = sqrt(test[0]->tsamples/12.0);
61 
62  if(verbose == D_RGB_LAGGED_SUMS || verbose == D_ALL){
63    printf("# rgb_lagged_sums(): Doing a test with lag %u\n",lag);
64  }
65 
66  for(t=0;t<test[0]->tsamples;t++){
67 
68    /*
69     * A VERY SIMPLE test, but sufficient to demonstrate the
70     * weaknesses in e.g. mt19937.
71     */
72 
73    /* Throw away lag per sample */
74    for(i=0;i<lag;i++) gsl_rng_uniform(rng);
75 
76    /* sample only every lag numbers, reset counter */
77    ptest.x += gsl_rng_uniform(rng);
78 
79  }
80 
81  Xtest_eval(&ptest);
82  test[0]->pvalues[irun] = ptest.pvalue;
83 
84  if(verbose == D_RGB_LAGGED_SUMS || verbose == D_ALL){
85    printf("# rgb_lagged_sums(): ks_pvalue[%u] = %10.5f\n",irun,test[0]->pvalues[irun]);
86  }
87 
88  return(0);
89 
90 }
91 
help_rgb_lagged_sums()92 void help_rgb_lagged_sums()
93 {
94 
95   printf("%s",rgb_lagged_sums_dtest.description);
96 
97 }
98