GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
randmtzig.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2006-2025 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26/*
27 A C-program for MT19937, with initialization improved 2002/2/10.
28 Coded by Takuji Nishimura and Makoto Matsumoto.
29 This is a faster version by taking Shawn Cokus's optimization,
30 Matthe Bellew's simplification, Isaku Wada's real version.
31 David Bateman added normal and exponential distributions following
32 Marsaglia and Tang's Ziggurat algorithm.
33
34 Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
35 Copyright (C) 2004, David Bateman
36 All rights reserved.
37
38 Redistribution and use in source and binary forms, with or without
39 modification, are permitted provided that the following conditions
40 are met:
41
42 1. Redistributions of source code must retain the above copyright
43 notice, this list of conditions and the following disclaimer.
44
45 2. Redistributions in binary form must reproduce the above copyright
46 notice, this list of conditions and the following disclaimer in the
47 documentation and/or other materials provided with the distribution.
48
49 3. The names of its contributors may not be used to endorse or promote
50 products derived from this software without specific prior written
51 permission.
52
53 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
54 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
55 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
56 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
57 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
58 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
59 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
60 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
61 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
62 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64
65
66 Any feedback is very welcome.
67 http://www.math.keio.ac.jp/matumoto/emt.html
68 email: matumoto@math.keio.ac.jp
69
70 * 2004-01-19 Paul Kienzle
71 * * comment out main
72 * add init_by_entropy, get_state, set_state
73 * * converted to allow compiling by C++ compiler
74 *
75 * 2004-01-25 David Bateman
76 * * Add Marsaglia and Tsang Ziggurat code
77 *
78 * 2004-07-13 Paul Kienzle
79 * * make into an independent library with some docs.
80 * * introduce new main and test code.
81 *
82 * 2004-07-28 Paul Kienzle & David Bateman
83 * * add -DALLBITS flag for 32 vs. 53 bits of randomness in mantissa
84 * * make the naming scheme more uniform
85 * * add -DHAVE_X86 for faster support of 53 bit mantissa on x86 arch.
86 *
87 * 2005-02-23 Paul Kienzle
88 * * fix -DHAVE_X86_32 flag and add -DUSE_X86_32=0|1 for explicit control
89 *
90 * 2006-04-01 David Bateman
91 * * convert for use in octave, declaring static functions only used
92 * here and adding oct_ to functions visible externally
93 * * inverse sense of ALLBITS
94 *
95 * 2012-05-18 David Bateman
96 * * Remove randu64 and ALLBIT option
97 * * Add the single precision generators
98 */
99
100/*
101 === Build instructions ===
102
103 Compile with -DHAVE_GETTIMEOFDAY if the gettimeofday function is
104 available. This is not necessary if your architecture has
105 /dev/urandom defined.
106
107 Uses implicit -Di386 or explicit -DHAVE_X86_32 to determine if CPU=x86.
108 You can force X86 behavior with -DUSE_X86_32=1, or suppress it with
109 -DUSE_X86_32=0. You should also consider -march=i686 or similar for
110 extra performance. Check whether -DUSE_X86_32=0 is faster on 64-bit
111 x86 architectures.
112
113 If you want to replace the Mersenne Twister with another
114 generator then redefine randi32 appropriately.
115
116 === Usage instructions ===
117 Before using any of the generators, initialize the state with one of
118 the init_mersenne_twister functions.
119
120 All generators share the same state vector.
121
122 === Mersenne Twister ===
123 random initial state:
124 void init_mersenne_twister ()
125
126 // 32-bit initial state:
127 void init_mersenne_twister (uint32_t s)
128
129 // m*32-bit initial state:
130 void init_mersenne_twister (uint32_t k[],int m)
131
132 // saves state in array:
133 void get_mersenne_twister_state (uint32_t save[MT_N+1])
134
135 // restores state from array
136 void set_mersenne_twister_state (uint32_t save[MT_N+1])
137
138 static uint32_t randmt () returns 32-bit unsigned int
139
140 === inline generators ===
141 static uint32_t randi32 () returns 32-bit unsigned int
142 static uint64_t randi53 () returns 53-bit unsigned int
143 static uint64_t randi54 () returns 54-bit unsigned int
144 static float randu24 () returns 24-bit uniform in (0,1)
145 static double randu53 () returns 53-bit uniform in (0,1)
146
147 double rand_uniform () returns M-bit uniform in (0,1)
148 double rand_normal () returns M-bit standard normal
149 double rand_exponential () returns N-bit standard exponential
150
151 === Array generators ===
152 void rand_uniform (octave_idx_type, double [])
153 void rand_normal (octave_idx_type, double [])
154 void rand_exponential (octave_idx_type, double [])
155*/
156
157#if defined (HAVE_CONFIG_H)
158# include "config.h"
159#endif
160
161#include <cmath>
162#include <cstdio>
163#include <ctime>
164
165#include <algorithm>
166#include <random>
167
168#include "oct-syscalls.h"
169#include "oct-time.h"
170#include "randmtzig.h"
171
172/* FIXME: may want to suppress X86 if sizeof(long) > 4 */
173#if ! defined (USE_X86_32)
174# if defined (i386) || defined (HAVE_X86_32)
175# define USE_X86_32 1
176# else
177# define USE_X86_32 0
178# endif
179#endif
180
182
183/* ===== Mersenne Twister 32-bit generator ===== */
184
185#define MT_M 397
186#define MATRIX_A 0x9908b0dfUL /* constant vector a */
187#define UMASK 0x80000000UL /* most significant w-r bits */
188#define LMASK 0x7fffffffUL /* least significant r bits */
189#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
190#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
191
192static uint32_t *next;
193static uint32_t state[MT_N]; /* the array for the state vector */
194static int left = 1;
195static int initf = 0;
196static int initt = 1;
197static int inittf = 1;
198
199/* initializes state[MT_N] with a seed */
200void
201init_mersenne_twister (const uint32_t s)
202{
203 int j;
204 state[0] = s & 0xffffffffUL;
205 for (j = 1; j < MT_N; j++)
206 {
207 state[j] = (1812433253UL * (state[j-1] ^ (state[j-1] >> 30)) + j);
208 /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
209 /* In the previous versions, MSBs of the seed affect */
210 /* only MSBs of the array state[]. */
211 /* 2002/01/09 modified by Makoto Matsumoto */
212 state[j] &= 0xffffffffUL; /* for >32 bit machines */
213 }
214 left = 1;
215 initf = 1;
216}
217
218/* initialize by an array with array-length */
219/* init_key is the array for initializing keys */
220/* key_length is its length */
221void
222init_mersenne_twister (const uint32_t *init_key, const int key_length)
223{
224 int i, j, k;
225 init_mersenne_twister (19650218UL);
226 i = 1;
227 j = 0;
228 k = (MT_N > key_length ? MT_N : key_length);
229 for (; k; k--)
230 {
231 state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1664525UL))
232 + init_key[j] + j; /* non linear */
233 state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
234 i++;
235 j++;
236 if (i >= MT_N)
237 {
238 state[0] = state[MT_N-1];
239 i = 1;
240 }
241 if (j >= key_length)
242 j = 0;
243 }
244 for (k = MT_N - 1; k; k--)
245 {
246 state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL))
247 - i; /* non linear */
248 state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
249 i++;
250 if (i >= MT_N)
251 {
252 state[0] = state[MT_N-1];
253 i = 1;
254 }
255 }
256
257 state[0] = 0x80000000UL; /* MSB is 1; assuring nonzero initial array */
258 left = 1;
259 initf = 1;
260}
261
262void
264{
265 uint32_t entropy[MT_N];
266 int n = 0;
267
268 // Gather some entropy from various sources
269
270 sys::time now;
271
272 // Current time in seconds
273 if (n < MT_N)
274 entropy[n++] = now.unix_time ();
275
276 // CPU time used (usec)
277 if (n < MT_N)
278 entropy[n++] = clock ();
279
280 // Fractional part of current time
281 if (n < MT_N)
282 entropy[n++] = now.usec ();
283
284 // Include the PID to make sure that several processes reaching here at the
285 // same time use different random numbers.
286 if (n < MT_N)
287 entropy[n++] = sys::getpid ();
288
289 if (n < MT_N)
290 {
291 try
292 {
293 // The standard doesn't *guarantee* that random_device provides
294 // non-deterministic random numbers. So add entropy from this
295 // source last to make sure we gathered at least some entropy from
296 // the earlier sources.
297 std::random_device rd;
298 std::uniform_int_distribution<uint32_t> dist;
299 // Add 1024 bit of "true" entropy
300 int n_max = std::min (n + 32, MT_N);
301 while (n < n_max)
302 entropy[n++] = dist (rd);
303 }
304 catch (const std::exception&)
305 {
306 // Just ignore any exception and skip that source of entropy.
307 }
308 }
309
310 // Send all the entropy into the initial state vector
311 init_mersenne_twister (entropy, n);
312}
313
314void
315set_mersenne_twister_state (const uint32_t *save)
316{
317 std::copy_n (save, MT_N, state);
318 left = save[MT_N];
319 next = state + (MT_N - left + 1);
320}
321
322void
324{
325 std::copy_n (state, MT_N, save);
326 save[MT_N] = left;
327}
328
329static void
330next_state ()
331{
332 uint32_t *p = state;
333 int j;
334
335 /* if init_by_int() has not been called, */
336 /* a default initial seed is used */
337 /* if (initf==0) init_by_int(5489UL); */
338 /* Or better yet, a random seed! */
339 if (initf == 0)
341
342 left = MT_N;
343 next = state;
344
345 for (j = MT_N - MT_M + 1; --j; p++)
346 *p = p[MT_M] ^ TWIST(p[0], p[1]);
347
348 for (j = MT_M; --j; p++)
349 *p = p[MT_M-MT_N] ^ TWIST(p[0], p[1]);
350
351 *p = p[MT_M-MT_N] ^ TWIST(p[0], state[0]);
352}
353
354/* generates a random number on [0,0xffffffff]-interval */
355static uint32_t
356randmt ()
357{
358 uint32_t y;
359
360 if (--left == 0)
361 next_state ();
362 y = *next++;
363
364 /* Tempering */
365 y ^= (y >> 11);
366 y ^= (y << 7) & 0x9d2c5680UL;
367 y ^= (y << 15) & 0xefc60000UL;
368 return (y ^ (y >> 18));
369}
370
371/* ===== Uniform generators ===== */
372
373/* Select which 32 bit generator to use */
374#define randi32 randmt
375
376static uint64_t
377randi53 ()
378{
379 const uint32_t lo = randi32 ();
380 const uint32_t hi = randi32 () & 0x1FFFFF;
381#if defined (HAVE_X86_32)
382 uint64_t u;
383 uint32_t *p = (uint32_t *)&u;
384 p[0] = lo;
385 p[1] = hi;
386 return u;
387#else
388 return ((static_cast<uint64_t> (hi) << 32) | lo);
389#endif
390}
391
392static uint64_t
393randi54 ()
394{
395 const uint32_t lo = randi32 ();
396 const uint32_t hi = randi32 () & 0x3FFFFF;
397#if defined (HAVE_X86_32)
398 uint64_t u;
399 uint32_t *p = static_cast<uint32_t *> (&u);
400 p[0] = lo;
401 p[1] = hi;
402 return u;
403#else
404 return ((static_cast<uint64_t> (hi) << 32) | lo);
405#endif
406}
407
408/* generates a random number on (0,1)-real-interval */
409static float
410randu24 ()
411{
412 uint32_t i;
413
414 do
415 {
416 i = randi32 () & static_cast<uint32_t> (0xFFFFFF);
417 }
418 while (i == 0);
419
420 return i * (1.0f / 16777216.0f);
421}
422
423/* generates a random number on (0,1) with 53-bit resolution */
424static double
425randu53 ()
426{
427 int32_t a, b;
428
429 do
430 {
431 a = randi32 () >> 5;
432 b = randi32 () >> 6;
433 }
434 while (a == 0 && b == 0);
435
436 return (a*67108864.0 + b) * (1.0/9007199254740992.0);
437}
438
439/* Determine mantissa for uniform doubles */
440template <>
443{
444 return randu53 ();
445}
446
447/* Determine mantissa for uniform floats */
448template <>
451{
452 return randu24 ();
453}
454
455/* ===== Ziggurat normal and exponential generators ===== */
456
457#define ZIGGURAT_TABLE_SIZE 256
458
459#define ZIGGURAT_NOR_R 3.6541528853610088
460#define ZIGGURAT_NOR_INV_R 0.27366123732975828
461#define NOR_SECTION_AREA 0.00492867323399
462
463#define ZIGGURAT_EXP_R 7.69711747013104972
464#define ZIGGURAT_EXP_INV_R 0.129918765548341586
465#define EXP_SECTION_AREA 0.0039496598225815571993
466
467#define ZIGINT uint64_t
468#define EMANTISSA 9007199254740992.0 /* 53 bit mantissa */
469#define ERANDI randi53() /* 53 bits for mantissa */
470#define NMANTISSA EMANTISSA
471#define NRANDI randi54() /* 53 bits for mantissa + 1 bit sign */
472#define RANDU randu53()
473
474static ZIGINT ki[ZIGGURAT_TABLE_SIZE];
475static double wi[ZIGGURAT_TABLE_SIZE], fi[ZIGGURAT_TABLE_SIZE];
476static ZIGINT ke[ZIGGURAT_TABLE_SIZE];
477static double we[ZIGGURAT_TABLE_SIZE], fe[ZIGGURAT_TABLE_SIZE];
478
479/*
480 This code is based on the paper Marsaglia and Tsang, "The ziggurat method
481 for generating random variables", Journ. Statistical Software. Code was
482 presented in this paper for a Ziggurat of 127 levels and using a 32 bit
483 integer random number generator. This version of the code, uses the
484 Mersenne Twister as the integer generator and uses 256 levels in the
485 Ziggurat. This has several advantages.
486
487 1) As Marsaglia and Tsang themselves states, the more levels the few
488 times the expensive tail algorithm must be called
489 2) The cycle time of the generator is determined by the integer
490 generator, thus the use of a Mersenne Twister for the core random
491 generator makes this cycle extremely long.
492 3) The license on the original code was unclear, thus rewriting the code
493 from the article means we are free of copyright issues.
494 4) Compile flag for full 53-bit random mantissa.
495
496 It should be stated that the authors made my life easier, by the fact that
497 the algorithm developed in the text of the article is for a 256 level
498 ziggurat, even if the code itself isn't...
499
500 One modification to the algorithm developed in the article, is that it is
501 assumed that 0 <= x < Inf, and "unsigned long"s are used, thus resulting in
502 terms like 2^32 in the code. As the normal distribution is defined between
503 -Inf < x < Inf, we effectively only have 31 bit integers plus a sign. Thus
504 in Marsaglia and Tsang, terms like 2^32 become 2^31. We use NMANTISSA for
505 this term. The exponential distribution is one sided so we use the
506 full 32 bits. We use EMANTISSA for this term.
507
508 It appears that I'm slightly slower than the code in the article, this
509 is partially due to a better generator of random integers than they
510 use. But might also be that the case of rapid return was optimized by
511 inlining the relevant code with a #define. As the basic Mersenne
512 Twister is only 25% faster than this code I suspect that the main
513 reason is just the use of the Mersenne Twister and not the inlining,
514 so I'm not going to try and optimize further.
515*/
516
517void
519{
520 int i;
521 double x, x1;
522
523 /* Ziggurat tables for the normal distribution */
524 x1 = ZIGGURAT_NOR_R;
525 wi[255] = x1 / NMANTISSA;
526 fi[255] = exp (-0.5 * x1 * x1);
527
528 /* Index zero is special for tail strip, where Marsaglia and Tsang
529 * defines this as
530 * k_0 = 2^31 * r * f(r) / v, w_0 = 0.5^31 * v / f(r), f_0 = 1,
531 * where v is the area of each strip of the ziggurat.
532 */
533 ki[0] = static_cast<ZIGINT> (x1 * fi[255] / NOR_SECTION_AREA * NMANTISSA);
534 wi[0] = NOR_SECTION_AREA / fi[255] / NMANTISSA;
535 fi[0] = 1.;
536
537 for (i = 254; i > 0; i--)
538 {
539 /* New x is given by x = f^{-1}(v/x_{i+1} + f(x_{i+1})), thus
540 * need inverse operator of y = exp(-0.5*x*x) -> x = sqrt(-2*ln(y))
541 */
542 x = std::sqrt (-2. * std::log (NOR_SECTION_AREA / x1 + fi[i+1]));
543 ki[i+1] = static_cast<ZIGINT> (x / x1 * NMANTISSA);
544 wi[i] = x / NMANTISSA;
545 fi[i] = exp (-0.5 * x * x);
546 x1 = x;
547 }
548
549 ki[1] = 0;
550
551 /* Zigurrat tables for the exponential distribution */
552 x1 = ZIGGURAT_EXP_R;
553 we[255] = x1 / EMANTISSA;
554 fe[255] = exp (-x1);
555
556 /* Index zero is special for tail strip, where Marsaglia and Tsang
557 * defines this as
558 * k_0 = 2^32 * r * f(r) / v, w_0 = 0.5^32 * v / f(r), f_0 = 1,
559 * where v is the area of each strip of the ziggurat.
560 */
561 ke[0] = static_cast<ZIGINT> (x1 * fe[255] / EXP_SECTION_AREA * EMANTISSA);
562 we[0] = EXP_SECTION_AREA / fe[255] / EMANTISSA;
563 fe[0] = 1.;
564
565 for (i = 254; i > 0; i--)
566 {
567 /* New x is given by x = f^{-1}(v/x_{i+1} + f(x_{i+1})), thus
568 * need inverse operator of y = exp(-x) -> x = -ln(y)
569 */
570 x = - std::log (EXP_SECTION_AREA / x1 + fe[i+1]);
571 ke[i+1] = static_cast<ZIGINT> (x / x1 * EMANTISSA);
572 we[i] = x / EMANTISSA;
573 fe[i] = exp (-x);
574 x1 = x;
575 }
576 ke[1] = 0;
577
578 initt = 0;
579}
580
581/*
582 * Here is the guts of the algorithm. As Marsaglia and Tsang state the
583 * algorithm in their paper
584 *
585 * 1) Calculate a random signed integer j and let i be the index
586 * provided by the rightmost 8-bits of j
587 * 2) Set x = j * w_i. If j < k_i return x
588 * 3) If i = 0, then return x from the tail
589 * 4) If [f(x_{i-1}) - f(x_i)] * U < f(x) - f(x_i), return x
590 * 5) goto step 1
591 *
592 * Where f is the functional form of the distribution, which for a normal
593 * distribution is exp(-0.5*x*x)
594 */
595
596
597template <>
600{
601 if (initt)
603
604 while (1)
605 {
606 /* The following code is specialized for 32-bit mantissa.
607 * Compared to the arbitrary mantissa code, there is a performance
608 * gain for 32-bits: PPC: 2%, MIPS: 8%, x86: 40%
609 * There is a bigger performance gain compared to using a full
610 * 53-bit mantissa: PPC: 60%, MIPS: 65%, x86: 240%
611 * Of course, different compilers and operating systems may
612 * have something to do with this.
613 */
614# if defined (HAVE_X86_32)
615 /* 53-bit mantissa, 1-bit sign, x86 32-bit architecture */
616 double x;
617 int si, idx;
618 uint32_t lo, hi;
619 int64_t rabs;
620 uint32_t *p = (uint32_t *)&rabs;
621 lo = randi32 ();
622 idx = lo & 0xFF;
623 hi = randi32 ();
624 si = hi & UMASK;
625 p[0] = lo;
626 p[1] = hi & 0x1FFFFF;
627 x = ( si ? -rabs : rabs ) * wi[idx];
628# else
629 /* arbitrary mantissa (selected by NRANDI, with 1 bit for sign) */
630 const uint64_t r = NRANDI;
631 const int64_t rabs = r >> 1;
632 const int idx = static_cast<int> (rabs & 0xFF);
633 const double x = ( (r & 1) ? -rabs : rabs) * wi[idx];
634# endif
635 if (rabs < static_cast<int64_t> (ki[idx]))
636 return x; /* 99.3% of the time we return here 1st try */
637 else if (idx == 0)
638 {
639 /* As stated in Marsaglia and Tsang
640 *
641 * For the normal tail, the method of Marsaglia[5] provides:
642 * generate x = -ln(U_1)/r, y = -ln(U_2), until y+y > x*x,
643 * then return r+x. Except that r+x is always in the positive
644 * tail!!!! Any thing random might be used to determine the
645 * sign, but as we already have r we might as well use it
646 *
647 * [PAK] but not the bottom 8 bits, since they are all 0 here!
648 */
649 double xx, yy;
650 do
651 {
652 xx = - ZIGGURAT_NOR_INV_R * std::log (RANDU);
653 yy = - std::log (RANDU);
654 }
655 while ( yy+yy <= xx*xx);
656 return ((rabs & 0x100) ? -ZIGGURAT_NOR_R-xx : ZIGGURAT_NOR_R+xx);
657 }
658 else if ((fi[idx-1] - fi[idx]) * RANDU + fi[idx] < exp (-0.5*x*x))
659 return x;
660 }
661}
662
663template <>
666{
667 if (initt)
669
670 while (1)
671 {
672 ZIGINT ri = ERANDI;
673 const int idx = static_cast<int> (ri & 0xFF);
674 const double x = ri * we[idx];
675 if (ri < ke[idx])
676 return x; /* 98.9% of the time we return here 1st try */
677 else if (idx == 0)
678 {
679 /* As stated in Marsaglia and Tsang
680 *
681 * For the exponential tail, the method of Marsaglia[5] provides:
682 * x = r - ln(U);
683 */
684 return ZIGGURAT_EXP_R - std::log (RANDU);
685 }
686 else if ((fe[idx-1] - fe[idx]) * RANDU + fe[idx] < exp (-x))
687 return x;
688 }
689}
690
691template <> OCTAVE_API void rand_uniform<double> (octave_idx_type n, double *p)
692{
693 std::generate_n (p, n, []() { return rand_uniform<double> (); });
694}
695
696template <> OCTAVE_API void rand_normal (octave_idx_type n, double *p)
697{
698 std::generate_n (p, n, []() { return rand_normal<double> (); });
699}
700
701template <> OCTAVE_API void rand_exponential (octave_idx_type n, double *p)
702{
703 std::generate_n (p, n, []() { return rand_exponential<double> (); });
704}
705
706#undef ZIGINT
707#undef EMANTISSA
708#undef ERANDI
709#undef NMANTISSA
710#undef NRANDI
711#undef RANDU
712
713#define ZIGINT uint32_t
714#define EMANTISSA 4294967296.0 /* 32 bit mantissa */
715#define ERANDI randi32() /* 32 bits for mantissa */
716#define NMANTISSA 2147483648.0 /* 31 bit mantissa */
717#define NRANDI randi32() /* 31 bits for mantissa + 1 bit sign */
718#define RANDU randu24()
719
720static ZIGINT fki[ZIGGURAT_TABLE_SIZE];
721static float fwi[ZIGGURAT_TABLE_SIZE], ffi[ZIGGURAT_TABLE_SIZE];
722static ZIGINT fke[ZIGGURAT_TABLE_SIZE];
723static float fwe[ZIGGURAT_TABLE_SIZE], ffe[ZIGGURAT_TABLE_SIZE];
724
725static void
726create_ziggurat_float_tables ()
727{
728 int i;
729 float x, x1;
730
731 /* Ziggurat tables for the normal distribution */
732 x1 = ZIGGURAT_NOR_R;
733 fwi[255] = x1 / NMANTISSA;
734 ffi[255] = exp (-0.5 * x1 * x1);
735
736 /* Index zero is special for tail strip, where Marsaglia and Tsang
737 * defines this as
738 * k_0 = 2^31 * r * f(r) / v, w_0 = 0.5^31 * v / f(r), f_0 = 1,
739 * where v is the area of each strip of the ziggurat.
740 */
741 fki[0] = static_cast<ZIGINT> (x1 * ffi[255] / NOR_SECTION_AREA * NMANTISSA);
742 fwi[0] = NOR_SECTION_AREA / ffi[255] / NMANTISSA;
743 ffi[0] = 1.;
744
745 for (i = 254; i > 0; i--)
746 {
747 /* New x is given by x = f^{-1}(v/x_{i+1} + f(x_{i+1})), thus
748 * need inverse operator of y = exp(-0.5*x*x) -> x = sqrt(-2*ln(y))
749 */
750 x = std::sqrt (-2. * std::log (NOR_SECTION_AREA / x1 + ffi[i+1]));
751 fki[i+1] = static_cast<ZIGINT> (x / x1 * NMANTISSA);
752 fwi[i] = x / NMANTISSA;
753 ffi[i] = exp (-0.5 * x * x);
754 x1 = x;
755 }
756
757 fki[1] = 0;
758
759 /* Zigurrat tables for the exponential distribution */
760 x1 = ZIGGURAT_EXP_R;
761 fwe[255] = x1 / EMANTISSA;
762 ffe[255] = exp (-x1);
763
764 /* Index zero is special for tail strip, where Marsaglia and Tsang
765 * defines this as
766 * k_0 = 2^32 * r * f(r) / v, w_0 = 0.5^32 * v / f(r), f_0 = 1,
767 * where v is the area of each strip of the ziggurat.
768 */
769 fke[0] = static_cast<ZIGINT> (x1 * ffe[255] / EXP_SECTION_AREA * EMANTISSA);
770 fwe[0] = EXP_SECTION_AREA / ffe[255] / EMANTISSA;
771 ffe[0] = 1.;
772
773 for (i = 254; i > 0; i--)
774 {
775 /* New x is given by x = f^{-1}(v/x_{i+1} + f(x_{i+1})), thus
776 * need inverse operator of y = exp(-x) -> x = -ln(y)
777 */
778 x = - std::log (EXP_SECTION_AREA / x1 + ffe[i+1]);
779 fke[i+1] = static_cast<ZIGINT> (x / x1 * EMANTISSA);
780 fwe[i] = x / EMANTISSA;
781 ffe[i] = exp (-x);
782 x1 = x;
783 }
784 fke[1] = 0;
785
786 inittf = 0;
787}
788
789/*
790 * Here is the guts of the algorithm. As Marsaglia and Tsang state the
791 * algorithm in their paper
792 *
793 * 1) Calculate a random signed integer j and let i be the index
794 * provided by the rightmost 8-bits of j
795 * 2) Set x = j * w_i. If j < k_i return x
796 * 3) If i = 0, then return x from the tail
797 * 4) If [f(x_{i-1}) - f(x_i)] * U < f(x) - f(x_i), return x
798 * 5) goto step 1
799 *
800 * Where f is the functional form of the distribution, which for a normal
801 * distribution is exp(-0.5*x*x)
802 */
803
804template <>
807{
808 if (inittf)
809 create_ziggurat_float_tables ();
810
811 while (1)
812 {
813 /* 32-bit mantissa */
814 const uint32_t r = randi32 ();
815 const uint32_t rabs = r & LMASK;
816 const int idx = static_cast<int> (r & 0xFF);
817 const float x = static_cast<int32_t> (r) * fwi[idx];
818 if (rabs < fki[idx])
819 return x; /* 99.3% of the time we return here 1st try */
820 else if (idx == 0)
821 {
822 /* As stated in Marsaglia and Tsang
823 *
824 * For the normal tail, the method of Marsaglia[5] provides:
825 * generate x = -ln(U_1)/r, y = -ln(U_2), until y+y > x*x,
826 * then return r+x. Except that r+x is always in the positive
827 * tail!!!! Any thing random might be used to determine the
828 * sign, but as we already have r we might as well use it
829 *
830 * [PAK] but not the bottom 8 bits, since they are all 0 here!
831 */
832 float xx, yy;
833 do
834 {
835 xx = - ZIGGURAT_NOR_INV_R * std::log (RANDU);
836 yy = - std::log (RANDU);
837 }
838 while ( yy+yy <= xx*xx);
839 return ((rabs & 0x100) ? -ZIGGURAT_NOR_R-xx : ZIGGURAT_NOR_R+xx);
840 }
841 else if ((ffi[idx-1] - ffi[idx]) * RANDU + ffi[idx] < exp (-0.5*x*x))
842 return x;
843 }
844}
845
846template <>
849{
850 if (inittf)
851 create_ziggurat_float_tables ();
852
853 while (1)
854 {
855 ZIGINT ri = ERANDI;
856 const int idx = static_cast<int> (ri & 0xFF);
857 const float x = ri * fwe[idx];
858 if (ri < fke[idx])
859 return x; /* 98.9% of the time we return here 1st try */
860 else if (idx == 0)
861 {
862 /* As stated in Marsaglia and Tsang
863 *
864 * For the exponential tail, the method of Marsaglia[5] provides:
865 * x = r - ln(U);
866 */
867 return ZIGGURAT_EXP_R - std::log (RANDU);
868 }
869 else if ((ffe[idx-1] - ffe[idx]) * RANDU + ffe[idx] < exp (-x))
870 return x;
871 }
872}
873
874template <> OCTAVE_API void rand_uniform (octave_idx_type n, float *p)
875{
876 std::generate_n (p, n, []() { return rand_uniform<float> (); });
877}
878
879template <> OCTAVE_API void rand_normal (octave_idx_type n, float *p)
880{
881 std::generate_n (p, n, []() { return rand_normal<float> (); });
882}
883
884template <> OCTAVE_API void rand_exponential (octave_idx_type n, float *p)
885{
886 std::generate_n (p, n, []() { return rand_exponential<float> (); });
887}
888
889OCTAVE_END_NAMESPACE(octave)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
F77_RET_T const F77_DBLE * x
#define OCTAVE_API
Definition main.in.cc:55
#define TWIST(u, v)
Definition randmtzig.cc:190
void get_mersenne_twister_state(uint32_t *save)
Definition randmtzig.cc:323
#define ZIGGURAT_EXP_R
Definition randmtzig.cc:463
double rand_uniform< double >()
Definition randmtzig.cc:442
void set_mersenne_twister_state(const uint32_t *save)
Definition randmtzig.cc:315
void init_mersenne_twister()
Definition randmtzig.cc:263
#define EMANTISSA
Definition randmtzig.cc:468
#define ZIGGURAT_TABLE_SIZE
Definition randmtzig.cc:457
#define randi32
Definition randmtzig.cc:374
double rand_normal< double >()
Definition randmtzig.cc:599
#define RANDU
Definition randmtzig.cc:472
#define ZIGINT
Definition randmtzig.cc:467
#define LMASK
Definition randmtzig.cc:188
#define NRANDI
Definition randmtzig.cc:471
#define ERANDI
Definition randmtzig.cc:469
float rand_normal< float >()
Definition randmtzig.cc:806
#define NOR_SECTION_AREA
Definition randmtzig.cc:461
float rand_exponential< float >()
Definition randmtzig.cc:848
void create_ziggurat_tables()
Definition randmtzig.cc:518
#define ZIGGURAT_NOR_R
Definition randmtzig.cc:459
#define ZIGGURAT_NOR_INV_R
Definition randmtzig.cc:460
#define UMASK
Definition randmtzig.cc:187
#define NMANTISSA
Definition randmtzig.cc:470
#define MT_M
Definition randmtzig.cc:185
double rand_exponential< double >()
Definition randmtzig.cc:665
#define EXP_SECTION_AREA
Definition randmtzig.cc:465
float rand_uniform< float >()
Definition randmtzig.cc:450
#define MT_N
Definition randmtzig.h:72
T rand_exponential()
T rand_uniform()
T rand_normal()