| 1 | <html> |
|---|
| 2 | <head> |
|---|
| 3 | <title>A Proposal to Add an Extensible Random Number Facility to the Standard Library</title> |
|---|
| 4 | <meta Author="Jens Maurer" content="proposal"> |
|---|
| 5 | </head> |
|---|
| 6 | |
|---|
| 7 | <body bgcolor="#FFFFFF" text="#000000"> |
|---|
| 8 | |
|---|
| 9 | <font size=-1> |
|---|
| 10 | Jens Maurer <Jens.Maurer@gmx.net> |
|---|
| 11 | <br> |
|---|
| 12 | 2002-11-10 |
|---|
| 13 | <br> |
|---|
| 14 | Document N1398=02-0056 |
|---|
| 15 | <p> |
|---|
| 16 | <code>$Id: proposal.html,v 1.44 2002/11/10 20:42:15 jmaurer Exp $</code> |
|---|
| 17 | </font> |
|---|
| 18 | |
|---|
| 19 | <h1>A Proposal to Add an Extensible Random Number Facility to the |
|---|
| 20 | Standard Library (N1398)</h1> |
|---|
| 21 | |
|---|
| 22 | <blockquote> |
|---|
| 23 | Any one who considers arithmetical methods of producing random digits |
|---|
| 24 | is, of course, in a state of sin. |
|---|
| 25 | </blockquote> |
|---|
| 26 | <p align="right"> |
|---|
| 27 | John von Neumann, 1951 |
|---|
| 28 | </p> |
|---|
| 29 | |
|---|
| 30 | <h2>Revision history</h2> |
|---|
| 31 | |
|---|
| 32 | <ul> |
|---|
| 33 | <li>2002-11-10: Publication in the Post-Santa Cruz mailing. |
|---|
| 34 | <li>The <code>seed(first, last)</code> interface now needs "unsigned |
|---|
| 35 | long" values. |
|---|
| 36 | <li>Introduce "variate_generator", adjust distribution interface |
|---|
| 37 | accordingly. |
|---|
| 38 | <li>Add "add-on packages" discussion. |
|---|
| 39 | <li>All distribution parameters must be defaulted. |
|---|
| 40 | <li>Add "target audience" subsection to "motivation" section. |
|---|
| 41 | <li>Add discussion of manager class. |
|---|
| 42 | <li>Engines are independent of distributions, thus consider respective |
|---|
| 43 | lifetimes. |
|---|
| 44 | <li>Add "sharing of engines" as a major requirement. |
|---|
| 45 | <li>Add some open issues. |
|---|
| 46 | <li>2002-10-11: First publication on the C++ committee's library reflector. |
|---|
| 47 | </ul> |
|---|
| 48 | |
|---|
| 49 | |
|---|
| 50 | <h2>I. Motivation</h2> |
|---|
| 51 | |
|---|
| 52 | <blockquote><i>Why is this important? What kinds of problems does it |
|---|
| 53 | address, and what kinds of programmers, is it intended to support? Is |
|---|
| 54 | it based on existing practice?</i></blockquote> |
|---|
| 55 | |
|---|
| 56 | Computers are deterministic machines by design: equal input data |
|---|
| 57 | results in equal output, given the same internal state. Sometimes, |
|---|
| 58 | applications require seemingly non-deterministic behaviour, usually |
|---|
| 59 | provided by generating random numbers. Such applications include: |
|---|
| 60 | <ul> |
|---|
| 61 | <li>numerics (simulation, Monte-Carlo integration) |
|---|
| 62 | <li>games (shuffling card decks, non-deterministic enemy behavior) |
|---|
| 63 | <li>testing (generation of test input data for good coverage) |
|---|
| 64 | <li>security (generation of cryptographic keys) |
|---|
| 65 | </ul> |
|---|
| 66 | <p> |
|---|
| 67 | |
|---|
| 68 | Programmers in all of the above areas have to find ways to generate |
|---|
| 69 | random numbers. However, the difficulty to find generators that are |
|---|
| 70 | both efficient and have good quality is often underestimated, and so |
|---|
| 71 | ad-hoc implementations often fail to meet either or both of these |
|---|
| 72 | goals. |
|---|
| 73 | <p> |
|---|
| 74 | |
|---|
| 75 | The C++ standard library includes <code>std::rand</code>, inherited |
|---|
| 76 | from the C standard library, as the only facility to generate |
|---|
| 77 | pseudo-random numbers. It is underspecified, because the generation |
|---|
| 78 | function is not defined, and indeed early C standard library |
|---|
| 79 | implementations provided surprisingly bad generators. Furthermore, |
|---|
| 80 | the interface relies on global state, making it difficult or |
|---|
| 81 | inefficient to provide for correct operation for simultaneous |
|---|
| 82 | invocations in multi-threaded applications. |
|---|
| 83 | <p> |
|---|
| 84 | |
|---|
| 85 | There is a lot of existing practice in this area. A multitude of |
|---|
| 86 | libraries, usually implemented in C or Fortran, is available from the |
|---|
| 87 | scientific community. Some implement just one random number |
|---|
| 88 | engine, others seek to provide a full framework. I know of no |
|---|
| 89 | comprehensive C++ framework for generating random numbers that adheres |
|---|
| 90 | to the design principles put forth in section III. |
|---|
| 91 | <p> |
|---|
| 92 | |
|---|
| 93 | Random number generators are appropriate for this TR because they fall |
|---|
| 94 | into one of the domains (numerics) identified in N1314 as a target for |
|---|
| 95 | the TR. |
|---|
| 96 | |
|---|
| 97 | |
|---|
| 98 | <h3>Target Audience</h3> |
|---|
| 99 | |
|---|
| 100 | There are several different kinds of programmers that are assumed to use |
|---|
| 101 | the facilities provided in this proposal. |
|---|
| 102 | |
|---|
| 103 | <ul> |
|---|
| 104 | <li>programmers that provide additional engines |
|---|
| 105 | <li>programmers that provide additional distributions |
|---|
| 106 | <li>programmers that provide generic add-on packages |
|---|
| 107 | <li>programmers that need random numbers |
|---|
| 108 | </ul> |
|---|
| 109 | |
|---|
| 110 | This proposal specifies an infrastructure so that the needs of all |
|---|
| 111 | four groups are met. The first two groups benefit from a modular |
|---|
| 112 | design so that they can plug in their contributions. Providing add-on |
|---|
| 113 | packages benefits from a design that suits to generic programming |
|---|
| 114 | needs. Finally, users in need of random numbers benefit from an |
|---|
| 115 | interface to the package that is easy to use. |
|---|
| 116 | |
|---|
| 117 | |
|---|
| 118 | <h2>II. Impact On the Standard</h2> |
|---|
| 119 | |
|---|
| 120 | <blockquote><i>What does it depend on, and what depends on it? Is it |
|---|
| 121 | a pure extension, or does it require changes to standard components? |
|---|
| 122 | Does it require core language changes?</i></blockquote> |
|---|
| 123 | |
|---|
| 124 | This proposal is a pure library extension. It does not require |
|---|
| 125 | changes to any standard classes or functions. It does not require |
|---|
| 126 | changes to any of the standard requirement tables. It does not |
|---|
| 127 | require any changes in the core language, and it has been implemented |
|---|
| 128 | in standard C++ as per ISO 14882:1998. |
|---|
| 129 | <p> |
|---|
| 130 | |
|---|
| 131 | The ISO C99 extension that specify integral types having a given |
|---|
| 132 | minimum or exact bitwidth (e.g. <code>int32_t</code>) aids in |
|---|
| 133 | implementing this proposal, however these types (or the equivalent |
|---|
| 134 | thereof under another name) can be defined with template |
|---|
| 135 | metaprogramming in standard C++, so these are not strictly necessary. |
|---|
| 136 | <p> |
|---|
| 137 | |
|---|
| 138 | In case the ISO C99 extensions become part of the TR, section IV should |
|---|
| 139 | be reviewed whether some requirements could be reformulated with the |
|---|
| 140 | ISO C99 extensions. |
|---|
| 141 | <p> |
|---|
| 142 | |
|---|
| 143 | In case a standard reference-counted smart pointer becomes part of |
|---|
| 144 | the TR, section IV should be reviewed and instances of the smart |
|---|
| 145 | pointer be added to the acceptable template parameters for a |
|---|
| 146 | <code>variate_generator</code>. |
|---|
| 147 | |
|---|
| 148 | |
|---|
| 149 | <h2>III. Design Decisions</h2> |
|---|
| 150 | |
|---|
| 151 | <blockquote><i>Why did you choose the specific design that you did? |
|---|
| 152 | What alternatives did you consider, and what are the tradeoffs? What |
|---|
| 153 | are the consequences of your choice, for users and implementors? What |
|---|
| 154 | decisions are left up to implementors? If there are any similar |
|---|
| 155 | libraries in use, how do their design decisions compare to yours? |
|---|
| 156 | </i></blockquote> |
|---|
| 157 | |
|---|
| 158 | |
|---|
| 159 | The design decisions are compared to those in the following libraries: |
|---|
| 160 | <ul> |
|---|
| 161 | <li>CLHEP (original at |
|---|
| 162 | http://wwwinfo.cern.ch/asd/lhc++/clhep/index.html, modifications from |
|---|
| 163 | FermiLab at (anonymous CVS) |
|---|
| 164 | :pserver:anonymous@zoomcvs.fnal.gov:/usr/people/cvsuser/repository) |
|---|
| 165 | </li> |
|---|
| 166 | |
|---|
| 167 | <li>crng 1.1: Random-number generators (RNGs) implemented as Python |
|---|
| 168 | extension types coded in C (at http://www.sbc.su.se/~per/crng/) |
|---|
| 169 | </li> |
|---|
| 170 | |
|---|
| 171 | <li>Swarm 2.1.1 (multi-agent simulation of complex systems), random |
|---|
| 172 | number package, using a Smalltalk-like programming language (at |
|---|
| 173 | http://www.santafe.edu/projects/swarm/swarmdocs/set/swarm.random.sgml.reference.html) |
|---|
| 174 | </li> |
|---|
| 175 | |
|---|
| 176 | <li>GNU Scientific Library: general scientific computing library |
|---|
| 177 | implemented in C, comprehensive coverage of random number engines and |
|---|
| 178 | distributions (at http://sources.redhat.com/gsl) |
|---|
| 179 | |
|---|
| 180 | </ul> |
|---|
| 181 | |
|---|
| 182 | |
|---|
| 183 | The choice of engines and distributions is also contrasted against the |
|---|
| 184 | following literature: |
|---|
| 185 | |
|---|
| 186 | <ul> |
|---|
| 187 | <li>Donald E. Knuth, "The Art of Computer Programming Vol. 2" |
|---|
| 188 | </li> |
|---|
| 189 | |
|---|
| 190 | <li>William H. Press et al., "Numerical Recipes in C" |
|---|
| 191 | </li> |
|---|
| 192 | |
|---|
| 193 | </ul> |
|---|
| 194 | |
|---|
| 195 | |
|---|
| 196 | <h3>A. Overview on Requirements</h3> |
|---|
| 197 | |
|---|
| 198 | Here is a short overview on the requirements for the random number |
|---|
| 199 | framework. |
|---|
| 200 | |
|---|
| 201 | <ul> |
|---|
| 202 | <li>allows users to choose in speed / size / quality trade-offs |
|---|
| 203 | <li>has a tight enough specification to get reliable cross-platform |
|---|
| 204 | results |
|---|
| 205 | <li>allows storage of state on non-volatile media (e.g., in a disk |
|---|
| 206 | file) to resume computation later |
|---|
| 207 | <li>does not impede sequence "jump-ahead" for parallel computation |
|---|
| 208 | <li>provides a variety of base engines, not just one |
|---|
| 209 | <li>allows the user to write its own base engines and use it with the |
|---|
| 210 | library-provided distributions |
|---|
| 211 | <li>provides the most popular distributions |
|---|
| 212 | <li>allows the user to write its own distributions and use it with the |
|---|
| 213 | library-provided engines |
|---|
| 214 | <li>allows sharing of engines by several distributions |
|---|
| 215 | <li>does not prevent implementations with utmost efficiency |
|---|
| 216 | <li>provides both pseudo-random number engines (for simulations etc.) |
|---|
| 217 | and "true" non-deterministic random numbers (for cryptography) |
|---|
| 218 | </ul> |
|---|
| 219 | |
|---|
| 220 | All of the requirements are revisited in detail in the following |
|---|
| 221 | sections. |
|---|
| 222 | |
|---|
| 223 | |
|---|
| 224 | <h3>B. Pseudo-Random vs. Non-Deterministic Random Numbers</h3> |
|---|
| 225 | |
|---|
| 226 | This section tries to avoid philosophical discussions about randomness |
|---|
| 227 | as much as possible, a certain amount of intuition is assumed. |
|---|
| 228 | <p> |
|---|
| 229 | |
|---|
| 230 | In this proposal, a <em>pseudo-random number engine</em> is defined as |
|---|
| 231 | an initial internal state x(0), a function f that |
|---|
| 232 | moves from one internal state to the next x(i+1) := f(x(i)), and an |
|---|
| 233 | output function o that produces the output o(x(i)) of the generator. |
|---|
| 234 | This is an entirely deterministic process, it is determined by the |
|---|
| 235 | initial state x(0) and functions f and o only. |
|---|
| 236 | The initial state x(0) is determined from a seed. Apparent randomness |
|---|
| 237 | is achieved only because the user has limited perception. |
|---|
| 238 | <p> |
|---|
| 239 | |
|---|
| 240 | A <em>non-deterministic random-number engine</em> provides a |
|---|
| 241 | sequence of random numbers x(i) that cannot be foreseen. Examples are |
|---|
| 242 | certain quantum-level physics experiments, measuring the time |
|---|
| 243 | difference between radioactive decay of individual atoms or noise of a |
|---|
| 244 | Zehner diode. Relatively unforeseeable random sources are also (the |
|---|
| 245 | low bits of) timing between key touches, mouse movements, Ethernet |
|---|
| 246 | packet arrivals, etc. An estimate for the amount of |
|---|
| 247 | unforeseeability is the entropy, a concept from information theory. |
|---|
| 248 | Completely foreseeable sequences (e.g., from pseudo-random number |
|---|
| 249 | engines) have entropy 0, if all bits are unforeseeable, the entropy is |
|---|
| 250 | equal to the number of bits in each number. |
|---|
| 251 | <p> |
|---|
| 252 | |
|---|
| 253 | Pseudo-random number engines are usually much faster than |
|---|
| 254 | non-deterministic random-number engines, because the latter require |
|---|
| 255 | I/O to query some randomness device outside of the computer. However, |
|---|
| 256 | there is a common interface feature subset of both pseudo-random and |
|---|
| 257 | non-deterministic random-number engines. For example, a |
|---|
| 258 | non-deterministic random-number engine could be employed to produce |
|---|
| 259 | random numbers with normal distribution; I believe this to be an |
|---|
| 260 | unlikely scenario in practice. |
|---|
| 261 | <p> |
|---|
| 262 | |
|---|
| 263 | Other libraries, including those mentioned above, only provide |
|---|
| 264 | either pseudo-random numbers, suitable for simulations and games, or |
|---|
| 265 | non-deterministic random numbers, suitable for cryptographic |
|---|
| 266 | applications. |
|---|
| 267 | |
|---|
| 268 | |
|---|
| 269 | |
|---|
| 270 | <h3>C. Separation of Engines and Distributions</h3> |
|---|
| 271 | |
|---|
| 272 | Random-number generation is usually conceptually separated into |
|---|
| 273 | <em>random-number engines</em> that produce uniformly distributed |
|---|
| 274 | random numbers between a given minimum and maximum and |
|---|
| 275 | <em>random-number distributions</em> that retrieve uniformly |
|---|
| 276 | distributed random numbers from some engine and produce numbers |
|---|
| 277 | according to some distribution (e.g., Gaussian normal or Bernoulli |
|---|
| 278 | distribution). |
|---|
| 279 | Returning to the formalism from section A, the former can be identified |
|---|
| 280 | with the function f and the latter with the output function o. |
|---|
| 281 | <p> |
|---|
| 282 | |
|---|
| 283 | This proposal honours this conceptual separation, and provides a class |
|---|
| 284 | template to merge an arbitrary engine with an arbitrary distribution |
|---|
| 285 | on top. To this end, this proposal sets up requirements for |
|---|
| 286 | engines so that each of them can be used to provide uniformly |
|---|
| 287 | distributed random numbers for any of the distributions. The |
|---|
| 288 | resulting freedom of combination allows for the utmost re-use. |
|---|
| 289 | <p> |
|---|
| 290 | |
|---|
| 291 | Engines have usually been analyzed with all mathematical and empirical |
|---|
| 292 | tools currently available. Nonetheless, those tools show the absence |
|---|
| 293 | of a particular weakness only, and are not exhaustive. Albeit |
|---|
| 294 | unlikely, a new kind of test (for example, a use of random numbers in |
|---|
| 295 | a new kind of simulation or game) could show serious weaknesses in |
|---|
| 296 | some engines that were not known before. |
|---|
| 297 | <p> |
|---|
| 298 | |
|---|
| 299 | This proposal attempts to specify the engines precisely; two different |
|---|
| 300 | implementations, with the same seed, should return the same output |
|---|
| 301 | sequence. This forces implementations to use the well-researched |
|---|
| 302 | engines specified hereinafter, and users can have confidence in their |
|---|
| 303 | quality and the limits thereof. |
|---|
| 304 | <p> |
|---|
| 305 | |
|---|
| 306 | On the other hand, the specifications for the distributions only |
|---|
| 307 | define the statistical result, not the precise algorithm to use. This |
|---|
| 308 | is different from engines, because for distribution algorithms, |
|---|
| 309 | rigorous proofs of their correctness are available, usually under the |
|---|
| 310 | precondition that the input random numbers are (truely) uniformly |
|---|
| 311 | distributed. For example, there are at least a handful of algorithms |
|---|
| 312 | known to produce normally distributed random numbers from uniformly |
|---|
| 313 | distributed ones. Which one of these is most efficient depends on at |
|---|
| 314 | least the relative execution speeds for various transcendental |
|---|
| 315 | functions, cache and branch prediction behaviour of the CPU, and |
|---|
| 316 | desired memory use. This proposal therefore leaves the choice of the |
|---|
| 317 | algorithm to the implementation. It follows that output sequences for |
|---|
| 318 | the distributions will not be identical across implementations. It is |
|---|
| 319 | expected that implementations will carefully choose the algorithms for |
|---|
| 320 | distributions up front, since it is certainly surprising to customers |
|---|
| 321 | if some distribution produces different numbers from one |
|---|
| 322 | implementation version to the next. |
|---|
| 323 | <p> |
|---|
| 324 | |
|---|
| 325 | Other libraries usually provide the same differentiation between |
|---|
| 326 | engines and distributions. Libraries rarely have a wrapper around |
|---|
| 327 | both engine and distribution, but it turns out that this can hide some |
|---|
| 328 | complexities from the authors of distributions, since some facitilies |
|---|
| 329 | need to be provided only once. A previous version of this proposal |
|---|
| 330 | had distributions directly exposed to the user, and the distribution |
|---|
| 331 | type dependent on the engine type. In various discussions, this was |
|---|
| 332 | considered as too much coupling. |
|---|
| 333 | <p> |
|---|
| 334 | |
|---|
| 335 | Since other libraries do not aim to provide a portable specification |
|---|
| 336 | framework, engines are sometimes only described qualitatively without |
|---|
| 337 | giving the exact parameterization. Also, distributions are given as |
|---|
| 338 | specific functions or classes, so the quality-of-implementation |
|---|
| 339 | question which distribution algorithm to employ does not need to be |
|---|
| 340 | addressed. |
|---|
| 341 | |
|---|
| 342 | |
|---|
| 343 | <h3>D. Templates vs. Virtual Functions</h3> |
|---|
| 344 | |
|---|
| 345 | The layering sketched in the previous subsection can be implemented by |
|---|
| 346 | either a template mechanism or by using virtual functions in a class |
|---|
| 347 | hierarchy. This proposal uses templates. Template parameters are |
|---|
| 348 | usually some base type and values denoting fixed parameters for the |
|---|
| 349 | functions f and o, e.g. a word size or modulus. |
|---|
| 350 | <p> |
|---|
| 351 | |
|---|
| 352 | For virtual functions in a class hierarchy, the core language requires |
|---|
| 353 | a (nearly) exact type match for a function in a derived classes |
|---|
| 354 | overriding a function in a base class. This seems to be unnecessarily |
|---|
| 355 | restrictive, because engines can sometimes benefit from using |
|---|
| 356 | different integral base types. Also, with |
|---|
| 357 | current compiler technology, virtual functions prevent inlining when a |
|---|
| 358 | pointer to the base class is used to call a virtual function that is |
|---|
| 359 | overridden in some derived class. In particular with applications |
|---|
| 360 | such as simulations that sometimes use millions of pseudo-random |
|---|
| 361 | numbers per second, losing significant amounts of performance due to |
|---|
| 362 | missed inlining opportunities appears to not be acceptable. |
|---|
| 363 | <p> |
|---|
| 364 | |
|---|
| 365 | The CLHEP library bases all its engines on the abstract base class |
|---|
| 366 | <code>HepRandomEngine</code>. Specific engines derive from this class |
|---|
| 367 | and override its pure virtual functions. Similarly, all |
|---|
| 368 | distributions are based on the base class <code>HepRandom</code>. |
|---|
| 369 | Specific distributions derive from this class, override operator(), |
|---|
| 370 | and provide a number of specific non-virtual functions. |
|---|
| 371 | <p> |
|---|
| 372 | |
|---|
| 373 | The GNU Scientific Library, while coded in C, adheres to the |
|---|
| 374 | principles of object-structuring; all engines can be used with any of |
|---|
| 375 | the distributions. The technical implementation is by mechanisms |
|---|
| 376 | similar to virtual functions. |
|---|
| 377 | |
|---|
| 378 | |
|---|
| 379 | <h3>E. Parameterization and Initialization for Engines</h3> |
|---|
| 380 | |
|---|
| 381 | Engines usually have a "base" type which is used to store its internal |
|---|
| 382 | state. Also, they usually have a choice of parameters. For example, |
|---|
| 383 | a linear congruential engine is defined by x(i+1) = (a*x(i)+c) mod m, |
|---|
| 384 | so f(x) = (a*x+c) mod m; the base type is "int" and parameters are a, |
|---|
| 385 | c, and m. Finding parameters for a given function f that make for |
|---|
| 386 | good randomness in the resulting engine's generated numbers x(i) |
|---|
| 387 | requires extensive and specialized mathematical training and |
|---|
| 388 | experience. In order to make good random numbers available to a large |
|---|
| 389 | number of library users, this proposal not only defines generic |
|---|
| 390 | random-number engines, but also provides a number of predefined |
|---|
| 391 | well-known good parameterizations for those. Usually, there are only |
|---|
| 392 | a few (less than five) well-known good parameterizations for each |
|---|
| 393 | engine, so it appears feasible to provide these. |
|---|
| 394 | <p> |
|---|
| 395 | |
|---|
| 396 | Since random-number engines are mathematically designed with computer |
|---|
| 397 | implementation in mind, parameters are usually integers representable |
|---|
| 398 | in a machine word, which usually coincides nicely with a C++ built-in |
|---|
| 399 | type. The parameters could either be given as (compile-time) template |
|---|
| 400 | arguments or as (run-time) constructor arguments. |
|---|
| 401 | <p> |
|---|
| 402 | |
|---|
| 403 | Providing parameters as template arguments allows for providing |
|---|
| 404 | predefined parameterizations as simple "typedef"s. Furthermore, the |
|---|
| 405 | parameters appear as integral constants, so the compiler can |
|---|
| 406 | value-check the given constants against the engine's base type. Also, |
|---|
| 407 | the library implementor can choose different implementations depending |
|---|
| 408 | on the values of the parameters, without incurring any runtime |
|---|
| 409 | overhead. For example, there is an efficient method to compute (a*x) |
|---|
| 410 | mod m, provided that a certain magnitude of m relative to the |
|---|
| 411 | underlying type is not exceeded. Additionally, the compiler's |
|---|
| 412 | optimizer can benefit from the constants and potentially produce |
|---|
| 413 | better code, for example by unrolling loops with fixed loop count. |
|---|
| 414 | <p> |
|---|
| 415 | |
|---|
| 416 | As an alternative, providing parameters as constructor arguments |
|---|
| 417 | allows for more flexibility for the library user, for example when |
|---|
| 418 | experimenting with several parameterizations. Predefined |
|---|
| 419 | parameterizations can be provided by defining wrapper types which |
|---|
| 420 | default the constructor parameters. |
|---|
| 421 | <p> |
|---|
| 422 | |
|---|
| 423 | Other libraries have hard-coded the parameters of their engines and do |
|---|
| 424 | not allow the user any configuration of them at all. If the user |
|---|
| 425 | wishes to change the parameters, he has to re-implement the engine's |
|---|
| 426 | algorithm. In my opinion, this approach unnecessarily restricts |
|---|
| 427 | re-use. |
|---|
| 428 | <p> |
|---|
| 429 | |
|---|
| 430 | Regarding initialization, this proposal chooses to provide |
|---|
| 431 | "deterministic seeding" with the default constructor and the |
|---|
| 432 | <code>seed</code> function without parameters: Two engines constructed |
|---|
| 433 | using the default constructor will output the same sequence. In |
|---|
| 434 | contrast, the CLHEP library's default constructed engines will take a |
|---|
| 435 | fresh seed from a seed table for each instance. While this approach |
|---|
| 436 | may be convenient for a certain group of users, it relies on global |
|---|
| 437 | state and can easily be emulated by appropriately wrapping engines |
|---|
| 438 | with deterministic seeding. |
|---|
| 439 | <p> |
|---|
| 440 | |
|---|
| 441 | In addition to the default constructor, all engines provide a |
|---|
| 442 | constructor and <code>seed</code> function taking an iterator range |
|---|
| 443 | [it1,it2) pointing to unsigned integral values. An engine initializes its state by successively consuming |
|---|
| 444 | values from the iterator range, then returning the advanced iterator it1. |
|---|
| 445 | This approach has the advantage that the user can completely exploit |
|---|
| 446 | the large state of some engines for initialization. Also, it allows |
|---|
| 447 | to initialize compound engines in a uniform manner. For example, a |
|---|
| 448 | compound engine consisting of two simpler engines would initialize the |
|---|
| 449 | first engine with its [it1,it2). The first engine returns a smaller |
|---|
| 450 | iterator range that it has not consumed yet. This can be used to |
|---|
| 451 | initialize the second engine. |
|---|
| 452 | <p> |
|---|
| 453 | |
|---|
| 454 | The iterator range [it1,it2) is specified to point to unsigned |
|---|
| 455 | long values. There is no way to determine from a generic user |
|---|
| 456 | program how the initialization values will be treated and what range |
|---|
| 457 | of bits must be provided, except by enumerating all engines, e.g. in |
|---|
| 458 | template specializations. The problem is that a given generator might |
|---|
| 459 | have differing requirements on the values of the seed range even |
|---|
| 460 | within one <code>seed</code> call. |
|---|
| 461 | <p> |
|---|
| 462 | |
|---|
| 463 | For example, imagine a |
|---|
| 464 | |
|---|
| 465 | <pre> xor_combine<lagged_fibonacci<...>, mersenne_twister<...> ></pre> |
|---|
| 466 | |
|---|
| 467 | generator. For this, <code>seed(first, last)</code> will consume |
|---|
| 468 | values as follows: First, seed the state of the |
|---|
| 469 | <code>lagged_fibonacci</code> generator by consuming one item from |
|---|
| 470 | [first, last) for each word of state. The values are reduced to |
|---|
| 471 | (e.g.) 24 bits to fit the <code>lagged_fibonacci</code> state |
|---|
| 472 | requirements. Then, seed the state of the |
|---|
| 473 | <code>mersenne_twister</code> by consuming some number of items from |
|---|
| 474 | the remaining [first, last). The values are reduced to 32 bits to fit |
|---|
| 475 | the <code>mersenne_twister</code> state requirements. |
|---|
| 476 | <p> |
|---|
| 477 | |
|---|
| 478 | How does a concise programming interface for those increasingly |
|---|
| 479 | complex and varying requirements on [first, last) look like? I don't |
|---|
| 480 | know, and I don't want to complicate the specification by inventing |
|---|
| 481 | something complicated here. |
|---|
| 482 | <p> |
|---|
| 483 | |
|---|
| 484 | Thus, the specification says for each generator how it uses the seed |
|---|
| 485 | values, and how many are consumed. Additional features are left to |
|---|
| 486 | the user. |
|---|
| 487 | <p> |
|---|
| 488 | |
|---|
| 489 | In a way, this is similar to STL containers: It is intended that the user |
|---|
| 490 | can exchange iterators to various containers in generic algorithms, |
|---|
| 491 | but the container itself is not meant to be exchanged, i.e. having a |
|---|
| 492 | Container template parameter is often not adequate. That is analogous |
|---|
| 493 | to the random number case: The user can pass an engine around and use its |
|---|
| 494 | <code>operator()</code> and <code>min</code> and <code>max</code> |
|---|
| 495 | functions generically. However, the user can't generically query the |
|---|
| 496 | engine attributes and parameters, simply because most are entirely |
|---|
| 497 | different in semantics for each engine. |
|---|
| 498 | <p> |
|---|
| 499 | |
|---|
| 500 | The <code>seed(first, last)</code> interface can serve two purposes: |
|---|
| 501 | |
|---|
| 502 | <ol> |
|---|
| 503 | <li>In a generic context, the user can pass several integer values >= 1 |
|---|
| 504 | for seeding. It is unlikely that the user explores the full state space |
|---|
| 505 | with the seeds she provides, but she can be reasonably sure that her |
|---|
| 506 | seeds aren't entirely incorrect. (There is no formal guarantee for that, except that |
|---|
| 507 | the ability to provide bad seeds usually means the parameterization of |
|---|
| 508 | the engine is bad, e.g. a non-prime modulus for a linear congruential |
|---|
| 509 | engine.) For example, if the user wants a <code>seed(uint32_t)</code> |
|---|
| 510 | on top of <code>seed(first, last)</code>, one option is to use a |
|---|
| 511 | <code>linear_congruential</code> generator that produces the values |
|---|
| 512 | required for <code>seed(first, last)</code>. When the user defines the |
|---|
| 513 | iterator type for <code>first</code> and <code>last</code> so that it |
|---|
| 514 | encapsulates the <code>linear_congruential</code> engine in |
|---|
| 515 | <code>operator++</code>, the user doesn't even need to know beforehand how |
|---|
| 516 | many values <code>seed(first, last)</code> will need.</li> |
|---|
| 517 | |
|---|
| 518 | <li>If the user is in a non-generic context, he knows the specific |
|---|
| 519 | template type of the engine (probably not the template value-based |
|---|
| 520 | parameterization, though). The precise specification for <code>seed(first, |
|---|
| 521 | last)</code> allows to know what values need to be passed in so |
|---|
| 522 | that a specific initial state is attained, for example to compare one |
|---|
| 523 | implementation of the engine with another one that uses different |
|---|
| 524 | seeding.</li> |
|---|
| 525 | |
|---|
| 526 | <li>If the user requires both, he needs to inject knowledge into (1) |
|---|
| 527 | so that he is in the position of (2). One way to inject the knowledge |
|---|
| 528 | is to use (partial) template specialization to add the knowledge. The |
|---|
| 529 | specific parameterization of some engine can then be obtained by |
|---|
| 530 | querying the data members of the engines.</li> |
|---|
| 531 | </ol> |
|---|
| 532 | <p> |
|---|
| 533 | |
|---|
| 534 | I haven't seen the iterator-based approach to engine initialization in |
|---|
| 535 | other libraries; most initialization approaches rely on a either a |
|---|
| 536 | single value or on per-engine specific approaches to initialization. |
|---|
| 537 | <p> |
|---|
| 538 | |
|---|
| 539 | An alternative approach is to pass a zero-argument function object |
|---|
| 540 | ("generator") for seeding. It is trivial to implement a generator |
|---|
| 541 | from a given iterator range, but it is more complicated to implement |
|---|
| 542 | an iterator range from a generator. Also, the exception object that |
|---|
| 543 | is specified to be thrown when the iterator range is exhausted could |
|---|
| 544 | be configured in a user-provided iterator to generator mapping. |
|---|
| 545 | With this approach, some engines would have three one-argument constructors: |
|---|
| 546 | One taking a single integer for seeding, one taking a (reference?) to |
|---|
| 547 | a (templated) generator, and the copy constructor. It appears that the |
|---|
| 548 | opportunities for ambiguities or choosing the wrong overload are too |
|---|
| 549 | confusing to the unsuspecting user. |
|---|
| 550 | |
|---|
| 551 | |
|---|
| 552 | <h3>F. Parameterization and Initialization for Distributions</h3> |
|---|
| 553 | |
|---|
| 554 | The distributions specified in this proposal have template parameters |
|---|
| 555 | that indicate the output data type (e.g. <code>float</code>, |
|---|
| 556 | <code>double</code>, <code>long double</code>) that the user desires. |
|---|
| 557 | <p> |
|---|
| 558 | |
|---|
| 559 | The probability density functions of distributions usually have |
|---|
| 560 | parameters. These are mapped to constructor parameters, to be set at |
|---|
| 561 | runtime by the library user according to her requirements. The |
|---|
| 562 | parameters for a distribution object cannot change after its |
|---|
| 563 | construction. When constructing the distribution, this allows to |
|---|
| 564 | pre-compute some data according to the parameters given without risk |
|---|
| 565 | of inadvertently invalidating them later. |
|---|
| 566 | <p> |
|---|
| 567 | |
|---|
| 568 | Distributions may implement <code>operator()(T x)</code>, for |
|---|
| 569 | arbitrary type <code>T</code>, to meet special needs, for example a |
|---|
| 570 | "one-shot" mode where each invocation uses different distribution |
|---|
| 571 | parameters. |
|---|
| 572 | |
|---|
| 573 | |
|---|
| 574 | <h3>G. Properties as Traits vs. In-Class Constants</h3> |
|---|
| 575 | |
|---|
| 576 | Users might wish to query compile-time properties of the engines and |
|---|
| 577 | distributions, e.g. their base types, constant parameters, etc. This |
|---|
| 578 | is similar to querying the properties of the built-in types such as |
|---|
| 579 | <code>double</code> using <code>std::numeric_limits<></code>. However, |
|---|
| 580 | engines and distributions cannot be simple types, so it does not |
|---|
| 581 | appear to be necessary to separate the properties into separate traits |
|---|
| 582 | classes. Instead, compile-time properties are given as members types |
|---|
| 583 | and static member constants. |
|---|
| 584 | |
|---|
| 585 | |
|---|
| 586 | <h3>H. Which Engines to Include</h3> |
|---|
| 587 | |
|---|
| 588 | There is a multitude of pseudo-random number engines available in both |
|---|
| 589 | literature and code. Some engines, such as Mersenne Twister, have an |
|---|
| 590 | independent algorithm ("base engine"). Others change the values or |
|---|
| 591 | order of output of other engines to improve randomness, for example |
|---|
| 592 | Knuth's "Algorithm B" ("compound engine"). The template mechanism |
|---|
| 593 | allows easy combination of base and compound engines. |
|---|
| 594 | <p> |
|---|
| 595 | |
|---|
| 596 | Engines may be categorized according to the following dimensions. |
|---|
| 597 | |
|---|
| 598 | <ul> |
|---|
| 599 | <li>integers or floating-point numbers produced (Some engines produce |
|---|
| 600 | uniformly distributed integers in the range [min,max], however, most |
|---|
| 601 | distribution functions expect uniformly distributed floating-point |
|---|
| 602 | numbers in the range [0,1) as the input sequence. The obvious |
|---|
| 603 | conversion requires a relatively costly integer to floating-point |
|---|
| 604 | conversion plus a floating-point multiplication by |
|---|
| 605 | (max-min+1)<sup>-1</sup> for each random number used. To save the |
|---|
| 606 | multiplication, some engines can directly produce floating-point |
|---|
| 607 | numbers in the range [0,1) by maintaining the state x(i) in an |
|---|
| 608 | appropriately normalized form, given a sufficiently good |
|---|
| 609 | implementation of basic floating-point operations (e.g. IEEE |
|---|
| 610 | 754).</li> |
|---|
| 611 | |
|---|
| 612 | <li>quality of random numbers produced (What is the cycle length? |
|---|
| 613 | Does the engine pass all relevant statistical tests? Up to what |
|---|
| 614 | dimension are numbers equidistributed?)</li> |
|---|
| 615 | |
|---|
| 616 | <li>speed of generation (How many and what kind of operations have to |
|---|
| 617 | be performed to produce one random number, on average?)</li> |
|---|
| 618 | |
|---|
| 619 | <li>size of state (How may machine words of storage are required to |
|---|
| 620 | hold the state x(i) of the random engine?)</li> |
|---|
| 621 | |
|---|
| 622 | <li>option for independent subsequences (Is it possible to move from |
|---|
| 623 | x(i) to x(i+k) with at most O(log(k)) steps? This allows to |
|---|
| 624 | efficiently use subsequences x(0)...x(k-1), x(k)...x(2k-1), ..., |
|---|
| 625 | x(jk)...x((j+1)k-1), ..., for example for parallel computation, where |
|---|
| 626 | each of the m processors gets assigned the (independent) subsequence |
|---|
| 627 | starting at x(jk) (0 <= k < m).)</li> |
|---|
| 628 | </ul> |
|---|
| 629 | |
|---|
| 630 | According to the criteria above, the engines given below were chosen. |
|---|
| 631 | The quality and size indications were completed according to best |
|---|
| 632 | known parameterizations. Other parameterizations usually yield poorer |
|---|
| 633 | quality and/or less size. |
|---|
| 634 | <p> |
|---|
| 635 | |
|---|
| 636 | <table border="1"> |
|---|
| 637 | <tr> |
|---|
| 638 | <th>engine</th> |
|---|
| 639 | <th>int / float</th> |
|---|
| 640 | <th>quality</th> |
|---|
| 641 | <th>speed</th> |
|---|
| 642 | <th>size of state</th> |
|---|
| 643 | <th>subsequences</th> |
|---|
| 644 | <th>comments</th> |
|---|
| 645 | </tr> |
|---|
| 646 | |
|---|
| 647 | <tr> |
|---|
| 648 | <td>linear_congruential</td> |
|---|
| 649 | <td>int</td> |
|---|
| 650 | <td>medium</td> |
|---|
| 651 | <td>medium</td> |
|---|
| 652 | <td>1 word</td> |
|---|
| 653 | <td>yes</td> |
|---|
| 654 | <td>cycle length is limited to the maximum value representable in one |
|---|
| 655 | machine word, passes most statisticial tests with chosen |
|---|
| 656 | parameters.</td> |
|---|
| 657 | </tr> |
|---|
| 658 | |
|---|
| 659 | <tr> |
|---|
| 660 | <td>mersenne_twister</td> |
|---|
| 661 | <td>int</td> |
|---|
| 662 | <td>good</td> |
|---|
| 663 | <td>fast</td> |
|---|
| 664 | <td>624 words</td> |
|---|
| 665 | <td>no</td> |
|---|
| 666 | <td>long cycles, passes all statistical tests, good |
|---|
| 667 | equidistribution in high dimensions</td> |
|---|
| 668 | </tr> |
|---|
| 669 | |
|---|
| 670 | <tr> |
|---|
| 671 | <td>subtract_with_carry</td> |
|---|
| 672 | <td>both</td> |
|---|
| 673 | <td>medium</td> |
|---|
| 674 | <td>fast</td> |
|---|
| 675 | <td>25 words</td> |
|---|
| 676 | <td>no</td> |
|---|
| 677 | <td>very long cycles possible, fails some statistical tests. Can be |
|---|
| 678 | improved with the discard_block compound engine.</td> |
|---|
| 679 | </tr> |
|---|
| 680 | |
|---|
| 681 | <tr> |
|---|
| 682 | <td>discard_block</td> |
|---|
| 683 | <td>both</td> |
|---|
| 684 | <td>good</td> |
|---|
| 685 | <td>slow</td> |
|---|
| 686 | <td>base engine + 1 word</td> |
|---|
| 687 | <td>no</td> |
|---|
| 688 | <td>compound engine that removes correlation provably by throwing away |
|---|
| 689 | significant chunks of the base engine's sequence, the resulting speed |
|---|
| 690 | is reduced to 10% to 3% of the base engine's.</td> |
|---|
| 691 | </tr> |
|---|
| 692 | |
|---|
| 693 | <tr> |
|---|
| 694 | <td>xor_combine</td> |
|---|
| 695 | <td>int</td> |
|---|
| 696 | <td>good</td> |
|---|
| 697 | <td>fast</td> |
|---|
| 698 | <td>base engines</td> |
|---|
| 699 | <td>yes, if one of the base engines</td> |
|---|
| 700 | <td>compound engine that XOR-combines the sequences of |
|---|
| 701 | two base engines</td> |
|---|
| 702 | </tr> |
|---|
| 703 | |
|---|
| 704 | </table> |
|---|
| 705 | <p> |
|---|
| 706 | |
|---|
| 707 | Some engines were considered for inclusion, but left out for the |
|---|
| 708 | following reasons: |
|---|
| 709 | <p> |
|---|
| 710 | |
|---|
| 711 | <table border="1"> |
|---|
| 712 | <tr> |
|---|
| 713 | <th>engine</th> |
|---|
| 714 | <th>int / float</th> |
|---|
| 715 | <th>quality</th> |
|---|
| 716 | <th>speed</th> |
|---|
| 717 | <th>size of state</th> |
|---|
| 718 | <th>subsequences</th> |
|---|
| 719 | <th>comments</th> |
|---|
| 720 | </tr> |
|---|
| 721 | |
|---|
| 722 | <tr> |
|---|
| 723 | <td>shuffle_output</td> |
|---|
| 724 | <td>int</td> |
|---|
| 725 | <td>good</td> |
|---|
| 726 | <td>fast</td> |
|---|
| 727 | <td>base engine + 100 words</td> |
|---|
| 728 | <td>no</td> |
|---|
| 729 | <td>compound engine that reorders the base engine's output, little |
|---|
| 730 | overhead for generation (one multiplication)</td> |
|---|
| 731 | </tr> |
|---|
| 732 | |
|---|
| 733 | <tr> |
|---|
| 734 | <td>lagged_fibonacci</td> |
|---|
| 735 | <td>both</td> |
|---|
| 736 | <td>medium</td> |
|---|
| 737 | <td>fast</td> |
|---|
| 738 | <td>up to 80,000 words</td> |
|---|
| 739 | <td>no</td> |
|---|
| 740 | <td>very long cycles possible, fails birthday spacings test. Same |
|---|
| 741 | principle of generation as <code>subtract_with_carry</code>, i.e. x(i) |
|---|
| 742 | = x(i-s) (*) x(i-r), where (*) is either of +, -, xor with or without |
|---|
| 743 | carry.</td> |
|---|
| 744 | </tr> |
|---|
| 745 | |
|---|
| 746 | <tr> |
|---|
| 747 | <td>inversive_congruential (Hellekalek 1995)</td> |
|---|
| 748 | <td>int</td> |
|---|
| 749 | <td>good</td> |
|---|
| 750 | <td>slow</td> |
|---|
| 751 | <td>1 word</td> |
|---|
| 752 | <td>no</td> |
|---|
| 753 | <td>x(i+1) = a x(i)<sup>-1</sup> + c. Good equidistribution in |
|---|
| 754 | several dimensions. Provides no apparent advantage compared to |
|---|
| 755 | ranlux; the latter can produce floating-point numbers directly.</td> |
|---|
| 756 | </tr> |
|---|
| 757 | |
|---|
| 758 | <tr> |
|---|
| 759 | <td>additive_combine (L'Ecuyer 1988)</td> |
|---|
| 760 | <td>int</td> |
|---|
| 761 | <td>good</td> |
|---|
| 762 | <td>medium</td> |
|---|
| 763 | <td>2 words</td> |
|---|
| 764 | <td>yes</td> |
|---|
| 765 | <td>Combines two linear congruential generators. Same principle |
|---|
| 766 | of combination as <code>xor_combine</code>, i.e. z(i) = x(i) (*) y(i), |
|---|
| 767 | where (*) is one of +, -, xor.</td> |
|---|
| 768 | </tr> |
|---|
| 769 | |
|---|
| 770 | <tr> |
|---|
| 771 | <td>R250 (Kirkpatrick and Stoll)</td> |
|---|
| 772 | <td>int</td> |
|---|
| 773 | <td>bad</td> |
|---|
| 774 | <td>fast</td> |
|---|
| 775 | <td>~ 20 words</td> |
|---|
| 776 | <td>no</td> |
|---|
| 777 | <td>General Feedback Shift Register with two taps: Easily exploitable |
|---|
| 778 | correlation.</td> |
|---|
| 779 | </tr> |
|---|
| 780 | |
|---|
| 781 | <tr> |
|---|
| 782 | <td>linear_feedback_shift</td> |
|---|
| 783 | <td>int</td> |
|---|
| 784 | <td>medium</td> |
|---|
| 785 | <td>fast</td> |
|---|
| 786 | <td>1 word</td> |
|---|
| 787 | <td>no</td> |
|---|
| 788 | <td>cycle length is limited to the maximum value representable in one |
|---|
| 789 | machine word, fails some statistical tests, can be improved with the |
|---|
| 790 | xor_combine compound engine.</td> |
|---|
| 791 | </tr> |
|---|
| 792 | |
|---|
| 793 | </table> |
|---|
| 794 | <p> |
|---|
| 795 | |
|---|
| 796 | The GNU Scientific Library and Swarm have additional engine that are |
|---|
| 797 | not mentioned in the table below. |
|---|
| 798 | <p> |
|---|
| 799 | |
|---|
| 800 | <table border="1"> |
|---|
| 801 | <tr> |
|---|
| 802 | <th>Engine</th> |
|---|
| 803 | <th>this proposal</th> |
|---|
| 804 | <th>CLHEP</th> |
|---|
| 805 | <th>crng</th> |
|---|
| 806 | <th>GNU Scientific Library</th> |
|---|
| 807 | <th>Swarm</th> |
|---|
| 808 | <th>Numerical Recipes</th> |
|---|
| 809 | <th>Knuth</th> |
|---|
| 810 | </tr> |
|---|
| 811 | |
|---|
| 812 | <tr> |
|---|
| 813 | <td>LCG(2<sup>31</sup>-1, 16807)</td> |
|---|
| 814 | <td>minstd_rand0</td> |
|---|
| 815 | <td>-</td> |
|---|
| 816 | <td>ParkMiller</td> |
|---|
| 817 | <td>ran0, minstd</td> |
|---|
| 818 | <td>-</td> |
|---|
| 819 | <td>ran0</td> |
|---|
| 820 | <td>p106, table 1, line 19</td> |
|---|
| 821 | </tr> |
|---|
| 822 | |
|---|
| 823 | <tr> |
|---|
| 824 | <td>LCG(2<sup>32</sup>, a=1664525, c=1013904223)</td> |
|---|
| 825 | <td>linear_congruential< ..., 1664525, 1013904223, (1 << 32) ></td> |
|---|
| 826 | <td>-</td> |
|---|
| 827 | <td>-</td> |
|---|
| 828 | <td>-</td> |
|---|
| 829 | <td>LCG1gen</td> |
|---|
| 830 | <td>-</td> |
|---|
| 831 | <td>p106, table 1, line 16</td> |
|---|
| 832 | </tr> |
|---|
| 833 | |
|---|
| 834 | <tr> |
|---|
| 835 | <td>LCG1 + LCG2 + LCG3</td> |
|---|
| 836 | <td>-</td> |
|---|
| 837 | <td>-</td> |
|---|
| 838 | <td>WichmannHill</td> |
|---|
| 839 | <td>-</td> |
|---|
| 840 | <td>-</td> |
|---|
| 841 | <td>-</td> |
|---|
| 842 | <td>-</td> |
|---|
| 843 | </tr> |
|---|
| 844 | |
|---|
| 845 | <tr> |
|---|
| 846 | <td>(LCG1 - LCG2 + LCG3 - LCG4) mod m0</td> |
|---|
| 847 | <td>-</td> |
|---|
| 848 | <td>-</td> |
|---|
| 849 | <td>-</td> |
|---|
| 850 | <td>-</td> |
|---|
| 851 | <td>C4LCGXgen</td> |
|---|
| 852 | <td>-</td> |
|---|
| 853 | <td>-</td> |
|---|
| 854 | </tr> |
|---|
| 855 | |
|---|
| 856 | <tr> |
|---|
| 857 | <td>LCG(2<sup>31</sup>-1, 16807) with Bays/Durham shuffle</td> |
|---|
| 858 | <td>shuffle_output<minstd_rand0, 32> (shuffle_output not in this |
|---|
| 859 | proposal)</td> |
|---|
| 860 | <td>-</td> |
|---|
| 861 | <td>-</td> |
|---|
| 862 | <td>ran1</td> |
|---|
| 863 | <td>PMMLCG1gen</td> |
|---|
| 864 | <td>ran1</td> |
|---|
| 865 | <td>Algorithm "B"</td> |
|---|
| 866 | </tr> |
|---|
| 867 | |
|---|
| 868 | <tr> |
|---|
| 869 | <td>(LCG(2<sup>31</sup>-85, 40014) + LCG(2<sup>31</sup>-249, 40692)) |
|---|
| 870 | mod 2<sup>31</sup>-85</td> |
|---|
| 871 | <td>ecuyer1988 (additive_combine not in this proposal)</td> |
|---|
| 872 | <td>Ranecu</td> |
|---|
| 873 | <td>LEcuyer</td> |
|---|
| 874 | <td>-</td> |
|---|
| 875 | <td>C2LCGXgen</td> |
|---|
| 876 | <td>-</td> |
|---|
| 877 | <td>-</td> |
|---|
| 878 | </tr> |
|---|
| 879 | |
|---|
| 880 | <tr> |
|---|
| 881 | <td>(LCG(2<sup>31</sup>-85, 40014) with Bays/Durham shuffle + |
|---|
| 882 | LCG(2<sup>31</sup>-249, 40692)) mod 2<sup>31</sup>-85</td> |
|---|
| 883 | <td>additive_combine< |
|---|
| 884 | shuffle_output<<br> |
|---|
| 885 | linear_congruential<int, 40014, 0, 2147483563>, 32>,<br> |
|---|
| 886 | linear_congruential<int, 40692, 0, 2147483399> > |
|---|
| 887 | (additive_combine and shuffle_output not in this proposal)</td> |
|---|
| 888 | <td>-</td> |
|---|
| 889 | <td>-</td> |
|---|
| 890 | <td>ran2</td> |
|---|
| 891 | <td>-</td> |
|---|
| 892 | <td>ran2</td> |
|---|
| 893 | <td>-</td> |
|---|
| 894 | </tr> |
|---|
| 895 | |
|---|
| 896 | <tr> |
|---|
| 897 | <td>X(i) = (X(i-55) - X(i-33)) mod 10<sup>9</sup></td> |
|---|
| 898 | <td>-</td> |
|---|
| 899 | <td>-</td> |
|---|
| 900 | <td>-</td> |
|---|
| 901 | <td>ran3</td> |
|---|
| 902 | <td>~SCGgen</td> |
|---|
| 903 | <td>ran3</td> |
|---|
| 904 | <td>-</td> |
|---|
| 905 | </tr> |
|---|
| 906 | |
|---|
| 907 | <tr> |
|---|
| 908 | <td>X(i) = (X(i-100) - X(i-37)) mod 2<sup>30</sup></td> |
|---|
| 909 | <td>-</td> |
|---|
| 910 | <td>-</td> |
|---|
| 911 | <td>-</td> |
|---|
| 912 | <td>-</td> |
|---|
| 913 | <td>-</td> |
|---|
| 914 | <td>-</td> |
|---|
| 915 | <td>ran_array</td> |
|---|
| 916 | </tr> |
|---|
| 917 | |
|---|
| 918 | <tr> |
|---|
| 919 | <td>X(i) = (X(i-55) + X(i-24)) mod 2<sup>32</sup></td> |
|---|
| 920 | <td>lagged_fibonacci< ..., 32, 55, 24, ...> |
|---|
| 921 | (lagged_fibonacci not in this proposal) |
|---|
| 922 | </td> |
|---|
| 923 | <td>-</td> |
|---|
| 924 | <td>-</td> |
|---|
| 925 | <td>-</td> |
|---|
| 926 | <td>ACGgen</td> |
|---|
| 927 | <td>-</td> |
|---|
| 928 | <td>-</td> |
|---|
| 929 | </tr> |
|---|
| 930 | |
|---|
| 931 | <tr> |
|---|
| 932 | <td>DEShash(i,j)</td> |
|---|
| 933 | <td>-</td> |
|---|
| 934 | <td>-</td> |
|---|
| 935 | <td>-</td> |
|---|
| 936 | <td>-</td> |
|---|
| 937 | <td>-</td> |
|---|
| 938 | <td>ran4</td> |
|---|
| 939 | <td>-</td> |
|---|
| 940 | </tr> |
|---|
| 941 | |
|---|
| 942 | <tr> |
|---|
| 943 | <td>MT</td> |
|---|
| 944 | <td>mt19937</td> |
|---|
| 945 | <td>MTwistEngine</td> |
|---|
| 946 | <td>MT19937</td> |
|---|
| 947 | <td>mt19937</td> |
|---|
| 948 | <td>MT19937gen</td> |
|---|
| 949 | <td>-</td> |
|---|
| 950 | <td>-</td> |
|---|
| 951 | </tr> |
|---|
| 952 | |
|---|
| 953 | <tr> |
|---|
| 954 | <td>X(i) = (X(i-37) - X(i-24) - carry) mod 2<sup>32</sup></td> |
|---|
| 955 | <td>subtract_with_carry< ..., (1<<32), 37, 24, ...></td> |
|---|
| 956 | <td>-</td> |
|---|
| 957 | <td>-</td> |
|---|
| 958 | <td>-</td> |
|---|
| 959 | <td>SWB1gen</td> |
|---|
| 960 | <td>-</td> |
|---|
| 961 | <td>-</td> |
|---|
| 962 | </tr> |
|---|
| 963 | |
|---|
| 964 | <tr> |
|---|
| 965 | <td>X(i) = (X(i-43) - X(i-22) - carry) mod 2<sup>32</sup>-5</td> |
|---|
| 966 | <td>subtract_with_carry< ..., (1<<32)-5, 43, 22, ...></td> |
|---|
| 967 | <td>-</td> |
|---|
| 968 | <td>-</td> |
|---|
| 969 | <td>-</td> |
|---|
| 970 | <td>PSWBgen</td> |
|---|
| 971 | <td>-</td> |
|---|
| 972 | <td>-</td> |
|---|
| 973 | </tr> |
|---|
| 974 | |
|---|
| 975 | <tr> |
|---|
| 976 | <td>RCARRY with block discard by Lüscher</td> |
|---|
| 977 | <td>discard_block< subtract_with_carry<...>, ...></td> |
|---|
| 978 | <td>RanluxEngine, Ranlux64Engine</td> |
|---|
| 979 | <td>Ranlux</td> |
|---|
| 980 | <td>ranlx*</td> |
|---|
| 981 | <td>-</td> |
|---|
| 982 | <td>-</td> |
|---|
| 983 | <td>-</td> |
|---|
| 984 | </tr> |
|---|
| 985 | |
|---|
| 986 | <tr> |
|---|
| 987 | <td>Hurd</td> |
|---|
| 988 | <td>-</td> |
|---|
| 989 | <td>Hurd160, Hurd288</td> |
|---|
| 990 | <td>-</td> |
|---|
| 991 | <td>-</td> |
|---|
| 992 | <td>-</td> |
|---|
| 993 | <td>-</td> |
|---|
| 994 | <td>-</td> |
|---|
| 995 | </tr> |
|---|
| 996 | |
|---|
| 997 | <tr> |
|---|
| 998 | <td>physical model by Ranshi</td> |
|---|
| 999 | <td>-</td> |
|---|
| 1000 | <td>Ranshi</td> |
|---|
| 1001 | <td>-</td> |
|---|
| 1002 | <td>-</td> |
|---|
| 1003 | <td>-</td> |
|---|
| 1004 | <td>-</td> |
|---|
| 1005 | <td>-</td> |
|---|
| 1006 | </tr> |
|---|
| 1007 | |
|---|
| 1008 | <tr> |
|---|
| 1009 | <td>return predefined data</td> |
|---|
| 1010 | <td>-</td> |
|---|
| 1011 | <td>NonRandom</td> |
|---|
| 1012 | <td>-</td> |
|---|
| 1013 | <td>-</td> |
|---|
| 1014 | <td>-</td> |
|---|
| 1015 | <td>-</td> |
|---|
| 1016 | <td>-</td> |
|---|
| 1017 | </tr> |
|---|
| 1018 | |
|---|
| 1019 | <tr> |
|---|
| 1020 | <td>RANMAR: z(i) = (z(i-97) - z(i-33)) mod 2<sup>24</sup>; y(i+1) = |
|---|
| 1021 | (y(i)-c) mod 2<sup>24</sup>-3; X(i) = (z(i) - y(i)) mod |
|---|
| 1022 | 2<sup>24</sup></td> |
|---|
| 1023 | <td>additive_combine< lagged_fibonacci< (1<<24), 97, 33, |
|---|
| 1024 | ... >, linear_congruential< (1<<24)-3, 1, c, ...> |
|---|
| 1025 | (additive_combine and lagged_fibonacci not in this proposal) |
|---|
| 1026 | </td> |
|---|
| 1027 | <td>JamesRandom</td> |
|---|
| 1028 | <td>-</td> |
|---|
| 1029 | <td>ranmar</td> |
|---|
| 1030 | <td>-</td> |
|---|
| 1031 | <td>-</td> |
|---|
| 1032 | <td>-</td> |
|---|
| 1033 | </tr> |
|---|
| 1034 | |
|---|
| 1035 | <tr> |
|---|
| 1036 | <td>Taus88</td> |
|---|
| 1037 | <td>taus88 = xor_combine ...</td> |
|---|
| 1038 | <td>-</td> |
|---|
| 1039 | <td>Taus88</td> |
|---|
| 1040 | <td>taus, taus2</td> |
|---|
| 1041 | <td>-</td> |
|---|
| 1042 | <td>-</td> |
|---|
| 1043 | <td>-</td> |
|---|
| 1044 | </tr> |
|---|
| 1045 | |
|---|
| 1046 | <tr> |
|---|
| 1047 | <td>Taus60</td> |
|---|
| 1048 | <td>xor_combine< linear_feedback_shift< 31, 13, 12 >, 0, |
|---|
| 1049 | linear_feedback_shift< 29, 2, 4 >, 2, 0> |
|---|
| 1050 | (linear_feedback_shift not in this proposal) |
|---|
| 1051 | </td> |
|---|
| 1052 | <td>-</td> |
|---|
| 1053 | <td>-</td> |
|---|
| 1054 | <td>-</td> |
|---|
| 1055 | <td>C2TAUSgen</td> |
|---|
| 1056 | <td>-</td> |
|---|
| 1057 | <td>-</td> |
|---|
| 1058 | </tr> |
|---|
| 1059 | |
|---|
| 1060 | <tr> |
|---|
| 1061 | <td>GFSR, 4-tap</td> |
|---|
| 1062 | <td>-</td> |
|---|
| 1063 | <td>-</td> |
|---|
| 1064 | <td>-</td> |
|---|
| 1065 | <td>gfsr4</td> |
|---|
| 1066 | <td>-</td> |
|---|
| 1067 | <td>-</td> |
|---|
| 1068 | <td>-</td> |
|---|
| 1069 | </tr> |
|---|
| 1070 | |
|---|
| 1071 | <tr> |
|---|
| 1072 | <td>MRG32k3a</td> |
|---|
| 1073 | <td>-</td> |
|---|
| 1074 | <td>-</td> |
|---|
| 1075 | <td>MRG32k3a</td> |
|---|
| 1076 | <td>-</td> |
|---|
| 1077 | <td>-</td> |
|---|
| 1078 | <td>-</td> |
|---|
| 1079 | <td>-</td> |
|---|
| 1080 | </tr> |
|---|
| 1081 | |
|---|
| 1082 | </table> |
|---|
| 1083 | |
|---|
| 1084 | |
|---|
| 1085 | <h3>I. Which Distributions to Include</h3> |
|---|
| 1086 | |
|---|
| 1087 | The following distributions were chosen due to their relatively |
|---|
| 1088 | widespread use: |
|---|
| 1089 | |
|---|
| 1090 | <ul> |
|---|
| 1091 | <li>Integer uniform |
|---|
| 1092 | <li>Floating-point uniform |
|---|
| 1093 | <li>Exponential |
|---|
| 1094 | <li>Normal |
|---|
| 1095 | <li>Gamma |
|---|
| 1096 | <li>Poisson |
|---|
| 1097 | <li>Binomial |
|---|
| 1098 | <li>Geometric |
|---|
| 1099 | <li>Bernoulli |
|---|
| 1100 | </ul> |
|---|
| 1101 | |
|---|
| 1102 | The GNU Scientific Library has a multitude of additional distributions |
|---|
| 1103 | that are not mentioned in the table below. |
|---|
| 1104 | <p> |
|---|
| 1105 | |
|---|
| 1106 | <table border="1"> |
|---|
| 1107 | <tr> |
|---|
| 1108 | <th>Distribution</th> |
|---|
| 1109 | <th>this proposal</th> |
|---|
| 1110 | <th>CLHEP</th> |
|---|
| 1111 | <th>crng</th> |
|---|
| 1112 | <th>GNU Scientific Library</th> |
|---|
| 1113 | <th>Swarm</th> |
|---|
| 1114 | <th>Numerical Recipes</th> |
|---|
| 1115 | <th>Knuth</th> |
|---|
| 1116 | </tr> |
|---|
| 1117 | |
|---|
| 1118 | <tr> |
|---|
| 1119 | <td>uniform (int)</td> |
|---|
| 1120 | <td>uniform_int</td> |
|---|
| 1121 | <td>-</td> |
|---|
| 1122 | <td>-</td> |
|---|
| 1123 | <td>-</td> |
|---|
| 1124 | <td>UniformIntegerDist</td> |
|---|
| 1125 | <td>-</td> |
|---|
| 1126 | <td>-</td> |
|---|
| 1127 | </tr> |
|---|
| 1128 | |
|---|
| 1129 | <tr> |
|---|
| 1130 | <td>uniform (float)</td> |
|---|
| 1131 | <td>uniform_real</td> |
|---|
| 1132 | <td>RandFlat</td> |
|---|
| 1133 | <td>UniformDeviate</td> |
|---|
| 1134 | <td>flat</td> |
|---|
| 1135 | <td>UniformDoubleDist</td> |
|---|
| 1136 | <td>-</td> |
|---|
| 1137 | <td>uniform</td> |
|---|
| 1138 | </tr> |
|---|
| 1139 | |
|---|
| 1140 | <tr> |
|---|
| 1141 | <td>exponential</td> |
|---|
| 1142 | <td>exponential_distribution</td> |
|---|
| 1143 | <td>RandExponential</td> |
|---|
| 1144 | <td>ExponentialDeviate</td> |
|---|
| 1145 | <td>exponential</td> |
|---|
| 1146 | <td>ExponentialDist</td> |
|---|
| 1147 | <td>exponential</td> |
|---|
| 1148 | <td>exponential</td> |
|---|
| 1149 | </tr> |
|---|
| 1150 | |
|---|
| 1151 | <tr> |
|---|
| 1152 | <td>normal</td> |
|---|
| 1153 | <td>normal_distribution</td> |
|---|
| 1154 | <td>RandGauss*</td> |
|---|
| 1155 | <td>NormalDeviate</td> |
|---|
| 1156 | <td>gaussian</td> |
|---|
| 1157 | <td>NormalDist</td> |
|---|
| 1158 | <td>normal (gaussian)</td> |
|---|
| 1159 | <td>normal</td> |
|---|
| 1160 | </tr> |
|---|
| 1161 | |
|---|
| 1162 | <tr> |
|---|
| 1163 | <td>lognormal</td> |
|---|
| 1164 | <td>-</td> |
|---|
| 1165 | <td>-</td> |
|---|
| 1166 | <td>-</td> |
|---|
| 1167 | <td>lognormal</td> |
|---|
| 1168 | <td>LogNormalDist</td> |
|---|
| 1169 | <td>-</td> |
|---|
| 1170 | <td>-</td> |
|---|
| 1171 | </tr> |
|---|
| 1172 | |
|---|
| 1173 | <tr> |
|---|
| 1174 | <td>gamma</td> |
|---|
| 1175 | <td>gamma_distribution</td> |
|---|
| 1176 | <td>RandGamma</td> |
|---|
| 1177 | <td>GammaDeviate</td> |
|---|
| 1178 | <td>gamma</td> |
|---|
| 1179 | <td>GammaDist</td> |
|---|
| 1180 | <td>gamma</td> |
|---|
| 1181 | <td>gamma</td> |
|---|
| 1182 | </tr> |
|---|
| 1183 | |
|---|
| 1184 | <tr> |
|---|
| 1185 | <td>beta</td> |
|---|
| 1186 | <td>-</td> |
|---|
| 1187 | <td>-</td> |
|---|
| 1188 | <td>BetaDeviate</td> |
|---|
| 1189 | <td>beta</td> |
|---|
| 1190 | <td>-</td> |
|---|
| 1191 | <td>-</td> |
|---|
| 1192 | <td>beta</td> |
|---|
| 1193 | </tr> |
|---|
| 1194 | |
|---|
| 1195 | <tr> |
|---|
| 1196 | <td>poisson</td> |
|---|
| 1197 | <td>poisson_distribution</td> |
|---|
| 1198 | <td>Poisson</td> |
|---|
| 1199 | <td>PoissonDeviate</td> |
|---|
| 1200 | <td>poisson</td> |
|---|
| 1201 | <td>PoissonDist</td> |
|---|
| 1202 | <td>poisson</td> |
|---|
| 1203 | <td>poisson</td> |
|---|
| 1204 | </tr> |
|---|
| 1205 | |
|---|
| 1206 | <tr> |
|---|
| 1207 | <td>binomial</td> |
|---|
| 1208 | <td>binomial_distribution</td> |
|---|
| 1209 | <td>RandBinomial</td> |
|---|
| 1210 | <td>BinomialDeviate</td> |
|---|
| 1211 | <td>binomial</td> |
|---|
| 1212 | <td>-</td> |
|---|
| 1213 | <td>binomial</td> |
|---|
| 1214 | <td>binomial</td> |
|---|
| 1215 | </tr> |
|---|
| 1216 | |
|---|
| 1217 | <tr> |
|---|
| 1218 | <td>geometric</td> |
|---|
| 1219 | <td>geometric_distribution</td> |
|---|
| 1220 | <td>-</td> |
|---|
| 1221 | <td>GeometricDeviate</td> |
|---|
| 1222 | <td>geometric</td> |
|---|
| 1223 | <td>-</td> |
|---|
| 1224 | <td>-</td> |
|---|
| 1225 | <td>geometric</td> |
|---|
| 1226 | </tr> |
|---|
| 1227 | |
|---|
| 1228 | <tr> |
|---|
| 1229 | <td>bernoulli</td> |
|---|
| 1230 | <td>bernoulli_distribution</td> |
|---|
| 1231 | <td>-</td> |
|---|
| 1232 | <td>BernoulliDeviate</td> |
|---|
| 1233 | <td>bernoulli</td> |
|---|
| 1234 | <td>BernoulliDist</td> |
|---|
| 1235 | <td>-</td> |
|---|
| 1236 | <td>-</td> |
|---|
| 1237 | </tr> |
|---|
| 1238 | |
|---|
| 1239 | <tr> |
|---|
| 1240 | <td>random bit</td> |
|---|
| 1241 | <td>-</td> |
|---|
| 1242 | <td>RandBit</td> |
|---|
| 1243 | <td>-</td> |
|---|
| 1244 | <td>-</td> |
|---|
| 1245 | <td>RandomBitDist</td> |
|---|
| 1246 | <td>-</td> |
|---|
| 1247 | <td>-</td> |
|---|
| 1248 | </tr> |
|---|
| 1249 | |
|---|
| 1250 | <tr> |
|---|
| 1251 | <td>breit-wigner</td> |
|---|
| 1252 | <td>-</td> |
|---|
| 1253 | <td>RandBreitWigner</td> |
|---|
| 1254 | <td>-</td> |
|---|
| 1255 | <td>-</td> |
|---|
| 1256 | <td>-</td> |
|---|
| 1257 | <td>-</td> |
|---|
| 1258 | <td>-</td> |
|---|
| 1259 | </tr> |
|---|
| 1260 | |
|---|
| 1261 | <tr> |
|---|
| 1262 | <td>chi-square</td> |
|---|
| 1263 | <td>-</td> |
|---|
| 1264 | <td>RandChiSquare</td> |
|---|
| 1265 | <td>-</td> |
|---|
| 1266 | <td>chisq</td> |
|---|
| 1267 | <td>-</td> |
|---|
| 1268 | <td>-</td> |
|---|
| 1269 | <td>chi-square</td> |
|---|
| 1270 | </tr> |
|---|
| 1271 | |
|---|
| 1272 | <tr> |
|---|
| 1273 | <td>landau</td> |
|---|
| 1274 | <td>-</td> |
|---|
| 1275 | <td>Landau</td> |
|---|
| 1276 | <td>-</td> |
|---|
| 1277 | <td>landau</td> |
|---|
| 1278 | <td>-</td> |
|---|
| 1279 | <td>-</td> |
|---|
| 1280 | <td>-</td> |
|---|
| 1281 | </tr> |
|---|
| 1282 | |
|---|
| 1283 | <tr> |
|---|
| 1284 | <td>F</td> |
|---|
| 1285 | <td>-</td> |
|---|
| 1286 | <td>-</td> |
|---|
| 1287 | <td>-</td> |
|---|
| 1288 | <td>F</td> |
|---|
| 1289 | <td>-</td> |
|---|
| 1290 | <td>-</td> |
|---|
| 1291 | <td>F (variance-ratio)</td> |
|---|
| 1292 | </tr> |
|---|
| 1293 | |
|---|
| 1294 | <tr> |
|---|
| 1295 | <td>t</td> |
|---|
| 1296 | <td>-</td> |
|---|
| 1297 | <td>-</td> |
|---|
| 1298 | <td>-</td> |
|---|
| 1299 | <td>t</td> |
|---|
| 1300 | <td>-</td> |
|---|
| 1301 | <td>-</td> |
|---|
| 1302 | <td>t</td> |
|---|
| 1303 | </tr> |
|---|
| 1304 | |
|---|
| 1305 | </table> |
|---|
| 1306 | |
|---|
| 1307 | |
|---|
| 1308 | <h3>J. Taxonomy of Concepts</h3> |
|---|
| 1309 | |
|---|
| 1310 | All of the engines support the number generator requirements, |
|---|
| 1311 | i.e. they are zero-argument function objects which return numbers. |
|---|
| 1312 | All of the distributions are one-argument function objects, taking a |
|---|
| 1313 | reference to an engine and returning numbers. All of the engines and |
|---|
| 1314 | some of the distributions return uniformly distributed random numbers. |
|---|
| 1315 | This is reflected in the concept of the uniform random number |
|---|
| 1316 | generator, which refines number generator. Engines for pseudo-random |
|---|
| 1317 | numbers model the requirements for pseudo-random number engine, which |
|---|
| 1318 | refines uniform random number generator. |
|---|
| 1319 | |
|---|
| 1320 | <pre> |
|---|
| 1321 | NumberGenerator ---- UniformRandomNumberGenerator ---- PseudoRandomNumberGenerator |
|---|
| 1322 | \--- RandomDistribution |
|---|
| 1323 | </pre> |
|---|
| 1324 | |
|---|
| 1325 | |
|---|
| 1326 | <h3>K. Validation</h3> |
|---|
| 1327 | |
|---|
| 1328 | How can a user have confidence that the implementation of a |
|---|
| 1329 | random-number engine is exactly as specified, correctly taking into |
|---|
| 1330 | account any platform pecularities (e.g., odd-sized ints)? After all, |
|---|
| 1331 | minor typos in the implementation might not be apparent; the numbers |
|---|
| 1332 | produced may look "random". This proposal therefore specifies for |
|---|
| 1333 | each engine the 10000th number in the random number sequence that a |
|---|
| 1334 | default-constructed engine object produces. |
|---|
| 1335 | <p> |
|---|
| 1336 | |
|---|
| 1337 | This is considered an important feature for library implementors and |
|---|
| 1338 | serious users to check whether the provided library on the given |
|---|
| 1339 | platform returns the correct numbers. It could be argued that a |
|---|
| 1340 | library implementor should provide a correct implementation of some |
|---|
| 1341 | standard feature in any case. |
|---|
| 1342 | <p> |
|---|
| 1343 | |
|---|
| 1344 | No other library I have encountered provides explicit validation |
|---|
| 1345 | values in either their specification or their implementation, although |
|---|
| 1346 | some of them claim to be widely portable. |
|---|
| 1347 | <p> |
|---|
| 1348 | |
|---|
| 1349 | Another design option for validation that was part of early drafts of |
|---|
| 1350 | this proposal is moving the reference number (10000th value in the |
|---|
| 1351 | sequence) from specification space to implementation space, thus |
|---|
| 1352 | providing a <code>validation(x)</code> static member function for each |
|---|
| 1353 | engine that compares the hard-coded 10000th value of the sequence with |
|---|
| 1354 | some user-provided value <code>x</code> presumeably obtained by |
|---|
| 1355 | actually invoking the random-number engine object 10000 times. Due to |
|---|
| 1356 | the template-based design, this amounted to a "val" template value |
|---|
| 1357 | parameter for each engine, and the <code>validation(x)</code> function |
|---|
| 1358 | reduced to the trivial comparison "val == x". Handling validation for |
|---|
| 1359 | floating-point engines required more machinery, because template value |
|---|
| 1360 | parameters cannot be of floating-point type. Also, from a conceptual |
|---|
| 1361 | perspective, it seemed odd to demand a validation decision from the |
|---|
| 1362 | very entitiy which one wanted to validate. |
|---|
| 1363 | |
|---|
| 1364 | |
|---|
| 1365 | <h3>L. Non-Volatile Storage of Engine and Distribution State</h3> |
|---|
| 1366 | |
|---|
| 1367 | Pseudo-random number engines and distributions may store their state on a |
|---|
| 1368 | <code>std::ostream</code> in textual form and recover it from an |
|---|
| 1369 | appropriate <code>std::istream</code>. Each engine specifies how its |
|---|
| 1370 | internal state is represented. The specific algorithm of a |
|---|
| 1371 | distribution is left implementation-defined, thus no specifics about |
|---|
| 1372 | the representation of its internal state are given. A store operation |
|---|
| 1373 | must not affect the number sequence produced. It is expected |
|---|
| 1374 | that such external storage happens rarely as opposed to producing |
|---|
| 1375 | random numbers, thus no particular attention to performance is paid. |
|---|
| 1376 | <p> |
|---|
| 1377 | |
|---|
| 1378 | Engines and distributions use the usual idioms of <code>operator<<</code> and |
|---|
| 1379 | <code>operator>></code>. If the user needs additional |
|---|
| 1380 | processing before or after storage on non-volatile media, there is |
|---|
| 1381 | always the option to use a temporary <code>std::stringstream</code>. |
|---|
| 1382 | <p> |
|---|
| 1383 | |
|---|
| 1384 | Distributions sometimes store values from their associated source of |
|---|
| 1385 | random numbers across calls to their <code>operator()</code>. For example, a |
|---|
| 1386 | common method for generating normally distributed random numbers is to |
|---|
| 1387 | retrieve two uniformly distributed random numbers and compute two |
|---|
| 1388 | normally distributed random numbers out of them. |
|---|
| 1389 | In order to reset the distribution's random number cache to a defined |
|---|
| 1390 | state, each distribution has a <code>reset</code> member function. It |
|---|
| 1391 | should be called on a distribution whenever its associated engine is |
|---|
| 1392 | exchanged or restored. |
|---|
| 1393 | |
|---|
| 1394 | |
|---|
| 1395 | <h3>M. Values vs. References</h3> |
|---|
| 1396 | |
|---|
| 1397 | Compounded engines such as <code>shuffle_output</code> and |
|---|
| 1398 | <code>discard_block</code> contain a base engine by value, because |
|---|
| 1399 | compounding is not intended to be used by reference to an existing |
|---|
| 1400 | (re-used) engine object. |
|---|
| 1401 | <p> |
|---|
| 1402 | |
|---|
| 1403 | The wrapper <code>variate_generator</code> can store engines either by |
|---|
| 1404 | value or by reference, explicitly chosen by the template parameters. |
|---|
| 1405 | This allows to use references to a single engine in several |
|---|
| 1406 | <code>variate_generator</code>, but makes it explicit to the user that |
|---|
| 1407 | he is responsible for the management of the lifetime of the engine. |
|---|
| 1408 | |
|---|
| 1409 | |
|---|
| 1410 | <h3>N. Providing the Probability Density Function in Distributions</h3> |
|---|
| 1411 | |
|---|
| 1412 | Some libraries provide the probability density function of a given |
|---|
| 1413 | distribution as part of that distribution's interface. While this may |
|---|
| 1414 | be useful occasionally, this proposal does not provide for such a |
|---|
| 1415 | feature. One reason is separation of concerns: The distribution class |
|---|
| 1416 | templates might benefit from precomputing large tables of values |
|---|
| 1417 | depending on the distribution parameters, while the computation of the |
|---|
| 1418 | probability density function does not. Also, the function |
|---|
| 1419 | representation is often straightforward, so the user can easily code |
|---|
| 1420 | it himself. |
|---|
| 1421 | |
|---|
| 1422 | |
|---|
| 1423 | <h3>O. Implementation-defined behaviour</h3> |
|---|
| 1424 | |
|---|
| 1425 | This proposal specifies implementation-defined behaviour in a number |
|---|
| 1426 | of places. I believe this is unavoidable; this section provides |
|---|
| 1427 | detailed reasoning, including why the implementation is required to |
|---|
| 1428 | document the choice. |
|---|
| 1429 | <p> |
|---|
| 1430 | |
|---|
| 1431 | The precise state-holding base data types for the various engines are |
|---|
| 1432 | left implementation-defined, because engines are usually optimized for |
|---|
| 1433 | binary integers with 32 bits of word size. The specification in this |
|---|
| 1434 | proposal cannot foresee whether a 32 bit quantity on the machine is |
|---|
| 1435 | available in C++ as short, int, long, or not at all. It is up to the |
|---|
| 1436 | implementation to decide which data type fits best. The |
|---|
| 1437 | implementation is required to document the choice of data type, so |
|---|
| 1438 | that users can (non-portably) rely on the precise type, for example |
|---|
| 1439 | for further computation. Should the ISO C99 extensions become part of |
|---|
| 1440 | ISO C++, the implementation-defined types could be replaced by |
|---|
| 1441 | e.g. <code>int_least32_t</code>. |
|---|
| 1442 | <p> |
|---|
| 1443 | |
|---|
| 1444 | The method how to produce non-deterministic random numbers is |
|---|
| 1445 | considered implementation-defined, because it inherently depends on |
|---|
| 1446 | the implementation and possibly even on the runtime environment: |
|---|
| 1447 | Imagine a platform that has operating system support for randomness |
|---|
| 1448 | collection, e.g. from user keystrokes and Ethernet inter-packet |
|---|
| 1449 | arrival timing (Linux <code>/dev/random</code> does this). If, in some |
|---|
| 1450 | installation, access to the operating system functions providing these |
|---|
| 1451 | services has been restricted, the C++ non-deterministic random number |
|---|
| 1452 | engine has been deprived of its randomness. An implementation is |
|---|
| 1453 | required to document how it obtains the non-deterministic random |
|---|
| 1454 | numbers, because only then can users' confidence in them grow. |
|---|
| 1455 | Confidence is of particular concern in the area of cryptography. |
|---|
| 1456 | <p> |
|---|
| 1457 | |
|---|
| 1458 | The algorithms how to produce the various distributions are specified |
|---|
| 1459 | as implementation-defined, because there is a vast variety of |
|---|
| 1460 | algorithms known for each distribution. Each has a different |
|---|
| 1461 | trade-off in terms of speed, adaptation to recent computer |
|---|
| 1462 | architectures, and memory use. The implementation is required to |
|---|
| 1463 | document its choice so that the user can judge whether it is |
|---|
| 1464 | acceptable quality-wise. |
|---|
| 1465 | |
|---|
| 1466 | |
|---|
| 1467 | <h3>P. Lower and upper bounds on UniformRandomNumberGenerator</h3> |
|---|
| 1468 | |
|---|
| 1469 | The member functions <code>min()</code> and <code>max()</code> return |
|---|
| 1470 | the lower and upper bounds of a UniformRandomNumberGenerator. This |
|---|
| 1471 | could be a random-number engine or one of the <code>uniform_int</code> |
|---|
| 1472 | and <code>uniform_real</code> distributions. |
|---|
| 1473 | <p> |
|---|
| 1474 | |
|---|
| 1475 | Those bounds are not specified to be tight, because for some engines, |
|---|
| 1476 | the bounds depend on the seeds. The seed can be changed during the |
|---|
| 1477 | lifetime of the engine object, while the values returned by |
|---|
| 1478 | <code>min()</code> and <code>max()</code> are invariant. Therefore, |
|---|
| 1479 | <code>min()</code> and <code>max()</code> must return conservative |
|---|
| 1480 | bounds that are independent of the seed. |
|---|
| 1481 | |
|---|
| 1482 | |
|---|
| 1483 | <h3>Q. With or without manager class</h3> |
|---|
| 1484 | |
|---|
| 1485 | This proposal presents a design with a manager class template, |
|---|
| 1486 | <code>variate_generator</code>, after extensive discussion with some |
|---|
| 1487 | members of the computing division of Fermi National Accelerator |
|---|
| 1488 | Laboratory. User-written and library-provided engines and |
|---|
| 1489 | distributions plug in to the manager class. The approach is remotely |
|---|
| 1490 | similar to the locale design in the standard library, where |
|---|
| 1491 | (user-written) facets plug in to the (library-provided) locale class. |
|---|
| 1492 | <p> |
|---|
| 1493 | |
|---|
| 1494 | Earlier versions of this propsoal made (potentially user-written) |
|---|
| 1495 | distributions directly visible to (some other) user that wants to get |
|---|
| 1496 | random numbers distributed accordingly ("client"), there was no |
|---|
| 1497 | additional management layer between the distribution and the client. |
|---|
| 1498 | <p> |
|---|
| 1499 | |
|---|
| 1500 | The following additional features could be provided by the management |
|---|
| 1501 | layer: |
|---|
| 1502 | |
|---|
| 1503 | <ul> |
|---|
| 1504 | <li>The management layer contains an adaptor (to convert the engine's |
|---|
| 1505 | output into the distribution's input) in addition to the engine and |
|---|
| 1506 | the distribution.</li> |
|---|
| 1507 | |
|---|
| 1508 | <li>Adaptors and distributions do not store state, but instead, in |
|---|
| 1509 | each invocation, consume an arbitrary number of input values and |
|---|
| 1510 | produce a fixed number of output values. The management layer is |
|---|
| 1511 | responsible for connecting the engine - adaptor - distribution chain, |
|---|
| 1512 | invoking each part when more numbers are needed from the next part of |
|---|
| 1513 | the chain. |
|---|
| 1514 | |
|---|
| 1515 | <li>On request, the management layer is responsible for saving and |
|---|
| 1516 | restoring the buffers that exist between engine, adaptor, and |
|---|
| 1517 | distribution.</li> |
|---|
| 1518 | |
|---|
| 1519 | <li>On request, the management layer shares engines with another |
|---|
| 1520 | instance of the management layer.</li> |
|---|
| 1521 | |
|---|
| 1522 | </ul> |
|---|
| 1523 | |
|---|
| 1524 | It is envisioned that user-written distributions will often be based |
|---|
| 1525 | on some arbitrary algorithmic distribution, instead of trying to |
|---|
| 1526 | implement a given mathematical probability density function. Here is |
|---|
| 1527 | an example: |
|---|
| 1528 | <ul> |
|---|
| 1529 | <li>Retrieve a uniform integer with value either 1 or 2. |
|---|
| 1530 | <li>If 1, return a number with normal distribution. |
|---|
| 1531 | <li>If 2, return a number with gamma distribution. |
|---|
| 1532 | </ul> |
|---|
| 1533 | |
|---|
| 1534 | Both in this case and when implementing complex distributions based on |
|---|
| 1535 | a probability density function (e.g. the gamma distribution), it is |
|---|
| 1536 | important to be able to arbitrarily nest distributions. Either design |
|---|
| 1537 | allows for this with utmost ease: Compounding |
|---|
| 1538 | distributions are contained in the compound by value, and each one |
|---|
| 1539 | produces a single value on invocation. With the alternative design of |
|---|
| 1540 | giving distributions the freedom to produce |
|---|
| 1541 | more than one output number in each invocation, compound distributions |
|---|
| 1542 | such as the one shown above need to handle the situation that each of |
|---|
| 1543 | the compounding members could provide several output values, the |
|---|
| 1544 | number of which is unknown at the time the distribution is written. |
|---|
| 1545 | (Remember that it is unfeasible to prescribe a precise algorithm for |
|---|
| 1546 | each library-provided distribution in the standard, see subsection O.) |
|---|
| 1547 | That approach shifts implementation effort from the place where it |
|---|
| 1548 | came up, i.e. the distribution that chose to use an algorithm that |
|---|
| 1549 | produces several values in one invocation, to the places where that |
|---|
| 1550 | distribution is used. This, considered by itself, does not seem to be |
|---|
| 1551 | a good approach. Also, only very few distributions lead to a natural |
|---|
| 1552 | implementation that produces several values in one invocation; so far, |
|---|
| 1553 | the normal distribution is the only one known to me. However, it is |
|---|
| 1554 | expected that there will be plenty of distributions that use a normal |
|---|
| 1555 | distribution as its base, so far those known to me are lognormal and |
|---|
| 1556 | uniform_on_sphere (both not part of this proposal). As a conclusion, |
|---|
| 1557 | independent of whether the design provides for a management layer or |
|---|
| 1558 | not, distributions should always return a single value on each |
|---|
| 1559 | invocation, and management of buffers for additional values that might |
|---|
| 1560 | be produced should be internal to the distribution. Should it become |
|---|
| 1561 | necessary for the user to employ buffer management more often, a |
|---|
| 1562 | user-written base class for the distributions could be of help. |
|---|
| 1563 | <p> |
|---|
| 1564 | |
|---|
| 1565 | The ability to share engines is important. This proposal makes |
|---|
| 1566 | lifetime management issues explicit by requiring pointer or reference |
|---|
| 1567 | types in the template instantiation of <code>variate_generator</code> |
|---|
| 1568 | if reference semantics are |
|---|
| 1569 | desired. Without a management class, providing this features is |
|---|
| 1570 | much more cumbersome and imposes additional burden on the programmers |
|---|
| 1571 | that produce distributions. Alternatively, reference semantics could |
|---|
| 1572 | always be used, but this is an |
|---|
| 1573 | error-prone approach due to the lack of a standard reference-counted |
|---|
| 1574 | smart pointer. I believe it is impossible to add a reference-counted |
|---|
| 1575 | sharing mechanism in a manager-class-free design without giving its precise |
|---|
| 1576 | type. And that would certainly conflict in semantic scope with a |
|---|
| 1577 | smart pointer that will get into the standard eventually. |
|---|
| 1578 | <p> |
|---|
| 1579 | |
|---|
| 1580 | The management layer allows for a few common features to be factored |
|---|
| 1581 | out, in particular access to the engine and some member typedefs. |
|---|
| 1582 | <p> |
|---|
| 1583 | |
|---|
| 1584 | Comparison of other differing features between manager and non-manager |
|---|
| 1585 | designs: |
|---|
| 1586 | |
|---|
| 1587 | <ul> |
|---|
| 1588 | <li>When passing a <code>variate_generator</code> as a an argument to |
|---|
| 1589 | a function, the design in this proposal allows selecting only those |
|---|
| 1590 | function signatures during overload resolution that are intended to be |
|---|
| 1591 | called with a <code>variate_generator</code>. In contrast, |
|---|
| 1592 | misbehaviour is possible without a manager class, similar to |
|---|
| 1593 | iterators in function signatures: <code>template<class BiIter> |
|---|
| 1594 | void f(BiIter it)</code> matches <code>f(5)</code>, without regard to |
|---|
| 1595 | the bidirectional iterator requirements. An error then happens when |
|---|
| 1596 | instantiating f. The situation worsens when several competing |
|---|
| 1597 | function templates are available and the wrong one is chosen |
|---|
| 1598 | accidentally. |
|---|
| 1599 | |
|---|
| 1600 | <li>With the engine passed into the distribution's constructor, the |
|---|
| 1601 | full type hierarchy of engine (and possibly adaptor) are available to |
|---|
| 1602 | the distribution, allowing to cache information derived from the |
|---|
| 1603 | engine (e.g. its value range) . Also, (partial) specialization |
|---|
| 1604 | of distributions could be written that optimize the interaction with a |
|---|
| 1605 | specific engine and/or adaptor. In this proposal's design, |
|---|
| 1606 | this information is available in the <code>variate_generator</code> template |
|---|
| 1607 | only. However, optimizations by specialization for the |
|---|
| 1608 | engine/adaptor combination are perceived to possibly have high |
|---|
| 1609 | benefit, while those for the (engine+adaptor) / distribution |
|---|
| 1610 | combination are presumed to be much less beneficial. |
|---|
| 1611 | |
|---|
| 1612 | <li>Having distribution classes directly exposed to the client easily |
|---|
| 1613 | allows that the user writes a distribution with an additional |
|---|
| 1614 | arbitrary member function declaration, intended to produce random |
|---|
| 1615 | numbers while taking additional parameters into account. In this |
|---|
| 1616 | proposal's design, this is possible by using the |
|---|
| 1617 | generic <code>operator()(T x)</code> forwarding function. |
|---|
| 1618 | |
|---|
| 1619 | </ul> |
|---|
| 1620 | |
|---|
| 1621 | |
|---|
| 1622 | <h3>R. Add-on packages</h3> |
|---|
| 1623 | |
|---|
| 1624 | This proposal specifies a framework for random number generation. |
|---|
| 1625 | Users might have additional requirements not met by this framework. |
|---|
| 1626 | The following extensions have been identified, and they are expressly not |
|---|
| 1627 | addressed in this proposal. It is perceived that these items can be |
|---|
| 1628 | seamlessly implemented in an add-on package which sits on top of an |
|---|
| 1629 | implementation according to this proposal. |
|---|
| 1630 | |
|---|
| 1631 | <ul> |
|---|
| 1632 | <li>unique seeding: Make it easy for the user to provide a unique seed |
|---|
| 1633 | for each instance of a pseudo-random number engine. Design idea: |
|---|
| 1634 | <pre> |
|---|
| 1635 | class unique_seed; |
|---|
| 1636 | |
|---|
| 1637 | template<class Engine> |
|---|
| 1638 | Engine seed(unique_seed&); |
|---|
| 1639 | </pre> |
|---|
| 1640 | The "seed" function retrieves some unique seed from the unique_seed |
|---|
| 1641 | class and then uses the <code>seed(first, last)</code> interface of an |
|---|
| 1642 | engine to implant that unique seed. Specific seeding requirements for |
|---|
| 1643 | some engine can be met by (partial) template specialization.</li> |
|---|
| 1644 | <p> |
|---|
| 1645 | |
|---|
| 1646 | <li>runtime-replaceable distributions and associated save/restore |
|---|
| 1647 | functionality: Provide a class hierarchy that invokes distributions by |
|---|
| 1648 | means of a virtual function, thereby allowing for runtime replacement |
|---|
| 1649 | of the actual distribution. Provide a factory function to reconstruct |
|---|
| 1650 | the distribution instance after saving it to some non-volatile media. |
|---|
| 1651 | |
|---|
| 1652 | </ul> |
|---|
| 1653 | |
|---|
| 1654 | |
|---|
| 1655 | <h3>S. Adaptors</h3> |
|---|
| 1656 | |
|---|
| 1657 | Sometimes, users may want to have better control how the bits from the |
|---|
| 1658 | engine are used to fill the mantissa of the floating-point value that |
|---|
| 1659 | serves as input to some distribution. This is possible by writing an |
|---|
| 1660 | engine wrapper and passing that in to the <code>variate_generator</code> as the |
|---|
| 1661 | engine. The <code>variate_generator</code> will only apply automatic adaptations |
|---|
| 1662 | if the output type of the engine is integers and the input type for |
|---|
| 1663 | the distribution is floating-point or vice versa. |
|---|
| 1664 | |
|---|
| 1665 | |
|---|
| 1666 | <h3>Z. Open issues</h3> |
|---|
| 1667 | |
|---|
| 1668 | <ul> |
|---|
| 1669 | <li>Some engines require non-negative template arguments, usually bit |
|---|
| 1670 | counts. Should these be given as "int" or "unsigned int"? Using |
|---|
| 1671 | "unsigned int" sometimes adds significant clutter to the |
|---|
| 1672 | presentation. Or "size_t", but this is probably too large a type?</li> |
|---|
| 1673 | |
|---|
| 1674 | </ul> |
|---|
| 1675 | |
|---|
| 1676 | |
|---|
| 1677 | |
|---|
| 1678 | <h2>IV. Proposed Text</h2> |
|---|
| 1679 | |
|---|
| 1680 | (Insert the following as a new section in clause 26 "Numerics". |
|---|
| 1681 | Adjust the overview at the beginning of clause 26 accordingly.) |
|---|
| 1682 | <p> |
|---|
| 1683 | |
|---|
| 1684 | This subclause defines a facility for generating random numbers. |
|---|
| 1685 | |
|---|
| 1686 | |
|---|
| 1687 | <h3>Random number requirements</h3> |
|---|
| 1688 | |
|---|
| 1689 | A number generator is a function object (std:20.3 |
|---|
| 1690 | [lib.function.objects]). |
|---|
| 1691 | <p> |
|---|
| 1692 | |
|---|
| 1693 | In the following table, <code>X</code> denotes a number generator |
|---|
| 1694 | class returning objects of type <code>T</code>, and <code>u</code> is |
|---|
| 1695 | a (possibly <code>const</code>) value of <code>X</code>. |
|---|
| 1696 | <p> |
|---|
| 1697 | |
|---|
| 1698 | <table border=1> |
|---|
| 1699 | <tr> |
|---|
| 1700 | <th colspan=4 align=center>Number generator requirements (in addition |
|---|
| 1701 | to function object)</th> |
|---|
| 1702 | </tr> |
|---|
| 1703 | |
|---|
| 1704 | <tr> |
|---|
| 1705 | <td>expression</td> |
|---|
| 1706 | <td>return type</td> |
|---|
| 1707 | <td>pre/post-condition</td> |
|---|
| 1708 | <td>complexity</td> |
|---|
| 1709 | </tr> |
|---|
| 1710 | |
|---|
| 1711 | <tr> |
|---|
| 1712 | <td><code>X::result_type</code></td> |
|---|
| 1713 | <td>T</td> |
|---|
| 1714 | <td><code>std::numeric_limits<T>::is_specialized</code> is |
|---|
| 1715 | <code>true</code></td> |
|---|
| 1716 | <td>compile-time</td> |
|---|
| 1717 | </tr> |
|---|
| 1718 | |
|---|
| 1719 | </table> |
|---|
| 1720 | <p> |
|---|
| 1721 | |
|---|
| 1722 | In the following table, <code>X</code> denotes a uniform random number |
|---|
| 1723 | generator class returning objects of type <code>T</code>, |
|---|
| 1724 | <code>u</code> is a value of <code>X</code> and <code>v</code> is a |
|---|
| 1725 | (possibly <code>const</code>) value of <code>X</code>. |
|---|
| 1726 | <p> |
|---|
| 1727 | |
|---|
| 1728 | <table border=1> |
|---|
| 1729 | <tr> |
|---|
| 1730 | <th colspan=4 align=center>Uniform random number generator |
|---|
| 1731 | requirements (in addition to number generator)</th> |
|---|
| 1732 | </tr> |
|---|
| 1733 | |
|---|
| 1734 | <tr> |
|---|
| 1735 | <td>expression</td> |
|---|
| 1736 | <td>return type</td> |
|---|
| 1737 | <td>pre/post-condition</td> |
|---|
| 1738 | <td>complexity</td> |
|---|
| 1739 | </tr> |
|---|
| 1740 | |
|---|
| 1741 | <tr> |
|---|
| 1742 | <td><code>u()</code></td> |
|---|
| 1743 | <td>T</td> |
|---|
| 1744 | <td>-</td> |
|---|
| 1745 | <td>amortized constant</td> |
|---|
| 1746 | </tr> |
|---|
| 1747 | |
|---|
| 1748 | <tr> |
|---|
| 1749 | <td><code>v.min()</code></td> |
|---|
| 1750 | <td><code>T</code></td> |
|---|
| 1751 | <td>Returns some l where l is less than or equal to all values |
|---|
| 1752 | potentially returned by <code>operator()</code>. |
|---|
| 1753 | The return value of this function shall not change during the lifetime |
|---|
| 1754 | of <code>v</code>.</td> |
|---|
| 1755 | <td>constant</td> |
|---|
| 1756 | </tr> |
|---|
| 1757 | |
|---|
| 1758 | <tr> |
|---|
| 1759 | <td><code>v.max()</code></td> |
|---|
| 1760 | <td><code>T</code></td> |
|---|
| 1761 | <td>If <code>std::numeric_limits<T>::is_integer</code>, returns |
|---|
| 1762 | l where l is less than or equal to all values potentially returned by |
|---|
| 1763 | <code>operator()</code>, otherwise, returns l where l is strictly less than all |
|---|
| 1764 | values potentially returned by <code>operator()</code>. In any case, |
|---|
| 1765 | the return value of this function shall not change during the lifetime |
|---|
| 1766 | of <code>v</code>.</td> |
|---|
| 1767 | <td>constant</td> |
|---|
| 1768 | </tr> |
|---|
| 1769 | |
|---|
| 1770 | </table> |
|---|
| 1771 | |
|---|
| 1772 | <p> |
|---|
| 1773 | In the following table, <code>X</code> denotes a pseudo-random number |
|---|
| 1774 | engine class returning objects of type <code>T</code>, <code>t</code> |
|---|
| 1775 | is a value of <code>T</code>, <code>u</code> is a value of |
|---|
| 1776 | <code>X</code>, <code>v</code> is an lvalue of <code>X</code>, |
|---|
| 1777 | <code>it1</code> is an lvalue and <code>it2</code> is a (possibly |
|---|
| 1778 | <code>const</code>) value of an input iterator type <code>It</code> |
|---|
| 1779 | having an unsigned integral value type, <code>x</code>, <code>y</code> |
|---|
| 1780 | are (possibly <code>const</code>) values of |
|---|
| 1781 | <code>X</code>, <code>os</code> is convertible to an lvalue of type |
|---|
| 1782 | <code>std::ostream</code>, and <code>is</code> is convertible to an |
|---|
| 1783 | lvalue of type <code>std::istream</code>. |
|---|
| 1784 | <p> |
|---|
| 1785 | A pseudo-random number engine x has a state x(i) at any given time. |
|---|
| 1786 | The specification of each pseudo-random number engines defines the size of its |
|---|
| 1787 | state in multiples of the size of its <code>result_type</code>, given |
|---|
| 1788 | as an integral constant expression. |
|---|
| 1789 | <p> |
|---|
| 1790 | |
|---|
| 1791 | <table border=1> |
|---|
| 1792 | <tr> |
|---|
| 1793 | <th colspan=4 align=center>Pseudo-random number engine requirements |
|---|
| 1794 | (in addition to uniform random number generator, |
|---|
| 1795 | <code>CopyConstructible</code>, and <code>Assignable</code>)</th> |
|---|
| 1796 | <tr><td>expression</td><td>return type</td> |
|---|
| 1797 | <td>pre/post-condition</td> |
|---|
| 1798 | <td>complexity</td> |
|---|
| 1799 | </tr> |
|---|
| 1800 | |
|---|
| 1801 | <tr> |
|---|
| 1802 | <td><code>X()</code></td> |
|---|
| 1803 | <td>-</td> |
|---|
| 1804 | <td>creates an engine with the same initial state as all other |
|---|
| 1805 | default-constructed engines of type <code>X</code> in the |
|---|
| 1806 | program.</td> |
|---|
| 1807 | <td>O(size of state)</td> |
|---|
| 1808 | </tr> |
|---|
| 1809 | |
|---|
| 1810 | <tr> |
|---|
| 1811 | <td><code>X(it1, it2)</code></td> |
|---|
| 1812 | <td>-</td> |
|---|
| 1813 | <td>creates an engine with the initial state given by the range |
|---|
| 1814 | <code>[it1,it2)</code>. <code>it1</code> is advanced by the size of |
|---|
| 1815 | state. If the size of the range [it1,it2) is insufficient, leaves |
|---|
| 1816 | <code>it1 == it2</code> and throws <code>invalid_argument</code>.</td> |
|---|
| 1817 | <td>O(size of state)</td> |
|---|
| 1818 | </tr> |
|---|
| 1819 | |
|---|
| 1820 | <tr> |
|---|
| 1821 | <td><code>u.seed()</code></td> |
|---|
| 1822 | <td>void</td> |
|---|
| 1823 | <td>post: <code>u == X()</code></td> |
|---|
| 1824 | <td>O(size of state)</td> |
|---|
| 1825 | </tr> |
|---|
| 1826 | |
|---|
| 1827 | <tr> |
|---|
| 1828 | <td><code>u.seed(it1, it2)</code></td> |
|---|
| 1829 | <td>void</td> |
|---|
| 1830 | <td>post: If there are sufficiently many values in [it1, it2) to |
|---|
| 1831 | initialize the state of <code>u</code>, then <code>u == |
|---|
| 1832 | X(it1,it2)</code>. Otherwise, <code>it1 == it2</code>, throws |
|---|
| 1833 | <code>invalid_argument</code>, and further use of <code>u</code> |
|---|
| 1834 | (except destruction) is undefined until a <code>seed</code> member |
|---|
| 1835 | function has been executed without throwing an exception.</td> |
|---|
| 1836 | <td>O(size of state)</td> |
|---|
| 1837 | </tr> |
|---|
| 1838 | |
|---|
| 1839 | <tr> |
|---|
| 1840 | <td><code>u()</code></td> |
|---|
| 1841 | <td><code>T</code> |
|---|
| 1842 | <td>given the state u(i) of the engine, computes u(i+1), sets the |
|---|
| 1843 | state to u(i+1), and returns some output dependent on u(i+1)</td> |
|---|
| 1844 | <td>amortized constant</td> |
|---|
| 1845 | </tr> |
|---|
| 1846 | |
|---|
| 1847 | <tr> |
|---|
| 1848 | <td><code>x == y</code></td> |
|---|
| 1849 | <td><code>bool</code></td> |
|---|
| 1850 | <td><code>==</code> is an equivalence relation. The current state x(i) |
|---|
| 1851 | of x is equal to the current state y(j) of y.</td> |
|---|
| 1852 | <td>O(size of state)</td> |
|---|
| 1853 | </tr> |
|---|
| 1854 | |
|---|
| 1855 | <tr> |
|---|
| 1856 | <td><code>x != y</code></td> |
|---|
| 1857 | <td><code>bool</code></td> |
|---|
| 1858 | <td><code>!(x == y)</code></td> |
|---|
| 1859 | <td>O(size of state)</td> |
|---|
| 1860 | </tr> |
|---|
| 1861 | |
|---|
| 1862 | <tr> |
|---|
| 1863 | <td><code>os << x</code></td> |
|---|
| 1864 | <td><code>std::ostream&</code></td> |
|---|
| 1865 | <td>writes the textual representation of the state x(i) of |
|---|
| 1866 | <code>x</code> to <code>os</code>, with |
|---|
| 1867 | <code>os.<em>fmtflags</em></code> set to |
|---|
| 1868 | <code>ios_base::dec|ios_base::fixed|ios_base::left</code> and the fill |
|---|
| 1869 | character set to the space character. In the output, adjacent numbers |
|---|
| 1870 | are separated by one or more space characters. |
|---|
| 1871 | <br> |
|---|
| 1872 | post: The <code>os.<em>fmtflags</em></code> and fill character are |
|---|
| 1873 | unchanged. </td> |
|---|
| 1874 | <td>O(size of state)</td> |
|---|
| 1875 | </tr> |
|---|
| 1876 | |
|---|
| 1877 | <tr> |
|---|
| 1878 | <td><code>is >> v</code></td> |
|---|
| 1879 | <td><code>std::istream&</code></td> |
|---|
| 1880 | <td>sets the state v(i) of <code>v</code> as determined by reading its |
|---|
| 1881 | textual representation from <code>is</code>. |
|---|
| 1882 | <br> |
|---|
| 1883 | post: The <code>is.<em>fmtflags</em></code> are unchanged.</td> |
|---|
| 1884 | <td>O(size of state)</td> |
|---|
| 1885 | </tr> |
|---|
| 1886 | |
|---|
| 1887 | </table> |
|---|
| 1888 | <p> |
|---|
| 1889 | |
|---|
| 1890 | In the following table, <code>X</code> denotes a random distribution |
|---|
| 1891 | class returning objects of type <code>T</code>, <code>u</code> is a |
|---|
| 1892 | value of <code>X</code>, <code>x</code> is a (possibly const) |
|---|
| 1893 | value of <code>X</code>, and <code>e</code> is an lvalue of an |
|---|
| 1894 | arbitrary type that meets the requirements of a uniform random number |
|---|
| 1895 | generator, returning values of type <code>U</code>. |
|---|
| 1896 | <p> |
|---|
| 1897 | |
|---|
| 1898 | <table border=1> |
|---|
| 1899 | <tr> |
|---|
| 1900 | <th colspan=4 align=center>Random distribution requirements |
|---|
| 1901 | (in addition to number generator, |
|---|
| 1902 | <code>CopyConstructible</code>, and <code>Assignable</code>)</th> |
|---|
| 1903 | <tr><td>expression</td><td>return type</td> |
|---|
| 1904 | <td>pre/post-condition</td> |
|---|
| 1905 | <td>complexity</td> |
|---|
| 1906 | </tr> |
|---|
| 1907 | |
|---|
| 1908 | <tr> |
|---|
| 1909 | <td><code>X::input_type</code></td> |
|---|
| 1910 | <td>U</td> |
|---|
| 1911 | <td>-</td> |
|---|
| 1912 | <td>compile-time</td> |
|---|
| 1913 | </tr> |
|---|
| 1914 | |
|---|
| 1915 | <tr> |
|---|
| 1916 | <td><code>u.reset()</code></td> |
|---|
| 1917 | <td><code>void</code></td> |
|---|
| 1918 | <td>subsequent uses of <code>u</code> do not depend on values |
|---|
| 1919 | produced by <code>e</code> prior to invoking <code>reset</code>.</td> |
|---|
| 1920 | <td>constant</td> |
|---|
| 1921 | </tr> |
|---|
| 1922 | |
|---|
| 1923 | <tr> |
|---|
| 1924 | <td><code>u(e)</code></td> |
|---|
| 1925 | <td><code>T</code></td> |
|---|
| 1926 | <td>the sequence of numbers returned by successive invocations with |
|---|
| 1927 | the same object <code>e</code> is randomly distributed with some |
|---|
| 1928 | probability density function p(x)</td> |
|---|
| 1929 | <td>amortized constant number of invocations of <code>e</code></td> |
|---|
| 1930 | </tr> |
|---|
| 1931 | |
|---|
| 1932 | <tr> |
|---|
| 1933 | <td><code>os << x</code></td> |
|---|
| 1934 | <td><code>std::ostream&</code></td> |
|---|
| 1935 | <td>writes a textual representation for the parameters and additional |
|---|
| 1936 | internal data of the distribution <code>x</code> to <code>os</code>. |
|---|
| 1937 | <br> |
|---|
| 1938 | post: The <code>os.<em>fmtflags</em></code> and fill character are |
|---|
| 1939 | unchanged.</td> |
|---|
| 1940 | <td>O(size of state)</td> |
|---|
| 1941 | </tr> |
|---|
| 1942 | |
|---|
| 1943 | <tr> |
|---|
| 1944 | <td><code>is >> u</code></td> |
|---|
| 1945 | <td><code>std::istream&</code></td> |
|---|
| 1946 | <td>restores the parameters and additional internal data of the |
|---|
| 1947 | distribution <code>u</code>. |
|---|
| 1948 | <br> |
|---|
| 1949 | pre: <code>is</code> provides a textual representation that was |
|---|
| 1950 | previously written by <code>operator<<</code> |
|---|
| 1951 | <br> |
|---|
| 1952 | post: The <code>is.<em>fmtflags</em></code> are unchanged.</td> |
|---|
| 1953 | <td>O(size of state)</td> |
|---|
| 1954 | </tr> |
|---|
| 1955 | |
|---|
| 1956 | </table> |
|---|
| 1957 | <p> |
|---|
| 1958 | |
|---|
| 1959 | Additional requirements: The sequence of numbers produced by |
|---|
| 1960 | repeated invocations of <code>x(e)</code> does not change whether or |
|---|
| 1961 | not <code>os << x</code> is invoked between any of the |
|---|
| 1962 | invocations <code>x(e)</code>. If a textual representation |
|---|
| 1963 | is written using <code>os << x</code> and that representation |
|---|
| 1964 | is restored into the same or a different object <code>y</code> of the |
|---|
| 1965 | same type using <code>is >> y</code>, repeated invocations of |
|---|
| 1966 | <code>y(e)</code> produce the same sequence of random numbers as would |
|---|
| 1967 | repeated invocations of <code>x(e)</code>. |
|---|
| 1968 | <p> |
|---|
| 1969 | |
|---|
| 1970 | In the following subclauses, a template parameter named |
|---|
| 1971 | <code>UniformRandomNumberGenerator</code> shall denote a class that |
|---|
| 1972 | satisfies all the requirements of a uniform random number generator. |
|---|
| 1973 | Moreover, a template parameter named <code>Distribution</code> shall |
|---|
| 1974 | denote a type that satisfies all the requirements of a random |
|---|
| 1975 | distribution. |
|---|
| 1976 | Furthermore, a template parameter named <code>RealType</code> shall |
|---|
| 1977 | denote a type that holds an approximation to a real number. This type |
|---|
| 1978 | shall meet the requirements for a numeric type (26.1 |
|---|
| 1979 | [lib.numeric.requirements]), the binary operators +, -, *, / shall be |
|---|
| 1980 | applicable to it, a conversion from <code>double</code> shall exist, |
|---|
| 1981 | and function signatures corresponding to those |
|---|
| 1982 | for type <code>double</code> in subclause 26.5 [lib.c.math] shall be |
|---|
| 1983 | available by argument-dependent lookup (3.4.2 [basic.lookup.koenig]). |
|---|
| 1984 | <em>[Note: The built-in floating-point types <code>float</code> |
|---|
| 1985 | and <code>double</code> meet these requirements.]</em> |
|---|
| 1986 | |
|---|
| 1987 | |
|---|
| 1988 | <h3>Header <code><random></code> synopsis</h3> |
|---|
| 1989 | |
|---|
| 1990 | <pre> |
|---|
| 1991 | namespace std { |
|---|
| 1992 | template<class UniformRandomNumberGenerator, class Distribution> |
|---|
| 1993 | class variate_generator; |
|---|
| 1994 | |
|---|
| 1995 | template<class IntType, IntType a, IntType c, IntType m> |
|---|
| 1996 | class linear_congruential; |
|---|
| 1997 | |
|---|
| 1998 | template<class UIntType, int w, int n, int m, int r, UIntType a, int u, |
|---|
| 1999 | int s, UIntType b, int t, UIntType c, int l> |
|---|
| 2000 | class mersenne_twister; |
|---|
| 2001 | |
|---|
| 2002 | template<class IntType, IntType m, int s, int r> |
|---|
| 2003 | class subtract_with_carry; |
|---|
| 2004 | |
|---|
| 2005 | template<class RealType, int w, int s, int r> |
|---|
| 2006 | class subtract_with_carry_01; |
|---|
| 2007 | |
|---|
| 2008 | template<class UniformRandomNumberGenerator, int p, int r> |
|---|
| 2009 | class discard_block; |
|---|
| 2010 | |
|---|
| 2011 | template<class UniformRandomNumberGenerator1, int s1, |
|---|
| 2012 | class UniformRandomNumberGenerator2, int s2> |
|---|
| 2013 | class xor_combine; |
|---|
| 2014 | |
|---|
| 2015 | class random_device; |
|---|
| 2016 | |
|---|
| 2017 | template<class IntType = int> |
|---|
| 2018 | class uniform_int; |
|---|
| 2019 | |
|---|
| 2020 | template<class RealType = double> |
|---|
| 2021 | class bernoulli_distribution; |
|---|
| 2022 | |
|---|
| 2023 | template<class IntType = int, class RealType = double> |
|---|
| 2024 | class geometric_distribution; |
|---|
| 2025 | |
|---|
| 2026 | template<class IntType = int, class RealType = double> |
|---|
| 2027 | class poisson_distribution; |
|---|
| 2028 | |
|---|
| 2029 | template<class IntType = int, class RealType = double> |
|---|
| 2030 | class binomial_distribution; |
|---|
| 2031 | |
|---|
| 2032 | template<class RealType = double> |
|---|
| 2033 | class uniform_real; |
|---|
| 2034 | |
|---|
| 2035 | template<class RealType = double> |
|---|
| 2036 | class exponential_distribution; |
|---|
| 2037 | |
|---|
| 2038 | template<class RealType = double> |
|---|
| 2039 | class normal_distribution; |
|---|
| 2040 | |
|---|
| 2041 | template<class RealType = double> |
|---|
| 2042 | class gamma_distribution; |
|---|
| 2043 | |
|---|
| 2044 | } // namespace std |
|---|
| 2045 | </pre> |
|---|
| 2046 | |
|---|
| 2047 | |
|---|
| 2048 | <h3>Class template <code>variate_generator</code></h3> |
|---|
| 2049 | |
|---|
| 2050 | A <code>variate_generator</code> produces random numbers, drawing |
|---|
| 2051 | randomness from an underlying uniform random number generator and |
|---|
| 2052 | shaping the distribution of the numbers corresponding to a |
|---|
| 2053 | distribution function. |
|---|
| 2054 | <pre> |
|---|
| 2055 | template<class Engine, class Distribution> |
|---|
| 2056 | class variate_generator |
|---|
| 2057 | { |
|---|
| 2058 | public: |
|---|
| 2059 | typedef Engine engine_type; |
|---|
| 2060 | typedef /* <em>implementation defined</em> */ engine_value_type; |
|---|
| 2061 | typedef Distribution distribution_type; |
|---|
| 2062 | typedef typename Distribution::result_type result_type; |
|---|
| 2063 | |
|---|
| 2064 | variate_generator(engine_type eng, distribution_type d); |
|---|
| 2065 | |
|---|
| 2066 | result_type operator()(); |
|---|
| 2067 | template<class T> result_type operator()(T value); |
|---|
| 2068 | |
|---|
| 2069 | engine_value_type& engine(); |
|---|
| 2070 | const engine_value_type& engine() const; |
|---|
| 2071 | |
|---|
| 2072 | distribution_type& distribution(); |
|---|
| 2073 | const distribution_type& distribution() const; |
|---|
| 2074 | |
|---|
| 2075 | result_type min() const; |
|---|
| 2076 | result_type max() const; |
|---|
| 2077 | }; |
|---|
| 2078 | </pre> |
|---|
| 2079 | |
|---|
| 2080 | The template argument for the parameter <code>Engine</code> shall be |
|---|
| 2081 | of the form <code><em>U</em></code>, <code><em>U</em>&</code>, or |
|---|
| 2082 | <code><em>U</em>*</code>, where <code><em>U</em></code> denotes a |
|---|
| 2083 | class that satisfies all the requirements of a uniform random number |
|---|
| 2084 | generator. The member <code>engine_value_type</code> shall name |
|---|
| 2085 | <code><em>U</em></code>. |
|---|
| 2086 | <p> |
|---|
| 2087 | |
|---|
| 2088 | Specializations of <code>variate_generator</code> satisfy the |
|---|
| 2089 | requirements of CopyConstructible. They also satisfy the requirements |
|---|
| 2090 | of Assignable unless the template parameter <code>Engine</code> is of |
|---|
| 2091 | the form <code><em>U</em>&</code>. |
|---|
| 2092 | <p> |
|---|
| 2093 | |
|---|
| 2094 | The complexity of all functions specified in this section is constant. |
|---|
| 2095 | No function described in this section except the constructor throws an |
|---|
| 2096 | exception. |
|---|
| 2097 | <p> |
|---|
| 2098 | |
|---|
| 2099 | <pre> variate_generator(engine_type eng, distribution_type d)</pre> |
|---|
| 2100 | <strong>Effects:</strong> Constructs a <code>variate_generator</code> |
|---|
| 2101 | object with the associated uniform random number generator |
|---|
| 2102 | <code>eng</code> and the associated random distribution |
|---|
| 2103 | <code>d</code>. |
|---|
| 2104 | <br> |
|---|
| 2105 | <strong>Throws:</strong> If and what the copy constructor of Engine or |
|---|
| 2106 | Distribution throws. |
|---|
| 2107 | |
|---|
| 2108 | <pre> result_type operator()()</pre> |
|---|
| 2109 | <strong>Returns:</strong> <code>distribution()(e)</code> |
|---|
| 2110 | <br> |
|---|
| 2111 | <strong>Notes:</strong> The sequence of numbers produced by the |
|---|
| 2112 | uniform random number generator <code>e</code>, s<sub>e</sub>, is |
|---|
| 2113 | obtained from the sequence of numbers produced by the associated |
|---|
| 2114 | uniform random number generator <code>eng</code>, s<sub>eng</sub>, as |
|---|
| 2115 | follows: Consider the values of |
|---|
| 2116 | <code>numeric_limits<<em>T</em>>::is_integer</code> for |
|---|
| 2117 | <code><em>T</em></code> both <code>Distribution::input_type</code> and |
|---|
| 2118 | <code>engine_value_type::result_type</code>. If the values for both |
|---|
| 2119 | types are <code>true</code>, then s<sub>e</sub> is identical to |
|---|
| 2120 | s<sub>eng</sub>. Otherwise, if the values for both types are |
|---|
| 2121 | <code>false</code>, then the numbers in s<sub>eng</sub> are divided by |
|---|
| 2122 | <code>engine().max()-engine().min()</code> to obtain the |
|---|
| 2123 | numbers in s<sub>e</sub>. Otherwise, if the value for |
|---|
| 2124 | <code>engine_value_type::result_type</code> is <code>true</code> and |
|---|
| 2125 | the value for <code>Distribution::input_type</code> is |
|---|
| 2126 | <code>false</code>, then the numbers in s<sub>eng</sub> are divided by |
|---|
| 2127 | <code>engine().max()-engine().min()+1</code> to obtain the |
|---|
| 2128 | numbers in s<sub>e</sub>. Otherwise, the mapping from s<sub>eng</sub> |
|---|
| 2129 | to s<sub>e</sub> is implementation-defined. In all cases, an implicit |
|---|
| 2130 | conversion from <code>engine_value_type::result_type</code> to |
|---|
| 2131 | <code>Distribution::input_type</code> is performed. If such a |
|---|
| 2132 | conversion does not exist, the program is ill-formed. |
|---|
| 2133 | |
|---|
| 2134 | <pre> template<class T> result_type operator()(T value)</pre> |
|---|
| 2135 | <strong>Returns:</strong> <code>distribution()(e, value)</code>. For |
|---|
| 2136 | the semantics of <code>e</code>, see the description of |
|---|
| 2137 | <code>operator()()</code>. |
|---|
| 2138 | |
|---|
| 2139 | <pre> engine_value_type& engine()</pre> |
|---|
| 2140 | <strong>Returns:</strong> A reference to the associated uniform random |
|---|
| 2141 | number generator. |
|---|
| 2142 | |
|---|
| 2143 | <pre> const engine_value_type& engine() const</pre> |
|---|
| 2144 | <strong>Returns:</strong> A reference to the associated uniform random |
|---|
| 2145 | number generator. |
|---|
| 2146 | |
|---|
| 2147 | <pre> distribution_type& distribution()</pre> |
|---|
| 2148 | <strong>Returns:</strong> A reference to the associated random |
|---|
| 2149 | distribution. |
|---|
| 2150 | |
|---|
| 2151 | <pre> const distribution_type& distribution() const</pre> |
|---|
| 2152 | <strong>Returns:</strong> A reference to the associated random |
|---|
| 2153 | distribution. |
|---|
| 2154 | |
|---|
| 2155 | <pre> result_type min() const</pre> |
|---|
| 2156 | <strong>Precondition:</strong> <code>distribution().min()</code> is |
|---|
| 2157 | well-formed |
|---|
| 2158 | <br> |
|---|
| 2159 | <strong>Returns:</strong> <code>distribution().min()</code> |
|---|
| 2160 | |
|---|
| 2161 | <pre> result_type max() const</pre> |
|---|
| 2162 | <strong>Precondition:</strong> <code>distribution().max()</code> is |
|---|
| 2163 | well-formed |
|---|
| 2164 | <br> |
|---|
| 2165 | <strong>Returns:</strong> <code>distribution().max()</code> |
|---|
| 2166 | |
|---|
| 2167 | |
|---|
| 2168 | <h3>Random number engine class templates</h3> |
|---|
| 2169 | |
|---|
| 2170 | Except where specified otherwise, the complexity of all functions specified in |
|---|
| 2171 | the following sections is constant. No function described in this |
|---|
| 2172 | section except the constructor and seed functions taking an iterator |
|---|
| 2173 | range [it1,it2) throws an exception. |
|---|
| 2174 | <p> |
|---|
| 2175 | |
|---|
| 2176 | The class templates specified in this section satisfy all the |
|---|
| 2177 | requirements of a pseudo-random number engine (given in tables in |
|---|
| 2178 | section x.x), except where specified otherwise. Descriptions are |
|---|
| 2179 | provided here only for operations on the engines that are not |
|---|
| 2180 | described in one of these tables or for operations where there is |
|---|
| 2181 | additional semantic information. |
|---|
| 2182 | <p> |
|---|
| 2183 | |
|---|
| 2184 | All members declared <code>static const</code> in any of the following |
|---|
| 2185 | class templates shall be defined in such a way that they are usable as |
|---|
| 2186 | integral constant expressions. |
|---|
| 2187 | |
|---|
| 2188 | |
|---|
| 2189 | <h4>Class template <code>linear_congruential</code></h4> |
|---|
| 2190 | |
|---|
| 2191 | A <code>linear_congruential</code> engine produces random numbers |
|---|
| 2192 | using a linear function x(i+1) := (a * x(i) + c) mod m. |
|---|
| 2193 | |
|---|
| 2194 | <pre> |
|---|
| 2195 | namespace std { |
|---|
| 2196 | template<class IntType, IntType a, IntType c, IntType m> |
|---|
| 2197 | class linear_congruential |
|---|
| 2198 | { |
|---|
| 2199 | public: |
|---|
| 2200 | // <em>types</em> |
|---|
| 2201 | typedef IntType result_type; |
|---|
| 2202 | |
|---|
| 2203 | // <em>parameter values</em> |
|---|
| 2204 | static const IntType multiplier = a; |
|---|
| 2205 | static const IntType increment = c; |
|---|
| 2206 | static const IntType modulus = m; |
|---|
| 2207 | |
|---|
| 2208 | // <em> constructors and member function</em> |
|---|
| 2209 | explicit linear_congruential(IntType x0 = 1); |
|---|
| 2210 | template<class In> linear_congruential(In& first, In last); |
|---|
| 2211 | void seed(IntType x0 = 1); |
|---|
| 2212 | template<class In> void seed(In& first, In last); |
|---|
| 2213 | result_type min() const; |
|---|
| 2214 | result_type max() const; |
|---|
| 2215 | result_type operator()(); |
|---|
| 2216 | }; |
|---|
| 2217 | |
|---|
| 2218 | template<class IntType, IntType a, IntType c, IntType m> |
|---|
| 2219 | bool operator==(const linear_congruential<IntType, a, c, m>& x, |
|---|
| 2220 | const linear_congruential<IntType, a, c, m>& y); |
|---|
| 2221 | template<class IntType, IntType a, IntType c, IntType m> |
|---|
| 2222 | bool operator!=(const linear_congruential<IntType, a, c, m>& x, |
|---|
| 2223 | const linear_congruential<IntType, a, c, m>& y); |
|---|
| 2224 | |
|---|
| 2225 | template<class CharT, class traits, |
|---|
| 2226 | class IntType, IntType a, IntType c, IntType m> |
|---|
| 2227 | basic_ostream<CharT, traits>& operator<<(basic_ostream<CharT, traits>& os, |
|---|
| 2228 | const linear_congruential<IntType, a, c, m>& x); |
|---|
| 2229 | template<class CharT, class traits, |
|---|
| 2230 | class IntType, IntType a, IntType c, IntType m> |
|---|
| 2231 | basic_istream<CharT, traits>& operator>>(basic_istream<CharT, traits>& is, |
|---|
| 2232 | linear_congruential<IntType, a, c, m>& x); |
|---|
| 2233 | } |
|---|
| 2234 | </pre> |
|---|
| 2235 | |
|---|
| 2236 | The template parameter <code>IntType</code> shall denote an integral |
|---|
| 2237 | type large enough to store values up to (m-1). If the template |
|---|
| 2238 | parameter <code>m</code> is 0, the behaviour is |
|---|
| 2239 | implementation-defined. Otherwise, the template parameters |
|---|
| 2240 | <code>a</code> and <code>c</code> shall be less than m. |
|---|
| 2241 | <p> |
|---|
| 2242 | |
|---|
| 2243 | The size of the state x(i) is 1. |
|---|
| 2244 | |
|---|
| 2245 | |
|---|
| 2246 | <pre> explicit linear_congruential(IntType x0 = 1)</pre> |
|---|
| 2247 | <strong>Requires:</strong> <code>c > 0 || (x0 % m) > 0</code> |
|---|
| 2248 | <br> |
|---|
| 2249 | <strong>Effects:</strong> Constructs a |
|---|
| 2250 | <code>linear_congruential</code> engine with state x(0) := |
|---|
| 2251 | <code>x0</code> mod m. |
|---|
| 2252 | |
|---|
| 2253 | <pre> void seed(IntType x0 = 1)</pre> |
|---|
| 2254 | <strong>Requires:</strong> <code>c > 0 || (x0 % m) > 0</code> |
|---|
| 2255 | <br> |
|---|
| 2256 | <strong>Effects:</strong> Sets the state x(i) of the engine to |
|---|
| 2257 | <code>x0</code> mod m. |
|---|
| 2258 | |
|---|
| 2259 | <pre> template<class In> linear_congruential(In& first, In last)</pre> |
|---|
| 2260 | <strong>Requires:</strong> <code>c > 0 || *first > 0</code> |
|---|
| 2261 | <br> |
|---|
| 2262 | <strong>Effects:</strong> Sets the state x(i) of the engine to |
|---|
| 2263 | <code>*first</code> mod m. |
|---|
| 2264 | <br> |
|---|
| 2265 | <strong>Complexity:</strong> Exactly one dereference of |
|---|
| 2266 | <code>*first</code>. |
|---|
| 2267 | |
|---|
| 2268 | |
|---|
| 2269 | <pre> |
|---|
| 2270 | template<class CharT, class traits, |
|---|
| 2271 | class IntType, IntType a, IntType c, IntType m> |
|---|
| 2272 | basic_ostream<CharT, traits>& operator<<(basic_ostream<CharT, traits>& os, |
|---|
| 2273 | const linear_congruential<IntType, a, c, m>& x); |
|---|
| 2274 | </pre> |
|---|
| 2275 | <strong>Effects:</strong> Writes x(i) to <code>os</code>. |
|---|
| 2276 | |
|---|
| 2277 | |
|---|
| 2278 | <h4>Class template <code>mersenne_twister</code></h4> |
|---|
| 2279 | |
|---|
| 2280 | A <code>mersenne_twister</code> engine produces random numbers |
|---|
| 2281 | o(x(i)) using the following computation, performed modulo |
|---|
| 2282 | 2<sup>w</sup>. <code>um</code> is a value with only the upper |
|---|
| 2283 | <code>w-r</code> bits set in its binary representation. |
|---|
| 2284 | <code>lm</code> is a value with only its lower <code>r</code> bits set |
|---|
| 2285 | in its binary representation. <em>rshift</em> is a bitwise right |
|---|
| 2286 | shift with zero-valued bits appearing in the high bits of the result. |
|---|
| 2287 | <em>lshift</em> is a bitwise left shift with zero-valued bits |
|---|
| 2288 | appearing in the low bits of the result. |
|---|
| 2289 | |
|---|
| 2290 | <ul> |
|---|
| 2291 | <li>y(i) = (x(i-n) <em>bitand</em> um) | (x(i-(n-1)) <em>bitand</em> lm) |
|---|
| 2292 | <li>If the lowest bit of the binary representation of y(i) is set, |
|---|
| 2293 | x(i) = x(i-(n-m)) <em>xor</em> (y(i) <em>rshift</em> 1) <em>xor</em> a; |
|---|
| 2294 | otherwise x(i) = x(i-(n-m)) <em>xor</em> (y(i) <em>rshift</em> 1). |
|---|
| 2295 | <li>z1(i) = x(i) <em>xor</em> ( x(i) <em>rshift</em> u ) |
|---|
| 2296 | <li>z2(i) = z1(i) <em>xor</em> ( (z1(i) <em>lshift</em> s) <em>bitand</em> b ) |
|---|
| 2297 | <li>z3(i) = z2(i) <em>xor</em> ( (z2(i) <em>lshift</em> t) <em>bitand</em> c ) |
|---|
| 2298 | <li>o(x(i)) = z3(i) <em>xor</em> ( z3(i) <em>rshift</em> l ) |
|---|
| 2299 | </ul> |
|---|
| 2300 | |
|---|
| 2301 | <pre> |
|---|
| 2302 | namespace std { |
|---|
| 2303 | template<class UIntType, int w, int n, int m, int r, UIntType a, int u, |
|---|
| 2304 | int s, UIntType b, int t, UIntType c, int l> |
|---|
| 2305 | class mersenne_twister |
|---|
| 2306 | { |
|---|
| 2307 | public: |
|---|
| 2308 | // <em>types</em> |
|---|
| 2309 | typedef UIntType result_type; |
|---|
| 2310 | |
|---|
| 2311 | // <em>parameter values</em> |
|---|
| 2312 | static const int word_size = w; |
|---|
| 2313 | static const int state_size = n; |
|---|
| 2314 | static const int shift_size = m; |
|---|
| 2315 | static const int mask_bits = r; |
|---|
| 2316 | static const UIntType parameter_a = a; |
|---|
| 2317 | static const int output_u = u; |
|---|
| 2318 | static const int output_s = s; |
|---|
| 2319 | static const UIntType output_b = b; |
|---|
| 2320 | static const int output_t = t; |
|---|
| 2321 | static const UIntType output_c = c; |
|---|
| 2322 | static const int output_l = l; |
|---|
| 2323 | |
|---|
| 2324 | // <em> constructors and member function</em> |
|---|
| 2325 | mersenne_twister(); |
|---|
| 2326 | explicit mersenne_twister(UIntType value); |
|---|
| 2327 | template<class In> mersenne_twister(In& first, In last); |
|---|
| 2328 | void seed(); |
|---|
| 2329 | void seed(UIntType value); |
|---|
| 2330 | template<class In> void seed(In& first, In last); |
|---|
| 2331 | result_type min() const; |
|---|
| 2332 | result_type max() const; |
|---|
| 2333 | result_type operator()(); |
|---|
| 2334 | }; |
|---|
| 2335 | |
|---|
| 2336 | template<class UIntType, int w, int n, int m, int r, UIntType a, int u, |
|---|
| 2337 | int s, UIntType b, int t, UIntType c, int l> |
|---|
| 2338 | bool operator==(const mersenne_twister<UIntType, w, n, m, r, a, u, s, b, t, c, l>& y, |
|---|
| 2339 | const mersenne_twister<UIntType, w, n, m, r, a, u, s, b, t, c, l>& x); |
|---|
| 2340 | template<class UIntType, int w, int n, int m, int r, UIntType a, int u, |
|---|
| 2341 | int s, UIntType b, int t, UIntType c, int l> |
|---|
| 2342 | bool operator!=(const mersenne_twister<UIntType, w, n, m, r, a, u, s, b, t, c, l>& y, |
|---|
| 2343 | const mersenne_twister<UIntType, w, n, m, r, a, u, s, b, t, c, l>& x); |
|---|
| 2344 | |
|---|
| 2345 | template<class CharT, class traits, |
|---|
| 2346 | class UIntType, int w, int n, int m, int r, UIntType a, int u, |
|---|
| 2347 | int s, UIntType b, int t, UIntType c, int l> |
|---|
| 2348 | basic_ostream<CharT, traits>& operator<<(basic_ostream<CharT, traits>& os, |
|---|
| 2349 | const mersenne_twister<UIntType, w, n, m, r, a, u, s, b, t, c, l>& x); |
|---|
| 2350 | template<class CharT, class traits, |
|---|
| 2351 | class UIntType, int w, int n, int m, int r, UIntType a, int u, |
|---|
| 2352 | int s, UIntType b, int t, UIntType c, int l> |
|---|
| 2353 | basic_istream<CharT, traits>& operator>>(basic_istream<CharT, traits>& is, |
|---|
| 2354 | mersenne_twister<UIntType, w, n, m, r, a, u, s, b, t, c, l>& x); |
|---|
| 2355 | } |
|---|
| 2356 | </pre> |
|---|
| 2357 | |
|---|
| 2358 | The template parameter <code>UIntType</code> shall denote an unsigned |
|---|
| 2359 | integral type large enough to store values up to |
|---|
| 2360 | 2<sup>w</sup>-1. Also, the following relations shall hold: |
|---|
| 2361 | 1<=m<=n. 0<=r,u,s,t,l<=w. 0<=a,b,c<=2<sup>w</sup>-1. |
|---|
| 2362 | <p> |
|---|
| 2363 | |
|---|
| 2364 | The size of the state x(i) is <code>n</code>. |
|---|
| 2365 | |
|---|
| 2366 | |
|---|
| 2367 | <pre> mersenne_twister()</pre> |
|---|
| 2368 | <strong>Effects:</strong> Constructs a <code>mersenne_twister</code> |
|---|
| 2369 | engine and invokes <code>seed()</code>. |
|---|
| 2370 | |
|---|
| 2371 | <pre> explicit mersenne_twister(result_type value)</pre> |
|---|
| 2372 | <strong>Effects:</strong> Constructs a <code>mersenne_twister</code> |
|---|
| 2373 | engine and invokes <code>seed(value)</code>. |
|---|
| 2374 | |
|---|
| 2375 | <pre> template<class In> mersenne_twister(In& first, In last)</pre> |
|---|
| 2376 | <strong>Effects:</strong> Constructs a <code>mersenne_twister</code> |
|---|
| 2377 | engine and invokes <code>seed(first, last)</code>. |
|---|
| 2378 | |
|---|
| 2379 | <pre> void seed()</pre> |
|---|
| 2380 | <strong>Effects:</strong> Invokes |
|---|
| 2381 | <code>seed(4357)</code>. |
|---|
| 2382 | |
|---|
| 2383 | <pre> void seed(result_type value)</pre> |
|---|
| 2384 | <strong>Requires:</strong> <code>value > 0</code> |
|---|
| 2385 | <br> |
|---|
| 2386 | <strong>Effects:</strong> With a linear congruential generator l(i) |
|---|
| 2387 | having parameters m<sub>l</sub> = 2<sup>32</sup>, a<sub>l</sub> = 69069, |
|---|
| 2388 | c<sub>l</sub> = 0, and l(0) = <code>value</code>, sets x(-n) ... x(-1) |
|---|
| 2389 | to l(1) ... l(n), respectively. |
|---|
| 2390 | <br> |
|---|
| 2391 | <strong>Complexity:</strong> O(n) |
|---|
| 2392 | |
|---|
| 2393 | <pre> template<class In> void seed(In& first, In last)</pre> |
|---|
| 2394 | <strong>Effects:</strong> Given the values z<sub>0</sub> |
|---|
| 2395 | ... z<sub>n-1</sub> obtained by dereferencing [first, first+n), sets |
|---|
| 2396 | x(-n) ... x(-1) to z<sub>0</sub> mod 2<sup>w</sup> |
|---|
| 2397 | ... z<sub>n-1</sub> mod 2<sup>w</sup>. |
|---|
| 2398 | <br> |
|---|
| 2399 | <strong>Complexity:</strong> Exactly <code>n</code> dereferences of |
|---|
| 2400 | <code>first</code>. |
|---|
| 2401 | |
|---|
| 2402 | <pre> |
|---|
| 2403 | template<class UIntType, int w, int n, int m, int r, UIntType a, int u, |
|---|
| 2404 | int s, UIntType b, int t, UIntType c, int l> |
|---|
| 2405 | bool operator==(const mersenne_twister<UIntType, w, n, m, r, a, u, s, b, t, c, l>& y, |
|---|
| 2406 | const mersenne_twister<UIntType, w, n, m, r, a, u, s, b, t, c, l>& x) |
|---|
| 2407 | </pre> |
|---|
| 2408 | <strong>Returns:</strong> x(i-n) == y(j-n) and ... and x(i-1) == |
|---|
| 2409 | y(j-1) |
|---|
| 2410 | <br> |
|---|
| 2411 | <strong>Notes:</strong> Assumes the next output of <code>x</code> is |
|---|
| 2412 | o(x(i)) and the next output of <code>y</code> is o(y(j)). |
|---|
| 2413 | <br> |
|---|
| 2414 | <strong>Complexity:</strong> O(n) |
|---|
| 2415 | |
|---|
| 2416 | <pre> |
|---|
| 2417 | template<class CharT, class traits, |
|---|
| 2418 | class UIntType, int w, int n, int m, int r, UIntType a, int u, |
|---|
| 2419 | int s, UIntType b, int t, UIntType c, int l> |
|---|
| 2420 | basic_ostream<CharT, traits>& operator<<(basic_ostream<CharT, traits>& os, |
|---|
| 2421 | const mersenne_twister<UIntType, w, n, m, r, a, u, s, b, t, c, l>& x) |
|---|
| 2422 | </pre> |
|---|
| 2423 | <strong>Effects:</strong> Writes x(i-n), ... x(i-1) to |
|---|
| 2424 | <code>os</code>, in that order. |
|---|
| 2425 | <br> |
|---|
| 2426 | <strong>Complexity:</strong> O(n) |
|---|
| 2427 | |
|---|
| 2428 | |
|---|
| 2429 | <h4>Class template <code>subtract_with_carry</code></h4> |
|---|
| 2430 | |
|---|
| 2431 | A <code>subtract_with_carry</code> engine produces integer random numbers |
|---|
| 2432 | using x(i) = (x(i-s) - x(i-r) - carry(i-1)) mod m; carry(i) = 1 if |
|---|
| 2433 | x(i-s) - x(i-r) - carry(i-1) < 0, else carry(i) = 0. |
|---|
| 2434 | <p> |
|---|
| 2435 | |
|---|
| 2436 | <pre> |
|---|
| 2437 | namespace std { |
|---|
| 2438 | template<class IntType, IntType m, int s, int r> |
|---|
| 2439 | class subtract_with_carry |
|---|
| 2440 | { |
|---|
| 2441 | public: |
|---|
| 2442 | // <em>types</em> |
|---|
| 2443 | typedef IntType result_type; |
|---|
| 2444 | |
|---|
| 2445 | // <em>parameter values</em> |
|---|
| 2446 | static const IntType modulus = m; |
|---|
| 2447 | static const int long_lag = r; |
|---|
| 2448 | static const int short_lag = s; |
|---|
| 2449 | |
|---|
| 2450 | // <em> constructors and member function</em> |
|---|
| 2451 | subtract_with_carry(); |
|---|
| 2452 | explicit subtract_with_carry(IntType value); |
|---|
| 2453 | template<class In> subtract_with_carry(In& first, In last); |
|---|
| 2454 | void seed(IntType value = 19780503); |
|---|
| 2455 | template<class In> void seed(In& first, In last); |
|---|
| 2456 | result_type min() const; |
|---|
| 2457 | result_type max() const; |
|---|
| 2458 | result_type operator()(); |
|---|
| 2459 | }; |
|---|
| 2460 | template<class IntType, IntType m, int s, int r> |
|---|
| 2461 | bool operator==(const subtract_with_carry<IntType, m, s, r> & x, |
|---|
| 2462 | const subtract_with_carry<IntType, m, s, r> & y); |
|---|
| 2463 | |
|---|
| 2464 | template<class IntType, IntType m, int s, int r> |
|---|
| 2465 | bool operator!=(const subtract_with_carry<IntType, m, s, r> & x, |
|---|
| 2466 | const subtract_with_carry<IntType, m, s, r> & y); |
|---|
| 2467 | |
|---|
| 2468 | template<class CharT, class Traits, |
|---|
| 2469 | class IntType, IntType m, int s, int r> |
|---|
| 2470 | std::basic_ostream<CharT,Traits>& operator<<(std::basic_ostream<CharT,Traits>& os, |
|---|
| 2471 | const subtract_with_carry<IntType, m, s, r>& f); |
|---|
| 2472 | |
|---|
| 2473 | template<class CharT, class Traits, |
|---|
| 2474 | class IntType, IntType m, int s, int r> |
|---|
| 2475 | std::basic_istream<CharT,Traits>& operator>>(std::basic_istream<CharT,Traits>& is, |
|---|
| 2476 | subtract_with_carry<IntType, m, s, r>& f); |
|---|
| 2477 | } |
|---|
| 2478 | </pre> |
|---|
| 2479 | |
|---|
| 2480 | The template parameter <code>IntType</code> shall denote a signed |
|---|
| 2481 | integral type large enough to store values up to m-1. The following |
|---|
| 2482 | relation shall hold: 0<s<r. Let w the number of bits in the |
|---|
| 2483 | binary representation of m. |
|---|
| 2484 | <p> |
|---|
| 2485 | |
|---|
| 2486 | The size of the state is <code>r</code>. |
|---|
| 2487 | |
|---|
| 2488 | <pre> subtract_with_carry()</pre> |
|---|
| 2489 | <strong>Effects:</strong> Constructs a <code>subtract_with_carry</code> |
|---|
| 2490 | engine and invokes <code>seed()</code>. |
|---|
| 2491 | |
|---|
| 2492 | <pre> explicit subtract_with_carry(IntType value)</pre> |
|---|
| 2493 | <strong>Effects:</strong> Constructs a <code>subtract_with_carry</code> |
|---|
| 2494 | engine and invokes <code>seed(value)</code>. |
|---|
| 2495 | |
|---|
| 2496 | <pre> template<class In> subtract_with_carry(In& first, In last)</pre> |
|---|
| 2497 | <strong>Effects:</strong> Constructs a <code>subtract_with_carry</code> |
|---|
| 2498 | engine and invokes <code>seed(first, last)</code>. |
|---|
| 2499 | |
|---|
| 2500 | <pre> void seed(IntType value = 19780503)</pre> |
|---|
| 2501 | <strong>Requires:</strong> <code>value > 0</code> |
|---|
| 2502 | <br> |
|---|
| 2503 | <strong>Effects:</strong> With a linear congruential generator l(i) |
|---|
| 2504 | having parameters m<sub>l</sub> = 2147483563, a<sub>l</sub> = 40014, |
|---|
| 2505 | c<sub>l</sub> = 0, and l(0) = <code>value</code>, sets x(-r) ... x(-1) |
|---|
| 2506 | to l(1) mod m ... l(r) mod m, respectively. If x(-1) == 0, sets |
|---|
| 2507 | carry(-1) = 1, else sets carry(-1) = 0. |
|---|
| 2508 | <br> |
|---|
| 2509 | <strong>Complexity:</strong> O(r) |
|---|
| 2510 | |
|---|
| 2511 | <pre> template<class In> void seed(In& first, In last)</pre> |
|---|
| 2512 | <strong>Effects:</strong> With n=w/32+1 (rounded downward) and given |
|---|
| 2513 | the values z<sub>0</sub> ... z<sub>n*r-1</sub> obtained by |
|---|
| 2514 | dereferencing [first, first+n*r), sets x(-r) ... x(-1) to |
|---|
| 2515 | (z<sub>0</sub> * 2<sup>32</sup> + ... + z<sub>n-1</sub> * |
|---|
| 2516 | 2<sup>32*(n-1)</sup>) mod m ... (z<sub>(r-1)*n</sub> * 2<sup>32</sup> |
|---|
| 2517 | + ... + z<sub>r-1</sub> * 2<sup>32*(n-1)</sup>) mod m. If x(-1) == 0, |
|---|
| 2518 | sets carry(-1) = 1, else sets carry(-1) = 0. |
|---|
| 2519 | <br> |
|---|
| 2520 | <strong>Complexity:</strong> Exactly <code>r*n</code> dereferences of |
|---|
| 2521 | <code>first</code>. |
|---|
| 2522 | |
|---|
| 2523 | <pre> |
|---|
| 2524 | template<class IntType, IntType m, int s, int r> |
|---|
| 2525 | bool operator==(const subtract_with_carry<IntType, m, s, r> & x, |
|---|
| 2526 | const subtract_with_carry<IntType, m, s, r> & y) |
|---|
| 2527 | </pre> |
|---|
| 2528 | <strong>Returns:</strong> x(i-r) == y(j-r) and ... and x(i-1) == |
|---|
| 2529 | y(j-1). |
|---|
| 2530 | <br> |
|---|
| 2531 | <strong>Notes:</strong> Assumes the next output of <code>x</code> is |
|---|
| 2532 | x(i) and the next output of <code>y</code> is y(j). |
|---|
| 2533 | <br> |
|---|
| 2534 | <strong>Complexity:</strong> O(r) |
|---|
| 2535 | |
|---|
| 2536 | <pre> |
|---|
| 2537 | template<class CharT, class Traits, |
|---|
| 2538 | class IntType, IntType m, int s, int r> |
|---|
| 2539 | std::basic_ostream<CharT,Traits>& operator<<(std::basic_ostream<CharT,Traits>& os, |
|---|
| 2540 | const subtract_with_carry<IntType, m, s, r>& f) |
|---|
| 2541 | </pre> |
|---|
| 2542 | <strong>Effects:</strong> Writes x(i-r) ... x(i-1), carry(i-1) to |
|---|
| 2543 | <code>os</code>, in that order. |
|---|
| 2544 | <br> |
|---|
| 2545 | <strong>Complexity:</strong> O(r) |
|---|
| 2546 | |
|---|
| 2547 | |
|---|
| 2548 | <h4>Class template <code>subtract_with_carry_01</code></h4> |
|---|
| 2549 | |
|---|
| 2550 | A <code>subtract_with_carry_01</code> engine produces floating-point |
|---|
| 2551 | random numbers using x(i) = (x(i-s) - x(i-r) - carry(i-1)) mod 1; |
|---|
| 2552 | carry(i) = 2<sup>-w</sup> if x(i-s) - x(i-r) - carry(i-1) < 0, else |
|---|
| 2553 | carry(i) = 0. |
|---|
| 2554 | <p> |
|---|
| 2555 | |
|---|
| 2556 | <pre> |
|---|
| 2557 | namespace std { |
|---|
| 2558 | template<class RealType, int w, int s, int r> |
|---|
| 2559 | class subtract_with_carry_01 |
|---|
| 2560 | { |
|---|
| 2561 | public: |
|---|
| 2562 | // <em>types</em> |
|---|
| 2563 | typedef RealType result_type; |
|---|
| 2564 | |
|---|
| 2565 | // <em>parameter values</em> |
|---|
| 2566 | static const int word_size = w; |
|---|
| 2567 | static const int long_lag = r; |
|---|
| 2568 | static const int short_lag = s; |
|---|
| 2569 | |
|---|
| 2570 | // <em> constructors and member function</em> |
|---|
| 2571 | subtract_with_carry_01(); |
|---|
| 2572 | explicit subtract_with_carry_01(unsigned int value); |
|---|
| 2573 | template<class In> subtract_with_carry_01(In& first, In last); |
|---|
| 2574 | void seed(unsigned int value = 19780503); |
|---|
| 2575 | template<class In> void seed(In& first, In last); |
|---|
| 2576 | result_type min() const; |
|---|
| 2577 | result_type max() const; |
|---|
| 2578 | result_type operator()(); |
|---|
| 2579 | }; |
|---|
| 2580 | template<class RealType, int w, int s, int r> |
|---|
| 2581 | bool operator==(const subtract_with_carry_01<RealType, w, s, r> x, |
|---|
| 2582 | const subtract_with_carry_01<RealType, w, s, r> y); |
|---|
| 2583 | |
|---|
| 2584 | template<class RealType, int w, int s, int r> |
|---|
| 2585 | bool operator!=(const subtract_with_carry_01<RealType, w, s, r> x, |
|---|
| 2586 | const subtract_with_carry_01<RealType, w, s, r> y); |
|---|
| 2587 | |
|---|
| 2588 | template<class CharT, class Traits, |
|---|
| 2589 | class RealType, int w, int s, int r> |
|---|
| 2590 | std::basic_ostream<CharT,Traits>& operator<<(std::basic_ostream<CharT,Traits>& os, |
|---|
| 2591 | const subtract_with_carry_01<RealType, w, s, r>& f); |
|---|
| 2592 | |
|---|
| 2593 | template<class CharT, class Traits, |
|---|
| 2594 | class RealType, int w, int s, int r> |
|---|
| 2595 | std::basic_istream<CharT,Traits>& operator>>(std::basic_istream<CharT,Traits>& is, |
|---|
| 2596 | subtract_with_carry_01<RealType, w, s, r>& f); |
|---|
| 2597 | } |
|---|
| 2598 | </pre> |
|---|
| 2599 | |
|---|
| 2600 | The following relation shall hold: 0<s<r. |
|---|
| 2601 | <p> |
|---|
| 2602 | |
|---|
| 2603 | The size of the state is <code>r</code>. |
|---|
| 2604 | |
|---|
| 2605 | <pre> subtract_with_carry_01()</pre> |
|---|
| 2606 | <strong>Effects:</strong> Constructs a <code>subtract_with_carry_01</code> |
|---|
| 2607 | engine and invokes <code>seed()</code>. |
|---|
| 2608 | |
|---|
| 2609 | <pre> explicit subtract_with_carry_01(unsigned int value)</pre> |
|---|
| 2610 | <strong>Effects:</strong> Constructs a <code>subtract_with_carry_01</code> |
|---|
| 2611 | engine and invokes <code>seed(value)</code>. |
|---|
| 2612 | |
|---|
| 2613 | <pre> template<class In> subtract_with_carry_01(In& first, In last)</pre> |
|---|
| 2614 | <strong>Effects:</strong> Constructs a <code>subtract_with_carry_01</code> |
|---|
| 2615 | engine and invokes <code>seed(first, last)</code>. |
|---|
| 2616 | |
|---|
| 2617 | <pre> void seed(unsigned int value = 19780503)</pre> |
|---|
| 2618 | <strong>Effects:</strong> With a linear congruential generator l(i) |
|---|
| 2619 | having parameters m = 2147483563, a = 40014, c = 0, and l(0) = |
|---|
| 2620 | <code>value</code>, sets x(-r) ... x(-1) to (l(1)*2<sup>-w</sup>) mod 1 |
|---|
| 2621 | ... (l(r)*2<sup>-w</sup>) mod 1, respectively. If x(-1) == 0, sets |
|---|
| 2622 | carry(-1) = 2<sup>-w</sup>, else sets carry(-1) = 0. |
|---|
| 2623 | <br> |
|---|
| 2624 | <strong>Complexity:</strong> O(r) |
|---|
| 2625 | |
|---|
| 2626 | <pre> template<class In> void seed(In& first, In last)</pre> |
|---|
| 2627 | <strong>Effects:</strong> With n=w/32+1 (rounded downward) and given |
|---|
| 2628 | the values z<sub>0</sub> ... z<sub>n*r-1</sub> obtained by |
|---|
| 2629 | dereferencing [first, first+n*r), sets x(-r) ... x(-1) to |
|---|
| 2630 | (z<sub>0</sub> * 2<sup>32</sup> + ... + z<sub>n-1</sub> * |
|---|
| 2631 | 2<sup>32*(n-1)</sup>) * 2<sup>-w</sup> mod 1 ... (z<sub>(r-1)*n</sub> |
|---|
| 2632 | * 2<sup>32</sup> + ... + z<sub>r-1</sub> * 2<sup>32*(n-1)</sup>) * |
|---|
| 2633 | 2<sup>-w</sup> mod 1. If x(-1) == 0, sets carry(-1) = 2<sup>-w</sup>, |
|---|
| 2634 | else sets carry(-1) = 0. |
|---|
| 2635 | <br> |
|---|
| 2636 | <strong>Complexity:</strong> O(r*n) |
|---|
| 2637 | |
|---|
| 2638 | <pre> |
|---|
| 2639 | template<class RealType, int w, int s, int r> |
|---|
| 2640 | bool operator==(const subtract_with_carry<RealType, w, s, r> x, |
|---|
| 2641 | const subtract_with_carry<RealType, w, s, r> y); |
|---|
| 2642 | </pre> |
|---|
| 2643 | <strong>Returns:</strong> true, if and only if x(i-r) == y(j-r) and |
|---|
| 2644 | ... and x(i-1) == y(j-1). |
|---|
| 2645 | <br> |
|---|
| 2646 | <strong>Complexity:</strong> O(r) |
|---|
| 2647 | |
|---|
| 2648 | <pre> |
|---|
| 2649 | template<class CharT, class Traits, |
|---|
| 2650 | class RealType, int w, int s, int r> |
|---|
| 2651 | std::basic_ostream<CharT,Traits>& operator<<(std::basic_ostream<CharT,Traits>& os, |
|---|
| 2652 | const subtract_with_carry<RealType, w, s, r>& f); |
|---|
| 2653 | </pre> |
|---|
| 2654 | <strong>Effects:</strong> Write x(i-r)*2<sup>w</sup> |
|---|
| 2655 | ... x(i-1)*2<sup>w</sup>, carry(i-1)*2<sup>w</sup> to <code>os</code>, |
|---|
| 2656 | in that order. |
|---|
| 2657 | <br> |
|---|
| 2658 | <strong>Complexity:</strong> O(r) |
|---|
| 2659 | |
|---|
| 2660 | |
|---|
| 2661 | <h4>Class template <code>discard_block</code></h4> |
|---|
| 2662 | |
|---|
| 2663 | A <code>discard_block</code> engine produces random numbers from some |
|---|
| 2664 | base engine by discarding blocks of data. |
|---|
| 2665 | <p> |
|---|
| 2666 | |
|---|
| 2667 | <pre> |
|---|
| 2668 | namespace std { |
|---|
| 2669 | template<class UniformRandomNumberGenerator, int p, int r> |
|---|
| 2670 | class discard_block |
|---|
| 2671 | { |
|---|
| 2672 | public: |
|---|
| 2673 | // <em>types</em> |
|---|
| 2674 | typedef UniformRandomNumberGenerator base_type; |
|---|
| 2675 | typedef typename base_type::result_type result_type; |
|---|
| 2676 | |
|---|
| 2677 | // <em>parameter values</em> |
|---|
| 2678 | static const int block_size = p; |
|---|
| 2679 | static const int used_block = r; |
|---|
| 2680 | |
|---|
| 2681 | // <em> constructors and member function</em> |
|---|
| 2682 | discard_block(); |
|---|
| 2683 | explicit discard_block(const base_type & rng); |
|---|
| 2684 | template<class In> discard_block(In& first, In last); |
|---|
| 2685 | void seed(); |
|---|
| 2686 | template<class In> void seed(In& first, In last); |
|---|
| 2687 | const base_type& base() const; |
|---|
| 2688 | result_type min() const; |
|---|
| 2689 | result_type max() const; |
|---|
| 2690 | result_type operator()(); |
|---|
| 2691 | private: |
|---|
| 2692 | // base_type b; <em>exposition only</em> |
|---|
| 2693 | // int n; <em>exposition only</em> |
|---|
| 2694 | }; |
|---|
| 2695 | template<class UniformRandomNumberGenerator, int p, int r> |
|---|
| 2696 | bool operator==(const discard_block<UniformRandomNumberGenerator,p,r> & x, |
|---|
| 2697 | (const discard_block<UniformRandomNumberGenerator,p,r> & y); |
|---|
| 2698 | template<class UniformRandomNumberGenerator, int p, int r, |
|---|
| 2699 | typename UniformRandomNumberGenerator::result_type val> |
|---|
| 2700 | bool operator!=(const discard_block<UniformRandomNumberGenerator,p,r> & x, |
|---|
| 2701 | (const discard_block<UniformRandomNumberGenerator,p,r> & y); |
|---|
| 2702 | |
|---|
| 2703 | template<class CharT, class traits, |
|---|
| 2704 | class UniformRandomNumberGenerator, int p, int r> |
|---|
| 2705 | basic_ostream<CharT, traits>& operator<<(basic_ostream<CharT, traits>& os, |
|---|
| 2706 | const discard_block<UniformRandomNumberGenerator,p,r> & x); |
|---|
| 2707 | template<class CharT, class traits, |
|---|
| 2708 | class UniformRandomNumberGenerator, int p, int r> |
|---|
| 2709 | basic_istream<CharT, traits>& operator>>(basic_istream<CharT, traits>& is, |
|---|
| 2710 | discard_block<UniformRandomNumberGenerator,p,r> & x); |
|---|
| 2711 | |
|---|
| 2712 | } |
|---|
| 2713 | </pre> |
|---|
| 2714 | |
|---|
| 2715 | The template parameter <code>UniformRandomNumberGenerator</code> shall |
|---|
| 2716 | denote a class that satisfies all the requirements of a uniform random |
|---|
| 2717 | number generator, given in tables in section x.x. r <= p. The size |
|---|
| 2718 | of the state is the size of <code><em>b</em></code> plus 1. |
|---|
| 2719 | |
|---|
| 2720 | <pre> discard_block()</pre> |
|---|
| 2721 | <strong>Effects:</strong> Constructs a <code>discard_block</code> |
|---|
| 2722 | engine. To construct the subobject <em>b</em>, invokes its default |
|---|
| 2723 | constructor. Sets <code>n = 0</code>. |
|---|
| 2724 | |
|---|
| 2725 | <pre> explicit discard_block(const base_type & rng)</pre> |
|---|
| 2726 | <strong>Effects:</strong> Constructs a <code>discard_block</code> |
|---|
| 2727 | engine. Initializes <em>b</em> with a copy of <code>rng</code>. |
|---|
| 2728 | Sets <code>n = 0</code>. |
|---|
| 2729 | |
|---|
| 2730 | <pre> template<class In> discard_block(In& first, In last)</pre> |
|---|
| 2731 | <strong>Effects:</strong> Constructs a <code>discard_block</code> |
|---|
| 2732 | engine. To construct the subobject <em>b</em>, invokes the |
|---|
| 2733 | <code>b(first, last)</code> constructor. Sets <code>n = 0</code>. |
|---|
| 2734 | |
|---|
| 2735 | <pre> void seed()</pre> |
|---|
| 2736 | <strong>Effects:</strong> Invokes <code><em>b</em>.seed()</code> |
|---|
| 2737 | and sets <code>n = 0</code>. |
|---|
| 2738 | |
|---|
| 2739 | <pre> template<class In> void seed(In& first, In last)</pre> |
|---|
| 2740 | <strong>Effects:</strong> Invokes <code><em>b</em>.seed(first, |
|---|
| 2741 | last)</code> and sets <code>n = 0</code>. |
|---|
| 2742 | |
|---|
| 2743 | <pre> const base_type& base() const</pre> |
|---|
| 2744 | <strong>Returns:</strong> <em>b</em> |
|---|
| 2745 | |
|---|
| 2746 | <pre> result_type operator()()</pre> |
|---|
| 2747 | <strong>Effects:</strong> If <em>n</em> >= r, invokes |
|---|
| 2748 | <code><em>b</em></code> (p-r) times, discards the values returned, |
|---|
| 2749 | and sets <code>n = 0</code>. In any case, then increments |
|---|
| 2750 | <code>n</code> and returns <code><em>b()</em></code>. |
|---|
| 2751 | |
|---|
| 2752 | <pre> |
|---|
| 2753 | template<class CharT, class traits, |
|---|
| 2754 | class UniformRandomNumberGenerator, int p, int r> |
|---|
| 2755 | basic_ostream<CharT, traits>& operator<<(basic_ostream<CharT, traits>& os, |
|---|
| 2756 | const discard_block<UniformRandomNumberGenerator,p,r> & x); |
|---|
| 2757 | </pre> |
|---|
| 2758 | <strong>Effects:</strong> Writes <code><em>b</em></code>, then |
|---|
| 2759 | <code><em>n</em></code> to <code>os</code>. |
|---|
| 2760 | |
|---|
| 2761 | |
|---|
| 2762 | <h4>Class template <code>xor_combine</code></h4> |
|---|
| 2763 | |
|---|
| 2764 | A <code>xor_combine</code> engine produces random numbers from two |
|---|
| 2765 | integer base engines by merging their random values with bitwise |
|---|
| 2766 | exclusive-or. |
|---|
| 2767 | <p> |
|---|
| 2768 | |
|---|
| 2769 | <pre> |
|---|
| 2770 | namespace std { |
|---|
| 2771 | template<class UniformRandomNumberGenerator1, int s1, |
|---|
| 2772 | class UniformRandomNumberGenerator2, int s2> |
|---|
| 2773 | class xor_combine |
|---|
| 2774 | { |
|---|
| 2775 | public: |
|---|
| 2776 | // <em>types</em> |
|---|
| 2777 | typedef UniformRandomNumberGenerator1 base1_type; |
|---|
| 2778 | typedef UniformRandomNumberGenerator2 base2_type; |
|---|
| 2779 | typedef typename base_type::result_type result_type; |
|---|
| 2780 | |
|---|
| 2781 | // <em>parameter values</em> |
|---|
| 2782 | static const int shift1 = s1; |
|---|
| 2783 | static const int shift2 = s2; |
|---|
| 2784 | |
|---|
| 2785 | // <em> constructors and member function</em> |
|---|
| 2786 | xor_combine(); |
|---|
| 2787 | xor_combine(const base1_type & rng1, const base2_type & rng2); |
|---|
| 2788 | template<class In> xor_combine(In& first, In last); |
|---|
| 2789 | void seed(); |
|---|
| 2790 | template<class In> void seed(In& first, In last); |
|---|
| 2791 | const base1_type& base1() const; |
|---|
| 2792 | const base2_type& base2() const; |
|---|
| 2793 | result_type min() const; |
|---|
| 2794 | result_type max() const; |
|---|
| 2795 | result_type operator()(); |
|---|
| 2796 | private: |
|---|
| 2797 | // base1_type b1; <em>exposition only</em> |
|---|
| 2798 | // base2_type b2; <em>exposition only</em> |
|---|
| 2799 | }; |
|---|
| 2800 | template<class UniformRandomNumberGenerator1, int s1, |
|---|
| 2801 | class UniformRandomNumberGenerator2, int s2> |
|---|
| 2802 | bool operator==(const xor_combine<UniformRandomNumberGenerator1, s1, |
|---|
| 2803 | UniformRandomNumberGenerator2, s2> & x, |
|---|
| 2804 | (const xor_combine<UniformRandomNumberGenerator1, s1, |
|---|
| 2805 | UniformRandomNumberGenerator2, s2> & y); |
|---|
| 2806 | template<class UniformRandomNumberGenerator1, int s1, |
|---|
| 2807 | class UniformRandomNumberGenerator2, int s2> |
|---|
| 2808 | bool operator!=(const xor_combine<UniformRandomNumberGenerator1, s1, |
|---|
| 2809 | UniformRandomNumberGenerator2, s2> & x, |
|---|
| 2810 | (const xor_combine<UniformRandomNumberGenerator1, s1, |
|---|
| 2811 | UniformRandomNumberGenerator2, s2> & y); |
|---|
| 2812 | |
|---|
| 2813 | template<class CharT, class traits, |
|---|
| 2814 | class UniformRandomNumberGenerator1, int s1, |
|---|
| 2815 | class UniformRandomNumberGenerator2, int s2> |
|---|
| 2816 | basic_ostream<CharT, traits>& operator<<(basic_ostream<CharT, traits>& os, |
|---|
| 2817 | const xor_combine<UniformRandomNumberGenerator1, s1, |
|---|
| 2818 | UniformRandomNumberGenerator2, s2> & x); |
|---|
| 2819 | template<class CharT, class traits, |
|---|
| 2820 | class UniformRandomNumberGenerator1, int s1, |
|---|
| 2821 | class UniformRandomNumberGenerator2, int s2> |
|---|
| 2822 | basic_istream<CharT, traits>& operator>>(basic_istream<CharT, traits>& is, |
|---|
| 2823 | xor_combine<UniformRandomNumberGenerator1, s1, |
|---|
| 2824 | UniformRandomNumberGenerator2, s2> & x); |
|---|
| 2825 | |
|---|
| 2826 | } |
|---|
| 2827 | </pre> |
|---|
| 2828 | |
|---|
| 2829 | The template parameters <code>UniformRandomNumberGenerator1</code> and |
|---|
| 2830 | <code>UniformRandomNumberGenerator1</code> shall denote classes that |
|---|
| 2831 | satisfy all the requirements of a uniform random number generator, |
|---|
| 2832 | given in tables in section x.x . The size of the state is |
|---|
| 2833 | the size of <code><em>b1</em></code> plus the size of |
|---|
| 2834 | <code><em>b2</em></code>. |
|---|
| 2835 | |
|---|
| 2836 | <pre> xor_combine()</pre> |
|---|
| 2837 | <strong>Effects:</strong> Constructs a <code>xor_combine</code> |
|---|
| 2838 | engine. To construct each of the subobjects <em>b1</em> and |
|---|
| 2839 | <em>b2</em>, invokes their respective default constructors. |
|---|
| 2840 | |
|---|
| 2841 | <pre> xor_combine(const base1_type & rng1, const base2_type & rng2)</pre> |
|---|
| 2842 | <strong>Effects:</strong> Constructs a <code>xor_combine</code> |
|---|
| 2843 | engine. Initializes <em>b1</em> with a copy of <code>rng1</code> and |
|---|
| 2844 | <em>b2</em> with a copy of <code>rng2</code>. |
|---|
| 2845 | |
|---|
| 2846 | <pre> template<class In> xor_combine(In& first, In last)</pre> |
|---|
| 2847 | <strong>Effects:</strong> Constructs a <code>xor_combine</code> |
|---|
| 2848 | engine. To construct the subobject <em>b1</em>, invokes the |
|---|
| 2849 | <code>b1(first, last)</code> constructor. Then, to construct the |
|---|
| 2850 | subobject <em>b2</em>, invokes the <code>b2(first, last)</code> |
|---|
| 2851 | constructor. |
|---|
| 2852 | |
|---|
| 2853 | <pre> void seed()</pre> |
|---|
| 2854 | <strong>Effects:</strong> Invokes <code><em>b1</em>.seed()</code> |
|---|
| 2855 | and <code><em>b2</em>.seed()</code>. |
|---|
| 2856 | |
|---|
| 2857 | <pre> template<class In> void seed(In& first, In last)</pre> |
|---|
| 2858 | <strong>Effects:</strong> Invokes <code><em>b1</em>.seed(first, |
|---|
| 2859 | last)</code>, then invokes <code><em>b2</em>.seed(first, last)</code>. |
|---|
| 2860 | |
|---|
| 2861 | <pre> const base1_type& base1() const</pre> |
|---|
| 2862 | <strong>Returns:</strong> <em>b1</em> |
|---|
| 2863 | |
|---|
| 2864 | <pre> const base2_type& base2() const</pre> |
|---|
| 2865 | <strong>Returns:</strong> <em>b2</em> |
|---|
| 2866 | |
|---|
| 2867 | <pre> result_type operator()()</pre> |
|---|
| 2868 | <strong>Returns:</strong> (<code><em>b1</em>() << s1) ^ |
|---|
| 2869 | (<em>b2</em>() << s2)</code>. |
|---|
| 2870 | |
|---|
| 2871 | <pre> |
|---|
| 2872 | template<class CharT, class traits, |
|---|
| 2873 | class UniformRandomNumberGenerator1, int s1, |
|---|
| 2874 | class UniformRandomNumberGenerator2, int s2> |
|---|
| 2875 | basic_ostream<CharT, traits>& operator<<(basic_ostream<CharT, traits>& os, |
|---|
| 2876 | const xor_combine<UniformRandomNumberGenerator1, s1, |
|---|
| 2877 | UniformRandomNumberGenerator2, s2> & x); |
|---|
| 2878 | </pre> |
|---|
| 2879 | <strong>Effects:</strong> Writes <code><em>b1</em></code>, then |
|---|
| 2880 | <code><em>b2</em></code> to <code>os</code>. |
|---|
| 2881 | |
|---|
| 2882 | |
|---|
| 2883 | <h3>Engines with predefined parameters</h3> |
|---|
| 2884 | |
|---|
| 2885 | <pre> |
|---|
| 2886 | namespace std { |
|---|
| 2887 | typedef linear_congruential</* <em>implementation defined</em> */, 16807, 0, 2147483647> minstd_rand0; |
|---|
| 2888 | typedef linear_congruential</* <em>implementation defined</em> */, 48271, 0, 2147483647> minstd_rand; |
|---|
| 2889 | |
|---|
| 2890 | typedef mersenne_twister</* <em>implementation defined</em> */,32,624,397,31,0x9908b0df,11,7,0x9d2c5680,15,0xefc60000,18> mt19937; |
|---|
| 2891 | |
|---|
| 2892 | typedef subtract_with_carry_01<float, 24, 10, 24> ranlux_base_01; |
|---|
| 2893 | typedef subtract_with_carry_01<double, 48, 10, 24> ranlux64_base_01; |
|---|
| 2894 | |
|---|
| 2895 | typedef discard_block<subtract_with_carry</* <em>implementation defined</em> */, (1<<24), 10, 24>, 223, 24> ranlux3; |
|---|
| 2896 | typedef discard_block<subtract_with_carry</* <em>implementation defined</em> */, (1<<24), 10, 24>, 389, 24> ranlux4; |
|---|
| 2897 | |
|---|
| 2898 | typedef discard_block<subtract_with_carry_01<float, 24, 10, 24>, 223, 24> ranlux3_01; |
|---|
| 2899 | typedef discard_block<subtract_with_carry_01<float, 24, 10, 24>, 389, 24> ranlux4_01; |
|---|
| 2900 | } |
|---|
| 2901 | </pre> |
|---|
| 2902 | |
|---|
| 2903 | For a default-constructed <code>minstd_rand0</code> object, x(10000) = |
|---|
| 2904 | 1043618065. For a default-constructed <code>minstd_rand</code> |
|---|
| 2905 | object, x(10000) = 399268537. |
|---|
| 2906 | <p> |
|---|
| 2907 | |
|---|
| 2908 | For a default-constructed <code>mt19937</code> object, x(10000) = |
|---|
| 2909 | 3346425566. |
|---|
| 2910 | <p> |
|---|
| 2911 | |
|---|
| 2912 | For a default-constructed <code>ranlux3</code> object, x(10000) = |
|---|
| 2913 | 5957620. For a default-constructed <code>ranlux4</code> object, |
|---|
| 2914 | x(10000) = 8587295. For a default-constructed <code>ranlux3_01</code> |
|---|
| 2915 | object, x(10000) = 5957620 * 2<sup>-24</sup>. For a |
|---|
| 2916 | default-constructed <code>ranlux4_01</code> object, x(10000) = 8587295 |
|---|
| 2917 | * 2<sup>-24</sup>. |
|---|
| 2918 | |
|---|
| 2919 | |
|---|
| 2920 | |
|---|
| 2921 | |
|---|
| 2922 | <h3>Class <code>random_device</code></h3> |
|---|
| 2923 | |
|---|
| 2924 | A <code>random_device</code> produces non-deterministic random |
|---|
| 2925 | numbers. It satisfies all the requirements of a uniform random number |
|---|
| 2926 | generator (given in tables in section x.x). Descriptions are provided |
|---|
| 2927 | here only for operations on the engines that are not described in one |
|---|
| 2928 | of these tables or for operations where there is additional semantic |
|---|
| 2929 | information. |
|---|
| 2930 | <p> |
|---|
| 2931 | |
|---|
| 2932 | If implementation limitations prevent generating non-deterministic |
|---|
| 2933 | random numbers, the implementation can employ a pseudo-random number |
|---|
| 2934 | engine. |
|---|
| 2935 | |
|---|
| 2936 | <pre> |
|---|
| 2937 | namespace std { |
|---|
| 2938 | class random_device |
|---|
| 2939 | { |
|---|
| 2940 | public: |
|---|
| 2941 | // <em>types</em> |
|---|
| 2942 | typedef unsigned int result_type; |
|---|
| 2943 | |
|---|
| 2944 | // <em>constructors, destructors and member functions</em> |
|---|
| 2945 | explicit random_device(const std::string& token = /* <em>implementation-defined</em> */); |
|---|
| 2946 | result_type min() const; |
|---|
| 2947 | result_type max() const; |
|---|
| 2948 | double entropy() const; |
|---|
| 2949 | result_type operator()(); |
|---|
| 2950 | |
|---|
| 2951 | private: |
|---|
| 2952 | random_device(const random_device& ); |
|---|
| 2953 | void operator=(const random_device& ); |
|---|
| 2954 | }; |
|---|
| 2955 | } |
|---|
| 2956 | </pre> |
|---|
| 2957 | |
|---|
| 2958 | <pre> explicit random_device(const std::string& token = /* <em>implementation-defined</em> */)</pre> |
|---|
| 2959 | <strong>Effects:</strong> Constructs a <code>random_device</code> |
|---|
| 2960 | non-deterministic random number engine. The semantics and default |
|---|
| 2961 | value of the <code>token</code> parameter are implementation-defined. |
|---|
| 2962 | [Footnote: The parameter is intended to allow an implementation to |
|---|
| 2963 | differentiate between different sources of randomness.] |
|---|
| 2964 | <br> |
|---|
| 2965 | <strong>Throws:</strong> A value of some type derived from |
|---|
| 2966 | <code>exception</code> if the <code>random_device</code> could not be |
|---|
| 2967 | initialized. |
|---|
| 2968 | |
|---|
| 2969 | <pre> result_type min() const</pre> |
|---|
| 2970 | <strong>Returns:</strong> |
|---|
| 2971 | <code>numeric_limits<result_type>::min()</code> |
|---|
| 2972 | |
|---|
| 2973 | <pre> result_type max() const</pre> |
|---|
| 2974 | <strong>Returns:</strong> |
|---|
| 2975 | <code>numeric_limits<result_type>::max()</code> |
|---|
| 2976 | |
|---|
| 2977 | <pre> double entropy() const</pre> |
|---|
| 2978 | <strong>Returns:</strong> An entropy estimate for the random numbers |
|---|
| 2979 | returned by operator(), in the range <code>min()</code> to |
|---|
| 2980 | log<sub>2</sub>( <code>max()</code>+1). A deterministic random |
|---|
| 2981 | number generator (e.g. a pseudo-random number engine) has entropy 0. |
|---|
| 2982 | <br> |
|---|
| 2983 | <strong>Throws:</strong> Nothing. |
|---|
| 2984 | |
|---|
| 2985 | <pre> result_type operator()()</pre> |
|---|
| 2986 | <strong>Returns:</strong> A non-deterministic random value, uniformly |
|---|
| 2987 | distributed between <code>min()</code> and <code>max()</code>, |
|---|
| 2988 | inclusive. It is implementation-defined how these values are |
|---|
| 2989 | generated. |
|---|
| 2990 | <br> |
|---|
| 2991 | <strong>Throws:</strong> A value of some type derived from |
|---|
| 2992 | <code>exception</code> if a random number could not be obtained. |
|---|
| 2993 | |
|---|
| 2994 | |
|---|
| 2995 | <h3>Random distribution class templates</h3> |
|---|
| 2996 | |
|---|
| 2997 | The class templates specified in this section satisfy all the |
|---|
| 2998 | requirements of a random distribution (given in tables in section |
|---|
| 2999 | x.x). Descriptions are provided here only for operations on the |
|---|
| 3000 | distributions that are not described in one of these tables or for |
|---|
| 3001 | operations where there is additional semantic information. |
|---|
| 3002 | <p> |
|---|
| 3003 | |
|---|
| 3004 | A template parameter named <code>IntType</code> shall denote a type |
|---|
| 3005 | that represents an integer number. This type shall meet the |
|---|
| 3006 | requirements for a numeric type (26.1 [lib.numeric.requirements]), the |
|---|
| 3007 | binary operators +, -, *, /, % shall be applicable to it, and a |
|---|
| 3008 | conversion from <code>int</code> shall exist. <em>[Footnote: The |
|---|
| 3009 | built-in types <code>int</code> and <code>long</code> meet these |
|---|
| 3010 | requirements.]</em> |
|---|
| 3011 | <p> |
|---|
| 3012 | |
|---|
| 3013 | Given an object whose type is specified in this subclause, if the |
|---|
| 3014 | lifetime of the uniform random number generator referred to in the |
|---|
| 3015 | constructor invocation for that object has ended, any use of that |
|---|
| 3016 | object is undefined. |
|---|
| 3017 | <p> |
|---|
| 3018 | |
|---|
| 3019 | No function described in this section throws an exception, unless an |
|---|
| 3020 | operation on values of <code>IntType</code> or <code>RealType</code> |
|---|
| 3021 | throws an exception. <em>[Note: Then, the effects are undefined, |
|---|
| 3022 | see [lib.numeric.requirements]. ]</em> |
|---|
| 3023 | <p> |
|---|
| 3024 | |
|---|
| 3025 | The algorithms for producing each of the specified distributions are |
|---|
| 3026 | implementation-defined. |
|---|
| 3027 | |
|---|
| 3028 | |
|---|
| 3029 | <h4>Class template <code>uniform_int</code></h4> |
|---|
| 3030 | |
|---|
| 3031 | A <code>uniform_int</code> random distribution produces integer random |
|---|
| 3032 | numbers x in the range min <= x <= max, with equal probability. |
|---|
| 3033 | min and max are the parameters of the distribution. |
|---|
| 3034 | <p> |
|---|
| 3035 | |
|---|
| 3036 | A <code>uniform_int</code> random distribution satisfies all the |
|---|
| 3037 | requirements of a uniform random number generator (given in tables in |
|---|
| 3038 | section x.x). |
|---|
| 3039 | |
|---|
| 3040 | <pre> |
|---|
| 3041 | namespace std { |
|---|
| 3042 | template<class IntType = int> |
|---|
| 3043 | class uniform_int |
|---|
| 3044 | { |
|---|
| 3045 | public: |
|---|
| 3046 | // <em>types</em> |
|---|
| 3047 | typedef IntType input_type; |
|---|
| 3048 | typedef IntType result_type; |
|---|
| 3049 | |
|---|
| 3050 | // <em> constructors and member function</em> |
|---|
| 3051 | explicit uniform_int(IntType min = 0, IntType max = 9); |
|---|
| 3052 | result_type min() const; |
|---|
| 3053 | result_type max() const; |
|---|
| 3054 | void reset(); |
|---|
| 3055 | template<class UniformRandomNumberGenerator> |
|---|
| 3056 | result_type operator()(UniformRandomNumberGenerator& urng); |
|---|
| 3057 | template<class UniformRandomNumberGenerator> |
|---|
| 3058 | result_type operator()(UniformRandomNumberGenerator& urng, result_type n); |
|---|
| 3059 | }; |
|---|
| 3060 | } |
|---|
| 3061 | </pre> |
|---|
| 3062 | |
|---|
| 3063 | <pre> uniform_int(IntType min = 0, IntType max = 9)</pre> |
|---|
| 3064 | <strong>Requires:</strong> min <= max |
|---|
| 3065 | <br> |
|---|
| 3066 | <strong>Effects:</strong> Constructs a <code>uniform_int</code> |
|---|
| 3067 | object. <code>min</code> and <code>max</code> are the parameters of |
|---|
| 3068 | the distribution. |
|---|
| 3069 | |
|---|
| 3070 | <pre> result_type min() const</pre> |
|---|
| 3071 | <strong>Returns:</strong> The "min" parameter of the distribution. |
|---|
| 3072 | |
|---|
| 3073 | <pre> result_type max() const</pre> |
|---|
| 3074 | <strong>Returns:</strong> The "max" parameter of the distribution. |
|---|
| 3075 | |
|---|
| 3076 | <pre> result_type operator()(UniformRandomNumberGenerator& urng, result_type n)</pre> |
|---|
| 3077 | <strong>Returns:</strong> A uniform random number x in the range 0 |
|---|
| 3078 | <= x < n. <em>[Note: This allows a |
|---|
| 3079 | <code>variate_generator</code> object with a <code>uniform_int</code> |
|---|
| 3080 | distribution to be used with std::random_shuffe, see |
|---|
| 3081 | [lib.alg.random.shuffle]. ]</em> |
|---|
| 3082 | |
|---|
| 3083 | |
|---|
| 3084 | <h4>Class template <code>bernoulli_distribution</code></h4> |
|---|
| 3085 | |
|---|
| 3086 | A <code>bernoulli_distribution</code> random distribution produces |
|---|
| 3087 | <code>bool</code> values distributed with probabilities p(true) = p |
|---|
| 3088 | and p(false) = 1-p. p is the parameter of the distribution. |
|---|
| 3089 | |
|---|
| 3090 | <pre> |
|---|
| 3091 | namespace std { |
|---|
| 3092 | template<class RealType = double> |
|---|
| 3093 | class bernoulli_distribution |
|---|
| 3094 | { |
|---|
| 3095 | public: |
|---|
| 3096 | // <em>types</em> |
|---|
| 3097 | typedef int input_type; |
|---|
| 3098 | typedef bool result_type; |
|---|
| 3099 | |
|---|
| 3100 | // <em> constructors and member function</em> |
|---|
| 3101 | explicit bernoulli_distribution(const RealType& p = RealType(0.5)); |
|---|
| 3102 | RealType p() const; |
|---|
| 3103 | void reset(); |
|---|
| 3104 | template<class UniformRandomNumberGenerator> |
|---|
| 3105 | result_type operator()(UniformRandomNumberGenerator& urng); |
|---|
| 3106 | }; |
|---|
| 3107 | } |
|---|
| 3108 | </pre> |
|---|
| 3109 | |
|---|
| 3110 | <pre> bernoulli_distribution(const RealType& p = RealType(0.5))</pre> |
|---|
| 3111 | |
|---|
| 3112 | <strong>Requires:</strong> 0 <= p <= 1 |
|---|
| 3113 | <br> |
|---|
| 3114 | <strong>Effects:</strong> Constructs a |
|---|
| 3115 | <code>bernoulli_distribution</code> object. <code>p</code> is the |
|---|
| 3116 | parameter of the distribution. |
|---|
| 3117 | |
|---|
| 3118 | <pre> RealType p() const</pre> |
|---|
| 3119 | <strong>Returns:</strong> The "p" parameter of the distribution. |
|---|
| 3120 | |
|---|
| 3121 | |
|---|
| 3122 | <h4>Class template <code>geometric_distribution</code></h4> |
|---|
| 3123 | |
|---|
| 3124 | A <code>geometric_distribution</code> random distribution produces |
|---|
| 3125 | integer values <em>i</em> >= 1 with p(i) = (1-p) * |
|---|
| 3126 | p<sup>i-1</sup>. p is the parameter of the distribution. |
|---|
| 3127 | |
|---|
| 3128 | <pre> |
|---|
| 3129 | namespace std { |
|---|
| 3130 | template<class IntType = int, class RealType = double> |
|---|
| 3131 | class geometric_distribution |
|---|
| 3132 | { |
|---|
| 3133 | public: |
|---|
| 3134 | // <em>types</em> |
|---|
| 3135 | typedef RealType input_type; |
|---|
| 3136 | typedef IntType result_type; |
|---|
| 3137 | |
|---|
| 3138 | // <em> constructors and member function</em> |
|---|
| 3139 | explicit geometric_distribution(const RealType& p = RealType(0.5)); |
|---|
| 3140 | RealType p() const; |
|---|
| 3141 | void reset(); |
|---|
| 3142 | template<class UniformRandomNumberGenerator> |
|---|
| 3143 | result_type operator()(UniformRandomNumberGenerator& urng); |
|---|
| 3144 | }; |
|---|
| 3145 | } |
|---|
| 3146 | </pre> |
|---|
| 3147 | |
|---|
| 3148 | <pre> geometric_distribution(const RealType& p = RealType(0.5))</pre> |
|---|
| 3149 | |
|---|
| 3150 | <strong>Requires:</strong> 0 < p < 1 |
|---|
| 3151 | <br> |
|---|
| 3152 | <strong>Effects:</strong> Constructs a |
|---|
| 3153 | <code>geometric_distribution</code> object; <code>p</code> is the |
|---|
| 3154 | parameter of the distribution. |
|---|
| 3155 | |
|---|
| 3156 | <pre> RealType p() const</pre> |
|---|
| 3157 | <strong>Returns:</strong> The "p" parameter of the distribution. |
|---|
| 3158 | |
|---|
| 3159 | |
|---|
| 3160 | <h4>Class template <code>poisson_distribution</code></h4> |
|---|
| 3161 | |
|---|
| 3162 | A <code>poisson_distribution</code> random distribution produces |
|---|
| 3163 | integer values <em>i</em> >= 0 with p(i) = exp(-mean) * |
|---|
| 3164 | mean<sup>i</sup> / i!. mean is the parameter of the distribution. |
|---|
| 3165 | |
|---|
| 3166 | <pre> |
|---|
| 3167 | namespace std { |
|---|
| 3168 | template<class IntType = int, class RealType = double> |
|---|
| 3169 | class poisson_distribution |
|---|
| 3170 | { |
|---|
| 3171 | public: |
|---|
| 3172 | // <em>types</em> |
|---|
| 3173 | typedef RealType input_type; |
|---|
| 3174 | typedef IntType result_type; |
|---|
| 3175 | |
|---|
| 3176 | // <em> constructors and member function</em> |
|---|
| 3177 | explicit poisson_distribution(const RealType& mean = RealType(1)); |
|---|
| 3178 | RealType mean() const; |
|---|
| 3179 | void reset(); |
|---|
| 3180 | template<class UniformRandomNumberGenerator> |
|---|
| 3181 | result_type operator()(UniformRandomNumberGenerator& urng); |
|---|
| 3182 | }; |
|---|
| 3183 | } |
|---|
| 3184 | </pre> |
|---|
| 3185 | |
|---|
| 3186 | <pre> poisson_distribution(const RealType& mean = RealType(1))</pre> |
|---|
| 3187 | |
|---|
| 3188 | <strong>Requires:</strong> mean > 0 |
|---|
| 3189 | <br> |
|---|
| 3190 | <strong>Effects:</strong> Constructs a |
|---|
| 3191 | <code>poisson_distribution</code> object; <code>mean</code> is the |
|---|
| 3192 | parameter of the distribution. |
|---|
| 3193 | |
|---|
| 3194 | <pre> RealType mean() const</pre> |
|---|
| 3195 | <strong>Returns:</strong> The "mean" parameter of the distribution. |
|---|
| 3196 | |
|---|
| 3197 | |
|---|
| 3198 | <h4>Class template <code>binomial_distribution</code></h4> |
|---|
| 3199 | |
|---|
| 3200 | A <code>binomial_distribution</code> random distribution produces |
|---|
| 3201 | integer values <em>i</em> >= 0 with p(i) = (n over i) * |
|---|
| 3202 | p<sup>i</sup> * (1-p)<sup>t-i</sup>. t and p are the parameters of |
|---|
| 3203 | the distribution. |
|---|
| 3204 | |
|---|
| 3205 | <pre> |
|---|
| 3206 | namespace std { |
|---|
| 3207 | template<class IntType = int, class RealType = double> |
|---|
| 3208 | class binomial_distribution |
|---|
| 3209 | { |
|---|
| 3210 | public: |
|---|
| 3211 | // <em>types</em> |
|---|
| 3212 | typedef /* <em>implementation-defined</em> */ input_type; |
|---|
| 3213 | typedef IntType result_type; |
|---|
| 3214 | |
|---|
| 3215 | // <em> constructors and member function</em> |
|---|
| 3216 | explicit binomial_distribution(IntType t = 1, const RealType& p = RealType(0.5)); |
|---|
| 3217 | IntType t() const; |
|---|
| 3218 | RealType p() const; |
|---|
| 3219 | void reset(); |
|---|
| 3220 | template<class UniformRandomNumberGenerator> |
|---|
| 3221 | result_type operator()(UniformRandomNumberGenerator& urng); |
|---|
| 3222 | }; |
|---|
| 3223 | } |
|---|
| 3224 | </pre> |
|---|
| 3225 | |
|---|
| 3226 | <pre> binomial_distribution(IntType t = 1, const RealType& p = RealType(0.5))</pre> |
|---|
| 3227 | |
|---|
| 3228 | <strong>Requires:</strong> 0 <= p <= 1 and t >= 0 |
|---|
| 3229 | <br> |
|---|
| 3230 | <strong>Effects:</strong> Constructs a |
|---|
| 3231 | <code>binomial_distribution</code> object; <code>t</code> and |
|---|
| 3232 | <code>p</code> are the parameters of the distribution. |
|---|
| 3233 | |
|---|
| 3234 | <pre> IntType t() const</pre> |
|---|
| 3235 | <strong>Returns:</strong> The "t" parameter of the distribution. |
|---|
| 3236 | |
|---|
| 3237 | <pre> RealType p() const</pre> |
|---|
| 3238 | <strong>Returns:</strong> The "p" parameter of the distribution. |
|---|
| 3239 | |
|---|
| 3240 | |
|---|
| 3241 | |
|---|
| 3242 | <h4>Class template <code>uniform_real</code></h4> |
|---|
| 3243 | |
|---|
| 3244 | A <code>uniform_real</code> random distribution produces |
|---|
| 3245 | floating-point random numbers x in the range min <= x <= max, |
|---|
| 3246 | with equal probability. min and max are the parameters of the |
|---|
| 3247 | distribution. |
|---|
| 3248 | <p> |
|---|
| 3249 | |
|---|
| 3250 | A <code>uniform_real</code> random distribution satisfies all the |
|---|
| 3251 | requirements of a uniform random number generator (given in tables in |
|---|
| 3252 | section x.x). |
|---|
| 3253 | |
|---|
| 3254 | <pre> |
|---|
| 3255 | namespace std { |
|---|
| 3256 | template<class RealType = double> |
|---|
| 3257 | class uniform_real |
|---|
| 3258 | { |
|---|
| 3259 | public: |
|---|
| 3260 | // <em>types</em> |
|---|
| 3261 | typedef RealType input_type; |
|---|
| 3262 | typedef RealType result_type; |
|---|
| 3263 | |
|---|
| 3264 | // <em> constructors and member function</em> |
|---|
| 3265 | explicit uniform_real(RealType min = RealType(0), RealType max = RealType(1)); |
|---|
| 3266 | result_type min() const; |
|---|
| 3267 | result_type max() const; |
|---|
| 3268 | void reset(); |
|---|
| 3269 | template<class UniformRandomNumberGenerator> |
|---|
| 3270 | result_type operator()(UniformRandomNumberGenerator& urng); |
|---|
| 3271 | }; |
|---|
| 3272 | } |
|---|
| 3273 | </pre> |
|---|
| 3274 | |
|---|
| 3275 | <pre> uniform_real(RealType min = RealType(0), RealType max = RealType(1))</pre> |
|---|
| 3276 | <strong>Requires:</strong> min <= max |
|---|
| 3277 | <br> |
|---|
| 3278 | <strong>Effects:</strong> Constructs a |
|---|
| 3279 | <code>uniform_real</code> object; <code>min</code> and |
|---|
| 3280 | <code>max</code> are the parameters of the distribution. |
|---|
| 3281 | |
|---|
| 3282 | <pre> result_type min() const</pre> |
|---|
| 3283 | <strong>Returns:</strong> The "min" parameter of the distribution. |
|---|
| 3284 | |
|---|
| 3285 | <pre> result_type max() const</pre> |
|---|
| 3286 | <strong>Returns:</strong> The "max" parameter of the distribution. |
|---|
| 3287 | |
|---|
| 3288 | |
|---|
| 3289 | <h4>Class template <code>exponential_distribution</code></h4> |
|---|
| 3290 | |
|---|
| 3291 | An <code>exponential_distribution</code> random distribution produces |
|---|
| 3292 | random numbers x > 0 distributed with probability density function |
|---|
| 3293 | p(x) = lambda * exp(-lambda * x), where lambda is the parameter of the |
|---|
| 3294 | distribution. |
|---|
| 3295 | |
|---|
| 3296 | <pre> |
|---|
| 3297 | namespace std { |
|---|
| 3298 | template<class RealType = double> |
|---|
| 3299 | class exponential_distribution |
|---|
| 3300 | { |
|---|
| 3301 | public: |
|---|
| 3302 | // <em>types</em> |
|---|
| 3303 | typedef RealType input_type; |
|---|
| 3304 | typedef RealType result_type; |
|---|
| 3305 | |
|---|
| 3306 | // <em> constructors and member function</em> |
|---|
| 3307 | explicit exponential_distribution(const result_type& lambda = result_type(1)); |
|---|
| 3308 | RealType lambda() const; |
|---|
| 3309 | void reset(); |
|---|
| 3310 | template<class UniformRandomNumberGenerator> |
|---|
| 3311 | result_type operator()(UniformRandomNumberGenerator& urng); |
|---|
| 3312 | }; |
|---|
| 3313 | } |
|---|
| 3314 | </pre> |
|---|
| 3315 | |
|---|
| 3316 | <pre> exponential_distribution(const result_type& lambda = result_type(1))</pre> |
|---|
| 3317 | <strong>Requires:</strong> lambda > 0 |
|---|
| 3318 | <br> |
|---|
| 3319 | <strong>Effects:</strong> Constructs an |
|---|
| 3320 | <code>exponential_distribution</code> object with <code>rng</code> as |
|---|
| 3321 | the reference to the underlying source of random |
|---|
| 3322 | numbers. <code>lambda</code> is the parameter for the distribution. |
|---|
| 3323 | |
|---|
| 3324 | <pre> RealType lambda() const</pre> |
|---|
| 3325 | <strong>Returns:</strong> The "lambda" parameter of the distribution. |
|---|
| 3326 | |
|---|
| 3327 | |
|---|
| 3328 | <h4>Class template <code>normal_distribution</code></h4> |
|---|
| 3329 | |
|---|
| 3330 | A <code>normal_distribution</code> random distribution produces |
|---|
| 3331 | random numbers x distributed with probability density function |
|---|
| 3332 | p(x) = 1/sqrt(2*pi*sigma) * exp(- (x-mean)<sup>2</sup> / |
|---|
| 3333 | (2*sigma<sup>2</sup>) ), where mean and sigma are the parameters of |
|---|
| 3334 | the distribution. |
|---|
| 3335 | |
|---|
| 3336 | <pre> |
|---|
| 3337 | namespace std { |
|---|
| 3338 | template<class RealType = double> |
|---|
| 3339 | class normal_distribution |
|---|
| 3340 | { |
|---|
| 3341 | public: |
|---|
| 3342 | // <em>types</em> |
|---|
| 3343 | typedef RealType input_type; |
|---|
| 3344 | typedef RealType result_type; |
|---|
| 3345 | |
|---|
| 3346 | // <em> constructors and member function</em> |
|---|
| 3347 | explicit normal_distribution(base_type & rng, const result_type& mean = 0, |
|---|
| 3348 | const result_type& sigma = 1); |
|---|
| 3349 | RealType mean() const; |
|---|
| 3350 | RealType sigma() const; |
|---|
| 3351 | void reset(); |
|---|
| 3352 | template<class UniformRandomNumberGenerator> |
|---|
| 3353 | result_type operator()(UniformRandomNumberGenerator& urng); |
|---|
| 3354 | }; |
|---|
| 3355 | } |
|---|
| 3356 | </pre> |
|---|
| 3357 | |
|---|
| 3358 | |
|---|
| 3359 | <pre> |
|---|
| 3360 | explicit normal_distribution( const result_type& mean = 0, |
|---|
| 3361 | const result_type& sigma = 1); |
|---|
| 3362 | </pre> |
|---|
| 3363 | |
|---|
| 3364 | <strong>Requires:</strong> sigma > 0 |
|---|
| 3365 | <br> |
|---|
| 3366 | <strong>Effects:</strong> Constructs a |
|---|
| 3367 | <code>normal_distribution</code> object; <code>mean</code> and |
|---|
| 3368 | <code>sigma</code> are the parameters for the distribution. |
|---|
| 3369 | |
|---|
| 3370 | <pre> RealType mean() const</pre> |
|---|
| 3371 | <strong>Returns:</strong> The "mean" parameter of the distribution. |
|---|
| 3372 | |
|---|
| 3373 | <pre> RealType sigma() const</pre> |
|---|
| 3374 | <strong>Returns:</strong> The "sigma" parameter of the distribution. |
|---|
| 3375 | |
|---|
| 3376 | |
|---|
| 3377 | <h4>Class template <code>gamma_distribution</code></h4> |
|---|
| 3378 | |
|---|
| 3379 | A <code>gamma_distribution</code> random distribution produces |
|---|
| 3380 | random numbers x distributed with probability density function |
|---|
| 3381 | p(x) = 1/Gamma(alpha) * x<sup>alpha-1</sup> * exp(-x), where alpha is the |
|---|
| 3382 | parameter of the distribution. |
|---|
| 3383 | |
|---|
| 3384 | <pre> |
|---|
| 3385 | namespace std { |
|---|
| 3386 | template<class RealType = double> |
|---|
| 3387 | class gamma_distribution |
|---|
| 3388 | { |
|---|
| 3389 | public: |
|---|
| 3390 | // <em>types</em> |
|---|
| 3391 | typedef RealType input_type; |
|---|
| 3392 | typedef RealType result_type; |
|---|
| 3393 | |
|---|
| 3394 | // <em> constructors and member function</em> |
|---|
| 3395 | explicit gamma_distribution(const result_type& alpha = result_type(1)); |
|---|
| 3396 | RealType alpha() const; |
|---|
| 3397 | void reset(); |
|---|
| 3398 | template<class UniformRandomNumberGenerator> |
|---|
| 3399 | result_type operator()(UniformRandomNumberGenerator& urng); |
|---|
| 3400 | }; |
|---|
| 3401 | } |
|---|
| 3402 | </pre> |
|---|
| 3403 | |
|---|
| 3404 | |
|---|
| 3405 | <pre> |
|---|
| 3406 | explicit gamma_distribution(const result_type& alpha = result_type(1)); |
|---|
| 3407 | </pre> |
|---|
| 3408 | |
|---|
| 3409 | <strong>Requires:</strong> alpha > 0 |
|---|
| 3410 | <br> |
|---|
| 3411 | <strong>Effects:</strong> Constructs a |
|---|
| 3412 | <code>gamma_distribution</code> object; <code>alpha</code> is the |
|---|
| 3413 | parameter for the distribution. |
|---|
| 3414 | |
|---|
| 3415 | <pre> RealType alpha() const</pre> |
|---|
| 3416 | <strong>Returns:</strong> The "alpha" parameter of the distribution. |
|---|
| 3417 | |
|---|
| 3418 | |
|---|
| 3419 | |
|---|
| 3420 | <h2>V. Acknowledgements</h2> |
|---|
| 3421 | |
|---|
| 3422 | <ul> |
|---|
| 3423 | <li>Thanks to Walter Brown, Mark Fischler and Marc Paterno from Fermilab |
|---|
| 3424 | for input about the requirements of high-energy physics. |
|---|
| 3425 | </li> |
|---|
| 3426 | |
|---|
| 3427 | <li>Thanks to David Abrahams for additional comments on the |
|---|
| 3428 | design.</li> |
|---|
| 3429 | |
|---|
| 3430 | <li>Thanks to the Boost community for a platform for experimentation. |
|---|
| 3431 | </li> |
|---|
| 3432 | |
|---|
| 3433 | </ul> |
|---|
| 3434 | |
|---|
| 3435 | |
|---|
| 3436 | |
|---|
| 3437 | <h2>VI. References</h2> |
|---|
| 3438 | |
|---|
| 3439 | <ul> |
|---|
| 3440 | <li>William H. Press, Saul A. Teukolsky, William A. Vetterling, Brian |
|---|
| 3441 | P. Flannery, "Numerical Recipes in C: The art of scientific |
|---|
| 3442 | computing", 2nd ed., 1992, pp. 274-328 |
|---|
| 3443 | </li> |
|---|
| 3444 | |
|---|
| 3445 | <li>Bruce Schneier, "Applied Cryptography", 2nd ed., 1996, ch. 16-17. |
|---|
| 3446 | [I haven't read this myself. Yet.] |
|---|
| 3447 | </li> |
|---|
| 3448 | |
|---|
| 3449 | <li>D. H. Lehmer, "Mathematical methods in large-scale computing |
|---|
| 3450 | units", Proc. 2nd Symposium on Large-Scale Digital Calculating |
|---|
| 3451 | Machines, Harvard University Press, 1951, pp. 141-146 |
|---|
| 3452 | </li> |
|---|
| 3453 | |
|---|
| 3454 | <li>P.A. Lewis, A.S. Goodman, J.M. Miller, "A pseudo-random number |
|---|
| 3455 | generator for the System/360", IBM Systems Journal, Vol. 8, No. 2, |
|---|
| 3456 | 1969, pp. 136-146 |
|---|
| 3457 | </li> |
|---|
| 3458 | |
|---|
| 3459 | <li>Stephen K. Park and Keith W. Miller, "Random Number Generators: |
|---|
| 3460 | Good ones are hard to find", Communications of the ACM, Vol. 31, |
|---|
| 3461 | No. 10, October 1988, pp. 1192-1201 |
|---|
| 3462 | </li> |
|---|
| 3463 | |
|---|
| 3464 | <li>Makoto Matsumoto and Takuji Nishimura, "Mersenne Twister: A |
|---|
| 3465 | 623-dimensionally equidistributed uniform pseudo-random number |
|---|
| 3466 | generator", ACM Transactions on Modeling and Computer Simulation: |
|---|
| 3467 | Special Issue on Uniform Random Number Generation, Vol. 8, No. 1, |
|---|
| 3468 | January 1998, pp. 3-30. |
|---|
| 3469 | http://www.math.keio.ac.jp/matumoto/emt.html. |
|---|
| 3470 | </li> |
|---|
| 3471 | |
|---|
| 3472 | <li>Donald E. Knuth, "The Art of Computer Programming, Vol. 2", |
|---|
| 3473 | 3rd ed., 1997, pp. 1-193. |
|---|
| 3474 | </li> |
|---|
| 3475 | |
|---|
| 3476 | <li>Carter Bays and S.D. Durham, "Improving a poor random number |
|---|
| 3477 | generator", ACM Transactions on Mathematical Software, Vol. 2, 1979, |
|---|
| 3478 | pp. 59-64. |
|---|
| 3479 | </li> |
|---|
| 3480 | |
|---|
| 3481 | <li>Martin Lüscher, "A portable high-quality random number generator |
|---|
| 3482 | for lattice field theory simulations.", Computer Physics |
|---|
| 3483 | Communications, Vol. 79, 1994, pp. 100-110. |
|---|
| 3484 | </li> |
|---|
| 3485 | |
|---|
| 3486 | <li>William J. Hurd, "Efficient Generation of Statistically Good |
|---|
| 3487 | Pseudonoise by Linearly Interconnected Shift Registers", Technical |
|---|
| 3488 | Report 32-1526, Volume XI, The Deep Space Network Progress Report for |
|---|
| 3489 | July and August 1972, NASA Jet Propulsion Laboratory, 1972 and IEEE |
|---|
| 3490 | Transactions on Computers Vol. 23, 1974. |
|---|
| 3491 | </li> |
|---|
| 3492 | |
|---|
| 3493 | <li>Pierre L'Ecuyer, "Efficient and Portable Combined Random Number |
|---|
| 3494 | Generators", Communications of the ACM, Vol. 31, pp. 742-749+774, |
|---|
| 3495 | 1988. |
|---|
| 3496 | </li> |
|---|
| 3497 | |
|---|
| 3498 | <li>Pierre L'Ecuyer, "Maximally equidistributed combined Tausworthe |
|---|
| 3499 | generators", Mathematics of Computation Vol. 65, pp. 203-213, 1996. |
|---|
| 3500 | </li> |
|---|
| 3501 | |
|---|
| 3502 | <li>Pierre L'Ecuyer, "Good parameters and implementations for combined |
|---|
| 3503 | multple recursive random number generators", Operations Research |
|---|
| 3504 | Vol. 47, pp. 159-164, 1999. |
|---|
| 3505 | </li> |
|---|
| 3506 | |
|---|
| 3507 | <li>S. Kirkpatrick and E. Stoll, "A very fast shift-register sequence |
|---|
| 3508 | random number generator", Journal of Computational Physics, Vol. 40, |
|---|
| 3509 | pp. 517-526, 1981.</li> |
|---|
| 3510 | |
|---|
| 3511 | <li>R. C. Tausworthe, "Random numbers generated by iinear recurrence |
|---|
| 3512 | modulo two", Mathematics of Computation, Vol. 19, pp. 201-209, |
|---|
| 3513 | 1965.</li> |
|---|
| 3514 | |
|---|
| 3515 | <li>George Marsaglia and Arif Zaman, "A New Class of Random Number |
|---|
| 3516 | Generators", Annals of Applied Probability, Vol. 1, No. 3, 1991.</li> |
|---|
| 3517 | |
|---|
| 3518 | </ul> |
|---|