12#ifndef EIGENRAND_RAND_UTILS_H
13#define EIGENRAND_RAND_UTILS_H
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
30 template<
typename PacketType,
typename Rng>
31 struct UniformRealUtils;
33 template<
typename PacketType,
typename Rng>
34 struct RandUtils :
public UniformRealUtils<PacketType, Rng>
36 EIGEN_STRONG_INLINE PacketType
balanced(Rng& rng)
38 return psub(pmul(this->zero_to_one(rng), pset1<PacketType>(2)), pset1<PacketType>(1));
41 template<
typename Scalar>
42 EIGEN_STRONG_INLINE PacketType
balanced(Rng& rng, Scalar slope, Scalar bias)
44 return padd(pmul(this->zero_to_one(rng), pset1<PacketType>(slope)), pset1<PacketType>(bias));
47 EIGEN_STRONG_INLINE PacketType nonzero_uniform_real(Rng& rng)
49 constexpr auto epsilon = std::numeric_limits<typename unpacket_traits<PacketType>::type>::epsilon() / 8;
50 return padd(this->uniform_real(rng), pset1<PacketType>(epsilon));
54 template<
typename Gen,
typename _Scalar,
typename Rng,
bool _mutable = false>
55 struct scalar_rng_adaptor
58 Rand::IsScalarFullBitRandomEngine<
59 typename std::remove_reference<Rng>::type
61 Rand::IsPacketRandomEngine<
62 typename std::remove_reference<Rng>::type
64 "Rng must satisfy RandomNumberEngine"
70 scalar_rng_adaptor(
const Rng& _rng) : rng{ _rng }
74 template<
typename _Gen>
75 scalar_rng_adaptor(
const Rng& _rng, _Gen&& _gen) : gen{ _gen }, rng{ _rng }
79 scalar_rng_adaptor(
const scalar_rng_adaptor& o) =
default;
80 scalar_rng_adaptor(scalar_rng_adaptor&& o) =
default;
82 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const _Scalar operator() ()
const
87 template<
typename Packet>
88 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp()
const
90 return gen.template packetOp<Packet>(rng);
94 template<
typename Gen,
typename _Scalar,
typename Rng>
95 struct scalar_rng_adaptor<Gen, _Scalar, Rng, true>
98 Rand::IsScalarFullBitRandomEngine<
99 typename std::remove_reference<Rng>::type
101 Rand::IsPacketRandomEngine<
102 typename std::remove_reference<Rng>::type
104 "Rng must satisfy RandomNumberEngine"
110 scalar_rng_adaptor(
const Rng& _rng) : rng{ _rng }
114 template<
typename _Gen>
115 scalar_rng_adaptor(
const Rng& _rng, _Gen&& _gen) : gen{ _gen }, rng{ _rng }
119 scalar_rng_adaptor(
const scalar_rng_adaptor& o) =
default;
120 scalar_rng_adaptor(scalar_rng_adaptor&& o) =
default;
122 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const _Scalar operator() ()
const
127 template<
typename Packet>
128 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp()
const
130 return gen.template packetOp<Packet>(rng);
134 template<
typename Gen,
typename _Scalar,
typename Urng,
bool _mutable>
135 struct functor_traits<scalar_rng_adaptor<Gen, _Scalar, Urng, _mutable> >
137 enum { Cost = HugeCost, PacketAccess = std::is_floating_point<_Scalar>::value ? packet_traits<_Scalar>::HasExp : packet_traits<_Scalar>::Vectorizable, IsRepeatable =
false };
140 template<
typename Gen,
typename _Scalar,
typename _ScalarA,
typename Rng,
bool _mutable = false>
141 struct scalar_unary_rng_adaptor
144 Rand::IsScalarFullBitRandomEngine<
145 typename std::remove_reference<Rng>::type
147 Rand::IsPacketRandomEngine<
148 typename std::remove_reference<Rng>::type
150 "Rng must satisfy RandomNumberEngine"
156 scalar_unary_rng_adaptor(
const Rng& _rng) : rng{ _rng }
160 template<
typename _Gen>
161 scalar_unary_rng_adaptor(
const Rng& _rng, _Gen&& _gen) : gen{ _gen }, rng{ _rng }
165 scalar_unary_rng_adaptor(
const scalar_unary_rng_adaptor& o) =
default;
166 scalar_unary_rng_adaptor(scalar_unary_rng_adaptor&& o) =
default;
168 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const _Scalar operator() (_ScalarA a)
const
173 template<
typename Packet>
174 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a)
const
176 return gen.template packetOp<Packet>(rng, a);
180 template<
typename Gen,
typename _Scalar,
typename _ScalarA,
typename Rng>
181 struct scalar_unary_rng_adaptor<Gen, _Scalar, _ScalarA, Rng, true>
184 Rand::IsScalarFullBitRandomEngine<
185 typename std::remove_reference<Rng>::type
187 Rand::IsPacketRandomEngine<
188 typename std::remove_reference<Rng>::type
190 "Rng must satisfy RandomNumberEngine"
196 scalar_unary_rng_adaptor(
const Rng& _rng) : rng{ _rng }
200 template<
typename _Gen>
201 scalar_unary_rng_adaptor(
const Rng& _rng, _Gen&& _gen) : gen{ _gen }, rng{ _rng }
205 scalar_unary_rng_adaptor(
const scalar_unary_rng_adaptor& o) =
default;
206 scalar_unary_rng_adaptor(scalar_unary_rng_adaptor&& o) =
default;
208 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const _Scalar operator() (_ScalarA a)
const
213 template<
typename Packet>
214 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a)
const
216 return gen.template packetOp<Packet>(rng, a);
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> >
223 enum { Cost = HugeCost, PacketAccess = std::is_floating_point<_Scalar>::value ? packet_traits<_Scalar>::HasExp : packet_traits<_Scalar>::Vectorizable, IsRepeatable =
false };
226 template<
typename Gen,
typename _Scalar,
typename _ScalarA,
typename _ScalarB,
typename Rng,
bool _mutable = false>
227 struct scalar_binary_rng_adaptor
230 Rand::IsScalarFullBitRandomEngine<
231 typename std::remove_reference<Rng>::type
233 Rand::IsPacketRandomEngine<
234 typename std::remove_reference<Rng>::type
236 "Rng must satisfy RandomNumberEngine"
242 scalar_binary_rng_adaptor(
const Rng& _rng) : rng{ _rng }
246 template<
typename _Gen>
247 scalar_binary_rng_adaptor(
const Rng& _rng, _Gen&& _gen) : gen{ _gen }, rng{ _rng }
251 scalar_binary_rng_adaptor(
const scalar_binary_rng_adaptor& o) =
default;
252 scalar_binary_rng_adaptor(scalar_binary_rng_adaptor&& o) =
default;
254 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const _Scalar operator() (_ScalarA a, _ScalarB b)
const
256 return gen(rng, a, b);
259 template<
typename Packet>
260 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const
262 return gen.template packetOp<Packet>(rng, a, b);
266 template<
typename Gen,
typename _Scalar,
typename _ScalarA,
typename _ScalarB,
typename Rng>
267 struct scalar_binary_rng_adaptor<Gen, _Scalar, _ScalarA, _ScalarB, Rng, true>
270 Rand::IsScalarFullBitRandomEngine<
271 typename std::remove_reference<Rng>::type
273 Rand::IsPacketRandomEngine<
274 typename std::remove_reference<Rng>::type
276 "Rng must satisfy RandomNumberEngine"
282 scalar_binary_rng_adaptor(
const Rng& _rng) : rng{ _rng }
286 template<
typename _Gen>
287 scalar_binary_rng_adaptor(
const Rng& _rng, _Gen&& _gen) : gen{ _gen }, rng{ _rng }
291 scalar_binary_rng_adaptor(
const scalar_binary_rng_adaptor& o) =
default;
292 scalar_binary_rng_adaptor(scalar_binary_rng_adaptor&& o) =
default;
294 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const _Scalar operator() (_ScalarA a, _ScalarB b)
const
296 return gen(rng, a, b);
299 template<
typename PacketA,
typename PacketB>
300 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const PacketA packetOp(
const PacketA& a,
const PacketB& b)
const
302 return gen.packetOp(rng, a, b);
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> >
309 enum { Cost = HugeCost, PacketAccess = std::is_floating_point<_Scalar>::value ? packet_traits<_Scalar>::HasExp : packet_traits<_Scalar>::Vectorizable, IsRepeatable =
false };
315#ifdef EIGEN_VECTORIZE_AVX
319#ifdef EIGEN_VECTORIZE_SSE2
323#ifdef EIGEN_VECTORIZE_NEON
332 EIGEN_STRONG_INLINE uint32_t collect_upper8bits(uint32_t a, uint32_t b, uint32_t c)
334 return ((a & 0xFF000000) >> 24) | ((b & 0xFF000000) >> 16) | ((c & 0xFF000000) >> 8);
339#if defined(DEBUG) || defined(_DEBUG)
340 #define EIGENRAND_CHECK_INFINITY_LOOP() do { assert(_i < 100); } while(0)
342 #define EIGENRAND_CHECK_INFINITY_LOOP()
const BalancedType< Derived, Urng > balanced(Index rows, Index cols, Urng &&urng)
generates reals in a range [-1, 1]
Definition: Basic.h:767