EigenRand  0.5.0
 
Loading...
Searching...
No Matches
NormalExp.h
Go to the documentation of this file.
1
13#ifndef EIGENRAND_DISTS_NORMAL_EXP_H
14#define EIGENRAND_DISTS_NORMAL_EXP_H
15
16namespace Eigen
17{
18 namespace Rand
19 {
25 template<typename _Scalar>
26 class StdNormalGen : OptCacheStore, public GenBase<StdNormalGen<_Scalar>, _Scalar>
27 {
28 static_assert(std::is_floating_point<_Scalar>::value, "normalDist needs floating point types.");
29 bool valid = false;
31
32 public:
33 using Scalar = _Scalar;
34
35 template<typename Rng>
36 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
37 {
38 using namespace Eigen::internal;
39 if (valid)
40 {
41 valid = false;
42 return OptCacheStore::get<_Scalar>();
43 }
44 valid = true;
45
46 _Scalar v1, v2, sx;
47 for (int _i = 0; ; ++_i)
48 {
49 EIGENRAND_CHECK_INFINITY_LOOP();
50 v1 = 2 * ur(rng) - 1;
51 v2 = 2 * ur(rng) - 1;
52 sx = v1 * v1 + v2 * v2;
53 if (sx && sx < 1) break;
54 }
55 _Scalar fx = std::sqrt((_Scalar)-2.0 * std::log(sx) / sx);
56 OptCacheStore::get<_Scalar>() = fx * v2;
57 return fx * v1;
58 }
59
60 template<typename Packet, typename Rng>
61 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
62 {
63 using namespace Eigen::internal;
64 if (valid)
65 {
66 valid = false;
67 return OptCacheStore::template get<Packet>();
68 }
69 valid = true;
70 Packet u1 = ur.template packetOp<Packet>(rng),
71 u2 = ur.template packetOp<Packet>(rng);
72
73 u1 = psub(pset1<Packet>(1), u1);
74
75 auto radius = psqrt(pmul(pset1<Packet>(-2), plog(u1)));
76 auto theta = pmul(pset1<Packet>(2 * constant::pi), u2);
77 Packet sintheta, costheta;
78
79 psincos(theta, sintheta, costheta);
80 OptCacheStore::template get<Packet>() = pmul(radius, costheta);
81 return pmul(radius, sintheta);
82 }
83 };
84
90 template<typename _Scalar>
91 class NormalGen : public GenBase<NormalGen<_Scalar>, _Scalar>
92 {
93 static_assert(std::is_floating_point<_Scalar>::value, "normalDist needs floating point types.");
95 _Scalar mean = 0, stdev = 1;
96
97 public:
98 using Scalar = _Scalar;
99
106 NormalGen(_Scalar _mean = 0, _Scalar _stdev = 1)
107 : mean{ _mean }, stdev{ _stdev }
108 {
109 }
110
111 NormalGen(const NormalGen&) = default;
112 NormalGen(NormalGen&&) = default;
113
114 NormalGen& operator=(const NormalGen&) = default;
115 NormalGen& operator=(NormalGen&&) = default;
116
117 template<typename Rng>
118 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
119 {
120 using namespace Eigen::internal;
121 return stdnorm(std::forward<Rng>(rng)) * stdev + mean;
122 }
123
124 template<typename Packet, typename Rng>
125 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
126 {
127 using namespace Eigen::internal;
128 return padd(pmul(
129 stdnorm.template packetOp<Packet>(std::forward<Rng>(rng)),
130 pset1<Packet>(stdev)
131 ), pset1<Packet>(mean));
132 }
133 };
134
135 template<typename _Scalar>
136 class NormalVGen : public BinaryGenBase<NormalVGen<_Scalar>, _Scalar, _Scalar, _Scalar>
137 {
138 static_assert(std::is_floating_point<_Scalar>::value, "normalDist needs floating point types.");
139 StdNormalGen<_Scalar> stdnorm;
140
141 public:
142 using Scalar = _Scalar;
143
144 template<typename Rng>
145 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng, _Scalar mean, _Scalar stdev)
146 {
147 using namespace Eigen::internal;
148 return stdnorm(std::forward<Rng>(rng)) * stdev + mean;
149 }
150
151 template<typename Packet, typename Rng>
152 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng, const Packet& mean, const Packet& stdev)
153 {
154 using namespace Eigen::internal;
155 return padd(pmul(
156 stdnorm.template packetOp<Packet>(std::forward<Rng>(rng)),
157 stdev
158 ), mean);
159 }
160 };
161
167 template<typename _Scalar>
168 class LognormalGen : public GenBase<LognormalGen<_Scalar>, _Scalar>
169 {
170 static_assert(std::is_floating_point<_Scalar>::value, "lognormalDist needs floating point types.");
172
173 public:
174 using Scalar = _Scalar;
175
182 LognormalGen(_Scalar _mean = 0, _Scalar _stdev = 1)
183 : norm{ _mean, _stdev }
184 {
185 }
186
187 LognormalGen(const LognormalGen&) = default;
188 LognormalGen(LognormalGen&&) = default;
189
190 LognormalGen& operator=(const LognormalGen&) = default;
191 LognormalGen& operator=(LognormalGen&&) = default;
192
193 template<typename Rng>
194 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
195 {
196 using namespace Eigen::internal;
197 return std::exp(norm(std::forward<Rng>(rng)));
198 }
199
200 template<typename Packet, typename Rng>
201 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
202 {
203 using namespace Eigen::internal;
204 return pexp(norm.template packetOp<Packet>(std::forward<Rng>(rng)));
205 }
206 };
207
208 template<typename _Scalar>
209 class LognormalVGen : public BinaryGenBase<LognormalVGen<_Scalar>, _Scalar, _Scalar, _Scalar>
210 {
211 static_assert(std::is_floating_point<_Scalar>::value, "lognormalDist needs floating point types.");
212 NormalVGen<_Scalar> norm;
213
214 public:
215 using Scalar = _Scalar;
216
217 template<typename Rng>
218 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng, _Scalar mean, _Scalar stdev)
219 {
220 using namespace Eigen::internal;
221 return std::exp(norm(std::forward<Rng>(rng), mean, stdev));
222 }
223
224 template<typename Packet, typename Rng>
225 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng, const Packet& mean, const Packet& stdev)
226 {
227 using namespace Eigen::internal;
228 return pexp(norm.template packetOp<Packet>(std::forward<Rng>(rng), mean, stdev));
229 }
230 };
231
237 template<typename _Scalar>
238 class StudentTGen : public GenBase<StudentTGen<_Scalar>, _Scalar>
239 {
240 static_assert(std::is_floating_point<_Scalar>::value, "studentT needs floating point types.");
242 _Scalar n;
243
244 public:
245 using Scalar = _Scalar;
246
252 StudentTGen(_Scalar _n = 1)
253 : n{ _n }
254 {
255 }
256
257 StudentTGen(const StudentTGen&) = default;
258 StudentTGen(StudentTGen&&) = default;
259
260 StudentTGen& operator=(const StudentTGen&) = default;
261 StudentTGen& operator=(StudentTGen&&) = default;
262
263 template<typename Rng>
264 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
265 {
266 using namespace Eigen::internal;
267 _Scalar v1, v2, sx;
268 for (int _i = 0; ; ++_i)
269 {
270 EIGENRAND_CHECK_INFINITY_LOOP();
271 v1 = 2 * ur(rng) - 1;
272 v2 = 2 * ur(rng) - 1;
273 sx = v1 * v1 + v2 * v2;
274 if (sx && sx < 1) break;
275 }
276
277 _Scalar fx = std::sqrt(n * (std::pow(sx, -2 / n) - 1) / sx);
278 return fx * v1;
279 }
280
281 template<typename Packet, typename Rng>
282 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
283 {
284 using namespace Eigen::internal;
285 Packet u1 = ur.template packetOp<Packet>(rng),
286 u2 = ur.template packetOp<Packet>(rng);
287
288 u1 = psub(pset1<Packet>(1), u1);
289 auto pn = pset1<Packet>(n);
290 auto radius = psqrt(pmul(pn,
291 psub(pexp(pmul(plog(u1), pset1<Packet>(-2 / n))), pset1<Packet>(1))
292 ));
293 auto theta = pmul(pset1<Packet>(2 * constant::pi), u2);
294 //Packet sintheta, costheta;
295 //psincos(theta, sintheta, costheta);
296 return pmul(radius, psin(theta));
297 }
298 };
299
300 template<typename _Scalar>
301 class StudentTVGen : public UnaryGenBase<StudentTVGen<_Scalar>, _Scalar, _Scalar>
302 {
303 static_assert(std::is_floating_point<_Scalar>::value, "studentT needs floating point types.");
304 StdUniformRealGen<_Scalar> ur;
305
306 public:
307 using Scalar = _Scalar;
308
309 template<typename Rng>
310 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng, _Scalar n)
311 {
312 using namespace Eigen::internal;
313 _Scalar v1, v2, sx;
314 for (int _i = 0; ; ++_i)
315 {
316 EIGENRAND_CHECK_INFINITY_LOOP();
317 v1 = 2 * ur(rng) - 1;
318 v2 = 2 * ur(rng) - 1;
319 sx = v1 * v1 + v2 * v2;
320 if (sx && sx < 1) break;
321 }
322
323 _Scalar fx = std::sqrt(n * (std::pow(sx, -2 / n) - 1) / sx);
324 return fx * v1;
325 }
326
327 template<typename Packet, typename Rng>
328 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng, const Packet& n)
329 {
330 using namespace Eigen::internal;
331 Packet u1 = ur.template packetOp<Packet>(rng),
332 u2 = ur.template packetOp<Packet>(rng);
333
334 u1 = psub(pset1<Packet>(1), u1);
335 auto radius = psqrt(pmul(n,
336 psub(pexp(pmul(plog(u1), pdiv(pset1<Packet>(-2), n))), pset1<Packet>(1))
337 ));
338 auto theta = pmul(pset1<Packet>(2 * constant::pi), u2);
339 //Packet sintheta, costheta;
340 //psincos(theta, sintheta, costheta);
341 return pmul(radius, psin(theta));
342 }
343 };
344
345 template<typename> class GammaGen;
346
352 template<typename _Scalar>
353 class ExponentialGen : public GenBase<ExponentialGen<_Scalar>, _Scalar>
354 {
355 friend GammaGen<_Scalar>;
356 static_assert(std::is_floating_point<_Scalar>::value, "expDist needs floating point types.");
358 _Scalar lambda = 1;
359
360 public:
361 using Scalar = _Scalar;
362
368 ExponentialGen(_Scalar _lambda = 1)
369 : lambda{ _lambda }
370 {
371 }
372
373 ExponentialGen(const ExponentialGen&) = default;
374 ExponentialGen(ExponentialGen&&) = default;
375
376 ExponentialGen& operator=(const ExponentialGen&) = default;
377 ExponentialGen& operator=(ExponentialGen&&) = default;
378
379 template<typename Rng>
380 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
381 {
382 using namespace Eigen::internal;
383 return -std::log(1 - ur(std::forward<Rng>(rng))) / lambda;
384 }
385
386 template<typename Packet, typename Rng>
387 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
388 {
389 using namespace Eigen::internal;
390 return pnegate(pdiv(plog(
391 psub(pset1<Packet>(1), ur.template packetOp<Packet>(std::forward<Rng>(rng)))
392 ), pset1<Packet>(lambda)));
393 }
394 };
395
396 template<typename _Scalar>
397 class ExponentialVGen : public UnaryGenBase<ExponentialVGen<_Scalar>, _Scalar, _Scalar>
398 {
399 static_assert(std::is_floating_point<_Scalar>::value, "expDist needs floating point types.");
400 StdUniformRealGen<_Scalar> ur;
401
402 public:
403 using Scalar = _Scalar;
404
405 template<typename Rng>
406 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng, _Scalar lambda)
407 {
408 using namespace Eigen::internal;
409 return -std::log(1 - ur(std::forward<Rng>(rng))) / lambda;
410 }
411
412 template<typename Packet, typename Rng>
413 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng, const Packet& lambda)
414 {
415 using namespace Eigen::internal;
416 return pnegate(pdiv(plog(
417 psub(pset1<Packet>(1), ur.template packetOp<Packet>(std::forward<Rng>(rng)))
418 ), lambda));
419 }
420 };
421
422 template<typename> class NegativeBinomialGen;
423
429 template<typename _Scalar>
430 class GammaGen : OptCacheStore, public GenBase<GammaGen<_Scalar>, _Scalar>
431 {
432 template<typename _Ty>
433 friend class NegativeBinomialGen;
434 static_assert(std::is_floating_point<_Scalar>::value, "gammaDist needs floating point types.");
435 int cache_rest_cnt = 0;
437 _Scalar alpha, beta, px, sqrt;
438
439 public:
440 using Scalar = _Scalar;
441
448 GammaGen(_Scalar _alpha = 1, _Scalar _beta = 1)
449 : alpha{ _alpha }, beta{ _beta }
450 {
451 px = (_Scalar)(constant::e / (alpha + constant::e));
452 sqrt = std::sqrt(2 * alpha - 1);
453 }
454
455 GammaGen(const GammaGen&) = default;
456 GammaGen(GammaGen&&) = default;
457
458 GammaGen& operator=(const GammaGen&) = default;
459 GammaGen& operator=(GammaGen&&) = default;
460
461 template<typename Rng>
462 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
463 {
464 using namespace Eigen::internal;
465 if (alpha < 1)
466 {
467 _Scalar ux, vx, xx, qx;
468 for (int _i = 0; ; ++_i)
469 {
470 EIGENRAND_CHECK_INFINITY_LOOP();
471 ux = expon.ur(rng);
472 vx = expon.ur.nzur_scalar(rng);
473
474 if (ux < px)
475 {
476 xx = std::pow(vx, 1 / alpha);
477 qx = std::exp(-xx);
478 }
479 else
480 {
481 xx = 1 - std::log(vx);
482 qx = std::pow(xx, alpha - 1);
483 }
484
485 if (expon.ur(rng) < qx)
486 {
487 return beta * xx;
488 }
489 }
490 }
491 if (alpha == 1)
492 {
493 return beta * expon(rng);
494 }
495 int count;
496 if ((count = alpha) == alpha && count < 20)
497 {
498 _Scalar yx;
499 yx = expon.ur.nzur_scalar(rng);
500 while (--count)
501 {
502 yx *= expon.ur.nzur_scalar(rng);
503 }
504 return -beta * std::log(yx);
505 }
506
507 for (int _i = 0; ; ++_i)
508 {
509 EIGENRAND_CHECK_INFINITY_LOOP();
510 _Scalar yx, xx;
511 yx = std::tan(constant::pi * expon.ur(rng));
512 xx = sqrt * yx + alpha - 1;
513 if (xx <= 0) continue;
514 if (expon.ur(rng) <= (1 + yx * yx)
515 * std::exp((alpha - 1) * std::log(xx / (alpha - 1)) - sqrt * yx))
516 {
517 return beta * xx;
518 }
519 }
520 }
521
522 template<typename Packet, typename Rng>
523 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
524 {
525 using namespace Eigen::internal;
526 using RUtils = RandUtils<Packet, Rng>;
527 auto& cm = Rand::detail::CompressMask<sizeof(Packet)>::get_inst();
528
529 RUtils ru;
530 if (alpha < 1)
531 {
532 for (int _i = 0; ; ++_i)
533 {
534 EIGENRAND_CHECK_INFINITY_LOOP();
535 Packet ux = ru.uniform_real(rng);
536 Packet vx = ru.nonzero_uniform_real(rng);
537
538 Packet xx = pexp(pmul(pset1<Packet>(1 / alpha), plog(vx)));
539 Packet qx = pexp(pnegate(xx));
540
541 Packet xx2 = psub(pset1<Packet>(1), plog(vx));
542 Packet qx2 = pexp(pmul(plog(xx2), pset1<Packet>(alpha - 1)));
543
544 auto c = pcmplt(ux, pset1<Packet>(px));
545 xx = pblendv(c, xx, xx2);
546 qx = pblendv(c, qx, qx2);
547
548 ux = ru.uniform_real(rng);
549 Packet cands = pmul(pset1<Packet>(beta), xx);
550 bool full = false;
551 cache_rest_cnt = cm.compress_append(cands, pcmplt(ux, qx),
552 OptCacheStore::template get<Packet>(), cache_rest_cnt, full);
553 if (full) return cands;
554 }
555 }
556 if (alpha == 1)
557 {
558 return pmul(pset1<Packet>(beta),
559 expon.template packetOp<Packet>(rng)
560 );
561 }
562 int count;
563 if ((count = alpha) == alpha && count < 20)
564 {
565 RUtils ru;
566 Packet ux, yx;
567 yx = ru.nonzero_uniform_real(rng);
568 while (--count)
569 {
570 yx = pmul(yx, ru.nonzero_uniform_real(rng));
571 }
572 return pnegate(pmul(pset1<Packet>(beta), plog(yx)));
573 }
574 else
575 {
576 for (int _i = 0; ; ++_i)
577 {
578 EIGENRAND_CHECK_INFINITY_LOOP();
579 Packet alpha_1 = pset1<Packet>(alpha - 1);
580 Packet ys, yc;
581 psincos(pmul(pset1<Packet>(constant::pi), ru.uniform_real(rng)), ys, yc);
582 Packet yx = pdiv(ys, yc);
583 Packet xx = padd(pmul(pset1<Packet>(sqrt), yx), alpha_1);
584 auto c = pcmplt(pset1<Packet>(0), xx);
585 Packet ux = ru.uniform_real(rng);
586 Packet ub = pmul(padd(pmul(yx, yx), pset1<Packet>(1)),
587 pexp(psub(
588 pmul(alpha_1, plog(pdiv(xx, alpha_1))),
589 pmul(yx, pset1<Packet>(sqrt))
590 ))
591 );
592 c = pand(c, pcmple(ux, ub));
593 Packet cands = pmul(pset1<Packet>(beta), xx);
594 bool full = false;
595 cache_rest_cnt = cm.compress_append(cands, c,
596 OptCacheStore::template get<Packet>(), cache_rest_cnt, full);
597 if (full) return cands;
598 }
599 }
600 }
601 };
602
608 template<typename _Scalar>
609 class WeibullGen : public GenBase<WeibullGen<_Scalar>, _Scalar>
610 {
611 static_assert(std::is_floating_point<_Scalar>::value, "weilbullDist needs floating point types.");
613 _Scalar a = 1, b = 1;
614
615 public:
616 using Scalar = _Scalar;
617
624 WeibullGen(_Scalar _a = 1, _Scalar _b = 1)
625 : a{ _a }, b{ _b }
626 {
627 }
628
629 WeibullGen(const WeibullGen&) = default;
630 WeibullGen(WeibullGen&&) = default;
631
632 WeibullGen& operator=(const WeibullGen&) = default;
633 WeibullGen& operator=(WeibullGen&&) = default;
634
635 template<typename Rng>
636 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
637 {
638 using namespace Eigen::internal;
639 return std::pow(-std::log(1 - ur(std::forward<Rng>(rng))), 1 / a) * b;
640 }
641
642 template<typename Packet, typename Rng>
643 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
644 {
645 using namespace Eigen::internal;
646 return pmul(pexp(pmul(plog(pnegate(plog(
647 psub(pset1<Packet>(1), ur.template packetOp<Packet>(std::forward<Rng>(rng)))
648 ))), pset1<Packet>(1 / a))), pset1<Packet>(b));
649 }
650 };
651
652 template<typename _Scalar>
653 class WeibullVGen : public BinaryGenBase<WeibullGen<_Scalar>, _Scalar, _Scalar, _Scalar>
654 {
655 static_assert(std::is_floating_point<_Scalar>::value, "weilbullDist needs floating point types.");
656 StdUniformRealGen<_Scalar> ur;
657
658 public:
659 using Scalar = _Scalar;
660
661 template<typename Rng>
662 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng, _Scalar a, _Scalar b)
663 {
664 using namespace Eigen::internal;
665 return std::pow(-std::log(1 - ur(std::forward<Rng>(rng))), 1 / a) * b;
666 }
667
668 template<typename Packet, typename Rng>
669 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng, const Packet& a, const Packet& b)
670 {
671 using namespace Eigen::internal;
672 return pmul(pexp(pmul(plog(pnegate(plog(
673 psub(pset1<Packet>(1), ur.template packetOp<Packet>(std::forward<Rng>(rng)))
674 ))), pdiv(pset1<Packet>(1), a))), b);
675 }
676 };
677
683 template<typename _Scalar>
684 class ExtremeValueGen : public GenBase<ExtremeValueGen<_Scalar>, _Scalar>
685 {
686 static_assert(std::is_floating_point<_Scalar>::value, "extremeValueDist needs floating point types.");
688 _Scalar a = 0, b = 1;
689
690 public:
691 using Scalar = _Scalar;
692
699 ExtremeValueGen(_Scalar _a = 0, _Scalar _b = 1)
700 : a{ _a }, b{ _b }
701 {
702 }
703
704 ExtremeValueGen(const ExtremeValueGen&) = default;
705 ExtremeValueGen(ExtremeValueGen&&) = default;
706
707 ExtremeValueGen& operator=(const ExtremeValueGen&) = default;
708 ExtremeValueGen& operator=(ExtremeValueGen&&) = default;
709
710 template<typename Rng>
711 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
712 {
713 using namespace Eigen::internal;
714 return (a - b * std::log(-std::log(ur.nzur_scalar(std::forward<Rng>(rng)))));
715 }
716
717 template<typename Packet, typename Rng>
718 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
719 {
720 using namespace Eigen::internal;
721 using RUtils = RandUtils<Packet, Rng>;
722 return psub(pset1<Packet>(a),
723 pmul(plog(pnegate(plog(RUtils{}.nonzero_uniform_real(std::forward<Rng>(rng))))), pset1<Packet>(b))
724 );
725 }
726 };
727
728 template<typename _Scalar>
729 class ExtremeValueVGen : public BinaryGenBase<ExtremeValueVGen<_Scalar>, _Scalar, _Scalar, _Scalar>
730 {
731 static_assert(std::is_floating_point<_Scalar>::value, "extremeValueDist needs floating point types.");
732 StdUniformRealGen<_Scalar> ur;
733
734 public:
735 using Scalar = _Scalar;
736
737 template<typename Rng>
738 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng, _Scalar a, _Scalar b)
739 {
740 using namespace Eigen::internal;
741 return (a - b * std::log(-std::log(ur.nzur_scalar(std::forward<Rng>(rng)))));
742 }
743
744 template<typename Packet, typename Rng>
745 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng, const Packet& a, const Packet& b)
746 {
747 using namespace Eigen::internal;
748 using RUtils = RandUtils<Packet, Rng>;
749 return psub(a,
750 pmul(plog(pnegate(plog(RUtils{}.nonzero_uniform_real(std::forward<Rng>(rng))))), b)
751 );
752 }
753 };
754
760 template<typename _Scalar>
761 class ChiSquaredGen : public GenBase<ChiSquaredGen<_Scalar>, _Scalar>
762 {
763 static_assert(std::is_floating_point<_Scalar>::value, "chiSquaredDist needs floating point types.");
764 GammaGen<_Scalar> gamma;
765 public:
766 using Scalar = _Scalar;
767
773 ChiSquaredGen(_Scalar n = 1)
774 : gamma{ n * _Scalar(0.5), 2 }
775 {
776 }
777
778 ChiSquaredGen(const ChiSquaredGen&) = default;
779 ChiSquaredGen(ChiSquaredGen&&) = default;
780
781 ChiSquaredGen& operator=(const ChiSquaredGen&) = default;
782 ChiSquaredGen& operator=(ChiSquaredGen&&) = default;
783
784 template<typename Rng>
785 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
786 {
787 return gamma(rng);
788 }
789
790 template<typename Packet, typename Rng>
791 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
792 {
793 return gamma.template packetOp<Packet>(rng);
794 }
795 };
796
802 template<typename _Scalar>
803 class CauchyGen : public GenBase<CauchyGen<_Scalar>, _Scalar>
804 {
805 static_assert(std::is_floating_point<_Scalar>::value, "cauchyDist needs floating point types.");
807 _Scalar a = 0, b = 1;
808
809 public:
810 using Scalar = _Scalar;
811
818 CauchyGen(_Scalar _a = 0, _Scalar _b = 1)
819 : a{ _a }, b{ _b }
820 {
821 }
822
823 CauchyGen(const CauchyGen&) = default;
824 CauchyGen(CauchyGen&&) = default;
825
826 CauchyGen& operator=(const CauchyGen&) = default;
827 CauchyGen& operator=(CauchyGen&&) = default;
828
829 template<typename Rng>
830 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
831 {
832 using namespace Eigen::internal;
833 return a + b * std::tan(constant::pi * (ur(std::forward<Rng>(rng)) - 0.5));
834 }
835
836 template<typename Packet, typename Rng>
837 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
838 {
839 using namespace Eigen::internal;
840 Packet s, c;
841 psincos(pmul(pset1<Packet>(constant::pi),
842 psub(ur.template packetOp<Packet>(std::forward<Rng>(rng)), pset1<Packet>(0.5))
843 ), s, c);
844 return padd(pset1<Packet>(a),
845 pmul(pset1<Packet>(b), pdiv(s, c))
846 );
847 }
848 };
849
850 template<typename _Scalar>
851 class CauchyVGen : public BinaryGenBase<CauchyVGen<_Scalar>, _Scalar, _Scalar, _Scalar>
852 {
853 static_assert(std::is_floating_point<_Scalar>::value, "cauchyDist needs floating point types.");
854 StdUniformRealGen<_Scalar> ur;
855
856 public:
857 using Scalar = _Scalar;
858
859 template<typename Rng>
860 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng, _Scalar a, _Scalar b)
861 {
862 using namespace Eigen::internal;
863 return a + b * std::tan(constant::pi * (ur(std::forward<Rng>(rng)) - 0.5));
864 }
865
866 template<typename Packet, typename Rng>
867 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng, const Packet& a, const Packet& b)
868 {
869 using namespace Eigen::internal;
870 Packet s, c;
871 psincos(pmul(pset1<Packet>(constant::pi),
872 psub(ur.template packetOp<Packet>(std::forward<Rng>(rng)), pset1<Packet>(0.5))
873 ), s, c);
874 return padd(a,
875 pmul(b, pdiv(s, c))
876 );
877 }
878 };
879
880 template<typename> class FisherFGen;
881
887 template<typename _Scalar>
888 class BetaGen : OptCacheStore, public GenBase<BetaGen<_Scalar>, _Scalar>
889 {
890 friend FisherFGen<_Scalar>;
891 static_assert(std::is_floating_point<_Scalar>::value, "betaDist needs floating point types.");
892 int cache_rest_cnt = 0;
894 _Scalar a, b;
895 GammaGen<_Scalar> gd1, gd2;
896
897 public:
898 using Scalar = _Scalar;
899
905 BetaGen(_Scalar _a = 1, _Scalar _b = 1)
906 : a{ _a }, b{ _b },
907 gd1{ _a }, gd2{ _b }
908 {
909 }
910
911 BetaGen(const BetaGen&) = default;
912 BetaGen(BetaGen&&) = default;
913
914 BetaGen& operator=(const BetaGen&) = default;
915 BetaGen& operator=(BetaGen&&) = default;
916
917 template<typename Rng>
918 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
919 {
920 using namespace Eigen::internal;
921 if (a < 1 && b < 1)
922 {
923 _Scalar x, p1, p2;
924 for (int _i = 0; ; ++_i)
925 {
926 EIGENRAND_CHECK_INFINITY_LOOP();
927 p1 = std::pow(ur(rng), 1 / a);
928 p2 = std::pow(ur(rng), 1 / b);
929 x = p1 + p2;
930 if (x <= 1) break;
931 }
932 return p1 / x;
933 }
934 else
935 {
936 _Scalar p1 = gd1(rng), p2 = gd2(rng);
937 return p1 / (p1 + p2);
938 }
939 }
940
941 template<typename Packet, typename Rng>
942 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
943 {
944 using namespace Eigen::internal;
945 if (a < 1 && b < 1)
946 {
947 auto& cm = Rand::detail::CompressMask<sizeof(Packet)>::get_inst();
948 Packet x, p1, p2;
949 for (int _i = 0; ; ++_i)
950 {
951 EIGENRAND_CHECK_INFINITY_LOOP();
952 p1 = pexp(pmul(plog(ur.template packetOp<Packet>(rng)), pset1<Packet>(1 / a)));
953 p2 = pexp(pmul(plog(ur.template packetOp<Packet>(rng)), pset1<Packet>(1 / b)));
954 x = padd(p1, p2);
955 Packet cands = pdiv(p1, x);
956 bool full = false;
957 cache_rest_cnt = cm.compress_append(cands, pcmple(x, pset1<Packet>(1)),
958 OptCacheStore::template get<Packet>(), cache_rest_cnt, full);
959 if (full) return cands;
960 }
961 }
962 else
963 {
964 auto p1 = gd1.template packetOp<Packet>(rng),
965 p2 = gd2.template packetOp<Packet>(rng);
966 return pdiv(p1, padd(p1, p2));
967 }
968 }
969 };
970
976 template<typename _Scalar>
977 class FisherFGen : public GenBase<FisherFGen<_Scalar>, _Scalar>
978 {
979 static_assert(std::is_floating_point<_Scalar>::value, "fisherF needs floating point types.");
981 public:
982 using Scalar = _Scalar;
983
989 FisherFGen(_Scalar m = 1, _Scalar n = 1)
990 : beta{ m * _Scalar(0.5), n * _Scalar(0.5) }
991 {
992 }
993
994 FisherFGen(const FisherFGen&) = default;
995 FisherFGen(FisherFGen&&) = default;
996
997 FisherFGen& operator=(const FisherFGen&) = default;
998 FisherFGen& operator=(FisherFGen&&) = default;
999
1000 template<typename Rng>
1001 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
1002 {
1003 using namespace Eigen::internal;
1004 auto x = beta(std::forward<Rng>(rng));
1005 return beta.b / beta.a * x / (1 - x);
1006 }
1007
1008 template<typename Packet, typename Rng>
1009 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
1010 {
1011 using namespace Eigen::internal;
1012 auto x = beta.template packetOp<Packet>(std::forward<Rng>(rng));
1013 return pdiv(pmul(pset1<Packet>(beta.b / beta.a), x), psub(pset1<Packet>(1), x));
1014 }
1015 };
1016
1017
1018 template<typename Derived, typename Urng>
1019 using BetaType = CwiseNullaryOp<internal::scalar_rng_adaptor<BetaGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1020
1034 template<typename Derived, typename Urng>
1035 inline const BetaType<Derived, Urng>
1036 beta(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
1037 {
1038 return {
1039 rows, cols, { std::forward<Urng>(urng), BetaGen<typename Derived::Scalar>{a, b} }
1040 };
1041 }
1042
1055 template<typename Derived, typename Urng>
1056 inline const BetaType<Derived, Urng>
1057 betaLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
1058 {
1059 return {
1060 o.rows(), o.cols(), { std::forward<Urng>(urng), BetaGen<typename Derived::Scalar>{a, b} }
1061 };
1062 }
1063
1064 template<typename Derived, typename Urng>
1065 using CauchyType = CwiseNullaryOp<internal::scalar_rng_adaptor<CauchyGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1066
1081 template<typename Derived, typename Urng>
1082 inline const CauchyType<Derived, Urng>
1083 cauchy(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
1084 {
1085 return {
1086 rows, cols, { std::forward<Urng>(urng), CauchyGen<typename Derived::Scalar>{a, b} }
1087 };
1088 }
1089
1103 template<typename Derived, typename Urng>
1104 inline const CauchyType<Derived, Urng>
1105 cauchyLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
1106 {
1107 return {
1108 o.rows(), o.cols(), { std::forward<Urng>(urng), CauchyGen<typename Derived::Scalar>{a, b} }
1109 };
1110 }
1111
1112 template<typename Lhs, typename Rhs, typename Urng>
1113 using CauchyVVType = CwiseBinaryOp<
1114 internal::scalar_binary_rng_adaptor<CauchyVGen<typename Lhs::Scalar>, typename Lhs::Scalar, typename Lhs::Scalar, typename Rhs::Scalar, Urng, true>,
1115 const Lhs, const Rhs
1116 >;
1117
1131 template<typename Lhs, typename Rhs, typename Urng>
1132 inline const CauchyVVType<Lhs, Rhs, Urng>
1133 cauchy(Urng&& urng, const ArrayBase<Lhs>& a, const ArrayBase<Rhs>& b)
1134 {
1135 return {
1136 static_cast<const Lhs&>(a), static_cast<const Rhs&>(b),
1137 { std::forward<Urng>(urng), CauchyVGen<typename Lhs::Scalar>{} }
1138 };
1139 }
1140
1141 template<typename Derived, typename Urng>
1142 using CauchyVSType = CwiseBinaryOp<
1143 internal::scalar_binary_rng_adaptor<CauchyVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1144 const Derived, CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>
1145 >;
1146
1147 template<typename Lhs, typename Urng>
1148 inline const CauchyVSType<Lhs, Urng>
1149 cauchy(Urng&& urng, const ArrayBase<Lhs>& a, typename Lhs::Scalar b)
1150 {
1151 return {
1152 static_cast<const Lhs&>(a),
1153 { a.rows(), a.cols(), internal::scalar_constant_op<typename Lhs::Scalar>{ b } },
1154 { std::forward<Urng>(urng), CauchyVGen<typename Lhs::Scalar>{} }
1155 };
1156 }
1157
1158 template<typename Derived, typename Urng>
1159 using CauchySVType = CwiseBinaryOp<
1160 internal::scalar_binary_rng_adaptor<CauchyVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1161 CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>, const Derived
1162 >;
1163
1164 template<typename Rhs, typename Urng>
1165 inline const CauchySVType<Rhs, Urng>
1166 cauchy(Urng&& urng, typename Rhs::Scalar a, const ArrayBase<Rhs>& b)
1167 {
1168 return {
1169 { b.rows(), b.cols(), internal::scalar_constant_op<typename Rhs::Scalar>{ a } },
1170 static_cast<const Rhs&>(b),
1171 { std::forward<Urng>(urng), CauchyVGen<typename Rhs::Scalar>{} }
1172 };
1173 }
1174
1175 template<typename Derived, typename Urng>
1176 using NormalType = CwiseNullaryOp<internal::scalar_rng_adaptor<StdNormalGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1177
1190 template<typename Derived, typename Urng>
1191 inline const NormalType<Derived, Urng>
1192 normal(Index rows, Index cols, Urng&& urng)
1193 {
1194 return {
1195 rows, cols, { std::forward<Urng>(urng) }
1196 };
1197 }
1198
1210 template<typename Derived, typename Urng>
1211 inline const NormalType<Derived, Urng>
1212 normalLike(Derived& o, Urng&& urng)
1213 {
1214 return {
1215 o.rows(), o.cols(), { std::forward<Urng>(urng) }
1216 };
1217 }
1218
1219 template<typename Derived, typename Urng>
1220 using Normal2Type = CwiseNullaryOp<internal::scalar_rng_adaptor<NormalGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1221
1236 template<typename Derived, typename Urng>
1237 inline const Normal2Type<Derived, Urng>
1238 normal(Index rows, Index cols, Urng&& urng, typename Derived::Scalar mean, typename Derived::Scalar stdev = 1)
1239 {
1240 return {
1241 rows, cols, { std::forward<Urng>(urng), NormalGen<typename Derived::Scalar>{mean, stdev} }
1242 };
1243 }
1244
1258 template<typename Derived, typename Urng>
1259 inline const Normal2Type<Derived, Urng>
1260 normalLike(Derived& o, Urng&& urng, typename Derived::Scalar mean, typename Derived::Scalar stdev = 1)
1261 {
1262 return {
1263 o.rows(), o.cols(), { std::forward<Urng>(urng), NormalGen<typename Derived::Scalar>{mean, stdev} }
1264 };
1265 }
1266
1267 template<typename Lhs, typename Rhs, typename Urng>
1268 using NormalVVType = CwiseBinaryOp<
1269 internal::scalar_binary_rng_adaptor<NormalVGen<typename Lhs::Scalar>, typename Lhs::Scalar, typename Lhs::Scalar, typename Rhs::Scalar, Urng, true>,
1270 const Lhs, const Rhs
1271 >;
1272
1286 template<typename Lhs, typename Rhs, typename Urng>
1287 inline const NormalVVType<Lhs, Rhs, Urng>
1288 normal(Urng&& urng, const ArrayBase<Lhs>& a, const ArrayBase<Rhs>& b)
1289 {
1290 return {
1291 static_cast<const Lhs&>(a), static_cast<const Rhs&>(b),
1292 { std::forward<Urng>(urng), NormalVGen<typename Lhs::Scalar>{} }
1293 };
1294 }
1295
1296 template<typename Derived, typename Urng>
1297 using NormalVSType = CwiseBinaryOp<
1298 internal::scalar_binary_rng_adaptor<NormalVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1299 const Derived, CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>
1300 >;
1301
1302 template<typename Lhs, typename Urng>
1303 inline const NormalVSType<Lhs, Urng>
1304 normal(Urng&& urng, const ArrayBase<Lhs>& a, typename Lhs::Scalar b)
1305 {
1306 return {
1307 static_cast<const Lhs&>(a),
1308 { a.rows(), a.cols(), internal::scalar_constant_op<typename Lhs::Scalar>{ b } },
1309 { std::forward<Urng>(urng), NormalVGen<typename Lhs::Scalar>{} }
1310 };
1311 }
1312
1313 template<typename Derived, typename Urng>
1314 using NormalSVType = CwiseBinaryOp<
1315 internal::scalar_binary_rng_adaptor<NormalVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1316 CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>, const Derived
1317 >;
1318
1319 template<typename Rhs, typename Urng>
1320 inline const NormalSVType<Rhs, Urng>
1321 normal(Urng&& urng, typename Rhs::Scalar a, const ArrayBase<Rhs>& b)
1322 {
1323 return {
1324 { b.rows(), b.cols(), internal::scalar_constant_op<typename Rhs::Scalar>{ a } },
1325 static_cast<const Rhs&>(b),
1326 { std::forward<Urng>(urng), NormalVGen<typename Rhs::Scalar>{} }
1327 };
1328 }
1329
1330 template<typename Derived, typename Urng>
1331 using LognormalType = CwiseNullaryOp<internal::scalar_rng_adaptor<LognormalGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1332
1347 template<typename Derived, typename Urng>
1348 inline const LognormalType<Derived, Urng>
1349 lognormal(Index rows, Index cols, Urng&& urng, typename Derived::Scalar mean = 0, typename Derived::Scalar stdev = 1)
1350 {
1351 return {
1352 rows, cols, { std::forward<Urng>(urng), LognormalGen<typename Derived::Scalar>{mean, stdev} }
1353 };
1354 }
1355
1369 template<typename Derived, typename Urng>
1370 inline const LognormalType<Derived, Urng>
1371 lognormalLike(Derived& o, Urng&& urng, typename Derived::Scalar mean = 0, typename Derived::Scalar stdev = 1)
1372 {
1373 return {
1374 o.rows(), o.cols(), { std::forward<Urng>(urng), LognormalGen<typename Derived::Scalar>{mean, stdev} }
1375 };
1376 }
1377
1378 template<typename Lhs, typename Rhs, typename Urng>
1379 using LognormalVVType = CwiseBinaryOp<
1380 internal::scalar_binary_rng_adaptor<LognormalVGen<typename Lhs::Scalar>, typename Lhs::Scalar, typename Lhs::Scalar, typename Rhs::Scalar, Urng, true>,
1381 const Lhs, const Rhs
1382 >;
1396 template<typename Lhs, typename Rhs, typename Urng>
1397 inline const LognormalVVType<Lhs, Rhs, Urng>
1398 lognormal(Urng&& urng, const ArrayBase<Lhs>& a, const ArrayBase<Rhs>& b)
1399 {
1400 return {
1401 static_cast<const Lhs&>(a), static_cast<const Rhs&>(b),
1402 { std::forward<Urng>(urng), LognormalVGen<typename Lhs::Scalar>{} }
1403 };
1404 }
1405
1406 template<typename Derived, typename Urng>
1407 using LognormalVSType = CwiseBinaryOp<
1408 internal::scalar_binary_rng_adaptor<LognormalVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1409 const Derived, CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>
1410 >;
1411
1412 template<typename Lhs, typename Urng>
1413 inline const LognormalVSType<Lhs, Urng>
1414 lognormal(Urng&& urng, const ArrayBase<Lhs>& a, typename Lhs::Scalar b)
1415 {
1416 return {
1417 static_cast<const Lhs&>(a),
1418 { a.rows(), a.cols(), internal::scalar_constant_op<typename Lhs::Scalar>{ b } },
1419 { std::forward<Urng>(urng), LognormalVGen<typename Lhs::Scalar>{} }
1420 };
1421 }
1422
1423 template<typename Derived, typename Urng>
1424 using LognormalSVType = CwiseBinaryOp<
1425 internal::scalar_binary_rng_adaptor<LognormalVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1426 CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>, const Derived
1427 >;
1428
1429 template<typename Rhs, typename Urng>
1430 inline const LognormalSVType<Rhs, Urng>
1431 lognormal(Urng&& urng, typename Rhs::Scalar a, const ArrayBase<Rhs>& b)
1432 {
1433 return {
1434 { b.rows(), b.cols(), internal::scalar_constant_op<typename Rhs::Scalar>{ a } },
1435 static_cast<const Rhs&>(b),
1436 { std::forward<Urng>(urng), LognormalVGen<typename Rhs::Scalar>{} }
1437 };
1438 }
1439
1440 template<typename Derived, typename Urng>
1441 using StudentTType = CwiseNullaryOp<internal::scalar_rng_adaptor<StudentTGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1442
1456 template<typename Derived, typename Urng>
1457 inline const StudentTType<Derived, Urng>
1458 studentT(Index rows, Index cols, Urng&& urng, typename Derived::Scalar n = 1)
1459 {
1460 return {
1461 rows, cols, { std::forward<Urng>(urng), StudentTGen<typename Derived::Scalar>{n} }
1462 };
1463 }
1464
1477 template<typename Derived, typename Urng>
1478 inline const StudentTType<Derived, Urng>
1479 studentTLike(Derived& o, Urng&& urng, typename Derived::Scalar n = 1)
1480 {
1481 return {
1482 o.rows(), o.cols(), { std::forward<Urng>(urng), StudentTGen<typename Derived::Scalar>{n} }
1483 };
1484 }
1485
1486 template<typename Lhs, typename Urng>
1487 using StudentTVType = CwiseUnaryOp<
1488 internal::scalar_unary_rng_adaptor<StudentTVGen<typename Lhs::Scalar>, typename Lhs::Scalar, typename Lhs::Scalar, Urng, true>,
1489 const Lhs
1490 >;
1502 template<typename Lhs, typename Urng>
1503 inline const StudentTVType<Lhs, Urng>
1504 studentT(Urng&& urng, const ArrayBase<Lhs>& a)
1505 {
1506 return StudentTVType<Lhs, Urng> {
1507 static_cast<const Lhs&>(a),
1508 { std::forward<Urng>(urng), StudentTVGen<typename Lhs::Scalar>{} }
1509 };
1510 }
1511
1512 template<typename Derived, typename Urng>
1513 using ExponentialType = CwiseNullaryOp<internal::scalar_rng_adaptor<ExponentialGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1514
1528 template<typename Derived, typename Urng>
1529 inline const ExponentialType<Derived, Urng>
1530 exponential(Index rows, Index cols, Urng&& urng, typename Derived::Scalar lambda = 1)
1531 {
1532 return {
1533 rows, cols, { std::forward<Urng>(urng), ExponentialGen<typename Derived::Scalar>{lambda} }
1534 };
1535 }
1536
1549 template<typename Derived, typename Urng>
1550 inline const ExponentialType<Derived, Urng>
1551 exponentialLike(Derived& o, Urng&& urng, typename Derived::Scalar lambda = 1)
1552 {
1553 return {
1554 o.rows(), o.cols(), { std::forward<Urng>(urng), ExponentialGen<typename Derived::Scalar>{lambda} }
1555 };
1556 }
1557
1558 template<typename Lhs, typename Urng>
1559 using ExponentialVType = CwiseUnaryOp<
1560 internal::scalar_unary_rng_adaptor<ExponentialVGen<typename Lhs::Scalar>, typename Lhs::Scalar, typename Lhs::Scalar, Urng, true>,
1561 const Lhs
1562 >;
1574 template<typename Lhs, typename Urng>
1575 inline const ExponentialVType<Lhs, Urng>
1576 exponential(Urng&& urng, const ArrayBase<Lhs>& a)
1577 {
1578 return ExponentialVType<Lhs, Urng> {
1579 static_cast<const Lhs&>(a),
1580 { std::forward<Urng>(urng), ExponentialVGen<typename Lhs::Scalar>{} }
1581 };
1582 }
1583
1584 template<typename Derived, typename Urng>
1585 using GammaType = CwiseNullaryOp<internal::scalar_rng_adaptor<GammaGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1586
1601 template<typename Derived, typename Urng>
1602 inline const GammaType<Derived, Urng>
1603 gamma(Index rows, Index cols, Urng&& urng, typename Derived::Scalar alpha = 1, typename Derived::Scalar beta = 1)
1604 {
1605 return {
1606 rows, cols, { std::forward<Urng>(urng), GammaGen<typename Derived::Scalar>{alpha, beta} }
1607 };
1608 }
1609
1623 template<typename Derived, typename Urng>
1624 inline const GammaType<Derived, Urng>
1625 gammaLike(Derived& o, Urng&& urng, typename Derived::Scalar alpha = 1, typename Derived::Scalar beta = 1)
1626 {
1627 return {
1628 o.rows(), o.cols(), { std::forward<Urng>(urng), GammaGen<typename Derived::Scalar>{alpha, beta} }
1629 };
1630 }
1631
1632 template<typename Derived, typename Urng>
1633 using WeibullType = CwiseNullaryOp<internal::scalar_rng_adaptor<WeibullGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1634
1649 template<typename Derived, typename Urng>
1650 inline const WeibullType<Derived, Urng>
1651 weibull(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
1652 {
1653 return {
1654 rows, cols, { std::forward<Urng>(urng), WeibullGen<typename Derived::Scalar>{a, b} }
1655 };
1656 }
1657
1671 template<typename Derived, typename Urng>
1672 inline const WeibullType<Derived, Urng>
1673 weibullLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
1674 {
1675 return {
1676 o.rows(), o.cols(), { std::forward<Urng>(urng), WeibullGen<typename Derived::Scalar>{a, b} }
1677 };
1678 }
1679
1680 template<typename Lhs, typename Rhs, typename Urng>
1681 using WeibullVVType = CwiseBinaryOp<
1682 internal::scalar_binary_rng_adaptor<WeibullVGen<typename Lhs::Scalar>, typename Lhs::Scalar, typename Lhs::Scalar, typename Rhs::Scalar, Urng, true>,
1683 const Lhs, const Rhs
1684 >;
1685
1699 template<typename Lhs, typename Rhs, typename Urng>
1700 inline const WeibullVVType<Lhs, Rhs, Urng>
1701 weibull(Urng&& urng, const ArrayBase<Lhs>& a, const ArrayBase<Rhs>& b)
1702 {
1703 return {
1704 static_cast<const Lhs&>(a), static_cast<const Rhs&>(b),
1705 { std::forward<Urng>(urng), WeibullVGen<typename Lhs::Scalar>{} }
1706 };
1707 }
1708
1709 template<typename Derived, typename Urng>
1710 using WeibullVSType = CwiseBinaryOp<
1711 internal::scalar_binary_rng_adaptor<WeibullVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1712 const Derived, CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>
1713 >;
1714
1715 template<typename Lhs, typename Urng>
1716 inline const WeibullVSType<Lhs, Urng>
1717 weibull(Urng&& urng, const ArrayBase<Lhs>& a, typename Lhs::Scalar b)
1718 {
1719 return {
1720 static_cast<const Lhs&>(a),
1721 { a.rows(), a.cols(), internal::scalar_constant_op<typename Lhs::Scalar>{ b } },
1722 { std::forward<Urng>(urng), WeibullVGen<typename Lhs::Scalar>{} }
1723 };
1724 }
1725
1726 template<typename Derived, typename Urng>
1727 using WeibullSVType = CwiseBinaryOp<
1728 internal::scalar_binary_rng_adaptor<WeibullVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1729 CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>, const Derived
1730 >;
1731
1732 template<typename Rhs, typename Urng>
1733 inline const WeibullSVType<Rhs, Urng>
1734 weibull(Urng&& urng, typename Rhs::Scalar a, const ArrayBase<Rhs>& b)
1735 {
1736 return {
1737 { b.rows(), b.cols(), internal::scalar_constant_op<typename Rhs::Scalar>{ a } },
1738 static_cast<const Rhs&>(b),
1739 { std::forward<Urng>(urng), WeibullVGen<typename Rhs::Scalar>{} }
1740 };
1741 }
1742
1743 template<typename Derived, typename Urng>
1744 using ExtremeValueType = CwiseNullaryOp<internal::scalar_rng_adaptor<ExtremeValueGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1745
1761 template<typename Derived, typename Urng>
1762 inline const ExtremeValueType<Derived, Urng>
1763 extremeValue(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
1764 {
1765 return {
1766 rows, cols, { std::forward<Urng>(urng), ExtremeValueGen<typename Derived::Scalar>{a, b} }
1767 };
1768 }
1769
1784 template<typename Derived, typename Urng>
1785 inline const ExtremeValueType<Derived, Urng>
1786 extremeValueLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
1787 {
1788 return {
1789 o.rows(), o.cols(), { std::forward<Urng>(urng), ExtremeValueGen<typename Derived::Scalar>{a, b} }
1790 };
1791 }
1792
1793 template<typename Lhs, typename Rhs, typename Urng>
1794 using ExtremeValueVVType = CwiseBinaryOp<
1795 internal::scalar_binary_rng_adaptor<ExtremeValueVGen<typename Lhs::Scalar>, typename Lhs::Scalar, typename Lhs::Scalar, typename Rhs::Scalar, Urng, true>,
1796 const Lhs, const Rhs
1797 >;
1798
1813 template<typename Lhs, typename Rhs, typename Urng>
1814 inline const ExtremeValueVVType<Lhs, Rhs, Urng>
1815 extremeValue(Urng&& urng, const ArrayBase<Lhs>& a, const ArrayBase<Rhs>& b)
1816 {
1817 return {
1818 static_cast<const Lhs&>(a), static_cast<const Rhs&>(b),
1819 { std::forward<Urng>(urng), ExtremeValueVGen<typename Lhs::Scalar>{} }
1820 };
1821 }
1822
1823 template<typename Derived, typename Urng>
1824 using ExtremeValueVSType = CwiseBinaryOp<
1825 internal::scalar_binary_rng_adaptor<ExtremeValueVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1826 const Derived, CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>
1827 >;
1828
1829 template<typename Lhs, typename Urng>
1830 inline const ExtremeValueVSType<Lhs, Urng>
1831 extremeValue(Urng&& urng, const ArrayBase<Lhs>& a, typename Lhs::Scalar b)
1832 {
1833 return {
1834 static_cast<const Lhs&>(a),
1835 { a.rows(), a.cols(), internal::scalar_constant_op<typename Lhs::Scalar>{ b } },
1836 { std::forward<Urng>(urng), ExtremeValueVGen<typename Lhs::Scalar>{} }
1837 };
1838 }
1839
1840 template<typename Derived, typename Urng>
1841 using ExtremeValueSVType = CwiseBinaryOp<
1842 internal::scalar_binary_rng_adaptor<ExtremeValueVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1843 CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>, const Derived
1844 >;
1845
1846 template<typename Rhs, typename Urng>
1847 inline const ExtremeValueSVType<Rhs, Urng>
1848 extremeValue(Urng&& urng, typename Rhs::Scalar a, const ArrayBase<Rhs>& b)
1849 {
1850 return {
1851 { b.rows(), b.cols(), internal::scalar_constant_op<typename Rhs::Scalar>{ a } },
1852 static_cast<const Rhs&>(b),
1853 { std::forward<Urng>(urng), ExtremeValueVGen<typename Rhs::Scalar>{} }
1854 };
1855 }
1856
1857 template<typename Derived, typename Urng>
1858 using ChiSquaredType = CwiseNullaryOp<internal::scalar_rng_adaptor<ChiSquaredGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1859
1873 template<typename Derived, typename Urng>
1874 inline const ChiSquaredType<Derived, Urng>
1875 chiSquared(Index rows, Index cols, Urng&& urng, typename Derived::Scalar n = 1)
1876 {
1877 return {
1878 rows, cols, { std::forward<Urng>(urng), ChiSquaredGen<typename Derived::Scalar>{n} }
1879 };
1880 }
1881
1894 template<typename Derived, typename Urng>
1895 inline const ChiSquaredType<Derived, Urng>
1896 chiSquaredLike(Derived& o, Urng&& urng, typename Derived::Scalar n = 1)
1897 {
1898 return {
1899 o.rows(), o.cols(), { std::forward<Urng>(urng), ChiSquaredGen<typename Derived::Scalar>{n} }
1900 };
1901 }
1902
1903 template<typename Derived, typename Urng>
1904 using FisherFType = CwiseNullaryOp<internal::scalar_rng_adaptor<FisherFGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1905
1920 template<typename Derived, typename Urng>
1921 inline const FisherFType<Derived, Urng>
1922 fisherF(Index rows, Index cols, Urng&& urng, typename Derived::Scalar m = 1, typename Derived::Scalar n = 1)
1923 {
1924 return {
1925 rows, cols, { std::forward<Urng>(urng), FisherFGen<typename Derived::Scalar>{m, n} }
1926 };
1927 }
1928
1942 template<typename Derived, typename Urng>
1943 inline const FisherFType<Derived, Urng>
1944 fisherFLike(Derived& o, Urng&& urng, typename Derived::Scalar m = 1, typename Derived::Scalar n = 1)
1945 {
1946 return {
1947 o.rows(), o.cols(), { std::forward<Urng>(urng), FisherFGen<typename Derived::Scalar>{m, n} }
1948 };
1949 }
1950 }
1951}
1952
1953#endif
Generator of reals on a beta distribution.
Definition: NormalExp.h:889
BetaGen(_Scalar _a=1, _Scalar _b=1)
Construct a new beta generator.
Definition: NormalExp.h:905
Generator of reals on a Cauchy distribution.
Definition: NormalExp.h:804
CauchyGen(_Scalar _a=0, _Scalar _b=1)
Construct a new Cauchy generator.
Definition: NormalExp.h:818
Generator of reals on a chi-squared distribution.
Definition: NormalExp.h:762
ChiSquaredGen(_Scalar n=1)
Construct a new chi-squared generator.
Definition: NormalExp.h:773
Generator of reals on an exponential distribution.
Definition: NormalExp.h:354
ExponentialGen(_Scalar _lambda=1)
Construct a new exponential generator.
Definition: NormalExp.h:368
Generator of reals on an extreme value distribution.
Definition: NormalExp.h:685
ExtremeValueGen(_Scalar _a=0, _Scalar _b=1)
Construct a new extreme value generator.
Definition: NormalExp.h:699
Generator of reals on a Fisher's f distribution.
Definition: NormalExp.h:978
FisherFGen(_Scalar m=1, _Scalar n=1)
Construct a new Fisher's f generator.
Definition: NormalExp.h:989
Generator of reals on a gamma distribution.
Definition: NormalExp.h:431
GammaGen(_Scalar _alpha=1, _Scalar _beta=1)
Construct a new gamma generator.
Definition: NormalExp.h:448
Base class of all univariate random generators.
Definition: Basic.h:33
Generator of reals on a lognormal distribution.
Definition: NormalExp.h:169
LognormalGen(_Scalar _mean=0, _Scalar _stdev=1)
Construct a new lognormal generator.
Definition: NormalExp.h:182
Generator of integers on a negative binomial distribution.
Definition: GammaPoisson.h:30
Generator of reals on a normal distribution.
Definition: NormalExp.h:92
NormalGen(_Scalar _mean=0, _Scalar _stdev=1)
Construct a new normal generator.
Definition: NormalExp.h:106
Generator of reals on the standard normal distribution.
Definition: NormalExp.h:27
Generator of reals in a range [0, 1)
Definition: Basic.h:495
Generator of reals on a Student's t distribution.
Definition: NormalExp.h:239
StudentTGen(_Scalar _n=1)
Construct a new Student's t generator.
Definition: NormalExp.h:252
Generator of reals on a Weibull distribution.
Definition: NormalExp.h:610
WeibullGen(_Scalar _a=1, _Scalar _b=1)
Construct a new Weibull generator.
Definition: NormalExp.h:624
const WeibullType< Derived, Urng > weibull(Index rows, Index cols, Urng &&urng, typename Derived::Scalar a=1, typename Derived::Scalar b=1)
generates reals on a Weibull distribution with arbitrary shape and scale parameter.
Definition: NormalExp.h:1651
const CauchyType< Derived, Urng > cauchyLike(Derived &o, Urng &&urng, typename Derived::Scalar a=0, typename Derived::Scalar b=1)
generates reals on the Cauchy distribution.
Definition: NormalExp.h:1105
const ExponentialType< Derived, Urng > exponential(Index rows, Index cols, Urng &&urng, typename Derived::Scalar lambda=1)
generates reals on an exponential distribution with arbitrary scale parameter.
Definition: NormalExp.h:1530
const NormalType< Derived, Urng > normal(Index rows, Index cols, Urng &&urng)
generates reals on a standard normal distribution (mean = 0, stdev=1)
Definition: NormalExp.h:1192
const NormalType< Derived, Urng > normalLike(Derived &o, Urng &&urng)
generates reals on a standard normal distribution (mean = 0, stdev=1)
Definition: NormalExp.h:1212
const CauchyType< Derived, Urng > cauchy(Index rows, Index cols, Urng &&urng, typename Derived::Scalar a=0, typename Derived::Scalar b=1)
generates reals on the Cauchy distribution.
Definition: NormalExp.h:1083
const StudentTType< Derived, Urng > studentTLike(Derived &o, Urng &&urng, typename Derived::Scalar n=1)
generates reals on the Student's t distribution with arbirtrary degress of freedom.
Definition: NormalExp.h:1479
const StudentTType< Derived, Urng > studentT(Index rows, Index cols, Urng &&urng, typename Derived::Scalar n=1)
generates reals on the Student's t distribution with arbirtrary degress of freedom.
Definition: NormalExp.h:1458
const WeibullType< Derived, Urng > weibullLike(Derived &o, Urng &&urng, typename Derived::Scalar a=1, typename Derived::Scalar b=1)
generates reals on a Weibull distribution with arbitrary shape and scale parameter.
Definition: NormalExp.h:1673
const GammaType< Derived, Urng > gammaLike(Derived &o, Urng &&urng, typename Derived::Scalar alpha=1, typename Derived::Scalar beta=1)
generates reals on a gamma distribution with arbitrary shape and scale parameter.
Definition: NormalExp.h:1625
const ExponentialType< Derived, Urng > exponentialLike(Derived &o, Urng &&urng, typename Derived::Scalar lambda=1)
generates reals on an exponential distribution with arbitrary scale parameter.
Definition: NormalExp.h:1551
const ChiSquaredType< Derived, Urng > chiSquared(Index rows, Index cols, Urng &&urng, typename Derived::Scalar n=1)
generates reals on the Chi-squared distribution with arbitrary degrees of freedom.
Definition: NormalExp.h:1875
const FisherFType< Derived, Urng > fisherFLike(Derived &o, Urng &&urng, typename Derived::Scalar m=1, typename Derived::Scalar n=1)
generates reals on the Fisher's F distribution.
Definition: NormalExp.h:1944
const GammaType< Derived, Urng > gamma(Index rows, Index cols, Urng &&urng, typename Derived::Scalar alpha=1, typename Derived::Scalar beta=1)
generates reals on a gamma distribution with arbitrary shape and scale parameter.
Definition: NormalExp.h:1603
const LognormalType< Derived, Urng > lognormal(Index rows, Index cols, Urng &&urng, typename Derived::Scalar mean=0, typename Derived::Scalar stdev=1)
generates reals on a lognormal distribution with arbitrary mean and stdev.
Definition: NormalExp.h:1349
const LognormalType< Derived, Urng > lognormalLike(Derived &o, Urng &&urng, typename Derived::Scalar mean=0, typename Derived::Scalar stdev=1)
generates reals on a lognormal distribution with arbitrary mean and stdev.
Definition: NormalExp.h:1371
const ExtremeValueType< Derived, Urng > extremeValueLike(Derived &o, Urng &&urng, typename Derived::Scalar a=0, typename Derived::Scalar b=1)
generates reals on an extreme value distribution (a.k.a Gumbel Type I, log-Weibull,...
Definition: NormalExp.h:1786
const ChiSquaredType< Derived, Urng > chiSquaredLike(Derived &o, Urng &&urng, typename Derived::Scalar n=1)
generates reals on the Chi-squared distribution with arbitrary degrees of freedom.
Definition: NormalExp.h:1896
const BetaType< Derived, Urng > betaLike(Derived &o, Urng &&urng, typename Derived::Scalar a=1, typename Derived::Scalar b=1)
generates reals on the beta distribution.
Definition: NormalExp.h:1057
const FisherFType< Derived, Urng > fisherF(Index rows, Index cols, Urng &&urng, typename Derived::Scalar m=1, typename Derived::Scalar n=1)
generates reals on the Fisher's F distribution.
Definition: NormalExp.h:1922
const ExtremeValueType< Derived, Urng > extremeValue(Index rows, Index cols, Urng &&urng, typename Derived::Scalar a=0, typename Derived::Scalar b=1)
generates reals on an extreme value distribution (a.k.a Gumbel Type I, log-Weibull,...
Definition: NormalExp.h:1763
const BetaType< Derived, Urng > beta(Index rows, Index cols, Urng &&urng, typename Derived::Scalar a=1, typename Derived::Scalar b=1)
generates reals on the beta distribution.
Definition: NormalExp.h:1036