gsl_rng__random.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. /* rng/random.c
  2. *
  3. * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. #include "gsl__config.h"
  20. #include <stdlib.h>
  21. #include "gsl_rng.h"
  22. /* This file provides support for random() generators. There are three
  23. versions in widespread use today,
  24. - The original BSD version, e.g. on SunOS 4.1 and FreeBSD.
  25. - The Linux libc5 version, which is differs from the BSD version in
  26. its seeding procedure, possibly due to the introduction of a typo
  27. in the multiplier.
  28. - The GNU glibc2 version, which has a new (and better) seeding
  29. procedure.
  30. They all produce different numbers, due to the different seeding
  31. algorithms, but the algorithm for the generator is the same in each
  32. case.
  33. */
  34. static inline long int random_get (int * i, int * j, int n, long int * x);
  35. static inline unsigned long int random8_get (void *vstate);
  36. static inline unsigned long int random32_get (void *vstate);
  37. static inline unsigned long int random64_get (void *vstate);
  38. static inline unsigned long int random128_get (void *vstate);
  39. static inline unsigned long int random256_get (void *vstate);
  40. static double random8_get_double (void *vstate);
  41. static double random32_get_double (void *vstate);
  42. static double random64_get_double (void *vstate);
  43. static double random128_get_double (void *vstate);
  44. static double random256_get_double (void *vstate);
  45. static void random8_glibc2_set (void *state, unsigned long int s);
  46. static void random32_glibc2_set (void *state, unsigned long int s);
  47. static void random64_glibc2_set (void *state, unsigned long int s);
  48. static void random128_glibc2_set (void *state, unsigned long int s);
  49. static void random256_glibc2_set (void *state, unsigned long int s);
  50. static void random8_libc5_set (void *state, unsigned long int s);
  51. static void random32_libc5_set (void *state, unsigned long int s);
  52. static void random64_libc5_set (void *state, unsigned long int s);
  53. static void random128_libc5_set (void *state, unsigned long int s);
  54. static void random256_libc5_set (void *state, unsigned long int s);
  55. static void random8_bsd_set (void *state, unsigned long int s);
  56. static void random32_bsd_set (void *state, unsigned long int s);
  57. static void random64_bsd_set (void *state, unsigned long int s);
  58. static void random128_bsd_set (void *state, unsigned long int s);
  59. static void random256_bsd_set (void *state, unsigned long int s);
  60. static void bsd_initialize (long int * x, int n, unsigned long int s);
  61. static void libc5_initialize (long int * x, int n, unsigned long int s);
  62. static void glibc2_initialize (long int * x, int n, unsigned long int s);
  63. typedef struct
  64. {
  65. long int x;
  66. }
  67. random8_state_t;
  68. typedef struct
  69. {
  70. int i, j;
  71. long int x[7];
  72. }
  73. random32_state_t;
  74. typedef struct
  75. {
  76. int i, j;
  77. long int x[15];
  78. }
  79. random64_state_t;
  80. typedef struct
  81. {
  82. int i, j;
  83. long int x[31];
  84. }
  85. random128_state_t;
  86. typedef struct
  87. {
  88. int i, j;
  89. long int x[63];
  90. }
  91. random256_state_t;
  92. static inline unsigned long int
  93. random8_get (void *vstate)
  94. {
  95. random8_state_t *state = (random8_state_t *) vstate;
  96. state->x = (1103515245 * state->x + 12345) & 0x7fffffffUL;
  97. return state->x;
  98. }
  99. static inline long int
  100. random_get (int * i, int * j, int n, long int * x)
  101. {
  102. long int k ;
  103. x[*i] += x[*j] ;
  104. k = (x[*i] >> 1) & 0x7FFFFFFF ;
  105. (*i)++ ;
  106. if (*i == n)
  107. *i = 0 ;
  108. (*j)++ ;
  109. if (*j == n)
  110. *j = 0 ;
  111. return k ;
  112. }
  113. static inline unsigned long int
  114. random32_get (void *vstate)
  115. {
  116. random32_state_t *state = (random32_state_t *) vstate;
  117. unsigned long int k = random_get (&state->i, &state->j, 7, state->x) ;
  118. return k ;
  119. }
  120. static inline unsigned long int
  121. random64_get (void *vstate)
  122. {
  123. random64_state_t *state = (random64_state_t *) vstate;
  124. long int k = random_get (&state->i, &state->j, 15, state->x) ;
  125. return k ;
  126. }
  127. static inline unsigned long int
  128. random128_get (void *vstate)
  129. {
  130. random128_state_t *state = (random128_state_t *) vstate;
  131. unsigned long int k = random_get (&state->i, &state->j, 31, state->x) ;
  132. return k ;
  133. }
  134. static inline unsigned long int
  135. random256_get (void *vstate)
  136. {
  137. random256_state_t *state = (random256_state_t *) vstate;
  138. long int k = random_get (&state->i, &state->j, 63, state->x) ;
  139. return k ;
  140. }
  141. static double
  142. random8_get_double (void *vstate)
  143. {
  144. return random8_get (vstate) / 2147483648.0 ;
  145. }
  146. static double
  147. random32_get_double (void *vstate)
  148. {
  149. return random32_get (vstate) / 2147483648.0 ;
  150. }
  151. static double
  152. random64_get_double (void *vstate)
  153. {
  154. return random64_get (vstate) / 2147483648.0 ;
  155. }
  156. static double
  157. random128_get_double (void *vstate)
  158. {
  159. return random128_get (vstate) / 2147483648.0 ;
  160. }
  161. static double
  162. random256_get_double (void *vstate)
  163. {
  164. return random256_get (vstate) / 2147483648.0 ;
  165. }
  166. static void
  167. random8_bsd_set (void *vstate, unsigned long int s)
  168. {
  169. random8_state_t *state = (random8_state_t *) vstate;
  170. if (s == 0)
  171. s = 1;
  172. state->x = s;
  173. }
  174. static void
  175. random32_bsd_set (void *vstate, unsigned long int s)
  176. {
  177. random32_state_t *state = (random32_state_t *) vstate;
  178. int i;
  179. bsd_initialize (state->x, 7, s) ;
  180. state->i = 3;
  181. state->j = 0;
  182. for (i = 0 ; i < 10 * 7 ; i++)
  183. random32_get (state) ;
  184. }
  185. static void
  186. random64_bsd_set (void *vstate, unsigned long int s)
  187. {
  188. random64_state_t *state = (random64_state_t *) vstate;
  189. int i;
  190. bsd_initialize (state->x, 15, s) ;
  191. state->i = 1;
  192. state->j = 0;
  193. for (i = 0 ; i < 10 * 15 ; i++)
  194. random64_get (state) ;
  195. }
  196. static void
  197. random128_bsd_set (void *vstate, unsigned long int s)
  198. {
  199. random128_state_t *state = (random128_state_t *) vstate;
  200. int i;
  201. bsd_initialize (state->x, 31, s) ;
  202. state->i = 3;
  203. state->j = 0;
  204. for (i = 0 ; i < 10 * 31 ; i++)
  205. random128_get (state) ;
  206. }
  207. static void
  208. random256_bsd_set (void *vstate, unsigned long int s)
  209. {
  210. random256_state_t *state = (random256_state_t *) vstate;
  211. int i;
  212. bsd_initialize (state->x, 63, s) ;
  213. state->i = 1;
  214. state->j = 0;
  215. for (i = 0 ; i < 10 * 63 ; i++)
  216. random256_get (state) ;
  217. }
  218. static void
  219. bsd_initialize (long int * x, int n, unsigned long int s)
  220. {
  221. int i;
  222. if (s == 0)
  223. s = 1 ;
  224. x[0] = s;
  225. for (i = 1 ; i < n ; i++)
  226. x[i] = 1103515245 * x[i-1] + 12345 ;
  227. }
  228. static void
  229. libc5_initialize (long int * x, int n, unsigned long int s)
  230. {
  231. int i;
  232. if (s == 0)
  233. s = 1 ;
  234. x[0] = s;
  235. for (i = 1 ; i < n ; i++)
  236. x[i] = 1103515145 * x[i-1] + 12345 ;
  237. }
  238. static void
  239. glibc2_initialize (long int * x, int n, unsigned long int s)
  240. {
  241. int i;
  242. if (s == 0)
  243. s = 1 ;
  244. x[0] = s;
  245. for (i = 1 ; i < n ; i++)
  246. {
  247. const long int h = s / 127773;
  248. const long int t = 16807 * (s - h * 127773) - h * 2836;
  249. if (t < 0)
  250. {
  251. s = t + 2147483647 ;
  252. }
  253. else
  254. {
  255. s = t ;
  256. }
  257. x[i] = s ;
  258. }
  259. }
  260. static void
  261. random8_glibc2_set (void *vstate, unsigned long int s)
  262. {
  263. random8_state_t *state = (random8_state_t *) vstate;
  264. if (s == 0)
  265. s = 1;
  266. state->x = s;
  267. }
  268. static void
  269. random32_glibc2_set (void *vstate, unsigned long int s)
  270. {
  271. random32_state_t *state = (random32_state_t *) vstate;
  272. int i;
  273. glibc2_initialize (state->x, 7, s) ;
  274. state->i = 3;
  275. state->j = 0;
  276. for (i = 0 ; i < 10 * 7 ; i++)
  277. random32_get (state) ;
  278. }
  279. static void
  280. random64_glibc2_set (void *vstate, unsigned long int s)
  281. {
  282. random64_state_t *state = (random64_state_t *) vstate;
  283. int i;
  284. glibc2_initialize (state->x, 15, s) ;
  285. state->i = 1;
  286. state->j = 0;
  287. for (i = 0 ; i < 10 * 15 ; i++)
  288. random64_get (state) ;
  289. }
  290. static void
  291. random128_glibc2_set (void *vstate, unsigned long int s)
  292. {
  293. random128_state_t *state = (random128_state_t *) vstate;
  294. int i;
  295. glibc2_initialize (state->x, 31, s) ;
  296. state->i = 3;
  297. state->j = 0;
  298. for (i = 0 ; i < 10 * 31 ; i++)
  299. random128_get (state) ;
  300. }
  301. static void
  302. random256_glibc2_set (void *vstate, unsigned long int s)
  303. {
  304. random256_state_t *state = (random256_state_t *) vstate;
  305. int i;
  306. glibc2_initialize (state->x, 63, s) ;
  307. state->i = 1;
  308. state->j = 0;
  309. for (i = 0 ; i < 10 * 63 ; i++)
  310. random256_get (state) ;
  311. }
  312. static void
  313. random8_libc5_set (void *vstate, unsigned long int s)
  314. {
  315. random8_state_t *state = (random8_state_t *) vstate;
  316. if (s == 0)
  317. s = 1;
  318. state->x = s;
  319. }
  320. static void
  321. random32_libc5_set (void *vstate, unsigned long int s)
  322. {
  323. random32_state_t *state = (random32_state_t *) vstate;
  324. int i;
  325. libc5_initialize (state->x, 7, s) ;
  326. state->i = 3;
  327. state->j = 0;
  328. for (i = 0 ; i < 10 * 7 ; i++)
  329. random32_get (state) ;
  330. }
  331. static void
  332. random64_libc5_set (void *vstate, unsigned long int s)
  333. {
  334. random64_state_t *state = (random64_state_t *) vstate;
  335. int i;
  336. libc5_initialize (state->x, 15, s) ;
  337. state->i = 1;
  338. state->j = 0;
  339. for (i = 0 ; i < 10 * 15 ; i++)
  340. random64_get (state) ;
  341. }
  342. static void
  343. random128_libc5_set (void *vstate, unsigned long int s)
  344. {
  345. random128_state_t *state = (random128_state_t *) vstate;
  346. int i;
  347. libc5_initialize (state->x, 31, s) ;
  348. state->i = 3;
  349. state->j = 0;
  350. for (i = 0 ; i < 10 * 31 ; i++)
  351. random128_get (state) ;
  352. }
  353. static void
  354. random256_libc5_set (void *vstate, unsigned long int s)
  355. {
  356. random256_state_t *state = (random256_state_t *) vstate;
  357. int i;
  358. libc5_initialize (state->x, 63, s) ;
  359. state->i = 1;
  360. state->j = 0;
  361. for (i = 0 ; i < 10 * 63 ; i++)
  362. random256_get (state) ;
  363. }
  364. static const gsl_rng_type random_glibc2_type =
  365. {"random-glibc2", /* name */
  366. 0x7fffffffUL, /* RAND_MAX */
  367. 0, /* RAND_MIN */
  368. sizeof (random128_state_t),
  369. &random128_glibc2_set,
  370. &random128_get,
  371. &random128_get_double};
  372. static const gsl_rng_type random8_glibc2_type =
  373. {"random8-glibc2", /* name */
  374. 0x7fffffffUL, /* RAND_MAX */
  375. 0, /* RAND_MIN */
  376. sizeof (random8_state_t),
  377. &random8_glibc2_set,
  378. &random8_get,
  379. &random8_get_double};
  380. static const gsl_rng_type random32_glibc2_type =
  381. {"random32-glibc2", /* name */
  382. 0x7fffffffUL, /* RAND_MAX */
  383. 0, /* RAND_MIN */
  384. sizeof (random32_state_t),
  385. &random32_glibc2_set,
  386. &random32_get,
  387. &random32_get_double};
  388. static const gsl_rng_type random64_glibc2_type =
  389. {"random64-glibc2", /* name */
  390. 0x7fffffffUL, /* RAND_MAX */
  391. 0, /* RAND_MIN */
  392. sizeof (random64_state_t),
  393. &random64_glibc2_set,
  394. &random64_get,
  395. &random64_get_double};
  396. static const gsl_rng_type random128_glibc2_type =
  397. {"random128-glibc2", /* name */
  398. 0x7fffffffUL, /* RAND_MAX */
  399. 0, /* RAND_MIN */
  400. sizeof (random128_state_t),
  401. &random128_glibc2_set,
  402. &random128_get,
  403. &random128_get_double};
  404. static const gsl_rng_type random256_glibc2_type =
  405. {"random256-glibc2", /* name */
  406. 0x7fffffffUL, /* RAND_MAX */
  407. 0, /* RAND_MIN */
  408. sizeof (random256_state_t),
  409. &random256_glibc2_set,
  410. &random256_get,
  411. &random256_get_double};
  412. static const gsl_rng_type random_libc5_type =
  413. {"random-libc5", /* name */
  414. 0x7fffffffUL, /* RAND_MAX */
  415. 0, /* RAND_MIN */
  416. sizeof (random128_state_t),
  417. &random128_libc5_set,
  418. &random128_get,
  419. &random128_get_double};
  420. static const gsl_rng_type random8_libc5_type =
  421. {"random8-libc5", /* name */
  422. 0x7fffffffUL, /* RAND_MAX */
  423. 0, /* RAND_MIN */
  424. sizeof (random8_state_t),
  425. &random8_libc5_set,
  426. &random8_get,
  427. &random8_get_double};
  428. static const gsl_rng_type random32_libc5_type =
  429. {"random32-libc5", /* name */
  430. 0x7fffffffUL, /* RAND_MAX */
  431. 0, /* RAND_MIN */
  432. sizeof (random32_state_t),
  433. &random32_libc5_set,
  434. &random32_get,
  435. &random32_get_double};
  436. static const gsl_rng_type random64_libc5_type =
  437. {"random64-libc5", /* name */
  438. 0x7fffffffUL, /* RAND_MAX */
  439. 0, /* RAND_MIN */
  440. sizeof (random64_state_t),
  441. &random64_libc5_set,
  442. &random64_get,
  443. &random64_get_double};
  444. static const gsl_rng_type random128_libc5_type =
  445. {"random128-libc5", /* name */
  446. 0x7fffffffUL, /* RAND_MAX */
  447. 0, /* RAND_MIN */
  448. sizeof (random128_state_t),
  449. &random128_libc5_set,
  450. &random128_get,
  451. &random128_get_double};
  452. static const gsl_rng_type random256_libc5_type =
  453. {"random256-libc5", /* name */
  454. 0x7fffffffUL, /* RAND_MAX */
  455. 0, /* RAND_MIN */
  456. sizeof (random256_state_t),
  457. &random256_libc5_set,
  458. &random256_get,
  459. &random256_get_double};
  460. static const gsl_rng_type random_bsd_type =
  461. {"random-bsd", /* name */
  462. 0x7fffffffUL, /* RAND_MAX */
  463. 0, /* RAND_MIN */
  464. sizeof (random128_state_t),
  465. &random128_bsd_set,
  466. &random128_get,
  467. &random128_get_double};
  468. static const gsl_rng_type random8_bsd_type =
  469. {"random8-bsd", /* name */
  470. 0x7fffffffUL, /* RAND_MAX */
  471. 0, /* RAND_MIN */
  472. sizeof (random8_state_t),
  473. &random8_bsd_set,
  474. &random8_get,
  475. &random8_get_double};
  476. static const gsl_rng_type random32_bsd_type =
  477. {"random32-bsd", /* name */
  478. 0x7fffffffUL, /* RAND_MAX */
  479. 0, /* RAND_MIN */
  480. sizeof (random32_state_t),
  481. &random32_bsd_set,
  482. &random32_get,
  483. &random32_get_double};
  484. static const gsl_rng_type random64_bsd_type =
  485. {"random64-bsd", /* name */
  486. 0x7fffffffUL, /* RAND_MAX */
  487. 0, /* RAND_MIN */
  488. sizeof (random64_state_t),
  489. &random64_bsd_set,
  490. &random64_get,
  491. &random64_get_double};
  492. static const gsl_rng_type random128_bsd_type =
  493. {"random128-bsd", /* name */
  494. 0x7fffffffUL, /* RAND_MAX */
  495. 0, /* RAND_MIN */
  496. sizeof (random128_state_t),
  497. &random128_bsd_set,
  498. &random128_get,
  499. &random128_get_double};
  500. static const gsl_rng_type random256_bsd_type =
  501. {"random256-bsd", /* name */
  502. 0x7fffffffUL, /* RAND_MAX */
  503. 0, /* RAND_MIN */
  504. sizeof (random256_state_t),
  505. &random256_bsd_set,
  506. &random256_get,
  507. &random256_get_double};
  508. const gsl_rng_type *gsl_rng_random_libc5 = &random_libc5_type;
  509. const gsl_rng_type *gsl_rng_random8_libc5 = &random8_libc5_type;
  510. const gsl_rng_type *gsl_rng_random32_libc5 = &random32_libc5_type;
  511. const gsl_rng_type *gsl_rng_random64_libc5 = &random64_libc5_type;
  512. const gsl_rng_type *gsl_rng_random128_libc5 = &random128_libc5_type;
  513. const gsl_rng_type *gsl_rng_random256_libc5 = &random256_libc5_type;
  514. const gsl_rng_type *gsl_rng_random_glibc2 = &random_glibc2_type;
  515. const gsl_rng_type *gsl_rng_random8_glibc2 = &random8_glibc2_type;
  516. const gsl_rng_type *gsl_rng_random32_glibc2 = &random32_glibc2_type;
  517. const gsl_rng_type *gsl_rng_random64_glibc2 = &random64_glibc2_type;
  518. const gsl_rng_type *gsl_rng_random128_glibc2 = &random128_glibc2_type;
  519. const gsl_rng_type *gsl_rng_random256_glibc2 = &random256_glibc2_type;
  520. const gsl_rng_type *gsl_rng_random_bsd = &random_bsd_type;
  521. const gsl_rng_type *gsl_rng_random8_bsd = &random8_bsd_type;
  522. const gsl_rng_type *gsl_rng_random32_bsd = &random32_bsd_type;
  523. const gsl_rng_type *gsl_rng_random64_bsd = &random64_bsd_type;
  524. const gsl_rng_type *gsl_rng_random128_bsd = &random128_bsd_type;
  525. const gsl_rng_type *gsl_rng_random256_bsd = &random256_bsd_type;