1 //////////////////////////////////////////////////////////////////////////
2 // MCMCrng.h is the header file for MCMCrng.cc. It contains
3 // functions used to handle random number generator streams.
4 //
5 // Andrew D. Martin
6 // Dept. of Political Science
7 // Washington University in St. Louis
8 // admartin@wustl.edu
9 //
10 // Kevin M. Quinn
11 // Dept. of Government
12 // Harvard University
13 // kevin_quinn@harvard.edu
14 //
15 // This software is distributed under the terms of the GNU GENERAL
16 // PUBLIC LICENSE Version 2, June 1991.  See the package LICENSE
17 // file for more information.
18 //
19 // ADM 7/22/04
20 //
21 // Copyright (C) 2003-2007 Andrew D. Martin and Kevin M. Quinn
22 // Copyright (C) 2007-present Andrew D. Martin, Kevin M. Quinn,
23 //    and Jong Hee Park
24 //////////////////////////////////////////////////////////////////////////
25 
26 #ifndef MCMCRNG_H
27 #define MCMCRNG_H
28 
29 #include "mersenne.h"
30 #include "lecuyer.h"
31 
32 /* This allows model handles to efficiently pass the appropriate rng
33  * to object a model's implementation.  The first arg is the name of
34  * the model implementation function.  The remaining arguments are the
35  * arguments to the model implementation function.
36  *
37  * The macro assumes that the function it is called in contains an int
38  * pointer named uselecuyer holding a boolean indication of whether or
39  * not to use the lecuyer rng.  Secondly, it assumes the function
40  * contains a pointer to an array of integers called seedarray that
41  * contains six random number seeds (or just one if using mersenne).
42  * Finally, it assumes it contains a pointer to an integer called
43  * lecuyerstream that indicates which of the lecuyer generator's
44  * streams to use.
45  */
46 
47 #define MCMCPACK_PASSRNG2MODEL(MODEL_IMPL, ...)                           \
48 {                                                                         \
49   unsigned long u_seed_array[6];                                          \
50   for (int i = 0; i < 6; ++i)                                             \
51     u_seed_array[i] = static_cast<unsigned long>(seedarray[i]);           \
52                                                                           \
53   if (*uselecuyer == 0) {                                                 \
54     mersenne the_rng;                                                     \
55     the_rng.initialize(u_seed_array[0]);                                  \
56     MODEL_IMPL(the_rng, __VA_ARGS__);                                     \
57   } else {                                                                \
58     lecuyer::SetPackageSeed(u_seed_array);                                \
59     for (int i = 0; i < (*lecuyerstream - 1); ++i)                        \
60       lecuyer skip_rng;                                                   \
61     lecuyer the_rng;                                                      \
62     MODEL_IMPL(the_rng, __VA_ARGS__);                                     \
63   }                                                                       \
64 }
65 
66 #endif
67