README.md (8765B)
1 <!-- 2 3 @license Apache-2.0 4 5 Copyright (c) 2018 The Stdlib Authors. 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 19 --> 20 21 # Improved Ziggurat Method 22 23 > Standard normally distributed pseudorandom numbers using the [Improved Ziggurat][ziggurat-algorithm] method. 24 25 <section class="usage"> 26 27 ## Usage 28 29 ```javascript 30 var randn = require( '@stdlib/random/base/improved-ziggurat' ); 31 ``` 32 33 #### randn() 34 35 Returns a standard normally distributed pseudorandom number. 36 37 ```javascript 38 var r = randn(); 39 // returns <number> 40 ``` 41 42 #### randn.factory( \[options] ) 43 44 Returns a pseudorandom number generator (PRNG) for generating standard normally distributed pseudorandom numbers. 45 46 ```javascript 47 var rand = randn.factory(); 48 ``` 49 50 The function accepts the following `options`: 51 52 - **prng**: pseudorandom number generator for generating uniformly distributed pseudorandom numbers on the interval `[0,1)`. If provided, the function **ignores** both the `state` and `seed` options. In order to seed the returned pseudorandom number generator, one must seed the provided `prng` (assuming the provided `prng` is seedable). 53 - **seed**: pseudorandom number generator seed. 54 - **state**: a [`Uint32Array`][@stdlib/array/uint32] containing pseudorandom number generator state. If provided, the function ignores the `seed` option. 55 - **copy**: `boolean` indicating whether to copy a provided pseudorandom number generator state. Setting this option to `false` allows sharing state between two or more pseudorandom number generators. Setting this option to `true` ensures that a returned generator has exclusive control over its internal state. Default: `true`. 56 57 To use a custom PRNG as the underlying source of uniformly distributed pseudorandom numbers, set the `prng` option. 58 59 ```javascript 60 var minstd = require( '@stdlib/random/base/minstd' ); 61 62 var rand = randn.factory({ 63 'prng': minstd.normalized 64 }); 65 66 var r = rand(); 67 // returns <number> 68 ``` 69 70 To seed a pseudorandom number generator, set the `seed` option. 71 72 ```javascript 73 var rand1 = randn.factory({ 74 'seed': 12345 75 }); 76 77 var r1 = rand1(); 78 // returns <number> 79 80 var rand2 = randn.factory({ 81 'seed': 12345 82 }); 83 84 var r2 = rand2(); 85 // returns <number> 86 87 var bool = ( r1 === r2 ); 88 // returns true 89 ``` 90 91 To return a generator having a specific initial state, set the generator `state` option. 92 93 ```javascript 94 var rand; 95 var bool; 96 var r; 97 var i; 98 99 // Generate pseudorandom numbers, thus progressing the generator state: 100 for ( i = 0; i < 1000; i++ ) { 101 r = randn(); 102 } 103 104 // Create a new PRNG initialized to the current state of `randn`: 105 rand = randn.factory({ 106 'state': randn.state 107 }); 108 109 // Test that the generated pseudorandom numbers are the same: 110 bool = ( rand() === randn() ); 111 // returns true 112 ``` 113 114 #### randn.NAME 115 116 The generator name. 117 118 ```javascript 119 var str = randn.NAME; 120 // returns 'improved-ziggurat' 121 ``` 122 123 #### randn.PRNG 124 125 The underlying pseudorandom number generator for uniformly distributed numbers on the interval `[0,1)`. 126 127 ```javascript 128 var prng = randn.PRNG; 129 // returns <Function> 130 ``` 131 132 #### randn.seed 133 134 The value used to seed `randn()`. 135 136 ```javascript 137 var rand; 138 var r; 139 var i; 140 141 // Generate pseudorandom values... 142 for ( i = 0; i < 100; i++ ) { 143 r = randn(); 144 } 145 146 // Generate the same pseudorandom values... 147 rand = randn.factory({ 148 'seed': randn.seed 149 }); 150 for ( i = 0; i < 100; i++ ) { 151 r = rand(); 152 } 153 ``` 154 155 If provided a PRNG for uniformly distributed numbers, this value is `null`. 156 157 <!-- eslint-disable stdlib/no-builtin-math --> 158 159 ```javascript 160 var rand = randn.factory({ 161 'prng': Math.random 162 }); 163 164 var seed = rand.seed; 165 // returns null 166 ``` 167 168 #### randn.seedLength 169 170 Length of generator seed. 171 172 ```javascript 173 var len = randn.seedLength; 174 // returns <number> 175 ``` 176 177 If provided a PRNG for uniformly distributed numbers, this value is `null`. 178 179 <!-- eslint-disable stdlib/no-builtin-math --> 180 181 ```javascript 182 var rand = randn.factory({ 183 'prng': Math.random 184 }); 185 186 var len = rand.seedLength; 187 // returns null 188 ``` 189 190 #### randn.state 191 192 Writable property for getting and setting the generator state. 193 194 ```javascript 195 var r = randn(); 196 // returns <number> 197 198 r = randn(); 199 // returns <number> 200 201 // ... 202 203 // Get a copy of the current state: 204 var state = randn.state; 205 // returns <Uint32Array> 206 207 r = randn(); 208 // returns <number> 209 210 r = randn(); 211 // returns <number> 212 213 // Reset the state: 214 randn.state = state; 215 216 // Replay the last two pseudorandom numbers: 217 r = randn(); 218 // returns <number> 219 220 r = randn(); 221 // returns <number> 222 223 // ... 224 ``` 225 226 If provided a PRNG for uniformly distributed numbers, this value is `null`. 227 228 <!-- eslint-disable stdlib/no-builtin-math --> 229 230 ```javascript 231 var rand = randn.factory({ 232 'prng': Math.random 233 }); 234 235 var state = rand.state; 236 // returns null 237 ``` 238 239 #### randn.stateLength 240 241 Length of generator state. 242 243 ```javascript 244 var len = randn.stateLength; 245 // returns <number> 246 ``` 247 248 If provided a PRNG for uniformly distributed numbers, this value is `null`. 249 250 <!-- eslint-disable stdlib/no-builtin-math --> 251 252 ```javascript 253 var rand = randn.factory({ 254 'prng': Math.random 255 }); 256 257 var len = rand.stateLength; 258 // returns null 259 ``` 260 261 #### randn.byteLength 262 263 Size (in bytes) of generator state. 264 265 ```javascript 266 var sz = randn.byteLength; 267 // returns <number> 268 ``` 269 270 If provided a PRNG for uniformly distributed numbers, this value is `null`. 271 272 <!-- eslint-disable stdlib/no-builtin-math --> 273 274 ```javascript 275 var rand = randn.factory({ 276 'prng': Math.random 277 }); 278 279 var sz = rand.byteLength; 280 // returns null 281 ``` 282 283 #### randn.toJSON() 284 285 Serializes the pseudorandom number generator as a JSON object. 286 287 ```javascript 288 var o = randn.toJSON(); 289 // returns { 'type': 'PRNG', 'name': '...', 'state': {...}, 'params': [] } 290 ``` 291 292 If provided a PRNG for uniformly distributed numbers, this method returns `null`. 293 294 <!-- eslint-disable stdlib/no-builtin-math --> 295 296 ```javascript 297 var rand = randn.factory({ 298 'prng': Math.random 299 }); 300 301 var o = rand.toJSON(); 302 // returns null 303 ``` 304 305 </section> 306 307 <!-- /.usage --> 308 309 <section class="notes"> 310 311 ## Notes 312 313 - If PRNG state is "shared" (meaning a state array was provided during PRNG creation and **not** copied) and one sets the generator state to a state array having a different length, the PRNG does **not** update the existing shared state and, instead, points to the newly provided state array. In order to synchronize PRNG output according to the new shared state array, the state array for **each** relevant PRNG must be **explicitly** set. 314 - If PRNG state is "shared" and one sets the generator state to a state array of the same length, the PRNG state is updated (along with the state of all other PRNGs sharing the PRNG's state array). 315 316 </section> 317 318 <!-- /.notes --> 319 320 <section class="examples"> 321 322 ## Examples 323 324 <!-- eslint no-undef: "error" --> 325 326 ```javascript 327 var randn = require( '@stdlib/random/base/improved-ziggurat' ); 328 329 var seed; 330 var rand; 331 var i; 332 333 // Generate pseudorandom numbers... 334 for ( i = 0; i < 100; i++ ) { 335 console.log( randn() ); 336 } 337 338 // Create a new pseudorandom number generator... 339 seed = 1234; 340 rand = randn.factory({ 341 'seed': seed 342 }); 343 for ( i = 0; i < 100; i++ ) { 344 console.log( rand() ); 345 } 346 347 // Create another pseudorandom number generator using a previous seed... 348 rand = randn.factory({ 349 'seed': randn.seed 350 }); 351 for ( i = 0; i < 100; i++ ) { 352 console.log( rand() ); 353 } 354 ``` 355 356 </section> 357 358 <!-- /.examples --> 359 360 * * * 361 362 <section class="references"> 363 364 ## References 365 366 - Doornik, Jurgen A. 2005. "An Improved Ziggurat Method to Generate Normal Random Samples." [<https://www.doornik.com/research/ziggurat.pdf>][@doornik:2005]. 367 - Marsaglia, George, and Wai Wan Tsang. 2000. "The Ziggurat Method for Generating Random Variables." _Journal of Statistical Software_ 5 (1): 1–7. doi:[10.18637/jss.v005.i08][@marsaglia:2000b]. 368 - Marsaglia, George. 1964. "Generating a Variable from the Tail of the Normal Distribution." _Technometrics_ 6 (1): 101–2. doi:[10.1080/00401706.1964.10490150][@marsaglia:1964b]. 369 370 </section> 371 372 <!-- /.references --> 373 374 <section class="links"> 375 376 [ziggurat-algorithm]: https://en.wikipedia.org/wiki/Ziggurat_algorithm 377 378 [@doornik:2005]: https://www.doornik.com/research/ziggurat.pdf 379 380 [@marsaglia:2000b]: http://dx.doi.org/10.18637/jss.v005.i08 381 382 [@marsaglia:1964b]: https://doi.org/10.1080/00401706.1964.10490150 383 384 [@stdlib/array/uint32]: https://www.npmjs.com/package/@stdlib/array-uint32 385 386 </section> 387 388 <!-- /.links -->