MCKL
Monte Carlo Kernel Library
u01_generic.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/random/internal/u01_generic.hpp
3 //----------------------------------------------------------------------------
4 // MCKL: Monte Carlo Kernel Library
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2018, 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 MCKL_RANDOM_INTERNAL_U01_GENERIC_HPP
33 #define MCKL_RANDOM_INTERNAL_U01_GENERIC_HPP
34 
36 
37 namespace mckl {
38 
39 namespace internal {
40 
41 template <int W, typename UIntType>
42 using U01UIntLeastType = std::conditional_t<W <= 32, std::uint32_t,
43  std::conditional_t<W <= 64, std::uint64_t, UIntType>>;
44 
45 template <typename UIntType, typename, typename, typename>
47 
48 template <typename UIntType, typename RealType>
49 class U01GenericImpl<UIntType, RealType, Closed, Closed>
50 {
51  public:
52  static RealType eval(UIntType u)
53  {
54  constexpr int W = std::numeric_limits<UIntType>::digits;
55  constexpr int M = std::numeric_limits<RealType>::digits;
56  constexpr int P = W - 1 < M ? W - 1 : M;
57  constexpr int V = P + 1;
58  constexpr int L = V < W ? 1 : 0;
59  constexpr int R = V < W ? W - 1 - V : 0;
60 
61  using UIntLeastType = U01UIntLeastType<W - R, UIntType>;
62 
63  return trans(static_cast<UIntLeastType>((u << L) >> (R + L)),
64  std::integral_constant<bool, (V < W)>()) *
65  Pow2<RealType, -(P + 1)>::value;
66  }
67 
68  static void eval(std::size_t n, const UIntType *u, RealType *r)
69  {
70  for (std::size_t i = 0; i != n; ++i) {
71  r[i] = eval(u[i]);
72  }
73  }
74 
75  private:
76  template <typename UIntLeastType>
77  static RealType trans(UIntLeastType u, std::true_type)
78  {
79  return static_cast<RealType>((u & 1) + u);
80  }
81 
82  template <typename UIntLeastType>
83  static RealType trans(UIntLeastType u, std::false_type)
84  {
85  return static_cast<RealType>(u & 1) + static_cast<RealType>(u);
86  }
87 }; // class U01GenericImpl
88 
89 template <typename UIntType, typename RealType>
90 class U01GenericImpl<UIntType, RealType, Closed, Open>
91 {
92  public:
93  static RealType eval(UIntType u)
94  {
95  constexpr int W = std::numeric_limits<UIntType>::digits;
96  constexpr int M = std::numeric_limits<RealType>::digits;
97  constexpr int P = W < M ? W : M;
98  constexpr int R = W - P;
99 
100  using UIntLeastType = U01UIntLeastType<W - R, UIntType>;
101 
102  return static_cast<RealType>(static_cast<UIntLeastType>(u >> R)) *
103  Pow2<RealType, -P>::value;
104  }
105 
106  static void eval(std::size_t n, const UIntType *u, RealType *r)
107  {
108  for (std::size_t i = 0; i != n; ++i) {
109  r[i] = eval(u[i]);
110  }
111  }
112 }; // class U01GenericImpl
113 
114 template <typename UIntType, typename RealType>
115 class U01GenericImpl<UIntType, RealType, Open, Closed>
116 {
117  public:
118  static RealType eval(UIntType u)
119  {
120  constexpr int W = std::numeric_limits<UIntType>::digits;
121  constexpr int M = std::numeric_limits<RealType>::digits;
122  constexpr int P = W < M ? W : M;
123  constexpr int R = W - P;
124 
125  using UIntLeastType = U01UIntLeastType<W - R, UIntType>;
126 
127  return static_cast<RealType>(static_cast<UIntLeastType>(u >> R)) *
128  Pow2<RealType, -P>::value +
129  Pow2<RealType, -P>::value;
130  }
131 
132  static void eval(std::size_t n, const UIntType *u, RealType *r)
133  {
134  for (std::size_t i = 0; i != n; ++i) {
135  r[i] = eval(u[i]);
136  }
137  }
138 }; // class U01GenericImpl
139 
140 template <typename UIntType, typename RealType>
141 class U01GenericImpl<UIntType, RealType, Open, Open>
142 {
143  public:
144  static RealType eval(UIntType u)
145  {
146  constexpr int W = std::numeric_limits<UIntType>::digits;
147  constexpr int M = std::numeric_limits<RealType>::digits;
148  constexpr int P = W + 1 < M ? W + 1 : M;
149  constexpr int R = W + 1 - P;
150 
151  using UIntLeastType = U01UIntLeastType<W - R, UIntType>;
152 
153  return static_cast<RealType>(static_cast<UIntLeastType>(u >> R)) *
154  Pow2<RealType, -(P - 1)>::value +
156  }
157 
158  static void eval(std::size_t n, const UIntType *u, RealType *r)
159  {
160  for (std::size_t i = 0; i != n; ++i) {
161  r[i] = eval(u[i]);
162  }
163  }
164 }; // class U01GenericImpl
165 
166 template <typename UIntType, typename RealType, int Q>
168 {
169  public:
170  static RealType eval(const UIntType *u)
171  {
172  return eval<0>(u, std::true_type());
173  }
174 
175  static void eval(std::size_t n, const UIntType *u, RealType *r)
176  {
177  for (std::size_t i = 0; i != n; ++i, u += Q) {
178  r[i] = eval(u);
179  }
180  }
181 
182  private:
183  template <std::size_t>
184  static RealType eval(const UIntType *, std::false_type)
185  {
186  return 0;
187  }
188 
189  template <std::size_t N>
190  static RealType eval(const UIntType *u, std::true_type)
191  {
192  constexpr int W = std::numeric_limits<UIntType>::digits;
193 
194  return static_cast<RealType>(u[N]) *
195  Pow2<RealType, -static_cast<int>((Q - N) * W)>::value +
196  eval<N + 1>(u, std::integral_constant<bool, N + 1 < Q>());
197  }
198 }; // class U01CanonicalGenericImpl
199 
200 } // namespace internal
201 
202 } // namespace mckl
203 
204 #endif // MCKL_RANDOM_INTERNAL_U01_GENERIC_HPP
uint uint32_t
Definition: opencl.h:41
static RealType eval(const UIntType *u)
static void eval(std::size_t n, const UIntType *u, RealType *r)
std::conditional_t< W<=32, std::uint32_t, std::conditional_t< W<=64, std::uint64_t, UIntType > > U01UIntLeastType
Definition: u01_generic.hpp:43
static void eval(std::size_t n, const UIntType *u, RealType *r)
Definition: mcmc.hpp:40
static void eval(std::size_t n, const UIntType *u, RealType *r)
Pow2Impl< RealType, P > Pow2
Definition: const_math.hpp:171
static void eval(std::size_t n, const UIntType *u, RealType *r)
static void eval(std::size_t n, const UIntType *u, RealType *r)
Definition: u01_generic.hpp:68