1 /*
2 * This is a hack of the GSL's rng/types.c:
3 *
4 * Copyright (C) 2001 Brian Gough
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or (at
9 * your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 *******************************************************************
21 * This is being directly adapted from and modified for use in dieharder
22 * so it can maintain its own independent RNG space of types not limited
23 * by its internal limit of 100. To avoid collisions, we'll start our number
24 * space above 100, and extend it to 1000.
25 *
26 * While we're at it, let's define the ranges:
27 *
28 * 0-199 gsl generators (fixed order from now on with room for growth)
29 * 200-399 libdieharder generators (fixed order from now on)
30 * 400-499 R-based generators (fixed order from now on)
31 * 500-599 hardware generators (e.g. /dev/random and friends)
32 * 600-699 user-defined generators (starting with dieharder example)
33 * 700-999 reserved for future integration with R-like environments
34 *
35 * Naturally, we can simply bump MAXRNGS and add more, but 1000 seems
36 * likely to last for "a while" and maybe "forever".
37 */
38
39 #include <dieharder/libdieharder.h>
40 FILE *test_fp;
41
dieharder_rng_types()42 void dieharder_rng_types()
43 {
44
45 int i;
46
47 /*
48 * Null the whole thing for starters
49 */
50 for(i=0;i<MAXRNGS;i++) dh_rng_types[i] = 0;
51
52 /*
53 * Initialize gsl_types to fill it with the current gsl rngs.
54 */
55 gsl_types = gsl_rng_types_setup();
56
57 /*
58 * Copy its contents over into dieharder_rng_generator_types.
59 */
60 i = 0;
61 while(gsl_types[i] != NULL){
62 dh_rng_types[i] = gsl_types[i];
63 i++;
64 }
65 dh_num_gsl_rngs = i;
66 MYDEBUG(D_TYPES){
67 printf("# startup: Found %u GSL rngs.\n",dh_num_gsl_rngs);
68 }
69
70 /*
71 * Now add the new ones in. These positions are to be locked in by
72 * order within the ranges, so we need to be careful to get them
73 * "right" the first time.
74 *
75 * These are the dieharder generators. I expect many users to use
76 * stdin-based raw input since it is by far the easiest one to come up
77 * with (and actually will work with e.g. /dev/random). The file-based
78 * inputs will also be fairly common. The rest are there for convenience,
79 * and to expose users to some new/interesting rngs.
80 */
81 i = 200;
82 dh_num_dieharder_rngs = 0;
83 ADD(gsl_rng_stdin_input_raw);
84 dh_num_dieharder_rngs++;
85 ADD(gsl_rng_file_input_raw);
86 dh_num_dieharder_rngs++;
87 ADD(gsl_rng_file_input);
88 dh_num_dieharder_rngs++;
89 ADD(gsl_rng_ca);
90 dh_num_dieharder_rngs++;
91 ADD(gsl_rng_uvag);
92 dh_num_dieharder_rngs++;
93 ADD(gsl_rng_aes);
94 dh_num_dieharder_rngs++;
95 ADD(gsl_rng_threefish);
96 dh_num_dieharder_rngs++;
97 ADD(gsl_rng_XOR);
98 dh_num_dieharder_rngs++;
99 ADD(gsl_rng_kiss);
100 dh_num_dieharder_rngs++;
101 ADD(gsl_rng_superkiss);
102 dh_num_dieharder_rngs++;
103 MYDEBUG(D_TYPES){
104 printf("# startup: Found %u dieharder rngs.\n",dh_num_dieharder_rngs);
105 }
106
107
108 /*
109 * These are the R-based generators. Honestly it would be lovely
110 * to merge them with the GSL permanently.
111 */
112 i = 400;
113 dh_num_R_rngs = 0;
114 ADD(gsl_rng_r_wichmann_hill);
115 dh_num_R_rngs++;
116 ADD(gsl_rng_r_marsaglia_mc);
117 dh_num_R_rngs++;
118 ADD(gsl_rng_r_super_duper);
119 dh_num_R_rngs++;
120 ADD(gsl_rng_r_mersenne_twister);
121 dh_num_R_rngs++;
122 ADD(gsl_rng_r_knuth_taocp);
123 dh_num_R_rngs++;
124 ADD(gsl_rng_r_knuth_taocp2);
125 dh_num_R_rngs++;
126 MYDEBUG(D_TYPES){
127 printf("# startup: Found %u R rngs.\n",dh_num_R_rngs);
128 }
129
130 /*
131 * These are hardware/system generators. Again, it would be lovely to
132 * merge them with the GSL permanently. It would also be good to wrap
133 * these in conditionals so that they are added iff the hardware
134 * interface exists. Perhaps we should try doing this -- it requires a
135 * call to stat, I believe. But not now.
136 */
137 i = 500;
138 dh_num_hardware_rngs = 0;
139 if ((test_fp = fopen("/dev/random","r"))) {
140 ADD(gsl_rng_dev_random);
141 fclose(test_fp);
142 dh_num_hardware_rngs++;
143 }
144 if ((test_fp = fopen("/dev/urandom","r"))) {
145 ADD(gsl_rng_dev_urandom);
146 fclose(test_fp);
147 dh_num_hardware_rngs++;
148 }
149 if ((test_fp = fopen("/dev/arandom","r"))) {
150 ADD(gsl_rng_dev_arandom);
151 fclose(test_fp);
152 dh_num_hardware_rngs++;
153 }
154 MYDEBUG(D_TYPES){
155 printf("# startup: Found %u hardware rngs.\n",dh_num_hardware_rngs);
156 }
157
158 /*
159 * Tally up all the generators we found.
160 */
161 dh_num_rngs = dh_num_gsl_rngs + dh_num_dieharder_rngs + dh_num_R_rngs +
162 dh_num_hardware_rngs;
163
164 }
165
166