Blame rng/test.c

Packit 67cb25
/* rng/test.c
Packit 67cb25
 * 
Packit 67cb25
 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough
Packit 67cb25
 * 
Packit 67cb25
 * This program is free software; you can redistribute it and/or modify
Packit 67cb25
 * it under the terms of the GNU General Public License as published by
Packit 67cb25
 * the Free Software Foundation; either version 3 of the License, or (at
Packit 67cb25
 * your option) any later version.
Packit 67cb25
 * 
Packit 67cb25
 * This program is distributed in the hope that it will be useful, but
Packit 67cb25
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 67cb25
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 67cb25
 * General Public License for more details.
Packit 67cb25
 * 
Packit 67cb25
 * You should have received a copy of the GNU General Public License
Packit 67cb25
 * along with this program; if not, write to the Free Software
Packit 67cb25
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Packit 67cb25
 */
Packit 67cb25
Packit 67cb25
#include <config.h>
Packit 67cb25
#include <stdlib.h>
Packit 67cb25
#include <stdio.h>
Packit 67cb25
#include <math.h>
Packit 67cb25
#include <gsl/gsl_rng.h>
Packit 67cb25
#include <gsl/gsl_test.h>
Packit 67cb25
#include <gsl/gsl_ieee_utils.h>
Packit 67cb25
Packit 67cb25
void rng_test (const gsl_rng_type * T, unsigned long int seed, unsigned int n,
Packit 67cb25
               unsigned long int result);
Packit 67cb25
void rng_float_test (const gsl_rng_type * T);
Packit 67cb25
void generic_rng_test (const gsl_rng_type * T);
Packit 67cb25
void rng_state_test (const gsl_rng_type * T);
Packit 67cb25
void rng_parallel_state_test (const gsl_rng_type * T);
Packit 67cb25
void rng_read_write_test (const gsl_rng_type * T);
Packit 67cb25
int rng_max_test (gsl_rng * r, unsigned long int *kmax, unsigned long int ran_max) ;
Packit 67cb25
int rng_min_test (gsl_rng * r, unsigned long int *kmin, unsigned long int ran_min, unsigned long int ran_max) ;
Packit 67cb25
int rng_sum_test (gsl_rng * r, double *sigma);
Packit 67cb25
int rng_bin_test (gsl_rng * r, double *sigma);
Packit 67cb25
void rng_seed_test (const gsl_rng_type * T);
Packit 67cb25
Packit 67cb25
#define N  10000
Packit 67cb25
#define N2 200000
Packit 67cb25
Packit 67cb25
int
Packit 67cb25
main (void)
Packit 67cb25
{
Packit 67cb25
  const gsl_rng_type ** rngs = gsl_rng_types_setup();  /* get all rng types */
Packit 67cb25
Packit 67cb25
  const gsl_rng_type ** r ;
Packit 67cb25
Packit 67cb25
  gsl_ieee_env_setup ();
Packit 67cb25
Packit 67cb25
  gsl_rng_env_setup ();
Packit 67cb25
Packit 67cb25
  /* specific tests of known results for 10000 iterations with seed = 1 */
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_rand, 1, 10000, 1910041713);
Packit 67cb25
  rng_test (gsl_rng_randu, 1, 10000, 1623524161);
Packit 67cb25
  rng_test (gsl_rng_cmrg, 1, 10000, 719452880);
Packit 67cb25
  rng_test (gsl_rng_minstd, 1, 10000, 1043618065);
Packit 67cb25
  rng_test (gsl_rng_mrg, 1, 10000, 2064828650);
Packit 67cb25
  rng_test (gsl_rng_taus, 1, 10000, 2733957125UL);
Packit 67cb25
  rng_test (gsl_rng_taus2, 1, 10000, 2733957125UL);
Packit 67cb25
  rng_test (gsl_rng_taus113, 1, 1000, 1925420673UL);
Packit 67cb25
  rng_test (gsl_rng_transputer, 1, 10000, 1244127297UL);
Packit 67cb25
  rng_test (gsl_rng_vax, 1, 10000, 3051034865UL);
Packit 67cb25
Packit 67cb25
  /* Borosh13 test value from PARI: (1812433253^10000)%(2^32) */
Packit 67cb25
  rng_test (gsl_rng_borosh13, 1, 10000, 2513433025UL);
Packit 67cb25
Packit 67cb25
  /* Fishman18 test value from PARI: (62089911^10000)%(2^31-1) */
Packit 67cb25
  rng_test (gsl_rng_fishman18, 1, 10000, 330402013UL);
Packit 67cb25
Packit 67cb25
  /* Fishman2x test value from PARI: 
Packit 67cb25
     ((48271^10000)%(2^31-1) - (40692^10000)%(2^31-249))%(2^31-1) */
Packit 67cb25
  rng_test (gsl_rng_fishman2x, 1, 10000, 540133597UL);
Packit 67cb25
Packit 67cb25
  /* Knuthran2 test value from PARI: 
Packit 67cb25
     { xn1=1; xn2=1; for (n=1,10000, 
Packit 67cb25
            xn = (271828183*xn1 - 314159269*xn2)%(2^31-1);
Packit 67cb25
            xn2=xn1; xn1=xn; print(xn); ) } */
Packit 67cb25
  rng_test (gsl_rng_knuthran2, 1, 10000, 1084477620UL);
Packit 67cb25
Packit 67cb25
  /* Knuthran test value taken from p188 in Knuth Vol 2. 3rd Ed */
Packit 67cb25
  rng_test (gsl_rng_knuthran, 310952, 1009 * 2009 + 1, 461390032);
Packit 67cb25
Packit 67cb25
  /* Knuthran improved test value from Knuth's source */
Packit 67cb25
  rng_test (gsl_rng_knuthran2002, 310952, 1, 708622036);
Packit 67cb25
  rng_test (gsl_rng_knuthran2002, 310952, 2, 1005450560);
Packit 67cb25
  rng_test (gsl_rng_knuthran2002, 310952, 100 * 2009 + 1, 995235265);
Packit 67cb25
  rng_test (gsl_rng_knuthran2002, 310952, 1009 * 2009 + 1, 704987132);
Packit 67cb25
Packit 67cb25
  /* Lecuyer21 test value from PARI: (40692^10000)%(2^31-249) */
Packit 67cb25
  rng_test (gsl_rng_lecuyer21, 1, 10000, 2006618587UL);
Packit 67cb25
Packit 67cb25
  /* Waterman14 test value from PARI: (1566083941^10000)%(2^32) */
Packit 67cb25
  rng_test (gsl_rng_waterman14, 1, 10000, 3776680385UL);
Packit 67cb25
Packit 67cb25
  /* specific tests of known results for 10000 iterations with seed = 6 */
Packit 67cb25
Packit 67cb25
  /* Coveyou test value from PARI:
Packit 67cb25
     x=6; for(n=1,10000,x=(x*(x+1))%(2^32);print(x);) */
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_coveyou, 6, 10000, 1416754246UL);
Packit 67cb25
Packit 67cb25
  /* Fishman20 test value from PARI: (6*48271^10000)%(2^31-1) */
Packit 67cb25
  rng_test (gsl_rng_fishman20, 6, 10000, 248127575UL);
Packit 67cb25
Packit 67cb25
  /* FIXME: the ranlux tests below were made by running the fortran code and
Packit 67cb25
     getting the expected value from that. An analytic calculation
Packit 67cb25
     would be preferable. */
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_ranlux, 314159265, 10000, 12077992);
Packit 67cb25
  rng_test (gsl_rng_ranlux389, 314159265, 10000, 165942);
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_ranlxs0, 1, 10000, 11904320);
Packit 67cb25
  /* 0.709552764892578125 * ldexp(1.0,24) */
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_ranlxs1, 1, 10000, 8734328);
Packit 67cb25
  /* 0.520606517791748047 * ldexp(1.0,24) */
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_ranlxs2, 1, 10000, 6843140); 
Packit 67cb25
  /* 0.407882928848266602 * ldexp(1.0,24) */
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_ranlxd1, 1, 10000, 1998227290UL);
Packit 67cb25
  /* 0.465248546261094020 * ldexp(1.0,32) */
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_ranlxd2, 1, 10000, 3949287736UL);
Packit 67cb25
  /* 0.919515205581550532 * ldexp(1.0,32) */
Packit 67cb25
Packit 67cb25
  /* FIXME: the tests below were made by running the original code in
Packit 67cb25
     the ../random directory and getting the expected value from
Packit 67cb25
     that. An analytic calculation would be preferable. */
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_slatec, 1, 10000, 45776);
Packit 67cb25
  rng_test (gsl_rng_uni, 1, 10000, 9214);
Packit 67cb25
  rng_test (gsl_rng_uni32, 1, 10000, 1155229825);
Packit 67cb25
  rng_test (gsl_rng_zuf, 1, 10000, 3970);
Packit 67cb25
Packit 67cb25
  /* The tests below were made by running the original code and
Packit 67cb25
     getting the expected value from that. An analytic calculation
Packit 67cb25
     would be preferable. */
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_r250, 1, 10000, 1100653588);
Packit 67cb25
  rng_test (gsl_rng_mt19937, 4357, 1000, 1186927261);
Packit 67cb25
  rng_test (gsl_rng_mt19937_1999, 4357, 1000, 1030650439);
Packit 67cb25
  rng_test (gsl_rng_mt19937_1998, 4357, 1000, 1309179303);
Packit 67cb25
  rng_test (gsl_rng_tt800, 0, 10000, 2856609219UL);
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_ran0, 0, 10000, 1115320064);
Packit 67cb25
  rng_test (gsl_rng_ran1, 0, 10000, 1491066076);
Packit 67cb25
  rng_test (gsl_rng_ran2, 0, 10000, 1701364455);
Packit 67cb25
  rng_test (gsl_rng_ran3, 0, 10000, 186340785);
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_ranmar, 1, 10000, 14428370);
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_rand48, 0, 10000, 0xDE095043UL);
Packit 67cb25
  rng_test (gsl_rng_rand48, 1, 10000, 0xEDA54977UL);
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_random_glibc2, 0, 10000, 1908609430);
Packit 67cb25
  rng_test (gsl_rng_random8_glibc2, 0, 10000, 1910041713);
Packit 67cb25
  rng_test (gsl_rng_random32_glibc2, 0, 10000, 1587395585);
Packit 67cb25
  rng_test (gsl_rng_random64_glibc2, 0, 10000, 52848624);
Packit 67cb25
  rng_test (gsl_rng_random128_glibc2, 0, 10000, 1908609430);
Packit 67cb25
  rng_test (gsl_rng_random256_glibc2, 0, 10000, 179943260);
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_random_bsd, 0, 10000, 1457025928);
Packit 67cb25
  rng_test (gsl_rng_random8_bsd, 0, 10000, 1910041713);
Packit 67cb25
  rng_test (gsl_rng_random32_bsd, 0, 10000, 1663114331);
Packit 67cb25
  rng_test (gsl_rng_random64_bsd, 0, 10000, 864469165);
Packit 67cb25
  rng_test (gsl_rng_random128_bsd, 0, 10000, 1457025928);
Packit 67cb25
  rng_test (gsl_rng_random256_bsd, 0, 10000, 1216357476);
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_random_libc5, 0, 10000, 428084942);
Packit 67cb25
  rng_test (gsl_rng_random8_libc5, 0, 10000, 1910041713);
Packit 67cb25
  rng_test (gsl_rng_random32_libc5, 0, 10000, 1967452027);
Packit 67cb25
  rng_test (gsl_rng_random64_libc5, 0, 10000, 2106639801);
Packit 67cb25
  rng_test (gsl_rng_random128_libc5, 0, 10000, 428084942);
Packit 67cb25
  rng_test (gsl_rng_random256_libc5, 0, 10000, 116367984);
Packit 67cb25
Packit 67cb25
  rng_test (gsl_rng_ranf, 0, 10000, 2152890433UL);
Packit 67cb25
  rng_test (gsl_rng_ranf, 2, 10000, 339327233);
Packit 67cb25
Packit 67cb25
  /* Test constant relationship between int and double functions */
Packit 67cb25
Packit 67cb25
  for (r = rngs ; *r != 0; r++)
Packit 67cb25
    rng_float_test (*r);
Packit 67cb25
Packit 67cb25
  /* Test save/restore functions */
Packit 67cb25
Packit 67cb25
  for (r = rngs ; *r != 0; r++)
Packit 67cb25
    rng_state_test (*r);
Packit 67cb25
Packit 67cb25
  for (r = rngs ; *r != 0; r++)
Packit 67cb25
    rng_parallel_state_test (*r);
Packit 67cb25
Packit 67cb25
  for (r = rngs ; *r != 0; r++)
Packit 67cb25
    rng_read_write_test (*r);
Packit 67cb25
Packit 67cb25
  /* generic statistical tests (these are just to make sure that we
Packit 67cb25
     don't get any crazy results back from the generator, i.e. they
Packit 67cb25
     aren't a test of the algorithm, just the implementation) */
Packit 67cb25
Packit 67cb25
  for (r = rngs ; *r != 0; r++)
Packit 67cb25
    generic_rng_test (*r);
Packit 67cb25
Packit 67cb25
#ifdef TEST_SEEDS
Packit 67cb25
  rng_seed_test (gsl_rng_mt19937);
Packit 67cb25
  rng_seed_test (gsl_rng_ranlxs0);
Packit 67cb25
  rng_seed_test (gsl_rng_ranlxs1);
Packit 67cb25
  rng_seed_test (gsl_rng_ranlxs2);
Packit 67cb25
Packit 67cb25
  rng_seed_test (gsl_rng_ranlxd1);
Packit 67cb25
  rng_seed_test (gsl_rng_ranlxd2);
Packit 67cb25
  rng_seed_test (gsl_rng_ranlux);
Packit 67cb25
  rng_seed_test (gsl_rng_ranlux389);
Packit 67cb25
Packit 67cb25
  rng_seed_test (gsl_rng_cmrg);
Packit 67cb25
  rng_seed_test (gsl_rng_mrg);
Packit 67cb25
  rng_seed_test (gsl_rng_taus);
Packit 67cb25
  rng_seed_test (gsl_rng_taus2);
Packit 67cb25
Packit 67cb25
  rng_seed_test (gsl_rng_gfsr4);
Packit 67cb25
#endif
Packit 67cb25
Packit 67cb25
  exit (gsl_test_summary ());
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
Packit 67cb25
void
Packit 67cb25
rng_test (const gsl_rng_type * T, unsigned long int seed, unsigned int n,
Packit 67cb25
          unsigned long int result)
Packit 67cb25
{
Packit 67cb25
  gsl_rng *r = gsl_rng_alloc (T);
Packit 67cb25
  unsigned int i;
Packit 67cb25
  unsigned long int k = 0;
Packit 67cb25
  int status;
Packit 67cb25
Packit 67cb25
  if (seed != 0)
Packit 67cb25
    {
Packit 67cb25
      gsl_rng_set (r, seed);
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  for (i = 0; i < n; i++)
Packit 67cb25
    {
Packit 67cb25
      k = gsl_rng_get (r);
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  status = (k != result);
Packit 67cb25
  gsl_test (status, "%s, %u steps (%u observed vs %u expected)",
Packit 67cb25
            gsl_rng_name (r), n, k, result);
Packit 67cb25
Packit 67cb25
  gsl_rng_free (r);
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
void
Packit 67cb25
rng_float_test (const gsl_rng_type * T)
Packit 67cb25
{
Packit 67cb25
  gsl_rng *ri = gsl_rng_alloc (T);
Packit 67cb25
  gsl_rng *rf = gsl_rng_alloc (T);
Packit 67cb25
Packit 67cb25
  double u, c ; 
Packit 67cb25
  unsigned int i;
Packit 67cb25
  unsigned long int k = 0;
Packit 67cb25
  int status = 0 ;
Packit 67cb25
Packit 67cb25
  do 
Packit 67cb25
    {
Packit 67cb25
      k = gsl_rng_get (ri);
Packit 67cb25
      u = gsl_rng_get (rf);
Packit 67cb25
    } 
Packit 67cb25
  while (k == 0) ;
Packit 67cb25
Packit 67cb25
  c = k / u ;
Packit 67cb25
  for (i = 0; i < N2; i++)
Packit 67cb25
    {
Packit 67cb25
      k = gsl_rng_get (ri);
Packit 67cb25
      u = gsl_rng_get (rf);
Packit 67cb25
      if (c*k != u)
Packit 67cb25
        {
Packit 67cb25
          status = 1 ;
Packit 67cb25
          break ;
Packit 67cb25
        }
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  gsl_test (status, "%s, ratio of int to double (%g observed vs %g expected)",
Packit 67cb25
            gsl_rng_name (ri), c, k/u);
Packit 67cb25
Packit 67cb25
  gsl_rng_free (ri);
Packit 67cb25
  gsl_rng_free (rf);
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
Packit 67cb25
void
Packit 67cb25
rng_state_test (const gsl_rng_type * T)
Packit 67cb25
{
Packit 67cb25
  unsigned long int test_a[N], test_b[N];
Packit 67cb25
Packit 67cb25
  int i;
Packit 67cb25
Packit 67cb25
  gsl_rng *r = gsl_rng_alloc (T);
Packit 67cb25
  gsl_rng *r_save = gsl_rng_alloc (T);
Packit 67cb25
Packit 67cb25
  for (i = 0; i < N; ++i)
Packit 67cb25
    {
Packit 67cb25
      gsl_rng_get (r);  /* throw away N iterations */
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  gsl_rng_memcpy (r_save, r);   /* save the intermediate state */
Packit 67cb25
Packit 67cb25
  for (i = 0; i < N; ++i)
Packit 67cb25
    {
Packit 67cb25
      test_a[i] = gsl_rng_get (r);
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  gsl_rng_memcpy (r, r_save);   /* restore the intermediate state */
Packit 67cb25
  gsl_rng_free (r_save);
Packit 67cb25
Packit 67cb25
  for (i = 0; i < N; ++i)
Packit 67cb25
    {
Packit 67cb25
      test_b[i] = gsl_rng_get (r);
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  {
Packit 67cb25
    int status = 0;
Packit 67cb25
    for (i = 0; i < N; ++i)
Packit 67cb25
      {
Packit 67cb25
        status |= (test_b[i] != test_a[i]);
Packit 67cb25
      }
Packit 67cb25
    gsl_test (status, "%s, random number state consistency",
Packit 67cb25
              gsl_rng_name (r));
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  gsl_rng_free (r);
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
Packit 67cb25
void
Packit 67cb25
rng_parallel_state_test (const gsl_rng_type * T)
Packit 67cb25
{
Packit 67cb25
  unsigned long int test_a[N], test_b[N];
Packit 67cb25
  unsigned long int test_c[N], test_d[N];
Packit 67cb25
  double test_e[N], test_f[N];
Packit 67cb25
Packit 67cb25
  int i;
Packit 67cb25
Packit 67cb25
  gsl_rng *r1 = gsl_rng_alloc (T);
Packit 67cb25
  gsl_rng *r2 = gsl_rng_alloc (T);
Packit 67cb25
Packit 67cb25
  for (i = 0; i < N; ++i)
Packit 67cb25
    {
Packit 67cb25
      gsl_rng_get (r1);         /* throw away N iterations */
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  gsl_rng_memcpy (r2, r1);              /* save the intermediate state */
Packit 67cb25
Packit 67cb25
  for (i = 0; i < N; ++i)
Packit 67cb25
    {
Packit 67cb25
      /* check that there is no hidden state intermixed between r1 and r2 */
Packit 67cb25
      test_a[i] = gsl_rng_get (r1);     
Packit 67cb25
      test_b[i] = gsl_rng_get (r2);
Packit 67cb25
      test_c[i] = gsl_rng_uniform_int (r1, 1234);       
Packit 67cb25
      test_d[i] = gsl_rng_uniform_int (r2, 1234);
Packit 67cb25
      test_e[i] = gsl_rng_uniform (r1); 
Packit 67cb25
      test_f[i] = gsl_rng_uniform (r2);
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  {
Packit 67cb25
    int status = 0;
Packit 67cb25
    for (i = 0; i < N; ++i)
Packit 67cb25
      {
Packit 67cb25
        status |= (test_b[i] != test_a[i]);
Packit 67cb25
        status |= (test_c[i] != test_d[i]);
Packit 67cb25
        status |= (test_e[i] != test_f[i]);
Packit 67cb25
      }
Packit 67cb25
    gsl_test (status, "%s, parallel random number state consistency",
Packit 67cb25
              gsl_rng_name (r1));
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  gsl_rng_free (r1);
Packit 67cb25
  gsl_rng_free (r2);
Packit 67cb25
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
void
Packit 67cb25
rng_read_write_test (const gsl_rng_type * T)
Packit 67cb25
{
Packit 67cb25
  unsigned long int test_a[N], test_b[N];
Packit 67cb25
Packit 67cb25
  int i;
Packit 67cb25
Packit 67cb25
  gsl_rng *r = gsl_rng_alloc (T);
Packit 67cb25
Packit 67cb25
  for (i = 0; i < N; ++i)
Packit 67cb25
    {
Packit 67cb25
      gsl_rng_get (r);  /* throw away N iterations */
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  { /* save the state to a binary file */
Packit 67cb25
    FILE *f = fopen("test.dat", "wb"); 
Packit 67cb25
    gsl_rng_fwrite(f, r);
Packit 67cb25
    fclose(f);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  for (i = 0; i < N; ++i)
Packit 67cb25
    {
Packit 67cb25
      test_a[i] = gsl_rng_get (r);
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  { /* read the state from a binary file */
Packit 67cb25
    FILE *f = fopen("test.dat", "rb"); 
Packit 67cb25
    gsl_rng_fread(f, r);
Packit 67cb25
    fclose(f);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  for (i = 0; i < N; ++i)
Packit 67cb25
    {
Packit 67cb25
      test_b[i] = gsl_rng_get (r);
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  {
Packit 67cb25
    int status = 0;
Packit 67cb25
    for (i = 0; i < N; ++i)
Packit 67cb25
      {
Packit 67cb25
        status |= (test_b[i] != test_a[i]);
Packit 67cb25
      }
Packit 67cb25
    gsl_test (status, "%s, random number generator read and write",
Packit 67cb25
              gsl_rng_name (r));
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  gsl_rng_free (r);
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
void
Packit 67cb25
generic_rng_test (const gsl_rng_type * T)
Packit 67cb25
{
Packit 67cb25
  gsl_rng *r = gsl_rng_alloc (T);
Packit 67cb25
  const char *name = gsl_rng_name (r);
Packit 67cb25
  unsigned long int kmax = 0, kmin = 1000;
Packit 67cb25
  double sigma = 0;
Packit 67cb25
  const unsigned long int ran_max = gsl_rng_max (r);
Packit 67cb25
  const unsigned long int ran_min = gsl_rng_min (r);
Packit 67cb25
Packit 67cb25
  int status = rng_max_test (r, &kmax, ran_max);
Packit 67cb25
Packit 67cb25
  gsl_test (status,
Packit 67cb25
            "%s, observed vs theoretical maximum (%lu vs %lu)",
Packit 67cb25
            name, kmax, ran_max);
Packit 67cb25
Packit 67cb25
  status = rng_min_test (r, &kmin, ran_min, ran_max);
Packit 67cb25
Packit 67cb25
  gsl_test (status,
Packit 67cb25
            "%s, observed vs theoretical minimum (%lu vs %lu)",
Packit 67cb25
            name, kmin, ran_min);
Packit 67cb25
Packit 67cb25
  status = rng_sum_test (r, &sigma);
Packit 67cb25
Packit 67cb25
  gsl_test (status,
Packit 67cb25
            "%s, sum test within acceptable sigma (observed %.2g sigma)",
Packit 67cb25
            name, sigma);
Packit 67cb25
Packit 67cb25
  status = rng_bin_test (r, &sigma);
Packit 67cb25
Packit 67cb25
  gsl_test (status,
Packit 67cb25
            "%s, bin test within acceptable chisq (observed %.2g sigma)",
Packit 67cb25
            name, sigma);
Packit 67cb25
Packit 67cb25
  gsl_rng_set (r, 1);   /* set seed to 1 */
Packit 67cb25
  status = rng_max_test (r, &kmax, ran_max);
Packit 67cb25
Packit 67cb25
  gsl_rng_set (r, 1);   /* set seed to 1 */
Packit 67cb25
  status |= rng_min_test (r, &kmin, ran_min, ran_max);
Packit 67cb25
Packit 67cb25
  gsl_rng_set (r, 1);   /* set seed to 1 */
Packit 67cb25
  status |= rng_sum_test (r, &sigma);
Packit 67cb25
Packit 67cb25
  gsl_test (status, "%s, max, min and sum tests for seed=1", name);
Packit 67cb25
Packit 67cb25
  gsl_rng_set (r, 12345);       /* set seed to a "typical" value */
Packit 67cb25
  status = rng_max_test (r, &kmax, ran_max);
Packit 67cb25
Packit 67cb25
  gsl_rng_set (r, 12345);       /* set seed to a "typical" value */
Packit 67cb25
  status |= rng_min_test (r, &kmin, ran_min, ran_max);
Packit 67cb25
Packit 67cb25
  gsl_rng_set (r, 12345);       /* set seed to a "typical" value */
Packit 67cb25
  status |= rng_sum_test (r, &sigma);
Packit 67cb25
Packit 67cb25
  gsl_test (status, "%s, max, min and sum tests for non-default seeds", name);
Packit 67cb25
Packit 67cb25
  gsl_rng_free (r);
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
int
Packit 67cb25
rng_max_test (gsl_rng * r, unsigned long int *kmax, unsigned long int ran_max)
Packit 67cb25
{
Packit 67cb25
  unsigned long int actual_uncovered;
Packit 67cb25
  double expect_uncovered;
Packit 67cb25
  int status;
Packit 67cb25
  unsigned long int max = 0;
Packit 67cb25
  int i;
Packit 67cb25
Packit 67cb25
  for (i = 0; i < N2; ++i)
Packit 67cb25
    {
Packit 67cb25
      unsigned long int k = gsl_rng_get (r);
Packit 67cb25
      if (k > max)
Packit 67cb25
        max = k;
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  *kmax = max;
Packit 67cb25
Packit 67cb25
  actual_uncovered = ran_max - max;
Packit 67cb25
  expect_uncovered = (double) ran_max / (double) N2;
Packit 67cb25
Packit 67cb25
  status = (max > ran_max) || (actual_uncovered > 7 * expect_uncovered) ;
Packit 67cb25
Packit 67cb25
  return status;
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
int
Packit 67cb25
rng_min_test (gsl_rng * r, unsigned long int *kmin, 
Packit 67cb25
              unsigned long int ran_min, unsigned long int ran_max)
Packit 67cb25
{
Packit 67cb25
  unsigned long int actual_uncovered;
Packit 67cb25
  double expect_uncovered;
Packit 67cb25
  int status;
Packit 67cb25
  unsigned long int min = 1000000000UL;
Packit 67cb25
  int i;
Packit 67cb25
Packit 67cb25
  for (i = 0; i < N2; ++i)
Packit 67cb25
    {
Packit 67cb25
      unsigned long int k = gsl_rng_get (r);
Packit 67cb25
      if (k < min)
Packit 67cb25
        min = k;
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  *kmin = min;
Packit 67cb25
Packit 67cb25
  actual_uncovered = min - ran_min;
Packit 67cb25
  expect_uncovered = (double) ran_max / (double) N2;
Packit 67cb25
Packit 67cb25
  status = (min < ran_min) || (actual_uncovered > 7 * expect_uncovered);
Packit 67cb25
Packit 67cb25
  return status;
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
int
Packit 67cb25
rng_sum_test (gsl_rng * r, double *sigma)
Packit 67cb25
{
Packit 67cb25
  double sum = 0;
Packit 67cb25
  int i, status;
Packit 67cb25
Packit 67cb25
  for (i = 0; i < N2; ++i)
Packit 67cb25
    {
Packit 67cb25
      double x = gsl_rng_uniform (r) - 0.5;
Packit 67cb25
      sum += x;
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  sum /= N2;
Packit 67cb25
Packit 67cb25
  /* expect the average to have a variance of 1/(12 n) */
Packit 67cb25
Packit 67cb25
  *sigma = sum * sqrt (12.0 * N2);
Packit 67cb25
Packit 67cb25
  /* more than 3 sigma is an error (increased to 3.1 to avoid false alarms) */
Packit 67cb25
  
Packit 67cb25
  status = (fabs (*sigma) > 3.1 || fabs(*sigma) < 0.003);
Packit 67cb25
Packit 67cb25
  if (status) {
Packit 67cb25
      fprintf(stderr,"sum=%g, sigma=%g\n",sum,*sigma);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  return status;
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
#define BINS 17
Packit 67cb25
#define EXTRA 10
Packit 67cb25
int
Packit 67cb25
rng_bin_test (gsl_rng * r, double *sigma)
Packit 67cb25
{
Packit 67cb25
  int count[BINS+EXTRA];
Packit 67cb25
  double chisq = 0;
Packit 67cb25
  int i, status;
Packit 67cb25
Packit 67cb25
  for (i = 0; i < BINS+EXTRA; i++)
Packit 67cb25
      count[i] = 0 ;
Packit 67cb25
Packit 67cb25
Packit 67cb25
  for (i = 0; i < N2; i++)
Packit 67cb25
    {
Packit 67cb25
      int j = gsl_rng_uniform_int (r, BINS);
Packit 67cb25
      count[j]++ ;
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  chisq = 0 ;
Packit 67cb25
  for (i = 0; i < BINS; i++)
Packit 67cb25
    {
Packit 67cb25
      double x = (double)N2/(double)BINS ;
Packit 67cb25
      double d = (count[i] - x) ;
Packit 67cb25
      chisq += (d*d) / x;
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  *sigma = sqrt(chisq/BINS) ;
Packit 67cb25
Packit 67cb25
  /* more than 3 sigma is an error */
Packit 67cb25
  
Packit 67cb25
  status = (fabs (*sigma) > 3 || fabs(*sigma) < 0.003);
Packit 67cb25
Packit 67cb25
  for (i = BINS; i < BINS+EXTRA; i++)
Packit 67cb25
    {
Packit 67cb25
      if (count[i] != 0)
Packit 67cb25
        {
Packit 67cb25
          status = 1 ;
Packit 67cb25
          gsl_test (status, 
Packit 67cb25
                    "%s, wrote outside range in bin test "
Packit 67cb25
                    "(%d observed vs %d expected)",
Packit 67cb25
                    gsl_rng_name(r), i, BINS - 1);
Packit 67cb25
        }
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  return status;
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
int
Packit 67cb25
rng_sanity_test (gsl_rng * r)
Packit 67cb25
{
Packit 67cb25
  double sum = 0, sigma;
Packit 67cb25
  int i, status = 0;
Packit 67cb25
Packit 67cb25
  for (i = 0; i < N2; ++i)
Packit 67cb25
    {
Packit 67cb25
      double x = gsl_rng_uniform (r);
Packit 67cb25
      sum += x;
Packit 67cb25
      if (x < 0.0 || x > 1.0) {
Packit 67cb25
        fprintf(stderr,"x=%g out of range\n", x);
Packit 67cb25
        return 1;
Packit 67cb25
      }
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  sum /= N2;
Packit 67cb25
Packit 67cb25
  /* expect the average to have a variance of 1/(12 n) */
Packit 67cb25
Packit 67cb25
  sigma = (sum - 0.5)* sqrt (12.0 * N2);
Packit 67cb25
Packit 67cb25
  /* more than 5 sigma is an error */
Packit 67cb25
  
Packit 67cb25
  status = (fabs (sigma) > 5 || fabs(sigma) < 0.0001);
Packit 67cb25
Packit 67cb25
  if (status) {
Packit 67cb25
      fprintf(stderr,"sum=%g, sigma=%g\n",sum,sigma);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  return status;
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
void
Packit 67cb25
rng_seed_test (const gsl_rng_type * T)
Packit 67cb25
{
Packit 67cb25
  gsl_rng *r = gsl_rng_alloc (T);
Packit 67cb25
  const char *name = gsl_rng_name (r);
Packit 67cb25
  unsigned long int i;
Packit 67cb25
  int j;
Packit 67cb25
  int status;
Packit 67cb25
Packit 67cb25
  for (i = 0xFFFFFFFFUL ; i > 0; i >>= 1) {
Packit 67cb25
    for (j = 1; j >= -1 ; j--) {
Packit 67cb25
      unsigned long int seed = i + j;
Packit 67cb25
      if (j > 0 && seed < i) continue;
Packit 67cb25
      gsl_rng_set (r, seed);
Packit 67cb25
      status = rng_sanity_test (r);
Packit 67cb25
      if (status) 
Packit 67cb25
        gsl_test (status, "%s, sanity tests for seed = %#lx", name, seed);
Packit 67cb25
    }
Packit 67cb25
  }
Packit 67cb25
}