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));
248 template<
typename Rng>
249 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
251 using namespace Eigen::internal;
252 auto rx = randbits(rng);
253 if (pdiff == bitmask)
255 return (_Scalar)(rx & bitmask) + pmin;
259 size_t bitcnt = bitsize;
262 _Scalar cands = (_Scalar)(rx & bitmask);
263 if (cands <= pdiff)
return cands;
264 if (bitcnt + bitsize < 32)
278 template<
typename Packet,
typename Rng>
279 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
281 using namespace Eigen::internal;
282 auto rx = randbits.template packetOp<Packet>(rng);
283 auto pbitmask = pset1<Packet>(bitmask);
284 if (pdiff == bitmask)
286 return padd(pand(rx, pbitmask), pset1<Packet>(pmin));
290 auto& cm = Rand::detail::CompressMask<
sizeof(Packet)>::get_inst();
291 auto plen = pset1<Packet>(pdiff + 1);
292 size_t bitcnt = bitsize;
296 auto cands = pand(rx, pbitmask);
298 cache_rest_cnt = cm.compress_append(cands, pcmplt(cands, plen),
299 OptCacheStore::template get<Packet>(), cache_rest_cnt, full);
300 if (full)
return padd(cands, pset1<Packet>(pmin));
302 if (bitcnt + bitsize < 32)
304 rx = psrl(rx, bitsize);
309 rx = randbits.template packetOp<Packet>(rng);
323 template<
typename _Scalar,
typename Precision =
float>
331 template<
typename _Scalar>
334 static_assert(std::is_same<_Scalar, int32_t>::value,
"discreteDist needs integral types.");
335 #ifdef EIGEN_VECTORIZE_AVX2
340 std::vector<uint32_t> cdf;
341 AliasMethod<int32_t, _Scalar> alias_table;
344 using Scalar = _Scalar;
353 template<
typename RealIter>
356 if (std::distance(first, last) < 16)
359 std::vector<double> _cdf;
361 for (; first != last; ++first)
363 _cdf.emplace_back(acc += *first);
368 cdf.emplace_back((uint32_t)(p / _cdf.back() * 0x80000000));
374 alias_table = AliasMethod<int32_t, _Scalar>{ first, last };
385 template<
typename Real,
386 typename std::enable_if<std::is_arithmetic<Real>::value,
int>::type = 0>
392 template<
typename Rng>
393 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
395 using namespace Eigen::internal;
398 auto rx = randbits(std::forward<Rng>(rng)) & 0x7FFFFFFF;
399 return (_Scalar)(std::lower_bound(cdf.begin(), cdf.end() - 1, rx) - cdf.begin());
403 auto rx = randbits(std::forward<Rng>(rng));
404 auto albit = rx & alias_table.get_bitmask();
405 uint32_t alx = (uint32_t)(rx >> (
sizeof(rx) * 8 - 31));
406 if (alx < alias_table.get_prob()[albit])
return albit;
407 return alias_table.get_alias()[albit];
411 template<
typename Packet,
typename Rng>
412 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
414 using namespace Eigen::internal;
415 #ifdef EIGEN_VECTORIZE_AVX2
419 return cache.template get<Packet>();
421 using PacketType = Packet8i;
423 using PacketType = Packet;
429 ret = pset1<PacketType>(cdf.size() - 1);
430 auto rx = pand(randbits.template packetOp<PacketType>(std::forward<Rng>(rng)), pset1<PacketType>(0x7FFFFFFF));
431 for (
size_t i = 0; i < cdf.size() - 1; ++i)
433 ret = padd(ret, pcmplt(rx, pset1<PacketType>(cdf[i])));
438 auto rx = randbits.template packetOp<PacketType>(std::forward<Rng>(rng));
439 auto albit = pand(rx, pset1<PacketType>(alias_table.get_bitmask()));
440 auto c = pcmplt(psrl(rx, 1), pgather(alias_table.get_prob(), albit));
441 ret = pblendv(c, albit, pgather(alias_table.get_alias(), albit));
444 #ifdef EIGEN_VECTORIZE_AVX2
446 cache.template get<Packet>() = _mm256_extractf128_si256(ret, 1);
447 return _mm256_extractf128_si256(ret, 0);
459 template<
typename _Scalar>
462 static_assert(std::is_same<_Scalar, int32_t>::value,
"discreteDist needs integral types.");
464 std::vector<float> cdf;
465 AliasMethod<float, _Scalar> alias_table;
468 using Scalar = _Scalar;
477 template<
typename RealIter>
480 if (std::distance(first, last) < 16)
483 std::vector<double> _cdf;
485 for (; first != last; ++first)
487 _cdf.emplace_back(acc += *first);
492 cdf.emplace_back(p / _cdf.back());
498 alias_table = AliasMethod<float, _Scalar>{ first, last };
509 template<
typename Real,
510 typename std::enable_if<std::is_arithmetic<Real>::value,
int>::type = 0>
516 template<
typename Rng>
517 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
519 using namespace Eigen::internal;
522 auto rx = ur(std::forward<Rng>(rng));
523 return (_Scalar)(std::lower_bound(cdf.begin(), cdf.end() - 1, rx) - cdf.begin());
527 auto albit = pfirst(rng()) & alias_table.get_bitmask();
529 if (alx < alias_table.get_prob()[albit])
return albit;
530 return alias_table.get_alias()[albit];
534 template<
typename Packet,
typename Rng>
535 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
537 using namespace Eigen::internal;
538 using PacketType = decltype(reinterpret_to_float(std::declval<Packet>()));
542 auto ret = pset1<Packet>(cdf.size());
543 auto rx = ur.template packetOp<PacketType>(std::forward<Rng>(rng));
546 ret = padd(ret, reinterpret_to_int(pcmplt(rx, pset1<PacketType>(p))));
552 using RUtils = RawbitsMaker<Packet, Rng>;
553 auto albit = pand(RUtils{}.rawbits(rng), pset1<Packet>(alias_table.get_bitmask()));
554 auto c = reinterpret_to_int(pcmplt(ur.template packetOp<PacketType>(rng), pgather(alias_table.get_prob(), albit)));
555 return pblendv(c, albit, pgather(alias_table.get_alias(), albit));
565 template<
typename _Scalar>
568 static_assert(std::is_same<_Scalar, int32_t>::value,
"discreteDist needs integral types.");
570 std::vector<double> cdf;
571 AliasMethod<double, _Scalar> alias_table;
574 using Scalar = _Scalar;
583 template<
typename RealIter>
586 if (std::distance(first, last) < 16)
589 std::vector<double> _cdf;
591 for (; first != last; ++first)
593 _cdf.emplace_back(acc += *first);
598 cdf.emplace_back(p / _cdf.back());
604 alias_table = AliasMethod<double, _Scalar>{ first, last };
615 template<
typename Real,
616 typename std::enable_if<std::is_arithmetic<Real>::value,
int>::type = 0>
622 template<
typename Rng>
623 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
625 using namespace Eigen::internal;
628 auto rx = ur(std::forward<Rng>(rng));
629 return (_Scalar)(std::lower_bound(cdf.begin(), cdf.end() - 1, rx) - cdf.begin());
633 auto albit = pfirst(rng()) & alias_table.get_bitmask();
635 if (alx < alias_table.get_prob()[albit])
return albit;
636 return alias_table.get_alias()[albit];
640 template<
typename Packet,
typename Rng>
641 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
643 using namespace Eigen::internal;
644 using DPacket = decltype(reinterpret_to_double(std::declval<Packet>()));
647 auto ret = pset1<Packet>(cdf.size());
648 #ifdef EIGEN_VECTORIZE_AVX
649 auto rx = ur.template packetOp<Packet4d>(std::forward<Rng>(rng));
652 auto c = reinterpret_to_int(pcmplt(rx, pset1<decltype(rx)>(p)));
653 auto r = combine_low32(c);
657 auto rx1 = ur.template packetOp<DPacket>(rng),
658 rx2 = ur.template packetOp<DPacket>(rng);
661 auto pp = pset1<decltype(rx1)>(p);
662 ret = padd(ret, combine_low32(reinterpret_to_int(pcmplt(rx1, pp)), reinterpret_to_int(pcmplt(rx2, pp))));
669 #ifdef EIGEN_VECTORIZE_AVX
670 using RUtils = RawbitsMaker<Packet, Rng>;
671 auto albit = pand(RUtils{}.rawbits(rng), pset1<Packet>(alias_table.get_bitmask()));
672 auto c = reinterpret_to_int(pcmplt(ur.template packetOp<Packet4d>(rng), pgather(alias_table.get_prob(), _mm256_castsi128_si256(albit))));
673 return pblendv(combine_low32(c), albit, pgather(alias_table.get_alias(), albit));
675 using RUtils = RawbitsMaker<Packet, Rng>;
676 auto albit = pand(RUtils{}.rawbits(rng), pset1<Packet>(alias_table.get_bitmask()));
677 auto c1 = reinterpret_to_int(pcmplt(ur.template packetOp<DPacket>(rng), pgather(alias_table.get_prob(), albit)));
678 auto c2 = reinterpret_to_int(pcmplt(ur.template packetOp<DPacket>(rng), pgather(alias_table.get_prob(), albit,
true)));
679 return pblendv(combine_low32(c1, c2), albit, pgather(alias_table.get_alias(), albit));
685 template<
typename>
class BinomialGen;
692 template<
typename _Scalar>
696 static_assert(std::is_same<_Scalar, int32_t>::value,
"poisson needs integral types.");
697 int cache_rest_cnt = 0;
701 double mean, ne_mean, sqrt_tmean, log_mean, g1;
704 using Scalar = _Scalar;
712 : mean{ _mean }, ne_mean{ std::exp(-_mean) }
714 sqrt_tmean = std::sqrt(2 * mean);
715 log_mean = std::log(mean);
716 g1 = mean * log_mean - std::lgamma(mean + 1);
719 template<
typename Rng>
720 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
722 using namespace Eigen::internal;
730 if (val <= ne_mean)
break;
740 yx = std::tan(constant::pi * ur(rng));
741 res = (_Scalar)(sqrt_tmean * yx + mean);
742 if (res >= 0 && ur(rng) <= 0.9 * (1.0 + yx * yx)
743 * std::exp(res * log_mean - std::lgamma(res + 1.0) - g1))
751 template<
typename Packet,
typename Rng>
752 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
754 using namespace Eigen::internal;
755 using PacketType = decltype(reinterpret_to_float(std::declval<Packet>()));
759 Packet res = pset1<Packet>(0);
760 PacketType val = pset1<PacketType>(1), pne_mean = pset1<PacketType>(ne_mean);
763 val = pmul(val, ur.template packetOp<PacketType>(rng));
764 auto c = reinterpret_to_int(pcmplt(pne_mean, val));
765 if (pmovemask(c) == 0)
break;
766 res = padd(res, pnegate(c));
772 auto& cm = Rand::detail::CompressMask<
sizeof(Packet)>::get_inst();
773 const PacketType ppi = pset1<PacketType>(constant::pi),
774 psqrt_tmean = pset1<PacketType>(sqrt_tmean),
775 pmean = pset1<PacketType>(mean),
776 plog_mean = pset1<PacketType>(log_mean),
777 pg1 = pset1<PacketType>(g1);
780 PacketType fres, yx, psin, pcos;
781 psincos(pmul(ppi, ur.template packetOp<PacketType>(rng)), psin, pcos);
782 yx = pdiv(psin, pcos);
783 fres = ptruncate(padd(pmul(psqrt_tmean, yx), pmean));
785 auto p1 = pmul(padd(pmul(yx, yx), pset1<PacketType>(1)), pset1<PacketType>(0.9));
786 auto p2 = pexp(psub(psub(pmul(fres, plog_mean), plgamma(padd(fres, pset1<PacketType>(1)))), pg1));
788 auto c1 = pcmple(pset1<PacketType>(0), fres);
789 auto c2 = pcmple(ur.template packetOp<PacketType>(rng), pmul(p1, p2));
793 cache_rest_cnt = cm.compress_append(cands, pand(c1, c2),
794 OptCacheStore::template get<PacketType>(), cache_rest_cnt, full);
795 if (full)
return pcast<PacketType, Packet>(cands);
806 template<
typename _Scalar>
809 static_assert(std::is_same<_Scalar, int32_t>::value,
"binomial needs integral types.");
813 double p, small_p, g1, sqrt_v, log_small_p, log_small_q;
816 using Scalar = _Scalar;
825 :
poisson{ _trials * std::min(_p, 1 - _p) },
826 trials{ _trials }, p{ _p }, small_p{ std::min(p, 1 - p) }
829 if (!(trials < 25 ||
poisson.mean < 1.0))
831 g1 = std::lgamma(trials + 1);
832 sqrt_v = std::sqrt(2 *
poisson.mean * (1 - small_p));
833 log_small_p = std::log(small_p);
834 log_small_q = std::log(1 - small_p);
838 template<
typename Rng>
839 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
841 using namespace Eigen::internal;
846 for (
int i = 0; i < trials; ++i)
848 if (
poisson.ur(rng) < p) ++res;
861 ys = std::tan(constant::pi *
poisson.ur(rng));
862 res = (_Scalar)(sqrt_v * ys +
poisson.mean);
863 if (0 <= res && res <= trials &&
poisson.ur(rng) <= 1.2 * sqrt_v
865 * std::exp(g1 - std::lgamma(res + 1)
866 - std::lgamma(trials - res + 1.0)
868 + (trials - res) * log_small_q)
875 return p == small_p ? res : trials - res;
878 template<
typename Packet,
typename Rng>
879 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
881 using namespace Eigen::internal;
882 using PacketType = decltype(reinterpret_to_float(std::declval<Packet>()));
886 PacketType pp = pset1<PacketType>(p);
887 res = pset1<Packet>(trials);
888 for (
int i = 0; i < trials; ++i)
890 auto c = reinterpret_to_int(pcmple(pp,
poisson.ur.template packetOp<PacketType>(rng)));
897 res =
poisson.template packetOp<Packet>(rng);
901 auto& cm = Rand::detail::CompressMask<
sizeof(Packet)>::get_inst();
902 const PacketType ppi = pset1<PacketType>(constant::pi),
903 ptrials = pset1<PacketType>(trials),
904 psqrt_v = pset1<PacketType>(sqrt_v),
905 pmean = pset1<PacketType>(
poisson.mean),
906 plog_small_p = pset1<PacketType>(log_small_p),
907 plog_small_q = pset1<PacketType>(log_small_q),
908 pg1 = pset1<PacketType>(g1);
911 PacketType fres, ys, psin, pcos;
912 psincos(pmul(ppi,
poisson.ur.template packetOp<PacketType>(rng)), psin, pcos);
913 ys = pdiv(psin, pcos);
914 fres = ptruncate(padd(pmul(psqrt_v, ys), pmean));
916 auto p1 = pmul(pmul(pset1<PacketType>(1.2), psqrt_v), padd(pset1<PacketType>(1), pmul(ys, ys)));
919 psub(pg1, plgamma(padd(fres, pset1<PacketType>(1)))),
920 plgamma(psub(padd(ptrials, pset1<PacketType>(1)), fres))
921 ), pmul(fres, plog_small_p)), pmul(psub(ptrials, fres), plog_small_q))
924 auto c1 = pand(pcmple(pset1<PacketType>(0), fres), pcmple(fres, ptrials));
925 auto c2 = pcmple(
poisson.ur.template packetOp<PacketType>(rng), pmul(p1, p2));
929 poisson.cache_rest_cnt = cm.compress_append(cands, pand(c1, c2),
930 poisson.template get<PacketType>(),
poisson.cache_rest_cnt, full);
933 res = pcast<PacketType, Packet>(cands);
938 return p == small_p ? res : psub(pset1<Packet>(trials), res);
947 template<
typename _Scalar>
950 static_assert(std::is_same<_Scalar, int32_t>::value,
"geomtric needs integral types.");
955 using Scalar = _Scalar;
963 : p{ _p }, rlog_q{ 1 / std::log(1 - p) }
967 template<
typename Rng>
968 EIGEN_STRONG_INLINE
const _Scalar operator() (Rng&& rng)
970 using namespace Eigen::internal;
971 return (_Scalar)(std::log(1 - ur(std::forward<Rng>(rng))) * rlog_q);
974 template<
typename Packet,
typename Rng>
975 EIGEN_STRONG_INLINE
const Packet packetOp(Rng&& rng)
977 using namespace Eigen::internal;
978 using PacketType = decltype(reinterpret_to_float(std::declval<Packet>()));
980 return pcast<PacketType, Packet>(ptruncate(pmul(plog(
981 psub(pset1<PacketType>(1), ur.template packetOp<PacketType>(std::forward<Rng>(rng)))
982 ), pset1<PacketType>(rlog_q))));
987 template<
typename Derived,
typename Urng>
988 using UniformIntType = CwiseNullaryOp<internal::scalar_rng_adaptor<UniformIntGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1003 template<
typename Derived,
typename Urng>
1004 inline const UniformIntType<Derived, Urng>
1005 uniformInt(Index rows, Index cols, Urng&& urng,
typename Derived::Scalar min,
typename Derived::Scalar max)
1024 template<
typename Derived,
typename Urng>
1025 inline const UniformIntType<Derived, Urng>
1026 uniformIntLike(Derived& o, Urng&& urng,
typename Derived::Scalar min,
typename Derived::Scalar max)
1033 template<
typename Derived,
typename Urng>
1034 using DiscreteFType = CwiseNullaryOp<internal::scalar_rng_adaptor<DiscreteGen<typename Derived::Scalar, float>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1050 template<
typename Derived,
typename Urng,
typename RealIter>
1051 inline const DiscreteFType<Derived, Urng>
1052 discreteF(Index rows, Index cols, Urng&& urng, RealIter first, RealIter last)
1072 template<
typename Derived,
typename Urng,
typename RealIter>
1073 inline const DiscreteFType<Derived, Urng>
1095 template<
typename Derived,
typename Urng,
typename Real>
1096 inline const DiscreteFType<Derived, Urng>
1097 discreteF(Index rows, Index cols, Urng&& urng,
const std::initializer_list<Real>& il)
1117 template<
typename Derived,
typename Urng,
typename Real>
1118 inline const DiscreteFType<Derived, Urng>
1126 template<
typename Derived,
typename Urng>
1127 using DiscreteDType = CwiseNullaryOp<internal::scalar_rng_adaptor<DiscreteGen<typename Derived::Scalar, double>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1143 template<
typename Derived,
typename Urng,
typename RealIter>
1144 inline const DiscreteDType<Derived, Urng>
1145 discreteD(Index rows, Index cols, Urng&& urng, RealIter first, RealIter last)
1165 template<
typename Derived,
typename Urng,
typename RealIter>
1166 inline const DiscreteDType<Derived, Urng>
1188 template<
typename Derived,
typename Urng,
typename Real>
1189 inline const DiscreteDType<Derived, Urng>
1190 discreteD(Index rows, Index cols, Urng&& urng,
const std::initializer_list<Real>& il)
1210 template<
typename Derived,
typename Urng,
typename Real>
1211 inline const DiscreteDType<Derived, Urng>
1219 template<
typename Derived,
typename Urng>
1220 using DiscreteType = CwiseNullaryOp<internal::scalar_rng_adaptor<DiscreteGen<typename Derived::Scalar, int32_t>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1236 template<
typename Derived,
typename Urng,
typename RealIter>
1237 inline const DiscreteType<Derived, Urng>
1238 discrete(Index rows, Index cols, Urng&& urng, RealIter first, RealIter last)
1258 template<
typename Derived,
typename Urng,
typename RealIter>
1259 inline const DiscreteType<Derived, Urng>
1281 template<
typename Derived,
typename Urng,
typename Real>
1282 inline const DiscreteType<Derived, Urng>
1283 discrete(Index rows, Index cols, Urng&& urng,
const std::initializer_list<Real>& il)
1303 template<
typename Derived,
typename Urng,
typename Real>
1304 inline const DiscreteType<Derived, Urng>
1305 discreteLike(Derived& o, Urng&& urng,
const std::initializer_list<Real>& il)
1312 template<
typename Derived,
typename Urng>
1313 using PoissonType = CwiseNullaryOp<internal::scalar_rng_adaptor<PoissonGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1328 template<
typename Derived,
typename Urng>
1329 inline const PoissonType<Derived, Urng>
1330 poisson(Index rows, Index cols, Urng&& urng,
double mean = 1)
1349 template<
typename Derived,
typename Urng>
1350 inline const PoissonType<Derived, Urng>
1358 template<
typename Derived,
typename Urng>
1359 using BinomialType = CwiseNullaryOp<internal::scalar_rng_adaptor<BinomialGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1375 template<
typename Derived,
typename Urng>
1376 inline const BinomialType<Derived, Urng>
1377 binomial(Index rows, Index cols, Urng&& urng,
typename Derived::Scalar trials = 1,
double p = 0.5)
1397 template<
typename Derived,
typename Urng>
1398 inline const BinomialType<Derived, Urng>
1399 binomialLike(Derived& o, Urng&& urng,
typename Derived::Scalar trials = 1,
double p = 0.5)
1406 template<
typename Derived,
typename Urng>
1407 using GeometricType = CwiseNullaryOp<internal::scalar_rng_adaptor<GeometricGen<typename Derived::Scalar>,
typename Derived::Scalar, Urng,
true>,
const Derived>;
1422 template<
typename Derived,
typename Urng>
1423 inline const GeometricType<Derived, Urng>
1424 geometric(Index rows, Index cols, Urng&& urng,
double p = 0.5)
1443 template<
typename Derived,
typename Urng>
1444 inline const GeometricType<Derived, Urng>