vSMC
vSMC: Scalable Monte Carlo
uniform_real_distribution.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/rng/uniform_real_distribution.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_UNIFORM_REAL_DISTRIBUTION_HPP
33 #define VSMC_RNG_UNIFORM_REAL_DISTRIBUTION_HPP
34 
36 #include <vsmc/rng/u01.hpp>
37 
38 #define VSMC_RUNTIME_ASSERT_RNG_UNIFORM_REAL_DISTRIBUTION_PARAM_CHECK(a, b) \
39  VSMC_RUNTIME_ASSERT((a <= b), \
40  ("**UniformRealDistribution** CONSTRUCTED WITH INVALID " \
41  "MINIMUM AND MAXIMUM PARAMTER VALUES"))
42 
43 #define VSMC_RUNTIME_ASSERT_RNG_UNIFORM_REAL_DISTRIBUTION_ENG_MIN(eng_min) \
44  VSMC_RUNTIME_ASSERT((eng_min == 0), \
45  ("**UniformRealDistribution::operator()** " \
46  "ENGINE MEMBER FUNCTION min() RETURN A VALUE OTHER THAN ZERO"))
47 
48 #define VSMC_RUNTIME_ASSERT_RNG_UNIFORM_REAL_DISTRIBUTION_ENG_MAX(eng_max) \
49  VSMC_RUNTIME_ASSERT((eng_max == uint32_t_max_ || eng_max == uint64_t_max_),\
50  ("**UniformRealDistribution::operator()** " \
51  "ENGINE MEMBER FUNCTION max() RETURN A VALUE OTHER THAN " \
52  "THE MAXIMUM OF uint32_t OR uint64_t"))
53 
54 namespace vsmc {
55 
56 namespace internal {
57 
58 template <uint64_t, uint64_t>
60 
61 template <>
63  static_cast<uint64_t>(static_cast<uint32_t>(~(static_cast<uint32_t>(0))))>
64 {typedef uint32_t type;};
65 
66 template <>
68  static_cast<uint64_t>(~(static_cast<uint64_t>(0)))>
69 {typedef uint64_t type;};
70 
71 template <typename FPType, typename Left, typename Right, typename Eng, bool>
73 {
74  static VSMC_CONSTEXPR const uint64_t uint32_t_max_ = static_cast<uint64_t>(
75  static_cast<uint32_t>(~(static_cast<uint32_t>(0))));
76 
77  static VSMC_CONSTEXPR const uint64_t uint64_t_max_ = static_cast<uint64_t>(
78  ~(static_cast<uint64_t>(0)));
79 
80  public :
81 
82  static FPType uint2fp (Eng &eng)
83  {
84  static const uint64_t eng_max = static_cast<uint64_t>(
85  eng.max VSMC_MNE ());
86 
88  (eng.min VSMC_MNE ()));
90 
91  if (eng_max == uint32_t_max_)
93  static_cast<uint32_t>(eng()));
94 
95  if (eng_max == uint64_t_max_)
97  static_cast<uint64_t>(eng()));
98 
99  return 0;
100  }
101 }; // class UniformRealDistributionOp
102 
103 #if VSMC_HAS_CXX11_CONSTEXPR
104 template <typename FPType, typename Left, typename Right, typename Eng>
105 class UniformRealDistributionOp<FPType, Left, Right, Eng, true>
106 {
108  Eng::min VSMC_MNE(), Eng::max VSMC_MNE ()>::type eng_uint_t;
109 
110  public :
111 
112  static FPType uint2fp (Eng &eng)
113  {
115  static_cast<eng_uint_t>(eng()));
116  }
117 }; // class UniformRealDistributionOp
118 #endif
119 
120 } // namespace vsmc::interal
121 
170 template <typename FPType = double,
171  typename Left = Closed, typename Right = Open,
172  bool MinMaxIsConstexpr = false>
174 {
175  public :
176 
177  typedef FPType result_type;
178 
179  struct param_type
180  {
181  typedef FPType result_type;
182 
185 
186  explicit param_type (result_type a = 0, result_type b = 1) :
187  a_(a), b_(b) {}
188 
189  result_type a () const {return a_;}
190  result_type b () const {return b_;}
191 
192  friend inline bool operator== (
193  const param_type &param1, const param_type &param2)
194  {
195  if (param1.a_ < param2.a_ || param1.a_ > param2.a_)
196  return false;
197  if (param1.b_ < param2.b_ || param1.b_ > param2.b_)
198  return false;
199  return true;
200  }
201 
202  friend inline bool operator!= (
203  const param_type param1, const param_type param2)
204  {return !(param1 == param2);}
205 
206  template <typename CharT, typename Traits>
207  friend inline std::basic_ostream<CharT, Traits> &operator<< (
208  std::basic_ostream<CharT, Traits> &os, const param_type &param)
209  {
210  if (!os.good())
211  return os;
212 
213  os << param.a_ << ' ' << param.b_;
214 
215  return os;
216  }
217 
218  template <typename CharT, typename Traits>
219  friend inline std::basic_istream<CharT, Traits> &operator>> (
220  std::basic_istream<CharT, Traits> &is, param_type &param)
221  {
222  if (!is.good())
223  return is;
224 
225  result_type a = 1;
226  result_type b = 0;
227  is >> std::ws >> a;
228  is >> std::ws >> b;
229 
230  if (is.good()) {
231  if (a <= b) {
232  param.a_ = a;
233  param.b_ = b;
234  } else {
235  is.setstate(std::ios_base::failbit);
236  }
237  }
238 
239  return is;
240  }
241 
242  private :
243 
244  result_type a_;
245  result_type b_;
246  }; // class param_type
247 
248  explicit UniformRealDistribution (result_type a = 0, result_type b = 1) :
249  a_(a), b_(b)
251 
253  a_(param.a()), b_(param.b())
255 
256  param_type param () const {return param_type(a_, b_);}
257 
258  void param (const param_type &param)
259  {
260  a_ = param.a();
261  b_ = param.b();
262  }
263 
264  void reset () const {}
265 
266  result_type a () const {return a_;}
267  result_type b () const {return b_;}
268  result_type min VSMC_MNE () const {return a_;}
269  result_type max VSMC_MNE () const {return b_;}
270 
280  template <typename Eng>
281  result_type operator() (Eng &eng) const
282  {
284  FPType, Left, Right, Eng, MinMaxIsConstexpr
285  >::uint2fp(eng) * (b_ - a_) + a_;
286  }
287 
288  friend inline bool operator== (
290  FPType, Left, Right, MinMaxIsConstexpr> &runif1,
292  FPType, Left, Right, MinMaxIsConstexpr> &runif2)
293  {
294  if (runif1.a_ < runif2.a_ || runif1.a_ > runif1.a_)
295  return false;
296  if (runif1.b_ < runif2.b_ || runif1.b_ > runif1.b_)
297  return false;
298  return true;
299  }
300 
301  friend inline bool operator!= (
303  FPType, Left, Right, MinMaxIsConstexpr> &runif1,
305  FPType, Left, Right, MinMaxIsConstexpr> &runif2)
306  {return !(runif1 == runif2);}
307 
308  template <typename CharT, typename Traits>
309  friend inline std::basic_ostream<CharT, Traits> &operator<< (
310  std::basic_ostream<CharT, Traits> &os,
312  FPType, Left, Right, MinMaxIsConstexpr> &runif)
313  {
314  if (!os.good())
315  return os;
316 
317  os << runif.a_ << ' ' << runif.b_;
318 
319  return os;
320  }
321 
322  template <typename CharT, typename Traits>
323  friend inline std::basic_istream<CharT, Traits> &operator>> (
324  std::basic_istream<CharT, Traits> &is,
326  FPType, Left, Right, MinMaxIsConstexpr> &runif)
327  {
328  if (!is.good())
329  return is;
330 
331  result_type a = 1;
332  result_type b = 0;
333  is >> std::ws >> a;
334  is >> std::ws >> b;
335  if (is.good()) {
336  if (a <= b) {
337  runif.a_ = a;
338  runif.b_ = b;
339  } else {
340  is.setstate(std::ios_base::failbit);
341  }
342  }
343 
344  return is;
345  }
346 
347  private :
348 
349  result_type a_;
350  result_type b_;
351 }; // class UniformRealDistribution
352 
353 } // namespace vsmc
354 
355 #endif // VSMC_RNG_UNIFORM_REAL_DISTRIBUTION_HPP
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, param_type &param)
Definition: adapter.hpp:37
#define VSMC_CONSTEXPR
constexpr
Definition: defines.hpp:55
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const param_type &param)
friend bool operator!=(const UniformRealDistribution< FPType, Left, Right, MinMaxIsConstexpr > &runif1, const UniformRealDistribution< FPType, Left, Right, MinMaxIsConstexpr > &runif2)
Uniform real distribution with variants open/closed variants.
#define VSMC_RUNTIME_ASSERT_RNG_UNIFORM_REAL_DISTRIBUTION_PARAM_CHECK(a, b)
UniformRealDistribution(result_type a=0, result_type b=1)
friend bool operator==(const param_type &param1, const param_type &param2)
#define VSMC_RUNTIME_ASSERT_RNG_UNIFORM_REAL_DISTRIBUTION_ENG_MAX(eng_max)
UniformRealDistribution< FPType, Left, Right, MinMaxIsConstexpr > distribution_type
#define VSMC_MNE
Avoid MSVC stupid behavior: MNE = Macro No Expansion.
Definition: defines.hpp:38
friend bool operator!=(const param_type param1, const param_type param2)
friend bool operator==(const UniformRealDistribution< FPType, Left, Right, MinMaxIsConstexpr > &runif1, const UniformRealDistribution< FPType, Left, Right, MinMaxIsConstexpr > &runif2)
UniformRealDistribution(const param_type &param)
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, UniformRealDistribution< FPType, Left, Right, MinMaxIsConstexpr > &runif)
result_type operator()(Eng &eng) const
Generate uniform random variates.
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const UniformRealDistribution< FPType, Left, Right, MinMaxIsConstexpr > &runif)
void param(const param_type &param)
#define VSMC_RUNTIME_ASSERT_RNG_UNIFORM_REAL_DISTRIBUTION_ENG_MIN(eng_min)