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[1 << bitsize]);
53 alias = std::unique_ptr<_Size[]>(
new _Size[1 << bitsize]);
55 std::copy(o.arr.get(), o.arr.get() + (1 << bitsize), arr.get());
56 std::copy(o.alias.get(), o.alias.get() + (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];
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();
161 if (std::is_integral<_Precision>::value)
163 arr[under] = std::numeric_limits<_Precision>::max();
169 alias[under] = 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] = 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;
265 _Scalar cands = (_Scalar)(rx & bitmask);
266 if (cands <= pdiff)
return cands;
267 if (bitcnt + bitsize < 32)
281 template<
typename Packet,
typename Rng>
282 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
284 using namespace Eigen::internal;
285 auto rx = randbits.template packetOp<Packet>(rng);
286 auto pbitmask = pset1<Packet>(bitmask);
287 if (pdiff == bitmask)
289 return padd(pand(rx, pbitmask), pset1<Packet>(pmin));
293 auto& cm = Rand::detail::CompressMask<
sizeof(Packet)>::get_inst();
294 auto plen = pset1<Packet>(pdiff + 1);
295 size_t bitcnt = bitsize;
299 auto cands = pand(rx, pbitmask);
301 cache_rest_cnt = cm.compress_append(cands, pcmplt(cands, plen),
302 OptCacheStore::template get<Packet>(), cache_rest_cnt, full);
303 if (full)
return padd(cands, pset1<Packet>(pmin));
305 if (bitcnt + bitsize < 32)
307 rx = psrl(rx, bitsize);
312 rx = randbits.template packetOp<Packet>(rng);
326 template<
typename _Scalar,
typename Precision =
float>
334 template<
typename _Scalar>
337 static_assert(std::is_same<_Scalar, int32_t>::value,
"discreteDist needs integral types.");
338 #ifdef EIGEN_VECTORIZE_AVX2
343 std::vector<uint32_t> cdf;
344 AliasMethod<int32_t, _Scalar> alias_table;
347 using Scalar = _Scalar;
356 template<
typename RealIter>
359 if (std::distance(first, last) < 16)
362 std::vector<double> _cdf;
364 for (; first != last; ++first)
366 _cdf.emplace_back(acc += *first);
371 cdf.emplace_back((uint32_t)(p / _cdf.back() * 0x80000000));
377 alias_table = AliasMethod<int32_t, _Scalar>{ first, last };
388 template<
typename Real,
389 typename std::enable_if<std::is_arithmetic<Real>::value,
int>::type = 0>
400 DiscreteGen(
const DiscreteGen&) =
default;
401 DiscreteGen(DiscreteGen&&) =
default;
403 DiscreteGen& operator=(
const DiscreteGen&) =
default;
404 DiscreteGen& operator=(DiscreteGen&&) =
default;
406 template<
typename Rng>
407 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
409 using namespace Eigen::internal;
412 auto rx = randbits(std::forward<Rng>(rng)) & 0x7FFFFFFF;
413 return (_Scalar)(std::lower_bound(cdf.begin(), cdf.end() - 1, rx) - cdf.begin());
417 auto rx = randbits(std::forward<Rng>(rng));
418 auto albit = rx & alias_table.get_bitmask();
419 uint32_t alx = (uint32_t)(rx >> (
sizeof(rx) * 8 - 31));
420 if (alx < alias_table.get_prob()[albit])
return albit;
421 return alias_table.get_alias()[albit];
425 template<
typename Packet,
typename Rng>
426 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
428 using namespace Eigen::internal;
429 #ifdef EIGEN_VECTORIZE_AVX2
433 return cache.template get<Packet>();
435 using PacketType = Packet8i;
437 using PacketType = Packet;
443 ret = pset1<PacketType>(cdf.size() - 1);
444 auto rx = pand(randbits.template packetOp<PacketType>(std::forward<Rng>(rng)), pset1<PacketType>(0x7FFFFFFF));
445 for (
size_t i = 0; i < cdf.size() - 1; ++i)
447 ret = padd(ret, pcmplt(rx, pset1<PacketType>(cdf[i])));
452 auto rx = randbits.template packetOp<PacketType>(std::forward<Rng>(rng));
453 auto albit = pand(rx, pset1<PacketType>(alias_table.get_bitmask()));
454 auto c = pcmplt(psrl(rx, 1), pgather(alias_table.get_prob(), albit));
455 ret = pblendv(c, albit, pgather(alias_table.get_alias(), albit));
458 #ifdef EIGEN_VECTORIZE_AVX2
460 cache.template get<Packet>() = _mm256_extractf128_si256(ret, 1);
461 return _mm256_extractf128_si256(ret, 0);
473 template<
typename _Scalar>
476 static_assert(std::is_same<_Scalar, int32_t>::value,
"discreteDist needs integral types.");
478 std::vector<float> cdf;
479 AliasMethod<float, _Scalar> alias_table;
482 using Scalar = _Scalar;
491 template<
typename RealIter>
494 if (std::distance(first, last) < 16)
497 std::vector<double> _cdf;
499 for (; first != last; ++first)
501 _cdf.emplace_back(acc += *first);
506 cdf.emplace_back(p / _cdf.back());
512 alias_table = AliasMethod<float, _Scalar>{ first, last };
523 template<
typename Real,
524 typename std::enable_if<std::is_arithmetic<Real>::value,
int>::type = 0>
535 DiscreteGen(
const DiscreteGen&) =
default;
536 DiscreteGen(DiscreteGen&&) =
default;
538 DiscreteGen& operator=(
const DiscreteGen&) =
default;
539 DiscreteGen& operator=(DiscreteGen&&) =
default;
541 template<
typename Rng>
542 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
544 using namespace Eigen::internal;
547 auto rx = ur(std::forward<Rng>(rng));
548 return (_Scalar)(std::lower_bound(cdf.begin(), cdf.end() - 1, rx) - cdf.begin());
552 auto albit = pfirst(rng()) & alias_table.get_bitmask();
554 if (alx < alias_table.get_prob()[albit])
return albit;
555 return alias_table.get_alias()[albit];
559 template<
typename Packet,
typename Rng>
560 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
562 using namespace Eigen::internal;
563 using PacketType = decltype(reinterpret_to_float(std::declval<Packet>()));
567 auto ret = pset1<Packet>(cdf.size());
568 auto rx = ur.template packetOp<PacketType>(std::forward<Rng>(rng));
571 ret = padd(ret, reinterpret_to_int(pcmplt(rx, pset1<PacketType>(p))));
577 using RUtils = RawbitsMaker<Packet, Rng>;
578 auto albit = pand(RUtils{}.rawbits(rng), pset1<Packet>(alias_table.get_bitmask()));
579 auto c = reinterpret_to_int(pcmplt(ur.template packetOp<PacketType>(rng), pgather(alias_table.get_prob(), albit)));
580 return pblendv(c, albit, pgather(alias_table.get_alias(), albit));
590 template<
typename _Scalar>
593 static_assert(std::is_same<_Scalar, int32_t>::value,
"discreteDist needs integral types.");
595 std::vector<double> cdf;
596 AliasMethod<double, _Scalar> alias_table;
599 using Scalar = _Scalar;
608 template<
typename RealIter>
611 if (std::distance(first, last) < 16)
614 std::vector<double> _cdf;
616 for (; first != last; ++first)
618 _cdf.emplace_back(acc += *first);
623 cdf.emplace_back(p / _cdf.back());
629 alias_table = AliasMethod<double, _Scalar>{ first, last };
640 template<
typename Real,
641 typename std::enable_if<std::is_arithmetic<Real>::value,
int>::type = 0>
652 DiscreteGen(
const DiscreteGen&) =
default;
653 DiscreteGen(DiscreteGen&&) =
default;
655 DiscreteGen& operator=(
const DiscreteGen&) =
default;
656 DiscreteGen& operator=(DiscreteGen&&) =
default;
658 template<
typename Rng>
659 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
661 using namespace Eigen::internal;
664 auto rx = ur(std::forward<Rng>(rng));
665 return (_Scalar)(std::lower_bound(cdf.begin(), cdf.end() - 1, rx) - cdf.begin());
669 auto albit = pfirst(rng()) & alias_table.get_bitmask();
671 if (alx < alias_table.get_prob()[albit])
return albit;
672 return alias_table.get_alias()[albit];
676 template<
typename Packet,
typename Rng>
677 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
679 using namespace Eigen::internal;
680 using DPacket = decltype(reinterpret_to_double(std::declval<Packet>()));
683 auto ret = pset1<Packet>(cdf.size());
684 #ifdef EIGEN_VECTORIZE_AVX
685 auto rx = ur.template packetOp<Packet4d>(std::forward<Rng>(rng));
688 auto c = reinterpret_to_int(pcmplt(rx, pset1<decltype(rx)>(p)));
689 auto r = combine_low32(c);
693 auto rx1 = ur.template packetOp<DPacket>(rng),
694 rx2 = ur.template packetOp<DPacket>(rng);
697 auto pp = pset1<decltype(rx1)>(p);
698 ret = padd(ret, combine_low32(reinterpret_to_int(pcmplt(rx1, pp)), reinterpret_to_int(pcmplt(rx2, pp))));
705 #ifdef EIGEN_VECTORIZE_AVX
706 using RUtils = RawbitsMaker<Packet, Rng>;
707 auto albit = pand(RUtils{}.rawbits(rng), pset1<Packet>(alias_table.get_bitmask()));
708 auto c = reinterpret_to_int(pcmplt(ur.template packetOp<Packet4d>(rng), pgather(alias_table.get_prob(), _mm256_castsi128_si256(albit))));
709 return pblendv(combine_low32(c), albit, pgather(alias_table.get_alias(), albit));
711 using RUtils = RawbitsMaker<Packet, Rng>;
712 auto albit = pand(RUtils{}.rawbits(rng), pset1<Packet>(alias_table.get_bitmask()));
713 auto c1 = reinterpret_to_int(pcmplt(ur.template packetOp<DPacket>(rng), pgather(alias_table.get_prob(), albit)));
714 auto c2 = reinterpret_to_int(pcmplt(ur.template packetOp<DPacket>(rng), pgather(alias_table.get_prob(), albit,
true)));
715 return pblendv(combine_low32(c1, c2), albit, pgather(alias_table.get_alias(), albit));
721 template<
typename>
class BinomialGen;
728 template<
typename _Scalar>
732 static_assert(std::is_same<_Scalar, int32_t>::value,
"poisson needs integral types.");
733 int cache_rest_cnt = 0;
737 double mean, ne_mean, sqrt_tmean, log_mean, g1;
740 using Scalar = _Scalar;
748 : mean{ _mean }, ne_mean{ std::exp(-_mean) }
750 sqrt_tmean = std::sqrt(2 * mean);
751 log_mean = std::log(mean);
752 g1 = mean * log_mean - std::lgamma(mean + 1);
761 template<
typename Rng>
762 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
764 using namespace Eigen::internal;
772 if (val <= ne_mean)
break;
782 yx = std::tan(constant::pi * ur(rng));
783 res = (_Scalar)(sqrt_tmean * yx + mean);
784 if (res >= 0 && ur(rng) <= 0.9 * (1.0 + yx * yx)
785 * std::exp(res * log_mean - std::lgamma(res + 1.0) - g1))
793 template<
typename Packet,
typename Rng>
794 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
796 using namespace Eigen::internal;
797 using PacketType = decltype(reinterpret_to_float(std::declval<Packet>()));
801 Packet res = pset1<Packet>(0);
802 PacketType val = pset1<PacketType>(1), pne_mean = pset1<PacketType>(ne_mean);
805 val = pmul(val, ur.template packetOp<PacketType>(rng));
806 auto c = reinterpret_to_int(pcmplt(pne_mean, val));
807 if (pmovemask(c) == 0)
break;
808 res = padd(res, pnegate(c));
814 auto& cm = Rand::detail::CompressMask<
sizeof(Packet)>::get_inst();
815 const PacketType ppi = pset1<PacketType>(constant::pi),
816 psqrt_tmean = pset1<PacketType>(sqrt_tmean),
817 pmean = pset1<PacketType>(mean),
818 plog_mean = pset1<PacketType>(log_mean),
819 pg1 = pset1<PacketType>(g1);
822 PacketType fres, yx, psin, pcos;
823 psincos(pmul(ppi, ur.template packetOp<PacketType>(rng)), psin, pcos);
824 yx = pdiv(psin, pcos);
825 fres = ptruncate(padd(pmul(psqrt_tmean, yx), pmean));
827 auto p1 = pmul(padd(pmul(yx, yx), pset1<PacketType>(1)), pset1<PacketType>(0.9));
828 auto p2 = pexp(psub(psub(pmul(fres, plog_mean), plgamma_approx(padd(fres, pset1<PacketType>(1)))), pg1));
830 auto c1 = pcmple(pset1<PacketType>(0), fres);
831 auto c2 = pcmple(ur.template packetOp<PacketType>(rng), pmul(p1, p2));
835 cache_rest_cnt = cm.compress_append(cands, pand(c1, c2),
836 OptCacheStore::template get<PacketType>(), cache_rest_cnt, full);
837 if (full)
return pcast<PacketType, Packet>(cands);
848 template<
typename _Scalar>
851 static_assert(std::is_same<_Scalar, int32_t>::value,
"binomial needs integral types.");
855 double p, small_p, g1, sqrt_v, log_small_p, log_small_q;
858 using Scalar = _Scalar;
867 :
poisson{ _trials * std::min(_p, 1 - _p) },
868 trials{ _trials }, p{ _p }, small_p{ std::min(p, 1 - p) }
871 if (!(trials < 25 ||
poisson.mean < 1.0))
873 g1 = std::lgamma(trials + 1);
874 sqrt_v = std::sqrt(2 *
poisson.mean * (1 - small_p));
875 log_small_p = std::log(small_p);
876 log_small_q = std::log(1 - small_p);
886 template<
typename Rng>
887 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
889 using namespace Eigen::internal;
894 for (
int i = 0; i < trials; ++i)
896 if (
poisson.ur(rng) < p) ++res;
909 ys = std::tan(constant::pi *
poisson.ur(rng));
910 res = (_Scalar)(sqrt_v * ys +
poisson.mean);
911 if (0 <= res && res <= trials &&
poisson.ur(rng) <= 1.2 * sqrt_v
913 * std::exp(g1 - std::lgamma(res + 1)
914 - std::lgamma(trials - res + 1.0)
916 + (trials - res) * log_small_q)
923 return p == small_p ? res : trials - res;
926 template<
typename Packet,
typename Rng>
927 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
929 using namespace Eigen::internal;
930 using PacketType = decltype(reinterpret_to_float(std::declval<Packet>()));
934 PacketType pp = pset1<PacketType>(p);
935 res = pset1<Packet>(trials);
936 for (
int i = 0; i < trials; ++i)
938 auto c = reinterpret_to_int(pcmple(pp,
poisson.ur.template packetOp<PacketType>(rng)));
945 res =
poisson.template packetOp<Packet>(rng);
949 auto& cm = Rand::detail::CompressMask<
sizeof(Packet)>::get_inst();
950 const PacketType ppi = pset1<PacketType>(constant::pi),
951 ptrials = pset1<PacketType>(trials),
952 psqrt_v = pset1<PacketType>(sqrt_v),
953 pmean = pset1<PacketType>(
poisson.mean),
954 plog_small_p = pset1<PacketType>(log_small_p),
955 plog_small_q = pset1<PacketType>(log_small_q),
956 pg1 = pset1<PacketType>(g1);
959 PacketType fres, ys, psin, pcos;
960 psincos(pmul(ppi,
poisson.ur.template packetOp<PacketType>(rng)), psin, pcos);
961 ys = pdiv(psin, pcos);
962 fres = ptruncate(padd(pmul(psqrt_v, ys), pmean));
964 auto p1 = pmul(pmul(pset1<PacketType>(1.2), psqrt_v), padd(pset1<PacketType>(1), pmul(ys, ys)));
967 psub(pg1, plgamma_approx(padd(fres, pset1<PacketType>(1)))),
968 plgamma_approx(psub(padd(ptrials, pset1<PacketType>(1)), fres))
969 ), pmul(fres, plog_small_p)), pmul(psub(ptrials, fres), plog_small_q))
972 auto c1 = pand(pcmple(pset1<PacketType>(0), fres), pcmple(fres, ptrials));
973 auto c2 = pcmple(
poisson.ur.template packetOp<PacketType>(rng), pmul(p1, p2));
977 poisson.cache_rest_cnt = cm.compress_append(cands, pand(c1, c2),
978 poisson.template get<PacketType>(),
poisson.cache_rest_cnt, full);
981 res = pcast<PacketType, Packet>(cands);
986 return p == small_p ? res : psub(pset1<Packet>(trials), res);
995 template<
typename _Scalar>
998 static_assert(std::is_same<_Scalar, int32_t>::value,
"geomtric needs integral types.");
1003 using Scalar = _Scalar;
1011 : p{ _p }, rlog_q{ 1 / std::log(1 - p) }
1021 template<
typename Rng>
1022 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
1024 using namespace Eigen::internal;
1025 return (_Scalar)(std::log(1 - ur(std::forward<Rng>(rng))) * rlog_q);
1028 template<
typename Packet,
typename Rng>
1029 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
1031 using namespace Eigen::internal;
1032 using PacketType = decltype(reinterpret_to_float(std::declval<Packet>()));
1034 return pcast<PacketType, Packet>(ptruncate(pmul(plog(
1035 psub(pset1<PacketType>(1), ur.template packetOp<PacketType>(std::forward<Rng>(rng)))
1036 ), pset1<PacketType>(rlog_q))));
1041 template<
typename Derived,
typename Urng>
1042 using UniformIntType = CwiseNullaryOp<internal::scalar_rng_adaptor<UniformIntGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1057 template<
typename Derived,
typename Urng>
1058 inline const UniformIntType<Derived, Urng>
1059 uniformInt(Index rows, Index cols, Urng&& urng,
typename Derived::Scalar min,
typename Derived::Scalar max)
1078 template<
typename Derived,
typename Urng>
1079 inline const UniformIntType<Derived, Urng>
1080 uniformIntLike(Derived& o, Urng&& urng,
typename Derived::Scalar min,
typename Derived::Scalar max)
1087 template<
typename Derived,
typename Urng>
1088 using DiscreteFType = CwiseNullaryOp<internal::scalar_rng_adaptor<DiscreteGen<typename Derived::Scalar, float>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1104 template<
typename Derived,
typename Urng,
typename RealIter>
1105 inline const DiscreteFType<Derived, Urng>
1106 discreteF(Index rows, Index cols, Urng&& urng, RealIter first, RealIter last)
1126 template<
typename Derived,
typename Urng,
typename RealIter>
1127 inline const DiscreteFType<Derived, Urng>
1149 template<
typename Derived,
typename Urng,
typename Real>
1150 inline const DiscreteFType<Derived, Urng>
1151 discreteF(Index rows, Index cols, Urng&& urng,
const std::initializer_list<Real>& il)
1171 template<
typename Derived,
typename Urng,
typename Real>
1172 inline const DiscreteFType<Derived, Urng>
1180 template<
typename Derived,
typename Urng>
1181 using DiscreteDType = CwiseNullaryOp<internal::scalar_rng_adaptor<DiscreteGen<typename Derived::Scalar, double>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1197 template<
typename Derived,
typename Urng,
typename RealIter>
1198 inline const DiscreteDType<Derived, Urng>
1199 discreteD(Index rows, Index cols, Urng&& urng, RealIter first, RealIter last)
1219 template<
typename Derived,
typename Urng,
typename RealIter>
1220 inline const DiscreteDType<Derived, Urng>
1242 template<
typename Derived,
typename Urng,
typename Real>
1243 inline const DiscreteDType<Derived, Urng>
1244 discreteD(Index rows, Index cols, Urng&& urng,
const std::initializer_list<Real>& il)
1264 template<
typename Derived,
typename Urng,
typename Real>
1265 inline const DiscreteDType<Derived, Urng>
1273 template<
typename Derived,
typename Urng>
1274 using DiscreteType = CwiseNullaryOp<internal::scalar_rng_adaptor<DiscreteGen<typename Derived::Scalar, int32_t>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1290 template<
typename Derived,
typename Urng,
typename RealIter>
1291 inline const DiscreteType<Derived, Urng>
1292 discrete(Index rows, Index cols, Urng&& urng, RealIter first, RealIter last)
1312 template<
typename Derived,
typename Urng,
typename RealIter>
1313 inline const DiscreteType<Derived, Urng>
1335 template<
typename Derived,
typename Urng,
typename Real>
1336 inline const DiscreteType<Derived, Urng>
1337 discrete(Index rows, Index cols, Urng&& urng,
const std::initializer_list<Real>& il)
1357 template<
typename Derived,
typename Urng,
typename Real>
1358 inline const DiscreteType<Derived, Urng>
1359 discreteLike(Derived& o, Urng&& urng,
const std::initializer_list<Real>& il)
1366 template<
typename Derived,
typename Urng>
1367 using PoissonType = CwiseNullaryOp<internal::scalar_rng_adaptor<PoissonGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1382 template<
typename Derived,
typename Urng>
1383 inline const PoissonType<Derived, Urng>
1384 poisson(Index rows, Index cols, Urng&& urng,
double mean = 1)
1403 template<
typename Derived,
typename Urng>
1404 inline const PoissonType<Derived, Urng>
1412 template<
typename Derived,
typename Urng>
1413 using BinomialType = CwiseNullaryOp<internal::scalar_rng_adaptor<BinomialGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1429 template<
typename Derived,
typename Urng>
1430 inline const BinomialType<Derived, Urng>
1431 binomial(Index rows, Index cols, Urng&& urng,
typename Derived::Scalar trials = 1,
double p = 0.5)
1451 template<
typename Derived,
typename Urng>
1452 inline const BinomialType<Derived, Urng>
1453 binomialLike(Derived& o, Urng&& urng,
typename Derived::Scalar trials = 1,
double p = 0.5)
1460 template<
typename Derived,
typename Urng>
1461 using GeometricType = CwiseNullaryOp<internal::scalar_rng_adaptor<GeometricGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1476 template<
typename Derived,
typename Urng>
1477 inline const GeometricType<Derived, Urng>
1478 geometric(Index rows, Index cols, Urng&& urng,
double p = 0.5)
1497 template<
typename Derived,
typename Urng>
1498 inline const GeometricType<Derived, Urng>
Generator of integers on a binomial distribution.
Definition: Discrete.h:850
BinomialGen(_Scalar _trials=1, double _p=0.5)
Construct a new Binomial Generator.
Definition: Discrete.h:866
DiscreteGen(RealIter first, RealIter last)
Construct a new Discrete Generator.
Definition: Discrete.h:609
DiscreteGen(const std::initializer_list< Real > &il)
Construct a new Discrete Generator.
Definition: Discrete.h:642
DiscreteGen(RealIter first, RealIter last)
Construct a new Discrete Generator.
Definition: Discrete.h:492
DiscreteGen(const std::initializer_list< Real > &il)
Construct a new Discrete Generator.
Definition: Discrete.h:525
DiscreteGen(RealIter first, RealIter last)
Construct a new Discrete Generator.
Definition: Discrete.h:357
DiscreteGen(const std::initializer_list< Real > &il)
Construct a new Discrete Generator.
Definition: Discrete.h:390
Generator of integers on the interval [0, n), where the probability of each individual integer i is p...
Definition: Discrete.h:327
Base class of all univariate random generators.
Definition: Basic.h:33
Generator of integers on a geometric distribution.
Definition: Discrete.h:997
GeometricGen(double _p=0.5)
Construct a new Geometric Generator.
Definition: Discrete.h:1010
Generator of integers on a Poisson distribution.
Definition: Discrete.h:730
PoissonGen(double _mean=1)
Construct a new Poisson Generator.
Definition: Discrete.h:747
Generator of random bits for integral scalars.
Definition: Basic.h:248
const PoissonType< Derived, Urng > poissonLike(Derived &o, Urng &&urng, double mean=1)
generates reals on the Poisson distribution.
Definition: Discrete.h:1405
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:1106
const GeometricType< Derived, Urng > geometricLike(Derived &o, Urng &&urng, double p=0.5)
generates reals on the geometric distribution.
Definition: Discrete.h:1499
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:1453
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:1059
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:1221
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:1128
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:1080
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:1199
const PoissonType< Derived, Urng > poisson(Index rows, Index cols, Urng &&urng, double mean=1)
generates reals on the Poisson distribution.
Definition: Discrete.h:1384
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:1292
const GeometricType< Derived, Urng > geometric(Index rows, Index cols, Urng &&urng, double p=0.5)
generates reals on the geometric distribution.
Definition: Discrete.h:1478
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:1314
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:1431