home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume28 / mrandom-3.0 / part02 < prev    next >
Encoding:
Text File  |  1994-05-06  |  87.7 KB  |  2,533 lines

  1. Newsgroups: comp.sources.unix
  2. From: cthombor@theory.lcs.mit.edu (Clark D. Thomborson)
  3. Subject: v28i028: mrandom-3.0 - random number generator with persistent state, Part02/06
  4. References: <1.768285901.18944@gw.home.vix.com>
  5. Sender: unix-sources-moderator@gw.home.vix.com
  6. Approved: vixie@gw.home.vix.com
  7.  
  8. Submitted-By: cthombor@theory.lcs.mit.edu (Clark D. Thomborson)
  9. Posting-Number: Volume 28, Issue 28
  10. Archive-Name: mrandom-3.0/part02
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 2 (of 6)."
  19. # Contents:  man/mrandom.3 man/mrandom.3.txt src/mrandom.h src/mrtest.c
  20. # Wrapped by vixie@gw.home.vix.com on Fri May  6 21:42:55 1994
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'man/mrandom.3' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'man/mrandom.3'\"
  24. else
  25. echo shar: Extracting \"'man/mrandom.3'\" \(21315 characters\)
  26. sed "s/^X//" >'man/mrandom.3' <<'END_OF_FILE'
  27. X.\" mrandom.3 3.1 5/28/93
  28. X.TH MRANDOM 3 "5/28/93"
  29. X.SH NAME
  30. Xinit_rng, kill_rng, \
  31. Xdxrandomrv, dxrandomr, dxrandomv, dxrandom, \
  32. Xfxrandomrv, fxrandomr, fxrandomv, fxrandom, \
  33. Xlxrandomrv, lxrandomr, lxrandomv, lxrandom, \
  34. Xbxrandomrv, bxrandomr, bxrandomv, bxrandom, \
  35. Xbxrandomrv_f, bxrandomr_f, bxrandomv_f, bxrandom_f, \
  36. Xdrandomrv, drandomr, drandomv, drandom, \
  37. Xfrandomrv, frandomr, frandomv, frandom, \
  38. Xlrandomrv, lrandomr, lrandomv, lrandom, \
  39. Xbrandomrv, brandomr, brandomv, brandom, \
  40. Xbrandomrv_f, brandomr_f, brandomv_f, brandom_f, \
  41. Xmrandomrv, mrandomr, mrandomv, mrandom, \
  42. Xflush_rng, save_rng, restart_rng, seed_rng, check_rng, \
  43. Xdescribe_rng, mralg_rng, split_rng, range_rng \
  44. X\- a uniform interface to several random number generators
  45. X.SH SYNOPSIS
  46. X.nf
  47. X.B RNGdata *init_rng(alg, mrandom_alg, seed, count1, count2, bufsize)
  48. X.B long alg, mrandom_alg, *seed, count1, count2, bufsize;
  49. X.LP
  50. X.B int kill_rng(rng)
  51. X.B RNGdata *rng;
  52. X.LP
  53. X.B double dxrandomrv(rng, n, v)
  54. X.B RNGdata *rng;
  55. X.B long n;
  56. X.B double v[];
  57. X.LP
  58. X.B float fxrandomrv(rng, n, v)
  59. X.B RNGdata *rng;
  60. X.B long n;
  61. X.B float v[];
  62. X.LP
  63. X.B long lxrandomrv(rng, n, v)
  64. X.B RNGdata *rng;
  65. X.B long n;
  66. X.B long v[];
  67. X.LP
  68. X.B long lxrandomv(n, v)
  69. X.B long n;
  70. X.B long v[];
  71. X.LP
  72. X.B int bxrandomrv(rng, n, v)
  73. X.B RNGdata *rng;
  74. X.B long n;
  75. X.B int v[];
  76. X.LP
  77. X.B int bxrandomrv_f(rng, n, v)
  78. X.B RNGdata *rng;
  79. X.B long n;
  80. X.B int v[];
  81. X.LP
  82. X.B double drandomrv(rng, n, v)
  83. X.B RNGdata *rng;
  84. X.B long n;
  85. X.B double v[];
  86. X.LP
  87. X.B float frandomrv(rng, n, v)
  88. X.B RNGdata *rng;
  89. X.B long n;
  90. X.B float v[];
  91. X.LP
  92. X.B long lrandomrv(rng, n, v)
  93. X.B RNGdata *rng;
  94. X.B long n;
  95. X.B long v[];
  96. X.LP
  97. X.B int brandomrv(rng, n, v)
  98. X.B RNGdata *rng;
  99. X.B long n;
  100. X.B int v[];
  101. X.LP
  102. X.B int brandomrv_f(rng, n, v)
  103. X.B RNGdata *rng;
  104. X.B long n;
  105. X.B int v[];
  106. X.LP
  107. X.B long mrandomrv(rng, m, n, v)
  108. X.B RNGdata *rng;
  109. X.B long m;
  110. X.B long n;
  111. X.B long v[];
  112. X.LP
  113. X.B int save_rng(rng, filename)
  114. X.B RNGdata *rng;
  115. X.B char *filename;
  116. X.LP 
  117. X.B RNGdata *restart_rng(rng, filename)
  118. X.B char *filename;
  119. X.LP
  120. X.B void seed_rng(rng, seed)
  121. X.B RNGdata *rng;
  122. X.B long *seed;
  123. X.LP
  124. X.B int check_rng(rng);
  125. X.B RNGdata *rng;
  126. X.LP
  127. X.B char *describe_rng(rng, rngid)
  128. X.B RNGdata *rng;
  129. X.B char rngid[RNGIDSTRLEN];
  130. X.LP
  131. X.B int mralg_rng(rng,new_value)
  132. X.B RNGdata *rng;
  133. X.B long new_value;
  134. X.LP
  135. X.B int split_rng(rng, new_value)
  136. X.B RNGdata *rng;
  137. X.B long new_value;
  138. X.LP
  139. X.B double range_rng(rng)
  140. X.B RNGdata *rng;
  141. X.fi
  142. X.IX  "init_rng()"  ""  "\fLinit_rng\fP \(em initialize random generator"
  143. X.IX  "kill_rng()"  ""  "\fLkill_rng\fP \(em kill random generator"
  144. X.IX  "dxrandomrv()"  ""  "\fldxrandomrv\fP \(em generate vector of \
  145. X    random doubles"
  146. X.IX  "fxrandomrv()"  ""  "\flfxrandomrv\fP \(em generate vector of \
  147. X    random floats"
  148. X.IX  "lxrandomrv()"  ""  "\fllxrandomrv\fP \(em generate vector of \
  149. X    random longs"
  150. X.IX  "bxrandomrv()"  ""  "\flbxrandomrv\fP \(em generate vector of \
  151. X    random bits, one bit from each generate"
  152. X.IX  "bxrandomrv_f()"  ""  "\flbxrandomrv_f\fP \(em generate vector of \
  153. X    random bits, 32 bits from each generate"
  154. X.IX  "dxrandomrv()"  ""  "\fldxrandomrv\fP \(em generate buffered vector of \
  155. X    random doubles"
  156. X.IX  "fxrandomrv()"  ""  "\flfxrandomrv\fP \(em generate buffered vector of \
  157. X    random floats"
  158. X.IX  "lxrandomrv()"  ""  "\fllxrandomrv\fP \(em generate buffered vector of \
  159. X    random longs"
  160. X.IX  "bxrandomrv()"  ""  "\flbxrandomrv\fP \(em generate buffered vector of \
  161. X    random bits, one bit from each generate"
  162. X.IX  "bxrandomrv_f()"  ""  "\flbxrandomrv_f\fP \(em generate buffered \
  163. X    vector of random bits, 32 bits from each generate"
  164. X.IX  "mrandomrv()"  ""  "\fLmrandomrv\fP \(em generate vector of \
  165. X    random integers mod m"
  166. X.IX  "save_rng()"  "" "\fLsave_rng\fP \(em save random generator to file"
  167. X.IX  "restart_rng()"  "" \
  168. X    "\fLrestart_rng\fP \(em restart random generator from file"
  169. X.IX  "seed_rng()"  ""  "\fLseed_rng\fP \(em seed random generator"
  170. X.IX  "check_rng()"  ""  "\fLcheck_rng\fP \(em check integrity of \
  171. X    random generator"
  172. X.IX  "describe_rng()"  "" \
  173. X    "\fLdescribe_rng\fP \(em construct short string describing \
  174. X     generator state" 
  175. X.IX  "mralg_rng()"  ""  "\fLmralg_rng\fP \(em set mrandomrv algorithm \
  176. X    number"
  177. X.IX  "split_rng()"  ""  "\fLsplit_rng\fP \(em set generator split value"
  178. X.IX  "range_rng()"  ""  "\fLrange_rng\fP \(em return generator range"
  179. X.IX  "random number generator"  "\fLinit_rng()\fP"
  180. X.IX  "random number generator"  "\fLkill_rng()\fP"
  181. X.IX  "random number generator"  "\fLdxrandomrv()\fP"
  182. X.IX  "random number generator"  "\fLfxrandomrv()\fP"
  183. X.IX  "random number generator"  "\fLlxrandomrv()\fP"
  184. X.IX  "random number generator"  "\fLbxrandomrv()\fP"
  185. X.IX  "random number generator"  "\fLbxrandomrv_f()\fP"
  186. X.IX  "random number generator"  "\fLdrandomrv()\fP"
  187. X.IX  "random number generator"  "\fLfrandomrv()\fP"
  188. X.IX  "random number generator"  "\fLlrandomrv()\fP"
  189. X.IX  "random number generator"  "\fLbrandomrv()\fP"
  190. X.IX  "random number generator"  "\fLbrandomrv_f()\fP"
  191. X.IX  "random number generator"  "\fLmrandomrv()\fP"
  192. X.IX  "random number generator"  "\fLdxrandomrv()\fP"
  193. X.IX  "random number generator"  "\fLfxrandomrv()\fP"
  194. X.IX  "random number generator"  "\fLlxrandomrv()\fP"
  195. X.IX  "random number generator"  "\fLbxrandomrv()\fP"
  196. X.IX  "random number generator"  "\fLflush_rng()\fP"
  197. X.IX  "random number generator"  "\fLsave_rng()\fP"
  198. X.IX  "random number generator"  "\fLrestart_rng()\fP"
  199. X.IX  "random number generator"  "\fLseed_rng()\fP"
  200. X.IX  "random number generator"  "\fLcheck_rng()\fP"
  201. X.IX  "random number generator"  "\fLdescribe_rng()\fP"
  202. X.IX  "random number generator"  "\fLmralg_rng()\fP"
  203. X.IX  "random number generator"  "\fLsplit_rng()\fP"
  204. X.IX  "random number generator"  "\fLrange_rng()\fP"
  205. X.IX  "generate random numbers"  "\fLinit_rng()\fP"
  206. X.IX  "generate random numbers"  "\fLkill_rng()\fP"
  207. X.IX  "generate random numbers"  "\fLdxrandomrv()\fP"
  208. X.IX  "generate random numbers"  "\fLfxrandomrv()\fP"
  209. X.IX  "generate random numbers"  "\fLlxrandomrv()\fP"
  210. X.IX  "generate random numbers"  "\fLbxrandomrv()\fP"
  211. X.IX  "generate random numbers"  "\fLbxrandomrv_f()\fP"
  212. X.IX  "generate random numbers"  "\fLdrandomrv()\fP"
  213. X.IX  "generate random numbers"  "\fLfrandomrv()\fP"
  214. X.IX  "generate random numbers"  "\fLlrandomrv()\fP"
  215. X.IX  "generate random numbers"  "\fLbrandomrv()\fP"
  216. X.IX  "generate random numbers"  "\fLbrandomrv_f()\fP"
  217. X.IX  "generate random numbers"  "\fLmrandomrv()\fP"
  218. X.IX  "generate random numbers"  "\fLdxrandomrv()\fP"
  219. X.IX  "generate random numbers"  "\fLfxrandomrv()\fP"
  220. X.IX  "generate random numbers"  "\fLlxrandomrv()\fP"
  221. X.IX  "generate random numbers"  "\fLbxrandomrv()\fP"
  222. X.IX  "generate random numbers"  "\fLflush_rng()\fP"
  223. X.IX  "generate random numbers"  "\fLsave_rng()\fP"
  224. X.IX  "generate random numbers"  "\fLrestart_rng()\fP"
  225. X.IX  "generate random numbers"  "\fLseed_rng()\fP"
  226. X.IX  "generate random numbers"  "\fLcheck_rng()\fP"
  227. X.IX  "generate random numbers"  "\fLdescribe_rng()\fP"
  228. X.IX  "generate random numbers"  "\fLmralg_rng()\fP"
  229. X.IX  "generate random numbers"  "\fLsplit_rng()\fP"
  230. X.IX  "generate random numbers"  "\fLrange_rng()\fP"
  231. X.SH DESCRIPTION
  232. X.LP
  233. X.I mrandomrv(rng,m,n,v)
  234. Xgenerates n random integers in the range 0 to m-1, using the generator
  235. Xrng, and storing them in vector v.
  236. XAn initialization routine,
  237. X.I init_rng(),
  238. Xdescribed below, allows you to select an appropriate generator.
  239. X
  240. XUsing this package, instead of direct calls to random() or some
  241. Xother RNG code, offers the following advantages.
  242. X.IP 1.
  243. XYou can switch to another RNG, and re-run a
  244. Xportion of your experiment to check its validity,
  245. Xwithout changing any of your code other
  246. Xthan a single parameter in your
  247. X.I
  248. Xinit_rng()
  249. Xcall.
  250. X.IP 2.
  251. XYou can use my unbiased method for generating random integers
  252. Xin the range 0..m-1.  By contrast, the typical integer-generating codes
  253. X"random()%m" or "(int) m * ((double) random()/MAXLONG)"
  254. Xhave a slight bias for large m.
  255. X.IP 3.
  256. XFloating point numbers, uniformly distributed in [0.0, 1.0),
  257. Xare available (as on most RNG interfaces).
  258. X.IP 4.
  259. XAs with most RNG interfaces, you can have many simultaneously-active RNGs.
  260. X(Unfortunately, I was unable to find an efficient work-around for 4.3bsd
  261. Xrandom()'s state-saving bug; you'll have to use one of the other generators
  262. Xif you want to use multiple RNG streams in a single program invocation.)
  263. X.IP 5.
  264. XTime-efficient vectorized calls, returning multiple uniform variates,
  265. Xare available.
  266. X.IP 6
  267. XThe ability to "split" RNGs to produce parallet output streams using the
  268. X"leapfrog" method.
  269. X.IP 7.
  270. XThe package offers a shorthand notation for completely specifying the
  271. Xalgorithm and current state of your RNG(s),
  272. Xin an 80-character human-readable ASCII string.
  273. XThis is very useful in experimental documentation and replication.
  274. X.IP 8.
  275. XA complete RNG state can be (serially) reconstructed from its
  276. Xshorthand notation, and
  277. X.IP 9.
  278. XA file-I/O interface allows fast saves and restarts of complete
  279. XRNG state vectors, without the time overhead of serial reconstruction.
  280. X
  281. X.LP
  282. XAlso included in this software release is a (unsupported) driver routine
  283. X.I mrtest.c.
  284. XThis routine implements some of the simpler tests of
  285. Xrandomness, e.g. equidistribution, pairwise (both short-
  286. Xand long-range) correlation, and 3-tuple correlation [Marsaglia, 1985].
  287. XThese tests were chosen to illustrate the use of the components
  288. Xof the 
  289. X.I mrandom()
  290. Xpackage, as well as to exhibit the known
  291. Xdefects of the 4.3bsd generators rand() and nrand48().
  292. XSee the man page on 
  293. X.I mrtest
  294. Xfor more details.
  295. X
  296. XAnother use for
  297. X.I mrtest.c
  298. Xis as a template for your own calls to the mrandom() package.
  299. X(I, for one, like to program by example...)
  300. X
  301. XBelow are detailed descriptions of the interfaces to the
  302. Xvarious C-language functions in the mrandom() package.
  303. XFor technical details, consult the file
  304. X.I mrandom.tex,
  305. Xalso included in this distribution.
  306. X
  307. XIn order to use an RNG, it must first be initialized.  This
  308. Xis accomplished by first declaring a pointer to an RNGdata
  309. Xstructure, and then calling
  310. X.I init_rng()
  311. X, which allocates memory for
  312. Xthe RNG and readies it for use by the other routines in the
  313. Xpackage.
  314. X
  315. X.I init_rng()
  316. Xreturns a pointer to an initialized RNG.  A pointer
  317. Xreturned by
  318. X.I init_rng() is valid for use by all other mrandom routines.
  319. X
  320. XIn an init_rng() call, the
  321. X.I alg
  322. Xparameter should have a value between 0 and 9, to indicate which RNG
  323. Xalgorithm is desired:
  324. X.IP 1.
  325. X4.3bsd random(), a non-linear additive feedback RNG,
  326. X.IP 2.
  327. XThe Knuth/Bentley prand(), a lagged-Fibonnacci generator
  328. Xwith a state table of size 55 [Bentley, 1992], 
  329. X.IP 3.
  330. X4.3bsd nrand48(),
  331. Xa 48-bit multiplicative congruential RNG,
  332. X.IP 4.
  333. XL'Ecuyer's ``portable combined'' 32-bit multiplicative congruential
  334. Xgenerator [L'Ecuyer, 1988],
  335. X.IP 5.
  336. X4.3bsd rand(),
  337. Xthe discredited 32-bit multiplicative congruential RNG, and
  338. X.IP 6-8.
  339. XPress & Teukolsky's ran0, ran1, and ran2, respectively [Press &
  340. XTeukolsky, 1992],
  341. X.IP 9.
  342. XMarsaglia's subtract-with-borrow Ultra generator [Marsaglia and Zaman, 1991],
  343. X.IP 0.
  344. Xfor testing purposes,
  345. Xa linear additive generator, "long state=seed1; state += seed2",
  346. Xcapable of generating any 32-bit constant or any arithmetic sequence.
  347. X
  348. X.I mrandom_alg
  349. Xis the algorithm to be used by
  350. X.I mrandomrv() when
  351. Xcalled with the RNG.
  352. X
  353. X.LP
  354. XThe seed and count parameters are used for initialization and
  355. X``cycling'' of the generator before control is returned to the calling
  356. Xprogram.  The generator will be cycled count1+(1.0e9)*count2 times, so
  357. Xbeware: if count2 is non-zero, the underlying RNG will be called
  358. Xbillions of times before control is returned to the calling program!
  359. XMost generators take just one 32-bit seed, but the
  360. X.I seed
  361. Xparameters points to a vector of seeds, whose length is determined by
  362. Xthe needs of the underlying generator.
  363. X
  364. X.I init_rng()
  365. Xreturns a pointer to the allocated and initialized RNG.
  366. X
  367. X.I bufsize
  368. Xis the size of the RNG's main buffer.  A non-positive value of
  369. X.I bufsize will be interpreted as a value of 1.
  370. X
  371. X.I kill_rng()
  372. Xdestroys the RNG, making it invalid for use.  This procedure
  373. Xde-allocates the space used by the RNG, and should therefore be used to
  374. Xkill RNGs which will no longer be used.
  375. X
  376. XDo
  377. X.I not
  378. Xuse an
  379. X.I RNGdata
  380. X
  381. Xpointer which points to an active RNG to store the return value of .I
  382. Xinit_rng().  In order to initialize an RNG, you should either declare a
  383. Xnew
  384. X.I RNGdata
  385. Xpointer, and then use it to store the return value of
  386. X.I init_rng(),
  387. Xor, use
  388. X.I kill_rng()
  389. Xto de-initialize an
  390. X.I RNGdata
  391. Xpointer which points to an active RNG, and then use that pointer to
  392. Xstore the return value of
  393. X.I init_rng()
  394. X
  395. XIn general, I believe that users should extend the sequence of an existing RNG,
  396. Xwhenever possible, instead of seeding a new one.
  397. XI suggest this methodology because it is so difficult to properly seed
  398. Xan RNG when performing multiple program runs during a single experiment.
  399. XWhere, after all, can you get truly random seeds?
  400. XTo use the time of day, or a process ID, is to invite disaster in the form
  401. Xof subtle experimental correlations or the (often not-so-subtle) effects of
  402. Xinadvertent reuse of a seed.
  403. XNote that if you use a ``perfectly random'' RNG to generate seeds
  404. Xuniformly distributed in 0..2^{31}-1,
  405. Xyou will are very likely to reuse a seed -- and thus risk a duplicated
  406. Xprogram run -- after running, say, thirty thousand experiments.
  407. X
  408. XAccordingly, my package makes it easy to save and restart RNGs,
  409. Xto minimize the attraction of reseeding with init_rng() calls.
  410. XThe call 
  411. X.I save_rng(rng, filename)
  412. Xwill write a complete state table to the specified file.
  413. XThe files are in human-readable ASCII,
  414. Xand are never more than about 1000 characters.
  415. XThe return value of save_rng is 1 if the file is successfully created;
  416. X0 otherwise.
  417. X
  418. XThe call
  419. X.I restart_rng(filename)
  420. Xreads the specified file
  421. Xinto and returns a pointer to the RNG constructed from the file.
  422. XA null pointer is returned, and a message is printed to stderr,
  423. Xif the restart fails due to a garbled or unreadable statefile.
  424. XOtherwise restart_rng returns the value 1. 
  425. X
  426. XA major advantage of using restart_rng
  427. Xinstead of init_rng
  428. Xis that the time required to initialize the RNG is independent
  429. Xof the value of the count1, count2 parameters.
  430. X
  431. X.LP
  432. XSeveral routines are available for generating pseudorandom numbers.
  433. XBoth buffered and unbuffered routines are provided.  Unbuffered routines
  434. Xcall the underlying RNG only as many times as are needed to produce the
  435. Xrequested number of generates, while buffered routines maintain buffers
  436. Xof generates, so that generates may be produced efficiently even when
  437. Xrequested in small quantities.  Roughly, buffered routines are
  438. Xpreferable when generates are requested one at a time or in small
  439. Xquantities, while unbuffered routines are preferable when generates are
  440. Xrequested in large quantities.  For detailed information about
  441. Xbuffering, seed mrandom.tex, included in this distribution.
  442. X
  443. XThe name of a routine denotes the type of the value which the routine
  444. Xreturns and whether the routine is buffered or unbuffered. The first
  445. Xletter of a routine denotes the type of value which it returns: ``d''
  446. Xfor double precision and ``f'' for single precision floating point in
  447. Xthe range [0,1); ``l'' for long integer in the range
  448. X0..(range_rng(rng)-1), and ``b'' for bit (either a 0 or a 1).  If the
  449. Xsecond letter of the routine's name is an ``x'', then the routine is
  450. Xunbuffered.  Otherwise, the routine is buffered.
  451. X
  452. XFor convenience in user programming, we also provide a number of macros
  453. Xthat supply default parameter values.  The last two letters of all our
  454. Xfundamental routines is ``rv''.  This means that they must be provided
  455. Xwith both a pointer to an RNGdata structure and a vector to fill with
  456. Xgenerates from the RNG.  Macros whose names do not contain an ``r'' have
  457. Xthe RNGdata pointer omitted from their parameter list; they use the
  458. Xmost-recently initialized or restarted RNG to produce generates.  Macros
  459. Xwhose names do not contain a ``v'' have the vector and number of
  460. Xgenerates omitted from their parameter list; they produce and return a
  461. Xsingle generate.
  462. X
  463. XAll generating routines abort with a message to stderr if called
  464. Xwith an invalid RNGdata pointer.
  465. X
  466. XThe two routines for generating bits deserve some extra attention.
  467. X.I bxrandomrv()
  468. Xand
  469. X.I brandomrv()
  470. Xeach use one generate from the RNG to generate each bit.
  471. X.I bxrandomrv_f()
  472. Xand
  473. X.I brandomrv_f()
  474. Xuse each generate to produce 32 bits.  These two routines can only be
  475. Xused with 32-bit generators; they return -1 otherwise.
  476. X
  477. X.I mrandomrv()
  478. Xfills the vector v with n generates in the range 0..m-1.  If
  479. Xrange_rng(rng) < m, the program aborts with an error.
  480. X
  481. XThe algorithm used by
  482. X.I mrandomrv()
  483. Xto fill v is set by
  484. X.I init_rng
  485. Xor by 
  486. X.I mralg_rng.
  487. X
  488. XAlgorithm 0 is Thomborson's unbiased method, which produces unbiased
  489. Xlong integers in the range [0..m).  The algorithm discards any outputs
  490. Xfrom rng which are larger than r-(r mod m), where r is equal to
  491. Xrange_rng(rng).  At worst, this code will discard (on long-term average)
  492. Xat most one value of r for every one that is useful.  This worst case is
  493. Xonly encountered for extremely large m; for fixed and moderate m, this
  494. Xcode will rarely discard a value, and thus will run essentially as fast
  495. Xas algorithm 1.  When the value of m changes on each call to
  496. X.I mrandomrv()
  497. X, however, this code is slower than algorithm 1, due to the
  498. Xnecessity of recomputing r-(r mod m).
  499. X
  500. XThe program aborts with an error message to stderr if rng is behaving so
  501. Xnon-randomly that Algorithm 0 must make an excessive number of calls to
  502. Xrng in order to produce the requested number of generates.
  503. X
  504. XAlgorithm 1 is the standard (long)(m*dxrandomr(rng)).  This algorithm
  505. Xmay be biased: for large m, some results may be be more likely than
  506. Xothers.  The bias is (r mod m)/m, which is upper-bounded by 0.1% if m is
  507. Xless than a million and the range r of rng is at least a billion.
  508. X
  509. XWe do not support, and indeed we actively discourage, generating
  510. Xrestricted-range integers with lrandomr(rng)%m.  Many RNGs have poor
  511. Xbehavior under this transformation, most noticeably when m is a power of
  512. X2.  When m is not a power of 2, fixed-point division required by an
  513. X``%'' operation is time-consuming on many workstations.
  514. X
  515. X.SH NOTES
  516. XThe mrandomrv procedure is capable of generating long integers in the
  517. Xfull range of any RNG for which 1 <= range_rng(rng) <= 2^32.  In order
  518. Xto accomplish this, with the parameter m a signed long integer, the
  519. Xfollowing mapping is used:
  520. X
  521. XRange(mrandom(m)) = 0..m-1        if 1 <= m < 2^31
  522. X            0.. 2^32-1      if m=0
  523. X            0..(2^31-m-1)    if -2^31 <= m < 0
  524. X
  525. X.LP
  526. X.I seed_rng()
  527. Xseeds rng with the seed table pointed to by seed.  The RNG's counter is
  528. Xreset to 0.
  529. X
  530. X.LP
  531. X.I check_rng()
  532. Xchecks the integrity of the RNG, in order to determine whether it can be
  533. Xused by the other mrandom library routines.
  534. X
  535. X.LP
  536. X.I describe_rng()
  537. Xplaces a human-readable description of rng in the string rngid.
  538. X
  539. X.LP
  540. X.I mralg_rng()
  541. Xsets the mrandom algorithm number of rng.
  542. X
  543. X.LP
  544. X.I split_rng()
  545. Xsets the split value of rng.
  546. X
  547. X.LP range_rng()
  548. Xreturns the range of rng.
  549. X
  550. X.SH AUTHOR
  551. XRobert Plotkin, rplotkin@athena.mit.edu and Clark Thomborson,
  552. Xcthombor@ub.d.umn.edu
  553. X.SH DIAGNOSTICS
  554. XIf error-checking code in any of the routines discovers a problem, an
  555. Xerror message is printed on the stderr stream.
  556. X
  557. X.SH "SEE ALSO"
  558. Xrandom(3), rand(3C), drand48(3), mrtest(1)
  559. X
  560. X.SH BUGS
  561. XA little slower than
  562. X.I random().
  563. X
  564. XA source-code rewrite of random() would allow efficient, bug-free,
  565. Xstate-saving and restarting.  As things stand, you can get
  566. X"non-random" and "non-restartable" RNG streams by calling
  567. Xinit_rng() several times with alg=1.  Perhaps I should add code to
  568. Xgenerate an error message in this case.
  569. X
  570. X.SH THEORY
  571. XAside from the bug with multiple simultaneous generators,
  572. XI know of no reason to choose
  573. X4.3bsd random() over the Knuth/Bentley RNG.
  574. XBoth are likely to fail Marsaglia's Birthday-Spacings test,
  575. Xalthough I don't know that this has been tested (and I don't see
  576. Xthat this is likely to pose a problem in any ``real'' application).
  577. XThe portable-combined RNG is noticeably slower, but arguably superior
  578. Xto both the above.
  579. XThe defects of 4.3bsd rand() and nrandom() are fairly well-known,
  580. Xand they are only included in this package for reasons of
  581. Xbackward compatibility and testing.
  582. X
  583. XFor more information on this package, see the LaTex files mrandom.tex
  584. Xand soda.tex included with this distribution.
  585. X
  586. X.SH REFERENCES
  587. X
  588. XJon Louis Bentley,
  589. X``The software exploratorium: Some random thoughts.''
  590. X.I UNIX Review 10,
  591. XNumber 6, June 1992.
  592. X
  593. XPierre L'Ecuyer,
  594. X``Efficient and portable combined random number generators.''
  595. X.I Communications of the ACM, 31(6):
  596. X742--774, June 1988.
  597. X
  598. XGeorge Marsaglia,
  599. X``A current view of random number generators.''
  600. XIn L. Billard, editor,
  601. X.I Computer Science and Statistics: The Interface,
  602. Xpages 3--10. Elsevier Science Publishers, 1985.
  603. X
  604. XGeorge Marsaglia and Arif Zaman,
  605. X``A New Class of Random Number Generators.''
  606. X.I The Annals of Applied Probability, 1(3):
  607. X1991.
  608. X
  609. XOra E. Percus and Malvin H. Kalos,
  610. X``Random number generators for MIMD parallel processors.''
  611. X.I Journal of Parallel and Distributed Computing, 6:
  612. X477--497, 1989.
  613. X
  614. XWilliam H. Press and Saul A. Teukolsky,
  615. X``Portable Random Number Generators.''
  616. X.I Computers in Physics, 6(5):
  617. XSept/Oct. 1992.
  618. X
  619. XRobert Sedgewick,
  620. X.I Algorithms in C,
  621. XAddison-Wesley, 1990.
  622. X
  623. XClark Thomborson, "Tools for Randomized Experimentation," to appear in the 
  624. X.I Proceedings of the 25th Symposium on the Interface:
  625. X.I Computing Science and Statistics,
  626. X1993.
  627. X
  628. XClark Thomborson.
  629. X``Mrandom (version 1).''
  630. X.I Comp.sources.unix 25(23),
  631. XDecember 1991.
  632. X
  633. END_OF_FILE
  634. if test 21315 -ne `wc -c <'man/mrandom.3'`; then
  635.     echo shar: \"'man/mrandom.3'\" unpacked with wrong size!
  636. fi
  637. # end of 'man/mrandom.3'
  638. fi
  639. if test -f 'man/mrandom.3.txt' -a "${1}" != "-c" ; then 
  640.   echo shar: Will not clobber existing file \"'man/mrandom.3.txt'\"
  641. else
  642. echo shar: Extracting \"'man/mrandom.3.txt'\" \(21353 characters\)
  643. sed "s/^X//" >'man/mrandom.3.txt' <<'END_OF_FILE'
  644. X
  645. X
  646. X
  647. XMRANDOM(3)             C LIBRARY FUNCTIONS             MRANDOM(3)
  648. X
  649. X
  650. X
  651. XNAME
  652. X     init_rng, kill_rng, dxrandomrv, dxrandomr, dxrandomv, dxran-
  653. X     dom, fxrandomrv, fxrandomr, fxrandomv, fxrandom, lxrandomrv,
  654. X     lxrandomr,  lxrandomv,  lxrandom,   bxrandomrv,   bxrandomr,
  655. X     bxrandomv, bxrandom, bxrandomrv_f, bxrandomr_f, bxrandomv_f,
  656. X     bxrandom_f, drandomrv, drandomr,  drandomv,  drandom,  fran-
  657. X     domrv,  frandomr,  frandomv,  frandom,  lrandomrv, lrandomr,
  658. X     lrandomv, lrandom, brandomrv, brandomr,  brandomv,  brandom,
  659. X     brandomrv_f,  brandomr_f,  brandomv_f, brandom_f, mrandomrv,
  660. X     mrandomr,   mrandomv,    mrandom,    flush_rng,    save_rng,
  661. X     restart_rng,  seed_rng,  check_rng, describe_rng, mralg_rng,
  662. X     split_rng, range_rng - a uniform interface to several random
  663. X     number generators
  664. X
  665. XSYNOPSIS
  666. X     RNGdata *init_rng(alg, mrandom_alg, seed, count1, count2,
  667. X     long alg, mrandom_alg, *seed, count1, count2,
  668. X
  669. X     int kill_rng(rng)
  670. X     RNGdata *rng;
  671. X
  672. X     double dxrandomrv(rng, n, v)
  673. X     RNGdata *rng;
  674. X     long n;
  675. X     double v[];
  676. X
  677. X     float fxrandomrv(rng, n, v)
  678. X     RNGdata *rng;
  679. X     long n;
  680. X     float v[];
  681. X
  682. X     long lxrandomrv(rng, n, v)
  683. X     RNGdata *rng;
  684. X     long n;
  685. X     long v[];
  686. X
  687. X     long lxrandomv(n, v)
  688. X     long n;
  689. X     long v[];
  690. X
  691. X     int bxrandomrv(rng, n, v)
  692. X     RNGdata *rng;
  693. X     long n;
  694. X     int v[];
  695. X
  696. X     int bxrandomrv_f(rng, n, v)
  697. X     RNGdata *rng;
  698. X     long n;
  699. X     int v[];
  700. X
  701. X     double drandomrv(rng, n, v)
  702. X     RNGdata *rng;
  703. X
  704. X
  705. X
  706. XSun Release 4.1       Last change: 5/28/93                      1
  707. X
  708. X
  709. X
  710. X
  711. X
  712. X
  713. XMRANDOM(3)             C LIBRARY FUNCTIONS             MRANDOM(3)
  714. X
  715. X
  716. X
  717. X     long n;
  718. X     double v[];
  719. X
  720. X     float frandomrv(rng, n, v)
  721. X     RNGdata *rng;
  722. X     long n;
  723. X     float v[];
  724. X
  725. X     long lrandomrv(rng, n, v)
  726. X     RNGdata *rng;
  727. X     long n;
  728. X     long v[];
  729. X
  730. X     int brandomrv(rng, n, v)
  731. X     RNGdata *rng;
  732. X     long n;
  733. X     int v[];
  734. X
  735. X     int brandomrv_f(rng, n, v)
  736. X     RNGdata *rng;
  737. X     long n;
  738. X     int v[];
  739. X
  740. X     long mrandomrv(rng, m, n, v)
  741. X     RNGdata *rng;
  742. X     long m;
  743. X     long n;
  744. X     long v[];
  745. X
  746. X     int save_rng(rng, filename)
  747. X     RNGdata *rng;
  748. X     char *filename;
  749. X
  750. X     RNGdata *restart_rng(rng, filename)
  751. X     char *filename;
  752. X
  753. X     void seed_rng(rng, seed)
  754. X     RNGdata *rng;
  755. X     long *seed;
  756. X
  757. X     int check_rng(rng);
  758. X     RNGdata *rng;
  759. X
  760. X     char *describe_rng(rng, rngid)
  761. X     RNGdata *rng;
  762. X     char rngid[RNGIDSTRLEN];
  763. X
  764. X     int mralg_rng(rng,new_value)
  765. X     RNGdata *rng;
  766. X     long new_value;
  767. X
  768. X
  769. X
  770. X
  771. X
  772. XSun Release 4.1       Last change: 5/28/93                      2
  773. X
  774. X
  775. X
  776. X
  777. X
  778. X
  779. XMRANDOM(3)             C LIBRARY FUNCTIONS             MRANDOM(3)
  780. X
  781. X
  782. X
  783. X     int split_rng(rng, new_value)
  784. X     RNGdata *rng;
  785. X     long new_value;
  786. X
  787. X     double range_rng(rng)
  788. X     RNGdata *rng;
  789. X
  790. XDESCRIPTION
  791. X     _m_r_a_n_d_o_m_r_v(_r_n_g,_m,_n,_v) generates  n  random  integers  in  the
  792. X     range 0 to m-1, using the generator rng, and storing them in
  793. X     vector v.  An initialization routine, _i_n_i_t__r_n_g(),  described
  794. X     below, allows you to select an appropriate generator.
  795. X
  796. X     Using this package, instead of direct calls to  random()  or
  797. X     some other RNG code, offers the following advantages.
  798. X
  799. X     1.   You can switch to another RNG, and re-run a portion  of
  800. X          your experiment to check its validity, without changing
  801. X          any of your code other than a single parameter in  your
  802. X          _i_n_i_t__r_n_g() call.
  803. X
  804. X     2.   You can use my unbiased method  for  generating  random
  805. X          integers in the range 0..m-1.  By contrast, the typical
  806. X          integer-generating codes "random()%m"  or  "(int)  m  *
  807. X          ((double)  random()/MAXLONG)"  have  a  slight bias for
  808. X          large m.
  809. X
  810. X     3.   Floating point numbers, uniformly distributed in  [0.0,
  811. X          1.0), are available (as on most RNG interfaces).
  812. X
  813. X     4.   As  with  most  RNG  interfaces,  you  can  have   many
  814. X          simultaneously-active   RNGs.   (Unfortunately,  I  was
  815. X          unable to find  an  efficient  work-around  for  4.3bsd
  816. X          random()'s  state-saving bug; you'll have to use one of
  817. X          the other generators if you want to  use  multiple  RNG
  818. X          streams in a single program invocation.)
  819. X
  820. X     5.   Time-efficient  vectorized  calls,  returning  multiple
  821. X          uniform variates, are available.
  822. X
  823. X     6    The ability to "split" RNGs to produce parallet  output
  824. X          streams using the "leapfrog" method.
  825. X
  826. X     7.   The package offers a shorthand notation for  completely
  827. X          specifying  the  algorithm  and  current  state of your
  828. X          RNG(s), in an 80-character human-readable ASCII string.
  829. X          This  is  very useful in experimental documentation and
  830. X          replication.
  831. X
  832. X     8.   A complete RNG state can  be  (serially)  reconstructed
  833. X          from its shorthand notation, and
  834. X
  835. X
  836. X
  837. X
  838. XSun Release 4.1       Last change: 5/28/93                      3
  839. X
  840. X
  841. X
  842. X
  843. X
  844. X
  845. XMRANDOM(3)             C LIBRARY FUNCTIONS             MRANDOM(3)
  846. X
  847. X
  848. X
  849. X     9.   A file-I/O interface allows fast saves and restarts  of
  850. X          complete  RNG  state vectors, without the time overhead
  851. X          of serial reconstruction.
  852. X
  853. X
  854. X     Also included in this software release  is  a  (unsupported)
  855. X     driver routine _m_r_t_e_s_t._c. This routine implements some of the
  856. X     simpler tests of randomness, e.g. equidistribution, pairwise
  857. X     (both short- and long-range) correlation, and 3-tuple corre-
  858. X     lation [Marsaglia, 1985].  These tests were chosen to illus-
  859. X     trate the use of the components of the _m_r_a_n_d_o_m() package, as
  860. X     well as to exhibit the known defects of the  4.3bsd  genera-
  861. X     tors  rand()  and nrand48().  See the man page on _m_r_t_e_s_t for
  862. X     more details.
  863. X
  864. X     Another use for _m_r_t_e_s_t._c is as a template for your own calls
  865. X     to  the  mrandom() package.  (I, for one, like to program by
  866. X     example...)
  867. X
  868. X     Below are detailed descriptions of  the  interfaces  to  the
  869. X     various  C-language functions in the mrandom() package.  For
  870. X     technical  details,  consult  the  file  _m_r_a_n_d_o_m._t_e_x,   also
  871. X     included in this distribution.
  872. X
  873. X     In order to use an RNG, it must first be initialized.   This
  874. X     is  accomplished  by first declaring a pointer to an RNGdata
  875. X     structure, and then calling  _i_n_i_t__r_n_g()  ,  which  allocates
  876. X     memory  for the RNG and readies it for use by the other rou-
  877. X     tines in the package.
  878. X
  879. X     _i_n_i_t__r_n_g() returns a  pointer  to  an  initialized  RNG.   A
  880. X     pointer returned by _i_n_i_t__r_n_g() _i_s _v_a_l_i_d _f_o_r _u_s_e _b_y
  881. X
  882. X     In an init_rng() call, the _a_l_g parameter should have a value
  883. X     between 0 and 9, to indicate which RNG algorithm is desired:
  884. X
  885. X     1.   4.3bsd random(), a non-linear additive feedback RNG,
  886. X
  887. X     2.   The Knuth/Bentley prand(), a lagged-Fibonnacci  genera-
  888. X          tor with a state table of size 55 [Bentley, 1992],
  889. X
  890. X     3.   4.3bsd nrand48(), a 48-bit multiplicative  congruential
  891. X          RNG,
  892. X
  893. X     4.   L'Ecuyer's ``portable combined'' 32-bit  multiplicative
  894. X          congruential generator [L'Ecuyer, 1988],
  895. X
  896. X     5.   4.3bsd rand(), the  discredited  32-bit  multiplicative
  897. X          congruential RNG, and
  898. X
  899. X     6-8. Press & Teukolsky's ran0, ran1, and ran2,  respectively
  900. X          [Press & Teukolsky, 1992],
  901. X
  902. X
  903. X
  904. XSun Release 4.1       Last change: 5/28/93                      4
  905. X
  906. X
  907. X
  908. X
  909. X
  910. X
  911. XMRANDOM(3)             C LIBRARY FUNCTIONS             MRANDOM(3)
  912. X
  913. X
  914. X
  915. X     9.   Marsaglia's subtract-with-borrow Ultra generator  [Mar-
  916. X          saglia and Zaman, 1991],
  917. X
  918. X     0.   for testing  purposes,  a  linear  additive  generator,
  919. X          "long state=seed1; state += seed2", capable of generat-
  920. X          ing any 32-bit constant or any arithmetic sequence.
  921. X
  922. X          _m_r_a_n_d_o_m__a_l_g is the algorithm to be used by  _m_r_a_n_d_o_m_r_v()
  923. X          _w_h_e_n called with the RNG.
  924. X
  925. X
  926. X     The seed and count parameters are  used  for  initialization
  927. X     and  ``cycling'' of the generator before control is returned
  928. X     to the  calling  program.   The  generator  will  be  cycled
  929. X     count1+(1.0e9)*count2  times,  so  beware: if count2 is non-
  930. X     zero, the underlying RNG will be called  billions  of  times
  931. X     before  control  is  returned  to the calling program!  Most
  932. X     generators take just one 32-bit seed, but the  _s_e_e_d  parame-
  933. X     ters points to a vector of seeds, whose length is determined
  934. X     by the needs of the underlying generator.
  935. X
  936. X     _i_n_i_t__r_n_g() returns a pointer to the allocated  and  initial-
  937. X     ized RNG.
  938. X
  939. X     _b_u_f_s_i_z_e is the size  of  the  RNG's  main  buffer.   A  non-
  940. X     positive value of _b_u_f_s_i_z_e _w_i_l_l _b_e _i_n_t_e_r_p_r_e_t_e_d _a_s _a
  941. X
  942. X     _k_i_l_l__r_n_g() destroys the RNG,  making  it  invalid  for  use.
  943. X     This  procedure  de-allocates the space used by the RNG, and
  944. X     should therefore be used to kill RNGs which will  no  longer
  945. X     be used.
  946. X
  947. X     Do _n_o_t use an _R_N_G_d_a_t_a
  948. X
  949. X     pointer which points to an active RNG to  store  the  return
  950. X     value  of .I init_rng().  In order to initialize an RNG, you
  951. X     should either declare a new _R_N_G_d_a_t_a pointer, and then use it
  952. X     to  store the return value of _i_n_i_t__r_n_g(), or, use _k_i_l_l__r_n_g()
  953. X     to de-initialize an  _R_N_G_d_a_t_a  pointer  which  points  to  an
  954. X     active  RNG,  and  then use that pointer to store the return
  955. X     value of _i_n_i_t__r_n_g()
  956. X
  957. X     In general, I believe that users should extend the  sequence
  958. X     of  an existing RNG, whenever possible, instead of seeding a
  959. X     new one.  I suggest this methodology because it is so diffi-
  960. X     cult  to  properly seed an RNG when performing multiple pro-
  961. X     gram runs during a single experiment.  Where, after all, can
  962. X     you  get  truly  random seeds?  To use the time of day, or a
  963. X     process ID, is to invite disaster  in  the  form  of  subtle
  964. X     experimental   correlations  or  the  (often  not-so-subtle)
  965. X     effects of inadvertent reuse of a seed.  Note  that  if  you
  966. X     use  a  ``perfectly random'' RNG to generate seeds uniformly
  967. X
  968. X
  969. X
  970. XSun Release 4.1       Last change: 5/28/93                      5
  971. X
  972. X
  973. X
  974. X
  975. X
  976. X
  977. XMRANDOM(3)             C LIBRARY FUNCTIONS             MRANDOM(3)
  978. X
  979. X
  980. X
  981. X     distributed in 0..2^{31}-1, you  will  are  very  likely  to
  982. X     reuse  a  seed  -- and thus risk a duplicated program run --
  983. X     after running, say, thirty thousand experiments.
  984. X
  985. X     Accordingly, my package makes it easy to  save  and  restart
  986. X     RNGs,   to   minimize   the  attraction  of  reseeding  with
  987. X     init_rng() calls.  The  call  _s_a_v_e__r_n_g(_r_n_g,  _f_i_l_e_n_a_m_e)  will
  988. X     write  a  complete  state  table to the specified file.  The
  989. X     files are in human-readable ASCII, and are never  more  than
  990. X     about 1000 characters.  The return value of save_rng is 1 if
  991. X     the file is successfully created; 0 otherwise.
  992. X
  993. X     The call _r_e_s_t_a_r_t__r_n_g(_f_i_l_e_n_a_m_e) reads the specified file into
  994. X     and  returns a pointer to the RNG constructed from the file.
  995. X     A null pointer is returned, and  a  message  is  printed  to
  996. X     stderr,  if the restart fails due to a garbled or unreadable
  997. X     statefile.  Otherwise restart_rng returns the value 1.
  998. X
  999. X     A major advantage of using restart_rng instead  of  init_rng
  1000. X     is  that the time required to initialize the RNG is indepen-
  1001. X     dent of the value of the count1, count2 parameters.
  1002. X
  1003. X
  1004. X     Several routines are available for  generating  pseudorandom
  1005. X     numbers.   Both  buffered  and  unbuffered routines are pro-
  1006. X     vided.  Unbuffered routines call the underlying RNG only  as
  1007. X     many  times as are needed to produce the requested number of
  1008. X     generates, while buffered routines maintain buffers of  gen-
  1009. X     erates,  so  that generates may be produced efficiently even
  1010. X     when requested in small quantities.  Roughly, buffered  rou-
  1011. X     tines  are  preferable when generates are requested one at a
  1012. X     time or in small quantities, while unbuffered  routines  are
  1013. X     preferable when generates are requested in large quantities.
  1014. X     For detailed information about buffering, seed  mrandom.tex,
  1015. X     included in this distribution.
  1016. X
  1017. X     The name of a routine denotes the type of  the  value  which
  1018. X     the  routine  returns and whether the routine is buffered or
  1019. X     unbuffered. The first letter of a routine denotes  the  type
  1020. X     of  value  which  it returns: ``d'' for double precision and
  1021. X     ``f'' for single  precision  floating  point  in  the  range
  1022. X     [0,1);    ``l''    for    long    integer   in   the   range
  1023. X     0..(range_rng(rng)-1), and ``b'' for bit (either a  0  or  a
  1024. X     1).  If the second letter of the routine's name is an ``x'',
  1025. X     then the routine is unbuffered.  Otherwise, the  routine  is
  1026. X     buffered.
  1027. X
  1028. X     For convenience in  user  programming,  we  also  provide  a
  1029. X     number  of macros that supply default parameter values.  The
  1030. X     last two letters of all our fundamental routines is  ``rv''.
  1031. X     This means that they must be provided with both a pointer to
  1032. X     an RNGdata structure and a vector  to  fill  with  generates
  1033. X
  1034. X
  1035. X
  1036. XSun Release 4.1       Last change: 5/28/93                      6
  1037. X
  1038. X
  1039. X
  1040. X
  1041. X
  1042. X
  1043. XMRANDOM(3)             C LIBRARY FUNCTIONS             MRANDOM(3)
  1044. X
  1045. X
  1046. X
  1047. X     from  the  RNG.   Macros whose names do not contain an ``r''
  1048. X     have the RNGdata pointer omitted from their parameter  list;
  1049. X     they  use  the most-recently initialized or restarted RNG to
  1050. X     produce generates.  Macros whose  names  do  not  contain  a
  1051. X     ``v''  have  the vector and number of generates omitted from
  1052. X     their parameter list; they produce and return a single  gen-
  1053. X     erate.
  1054. X
  1055. X     All generating routines abort with a message  to  stderr  if
  1056. X     called with an invalid RNGdata pointer.
  1057. X
  1058. X     The two routines for  generating  bits  deserve  some  extra
  1059. X     attention.   _b_x_r_a_n_d_o_m_r_v()  and _b_r_a_n_d_o_m_r_v() each use one gen-
  1060. X     erate from the RNG to generate each bit.  _b_x_r_a_n_d_o_m_r_v__f() and
  1061. X     _b_r_a_n_d_o_m_r_v__f()  use  each generate to produce 32 bits.  These
  1062. X     two routines can only be used with 32-bit  generators;  they
  1063. X     return -1 otherwise.
  1064. X
  1065. X     _m_r_a_n_d_o_m_r_v() fills the vector v with n generates in the range
  1066. X     0..m-1.   If  range_rng(rng) < m, the program aborts with an
  1067. X     error.
  1068. X
  1069. X     The algorithm used by  _m_r_a_n_d_o_m_r_v()  to  fill  v  is  set  by
  1070. X     _i_n_i_t__r_n_g or by _m_r_a_l_g__r_n_g.
  1071. X
  1072. X     Algorithm 0 is Thomborson's unbiased method, which  produces
  1073. X     unbiased  long  integers in the range [0..m).  The algorithm
  1074. X     discards any outputs from rng which are larger than r-(r mod
  1075. X     m), where r is equal to range_rng(rng).  At worst, this code
  1076. X     will discard (on long-term average) at most one value  of  r
  1077. X     for  every  one  that  is  useful.   This worst case is only
  1078. X     encountered for extremely large m; for fixed and moderate m,
  1079. X     this  code  will  rarely  discard a value, and thus will run
  1080. X     essentially as fast as algorithm 1.  When  the  value  of  m
  1081. X     changes  on each call to _m_r_a_n_d_o_m_r_v() , however, this code is
  1082. X     slower than algorithm 1, due to the necessity of recomputing
  1083. X     r-(r mod m).
  1084. X
  1085. X     The program aborts with an error message to stderr if rng is
  1086. X     behaving  so  non-randomly  that  Algorithm  0  must make an
  1087. X     excessive number of calls to rng in  order  to  produce  the
  1088. X     requested number of generates.
  1089. X
  1090. X     Algorithm 1 is the standard (long)(m*dxrandomr(rng)).   This
  1091. X     algorithm may be biased: for large m, some results may be be
  1092. X     more likely than others.  The bias is (r mod m)/m, which  is
  1093. X     upper-bounded  by  0.1%  if m is less than a million and the
  1094. X     range r of rng is at least a billion.
  1095. X
  1096. X     We do not support, and indeed we actively  discourage,  gen-
  1097. X     erating   restricted-range  integers  with  lrandomr(rng)%m.
  1098. X     Many RNGs have poor behavior under this transformation, most
  1099. X
  1100. X
  1101. X
  1102. XSun Release 4.1       Last change: 5/28/93                      7
  1103. X
  1104. X
  1105. X
  1106. X
  1107. X
  1108. X
  1109. XMRANDOM(3)             C LIBRARY FUNCTIONS             MRANDOM(3)
  1110. X
  1111. X
  1112. X
  1113. X     noticeably when m is a power of 2.  When m is not a power of
  1114. X     2, fixed-point division required by an  ``%''  operation  is
  1115. X     time-consuming on many workstations.
  1116. X
  1117. X
  1118. XNOTES
  1119. X     The  mrandomrv  procedure  is  capable  of  generating  long
  1120. X     integers  in  the  full  range  of  any  RNG  for which 1 <=
  1121. X     range_rng(rng) <= 2^32.  In order to accomplish  this,  with
  1122. X     the parameter m a signed long integer, the following mapping
  1123. X     is used:
  1124. X
  1125. X     Range(mrandom(m))  =  0..m-1         if  1  <=  m   <   2^31
  1126. X                      0..    2^32-1         if   m=0
  1127. X     0..(2^31-m-1)   if -2^31 <= m < 0
  1128. X
  1129. X
  1130. X     _s_e_e_d__r_n_g() seeds rng with the seed table pointed to by seed.
  1131. X     The RNG's counter is reset to 0.
  1132. X
  1133. X
  1134. X     _c_h_e_c_k__r_n_g() checks the integrity of the  RNG,  in  order  to
  1135. X     determine  whether  it  can  be  used  by  the other mrandom
  1136. X     library routines.
  1137. X
  1138. X
  1139. X     _d_e_s_c_r_i_b_e__r_n_g() places a human-readable description of rng in
  1140. X     the string rngid.
  1141. X
  1142. X
  1143. X     _m_r_a_l_g__r_n_g() sets the mrandom algorithm number of rng.
  1144. X
  1145. X
  1146. X     _s_p_l_i_t__r_n_g() sets the split value of rng.
  1147. X
  1148. X
  1149. X     returns the range of rng.
  1150. X
  1151. X
  1152. XAUTHOR
  1153. X     Robert Plotkin, rplotkin@athena.mit.edu and  Clark  Thombor-
  1154. X     son, cthombor@ub.d.umn.edu
  1155. X
  1156. XDIAGNOSTICS
  1157. X     If error-checking code in any of the  routines  discovers  a
  1158. X     problem, an error message is printed on the stderr stream.
  1159. X
  1160. X
  1161. XSEE ALSO
  1162. X     random(3), rand(3C), drand48(3), mrtest(1)
  1163. X
  1164. X
  1165. X
  1166. X
  1167. X
  1168. XSun Release 4.1       Last change: 5/28/93                      8
  1169. X
  1170. X
  1171. X
  1172. X
  1173. X
  1174. X
  1175. XMRANDOM(3)             C LIBRARY FUNCTIONS             MRANDOM(3)
  1176. X
  1177. X
  1178. X
  1179. XBUGS
  1180. X     A little slower than _r_a_n_d_o_m().
  1181. X
  1182. X     A source-code rewrite of  random()  would  allow  efficient,
  1183. X     bug-free, state-saving and restarting.  As things stand, you
  1184. X     can get "non-random" and "non-restartable"  RNG  streams  by
  1185. X     calling  init_rng()  several  times  with  alg=1.  Perhaps I
  1186. X     should add code to generate an error message in this case.
  1187. X
  1188. X
  1189. XTHEORY
  1190. X     Aside from the bug with multiple simultaneous generators,  I
  1191. X     know  of  no  reason  to  choose  4.3bsd  random()  over the
  1192. X     Knuth/Bentley RNG.  Both  are  likely  to  fail  Marsaglia's
  1193. X     Birthday-Spacings  test, although I don't know that this has
  1194. X     been tested (and I don't see that this is likely to  pose  a
  1195. X     problem in any ``real'' application).  The portable-combined
  1196. X     RNG is noticeably slower, but arguably superior to both  the
  1197. X     above.   The  defects  of  4.3bsd  rand()  and nrandom() are
  1198. X     fairly well-known, and they are only included in this  pack-
  1199. X     age for reasons of backward compatibility and testing.
  1200. X
  1201. X     For more information on this package, see  the  LaTex  files
  1202. X     mrandom.tex and soda.tex included with this distribution.
  1203. X
  1204. X
  1205. XREFERENCES
  1206. X     Jon Louis Bentley, ``The software exploratorium: Some random
  1207. X     thoughts.'' _U_N_I_X _R_e_v_i_e_w _1_0, Number 6, June 1992.
  1208. X
  1209. X     Pierre L'Ecuyer, ``Efficient and  portable  combined  random
  1210. X     number  generators.'' _C_o_m_m_u_n_i_c_a_t_i_o_n_s _o_f _t_h_e _A_C_M, _3_1(_6): 742-
  1211. X     -774, June 1988.
  1212. X
  1213. X     George Marsaglia, ``A current view of random number  genera-
  1214. X     tors.''  In L. Billard, editor, _C_o_m_p_u_t_e_r _S_c_i_e_n_c_e _a_n_d _S_t_a_t_i_s_-
  1215. X     _t_i_c_s: _T_h_e _I_n_t_e_r_f_a_c_e, pages 3--10. Elsevier Science  Publish-
  1216. X     ers, 1985.
  1217. X
  1218. X     George Marsaglia and Arif Zaman, ``A  New  Class  of  Random
  1219. X     Number  Generators.''  _T_h_e  _A_n_n_a_l_s  _o_f  _A_p_p_l_i_e_d _P_r_o_b_a_b_i_l_i_t_y,
  1220. X     _1(_3): 1991.
  1221. X
  1222. X     Ora E. Percus and Malvin H. Kalos, ``Random  number  genera-
  1223. X     tors for MIMD parallel processors.'' _J_o_u_r_n_a_l _o_f _P_a_r_a_l_l_e_l _a_n_d
  1224. X     _D_i_s_t_r_i_b_u_t_e_d _C_o_m_p_u_t_i_n_g, 477--497, 1989.
  1225. X
  1226. X     William H. Press and Saul A.  Teukolsky,  ``Portable  Random
  1227. X     Number  Generators.''  _C_o_m_p_u_t_e_r_s _i_n _P_h_y_s_i_c_s, _6(_5): Sept/Oct.
  1228. X     1992.
  1229. X
  1230. X     Robert Sedgewick, _A_l_g_o_r_i_t_h_m_s _i_n _C, Addison-Wesley, 1990.
  1231. X
  1232. X
  1233. X
  1234. XSun Release 4.1       Last change: 5/28/93                      9
  1235. X
  1236. X
  1237. X
  1238. X
  1239. X
  1240. X
  1241. XMRANDOM(3)             C LIBRARY FUNCTIONS             MRANDOM(3)
  1242. X
  1243. X
  1244. X
  1245. X     Clark Thomborson, "Tools for Randomized Experimentation," to
  1246. X     appear in the _P_r_o_c_e_e_d_i_n_g_s _o_f _t_h_e _2_5_t_h _S_y_m_p_o_s_i_u_m _o_n _C_o_m_p_u_t_i_n_g
  1247. X     _S_c_i_e_n_c_e _a_n_d _S_t_a_t_i_s_t_i_c_s, 1993.
  1248. X
  1249. X     Clark     Thomborson.      ``Mrandom     (version      1).''
  1250. X     _C_o_m_p._s_o_u_r_c_e_s._u_n_i_x _2_5(_2_3), December 1991.
  1251. X
  1252. X
  1253. X
  1254. X
  1255. X
  1256. X
  1257. X
  1258. X
  1259. X
  1260. X
  1261. X
  1262. X
  1263. X
  1264. X
  1265. X
  1266. X
  1267. X
  1268. X
  1269. X
  1270. X
  1271. X
  1272. X
  1273. X
  1274. X
  1275. X
  1276. X
  1277. X
  1278. X
  1279. X
  1280. X
  1281. X
  1282. X
  1283. X
  1284. X
  1285. X
  1286. X
  1287. X
  1288. X
  1289. X
  1290. X
  1291. X
  1292. X
  1293. X
  1294. X
  1295. X
  1296. X
  1297. X
  1298. X
  1299. X
  1300. XSun Release 4.1       Last change: 5/28/93                     10
  1301. X
  1302. X
  1303. X
  1304. END_OF_FILE
  1305. echo shar: 652 control characters may be missing from \"'man/mrandom.3.txt'\"
  1306. if test 21353 -ne `wc -c <'man/mrandom.3.txt'`; then
  1307.     echo shar: \"'man/mrandom.3.txt'\" unpacked with wrong size!
  1308. fi
  1309. # end of 'man/mrandom.3.txt'
  1310. fi
  1311. if test -f 'src/mrandom.h' -a "${1}" != "-c" ; then 
  1312.   echo shar: Will not clobber existing file \"'src/mrandom.h'\"
  1313. else
  1314. echo shar: Extracting \"'src/mrandom.h'\" \(20309 characters\)
  1315. sed "s/^X//" >'src/mrandom.h' <<'END_OF_FILE'
  1316. X/* mrandom.h 3.1 5/28/93 */
  1317. X/*
  1318. X *        mrandom.h
  1319. X *
  1320. X *      An interface for random number generators (RNGs)
  1321. X *
  1322. X *    Original Implementation:
  1323. X *        Clark Thomborson, September 1991
  1324. X *    Modifications:
  1325. X *       - give uniform interface to other rngs
  1326. X *       - remove bias from integer generator
  1327. X *       - avoid possible infinite loop in mrandom(m)
  1328. X *       - allow access to multiple simultaneous rngs
  1329. X *       - add interface to nrand48()
  1330. X *       - add interface to rand()
  1331. X *       - tuned for speed
  1332. X *        Clark Thomborson, May 1992
  1333. X *    
  1334. X *      Version 3.0:
  1335. X *              Robert Plotkin, May 1993
  1336. X *      Modifications include:
  1337. X *         - Standardized interface to underlying RNGs
  1338. X *         - Added buffered generating routines
  1339. X *         - Added interfaces to ran0, ran1, ran2, Ultra RNGs
  1340. X *         - Added routines for generating bits
  1341. X *         - Added split feature
  1342. X *         - Allow choice of algorithms in mrandomrv
  1343. X *         - Dynamic allocation of RNGs
  1344. X *
  1345. X *    This material is based upon work supported by the National
  1346. X *    Science Foundation under grant number MIP-9023238.  The
  1347. X *    Government has certain rights in this material.
  1348. X *
  1349. X *    Any opinions, findings, and conclusions or recommendations
  1350. X *    expressed in this material are those of the author and do
  1351. X *    not necessarily reflect the view of the National Science
  1352. X *    Foundation.
  1353. X *
  1354. X *    This code is neither copyrighted nor patented, although we are
  1355. X *    not sure about the status of some of the routines it calls.
  1356. X */
  1357. X
  1358. X#ifndef MRANDOM
  1359. X#define MRANDOM
  1360. X#endif
  1361. X
  1362. X/*****************************/
  1363. X/* Miscellaneous definitions */
  1364. X/*****************************/
  1365. X#define RNGIDSTRLEN 80 /* Maximum length of string written by */
  1366. X               /* describe_rng() */
  1367. X#define BILLION    1000000000 /* The modulus for 32-bit RNGcount1 in our */
  1368. X               /* statefile, i.e. */
  1369. X                           /* (Number of calls to RNG since seeding) = */
  1370. X               /* RNGcount1 + BILLION * RNGcount2 */
  1371. X#define BBUF_SIZE    32 /* Size of the bit buffer */
  1372. X#define NUM_RNGS     10 /* Number of RNGs currently installed */
  1373. X#define SPLIT_DEF    0  /* Default split value for all RNGs */
  1374. X
  1375. X#define RET_LONG     4  /* Types of values returned by */
  1376. X#define RET_DOUBLE   -8 /* RNG generating routines */
  1377. X
  1378. X#define STATE_CHAR   1  /* Types of values stored in */
  1379. X#define STATE_INT    2  /* RNG state and seed vectors */
  1380. X#define STATE_LONG   4
  1381. X#define STATE_FLOAT  -4 /* STATE_FLOAT and STATE_DOUBLE are */
  1382. X#define STATE_DOUBLE -8 /* currently unsupported */
  1383. X
  1384. X/**************************/
  1385. X/* RNGdata                */
  1386. X/* Data describing an RNG */
  1387. X/**************************/
  1388. Xstruct rngdata {
  1389. X  /* The following data is taken directly from the statefile */
  1390. X  long    rngalg;        /* algorithm used to generate pseudorandoms:
  1391. X             * 0 = trivial rng (long state=seed1; state += seed2)
  1392. X             * 1 = 4.3bsd random.c,
  1393. X             * 2 = bentley.c,
  1394. X             * 3 = pcrand.c,
  1395. X             * 4 = 4.3bsd nrand48.c,
  1396. X             * 5 = 4.3bsd rand.c,
  1397. X             * 6 = Press & Teukolsky's ran0 (ran0.c)
  1398. X             * 7 = Press & Teukolsky's ran1 (ran1.c)
  1399. X             * 8 = Press & Teukolsky's ran2 (ran2.c)
  1400. X             * 9 = Marsaglia's Ultra (ultra.c)
  1401. X             */
  1402. X  long mrandom_alg; /* Algorithm used by mrandomrv */
  1403. X  long *rngstate;   /* The RNG's state vector */
  1404. X  long *rngseed;    /* The seed originally used to initialize rngstate */
  1405. X  long rngcount1;   /* mod-BILLION counter of calls to the RNG */
  1406. X  long rngcount2;   /* div-BILLION counter */
  1407. X  struct {
  1408. X    long size;              /* Number of entries in buffer */
  1409. X    long nleft;             /* Number of values left in buffer */
  1410. X    int nbleft;             /* Number of values in bit buffer */
  1411. X    double *dbuf,*dbufp;    /* RNG double buffer [0,1) */
  1412. X    long *lbuf,*lbufp;      /* RNG long buffer 0...RNGrange-1 */
  1413. X    int *bbuf,*bbufp;       /* RNG bit buffer 0,1 */
  1414. X  } buffer;
  1415. X  long rngnextval;          /* the RNG's next output */
  1416. X  long rngsplit;            /* Return every rngsplit-th generate */
  1417. X  
  1418. X  /* The next six values are inferred from rngalg */
  1419. X  char rngname[RNGIDSTRLEN]; /* Name of the RNG */
  1420. X  long rngstatesize;
  1421. X  long rngseedsize; /* It is permissible to have an RNG which can use */
  1422. X            /* different numbers of seeds.  In that case, use */
  1423. X            /* the maximum permissible number of seeds for */
  1424. X            /* this value. */
  1425. X  double rngrange;  /* The RNG's range, expressed as a d.p. float */
  1426. X  signed int rngreturns; /* The kind of value the rng returns
  1427. X                - Positive numbers indicate integers in the
  1428. X                  range 0...RNGrange-1
  1429. X                - Negative numbers indicate floats in the
  1430. X                  range [0,1)
  1431. X                - Absolute value indicates the number of
  1432. X                  bytes per RNG output
  1433. X                  e.g. 4 means a 32-bit integer,
  1434. X                  -16 means a 128 bit float
  1435. X                  Currently only 4 and -8 are supported.
  1436. X                  These are defined as RET_LONG and
  1437. X                  RET_DOUBLE, respectively. */
  1438. X  int rngstatetype; /* The type of the value stored in the RNG's state */
  1439. X            /* and seed vectors.  Currently, three types are */
  1440. X            /* supported:
  1441. X               Type            Value
  1442. X               -----------     ----------
  1443. X               8-bit char      STATE_CHAR
  1444. X               16-bit int      STATE_INT
  1445. X               32-bit long     STATE_LONG
  1446. X               */
  1447. X};
  1448. Xtypedef struct rngdata RNGdata;
  1449. X
  1450. X/* Convenient names for data in our RNGdata struct */
  1451. X#define RNGalg        (rng->rngalg)
  1452. X#define RNGname         (rng->rngname)
  1453. X#define RNGseed            (rng->rngseed)
  1454. X#define RNGcount1    (rng->rngcount1)
  1455. X#define RNGcount2    (rng->rngcount2)
  1456. X#define RNGnextval    (rng->rngnextval)
  1457. X#define RNGstatesize    (rng->rngstatesize)
  1458. X#define RNGseedsize     (rng->rngseedsize)
  1459. X#define RNGrangem1    (rng->rngrangem1)
  1460. X#define RNGrange    (rng->rngrange)
  1461. X#define RNGstate    (rng->rngstate)
  1462. X#define RNGmrandom_alg  (rng->mrandom_alg)
  1463. X#define RNGbuffer       (rng->buffer)
  1464. X#define RNGreturns      (rng->rngreturns)
  1465. X#define RNGstatetype    (rng->rngstatetype)
  1466. X#define RNGsplit        (rng->rngsplit)
  1467. X
  1468. X/*******************************************************************/
  1469. X/* Procedures for generating pseudorandom numbers                  */
  1470. X/* These procedures write a vector v of length n, by repeating the */
  1471. X/* following two steps n times:                                    */
  1472. X/*      - place the next generate in v                             */
  1473. X/*      - discard the next k generates, where k is the split value */
  1474. X/*         of the RNG                                              */
  1475. X/*                                                                 */
  1476. X/* Special cases:                                                  */
  1477. X/*  Argument  Value  Meaning                                       */
  1478. X/*  --------  -----  -------                                       */
  1479. X/*  rng         0    Use most recently used or initialized rng.    */
  1480. X/*  n           0    Return  a single generate.                    */
  1481. X/*                   The value of v is ignored(it may be set to 0).*/
  1482. X/*                                                                 */  
  1483. X/* All procedures return the first entry in the vector v.          */
  1484. X/*******************************************************************/
  1485. X
  1486. X/***********************************************/
  1487. X/* Buffered calling procedures.                */
  1488. X/***********************************************/
  1489. X/*******************/
  1490. X/* drandomrv       */
  1491. X/* Returns doubles */
  1492. X/*******************/
  1493. Xdouble drandomrv(/*RNGdata *rng, long n, double v[]*/);
  1494. X#define drandomr(rng)  drandomrv(rng,0,0)
  1495. X#define drandomv(n,v)  drandomrv(0,n,v)
  1496. X#define drandom()      drandomrv(0,0,0)
  1497. X
  1498. X/******************/
  1499. X/* frandomrv      */
  1500. X/* Returns floats */
  1501. X/******************/
  1502. Xfloat frandomrv(/*RNGdata *rng, long n, float v[]*/);
  1503. X#define frandomr(rng)  frandomrv(rng,0,0)
  1504. X#define frandomv(n,v)  frandomrv(0,n,v)
  1505. X#define frandom()      frandomrv(0,0,0)
  1506. X
  1507. X/*****************/
  1508. X/* lrandomrv     */
  1509. X/* Returns longs */
  1510. X/*****************/
  1511. Xlong lrandomrv(/*RNGdata *rng, long n, long v[]*/);
  1512. X#define lrandomr(rng)  lrandomrv(rng,0,0)
  1513. X#define lrandomv(n,v)  lrandomrv(0,n,v)
  1514. X#define lrandom()      lrandomrv(0,0,0)
  1515. X
  1516. X/******************************************/
  1517. X/* brandomrv                              */
  1518. X/* Returns "high quality" bits,           */
  1519. X/*  i.e. each generate from the underlying*/
  1520. X/*  RNG is used to generate one bit.      */
  1521. X/******************************************/
  1522. Xint brandomrv(/*RNGdata *rng, long n, int v[]*/);
  1523. X#define brandomr(rng)  brandomrv(rng,0,0)
  1524. X#define brandomv(n,v)  brandomrv(0,n,v)
  1525. X#define brandom()      brandomrv(0,0,0)
  1526. X
  1527. X/******************************************/
  1528. X/* brandomrv_f                            */
  1529. X/* Returns "low quality" fast bits,       */
  1530. X/*  i.e. each generate from the underlying*/
  1531. X/*  RNG is used to generate 32 bits.      */
  1532. X/* Return -1 if the range of the RNG      */
  1533. X/*  is not 2^32.                          */
  1534. X/******************************************/
  1535. X/* Splitting of this fast bit stream is not currently supported. */
  1536. Xint brandomrv_f(/*RNGdata *rng, long n, int v[]*/);
  1537. X#define brandomr_f(rng)  brandomrv_f(rng,0,0)
  1538. X#define brandomv_f(n,v)  brandomrv_f(0,n,v)
  1539. X#define brandom_f()      brandomrv_f(0,0,0)
  1540. X
  1541. X/*********************************/
  1542. X/* Unbuffered calling procedures */
  1543. X/*********************************/
  1544. X/*******************/
  1545. X/* dxrandomrv      */
  1546. X/* Returns doubles */
  1547. X/*******************/
  1548. Xdouble dxrandomrv(/*RNGdata *rng, long n, double v[]*/);
  1549. X#define dxrandomr(rng) dxrandomrv(rng,0,0)
  1550. X#define dxrandomv(n,v) dxrandomrv(0,n,v)
  1551. X#define dxrandom()     dxrandomrv(0,0,0)
  1552. X
  1553. X/******************/
  1554. X/* fxrandomrv     */
  1555. X/* Returns floats */
  1556. X/******************/
  1557. Xfloat fxrandomrv(/*RNGdata *rng, long n, float v[]*/);
  1558. X#define fxrandomr(rng) fxrandomrv(rng,0,0)
  1559. X#define fxrandomv(n,v) fxrandomrv(0,n,v)
  1560. X#define fxrandom()     fxrandomrv(0,0,0)
  1561. X
  1562. X/*****************/
  1563. X/* lxrandomrv    */
  1564. X/* Returns longs */
  1565. X/*****************/
  1566. Xlong lxrandomrv(/*RNGdata *rng, long n, long v[]*/);
  1567. X#define lxrandomr(rng) lxrandomrv(rng,0,0)
  1568. X#define lxrandomv(n,v) lxrandomrv(0,n,v)
  1569. X#define lxrandom()     lxrandomrv(0,0,0)
  1570. X
  1571. X/*******************************/
  1572. X/* bxrandomrv                  */
  1573. X/* Return "high quality" bits. */
  1574. X/*******************************/
  1575. Xint bxrandomrv(/*RNGdata *rng, long n, int v[]*/);
  1576. X#define bxrandomr(rng) bxrandomrv(rng,0,0)
  1577. X#define bxrandomv(n,v) bxrandomrv(0,n,v)
  1578. X#define bxrandom()     bxrandomrv(0,0,0)
  1579. X
  1580. X/*******************************/
  1581. X/* bxrandomrv_f                */
  1582. X/* Return "low quality" bits.  */
  1583. X/* Return -1 if range of RNG   */
  1584. X/*  is not 2^32                */
  1585. X/*******************************/
  1586. X/* This routine will "lose" random bits if they are not requested in
  1587. X *  multiples of (RNGsplit+1)*BBUF_SIZE, since bits are returned by
  1588. X *  pulling them off the random stream sequentially, using up exactly
  1589. X *  as many as are needed in order to generate the requested number
  1590. X *  of bits.
  1591. X * Splitting of this fast bit stream is not currently supported.
  1592. X */
  1593. Xint bxrandomrv_f(/*RNGdata *rng, long n, int v[]*/);
  1594. X#define bxrandomr_f(rng) bxrandomrv_f(rng,0,0)
  1595. X#define bxrandomv_f(n,v) bxrandomrv_f(0,n,v)
  1596. X#define bxrandom_f()     bxrandomrv_f(0,0,0)
  1597. X
  1598. X/****************************/
  1599. X/* seed_rng                 */
  1600. X/* Seeds the underlying RNG */
  1601. X/****************************/
  1602. Xvoid seed_rng(/*RNGdata *rng, long *seed*/);
  1603. X
  1604. X/*************************************/
  1605. X/* check_rng                         */
  1606. X/* Check the integrity of the RNG.   */
  1607. X/* Return 1 if ok, 0 if not.         */
  1608. X/*************************************/
  1609. Xint check_rng(/*RNGdata *rng*/);
  1610. X
  1611. X/*************************************/
  1612. X/* describe_rng                      */
  1613. X/* Write a short ASCII description   */
  1614. X/*  of the RNG to the user-supplied  */
  1615. X/*  string rngid, which must be of   */
  1616. X/*  length at least RNGIDSTRLEN.     */
  1617. X/* If the user has not initialized   */
  1618. X/*  the rng with init_rng() or       */
  1619. X/*  restart_rng(), abort with an     */
  1620. X/*  error message to stderr.         */
  1621. X/* Otherwise return rngid.           */
  1622. X/* Currently only supports RNGs with */
  1623. X/*  at most two seeds.               */
  1624. X/*************************************/
  1625. Xchar *describe_rng (/*RNGdata *rng, char rngid[RNGIDSTRLEN]*/);
  1626. X
  1627. X/*************************************/
  1628. X/* split_rng                         */
  1629. X/* Modify rng to "leapfrog" a number */
  1630. X/*  of generates determined by the   */
  1631. X/*  value of new_value               */
  1632. X/*  (new_value == 0 returns          */
  1633. X/*     every generate)               */
  1634. X/* Returns 0 if new_value < 0        */
  1635. X/* Returns 1 otherwise               */
  1636. X/* Exits on error if rng has not     */
  1637. X/*  been initialized                 */
  1638. X/*************************************/
  1639. Xint split_rng(/* RNGdata *rng, long new_value*/);
  1640. X
  1641. X/*************************************/
  1642. X/* mralg_rng                         */
  1643. X/* Modify rng to use a different     */
  1644. X/*  algorithm for mrandom()          */
  1645. X/* Returns 0 if mralg is out of range*/
  1646. X/* Returns 1 otherwise               */
  1647. X/* Exits on error if rng has not     */
  1648. X/*  been initialized                 */
  1649. X/*************************************/
  1650. Xint mralg_rng(/* RNGdata *rng, long new_value*/);
  1651. X
  1652. X/*************************************/
  1653. X/* range_rng                         */
  1654. X/* Return the range of the RNG       */
  1655. X/*  (i.e. rng is capable of producing*/
  1656. X/*  generates in the range           */
  1657. X/*  0...(range_rng(rng)-1)           */
  1658. X/* Exits on error if rng has not     */
  1659. X/*  been initialized                 */
  1660. X/*************************************/
  1661. Xdouble range_rng(/*RNGdata *rng*/);
  1662. X
  1663. X/************/
  1664. X/* init_rng */
  1665. X/************/
  1666. X/* Initialize the general-purpose rng data area so that it holds the
  1667. X * state and other data required for the selected algorithm "alg", where
  1668. X *    alg = 0 is a trivial generator that returns state += seed2,
  1669. X *      where state is initially set to seed1.  Use for debugging only!
  1670. X *    alg = 1 is 4.3bsd random.c (non-linear additive feedback)
  1671. X *    alg = 2 is the Knuth/Bentley prand (lagged Fibonnacci)
  1672. X *    alg = 3 is L'Ecuyer's portable combined (multiplicative) RNG
  1673. X *    alg = 4 is 4.3bsd nrand48.c,
  1674. X *      alg = 5 is 4.3bsd rand
  1675. X *      alg = 6 is Press and Teukolsky's ran0
  1676. X *      alg = 7 is Press and Teukolsky's ran1
  1677. X *      alg = 8 is Press and Teukolsky's ran2
  1678. X *      alg = 9 is Marsaglia's Ultra RNG
  1679. X *
  1680. X * Note: Memory for rng is allocated by this routine.  Before calling
  1681. X *  this routine the user need only declare a pointer to the generator,
  1682. X *  for example
  1683. X *        RNGdata *myrng;
  1684. X *
  1685. X * The mrandom_alg parameter determines which algorithm will be used
  1686. X *  by mrandom when call with this RNG:
  1687. X *      0 = Thomborson's unbiased conversion
  1688. X *      1 = (int) (m * drandomr(rng))
  1689. X *
  1690. X * The bufsize parameter determines the number of entries in the
  1691. X *  buffer.  Buffer space is allocated dynamically during
  1692. X *  initialization.  Thirty-two entries are allocated for the bit
  1693. X *  buffer.
  1694. X *
  1695. X * The count1 parameter indicates how many times the selected RNG algorithm
  1696. X *  should be called prior to returning control to the calling routine.
  1697. X *  We recommend a high value, at least 10000, for this parameter, to minimize
  1698. X *  the ill effects of seeding.  The count2 parameter can be given a non-zero
  1699. X *  value if you wish to "cycle" the generator a huge number of times: it 
  1700. X *  will be called (count2*1e9 + count1) times.  Probably count2 should always
  1701. X *  be 0 until computers become much, much faster than today.
  1702. X *
  1703. X * init_rng() returns a pointer to the initialized RNG unless an
  1704. X *  out-of-range argument is detected (rngalg >9 or < 0; count1 >1e9 or <0;
  1705. X *  or count2 <0), or if memory cannot be allocated for the RNG,
  1706. X *  in which case it returns a null pointer.
  1707. X *
  1708. X * Note: a single program may call init_rng() any number of times, to set up
  1709. X * multiple generators (possibly using more than one RNG algorithm), e.g with 
  1710. X *        RNGdata *myrngs[8];
  1711. X *        long i,sum=0,seed[2];
  1712. X *              seed[1]=0;
  1713. X *        for (i=0; i<7; i++) {
  1714. X *          /* generator #i gets seed1 = i
  1715. X *                seed[0]=i;
  1716. X *          myrngs[i]=init_rng(2,0,seed,100000,0,1024);
  1717. X *        }
  1718. X *        /* our eighth RNG uses algorithm #3
  1719. X *              seed[7]=7;
  1720. X *        myrngs[7]=init_rng(3,0,seed,100000,0,1024);
  1721. X *        /* add 1-bit numbers, one from each generator
  1722. X *        for (i=0; i<7; i++) {
  1723. X *          sum += mrandom(&myrngs[i],2);
  1724. X *        }
  1725. X *
  1726. X * Warning: do not attempt to use multiple RNGdata areas for algorithm #1.
  1727. X *  The 4.3bsd random.c code has internal state that will not be modified
  1728. X *  correctly when you switch generators (this was a bug in the original
  1729. X *  implementation and it would be very difficult to fix here).
  1730. X * 
  1731. X * Warning: Do NOT override previously-initialized RNGs with the results
  1732. X *  of this procedure.  If you have a pointer to a valid RNG and wish to
  1733. X *  initialize a new RNG using the same pointer, you should call
  1734. X *  kill_rng() before calling init_rng().  For example:
  1735. X *              ...
  1736. X *              i=lrandomr(rng); /* This RNG is in use
  1737. X *              kill_rng(rng);   /* Kill the RNG, and THEN
  1738. X *              rng=init_rng(3,1,seed,1000,0,256); /* init a new one
  1739. X *
  1740. X * We recommend that init_rng() be used very sparingly.  Except when
  1741. X * replicating experiments or debugging, it is better to restart an
  1742. X * existing generator (stored in a statefile) than to initialize a new one.
  1743. X */
  1744. XRNGdata *init_rng(/* long alg, long mrandom_alg, long *seed,
  1745. X             long count1, long count2, long bufsize*/);
  1746. X
  1747. X/*******************************/
  1748. X/* kill_rng                    */
  1749. X/* Frees memory used by an RNG */
  1750. X/* Returns 0 if kill failed    */
  1751. X/* Returns 1 otherwise         */
  1752. X/*******************************/
  1753. Xint kill_rng(/*RNGdata *rng*/);
  1754. X
  1755. X/*********************************************/
  1756. X/* save_rng                                  */
  1757. X/* Save the RNG state to a statefile.        */
  1758. X/* Return 0 if RNG couldn't be saved.        */
  1759. X/* Returns 1 otherwise.                      */
  1760. X/*********************************************/
  1761. Xint save_rng(/* RNGdata *rng, char *filename*/);
  1762. X
  1763. X/****************************************************************/
  1764. X/* restart_rng                                                  */
  1765. X/* Restart a generator from a statefile.                        */
  1766. X/* Return a null pointer if the restart failed due to a garbled */
  1767. X/*  or nonexistent statefile.                                   */
  1768. X/* Otherwise return a pointer to the restarted RNG.             */
  1769. X/* WARNING: An RNG which has been previously initialized using  */
  1770. X/*  init_rng() should NOT be overwritten with the return value  */
  1771. X/*  of this procedure.  In order to provide a "fresh" RNG for   */
  1772. X/*  this procedure, do one of the following:                    */
  1773. X/*     - Declare a new RNG                                      */
  1774. X/*     - Kill a previously initialized RNG using kill_rng()     */
  1775. X/****************************************************************/
  1776. XRNGdata *restart_rng(/* char *filename*/);
  1777. X
  1778. X/*********************************************/
  1779. X/* flush_rng                                 */
  1780. X/* Flush the contents of the RNG's buffers   */
  1781. X/* Returns 1 upon success, 0 upon failure    */
  1782. X/*********************************************/
  1783. Xint flush_rng(/*RNGdata *rng*/);
  1784. X
  1785. X/*************/
  1786. X/* mrandomrv */
  1787. X/*************/
  1788. X/* Generate a length-n vector v of random longs, uniformly distributed
  1789. X * in the range 0..m-1, using the indicated rng.  Return a copy of the
  1790. X * first random variate, v[0].
  1791. X *
  1792. X * Special-case parameter values: if rng==0, use the RNG that was
  1793. X * the most-recently initialized or restarted; if n==0, return one
  1794. X * random variate and don't write into v[]. 
  1795. X *
  1796. X * Our code does not have a deterministic bias for any m, unlike the
  1797. X * typical "good" code
  1798. X *        (int) floor( drandom() * (double) m )
  1799. X * or the commonly-used, but hazardous (because it exposes the flaws
  1800. X * in many RNGs) code 
  1801. X *        random()%m
  1802. X * We remove the bias by making multiple calls (on rare occasions)
  1803. X * to the underlying generator.  The expected number of RNG calls
  1804. X * is upper-bounded by n/(1 - (RNGrange%m)/RNGrange) < 2n.
  1805. X *
  1806. X * The program is aborted, with an error message, if
  1807. X *  m exceeds the range of the RNG.
  1808. X *
  1809. X * The program will also abort, again with an error message to stderr,
  1810. X * if the generator is behaving so non-randomly that our multiple-call
  1811. X * bias-removal algorithm makes an excessive number of calls to the
  1812. X * underlying generator.
  1813. X */
  1814. Xlong mrandomrv (/* RNGdata *rng, long m, long n, long v*/);
  1815. X#define mrandomr(rng,m)  mrandomrv(rng,m,0,0)
  1816. X#define mrandomv(m,n,v)  mrandomrv(0,m,n,v)
  1817. X#define mrandom(m)       mrandomrv(0,m,0,0)
  1818. END_OF_FILE
  1819. if test 20309 -ne `wc -c <'src/mrandom.h'`; then
  1820.     echo shar: \"'src/mrandom.h'\" unpacked with wrong size!
  1821. fi
  1822. # end of 'src/mrandom.h'
  1823. fi
  1824. if test -f 'src/mrtest.c' -a "${1}" != "-c" ; then 
  1825.   echo shar: Will not clobber existing file \"'src/mrtest.c'\"
  1826. else
  1827. echo shar: Extracting \"'src/mrtest.c'\" \(21361 characters\)
  1828. sed "s/^X//" >'src/mrtest.c' <<'END_OF_FILE'
  1829. X/* mrtest.c 3.1 5/28/93 */
  1830. X/*
  1831. X *        mrtest.c
  1832. X *
  1833. X *    Test routine for mrandom.c 
  1834. X *
  1835. X *    Original Implementation:
  1836. X *        Clark Thomborson, September 1991
  1837. X *
  1838. X *    Modifications:
  1839. X *
  1840. X *    Clark Thomborson, May 1992 -- used new mrandom.h features,
  1841. X *        -added Chi-square test (based on Sedgewick's {it Algorithms}),
  1842. X *        -added -dnnn option, to demonstrate a problem with nrand48,
  1843. X *        -added Marsaglia's k-tuple test (from {\it Computer Science and
  1844. X *         Statistics: The Interface}, L. Billard (ed.), Elsevier 1985,
  1845. X *         pp. 3--10,
  1846. X *        -added -v, -f, and -p options; added -DVECTOR cc option
  1847. X *        -added median and mod 3 tests
  1848. X *        -added -t,-e options; added lots of argerr() calls 
  1849. X *        -used xsq instead of Chi-square.  Statistic is not chi-squared,
  1850. X *         except in large-n limit.
  1851. X *        -improved accuracy of xsq calcs for very large n
  1852. X *        -adjusted code, so "mrtest 0" prints current rngstate
  1853. X *        -added large-m equidistribution test
  1854. X *        -debugged default RNGfile creation code (Aug 1992)
  1855. X *
  1856. X *      Robert Plotkin, May 1993
  1857. X *              -update for use with mrandom 3.0
  1858. X *
  1859. X *    Possible future additions:
  1860. X *        -more RNGs
  1861. X *        -faster (hash-based) large-m equidistribution test 
  1862. X *        -add Marsaglia's "Birthday-Spacings" test, to exhibit a
  1863. X *         shortcoming of Bentley's prand() (as well as 4.3bsd random()):
  1864. X *         sort n results from mrandom(m), compute the list of "spacings"
  1865. X *         (differences) between adjacent output values in the sorted
  1866. X *         list, then let Y be the number of values that appear
  1867. X *         more than once among the spacings.  Y is asymptotically
  1868. X *         Poisson with parameter $\lambda = n^3/(4m)$ [Marsaglia,
  1869. X *         ``A current view of random number generators'', Computer
  1870. X *         Science and Statistics: The Interface, Elsevier, 1985;
  1871. X *         Marsaglia says the ``proof, due to Janos Komlos, and
  1872. X *         detailed discussion of the test will appear elsewhere.''].
  1873. X *         According to Marsaglia, lagged-Fibbonacci generators
  1874. X *         based on binary addition, e.g. Bentley's RNG, fail this
  1875. X *         test.  Quite probably random() would fail it as well.
  1876. X *        -add a Poisson interpretation routine, to support the
  1877. X *         Birthday Spacings test.  This could also be useful in
  1878. X *         a possible improvement to the interpret_xsq routine,
  1879. X *         since Poisson statistics could be used to analyze frequency
  1880. X *         counts in (our usual) case of very small n/k.
  1881. X *         
  1882. X *
  1883. X *    This material is based upon work supported by the National
  1884. X *    Science Foundation under grant number MIP-9023238.  The
  1885. X *    Government has certain rights in this material.
  1886. X *
  1887. X *    Any opinions, findings, and conclusions or recommendations
  1888. X *    expressed in this material are those of the author and do
  1889. X *    not necessarily reflect the view of the National Science
  1890. X *    Foundation.
  1891. X *
  1892. X *    This code is neither copyrighted nor patented.
  1893. X */
  1894. X
  1895. X# include <sys/file.h> /* we use access() */
  1896. X# include "mrandom.h"
  1897. X# include "xsq.h" /* for interpretation of X-squared values */
  1898. X# include <math.h>
  1899. X# include <values.h> /* we need MAXLONG */
  1900. X
  1901. X# ifndef RNGFILENAME
  1902. X# define RNGFILENAME "RNGstatefile" /* where the RNG state is stored */
  1903. X# endif
  1904. X
  1905. X/* max(m,n) for which equidistribution test will be performed */
  1906. X# define EQUIDISTMAX (1<<18)
  1907. X/* max m for which 2-tuple correlation will be tested */
  1908. X# define PAIRMAXM 256
  1909. X
  1910. Xvoid argerr(progname)
  1911. Xchar *progname;
  1912. X{
  1913. X  printf(
  1914. X    "Usage: %s [ nn -dnnnn -S[n[,n[,n[,n[,n]]]]] -mnn -Mnn -q -t -e]",
  1915. X     progname);
  1916. X#ifndef VECTOR
  1917. X  printf(" -f -v -p");
  1918. X#endif
  1919. X  printf(" ]\n");
  1920. X  printf("  nn sets number of random generates to be tested.  Default 10.\n");
  1921. X  printf(
  1922. X   "  -dnnnn discards nnnn generates between tested values.  Default 0.\n");
  1923. X  printf("  -S[n[,n[,n[,n[,n[,n]]]]]] initializes an RNG, as follows:\n");
  1924. X  printf("    parameter #1 sets the RNG algorithm:\n");
  1925. X  printf("      0 is an additive linear scheme (for testing only);\n");
  1926. X  printf("      1 is 4.3bsd random,\n");
  1927. X  printf("      2 is the Knuth/Bentley prand,\n");
  1928. X  printf("      3 is L'Ecuyer's portable combined multiplicative RNG,\n");
  1929. X  printf("      4 is 4.3bsd nrandom48, and\n");
  1930. X  printf("      5 is 4.3bsd rand;\n");
  1931. X  printf("      6 is Press & Teukolsky's ran0\n");
  1932. X  printf("      7 is Press & Teukolsky's ran1\n");
  1933. X  printf("      8 is Press & Teukolsky's ran2\n");
  1934. X  printf("      9 is Marsaglia's Ultra\n");
  1935. X  printf("    parameter #2 sets the first RNG seed\n");
  1936. X  printf("    parameter #3 sets the second RNG seed (if any)\n");
  1937. X  printf("    parameter #4 sets the number of times to cycle the RNG\n");
  1938. X  printf("      before starting the tests, mod 1 billion.\n");
  1939. X  printf("    parameter #5 sets the number of times to cycle the RNG\n");
  1940. X  printf("      before starting the tests, div 1 billion.\n");
  1941. X  printf("    defaults are 1,1,1,0,0 respectively.\n");
  1942. X  printf("  -mnnnn sets the range of the RNG to be nnnn.  Default 100.\n");
  1943. X  printf("  -Mnn sets the range of the RNG to be 2^nn, 0<=nn<=31.\n");
  1944. X  printf("  -q or -quiet doesn't print any random generates.\n");
  1945. X  printf("  -t eliminates most RNG tests, for timing measurements.\n");
  1946. X  printf("  -e echos the command line (useful in scripts).\n");
  1947. X# ifdef VECTOR
  1948. X  printf("  This version of the code is optimized for speed.\n");
  1949. X  printf("  Recompile without -DVECTOR if you want any of the following:\n");
  1950. X# endif
  1951. X  printf("  -f uses (int(dxrandom()*m): faster, but slightly biased.\n");
  1952. X  printf("  -p uses random()%%m, a poor method.\n");
  1953. X  exit(1);
  1954. X} /* end argerr */
  1955. X
  1956. X#define NORMAL      0
  1957. X#define VECTORIZED  1
  1958. X#define FAST        2
  1959. X#define POOR        3
  1960. X
  1961. X/* declare storage for a vector of random generates */
  1962. X# define VECLENGTH 64
  1963. Xstatic long rpt=VECLENGTH;
  1964. Xstatic long rvals[VECLENGTH];
  1965. X
  1966. X# ifndef VECTOR
  1967. X/* slower code with runtime options */
  1968. Xlong random_value(rng,m,method)
  1969. XRNGdata *rng;
  1970. Xlong m,method;
  1971. X{
  1972. X
  1973. X  switch (method) {
  1974. X    case NORMAL:
  1975. X     return( mrandom(m) );
  1976. X    case VECTORIZED:
  1977. X     if (rpt==VECLENGTH) {
  1978. X       rpt = 1;
  1979. X       return( mrandomrv(rng,m,VECLENGTH,rvals) );
  1980. X     } else {
  1981. X       return( rvals[rpt++] );
  1982. X     }
  1983. X    case FAST:
  1984. X     return( (int) (dxrandom()*m) );
  1985. X    case POOR:
  1986. X     return( lxrandom()%m );
  1987. X    default:
  1988. X     return( 0 );
  1989. X  }
  1990. X}
  1991. X# else
  1992. X/* fast code, an optimized version of the -v option */
  1993. X# define random_value(rng,m,method) \
  1994. X    (rpt==VECLENGTH ? \
  1995. X       ( rpt = 1, mrandomrv(rng,m,VECLENGTH,rvals) ) : \
  1996. X       ( rvals[rpt++] ) \
  1997. X    )
  1998. X# endif /* VECTOR */
  1999. X
  2000. X/* Comparison routine, for qsort() */
  2001. Xint comparelongs(a,b)
  2002. Xlong *a,*b;
  2003. X{
  2004. X  return( ((*a)<(*b))? -1 : (((*a)==(*b))? 0 : 1) );
  2005. X}
  2006. X
  2007. X/* A simple test-driver */
  2008. Xint main(argc,argv)
  2009. Xint argc; char *argv[];
  2010. X{
  2011. X  /* command-line arguments, with default values */
  2012. X  int reseeding=0; /* nonzero if RNG state will be re-initialized */
  2013. X  int quiet=0; /* nonzero if we don't want to print random generates */
  2014. X  int echo=0; /* nonzero if we want to echo the mrtest invocation line */
  2015. X  int timing=0; /* nonzero if we don't want to make a lot of RNG tests */
  2016. X# ifndef VECTOR
  2017. X  int method=NORMAL; /* how we should call the mrandom package;
  2018. X    * other defined values are VECTORIZED (the -v option),
  2019. X    * FAST (-f), and POOR (-p).
  2020. X    */
  2021. X# else
  2022. X  int method = VECTORIZED; /* default (and only) option in this version */ 
  2023. X# endif
  2024. X  long alg=1;
  2025. X  long mrandom_alg=0;
  2026. X  long bufsize=1;
  2027. X  long seed1=1,seed2=1, seed[2]; /* seed for RNG */
  2028. X  long count1=0,count2=0; /* init call count for RNG */
  2029. X  long n=10; /* number of randoms to generate */
  2030. X  long m=100; /* desired range of random outputs: 0..m-1 */
  2031. X  long discards=0; /* how many generates to discard between outputs */
  2032. X
  2033. X  long i,j,k; /* temp counters */
  2034. X  char rngdesc[RNGIDSTRLEN]; /* for a describe_rng() call */
  2035. X
  2036. X  RNGdata *myrng; /* area to store this RNG's state & other data */
  2037. X
  2038. X  double dm,dn; /* = (double) m, (double) n */
  2039. X
  2040. X  /* temps used to calculate x-squared values */
  2041. X  double expf,f,sumfsq; /* we use doubles, not longs, to avoid overflow */
  2042. X  long sumf;  /* sum of all freqs, for error check */
  2043. X  double zerofreqs; /* number of freqs = 0 */
  2044. X  /* flags to indicate which tests will be run */
  2045. X  int testequidist; /* 0: max(m,n) too big, don't test;
  2046. X             * 1: count freqs online,
  2047. X             * 3: m is huge, count freqs offline.
  2048. X             */
  2049. X  int test2tuples, test3tuples;
  2050. X  /* various xsq stats */
  2051. X  double xsq,xsq2,xsq3, xsq2l, xsq3l;
  2052. X  /* random generates: current, previous, previous^2, first, second */
  2053. X  long x, prevx, pprevx, firstx, secondx;
  2054. X
  2055. X  /* var for max test */
  2056. X  long maxx;
  2057. X  /* var for median test */
  2058. X  long lowcount,median;
  2059. X  /* vars for mod 3 test */
  2060. X  long mod0, mod1;
  2061. X  /* data for equi-distribution test:
  2062. X   * freq[i] = sum_{1 \leq j \leq n} (x[j]==i), if testequidist == 1
  2063. X   * freq[i] = x[i], if testequidist == 3
  2064. X   * freq[i] = undefined, otherwise
  2065. X   */
  2066. X  long freq[EQUIDISTMAX];
  2067. X  /* data for 2-tuple test */
  2068. X  long pairs[PAIRMAXM][PAIRMAXM];
  2069. X  /* vars for 3-tuple test on low-order 3 bits */
  2070. X  long lowpairs[8][8];
  2071. X  long lowtrips[8][8][8];
  2072. X
  2073. X  if(argc > 1) {
  2074. X    for(i=1;i<argc;i++) {
  2075. X      if(argv[i][0] >= '0' && argv[i][0] <= '9') {
  2076. X    n = atol(&(argv[i][0]));
  2077. X    if (n < 0) {
  2078. X      printf("Illegal value, %ld, for number of random generates.\n",n);
  2079. X      argerr((char*) argv[0]);
  2080. X        }
  2081. X      } else if(argv[i][0] == '-') {
  2082. X    switch(argv[i][1]) {
  2083. X    case 'S': /* new seed(s) for rng */
  2084. X      seed1 = 1; /* defaults */
  2085. X      seed2 = 1;
  2086. X      count1 = 0;
  2087. X      count2 = 0;
  2088. X      sscanf (&(argv[i][2]), "%ld,%ld,%ld,%ld,%ld,&ld,&ld",
  2089. X         &alg, &seed1, &seed2, &count1, &count2);
  2090. X      seed[0]=seed1; seed[1]=seed2;
  2091. X      reseeding = 1;
  2092. X      if (seed1<0) {
  2093. X        printf("Illegal value, %ld, for RNG seed.\n",seed1);
  2094. X        argerr((char*) argv[0]);
  2095. X          }
  2096. X      if (seed2<0) {
  2097. X        printf("Illegal value, %ld, for second RNG seed.\n",seed2);
  2098. X        argerr((char*) argv[0]);
  2099. X          }
  2100. X      if (count1<0) {
  2101. X        printf("Illegal value, %ld, for number of times ");
  2102. X        printf(" to cycle rng before starting tests.\n",count1);
  2103. X        argerr((char*) argv[0]);
  2104. X          }
  2105. X      if (count2<0) {
  2106. X        printf("Illegal value, %ld, for number of billions of times ");
  2107. X        printf(" to cycle rng before starting tests.\n",count1);
  2108. X        argerr((char*) argv[0]);
  2109. X          }
  2110. X      break;
  2111. X    case 'd': /* adjust number of discards */
  2112. X      discards = atol(&(argv[i][2]));
  2113. X      if (discards < 0) {
  2114. X        printf("Illegal value, %ld, for number of discards.\n",discards);
  2115. X        argerr((char*) argv[0]);
  2116. X          }
  2117. X      break;
  2118. X    case 'm': /* adjust range of rng */
  2119. X      m = atol(&(argv[i][2]));
  2120. X      break;
  2121. X    case 'M': /* adjust log range of rng */
  2122. X      j = atol(&(argv[i][2]));
  2123. X      if (j<0 || j>31) {
  2124. X        printf("Illegal value, %ld, for log range of rng.\n",j);
  2125. X        argerr((char*) argv[0]);
  2126. X          }
  2127. X      if (j == 31) {
  2128. X        m = ~MAXLONG; /* note: m is an unsigned long */
  2129. X      }
  2130. X      else if (j==0) {
  2131. X        m = 0;
  2132. X      }
  2133. X      else {
  2134. X        m = (long)pow( 2.0, (double) j );
  2135. X      }
  2136. X      break;
  2137. X    case 'q': /* quiet! */
  2138. X      quiet = 1;
  2139. X      break;
  2140. X    case 't': /* strip testing code from inner loop, for timing */
  2141. X      timing = 1;
  2142. X      quiet = 1; /* -t implies -q */
  2143. X      break;
  2144. X    case 'e':
  2145. X      echo = 1; /* echo mrtest invocation */
  2146. X      break;
  2147. X# ifndef VECTOR
  2148. X    case 'v':
  2149. X      method = VECTORIZED;
  2150. X      break;
  2151. X    case 'f':
  2152. X      method = FAST;
  2153. X      break;
  2154. X    case 'p':
  2155. X      method = POOR;
  2156. X      break;
  2157. X# endif VECTOR
  2158. X    default:
  2159. X      argerr((char*) argv[0]);
  2160. X    }
  2161. X      } else {
  2162. X    argerr((char*) argv[0]);
  2163. X      }
  2164. X    }
  2165. X  }
  2166. X
  2167. X  if (echo) for (i=0; i<argc; i++) {
  2168. X    printf("%s ",argv[i]);
  2169. X  }
  2170. X  printf("\n");
  2171. X
  2172. X  dn = (double) n;
  2173. X
  2174. X  if (m > 0) {
  2175. X    dm = (double) m;
  2176. X  }
  2177. X  else if (m < 0) {
  2178. X    dm = (double)(m & 0x7fffffff) + 2147483648.0; /* 2^31 */
  2179. X  }
  2180. X  else {
  2181. X    dm = 4294967296.0; /* 2^32 */
  2182. X  }
  2183. X
  2184. X  if (!reseeding ) {
  2185. X    if (access(RNGFILENAME, R_OK)) {
  2186. X      printf("There is no RNG statefile in this directory, so ");
  2187. X      printf("I'll make one for you.\n");
  2188. X      reseeding = 1;
  2189. X    }
  2190. X  }
  2191. X
  2192. X  if (reseeding) { /* create a new statefile from scratch */
  2193. X    printf("Initializing RNG.\n");
  2194. X    myrng=init_rng(alg,mrandom_alg,seed,count1,count2,bufsize);
  2195. X  } else { /* use an existing statefile */
  2196. X    if (n != 0) printf("Restarting RNG.\n");
  2197. X    if (!(myrng=restart_rng(RNGFILENAME))) {
  2198. X      exit(1);
  2199. X    }
  2200. X  }
  2201. X  printf(describe_rng(myrng,rngdesc));
  2202. X
  2203. X  if (n == 0) {
  2204. X    if (reseeding) {
  2205. X      exit( save_rng(myrng,RNGFILENAME) ); /* save new rng, exit */
  2206. X    } else {
  2207. X      exit(0); /* immediate exit if n == 0 */
  2208. X    }
  2209. X  }
  2210. X
  2211. X  /* set flags: will we run the various tests? */
  2212. X  if (timing) { /* avoid time-consuming tests */
  2213. X    testequidist = 0;
  2214. X    test2tuples = 0;
  2215. X    test3tuples = 0;
  2216. X  } else {
  2217. X    if (m == ~MAXLONG) { /* special case for M==31 (m==2^31) */
  2218. X      testequidist = (n <= EQUIDISTMAX ? 3 : 0);
  2219. X      test2tuples = 0;
  2220. X      test3tuples=1;
  2221. X    } else {
  2222. X      testequidist = ( m <= EQUIDISTMAX ? 1 : (n <= EQUIDISTMAX ? 3 : 0));
  2223. X      test2tuples = ( m <= PAIRMAXM );
  2224. X      test3tuples = ( (m%8) == 0 );
  2225. X    }
  2226. X  }
  2227. X
  2228. X  /* initialize the various frequency-counting arrays, if needed */
  2229. X  if (testequidist==1) for (i=0; i<m; i++) freq[i] = 0;
  2230. X  if (test2tuples) for (i=0; i<m; i++) for (j=0; j<m; j++) pairs[i][j] = 0;
  2231. X  if (test3tuples) {
  2232. X    for (i=0; i<8; i++) {
  2233. X      for (j=0; j<8; j++) {
  2234. X    lowpairs[i][j] = 0;
  2235. X        for (k=0; k<8; k++) {
  2236. X      lowtrips[i][j][k] = 0;
  2237. X    }
  2238. X      }
  2239. X    }
  2240. X  }
  2241. X
  2242. X  /* initialize counter, threshhold for median test */
  2243. X  lowcount = 0;
  2244. X  median = ( (m == ~MAXLONG) ? 1<<30 : m/2 );
  2245. X
  2246. X  /* initialize counters for mod 3 test */
  2247. X  mod0 = 0;
  2248. X  mod1 = 0;
  2249. X
  2250. X  /* initialize storage for max test */
  2251. X  maxx = -1;
  2252. X
  2253. X  if (timing) discards=0; /* -d is meaningless with -t */
  2254. X
  2255. X  if (!quiet) {
  2256. X    printf("Here %s %ld random value", ((n == 1)? "is" : "are"), n);
  2257. X  } else {
  2258. X    printf("Generating %ld random value", n);
  2259. X  }
  2260. X  printf("%s", ((n == 1)? " " : "s "));
  2261. X  printf("in the range 0 to %ld\n", ((m == ~MAXLONG)? MAXLONG : m-1));
  2262. X
  2263. X  if (discards > 0) {
  2264. X    printf("Note: discards = %ld, so mrandom() will be called a",discards);
  2265. X    printf(" total of %.0f times.\n", (1.+(float)discards)*(float)n);
  2266. X  }
  2267. X
  2268. X
  2269. X  if (timing) {
  2270. X
  2271. X    /* vectorized inner loop */
  2272. X    for (i=0; i+VECLENGTH<n; i+=VECLENGTH) {
  2273. X      mrandomrv(myrng,m,VECLENGTH,rvals);
  2274. X      for (j=0; j<VECLENGTH; j++) {
  2275. X    /* Note: there are no subroutine calls in this loop! */
  2276. X    x = rvals[j];
  2277. X    if (x > maxx) maxx = x;
  2278. X      }
  2279. X    }
  2280. X    /* the last (partial) block, if any */
  2281. X    for ( ; i<n; i++) {
  2282. X      x = mrandomr(myrng,m);
  2283. X      if (x > maxx) maxx = x;
  2284. X    }
  2285. X
  2286. X  } else for (i=0; i<n; i++) { /* do lots of RNG tests */
  2287. X
  2288. X    x = random_value(myrng,m,method);
  2289. X    if ( (x >= m && m != ~MAXLONG) || x < 0) {
  2290. X      printf("Illegal output, %ld, from mrandom(%ld).\n",x,m);
  2291. X      printf("Please contact cthombor@mars.d.umn.edu.\n");
  2292. X      printf(describe_rng(myrng,rngdesc));
  2293. X      exit(1);
  2294. X    }
  2295. X
  2296. X    /* max test */
  2297. X    if (x > maxx) maxx = x;
  2298. X
  2299. X    /* count number of occurrences of each distinct output, if range is small,
  2300. X     * otherwise just keep track of outputs (we'll count freqs later)
  2301. X     */
  2302. X    if (testequidist==1) {
  2303. X      freq[x]++; 
  2304. X    } else if (testequidist==3) {
  2305. X      freq[i] = x;
  2306. X    }
  2307. X
  2308. X    /* count pairs */
  2309. X    if (i == 0) {
  2310. X      firstx = x; /* keep track of first generate for "circular" pairs count */
  2311. X    } else {
  2312. X      if (test2tuples) {
  2313. X    pairs[x][prevx]++;
  2314. X    if (i == n-1) pairs[firstx][x]++; /* handle the "wraparound pair" */
  2315. X      }
  2316. X      if (test3tuples) {
  2317. X    lowpairs[x&7][prevx&7]++;
  2318. X    if (i == n-1) pairs[firstx&7][x&7]++; /* handle the "wraparound pair" */
  2319. X      }
  2320. X    }
  2321. X
  2322. X    /* count triples */
  2323. X    if (i == 1) {
  2324. X      secondx = x; /* needed for the last "wraparound triplet" */
  2325. X    }
  2326. X    if (i > 1) {
  2327. X      if (test3tuples) {
  2328. X    lowtrips[x&7][prevx&7][pprevx&7]++;
  2329. X    if (i == n-1) { /* time to do the wraparound triplets? */
  2330. X      lowtrips[firstx&7][x&7][prevx&7]++;
  2331. X      lowtrips[secondx&7][firstx&7][x&7]++;
  2332. X    }
  2333. X      }
  2334. X    }
  2335. X
  2336. X    /* count number below median */
  2337. X    if (x < median) lowcount++;
  2338. X
  2339. X    /* count number ==0 and ==1, mod 3 */
  2340. X    j = x%3;
  2341. X    if (j==0) {
  2342. X      mod0++;
  2343. X    } else if (j==1) {
  2344. X      mod1++;
  2345. X    }
  2346. X
  2347. X    /* keep track of previous two generates, for pair and triple counts */
  2348. X    pprevx = prevx;
  2349. X    prevx = x;
  2350. X
  2351. X    /* use fixed-width format, to make it easy to sort the output */
  2352. X    if (!quiet) {
  2353. X      if (m < 0 && x < 0) { /* print an unsigned long */
  2354. X        printf("  %.0f\n", (double)(x&MAXLONG)+(double)MAXLONG+1.0);
  2355. X      } else if (m <= 10) {
  2356. X        printf("  %d\n", x);
  2357. X      } else if (m <= 100) {
  2358. X        printf("  %2d\n", x);
  2359. X      } else if (m <= 1000) {
  2360. X        printf("  %3d\n", x);
  2361. X      } else {
  2362. X        printf("  %4d\n", x);
  2363. X      }
  2364. X    }
  2365. X    /* now discard some generates: d=2^k, k>9, gives nrand48() trouble */ 
  2366. X    for (j=0; j<discards; j++) {
  2367. X      /* note: we don't even check whether x is in range */
  2368. X      x = random_value(myrng,m,method);
  2369. X    }
  2370. X  }
  2371. X
  2372. X  printf("Max value from %ld call%s", n, (n==1? "" : "s"));
  2373. X  if (discards) printf(" (discards = %ld)",discards);
  2374. X  printf(" to mrandom(%ld) = %ld\n",m,maxx);
  2375. X  if ( (maxx >= m && m != ~MAXLONG) || maxx < 0) {
  2376. X    printf("Illegal value for max!\n");
  2377. X    printf("Please contact cthombor@mars.d.umn.edu.\n");
  2378. X    printf(describe_rng(myrng,rngdesc));
  2379. X    exit(1);
  2380. X  }
  2381. X
  2382. X  if (!timing && n>2) {
  2383. X    printf("Equi-distribution test results:\n");
  2384. X    if (testequidist == 0) {
  2385. X      printf("  Range m and/or number of random generates n is too large.\n");
  2386. X      printf("  Max(m,n) for this test is %d.\n", EQUIDISTMAX);
  2387. X    } else if (m == 1) {
  2388. X      printf("  You need m > 1 for this test.\n");
  2389. X    } else {
  2390. X      sumfsq = 0.0;
  2391. X      expf = dn/dm; /* expected freq[] */
  2392. X      if (testequidist == 1) { /* freq[] array has frequencies */
  2393. X        sumf = 0; /* error check: is ((sumf = \sum_i{freq[i]}) == n)? */
  2394. X        for (i=0; i<m; i++) {
  2395. X      sumf += freq[i];
  2396. X          f = ((double)freq[i]) - expf;
  2397. X          sumfsq += f*f;
  2398. X        }
  2399. X        if (sumf != n) {
  2400. X      printf("Warning: a frequency counter has overflowed.");
  2401. X      printf("  Test invalid!\n");
  2402. X      goto testinvalid;
  2403. X        }
  2404. X      } else if (testequidist == 3) { 
  2405. X    /* freq[] array has the random generates: sort, count dups */
  2406. X        qsort(freq,n,sizeof(long),comparelongs);
  2407. X    f = 1.0;
  2408. X    zerofreqs = dm; /* number of integers NOT seen in RNG output */ 
  2409. X    for (i=0; i<n; i++) {
  2410. X      if (i == (n-1) || freq[i] != freq[i+1]) {
  2411. X        sumfsq += (f-expf)*(f-expf); /* end of one run of duplicates... */
  2412. X        zerofreqs -= 1.0;
  2413. X        f = 1.0; /* ...and the beginning of another run */
  2414. X      } else {
  2415. X        f += 1.0; /* a "match" extends a run */
  2416. X      }
  2417. X    }
  2418. X    /* add contributions from zero-frequency outputs */
  2419. X    sumfsq += zerofreqs*(-expf)*(-expf);
  2420. X      }
  2421. X      /* Note: many texts suggest summing t += freq[i]^2, then calculating
  2422. X       * xsq by (dm*t/dn)-dn.  This is slightly faster, but MUCH less
  2423. X       * accurate when dn is much larger (e.g. 2^20 times larger) than dm.
  2424. X       */
  2425. X      xsq = sumfsq/expf;
  2426. X      interpret_xsq(xsq, dm, dn);
  2427. X      /* End of equi-distribution test code */
  2428. X  
  2429. X      printf("Pairwise correlation test results:\n");
  2430. X      if (!test2tuples) {
  2431. X        printf("  Range is too large.  Max m for this test is %d.\n", PAIRMAXM);
  2432. X      } else {
  2433. X        sumfsq = 0.0;
  2434. X        expf = dn/(dm*dm); /* expected freq[] */
  2435. X        for (i=0; i<m; i++) for (j=0; j<m; j++) {
  2436. X      f = (double)pairs[i][j] - expf;
  2437. X          sumfsq += f*f;
  2438. X        }
  2439. X        xsq2 = sumfsq/expf;
  2440. X    /* note that we use the xsq from the equi-distribution test */
  2441. X        interpret_xsq(xsq2-xsq, dm*dm-dm+1.0, dn);
  2442. X      } /* end of pairwise correlation test code */
  2443. X    }
  2444. X  
  2445. X    printf("3-tuple, low-order 3 bits, correlation test results:\n");
  2446. X    if (!test3tuples) {
  2447. X      printf("  You need (m mod 8) == 0 for this test.\n");
  2448. X    } else {
  2449. X      sumfsq = 0.0;
  2450. X      expf = dn/64.0; /* expected freq in each bin */
  2451. X      for (i=0; i<8; i++) {
  2452. X        for (j=0; j<8; j++) {
  2453. X          f = (double)lowpairs[i][j] - expf;
  2454. X          sumfsq += f*f;
  2455. X        }
  2456. X      }
  2457. X      xsq2l = sumfsq/expf;
  2458. X      sumfsq = 0.0;
  2459. X      expf = dn/512.0; /* expected freq in each bin */
  2460. X      for (i=0; i<8; i++) {
  2461. X        for (j=0; j<8; j++) {
  2462. X      for (k=0; k<8; k++) {
  2463. X            f = (double)lowtrips[i][j][k] - expf;
  2464. X            sumfsq += f*f;
  2465. X      }
  2466. X        }
  2467. X      }
  2468. X      xsq3l = sumfsq/expf;
  2469. X      interpret_xsq(xsq3l-xsq2l, 8.0*8.0*8.0-8.0*8.0+1.0, dn);
  2470. X    } /* end of 3-tuple test code */
  2471. X  
  2472. X    printf("Most-significant bit test results:\n");
  2473. X    f = (double)lowcount; /* freq below m/2 */
  2474. X    expf = dn*(floor(dm/2.))/dm; /* expected val of f */
  2475. X    sumfsq = ((f-expf)*(f-expf))/expf; /* normalized dev^2 from expectation */
  2476. X    f = dn-f; /* freq at or above m/2 */
  2477. X    expf = dn-expf;
  2478. X    sumfsq += (f-expf)*(f-expf)/expf;
  2479. X    interpret_xsq(sumfsq,2.0,dn);
  2480. X    /* end of MSB test code */
  2481. X
  2482. X    printf("Mod-3 test results:\n");
  2483. X    /* We need the freq[] to be reasonably equal for xsq analysis */
  2484. X    if (!(m == 3 || m > 5 || m == ~MAXLONG)) {
  2485. X      printf("  You need m==3 or m>5 to run this test.\n");
  2486. X    } else {
  2487. X      f = (double)mod0; /* freq of x==0 mod 3 */
  2488. X      expf = dn*(ceil(dm/3.))/dm;
  2489. X      sumfsq = ((f-expf)*(f-expf))/expf;
  2490. X      f = (double)mod1; /* freq of x==1 mod 3 */
  2491. X      expf = dn*(ceil(2.*dm/3.))/dm - expf;
  2492. X      sumfsq += (f-expf)*(f-expf)/expf;
  2493. X      f = dn-f-(double)mod0; /* freq of x==2 mod 3 */
  2494. X      expf = dn-dn*(ceil(2.*dm/3.))/dm;
  2495. X      sumfsq += (f-expf)*(f-expf)/expf;
  2496. X      interpret_xsq(sumfsq,3.0,dn);
  2497. X    } /* end of mod-3 test code */
  2498. X  } else if (n < 3) {
  2499. X    printf("At least 3 random generates are required for the testing module.\n"
  2500. X      );
  2501. X  }
  2502. Xtestinvalid:
  2503. X  /* terminate job */
  2504. X  printf("Final ");
  2505. X  printf(describe_rng(myrng,rngdesc));
  2506. X
  2507. X  return( save_rng(myrng,RNGFILENAME) );
  2508. X
  2509. X} /* end main */
  2510. END_OF_FILE
  2511. if test 21361 -ne `wc -c <'src/mrtest.c'`; then
  2512.     echo shar: \"'src/mrtest.c'\" unpacked with wrong size!
  2513. fi
  2514. # end of 'src/mrtest.c'
  2515. fi
  2516. echo shar: End of archive 2 \(of 6\).
  2517. cp /dev/null ark2isdone
  2518. MISSING=""
  2519. for I in 1 2 3 4 5 6 ; do
  2520.     if test ! -f ark${I}isdone ; then
  2521.     MISSING="${MISSING} ${I}"
  2522.     fi
  2523. done
  2524. if test "${MISSING}" = "" ; then
  2525.     echo You have unpacked all 6 archives.
  2526.     rm -f ark[1-9]isdone
  2527. else
  2528.     echo You still need to unpack the following archives:
  2529.     echo "        " ${MISSING}
  2530. fi
  2531. ##  End of shell archive.
  2532. exit 0
  2533.