12 #ifndef EIGENRAND_DISTS_BASIC_H
13 #define EIGENRAND_DISTS_BASIC_H
21 static constexpr
double pi = 3.1415926535897932;
22 static constexpr
double e = 2.7182818284590452;
31 template<
typename DerivedGen,
typename Scalar>
46 template<
typename Derived,
typename Urng>
47 inline const CwiseNullaryOp<internal::scalar_rng_adaptor<DerivedGen&, Scalar, Urng>,
const Derived>
51 rows, cols, { std::forward<Urng>(urng),
static_cast<DerivedGen&
>(*this) }
65 template<
typename Derived,
typename Urng>
66 inline const CwiseNullaryOp<internal::scalar_rng_adaptor<DerivedGen&, Scalar, Urng>,
const Derived>
70 o.rows(), o.cols(), { std::forward<Urng>(urng),
static_cast<DerivedGen&
>(*this) }
82 template<
typename DerivedGen,
typename _Scalar, Index Dim>
89 Index
dims()
const {
return static_cast<DerivedGen&
>(*this).dims(); }
100 template<
typename Urng>
101 inline Matrix<_Scalar, Dim, -1>
generate(Urng&& urng, Index samples)
103 return static_cast<DerivedGen&
>(*this).generatr(std::forward<Urng>(urng), samples);
113 template<
typename Urng>
114 inline Matrix<_Scalar, Dim, 1>
generate(Urng&& urng)
116 return static_cast<DerivedGen&
>(*this).generatr(std::forward<Urng>(urng));
127 template<
typename DerivedGen,
typename _Scalar, Index Dim>
134 Index
dims()
const {
return static_cast<DerivedGen&
>(*this).dims(); }
145 template<
typename Urng>
146 inline Matrix<_Scalar, Dim, -1>
generate(Urng&& urng, Index samples)
148 return static_cast<DerivedGen&
>(*this).generate(std::forward<Urng>(urng), samples);
158 template<
typename Urng>
159 inline Matrix<_Scalar, Dim, Dim>
generate(Urng&& urng)
161 return static_cast<DerivedGen&
>(*this).generate(std::forward<Urng>(urng));
165 template<Index _alignment=0>
169 enum { max_size =
sizeof(internal::find_best_packet<float, -1>::type) };
170 int8_t raw_data[max_size + _alignment - 1] = { 0, };
176 aligned_ptr = (
void*)((((
size_t)raw_data + _alignment - 1) / _alignment) * _alignment);
179 CacheStore(
const CacheStore& c)
181 std::copy(c.raw_data, c.raw_data + max_size, raw_data);
182 aligned_ptr = (
void*)((((
size_t)raw_data + _alignment - 1) / _alignment) * _alignment);
185 CacheStore(CacheStore&& c)
187 std::copy(c.raw_data, c.raw_data + max_size, raw_data);
188 aligned_ptr = (
void*)((((
size_t)raw_data + _alignment - 1) / _alignment) * _alignment);
191 template<
typename Ty>
194 return *(Ty*)aligned_ptr;
197 template<
typename Ty>
198 const Ty& get()
const
200 return *(
const Ty*)aligned_ptr;
208 enum { max_size =
sizeof(internal::find_best_packet<float, -1>::type) };
209 int8_t raw_data[max_size] = { 0, };
216 CacheStore(
const CacheStore& c)
218 std::copy(c.raw_data, c.raw_data + max_size, raw_data);
221 CacheStore(CacheStore&& c)
223 std::copy(c.raw_data, c.raw_data + max_size, raw_data);
226 template<
typename Ty>
229 return *(Ty*)raw_data;
232 template<
typename Ty>
233 const Ty& get()
const
235 return *(
const Ty*)raw_data;
239 using OptCacheStore = CacheStore<EIGEN_MAX_ALIGN_BYTES>;
241 template<
typename _Scalar>
242 struct ExtractFirstUint;
245 struct ExtractFirstUint<float>
247 template<
typename Packet>
248 auto operator()(Packet v) -> decltype(Eigen::internal::pfirst(v))
250 return Eigen::internal::pfirst(v);
255 struct ExtractFirstUint<double>
257 template<
typename Packet>
258 auto operator()(Packet v) -> uint64_t
260 uint64_t arr[
sizeof(Packet) / 8];
261 Eigen::internal::pstoreu((Packet*)arr, v);
271 template<
typename _Scalar>
274 static_assert(std::is_integral<_Scalar>::value,
"randBits needs integral types.");
277 using Scalar = _Scalar;
279 template<
typename Rng>
280 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
282 using namespace Eigen::internal;
283 return pfirst(std::forward<Rng>(rng)());
286 template<
typename Packet,
typename Rng>
287 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
289 using namespace Eigen::internal;
290 using RUtils = RawbitsMaker<Packet, Rng>;
291 return RUtils{}.rawbits(std::forward<Rng>(rng));
300 template<
typename _Scalar>
303 static_assert(std::is_floating_point<_Scalar>::value,
"balanced needs floating point types.");
306 using Scalar = _Scalar;
308 template<
typename Rng>
309 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
311 using namespace Eigen::internal;
312 return ((_Scalar)((int32_t)pfirst(std::forward<Rng>(rng)()) & 0x7FFFFFFF) / 0x7FFFFFFF) * 2 - 1;
315 template<
typename Packet,
typename Rng>
316 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
318 using namespace Eigen::internal;
319 using RUtils = RandUtils<Packet, Rng>;
320 return RUtils{}.balanced(std::forward<Rng>(rng));
329 template<
typename _Scalar>
332 static_assert(std::is_floating_point<_Scalar>::value,
"balanced needs floating point types.");
333 _Scalar slope = 2, bias = -1;
335 using Scalar = _Scalar;
343 : slope{ _b - _a }, bias{ _a }
347 template<
typename Rng>
348 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
350 using namespace Eigen::internal;
351 return ((_Scalar)((int32_t)pfirst(std::forward<Rng>(rng)()) & 0x7FFFFFFF) / 0x7FFFFFFF) * slope + bias;
354 template<
typename Packet,
typename Rng>
355 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
357 using namespace Eigen::internal;
358 using RUtils = RandUtils<Packet, Rng>;
359 return RUtils{}.balanced(std::forward<Rng>(rng), slope, bias);
368 template<
typename _Scalar>
371 static_assert(std::is_floating_point<_Scalar>::value,
"uniformReal needs floating point types.");
374 using Scalar = _Scalar;
376 template<
typename Rng>
377 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
379 using namespace Eigen::internal;
380 return BitScalar<_Scalar>{}.to_ur(ExtractFirstUint<_Scalar>{}(std::forward<Rng>(rng)()));
383 template<
typename Rng>
384 EIGEN_STRONG_INLINE
const _Scalar nzur_scalar(Rng&& rng)
386 using namespace Eigen::internal;
387 return BitScalar<_Scalar>{}.to_nzur(ExtractFirstUint<_Scalar>{}(std::forward<Rng>(rng)()));
390 template<
typename Packet,
typename Rng>
391 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
393 using namespace Eigen::internal;
394 using RUtils = RandUtils<Packet, Rng>;
395 return RUtils{}.uniform_real(std::forward<Rng>(rng));
404 template<
typename _Scalar>
407 static_assert(std::is_floating_point<_Scalar>::value,
"uniformReal needs floating point types.");
411 using Scalar = _Scalar;
414 : bias{ _min }, slope{ _max - _min }
424 template<
typename Rng>
425 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
427 using namespace Eigen::internal;
428 return bias + BitScalar<_Scalar>{}.to_ur(pfirst(std::forward<Rng>(rng)())) * slope;
431 template<
typename Packet,
typename Rng>
432 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
434 using namespace Eigen::internal;
435 using RUtils = RandUtils<Packet, Rng>;
437 RUtils{}.uniform_real(std::forward<Rng>(rng)), pset1<Packet>(slope)
438 ), pset1<Packet>(bias));
448 template<
typename _Scalar>
453 using Scalar = _Scalar;
457 eigen_assert(0 <= _p && _p <= 1 );
458 p = (uint32_t)(_p * 0x80000000);
467 template<
typename Rng>
468 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
470 using namespace Eigen::internal;
471 return (((uint32_t)pfirst(std::forward<Rng>(rng)()) & 0x7FFFFFFF) < p) ? 1 : 0;
474 template<
typename Packet,
typename Rng>
475 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
477 using namespace Eigen::internal;
478 using IPacket = decltype(reinterpret_to_int(std::declval<Packet>()));
479 using RUtils = RawbitsMaker<IPacket, Rng>;
480 auto one = pset1<Packet>(1);
481 auto zero = pset1<Packet>(0);
482 auto r = RUtils{}.rawbits(std::forward<Rng>(rng));
483 r = pand(r, pset1<IPacket>(0x7FFFFFFF));
484 return pblendv(pcmplt(r, pset1<IPacket>(p)), one, zero);
489 template<
typename Derived,
typename Urng>
490 using RandBitsType = CwiseNullaryOp<internal::scalar_rng_adaptor<RandbitsGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
504 template<
typename Derived,
typename Urng>
505 inline const RandBitsType<Derived, Urng>
509 rows, cols, { std::forward<Urng>(urng) }
524 template<
typename Derived,
typename Urng>
525 inline const RandBitsType<Derived, Urng>
529 o.rows(), o.cols(), { std::forward<Urng>(urng) }
533 template<
typename Derived,
typename Urng>
534 using BalancedType = CwiseNullaryOp<internal::scalar_rng_adaptor<BalancedGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
548 template<
typename Derived,
typename Urng>
549 inline const BalancedType<Derived, Urng>
553 rows, cols, { std::forward<Urng>(urng) }
568 template<
typename Derived,
typename Urng>
569 inline const BalancedType<Derived, Urng>
573 o.rows(), o.cols(), { std::forward<Urng>(urng) }
577 template<
typename Derived,
typename Urng>
578 using Balanced2Type = CwiseNullaryOp<internal::scalar_rng_adaptor<Balanced2Gen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
593 template<
typename Derived,
typename Urng>
594 inline const Balanced2Type<Derived, Urng>
595 balanced(Index rows, Index cols, Urng&& urng,
typename Derived::Scalar a,
typename Derived::Scalar b)
614 template<
typename Derived,
typename Urng>
615 inline const Balanced2Type<Derived, Urng>
616 balancedLike(
const Derived& o, Urng&& urng,
typename Derived::Scalar a,
typename Derived::Scalar b)
623 template<
typename Derived,
typename Urng>
624 using StdUniformRealType = CwiseNullaryOp<internal::scalar_rng_adaptor<StdUniformRealGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
638 template<
typename Derived,
typename Urng>
639 inline const StdUniformRealType<Derived, Urng>
643 rows, cols, { std::forward<Urng>(urng) }
658 template<
typename Derived,
typename Urng>
659 inline const StdUniformRealType<Derived, Urng>
663 o.rows(), o.cols(), { std::forward<Urng>(urng) }
667 template<
typename Derived,
typename Urng>
668 using UniformRealType = CwiseNullaryOp<internal::scalar_rng_adaptor<UniformRealGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
683 template<
typename Derived,
typename Urng>
684 inline const UniformRealType<Derived, Urng>
685 uniformReal(Index rows, Index cols, Urng&& urng,
typename Derived::Scalar min,
typename Derived::Scalar max)
704 template<
typename Derived,
typename Urng>
705 inline const UniformRealType<Derived, Urng>
706 uniformRealLike(Derived& o, Urng&& urng,
typename Derived::Scalar min,
typename Derived::Scalar max)
713 template<
typename Derived,
typename Urng>
714 using BernoulliType = CwiseNullaryOp<internal::scalar_rng_adaptor<BernoulliGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
727 template<
typename Derived,
typename Urng>
728 inline const BernoulliType<Derived, Urng>
729 bernoulli(Index rows, Index cols, Urng&& urng,
double p = 0.5)
746 template<
typename Derived,
typename Urng>
747 inline const BernoulliType<Derived, Urng>
Generator of reals in a range [a, b]
Definition: Basic.h:331
Balanced2Gen(_Scalar _a=-1, _Scalar _b=1)
Construct a new balanced generator.
Definition: Basic.h:342
Generator of reals in a range [-1, 1]
Definition: Basic.h:302
Generator of Bernoulli distribution.
Definition: Basic.h:450
Base class of all univariate random generators.
Definition: Basic.h:33
const CwiseNullaryOp< internal::scalar_rng_adaptor< DerivedGen &, Scalar, Urng >, const Derived > generate(Index rows, Index cols, Urng &&urng)
generate random values from its distribution
Definition: Basic.h:48
const CwiseNullaryOp< internal::scalar_rng_adaptor< DerivedGen &, Scalar, Urng >, const Derived > generateLike(const Derived &o, Urng &&urng)
generate random values from its distribution
Definition: Basic.h:67
Base class of all multivariate random matrix generators.
Definition: Basic.h:129
Matrix< _Scalar, Dim, -1 > generate(Urng &&urng, Index samples)
generates multiple samples at once
Definition: Basic.h:146
Matrix< _Scalar, Dim, Dim > generate(Urng &&urng)
generates one sample
Definition: Basic.h:159
Index dims() const
returns the dimensions of matrices to be generated
Definition: Basic.h:134
Base class of all multivariate random vector generators.
Definition: Basic.h:84
Matrix< _Scalar, Dim, -1 > generate(Urng &&urng, Index samples)
generates multiple samples at once
Definition: Basic.h:101
Index dims() const
returns the dimensions of vectors to be generated
Definition: Basic.h:89
Matrix< _Scalar, Dim, 1 > generate(Urng &&urng)
generates one sample
Definition: Basic.h:114
Generator of random bits for integral scalars.
Definition: Basic.h:273
const StdUniformRealType< Derived, Urng > uniformReal(Index rows, Index cols, Urng &&urng)
generates reals in a range [0, 1)
Definition: Basic.h:640
const RandBitsType< Derived, Urng > randBits(Index rows, Index cols, Urng &&urng)
generates integers with random bits
Definition: Basic.h:506
const BernoulliType< Derived, Urng > bernoulli(Index rows, Index cols, Urng &&urng, double p=0.5)
generates 1 with probability p and 0 with probability 1 - p
Definition: Basic.h:729
const BalancedType< Derived, Urng > balanced(Index rows, Index cols, Urng &&urng)
generates reals in a range [-1, 1]
Definition: Basic.h:550
const BalancedType< Derived, Urng > balancedLike(const Derived &o, Urng &&urng)
generates reals in a range [-1, 1]
Definition: Basic.h:570
const StdUniformRealType< Derived, Urng > uniformRealLike(Derived &o, Urng &&urng)
generates reals in a range [0, 1)
Definition: Basic.h:660
const RandBitsType< Derived, Urng > randBitsLike(Derived &o, Urng &&urng)
generates integers with random bits
Definition: Basic.h:526