EigenRand  0.5.0
 
Loading...
Searching...
No Matches
RandUtils.h
Go to the documentation of this file.
1
12#ifndef EIGENRAND_RAND_UTILS_H
13#define EIGENRAND_RAND_UTILS_H
14
15#include "MorePacketMath.h"
16#include "PacketFilter.h"
17#include "PacketRandomEngine.h"
18
19namespace Eigen
20{
21 namespace internal
22 {
23 template<typename Packet, typename Rng,
24 typename RngResult = typename std::remove_reference<Rng>::type::result_type,
25 Rand::RandomEngineType reType = Rand::GetRandomEngineType<
26 typename std::remove_reference<Rng>::type
27 >::value>
28 struct RawbitsMaker;
29
30 template<typename PacketType, typename Rng>
31 struct UniformRealUtils;
32
33 template<typename PacketType, typename Rng>
34 struct RandUtils : public UniformRealUtils<PacketType, Rng>
35 {
36 EIGEN_STRONG_INLINE PacketType balanced(Rng& rng)
37 {
38 return psub(pmul(this->zero_to_one(rng), pset1<PacketType>(2)), pset1<PacketType>(1));
39 }
40
41 template<typename Scalar>
42 EIGEN_STRONG_INLINE PacketType balanced(Rng& rng, Scalar slope, Scalar bias)
43 {
44 return padd(pmul(this->zero_to_one(rng), pset1<PacketType>(slope)), pset1<PacketType>(bias));
45 }
46
47 EIGEN_STRONG_INLINE PacketType nonzero_uniform_real(Rng& rng)
48 {
49 constexpr auto epsilon = std::numeric_limits<typename unpacket_traits<PacketType>::type>::epsilon() / 8;
50 return padd(this->uniform_real(rng), pset1<PacketType>(epsilon));
51 }
52 };
53
54 template<typename Gen, typename _Scalar, typename Rng, bool _mutable = false>
55 struct scalar_rng_adaptor
56 {
57 static_assert(
58 Rand::IsScalarFullBitRandomEngine<
59 typename std::remove_reference<Rng>::type
60 >::value ||
61 Rand::IsPacketRandomEngine<
62 typename std::remove_reference<Rng>::type
63 >::value,
64 "Rng must satisfy RandomNumberEngine"
65 );
66
67 Gen gen;
68 Rng rng;
69
70 scalar_rng_adaptor(const Rng& _rng) : rng{ _rng }
71 {
72 }
73
74 template<typename _Gen>
75 scalar_rng_adaptor(const Rng& _rng, _Gen&& _gen) : gen{ _gen }, rng{ _rng }
76 {
77 }
78
79 scalar_rng_adaptor(const scalar_rng_adaptor& o) = default;
80 scalar_rng_adaptor(scalar_rng_adaptor&& o) = default;
81
82 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const _Scalar operator() () const
83 {
84 return gen(rng);
85 }
86
87 template<typename Packet>
88 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp() const
89 {
90 return gen.template packetOp<Packet>(rng);
91 }
92 };
93
94 template<typename Gen, typename _Scalar, typename Rng>
95 struct scalar_rng_adaptor<Gen, _Scalar, Rng, true>
96 {
97 static_assert(
98 Rand::IsScalarFullBitRandomEngine<
99 typename std::remove_reference<Rng>::type
100 >::value ||
101 Rand::IsPacketRandomEngine<
102 typename std::remove_reference<Rng>::type
103 >::value,
104 "Rng must satisfy RandomNumberEngine"
105 );
106
107 mutable Gen gen;
108 Rng rng;
109
110 scalar_rng_adaptor(const Rng& _rng) : rng{ _rng }
111 {
112 }
113
114 template<typename _Gen>
115 scalar_rng_adaptor(const Rng& _rng, _Gen&& _gen) : gen{ _gen }, rng{ _rng }
116 {
117 }
118
119 scalar_rng_adaptor(const scalar_rng_adaptor& o) = default;
120 scalar_rng_adaptor(scalar_rng_adaptor&& o) = default;
121
122 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const _Scalar operator() () const
123 {
124 return gen(rng);
125 }
126
127 template<typename Packet>
128 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp() const
129 {
130 return gen.template packetOp<Packet>(rng);
131 }
132 };
133
134 template<typename Gen, typename _Scalar, typename Urng, bool _mutable>
135 struct functor_traits<scalar_rng_adaptor<Gen, _Scalar, Urng, _mutable> >
136 {
137 enum { Cost = HugeCost, PacketAccess = std::is_floating_point<_Scalar>::value ? packet_traits<_Scalar>::HasExp : packet_traits<_Scalar>::Vectorizable, IsRepeatable = false };
138 };
139
140 template<typename Gen, typename _Scalar, typename _ScalarA, typename Rng, bool _mutable = false>
141 struct scalar_unary_rng_adaptor
142 {
143 static_assert(
144 Rand::IsScalarFullBitRandomEngine<
145 typename std::remove_reference<Rng>::type
146 >::value ||
147 Rand::IsPacketRandomEngine<
148 typename std::remove_reference<Rng>::type
149 >::value,
150 "Rng must satisfy RandomNumberEngine"
151 );
152
153 Gen gen;
154 Rng rng;
155
156 scalar_unary_rng_adaptor(const Rng& _rng) : rng{ _rng }
157 {
158 }
159
160 template<typename _Gen>
161 scalar_unary_rng_adaptor(const Rng& _rng, _Gen&& _gen) : gen{ _gen }, rng{ _rng }
162 {
163 }
164
165 scalar_unary_rng_adaptor(const scalar_unary_rng_adaptor& o) = default;
166 scalar_unary_rng_adaptor(scalar_unary_rng_adaptor&& o) = default;
167
168 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const _Scalar operator() (_ScalarA a) const
169 {
170 return gen(rng, a);
171 }
172
173 template<typename Packet>
174 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
175 {
176 return gen.template packetOp<Packet>(rng, a);
177 }
178 };
179
180 template<typename Gen, typename _Scalar, typename _ScalarA, typename Rng>
181 struct scalar_unary_rng_adaptor<Gen, _Scalar, _ScalarA, Rng, true>
182 {
183 static_assert(
184 Rand::IsScalarFullBitRandomEngine<
185 typename std::remove_reference<Rng>::type
186 >::value ||
187 Rand::IsPacketRandomEngine<
188 typename std::remove_reference<Rng>::type
189 >::value,
190 "Rng must satisfy RandomNumberEngine"
191 );
192
193 mutable Gen gen;
194 Rng rng;
195
196 scalar_unary_rng_adaptor(const Rng& _rng) : rng{ _rng }
197 {
198 }
199
200 template<typename _Gen>
201 scalar_unary_rng_adaptor(const Rng& _rng, _Gen&& _gen) : gen{ _gen }, rng{ _rng }
202 {
203 }
204
205 scalar_unary_rng_adaptor(const scalar_unary_rng_adaptor& o) = default;
206 scalar_unary_rng_adaptor(scalar_unary_rng_adaptor&& o) = default;
207
208 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const _Scalar operator() (_ScalarA a) const
209 {
210 return gen(rng, a);
211 }
212
213 template<typename Packet>
214 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
215 {
216 return gen.template packetOp<Packet>(rng, a);
217 }
218 };
219
220 template<typename Gen, typename _Scalar, typename _ScalarA, typename Urng, bool _mutable>
221 struct functor_traits<scalar_unary_rng_adaptor<Gen, _Scalar, _ScalarA, Urng, _mutable> >
222 {
223 enum { Cost = HugeCost, PacketAccess = std::is_floating_point<_Scalar>::value ? packet_traits<_Scalar>::HasExp : packet_traits<_Scalar>::Vectorizable, IsRepeatable = false };
224 };
225
226 template<typename Gen, typename _Scalar, typename _ScalarA, typename _ScalarB, typename Rng, bool _mutable = false>
227 struct scalar_binary_rng_adaptor
228 {
229 static_assert(
230 Rand::IsScalarFullBitRandomEngine<
231 typename std::remove_reference<Rng>::type
232 >::value ||
233 Rand::IsPacketRandomEngine<
234 typename std::remove_reference<Rng>::type
235 >::value,
236 "Rng must satisfy RandomNumberEngine"
237 );
238
239 Gen gen;
240 Rng rng;
241
242 scalar_binary_rng_adaptor(const Rng& _rng) : rng{ _rng }
243 {
244 }
245
246 template<typename _Gen>
247 scalar_binary_rng_adaptor(const Rng& _rng, _Gen&& _gen) : gen{ _gen }, rng{ _rng }
248 {
249 }
250
251 scalar_binary_rng_adaptor(const scalar_binary_rng_adaptor& o) = default;
252 scalar_binary_rng_adaptor(scalar_binary_rng_adaptor&& o) = default;
253
254 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const _Scalar operator() (_ScalarA a, _ScalarB b) const
255 {
256 return gen(rng, a, b);
257 }
258
259 template<typename Packet>
260 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
261 {
262 return gen.template packetOp<Packet>(rng, a, b);
263 }
264 };
265
266 template<typename Gen, typename _Scalar, typename _ScalarA, typename _ScalarB, typename Rng>
267 struct scalar_binary_rng_adaptor<Gen, _Scalar, _ScalarA, _ScalarB, Rng, true>
268 {
269 static_assert(
270 Rand::IsScalarFullBitRandomEngine<
271 typename std::remove_reference<Rng>::type
272 >::value ||
273 Rand::IsPacketRandomEngine<
274 typename std::remove_reference<Rng>::type
275 >::value,
276 "Rng must satisfy RandomNumberEngine"
277 );
278
279 mutable Gen gen;
280 Rng rng;
281
282 scalar_binary_rng_adaptor(const Rng& _rng) : rng{ _rng }
283 {
284 }
285
286 template<typename _Gen>
287 scalar_binary_rng_adaptor(const Rng& _rng, _Gen&& _gen) : gen{ _gen }, rng{ _rng }
288 {
289 }
290
291 scalar_binary_rng_adaptor(const scalar_binary_rng_adaptor& o) = default;
292 scalar_binary_rng_adaptor(scalar_binary_rng_adaptor&& o) = default;
293
294 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const _Scalar operator() (_ScalarA a, _ScalarB b) const
295 {
296 return gen(rng, a, b);
297 }
298
299 template<typename PacketA, typename PacketB>
300 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const PacketA packetOp(const PacketA& a, const PacketB& b) const
301 {
302 return gen.packetOp(rng, a, b);
303 }
304 };
305
306 template<typename Gen, typename _Scalar, typename _ScalarA, typename _ScalarB, typename Urng, bool _mutable>
307 struct functor_traits<scalar_binary_rng_adaptor<Gen, _Scalar, _ScalarA, _ScalarB, Urng, _mutable> >
308 {
309 enum { Cost = HugeCost, PacketAccess = std::is_floating_point<_Scalar>::value ? packet_traits<_Scalar>::HasExp : packet_traits<_Scalar>::Vectorizable, IsRepeatable = false };
310 };
311 }
312}
313
314
315#ifdef EIGEN_VECTORIZE_AVX
316#include "arch/AVX/RandUtils.h"
317#endif
318
319#ifdef EIGEN_VECTORIZE_SSE2
320#include "arch/SSE/RandUtils.h"
321#endif
322
323#ifdef EIGEN_VECTORIZE_NEON
324#include "arch/NEON/RandUtils.h"
325#endif
326
327
328namespace Eigen
329{
330 namespace internal
331 {
332 EIGEN_STRONG_INLINE uint32_t collect_upper8bits(uint32_t a, uint32_t b, uint32_t c)
333 {
334 return ((a & 0xFF000000) >> 24) | ((b & 0xFF000000) >> 16) | ((c & 0xFF000000) >> 8);
335 }
336 }
337}
338
339#if defined(DEBUG) || defined(_DEBUG)
340 #define EIGENRAND_CHECK_INFINITY_LOOP() do { assert(_i < 100); } while(0)
341#else
342 #define EIGENRAND_CHECK_INFINITY_LOOP()
343#endif
344
345#endif
const BalancedType< Derived, Urng > balanced(Index rows, Index cols, Urng &&urng)
generates reals in a range [-1, 1]
Definition: Basic.h:767