gsl_qrng__niederreiter-2.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /* Author: G. Jungman
  2. */
  3. /* Implement Niederreiter base 2 generator.
  4. * See:
  5. * Bratley, Fox, Niederreiter, ACM Trans. Model. Comp. Sim. 2, 195 (1992)
  6. */
  7. #include "gsl__config.h"
  8. #include "gsl_qrng.h"
  9. #define NIED2_CHARACTERISTIC 2
  10. #define NIED2_BASE 2
  11. #define NIED2_MAX_DIMENSION 12
  12. #define NIED2_MAX_PRIM_DEGREE 5
  13. #define NIED2_MAX_DEGREE 50
  14. #define NIED2_BIT_COUNT 30
  15. #define NIED2_NBITS (NIED2_BIT_COUNT+1)
  16. #define MAXV (NIED2_NBITS + NIED2_MAX_DEGREE)
  17. /* Z_2 field operations */
  18. #define NIED2_ADD(x,y) (((x)+(y))%2)
  19. #define NIED2_MUL(x,y) (((x)*(y))%2)
  20. #define NIED2_SUB(x,y) NIED2_ADD((x),(y))
  21. static size_t nied2_state_size(unsigned int dimension);
  22. static int nied2_init(void * state, unsigned int dimension);
  23. static int nied2_get(void * state, unsigned int dimension, double * v);
  24. static const gsl_qrng_type nied2_type =
  25. {
  26. "niederreiter-base-2",
  27. NIED2_MAX_DIMENSION,
  28. nied2_state_size,
  29. nied2_init,
  30. nied2_get
  31. };
  32. const gsl_qrng_type * gsl_qrng_niederreiter_2 = &nied2_type;
  33. /* primitive polynomials in binary encoding */
  34. static const int primitive_poly[NIED2_MAX_DIMENSION+1][NIED2_MAX_PRIM_DEGREE+1] =
  35. {
  36. { 1, 0, 0, 0, 0, 0 }, /* 1 */
  37. { 0, 1, 0, 0, 0, 0 }, /* x */
  38. { 1, 1, 0, 0, 0, 0 }, /* 1 + x */
  39. { 1, 1, 1, 0, 0, 0 }, /* 1 + x + x^2 */
  40. { 1, 1, 0, 1, 0, 0 }, /* 1 + x + x^3 */
  41. { 1, 0, 1, 1, 0, 0 }, /* 1 + x^2 + x^3 */
  42. { 1, 1, 0, 0, 1, 0 }, /* 1 + x + x^4 */
  43. { 1, 0, 0, 1, 1, 0 }, /* 1 + x^3 + x^4 */
  44. { 1, 1, 1, 1, 1, 0 }, /* 1 + x + x^2 + x^3 + x^4 */
  45. { 1, 0, 1, 0, 0, 1 }, /* 1 + x^2 + x^5 */
  46. { 1, 0, 0, 1, 0, 1 }, /* 1 + x^3 + x^5 */
  47. { 1, 1, 1, 1, 0, 1 }, /* 1 + x + x^2 + x^3 + x^5 */
  48. { 1, 1, 1, 0, 1, 1 } /* 1 + x + x^2 + x^4 + x^5 */
  49. };
  50. /* degrees of primitive polynomials */
  51. static const int poly_degree[NIED2_MAX_DIMENSION+1] =
  52. {
  53. 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5
  54. };
  55. typedef struct
  56. {
  57. unsigned int sequence_count;
  58. int cj[NIED2_NBITS][NIED2_MAX_DIMENSION];
  59. int nextq[NIED2_MAX_DIMENSION];
  60. } nied2_state_t;
  61. static size_t nied2_state_size(unsigned int dimension)
  62. {
  63. return sizeof(nied2_state_t);
  64. }
  65. /* Multiply polynomials over Z_2.
  66. * Notice use of a temporary vector,
  67. * side-stepping aliasing issues when
  68. * one of inputs is the same as the output
  69. * [especially important in the original fortran version, I guess].
  70. */
  71. static void poly_multiply(
  72. const int pa[], int pa_degree,
  73. const int pb[], int pb_degree,
  74. int pc[], int * pc_degree
  75. )
  76. {
  77. int j, k;
  78. int pt[NIED2_MAX_DEGREE+1];
  79. int pt_degree = pa_degree + pb_degree;
  80. for(k=0; k<=pt_degree; k++) {
  81. int term = 0;
  82. for(j=0; j<=k; j++) {
  83. const int conv_term = NIED2_MUL(pa[k-j], pb[j]);
  84. term = NIED2_ADD(term, conv_term);
  85. }
  86. pt[k] = term;
  87. }
  88. for(k=0; k<=pt_degree; k++) {
  89. pc[k] = pt[k];
  90. }
  91. for(k=pt_degree+1; k<=NIED2_MAX_DEGREE; k++) {
  92. pc[k] = 0;
  93. }
  94. *pc_degree = pt_degree;
  95. }
  96. /* Calculate the values of the constants V(J,R) as
  97. * described in BFN section 3.3.
  98. *
  99. * px = appropriate irreducible polynomial for current dimension
  100. * pb = polynomial defined in section 2.3 of BFN.
  101. * pb is modified
  102. */
  103. static void calculate_v(
  104. const int px[], int px_degree,
  105. int pb[], int * pb_degree,
  106. int v[], int maxv
  107. )
  108. {
  109. const int nonzero_element = 1; /* nonzero element of Z_2 */
  110. const int arbitrary_element = 1; /* arbitray element of Z_2 */
  111. /* The polynomial ph is px**(J-1), which is the value of B on arrival.
  112. * In section 3.3, the values of Hi are defined with a minus sign:
  113. * don't forget this if you use them later !
  114. */
  115. int ph[NIED2_MAX_DEGREE+1];
  116. /* int ph_degree = *pb_degree; */
  117. int bigm = *pb_degree; /* m from section 3.3 */
  118. int m; /* m from section 2.3 */
  119. int r, k, kj;
  120. for(k=0; k<=NIED2_MAX_DEGREE; k++) {
  121. ph[k] = pb[k];
  122. }
  123. /* Now multiply B by PX so B becomes PX**J.
  124. * In section 2.3, the values of Bi are defined with a minus sign :
  125. * don't forget this if you use them later !
  126. */
  127. poly_multiply(px, px_degree, pb, *pb_degree, pb, pb_degree);
  128. m = *pb_degree;
  129. /* Now choose a value of Kj as defined in section 3.3.
  130. * We must have 0 <= Kj < E*J = M.
  131. * The limit condition on Kj does not seem very relevant
  132. * in this program.
  133. */
  134. /* Quoting from BFN: "Our program currently sets each K_q
  135. * equal to eq. This has the effect of setting all unrestricted
  136. * values of v to 1."
  137. * Actually, it sets them to the arbitrary chosen value.
  138. * Whatever.
  139. */
  140. kj = bigm;
  141. /* Now choose values of V in accordance with
  142. * the conditions in section 3.3.
  143. */
  144. for(r=0; r<kj; r++) {
  145. v[r] = 0;
  146. }
  147. v[kj] = 1;
  148. if(kj >= bigm) {
  149. for(r=kj+1; r<m; r++) {
  150. v[r] = arbitrary_element;
  151. }
  152. }
  153. else {
  154. /* This block is never reached. */
  155. int term = NIED2_SUB(0, ph[kj]);
  156. for(r=kj+1; r<bigm; r++) {
  157. v[r] = arbitrary_element;
  158. /* Check the condition of section 3.3,
  159. * remembering that the H's have the opposite sign. [????????]
  160. */
  161. term = NIED2_SUB(term, NIED2_MUL(ph[r], v[r]));
  162. }
  163. /* Now v[bigm] != term. */
  164. v[bigm] = NIED2_ADD(nonzero_element, term);
  165. for(r=bigm+1; r<m; r++) {
  166. v[r] = arbitrary_element;
  167. }
  168. }
  169. /* Calculate the remaining V's using the recursion of section 2.3,
  170. * remembering that the B's have the opposite sign.
  171. */
  172. for(r=0; r<=maxv-m; r++) {
  173. int term = 0;
  174. for(k=0; k<m; k++) {
  175. term = NIED2_SUB(term, NIED2_MUL(pb[k], v[r+k]));
  176. }
  177. v[r+m] = term;
  178. }
  179. }
  180. static void calculate_cj(nied2_state_t * ns, unsigned int dimension)
  181. {
  182. int ci[NIED2_NBITS][NIED2_NBITS];
  183. int v[MAXV+1];
  184. int r;
  185. unsigned int i_dim;
  186. for(i_dim=0; i_dim<dimension; i_dim++) {
  187. const int poly_index = i_dim + 1;
  188. int j, k;
  189. /* Niederreiter (page 56, after equation (7), defines two
  190. * variables Q and U. We do not need Q explicitly, but we
  191. * do need U.
  192. */
  193. int u = 0;
  194. /* For each dimension, we need to calculate powers of an
  195. * appropriate irreducible polynomial, see Niederreiter
  196. * page 65, just below equation (19).
  197. * Copy the appropriate irreducible polynomial into PX,
  198. * and its degree into E. Set polynomial B = PX ** 0 = 1.
  199. * M is the degree of B. Subsequently B will hold higher
  200. * powers of PX.
  201. */
  202. int pb[NIED2_MAX_DEGREE+1];
  203. int px[NIED2_MAX_DEGREE+1];
  204. int px_degree = poly_degree[poly_index];
  205. int pb_degree = 0;
  206. for(k=0; k<=px_degree; k++) {
  207. px[k] = primitive_poly[poly_index][k];
  208. pb[k] = 0;
  209. }
  210. for (;k<NIED2_MAX_DEGREE+1;k++) {
  211. px[k] = 0;
  212. pb[k] = 0;
  213. }
  214. pb[0] = 1;
  215. for(j=0; j<NIED2_NBITS; j++) {
  216. /* If U = 0, we need to set B to the next power of PX
  217. * and recalculate V.
  218. */
  219. if(u == 0) calculate_v(px, px_degree, pb, &pb_degree, v, MAXV);
  220. /* Now C is obtained from V. Niederreiter
  221. * obtains A from V (page 65, near the bottom), and then gets
  222. * C from A (page 56, equation (7)). However this can be done
  223. * in one step. Here CI(J,R) corresponds to
  224. * Niederreiter's C(I,J,R).
  225. */
  226. for(r=0; r<NIED2_NBITS; r++) {
  227. ci[r][j] = v[r+u];
  228. }
  229. /* Advance Niederreiter's state variables. */
  230. ++u;
  231. if(u == px_degree) u = 0;
  232. }
  233. /* The array CI now holds the values of C(I,J,R) for this value
  234. * of I. We pack them into array CJ so that CJ(I,R) holds all
  235. * the values of C(I,J,R) for J from 1 to NBITS.
  236. */
  237. for(r=0; r<NIED2_NBITS; r++) {
  238. int term = 0;
  239. for(j=0; j<NIED2_NBITS; j++) {
  240. term = 2*term + ci[r][j];
  241. }
  242. ns->cj[r][i_dim] = term;
  243. }
  244. }
  245. }
  246. static int nied2_init(void * state, unsigned int dimension)
  247. {
  248. nied2_state_t * n_state = (nied2_state_t *) state;
  249. unsigned int i_dim;
  250. if(dimension < 1 || dimension > NIED2_MAX_DIMENSION) return GSL_EINVAL;
  251. calculate_cj(n_state, dimension);
  252. for(i_dim=0; i_dim<dimension; i_dim++) n_state->nextq[i_dim] = 0;
  253. n_state->sequence_count = 0;
  254. return GSL_SUCCESS;
  255. }
  256. static int nied2_get(void * state, unsigned int dimension, double * v)
  257. {
  258. static const double recip = 1.0/(double)(1U << NIED2_NBITS); /* 2^(-nbits) */
  259. nied2_state_t * n_state = (nied2_state_t *) state;
  260. int r;
  261. int c;
  262. unsigned int i_dim;
  263. /* Load the result from the saved state. */
  264. for(i_dim=0; i_dim<dimension; i_dim++) {
  265. v[i_dim] = n_state->nextq[i_dim] * recip;
  266. }
  267. /* Find the position of the least-significant zero in sequence_count.
  268. * This is the bit that changes in the Gray-code representation as
  269. * the count is advanced.
  270. */
  271. r = 0;
  272. c = n_state->sequence_count;
  273. while(1) {
  274. if((c % 2) == 1) {
  275. ++r;
  276. c /= 2;
  277. }
  278. else break;
  279. }
  280. if(r >= NIED2_NBITS) return GSL_EFAILED; /* FIXME: better error code here */
  281. /* Calculate the next state. */
  282. for(i_dim=0; i_dim<dimension; i_dim++) {
  283. n_state->nextq[i_dim] ^= n_state->cj[r][i_dim];
  284. }
  285. n_state->sequence_count++;
  286. return GSL_SUCCESS;
  287. }