EigenRand  0.4.0-alpha
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 
19 namespace 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::IsScalarRandomEngine<
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::IsScalarRandomEngine<
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 = packet_traits<_Scalar>::Vectorizable, IsRepeatable = false };
138  };
139  }
140 }
141 
142 
143 #ifdef EIGEN_VECTORIZE_AVX
144 #include "arch/AVX/RandUtils.h"
145 #endif
146 
147 #ifdef EIGEN_VECTORIZE_SSE2
148 #include "arch/SSE/RandUtils.h"
149 #endif
150 
151 #ifdef EIGEN_VECTORIZE_NEON
152 #include "arch/NEON/RandUtils.h"
153 #endif
154 
155 
156 namespace Eigen
157 {
158  namespace internal
159  {
160  EIGEN_STRONG_INLINE uint32_t collect_upper8bits(uint32_t a, uint32_t b, uint32_t c)
161  {
162  return ((a & 0xFF000000) >> 24) | ((b & 0xFF000000) >> 16) | ((c & 0xFF000000) >> 8);
163  }
164  }
165 }
166 
167 #if defined(DEBUG) || defined(_DEBUG)
168  #define EIGENRAND_CHECK_INFINITY_LOOP() do { assert(_i < 100); } while(0)
169 #else
170  #define EIGENRAND_CHECK_INFINITY_LOOP()
171 #endif
172 
173 #endif
const BalancedType< Derived, Urng > balanced(Index rows, Index cols, Urng &&urng)
generates reals in a range [-1, 1]
Definition: Basic.h:550