12 #ifndef EIGENRAND_DISTS_DISCRETE_H
13 #define EIGENRAND_DISTS_DISCRETE_H
23 template<
typename _Precision = u
int32_t,
typename _Size = u
int32_t>
26 std::unique_ptr<_Precision[]> arr;
27 std::unique_ptr<_Size[]> alias;
28 size_t msize = 0, bitsize = 0, bitmask = 0;
35 AliasMethod(
const AliasMethod& o)
40 AliasMethod(AliasMethod&& o)
45 AliasMethod& operator=(
const AliasMethod& o)
52 arr = std::unique_ptr<_Precision[]>(
new _Precision[(
size_t)1 << bitsize]);
53 alias = std::unique_ptr<_Size[]>(
new _Size[(
size_t)1 << bitsize]);
55 std::copy(o.arr.get(), o.arr.get() + ((
size_t)1 << bitsize), arr.get());
56 std::copy(o.alias.get(), o.alias.get() + ((
size_t)1 << bitsize), alias.get());
61 AliasMethod& operator=(AliasMethod&& o)
66 std::swap(arr, o.arr);
67 std::swap(alias, o.alias);
71 template<
typename _Iter>
72 AliasMethod(_Iter first, _Iter last)
74 buildTable(first, last);
77 template<
typename _Iter>
78 void buildTable(_Iter first, _Iter last)
83 for (
auto it = first; it != last; ++it, ++msize)
88 if (!std::isfinite(sum))
throw std::invalid_argument{
"cannot build NaN value distribution" };
91 nbsize = (size_t)std::ceil(std::log2(msize));
92 psize = (size_t)1 << nbsize;
94 if (nbsize != bitsize)
96 arr = std::unique_ptr<_Precision[]>(
new _Precision[psize]);
97 std::fill(arr.get(), arr.get() + psize, 0);
98 alias = std::unique_ptr<_Size[]>(
new _Size[psize]);
100 bitmask = ((size_t)(-1)) >> (
sizeof(
size_t) * 8 - bitsize);
105 auto f = std::unique_ptr<double[]>(
new double[psize]);
107 for (
auto it = first; it != last; ++it, ++pf)
111 std::fill(pf, pf + psize - msize, 0);
113 size_t over = 0, under = 0, mm;
114 while (over < psize && f[over] < 1) ++over;
115 while (under < psize && f[under] >= 1) ++under;
118 while (over < psize && under < psize)
120 if (std::is_integral<_Precision>::value)
122 arr[under] = (_Precision)(f[under] * (std::numeric_limits<_Precision>::max() + 1.0));
126 arr[under] = (_Precision)f[under];
128 alias[under] = (_Size)over;
129 f[over] += f[under] - 1;
130 if (f[over] >= 1 || mm <= over)
132 for (under = mm; under < psize && f[under] >= 1; ++under);
140 while (over < psize && f[over] < 1) ++over;
143 for (; over < psize; ++over)
147 if (std::is_integral<_Precision>::value)
149 arr[over] = std::numeric_limits<_Precision>::max();
155 alias[over] = (_Size)over;
161 if (std::is_integral<_Precision>::value)
163 arr[under] = std::numeric_limits<_Precision>::max();
169 alias[under] = (_Size)under;
170 for (under = mm; under < msize; ++under)
174 if (std::is_integral<_Precision>::value)
176 arr[under] = std::numeric_limits<_Precision>::max();
182 alias[under] = (_Size)under;
188 size_t get_bitsize()
const
193 size_t get_bitmask()
const
198 const _Precision* get_prob()
const
203 const _Size* get_alias()
const
214 template<
typename _Scalar>
217 static_assert(std::is_same<_Scalar, int32_t>::value,
"uniformInt needs integral types.");
218 int cache_rest_cnt = 0;
221 size_t pdiff, bitsize, bitmask;
224 using Scalar = _Scalar;
232 : pmin{ _min }, pdiff{ (size_t)(_max - _min) }
234 if ((pdiff + 1) > pdiff)
236 bitsize = (size_t)std::ceil(std::log2(pdiff + 1));
240 bitsize = (size_t)std::ceil(std::log2(pdiff));
242 bitmask = (_Scalar)(((
size_t)-1) >> (
sizeof(
size_t) * 8 - bitsize));
251 template<
typename Rng>
252 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
254 using namespace Eigen::internal;
255 auto rx = randbits(rng);
256 if (pdiff == bitmask)
258 return (_Scalar)(rx & bitmask) + pmin;
262 size_t bitcnt = bitsize;
263 for (
int _i = 0; ; ++_i)
265 EIGENRAND_CHECK_INFINITY_LOOP();
266 _Scalar cands = (_Scalar)(rx & bitmask);
267 if (cands <= pdiff)
return cands;
268 if (bitcnt + bitsize < 32)
282 template<
typename Packet,
typename Rng>
283 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
285 using namespace Eigen::internal;
286 auto rx = randbits.template packetOp<Packet>(rng);
287 auto pbitmask = pset1<Packet>(bitmask);
288 if (pdiff == bitmask)
290 return padd(pand(rx, pbitmask), pset1<Packet>(pmin));
294 auto& cm = Rand::detail::CompressMask<
sizeof(Packet)>::get_inst();
295 auto plen = pset1<Packet>(pdiff + 1);
296 size_t bitcnt = bitsize;
297 for (
int _i = 0; ; ++_i)
299 EIGENRAND_CHECK_INFINITY_LOOP();
301 auto cands = pand(rx, pbitmask);
303 cache_rest_cnt = cm.compress_append(cands, pcmplt(cands, plen),
304 OptCacheStore::template get<Packet>(), cache_rest_cnt, full);
305 if (full)
return padd(cands, pset1<Packet>(pmin));
307 if (bitcnt + bitsize < 32)
309 rx = psrl<-1>(rx, bitsize);
314 rx = randbits.template packetOp<Packet>(rng);
328 template<
typename _Scalar,
typename Precision =
float>
336 template<
typename _Scalar>
339 static_assert(std::is_same<_Scalar, int32_t>::value,
"discreteDist needs integral types.");
340 #ifdef EIGEN_VECTORIZE_AVX2
345 std::vector<uint32_t> cdf;
346 AliasMethod<int32_t, _Scalar> alias_table;
349 using Scalar = _Scalar;
358 template<
typename RealIter>
361 if (std::distance(first, last) < 16)
364 std::vector<double> _cdf;
366 for (; first != last; ++first)
368 _cdf.emplace_back(acc += *first);
373 cdf.emplace_back((uint32_t)(p / _cdf.back() * 0x80000000));
379 alias_table = AliasMethod<int32_t, _Scalar>{ first, last };
390 template<
typename Real,
391 typename std::enable_if<std::is_arithmetic<Real>::value,
int>::type = 0>
402 DiscreteGen(
const DiscreteGen&) =
default;
403 DiscreteGen(DiscreteGen&&) =
default;
405 DiscreteGen& operator=(
const DiscreteGen&) =
default;
406 DiscreteGen& operator=(DiscreteGen&&) =
default;
408 template<
typename Rng>
409 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
411 using namespace Eigen::internal;
414 auto rx = randbits(std::forward<Rng>(rng)) & 0x7FFFFFFF;
415 return (_Scalar)(std::lower_bound(cdf.begin(), cdf.end() - 1, rx) - cdf.begin());
419 auto rx = randbits(std::forward<Rng>(rng));
420 auto albit = rx & alias_table.get_bitmask();
421 uint32_t alx = (uint32_t)(rx >> (
sizeof(rx) * 8 - 31));
422 if (alx < alias_table.get_prob()[albit])
return (_Scalar)albit;
423 return alias_table.get_alias()[albit];
427 template<
typename Packet,
typename Rng>
428 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
430 using namespace Eigen::internal;
431 #ifdef EIGEN_VECTORIZE_AVX2
435 return cache.template get<Packet>();
437 using PacketType = Packet8i;
439 using PacketType = Packet;
445 ret = pset1<PacketType>(cdf.size() - 1);
446 auto rx = pand(randbits.template packetOp<PacketType>(std::forward<Rng>(rng)), pset1<PacketType>(0x7FFFFFFF));
447 for (
size_t i = 0; i < cdf.size() - 1; ++i)
449 ret = padd(ret, pcmplt(rx, pset1<PacketType>(cdf[i])));
454 auto rx = randbits.template packetOp<PacketType>(std::forward<Rng>(rng));
455 auto albit = pand(rx, pset1<PacketType>(alias_table.get_bitmask()));
456 auto c = pcmplt(psrl<1>(rx), pgather(alias_table.get_prob(), albit));
457 ret = pblendv(c, albit, pgather(alias_table.get_alias(), albit));
460 #ifdef EIGEN_VECTORIZE_AVX2
462 cache.template get<Packet>() = _mm256_extractf128_si256(ret, 1);
463 return _mm256_extractf128_si256(ret, 0);
475 template<
typename _Scalar>
478 static_assert(std::is_same<_Scalar, int32_t>::value,
"discreteDist needs integral types.");
480 std::vector<float> cdf;
481 AliasMethod<float, _Scalar> alias_table;
484 using Scalar = _Scalar;
493 template<
typename RealIter>
496 if (std::distance(first, last) < 16)
499 std::vector<double> _cdf;
501 for (; first != last; ++first)
503 _cdf.emplace_back(acc += *first);
508 cdf.emplace_back(p / _cdf.back());
514 alias_table = AliasMethod<float, _Scalar>{ first, last };
525 template<
typename Real,
526 typename std::enable_if<std::is_arithmetic<Real>::value,
int>::type = 0>
537 DiscreteGen(
const DiscreteGen&) =
default;
538 DiscreteGen(DiscreteGen&&) =
default;
540 DiscreteGen& operator=(
const DiscreteGen&) =
default;
541 DiscreteGen& operator=(DiscreteGen&&) =
default;
543 template<
typename Rng>
544 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
546 using namespace Eigen::internal;
549 auto rx = ur(std::forward<Rng>(rng));
550 return (_Scalar)(std::lower_bound(cdf.begin(), cdf.end() - 1, rx) - cdf.begin());
554 auto albit = pfirst(rng()) & alias_table.get_bitmask();
556 if (alx < alias_table.get_prob()[albit])
return albit;
557 return alias_table.get_alias()[albit];
561 template<
typename Packet,
typename Rng>
562 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
564 using namespace Eigen::internal;
565 using PacketType = decltype(reinterpret_to_float(std::declval<Packet>()));
569 auto ret = pset1<Packet>(cdf.size());
570 auto rx = ur.template packetOp<PacketType>(std::forward<Rng>(rng));
573 ret = padd(ret, reinterpret_to_int(pcmplt(rx, pset1<PacketType>(p))));
579 using RUtils = RawbitsMaker<Packet, Rng>;
580 auto albit = pand(RUtils{}.rawbits(rng), pset1<Packet>(alias_table.get_bitmask()));
581 auto c = reinterpret_to_int(pcmplt(ur.template packetOp<PacketType>(rng), pgather(alias_table.get_prob(), albit)));
582 return pblendv(c, albit, pgather(alias_table.get_alias(), albit));
592 template<
typename _Scalar>
595 static_assert(std::is_same<_Scalar, int32_t>::value,
"discreteDist needs integral types.");
597 std::vector<double> cdf;
598 AliasMethod<double, _Scalar> alias_table;
601 using Scalar = _Scalar;
610 template<
typename RealIter>
613 if (std::distance(first, last) < 16)
616 std::vector<double> _cdf;
618 for (; first != last; ++first)
620 _cdf.emplace_back(acc += *first);
625 cdf.emplace_back(p / _cdf.back());
631 alias_table = AliasMethod<double, _Scalar>{ first, last };
642 template<
typename Real,
643 typename std::enable_if<std::is_arithmetic<Real>::value,
int>::type = 0>
654 DiscreteGen(
const DiscreteGen&) =
default;
655 DiscreteGen(DiscreteGen&&) =
default;
657 DiscreteGen& operator=(
const DiscreteGen&) =
default;
658 DiscreteGen& operator=(DiscreteGen&&) =
default;
660 template<
typename Rng>
661 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
663 using namespace Eigen::internal;
666 auto rx = ur(std::forward<Rng>(rng));
667 return (_Scalar)(std::lower_bound(cdf.begin(), cdf.end() - 1, rx) - cdf.begin());
671 auto albit = pfirst(rng()) & alias_table.get_bitmask();
673 if (alx < alias_table.get_prob()[albit])
return albit;
674 return alias_table.get_alias()[albit];
678 #ifdef EIGEN_VECTORIZE_NEON
680 template<
typename Packet,
typename Rng>
681 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
683 using namespace Eigen::internal;
684 using DPacket = decltype(reinterpret_to_double(std::declval<Packet>()));
687 auto ret = pset1<Packet>(cdf.size());
688 #ifdef EIGEN_VECTORIZE_AVX
689 auto rx = ur.template packetOp<Packet4d>(std::forward<Rng>(rng));
692 auto c = reinterpret_to_int(pcmplt(rx, pset1<decltype(rx)>(p)));
693 auto r = combine_low32(c);
697 auto rx1 = ur.template packetOp<DPacket>(rng),
698 rx2 = ur.template packetOp<DPacket>(rng);
701 auto pp = pset1<decltype(rx1)>(p);
702 ret = padd(ret, combine_low32(reinterpret_to_int(pcmplt(rx1, pp)), reinterpret_to_int(pcmplt(rx2, pp))));
709 #ifdef EIGEN_VECTORIZE_AVX
710 using RUtils = RawbitsMaker<Packet, Rng>;
711 auto albit = pand(RUtils{}.rawbits(rng), pset1<Packet>(alias_table.get_bitmask()));
712 auto c = reinterpret_to_int(pcmplt(ur.template packetOp<Packet4d>(rng), pgather(alias_table.get_prob(), _mm256_castsi128_si256(albit))));
713 return pblendv(combine_low32(c), albit, pgather(alias_table.get_alias(), albit));
715 using RUtils = RawbitsMaker<Packet, Rng>;
716 auto albit = pand(RUtils{}.rawbits(rng), pset1<Packet>(alias_table.get_bitmask()));
717 auto c1 = reinterpret_to_int(pcmplt(ur.template packetOp<DPacket>(rng), pgather(alias_table.get_prob(), albit)));
718 auto c2 = reinterpret_to_int(pcmplt(ur.template packetOp<DPacket>(rng), pgather(alias_table.get_prob(), albit,
true)));
719 return pblendv(combine_low32(c1, c2), albit, pgather(alias_table.get_alias(), albit));
726 template<
typename>
class BinomialGen;
733 template<
typename _Scalar>
737 static_assert(std::is_same<_Scalar, int32_t>::value,
"poisson needs integral types.");
738 int cache_rest_cnt = 0;
742 double mean, ne_mean, sqrt_tmean, log_mean, g1;
745 using Scalar = _Scalar;
753 : mean{ _mean }, ne_mean{ std::exp(-_mean) }
755 sqrt_tmean = std::sqrt(2 * mean);
756 log_mean = std::log(mean);
757 g1 = mean * log_mean - std::lgamma(mean + 1);
766 template<
typename Rng>
767 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
769 using namespace Eigen::internal;
777 if (val <= ne_mean)
break;
785 for (
int _i = 0; ; ++_i)
787 EIGENRAND_CHECK_INFINITY_LOOP();
788 yx = std::tan(constant::pi * ur(rng));
789 res = (_Scalar)(sqrt_tmean * yx + mean);
790 if (res >= 0 && ur(rng) <= 0.9 * (1.0 + yx * yx)
791 * std::exp(res * log_mean - std::lgamma(res + 1.0) - g1))
799 template<
typename Packet,
typename Rng>
800 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
802 using namespace Eigen::internal;
803 using PacketType = decltype(reinterpret_to_float(std::declval<Packet>()));
807 Packet res = pset1<Packet>(0);
808 PacketType val = pset1<PacketType>(1), pne_mean = pset1<PacketType>(ne_mean);
809 for (
int _i = 0; ; ++_i)
811 EIGENRAND_CHECK_INFINITY_LOOP();
812 val = pmul(val, ur.template packetOp<PacketType>(rng));
813 auto c = reinterpret_to_int(pcmplt(pne_mean, val));
814 if (pmovemask(c) == 0)
break;
815 res = padd(res, pnegate(c));
821 auto& cm = Rand::detail::CompressMask<
sizeof(Packet)>::get_inst();
822 const PacketType ppi = pset1<PacketType>(constant::pi),
823 psqrt_tmean = pset1<PacketType>(sqrt_tmean),
824 pmean = pset1<PacketType>(mean),
825 plog_mean = pset1<PacketType>(log_mean),
826 pg1 = pset1<PacketType>(g1);
827 for (
int _i = 0; ; ++_i)
829 EIGENRAND_CHECK_INFINITY_LOOP();
830 PacketType fres, yx, psin, pcos;
831 psincos(pmul(ppi, ur.template packetOp<PacketType>(rng)), psin, pcos);
832 yx = pdiv(psin, pcos);
833 fres = ptruncate(padd(pmul(psqrt_tmean, yx), pmean));
835 auto p1 = pmul(padd(pmul(yx, yx), pset1<PacketType>(1)), pset1<PacketType>(0.9));
836 auto p2 = pexp(psub(psub(pmul(fres, plog_mean), plgamma_approx(padd(fres, pset1<PacketType>(1)))), pg1));
838 auto c1 = pcmple(pset1<PacketType>(0), fres);
839 auto c2 = pcmple(ur.template packetOp<PacketType>(rng), pmul(p1, p2));
843 cache_rest_cnt = cm.compress_append(cands, pand(c1, c2),
844 OptCacheStore::template get<PacketType>(), cache_rest_cnt, full);
845 if (full)
return pcast<PacketType, Packet>(cands);
856 template<
typename _Scalar>
859 static_assert(std::is_same<_Scalar, int32_t>::value,
"binomial needs integral types.");
863 double p = 0, small_p = 0, g1 = 0, sqrt_v = 0, log_small_p = 0, log_small_q = 0;
866 using Scalar = _Scalar;
875 :
poisson{ _trials * std::min(_p, 1 - _p) },
876 trials{ _trials }, p{ _p }, small_p{ std::min(p, 1 - p) }
879 if (!(trials < 25 ||
poisson.mean < 1.0))
881 g1 = std::lgamma(trials + 1);
882 sqrt_v = std::sqrt(2 *
poisson.mean * (1 - small_p));
883 log_small_p = std::log(small_p);
884 log_small_q = std::log(1 - small_p);
894 template<
typename Rng>
895 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
897 using namespace Eigen::internal;
902 for (
int i = 0; i < trials; ++i)
904 if (
poisson.ur(rng) < p) ++res;
914 for (
int _i = 0; ; ++_i)
916 EIGENRAND_CHECK_INFINITY_LOOP();
918 ys = std::tan(constant::pi *
poisson.ur(rng));
919 res = (_Scalar)(sqrt_v * ys +
poisson.mean);
920 if (0 <= res && res <= trials &&
poisson.ur(rng) <= 1.2 * sqrt_v
922 * std::exp(g1 - std::lgamma(res + 1)
923 - std::lgamma(trials - res + 1.0)
925 + (trials - res) * log_small_q)
932 return p == small_p ? res : trials - res;
935 template<
typename Packet,
typename Rng>
936 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
938 using namespace Eigen::internal;
939 using PacketType = decltype(reinterpret_to_float(std::declval<Packet>()));
943 PacketType pp = pset1<PacketType>(p);
944 res = pset1<Packet>(trials);
945 for (
int i = 0; i < trials; ++i)
947 auto c = reinterpret_to_int(pcmple(pp,
poisson.ur.template packetOp<PacketType>(rng)));
954 res =
poisson.template packetOp<Packet>(rng);
958 auto& cm = Rand::detail::CompressMask<
sizeof(Packet)>::get_inst();
959 const PacketType ppi = pset1<PacketType>(constant::pi),
960 ptrials = pset1<PacketType>(trials),
961 psqrt_v = pset1<PacketType>(sqrt_v),
962 pmean = pset1<PacketType>(
poisson.mean),
963 plog_small_p = pset1<PacketType>(log_small_p),
964 plog_small_q = pset1<PacketType>(log_small_q),
965 pg1 = pset1<PacketType>(g1);
966 for (
int _i = 0; ; ++_i)
968 EIGENRAND_CHECK_INFINITY_LOOP();
969 PacketType fres, ys, psin, pcos;
970 psincos(pmul(ppi,
poisson.ur.template packetOp<PacketType>(rng)), psin, pcos);
971 ys = pdiv(psin, pcos);
972 fres = ptruncate(padd(pmul(psqrt_v, ys), pmean));
974 auto p1 = pmul(pmul(pset1<PacketType>(1.2), psqrt_v), padd(pset1<PacketType>(1), pmul(ys, ys)));
977 psub(pg1, plgamma_approx(padd(fres, pset1<PacketType>(1)))),
978 plgamma_approx(psub(padd(ptrials, pset1<PacketType>(1)), fres))
979 ), pmul(fres, plog_small_p)), pmul(psub(ptrials, fres), plog_small_q))
982 auto c1 = pand(pcmple(pset1<PacketType>(0), fres), pcmple(fres, ptrials));
983 auto c2 = pcmple(
poisson.ur.template packetOp<PacketType>(rng), pmul(p1, p2));
987 poisson.cache_rest_cnt = cm.compress_append(cands, pand(c1, c2),
988 poisson.template get<PacketType>(),
poisson.cache_rest_cnt, full);
991 res = pcast<PacketType, Packet>(cands);
996 return p == small_p ? res : psub(pset1<Packet>(trials), res);
1005 template<
typename _Scalar>
1008 static_assert(std::is_same<_Scalar, int32_t>::value,
"geomtric needs integral types.");
1013 using Scalar = _Scalar;
1021 : p{ _p }, rlog_q{ 1 / std::log(1 - p) }
1031 template<
typename Rng>
1032 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
1034 using namespace Eigen::internal;
1035 return (_Scalar)(std::log(1 - ur(std::forward<Rng>(rng))) * rlog_q);
1038 template<
typename Packet,
typename Rng>
1039 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
1041 using namespace Eigen::internal;
1042 using PacketType = decltype(reinterpret_to_float(std::declval<Packet>()));
1044 return pcast<PacketType, Packet>(ptruncate(pmul(plog(
1045 psub(pset1<PacketType>(1), ur.template packetOp<PacketType>(std::forward<Rng>(rng)))
1046 ), pset1<PacketType>(rlog_q))));
1051 template<
typename Derived,
typename Urng>
1052 using UniformIntType = CwiseNullaryOp<internal::scalar_rng_adaptor<UniformIntGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1067 template<
typename Derived,
typename Urng>
1068 inline const UniformIntType<Derived, Urng>
1069 uniformInt(Index rows, Index cols, Urng&& urng,
typename Derived::Scalar min,
typename Derived::Scalar max)
1088 template<
typename Derived,
typename Urng>
1089 inline const UniformIntType<Derived, Urng>
1090 uniformIntLike(Derived& o, Urng&& urng,
typename Derived::Scalar min,
typename Derived::Scalar max)
1097 template<
typename Derived,
typename Urng>
1098 using DiscreteFType = CwiseNullaryOp<internal::scalar_rng_adaptor<DiscreteGen<typename Derived::Scalar, float>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1114 template<
typename Derived,
typename Urng,
typename RealIter>
1115 inline const DiscreteFType<Derived, Urng>
1116 discreteF(Index rows, Index cols, Urng&& urng, RealIter first, RealIter last)
1136 template<
typename Derived,
typename Urng,
typename RealIter>
1137 inline const DiscreteFType<Derived, Urng>
1159 template<
typename Derived,
typename Urng,
typename Real>
1160 inline const DiscreteFType<Derived, Urng>
1161 discreteF(Index rows, Index cols, Urng&& urng,
const std::initializer_list<Real>& il)
1181 template<
typename Derived,
typename Urng,
typename Real>
1182 inline const DiscreteFType<Derived, Urng>
1190 template<
typename Derived,
typename Urng>
1191 using DiscreteDType = CwiseNullaryOp<internal::scalar_rng_adaptor<DiscreteGen<typename Derived::Scalar, double>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1207 template<
typename Derived,
typename Urng,
typename RealIter>
1208 inline const DiscreteDType<Derived, Urng>
1209 discreteD(Index rows, Index cols, Urng&& urng, RealIter first, RealIter last)
1229 template<
typename Derived,
typename Urng,
typename RealIter>
1230 inline const DiscreteDType<Derived, Urng>
1252 template<
typename Derived,
typename Urng,
typename Real>
1253 inline const DiscreteDType<Derived, Urng>
1254 discreteD(Index rows, Index cols, Urng&& urng,
const std::initializer_list<Real>& il)
1274 template<
typename Derived,
typename Urng,
typename Real>
1275 inline const DiscreteDType<Derived, Urng>
1283 template<
typename Derived,
typename Urng>
1284 using DiscreteType = CwiseNullaryOp<internal::scalar_rng_adaptor<DiscreteGen<typename Derived::Scalar, int32_t>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1300 template<
typename Derived,
typename Urng,
typename RealIter>
1301 inline const DiscreteType<Derived, Urng>
1302 discrete(Index rows, Index cols, Urng&& urng, RealIter first, RealIter last)
1322 template<
typename Derived,
typename Urng,
typename RealIter>
1323 inline const DiscreteType<Derived, Urng>
1345 template<
typename Derived,
typename Urng,
typename Real>
1346 inline const DiscreteType<Derived, Urng>
1347 discrete(Index rows, Index cols, Urng&& urng,
const std::initializer_list<Real>& il)
1367 template<
typename Derived,
typename Urng,
typename Real>
1368 inline const DiscreteType<Derived, Urng>
1369 discreteLike(Derived& o, Urng&& urng,
const std::initializer_list<Real>& il)
1376 template<
typename Derived,
typename Urng>
1377 using PoissonType = CwiseNullaryOp<internal::scalar_rng_adaptor<PoissonGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1392 template<
typename Derived,
typename Urng>
1393 inline const PoissonType<Derived, Urng>
1394 poisson(Index rows, Index cols, Urng&& urng,
double mean = 1)
1413 template<
typename Derived,
typename Urng>
1414 inline const PoissonType<Derived, Urng>
1422 template<
typename Derived,
typename Urng>
1423 using BinomialType = CwiseNullaryOp<internal::scalar_rng_adaptor<BinomialGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1439 template<
typename Derived,
typename Urng>
1440 inline const BinomialType<Derived, Urng>
1441 binomial(Index rows, Index cols, Urng&& urng,
typename Derived::Scalar trials = 1,
double p = 0.5)
1461 template<
typename Derived,
typename Urng>
1462 inline const BinomialType<Derived, Urng>
1463 binomialLike(Derived& o, Urng&& urng,
typename Derived::Scalar trials = 1,
double p = 0.5)
1470 template<
typename Derived,
typename Urng>
1471 using GeometricType = CwiseNullaryOp<internal::scalar_rng_adaptor<GeometricGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1486 template<
typename Derived,
typename Urng>
1487 inline const GeometricType<Derived, Urng>
1488 geometric(Index rows, Index cols, Urng&& urng,
double p = 0.5)
1507 template<
typename Derived,
typename Urng>
1508 inline const GeometricType<Derived, Urng>
1517 #ifdef EIGEN_VECTORIZE_NEON
1520 template<
typename _Scalar,
typename Urng,
bool _mutable>
1521 struct functor_traits<scalar_rng_adaptor<Rand::DiscreteGen<_Scalar, double>, _Scalar, Urng, _mutable> >
1523 enum { Cost = HugeCost, PacketAccess = 0, IsRepeatable =
false };
Generator of integers on a binomial distribution.
Definition: Discrete.h:858
BinomialGen(_Scalar _trials=1, double _p=0.5)
Construct a new Binomial Generator.
Definition: Discrete.h:874
DiscreteGen(RealIter first, RealIter last)
Construct a new Discrete Generator.
Definition: Discrete.h:611
DiscreteGen(const std::initializer_list< Real > &il)
Construct a new Discrete Generator.
Definition: Discrete.h:644
DiscreteGen(RealIter first, RealIter last)
Construct a new Discrete Generator.
Definition: Discrete.h:494
DiscreteGen(const std::initializer_list< Real > &il)
Construct a new Discrete Generator.
Definition: Discrete.h:527
DiscreteGen(RealIter first, RealIter last)
Construct a new Discrete Generator.
Definition: Discrete.h:359
DiscreteGen(const std::initializer_list< Real > &il)
Construct a new Discrete Generator.
Definition: Discrete.h:392
Generator of integers on the interval [0, n), where the probability of each individual integer i is p...
Definition: Discrete.h:329
Base class of all univariate random generators.
Definition: Basic.h:33
Generator of integers on a geometric distribution.
Definition: Discrete.h:1007
GeometricGen(double _p=0.5)
Construct a new Geometric Generator.
Definition: Discrete.h:1020
Generator of integers on a Poisson distribution.
Definition: Discrete.h:735
PoissonGen(double _mean=1)
Construct a new Poisson Generator.
Definition: Discrete.h:752
Generator of random bits for integral scalars.
Definition: Basic.h:273
const PoissonType< Derived, Urng > poissonLike(Derived &o, Urng &&urng, double mean=1)
generates reals on the Poisson distribution.
Definition: Discrete.h:1415
const DiscreteFType< Derived, Urng > discreteF(Index rows, Index cols, Urng &&urng, RealIter first, RealIter last)
generates random integers on the interval [0, n), where the probability of each individual integer i ...
Definition: Discrete.h:1116
const GeometricType< Derived, Urng > geometricLike(Derived &o, Urng &&urng, double p=0.5)
generates reals on the geometric distribution.
Definition: Discrete.h:1509
const BinomialType< Derived, Urng > binomialLike(Derived &o, Urng &&urng, typename Derived::Scalar trials=1, double p=0.5)
generates reals on the binomial distribution.
Definition: Discrete.h:1463
const UniformIntType< Derived, Urng > uniformInt(Index rows, Index cols, Urng &&urng, typename Derived::Scalar min, typename Derived::Scalar max)
generates integers with a given range [min, max]
Definition: Discrete.h:1069
const DiscreteDType< Derived, Urng > discreteDLike(Derived &o, Urng &&urng, RealIter first, RealIter last)
generates random integers on the interval [0, n), where the probability of each individual integer i ...
Definition: Discrete.h:1231
const DiscreteFType< Derived, Urng > discreteFLike(Derived &o, Urng &&urng, RealIter first, RealIter last)
generates random integers on the interval [0, n), where the probability of each individual integer i ...
Definition: Discrete.h:1138
const UniformIntType< Derived, Urng > uniformIntLike(Derived &o, Urng &&urng, typename Derived::Scalar min, typename Derived::Scalar max)
generates integers with a given range [min, max]
Definition: Discrete.h:1090
const DiscreteDType< Derived, Urng > discreteD(Index rows, Index cols, Urng &&urng, RealIter first, RealIter last)
generates random integers on the interval [0, n), where the probability of each individual integer i ...
Definition: Discrete.h:1209
const PoissonType< Derived, Urng > poisson(Index rows, Index cols, Urng &&urng, double mean=1)
generates reals on the Poisson distribution.
Definition: Discrete.h:1394
const DiscreteType< Derived, Urng > discrete(Index rows, Index cols, Urng &&urng, RealIter first, RealIter last)
generates random integers on the interval [0, n), where the probability of each individual integer i ...
Definition: Discrete.h:1302
const GeometricType< Derived, Urng > geometric(Index rows, Index cols, Urng &&urng, double p=0.5)
generates reals on the geometric distribution.
Definition: Discrete.h:1488
const DiscreteType< Derived, Urng > discreteLike(Derived &o, Urng &&urng, RealIter first, RealIter last)
generates random integers on the interval [0, n), where the probability of each individual integer i ...
Definition: Discrete.h:1324
const BinomialType< Derived, Urng > binomial(Index rows, Index cols, Urng &&urng, typename Derived::Scalar trials=1, double p=0.5)
generates reals on the binomial distribution.
Definition: Discrete.h:1441