PageRenderTime 56ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/dieharder-3.31.1/dieharder/rdieharder.c

#
C | 238 lines | 153 code | 33 blank | 52 comment | 29 complexity | 8ca48d09c5f6e14b639eb5ed16d649d8 MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. *========================================================================
  3. * See copyright in copyright.h and the accompanying file COPYING
  4. *========================================================================
  5. */
  6. /*
  7. * RDieHarder interface to DieHarder
  8. * Copyright (C) 2006 - 2008 Dirk Eddelbuettel
  9. * GPL'ed
  10. *
  11. * Based on dieharder.c from DieHarder, and interfacing DieHarder
  12. * DieHarder is Copyright 2002 - 2008 (C) Robert G. Brown and GPL'ed
  13. *
  14. */
  15. #ifdef RDIEHARDER
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <stdlib.h>
  19. #include <R.h>
  20. #include <Rdefines.h>
  21. #include <Rinternals.h>
  22. #include "dieharder.h" /* from the front-end sources */
  23. SEXP dieharder(SEXP genS, SEXP testS, SEXP seedS, SEXP psamplesS, SEXP verbS, SEXP infileS, SEXP ntupleS) {
  24. int verb, testarg;
  25. unsigned int i;
  26. SEXP result = NULL, vec, pv, name, desc, nkps;
  27. char *inputfile;
  28. /* Setup argv to allow call of parsecl() to let dieharder set globals */
  29. char *argv[] = { "dieharder" };
  30. optind = 0;
  31. parsecl(1, argv);
  32. /* Parse 'our' parameters from R */
  33. generator = INTEGER_VALUE(genS);
  34. testarg = INTEGER_VALUE(testS);
  35. diehard = rgb = sts = user = 0;
  36. if (testarg < 100) {
  37. diehard = testarg;
  38. } else if (testarg < 200) {
  39. rgb = testarg - 100;
  40. } else if (testarg < 300) {
  41. sts = testarg - 200;
  42. } else {
  43. user = testarg - 300;
  44. }
  45. Seed = (unsigned long int) INTEGER_VALUE(seedS); /* (user-select) Seed, not (save switch) seed */
  46. psamples = INTEGER_VALUE(psamplesS);
  47. verb = INTEGER_VALUE(verbS);
  48. inputfile = (char*) CHARACTER_VALUE(infileS);
  49. ntuple = INTEGER_VALUE(ntupleS);
  50. rdh_testptr = NULL;
  51. rdh_dtestptr = NULL; /* to be safe, explicitly flag as NULL; cf test in output.c */
  52. if (strcmp(inputfile, "") != 0) {
  53. strncpy(filename, inputfile, 128);
  54. fromfile = 1; /* flag this as file input */
  55. }
  56. if (Seed == 0) {
  57. seed = random_seed();
  58. } else {
  59. seed = (unsigned long int) Seed;
  60. }
  61. if (verb) {
  62. Rprintf("Dieharder called with gen=%d test=%d seed=%lu\n", generator, diehard, seed);
  63. quiet = 0;
  64. hist_flag = 1;
  65. } else {
  66. quiet = 1; /* override dieharder command-line default */
  67. hist_flag = 0;
  68. }
  69. /* Now do the work that dieharder.c does */
  70. startup();
  71. work();
  72. gsl_rng_free(rng);
  73. reset_bit_buffers();
  74. /* And then bring our results back to R */
  75. /* create vector of size four: [0] is vector (!!) ks_pv, [1] is pvalues vec, [2] name, [3] nkps */
  76. PROTECT(result = allocVector(VECSXP, 4));
  77. /* alloc vector and scalars, and set it */
  78. PROTECT(pv = allocVector(REALSXP, rdh_dtestptr->nkps));
  79. PROTECT(name = allocVector(STRSXP, 1));
  80. PROTECT(nkps = allocVector(INTSXP, 1));
  81. if (rdh_testptr != NULL && rdh_dtestptr != NULL) {
  82. for (i=0; i<rdh_dtestptr->nkps; i++) { /* there can be nkps p-values per test */
  83. REAL(pv)[i] = rdh_testptr[i]->ks_pvalue;
  84. }
  85. PROTECT(vec = allocVector(REALSXP, rdh_testptr[0]->psamples)); /* alloc vector and set it */
  86. for (i = 0; i < rdh_testptr[0]->psamples; i++) {
  87. REAL(vec)[i] = rdh_testptr[0]->pvalues[i];
  88. }
  89. SET_STRING_ELT(name, 0, mkChar(rdh_dtestptr->name));
  90. INTEGER(nkps)[0] = rdh_dtestptr->nkps; /* nb of Kuiper KS p-values in pv vector */
  91. } else {
  92. PROTECT(vec = allocVector(REALSXP, 1));
  93. REAL(pv)[0] = R_NaN;
  94. REAL(vec)[0] = R_NaN;
  95. SET_STRING_ELT(name, 0, mkChar(""));
  96. INTEGER(nkps)[0] = R_NaN;
  97. }
  98. /* insert vectors and scalars into result vector */
  99. SET_VECTOR_ELT(result, 0, pv);
  100. SET_VECTOR_ELT(result, 1, vec);
  101. SET_VECTOR_ELT(result, 2, name);
  102. SET_VECTOR_ELT(result, 3, nkps);
  103. UNPROTECT(5);
  104. return result;
  105. }
  106. SEXP dieharderGenerators(void) {
  107. SEXP result, gens, genid;
  108. unsigned int i,j;
  109. /* from startup.c */
  110. /*
  111. * We new have to work a bit harder to determine how many
  112. * generators we have of the different dh_types because there are
  113. * different ranges for different sources of generator.
  114. *
  115. * We start with the basic GSL generators, which start at offset 0.
  116. */
  117. dh_types = dieharder_rng_dh_types_setup ();
  118. i = 0;
  119. while(dh_types[i] != NULL){
  120. i++;
  121. j++;
  122. }
  123. num_gsl_rngs = i;
  124. /*
  125. * Next come the dieharder generators, which start at offset 200.
  126. */
  127. i = 200;
  128. j = 0;
  129. while(dh_types[i] != NULL){
  130. i++;
  131. j++;
  132. }
  133. num_dieharder_rngs = j;
  134. /*
  135. * Next come the R generators, which start at offset 400.
  136. */
  137. i = 400;
  138. j = 0;
  139. while(dh_types[i] != NULL){
  140. i++;
  141. j++;
  142. }
  143. num_R_rngs = j;
  144. /*
  145. * Next come the hardware generators, which start at offset 500.
  146. */
  147. i = 500;
  148. j = 0;
  149. while(dh_types[i] != NULL){
  150. i++;
  151. j++;
  152. }
  153. num_hardware_rngs = j;
  154. /*
  155. * Finally, any generators added by the user at the interface level.
  156. * That is, if you are hacking dieharder to add your own rng, add it
  157. * below and it should "just appear" in the dieharder list of available
  158. * generators and be immediately useful.
  159. */
  160. i = 600;
  161. j = 0;
  162. dh_types[i] = gsl_rng_empty_random;
  163. i++;
  164. j++;
  165. num_ui_rngs = j;
  166. /* /\* */
  167. /* * Now add my own dh_types and count THEM. */
  168. /* *\/ */
  169. /* add_ui_rngs(); */
  170. /* while(dh_types[i] != NULL){ */
  171. /* i++; */
  172. /* } */
  173. num_rngs = num_gsl_rngs + num_dieharder_rngs + num_R_rngs +
  174. num_hardware_rngs + num_ui_rngs;
  175. /* vector of size onetwo: [0] is scalar ks_pv, [1] is vector of pvalues */
  176. PROTECT(result = allocVector(VECSXP, 2));
  177. PROTECT(gens = allocVector(STRSXP, num_rngs));
  178. PROTECT(genid = allocVector(INTSXP, num_rngs));
  179. j = 0;
  180. for (i = 0; i < num_gsl_rngs; i++) {
  181. SET_STRING_ELT(gens, j, mkChar(dh_types[i]->name));
  182. INTEGER(genid)[j++] = i;
  183. }
  184. for (i = 200; i < 200 + num_dieharder_rngs; i++) {
  185. SET_STRING_ELT(gens, j, mkChar(dh_types[i]->name));
  186. INTEGER(genid)[j++] = i;
  187. }
  188. for (i = 400; i < 400 + num_R_rngs; i++) {
  189. SET_STRING_ELT(gens, j, mkChar(dh_types[i]->name));
  190. INTEGER(genid)[j++] = i;
  191. }
  192. for (i = 500; i < 500 + num_hardware_rngs; i++) {
  193. SET_STRING_ELT(gens, j, mkChar(dh_types[i]->name));
  194. INTEGER(genid)[j++] = i;
  195. }
  196. for (i = 600; i < 600 + num_ui_rngs; i++) {
  197. SET_STRING_ELT(gens, j, mkChar(dh_types[i]->name));
  198. INTEGER(genid)[j++] = i;
  199. }
  200. SET_VECTOR_ELT(result, 0, gens);
  201. SET_VECTOR_ELT(result, 1, genid);
  202. UNPROTECT(3);
  203. return result;
  204. }
  205. #endif /* RDIEHARDER */