vSMC
vSMC: Scalable Monte Carlo
gsl.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/rng/gsl.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013,2014, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef VSMC_RNG_GSL_HPP
33 #define VSMC_RNG_GSL_HPP
34 
37 #include <gsl/gsl_rng.h>
38 
39 #define VSMC_DEFINE_RNG_GSL_RNG_TYPE_POINTER(Generator, pointer) \
40  template <> struct GSLRngTypePointer< GSL_RNG_TYPE_##Generator > \
41  {static const ::gsl_rng_type *get () {return ::gsl_rng_##pointer ;}};
42 
43 #define VSMC_DEFINE_RNG_GSL_RNG_MIN_MAX(Generator, Min, Max) \
44 template <> struct GSLRngMinMax< GSL_RNG_TYPE_##Generator > \
45 { \
46  static VSMC_CONSTEXPR const uint32_t _Min = \
47  static_cast<uint32_t>(Min##UL); \
48  static VSMC_CONSTEXPR const uint32_t _Max = \
49  static_cast<uint32_t>(Max##UL); \
50  static VSMC_CONSTEXPR uint32_t min VSMC_MNE () {return _Min;} \
51  static VSMC_CONSTEXPR uint32_t max VSMC_MNE () {return _Max;} \
52 }; // VSMC_DEFINE_RNG_GSL_RNG_MIN_MAX
53 
54 namespace vsmc {
55 
58 enum GSLRngType {
72 }; // enum GSLRngType
73 
74 namespace internal {
75 
76 template <GSLRngType> struct GSLRngTypePointer;
77 
91 
92 template <GSLRngType RngType> struct GSLRngMinMax;
93 
94 VSMC_DEFINE_RNG_GSL_RNG_MIN_MAX(MT19937, 0, 0xFFFFFFFF)
95 VSMC_DEFINE_RNG_GSL_RNG_MIN_MAX(RANLXS0, 0, 0x00FFFFFF)
96 VSMC_DEFINE_RNG_GSL_RNG_MIN_MAX(RANLXS1, 0, 0x00FFFFFF)
97 VSMC_DEFINE_RNG_GSL_RNG_MIN_MAX(RANLXS2, 0, 0x00FFFFFF)
98 VSMC_DEFINE_RNG_GSL_RNG_MIN_MAX(RANLXD1, 0, 0xFFFFFFFF)
99 VSMC_DEFINE_RNG_GSL_RNG_MIN_MAX(RANLXD2, 0, 0xFFFFFFFF)
100 VSMC_DEFINE_RNG_GSL_RNG_MIN_MAX(RANLUX, 0, 0x00FFFFFF)
101 VSMC_DEFINE_RNG_GSL_RNG_MIN_MAX(RANLUX389, 0, 0x00FFFFFF)
105 VSMC_DEFINE_RNG_GSL_RNG_MIN_MAX(TAUS2, 0, 0xFFFFFFFF)
106 VSMC_DEFINE_RNG_GSL_RNG_MIN_MAX(GFSR4, 0, 0xFFFFFFFF)
107 } // namespace vsmc::internal
108 
111 template <GSLRngType RngType>
113 {
114  public :
115 
117  rng_(::gsl_rng_alloc(internal::GSLRngTypePointer<RngType>::get())) {}
118 
120  rng_(::gsl_rng_clone(other.rng_)) {}
121 
123  {
124  if (this != &other)
125  ::gsl_rng_memcpy(rng_, other.rng_);
126 
127  return *this;
128  }
129 
130 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
132  rng_(other.rng_) {other.rng_ = VSMC_NULLPTR;}
133 
135  {
136  using std::swap;
137 
138  if (this != &other)
139  swap(rng_, other.rng_);
140 
141  return *this;
142  }
143 #endif
144 
146  {
147  if (rng_ != VSMC_NULLPTR)
148  ::gsl_rng_free(rng_);
149  }
150 
151  void seed (unsigned long s)
152  {
153  if (rng_ != VSMC_NULLPTR)
154  ::gsl_rng_set(rng_, s);
155  }
156 
157  unsigned long generate ()
158  {
159  if (rng_ != VSMC_NULLPTR)
160  return ::gsl_rng_get(rng_);
161 
162  return 0;
163  }
164 
165  unsigned long min VSMC_MNE () const {return ::gsl_rng_min(rng_);}
166  unsigned long max VSMC_MNE () const {return ::gsl_rng_max(rng_);}
167 
168  private :
169 
170  ::gsl_rng *rng_;
171 }; // class GSLGenerator
172 
175 template <GSLRngType RngType>
176 class GSLEngine :
177  public GeneratorWrapper<uint32_t, GSLGenerator<RngType>,
178  internal::GSLRngMinMax<RngType> >
179 {
182 
183  public :
184 
185  typedef uint32_t result_type;
186 
187  GSLEngine (result_type s = 0) : base(s) {seed(s);}
188 
189  template <typename SeedSeq>
190  explicit GSLEngine (SeedSeq &seq,
191  typename cxx11::enable_if<internal::is_seed_seq<SeedSeq,
192  result_type, GSLEngine<RngType>
193  >::value>::type * = VSMC_NULLPTR) : base(seq) {seed(seq);}
194 
195  void seed (result_type s)
196  {this->generator().seed(static_cast<unsigned long>(s));}
197 
198  template <typename SeedSeq>
199  void seed (SeedSeq &seq,
200  typename cxx11::enable_if<internal::is_seed_seq<SeedSeq,
201  result_type, GSLEngine<RngType>
202  >::value>::type * = VSMC_NULLPTR)
203  {
204  unsigned long s;
205  seq.generate(&s, &s + 1);
206  this->generator().seed(s);
207  }
208 }; // class GSLEngine
209 
213 
217 
221 
225 
229 
233 
237 
241 
245 
249 
253 
258 
262 
263 } // namespace vsmc
264 
265 #endif // VSMC_RNG_GSL_HPP
Definition: adapter.hpp:37
GSLGenerator(const GSLGenerator< RngType > &other)
Definition: gsl.hpp:119
GSLEngine< GSL_RNG_TYPE_RANLXS0 > GSL_RANLXS0
A RANLUX generator with luxury level 0.
Definition: gsl.hpp:216
gsl_rng_cmrg
Definition: gsl.hpp:67
gsl_rng_ranlxs1
Definition: gsl.hpp:61
gsl_rng_ranlxs0
Definition: gsl.hpp:60
GSLEngine< GSL_RNG_TYPE_RANLUX > GSL_RANLUX
A RANLUX generator.
Definition: gsl.hpp:236
uint32_t result_type
Definition: gsl.hpp:185
GSLEngine< GSL_RNG_TYPE_CMRG > GSL_CMRG
A combined multiple recursive generator.
Definition: gsl.hpp:244
void seed(SeedSeq &seq, typename cxx11::enable_if< internal::is_seed_seq< SeedSeq, result_type, GSLEngine< RngType > >::value >::type *=nullptr)
Definition: gsl.hpp:199
GSLEngine< GSL_RNG_TYPE_TAUS > GSL_TAUS
A maximally equidistributed combined Tausworthe generator.
Definition: gsl.hpp:252
gsl_rng_ranlxd1
Definition: gsl.hpp:63
#define VSMC_DEFINE_RNG_GSL_RNG_TYPE_POINTER(Generator, pointer)
Definition: gsl.hpp:39
GSLEngine< GSL_RNG_TYPE_RANLUX389 > GSL_RANLUX389
A RANLUX generator with the highest level of randomness.
Definition: gsl.hpp:240
gsl_rng_ranlux
Definition: gsl.hpp:65
gsl_rng_ranlxs2
Definition: gsl.hpp:62
GSLEngine< GSL_RNG_TYPE_MRG > GSL_MRG
A fifth-order multiple recursive generator.
Definition: gsl.hpp:248
void seed(result_type s)
Definition: gsl.hpp:195
T & get(Array< T, N > &ary)
Array ADL of get.
Definition: array.hpp:322
gsl_rng_gfsr4
Definition: gsl.hpp:71
gsl_rng_mrg
Definition: gsl.hpp:68
unsigned long generate()
Definition: gsl.hpp:157
#define VSMC_MNE
Avoid MSVC stupid behavior: MNE = Macro No Expansion.
Definition: defines.hpp:38
GSLEngine< GSL_RNG_TYPE_RANLXS1 > GSL_RANLXS1
A RANLUX generator with luxury level 0.
Definition: gsl.hpp:220
A thin wrapper over any RNG Generator for use with C++11 API.
GSLEngine(SeedSeq &seq, typename cxx11::enable_if< internal::is_seed_seq< SeedSeq, result_type, GSLEngine< RngType > >::value >::type *=nullptr)
Definition: gsl.hpp:190
GSLRngType
GSL RNG algorithms.
Definition: gsl.hpp:58
GSLEngine< GSL_RNG_TYPE_RANLXS2 > GSL_RANLXS2
A RANLUX generator with luxury level 0.
Definition: gsl.hpp:224
GSLEngine< GSL_RNG_TYPE_MT19937 > GSL_MT19937
A Mersenne-Twister pseudoranom number genertor.
Definition: gsl.hpp:212
#define VSMC_NULLPTR
nullptr
Definition: defines.hpp:79
GSL RNG generator for use with GeneratorWrapper.
Definition: gsl.hpp:112
void swap(Array< T, N > &ary1, Array< T, N > &ary2)
Array ADL of swap.
Definition: array.hpp:317
GSLGenerator(GSLGenerator< RngType > &&other)
Definition: gsl.hpp:131
GSLEngine< GSL_RNG_TYPE_TAUS2 > GSL_TAUS2
A maximally equidistributed combined Tausworthe generator with improved seeding procedure.
Definition: gsl.hpp:257
gsl_rng_ranlxd2
Definition: gsl.hpp:64
GSLEngine< GSL_RNG_TYPE_RANLXD1 > GSL_RANLXD1
A RANLXS generator with luxury level 1.
Definition: gsl.hpp:228
GSLEngine< GSL_RNG_TYPE_GFSR4 > GSL_GFSR4
A a lagged-fibonacci alike generator.
Definition: gsl.hpp:261
GSLEngine< GSL_RNG_TYPE_RANLXD2 > GSL_RANLXD2
A RANLXS generator with luxury level 2.
Definition: gsl.hpp:232
gsl_rng_taus2
Definition: gsl.hpp:70
gsl_rng_taus
Definition: gsl.hpp:69
gsl_rng_mt19937
Definition: gsl.hpp:59
gsl_rng_ranlux389
Definition: gsl.hpp:66
GSLEngine(result_type s=0)
Definition: gsl.hpp:187
void seed(unsigned long s)
Definition: gsl.hpp:151
#define VSMC_DEFINE_RNG_GSL_RNG_MIN_MAX(Generator, Min, Max)
Definition: gsl.hpp:43
GSL RNG Engine.
Definition: gsl.hpp:176