EigenRand  0.4.0-alpha
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 
16 namespace 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.");
94  StdNormalGen<_Scalar> stdnorm;
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 
140  template<typename _Scalar>
141  class LognormalGen : public GenBase<LognormalGen<_Scalar>, _Scalar>
142  {
143  static_assert(std::is_floating_point<_Scalar>::value, "lognormalDist needs floating point types.");
144  NormalGen<_Scalar> norm;
145 
146  public:
147  using Scalar = _Scalar;
148 
155  LognormalGen(_Scalar _mean = 0, _Scalar _stdev = 1)
156  : norm{ _mean, _stdev }
157  {
158  }
159 
160  LognormalGen(const LognormalGen&) = default;
161  LognormalGen(LognormalGen&&) = default;
162 
163  LognormalGen& operator=(const LognormalGen&) = default;
164  LognormalGen& operator=(LognormalGen&&) = default;
165 
166  template<typename Rng>
167  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
168  {
169  using namespace Eigen::internal;
170  return std::exp(norm(std::forward<Rng>(rng)));
171  }
172 
173  template<typename Packet, typename Rng>
174  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
175  {
176  using namespace Eigen::internal;
177  return pexp(norm.template packetOp<Packet>(std::forward<Rng>(rng)));
178  }
179  };
180 
186  template<typename _Scalar>
187  class StudentTGen : public GenBase<StudentTGen<_Scalar>, _Scalar>
188  {
189  static_assert(std::is_floating_point<_Scalar>::value, "studentT needs floating point types.");
191  _Scalar n;
192 
193  public:
194  using Scalar = _Scalar;
195 
201  StudentTGen(_Scalar _n = 1)
202  : n{ _n }
203  {
204  }
205 
206  StudentTGen(const StudentTGen&) = default;
207  StudentTGen(StudentTGen&&) = default;
208 
209  StudentTGen& operator=(const StudentTGen&) = default;
210  StudentTGen& operator=(StudentTGen&&) = default;
211 
212  template<typename Rng>
213  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
214  {
215  using namespace Eigen::internal;
216  _Scalar v1, v2, sx;
217  for (int _i = 0; ; ++_i)
218  {
219  EIGENRAND_CHECK_INFINITY_LOOP();
220  v1 = 2 * ur(rng) - 1;
221  v2 = 2 * ur(rng) - 1;
222  sx = v1 * v1 + v2 * v2;
223  if (sx && sx < 1) break;
224  }
225 
226  _Scalar fx = std::sqrt(n * (std::pow(sx, -2 / n) - 1) / sx);
227  return fx * v1;
228  }
229 
230  template<typename Packet, typename Rng>
231  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
232  {
233  using namespace Eigen::internal;
234  Packet u1 = ur.template packetOp<Packet>(rng),
235  u2 = ur.template packetOp<Packet>(rng);
236 
237  u1 = psub(pset1<Packet>(1), u1);
238  auto pn = pset1<Packet>(n);
239  auto radius = psqrt(pmul(pn,
240  psub(pexp(pmul(plog(u1), pset1<Packet>(-2 / n))), pset1<Packet>(1))
241  ));
242  auto theta = pmul(pset1<Packet>(2 * constant::pi), u2);
243  //Packet sintheta, costheta;
244  //psincos(theta, sintheta, costheta);
245  return pmul(radius, psin(theta));
246  }
247  };
248 
249  template<typename> class GammaGen;
250 
256  template<typename _Scalar>
257  class ExponentialGen : public GenBase<ExponentialGen<_Scalar>, _Scalar>
258  {
259  friend GammaGen<_Scalar>;
260  static_assert(std::is_floating_point<_Scalar>::value, "expDist needs floating point types.");
262  _Scalar lambda = 1;
263 
264  public:
265  using Scalar = _Scalar;
266 
272  ExponentialGen(_Scalar _lambda = 1)
273  : lambda{ _lambda }
274  {
275  }
276 
277  ExponentialGen(const ExponentialGen&) = default;
278  ExponentialGen(ExponentialGen&&) = default;
279 
280  ExponentialGen& operator=(const ExponentialGen&) = default;
281  ExponentialGen& operator=(ExponentialGen&&) = default;
282 
283  template<typename Rng>
284  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
285  {
286  using namespace Eigen::internal;
287  return -std::log(1 - ur(std::forward<Rng>(rng))) / lambda;
288  }
289 
290  template<typename Packet, typename Rng>
291  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
292  {
293  using namespace Eigen::internal;
294  return pnegate(pdiv(plog(
295  psub(pset1<Packet>(1), ur.template packetOp<Packet>(std::forward<Rng>(rng)))
296  ), pset1<Packet>(lambda)));
297  }
298  };
299 
300  template<typename> class NegativeBinomialGen;
301 
307  template<typename _Scalar>
308  class GammaGen : OptCacheStore, public GenBase<GammaGen<_Scalar>, _Scalar>
309  {
310  template<typename _Ty>
311  friend class NegativeBinomialGen;
312  static_assert(std::is_floating_point<_Scalar>::value, "gammaDist needs floating point types.");
313  int cache_rest_cnt = 0;
315  _Scalar alpha, beta, px, sqrt;
316 
317  public:
318  using Scalar = _Scalar;
319 
326  GammaGen(_Scalar _alpha = 1, _Scalar _beta = 1)
327  : alpha{ _alpha }, beta{ _beta }
328  {
329  px = (_Scalar)(constant::e / (alpha + constant::e));
330  sqrt = std::sqrt(2 * alpha - 1);
331  }
332 
333  GammaGen(const GammaGen&) = default;
334  GammaGen(GammaGen&&) = default;
335 
336  GammaGen& operator=(const GammaGen&) = default;
337  GammaGen& operator=(GammaGen&&) = default;
338 
339  template<typename Rng>
340  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
341  {
342  using namespace Eigen::internal;
343  if (alpha < 1)
344  {
345  _Scalar ux, vx, xx, qx;
346  for (int _i = 0; ; ++_i)
347  {
348  EIGENRAND_CHECK_INFINITY_LOOP();
349  ux = expon.ur(rng);
350  vx = expon.ur.nzur_scalar(rng);
351 
352  if (ux < px)
353  {
354  xx = std::pow(vx, 1 / alpha);
355  qx = std::exp(-xx);
356  }
357  else
358  {
359  xx = 1 - std::log(vx);
360  qx = std::pow(xx, alpha - 1);
361  }
362 
363  if (expon.ur(rng) < qx)
364  {
365  return beta * xx;
366  }
367  }
368  }
369  if (alpha == 1)
370  {
371  return beta * expon(rng);
372  }
373  int count;
374  if ((count = alpha) == alpha && count < 20)
375  {
376  _Scalar yx;
377  yx = expon.ur.nzur_scalar(rng);
378  while (--count)
379  {
380  yx *= expon.ur.nzur_scalar(rng);
381  }
382  return -beta * std::log(yx);
383  }
384 
385  for (int _i = 0; ; ++_i)
386  {
387  EIGENRAND_CHECK_INFINITY_LOOP();
388  _Scalar yx, xx;
389  yx = std::tan(constant::pi * expon.ur(rng));
390  xx = sqrt * yx + alpha - 1;
391  if (xx <= 0) continue;
392  if (expon.ur(rng) <= (1 + yx * yx)
393  * std::exp((alpha - 1) * std::log(xx / (alpha - 1)) - sqrt * yx))
394  {
395  return beta * xx;
396  }
397  }
398  }
399 
400  template<typename Packet, typename Rng>
401  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
402  {
403  using namespace Eigen::internal;
404  using RUtils = RandUtils<Packet, Rng>;
405  auto& cm = Rand::detail::CompressMask<sizeof(Packet)>::get_inst();
406 
407  RUtils ru;
408  if (alpha < 1)
409  {
410  for (int _i = 0; ; ++_i)
411  {
412  EIGENRAND_CHECK_INFINITY_LOOP();
413  Packet ux = ru.uniform_real(rng);
414  Packet vx = ru.nonzero_uniform_real(rng);
415 
416  Packet xx = pexp(pmul(pset1<Packet>(1 / alpha), plog(vx)));
417  Packet qx = pexp(pnegate(xx));
418 
419  Packet xx2 = psub(pset1<Packet>(1), plog(vx));
420  Packet qx2 = pexp(pmul(plog(xx2), pset1<Packet>(alpha - 1)));
421 
422  auto c = pcmplt(ux, pset1<Packet>(px));
423  xx = pblendv(c, xx, xx2);
424  qx = pblendv(c, qx, qx2);
425 
426  ux = ru.uniform_real(rng);
427  Packet cands = pmul(pset1<Packet>(beta), xx);
428  bool full = false;
429  cache_rest_cnt = cm.compress_append(cands, pcmplt(ux, qx),
430  OptCacheStore::template get<Packet>(), cache_rest_cnt, full);
431  if (full) return cands;
432  }
433  }
434  if (alpha == 1)
435  {
436  return pmul(pset1<Packet>(beta),
437  expon.template packetOp<Packet>(rng)
438  );
439  }
440  int count;
441  if ((count = alpha) == alpha && count < 20)
442  {
443  RUtils ru;
444  Packet ux, yx;
445  yx = ru.nonzero_uniform_real(rng);
446  while (--count)
447  {
448  yx = pmul(yx, ru.nonzero_uniform_real(rng));
449  }
450  return pnegate(pmul(pset1<Packet>(beta), plog(yx)));
451  }
452  else
453  {
454  for (int _i = 0; ; ++_i)
455  {
456  EIGENRAND_CHECK_INFINITY_LOOP();
457  Packet alpha_1 = pset1<Packet>(alpha - 1);
458  Packet ys, yc;
459  psincos(pmul(pset1<Packet>(constant::pi), ru.uniform_real(rng)), ys, yc);
460  Packet yx = pdiv(ys, yc);
461  Packet xx = padd(pmul(pset1<Packet>(sqrt), yx), alpha_1);
462  auto c = pcmplt(pset1<Packet>(0), xx);
463  Packet ux = ru.uniform_real(rng);
464  Packet ub = pmul(padd(pmul(yx, yx), pset1<Packet>(1)),
465  pexp(psub(
466  pmul(alpha_1, plog(pdiv(xx, alpha_1))),
467  pmul(yx, pset1<Packet>(sqrt))
468  ))
469  );
470  c = pand(c, pcmple(ux, ub));
471  Packet cands = pmul(pset1<Packet>(beta), xx);
472  bool full = false;
473  cache_rest_cnt = cm.compress_append(cands, c,
474  OptCacheStore::template get<Packet>(), cache_rest_cnt, full);
475  if (full) return cands;
476  }
477  }
478  }
479  };
480 
486  template<typename _Scalar>
487  class WeibullGen : public GenBase<WeibullGen<_Scalar>, _Scalar>
488  {
489  static_assert(std::is_floating_point<_Scalar>::value, "weilbullDist needs floating point types.");
491  _Scalar a = 1, b = 1;
492 
493  public:
494  using Scalar = _Scalar;
495 
502  WeibullGen(_Scalar _a = 1, _Scalar _b = 1)
503  : a{ _a }, b{ _b }
504  {
505  }
506 
507  WeibullGen(const WeibullGen&) = default;
508  WeibullGen(WeibullGen&&) = default;
509 
510  WeibullGen& operator=(const WeibullGen&) = default;
511  WeibullGen& operator=(WeibullGen&&) = default;
512 
513  template<typename Rng>
514  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
515  {
516  using namespace Eigen::internal;
517  return std::pow(-std::log(1 - ur(std::forward<Rng>(rng))), 1 / a) * b;
518  }
519 
520  template<typename Packet, typename Rng>
521  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
522  {
523  using namespace Eigen::internal;
524  return pmul(pexp(pmul(plog(pnegate(plog(
525  psub(pset1<Packet>(1), ur.template packetOp<Packet>(std::forward<Rng>(rng)))
526  ))), pset1<Packet>(1 / a))), pset1<Packet>(b));
527  }
528  };
529 
535  template<typename _Scalar>
536  class ExtremeValueGen : public GenBase<ExtremeValueGen<_Scalar>, _Scalar>
537  {
538  static_assert(std::is_floating_point<_Scalar>::value, "extremeValueDist needs floating point types.");
540  _Scalar a = 0, b = 1;
541 
542  public:
543  using Scalar = _Scalar;
544 
551  ExtremeValueGen(_Scalar _a = 0, _Scalar _b = 1)
552  : a{ _a }, b{ _b }
553  {
554  }
555 
556  ExtremeValueGen(const ExtremeValueGen&) = default;
557  ExtremeValueGen(ExtremeValueGen&&) = default;
558 
559  ExtremeValueGen& operator=(const ExtremeValueGen&) = default;
560  ExtremeValueGen& operator=(ExtremeValueGen&&) = default;
561 
562  template<typename Rng>
563  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
564  {
565  using namespace Eigen::internal;
566  return (a - b * std::log(-std::log(ur.nzur_scalar(std::forward<Rng>(rng)))));
567  }
568 
569  template<typename Packet, typename Rng>
570  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
571  {
572  using namespace Eigen::internal;
573  using RUtils = RandUtils<Packet, Rng>;
574  return psub(pset1<Packet>(a),
575  pmul(plog(pnegate(plog(RUtils{}.nonzero_uniform_real(std::forward<Rng>(rng))))), pset1<Packet>(b))
576  );
577  }
578  };
579 
585  template<typename _Scalar>
586  class ChiSquaredGen : public GenBase<ChiSquaredGen<_Scalar>, _Scalar>
587  {
588  static_assert(std::is_floating_point<_Scalar>::value, "chiSquaredDist needs floating point types.");
590  public:
591  using Scalar = _Scalar;
592 
598  ChiSquaredGen(_Scalar n = 1)
599  : gamma{ n * _Scalar(0.5), 2 }
600  {
601  }
602 
603  ChiSquaredGen(const ChiSquaredGen&) = default;
604  ChiSquaredGen(ChiSquaredGen&&) = default;
605 
606  ChiSquaredGen& operator=(const ChiSquaredGen&) = default;
607  ChiSquaredGen& operator=(ChiSquaredGen&&) = default;
608 
609  template<typename Rng>
610  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
611  {
612  return gamma(rng);
613  }
614 
615  template<typename Packet, typename Rng>
616  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
617  {
618  return gamma.template packetOp<Packet>(rng);
619  }
620  };
621 
627  template<typename _Scalar>
628  class CauchyGen : public GenBase<CauchyGen<_Scalar>, _Scalar>
629  {
630  static_assert(std::is_floating_point<_Scalar>::value, "cauchyDist needs floating point types.");
632  _Scalar a = 0, b = 1;
633 
634  public:
635  using Scalar = _Scalar;
636 
643  CauchyGen(_Scalar _a = 0, _Scalar _b = 1)
644  : a{ _a }, b{ _b }
645  {
646  }
647 
648  CauchyGen(const CauchyGen&) = default;
649  CauchyGen(CauchyGen&&) = default;
650 
651  CauchyGen& operator=(const CauchyGen&) = default;
652  CauchyGen& operator=(CauchyGen&&) = default;
653 
654  template<typename Rng>
655  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
656  {
657  using namespace Eigen::internal;
658  return a + b * std::tan(constant::pi * (ur(std::forward<Rng>(rng)) - 0.5));
659  }
660 
661  template<typename Packet, typename Rng>
662  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
663  {
664  using namespace Eigen::internal;
665  Packet s, c;
666  psincos(pmul(pset1<Packet>(constant::pi),
667  psub(ur.template packetOp<Packet>(std::forward<Rng>(rng)), pset1<Packet>(0.5))
668  ), s, c);
669  return padd(pset1<Packet>(a),
670  pmul(pset1<Packet>(b), pdiv(s, c))
671  );
672  }
673  };
674 
675  template<typename> class FisherFGen;
676 
682  template<typename _Scalar>
683  class BetaGen : OptCacheStore, public GenBase<BetaGen<_Scalar>, _Scalar>
684  {
685  friend FisherFGen<_Scalar>;
686  static_assert(std::is_floating_point<_Scalar>::value, "betaDist needs floating point types.");
687  int cache_rest_cnt = 0;
689  _Scalar a, b;
690  GammaGen<_Scalar> gd1, gd2;
691 
692  public:
693  using Scalar = _Scalar;
694 
700  BetaGen(_Scalar _a = 1, _Scalar _b = 1)
701  : a{ _a }, b{ _b },
702  gd1{ _a }, gd2{ _b }
703  {
704  }
705 
706  BetaGen(const BetaGen&) = default;
707  BetaGen(BetaGen&&) = default;
708 
709  BetaGen& operator=(const BetaGen&) = default;
710  BetaGen& operator=(BetaGen&&) = default;
711 
712  template<typename Rng>
713  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
714  {
715  using namespace Eigen::internal;
716  if (a < 1 && b < 1)
717  {
718  _Scalar x, p1, p2;
719  for (int _i = 0; ; ++_i)
720  {
721  EIGENRAND_CHECK_INFINITY_LOOP();
722  p1 = std::pow(ur(rng), 1 / a);
723  p2 = std::pow(ur(rng), 1 / b);
724  x = p1 + p2;
725  if (x <= 1) break;
726  }
727  return p1 / x;
728  }
729  else
730  {
731  _Scalar p1 = gd1(rng), p2 = gd2(rng);
732  return p1 / (p1 + p2);
733  }
734  }
735 
736  template<typename Packet, typename Rng>
737  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
738  {
739  using namespace Eigen::internal;
740  if (a < 1 && b < 1)
741  {
742  auto& cm = Rand::detail::CompressMask<sizeof(Packet)>::get_inst();
743  Packet x, p1, p2;
744  for (int _i = 0; ; ++_i)
745  {
746  EIGENRAND_CHECK_INFINITY_LOOP();
747  p1 = pexp(pmul(plog(ur.template packetOp<Packet>(rng)), pset1<Packet>(1 / a)));
748  p2 = pexp(pmul(plog(ur.template packetOp<Packet>(rng)), pset1<Packet>(1 / b)));
749  x = padd(p1, p2);
750  Packet cands = pdiv(p1, x);
751  bool full = false;
752  cache_rest_cnt = cm.compress_append(cands, pcmple(x, pset1<Packet>(1)),
753  OptCacheStore::template get<Packet>(), cache_rest_cnt, full);
754  if (full) return cands;
755  }
756  }
757  else
758  {
759  auto p1 = gd1.template packetOp<Packet>(rng),
760  p2 = gd2.template packetOp<Packet>(rng);
761  return pdiv(p1, padd(p1, p2));
762  }
763  }
764  };
765 
771  template<typename _Scalar>
772  class FisherFGen : public GenBase<FisherFGen<_Scalar>, _Scalar>
773  {
774  static_assert(std::is_floating_point<_Scalar>::value, "fisherF needs floating point types.");
776  public:
777  using Scalar = _Scalar;
778 
784  FisherFGen(_Scalar m = 1, _Scalar n = 1)
785  : beta{ m * _Scalar(0.5), n * _Scalar(0.5) }
786  {
787  }
788 
789  FisherFGen(const FisherFGen&) = default;
790  FisherFGen(FisherFGen&&) = default;
791 
792  FisherFGen& operator=(const FisherFGen&) = default;
793  FisherFGen& operator=(FisherFGen&&) = default;
794 
795  template<typename Rng>
796  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
797  {
798  using namespace Eigen::internal;
799  auto x = beta(std::forward<Rng>(rng));
800  return beta.b / beta.a * x / (1 - x);
801  }
802 
803  template<typename Packet, typename Rng>
804  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
805  {
806  using namespace Eigen::internal;
807  auto x = beta.template packetOp<Packet>(std::forward<Rng>(rng));
808  return pdiv(pmul(pset1<Packet>(beta.b / beta.a), x), psub(pset1<Packet>(1), x));
809  }
810  };
811 
812 
813  template<typename Derived, typename Urng>
814  using BetaType = CwiseNullaryOp<internal::scalar_rng_adaptor<BetaGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
815 
829  template<typename Derived, typename Urng>
830  inline const BetaType<Derived, Urng>
831  beta(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
832  {
833  return {
834  rows, cols, { std::forward<Urng>(urng), BetaGen<typename Derived::Scalar>{a, b} }
835  };
836  }
837 
850  template<typename Derived, typename Urng>
851  inline const BetaType<Derived, Urng>
852  betaLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
853  {
854  return {
855  o.rows(), o.cols(), { std::forward<Urng>(urng), BetaGen<typename Derived::Scalar>{a, b} }
856  };
857  }
858 
859  template<typename Derived, typename Urng>
860  using CauchyType = CwiseNullaryOp<internal::scalar_rng_adaptor<CauchyGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
861 
876  template<typename Derived, typename Urng>
877  inline const CauchyType<Derived, Urng>
878  cauchy(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
879  {
880  return {
881  rows, cols, { std::forward<Urng>(urng), CauchyGen<typename Derived::Scalar>{a, b} }
882  };
883  }
884 
898  template<typename Derived, typename Urng>
899  inline const CauchyType<Derived, Urng>
900  cauchyLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
901  {
902  return {
903  o.rows(), o.cols(), { std::forward<Urng>(urng), CauchyGen<typename Derived::Scalar>{a, b} }
904  };
905  }
906 
907  template<typename Derived, typename Urng>
908  using NormalType = CwiseNullaryOp<internal::scalar_rng_adaptor<StdNormalGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
909 
922  template<typename Derived, typename Urng>
923  inline const NormalType<Derived, Urng>
924  normal(Index rows, Index cols, Urng&& urng)
925  {
926  return {
927  rows, cols, { std::forward<Urng>(urng) }
928  };
929  }
930 
942  template<typename Derived, typename Urng>
943  inline const NormalType<Derived, Urng>
944  normalLike(Derived& o, Urng&& urng)
945  {
946  return {
947  o.rows(), o.cols(), { std::forward<Urng>(urng) }
948  };
949  }
950 
951  template<typename Derived, typename Urng>
952  using Normal2Type = CwiseNullaryOp<internal::scalar_rng_adaptor<NormalGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
953 
968  template<typename Derived, typename Urng>
969  inline const Normal2Type<Derived, Urng>
970  normal(Index rows, Index cols, Urng&& urng, typename Derived::Scalar mean, typename Derived::Scalar stdev = 1)
971  {
972  return {
973  rows, cols, { std::forward<Urng>(urng), NormalGen<typename Derived::Scalar>{mean, stdev} }
974  };
975  }
976 
990  template<typename Derived, typename Urng>
991  inline const Normal2Type<Derived, Urng>
992  normalLike(Derived& o, Urng&& urng, typename Derived::Scalar mean, typename Derived::Scalar stdev = 1)
993  {
994  return {
995  o.rows(), o.cols(), { std::forward<Urng>(urng), NormalGen<typename Derived::Scalar>{mean, stdev} }
996  };
997  }
998 
999  template<typename Derived, typename Urng>
1000  using LognormalType = CwiseNullaryOp<internal::scalar_rng_adaptor<LognormalGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1001 
1016  template<typename Derived, typename Urng>
1017  inline const LognormalType<Derived, Urng>
1018  lognormal(Index rows, Index cols, Urng&& urng, typename Derived::Scalar mean = 0, typename Derived::Scalar stdev = 1)
1019  {
1020  return {
1021  rows, cols, { std::forward<Urng>(urng), LognormalGen<typename Derived::Scalar>{mean, stdev} }
1022  };
1023  }
1024 
1038  template<typename Derived, typename Urng>
1039  inline const LognormalType<Derived, Urng>
1040  lognormalLike(Derived& o, Urng&& urng, typename Derived::Scalar mean = 0, typename Derived::Scalar stdev = 1)
1041  {
1042  return {
1043  o.rows(), o.cols(), { std::forward<Urng>(urng), LognormalGen<typename Derived::Scalar>{mean, stdev} }
1044  };
1045  }
1046 
1047  template<typename Derived, typename Urng>
1048  using StudentTType = CwiseNullaryOp<internal::scalar_rng_adaptor<StudentTGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1049 
1063  template<typename Derived, typename Urng>
1064  inline const StudentTType<Derived, Urng>
1065  studentT(Index rows, Index cols, Urng&& urng, typename Derived::Scalar n = 1)
1066  {
1067  return {
1068  rows, cols, { std::forward<Urng>(urng), StudentTGen<typename Derived::Scalar>{n} }
1069  };
1070  }
1071 
1084  template<typename Derived, typename Urng>
1085  inline const StudentTType<Derived, Urng>
1086  studentTLike(Derived& o, Urng&& urng, typename Derived::Scalar n = 1)
1087  {
1088  return {
1089  o.rows(), o.cols(), { std::forward<Urng>(urng), StudentTGen<typename Derived::Scalar>{n} }
1090  };
1091  }
1092 
1093  template<typename Derived, typename Urng>
1094  using ExponentialType = CwiseNullaryOp<internal::scalar_rng_adaptor<ExponentialGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1095 
1109  template<typename Derived, typename Urng>
1110  inline const ExponentialType<Derived, Urng>
1111  exponential(Index rows, Index cols, Urng&& urng, typename Derived::Scalar lambda = 1)
1112  {
1113  return {
1114  rows, cols, { std::forward<Urng>(urng), ExponentialGen<typename Derived::Scalar>{lambda} }
1115  };
1116  }
1117 
1130  template<typename Derived, typename Urng>
1131  inline const ExponentialType<Derived, Urng>
1132  exponentialLike(Derived& o, Urng&& urng, typename Derived::Scalar lambda = 1)
1133  {
1134  return {
1135  o.rows(), o.cols(), { std::forward<Urng>(urng), ExponentialGen<typename Derived::Scalar>{lambda} }
1136  };
1137  }
1138 
1139  template<typename Derived, typename Urng>
1140  using GammaType = CwiseNullaryOp<internal::scalar_rng_adaptor<GammaGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1141 
1156  template<typename Derived, typename Urng>
1157  inline const GammaType<Derived, Urng>
1158  gamma(Index rows, Index cols, Urng&& urng, typename Derived::Scalar alpha = 1, typename Derived::Scalar beta = 1)
1159  {
1160  return {
1161  rows, cols, { std::forward<Urng>(urng), GammaGen<typename Derived::Scalar>{alpha, beta} }
1162  };
1163  }
1164 
1178  template<typename Derived, typename Urng>
1179  inline const GammaType<Derived, Urng>
1180  gammaLike(Derived& o, Urng&& urng, typename Derived::Scalar alpha = 1, typename Derived::Scalar beta = 1)
1181  {
1182  return {
1183  o.rows(), o.cols(), { std::forward<Urng>(urng), GammaGen<typename Derived::Scalar>{alpha, beta} }
1184  };
1185  }
1186 
1187  template<typename Derived, typename Urng>
1188  using WeibullType = CwiseNullaryOp<internal::scalar_rng_adaptor<WeibullGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1189 
1204  template<typename Derived, typename Urng>
1205  inline const WeibullType<Derived, Urng>
1206  weibull(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
1207  {
1208  return {
1209  rows, cols, { std::forward<Urng>(urng), WeibullGen<typename Derived::Scalar>{a, b} }
1210  };
1211  }
1212 
1226  template<typename Derived, typename Urng>
1227  inline const WeibullType<Derived, Urng>
1228  weibullLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
1229  {
1230  return {
1231  o.rows(), o.cols(), { std::forward<Urng>(urng), WeibullGen<typename Derived::Scalar>{a, b} }
1232  };
1233  }
1234 
1235  template<typename Derived, typename Urng>
1236  using ExtremeValueType = CwiseNullaryOp<internal::scalar_rng_adaptor<ExtremeValueGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1237 
1253  template<typename Derived, typename Urng>
1254  inline const ExtremeValueType<Derived, Urng>
1255  extremeValue(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
1256  {
1257  return {
1258  rows, cols, { std::forward<Urng>(urng), ExtremeValueGen<typename Derived::Scalar>{a, b} }
1259  };
1260  }
1261 
1276  template<typename Derived, typename Urng>
1277  inline const ExtremeValueType<Derived, Urng>
1278  extremeValueLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
1279  {
1280  return {
1281  o.rows(), o.cols(), { std::forward<Urng>(urng), ExtremeValueGen<typename Derived::Scalar>{a, b} }
1282  };
1283  }
1284 
1285  template<typename Derived, typename Urng>
1286  using ChiSquaredType = CwiseNullaryOp<internal::scalar_rng_adaptor<ChiSquaredGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1287 
1301  template<typename Derived, typename Urng>
1302  inline const ChiSquaredType<Derived, Urng>
1303  chiSquared(Index rows, Index cols, Urng&& urng, typename Derived::Scalar n = 1)
1304  {
1305  return {
1306  rows, cols, { std::forward<Urng>(urng), ChiSquaredGen<typename Derived::Scalar>{n} }
1307  };
1308  }
1309 
1322  template<typename Derived, typename Urng>
1323  inline const ChiSquaredType<Derived, Urng>
1324  chiSquaredLike(Derived& o, Urng&& urng, typename Derived::Scalar n = 1)
1325  {
1326  return {
1327  o.rows(), o.cols(), { std::forward<Urng>(urng), ChiSquaredGen<typename Derived::Scalar>{n} }
1328  };
1329  }
1330 
1331  template<typename Derived, typename Urng>
1332  using FisherFType = CwiseNullaryOp<internal::scalar_rng_adaptor<FisherFGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1333 
1348  template<typename Derived, typename Urng>
1349  inline const FisherFType<Derived, Urng>
1350  fisherF(Index rows, Index cols, Urng&& urng, typename Derived::Scalar m = 1, typename Derived::Scalar n = 1)
1351  {
1352  return {
1353  rows, cols, { std::forward<Urng>(urng), FisherFGen<typename Derived::Scalar>{m, n} }
1354  };
1355  }
1356 
1370  template<typename Derived, typename Urng>
1371  inline const FisherFType<Derived, Urng>
1372  fisherFLike(Derived& o, Urng&& urng, typename Derived::Scalar m = 1, typename Derived::Scalar n = 1)
1373  {
1374  return {
1375  o.rows(), o.cols(), { std::forward<Urng>(urng), FisherFGen<typename Derived::Scalar>{m, n} }
1376  };
1377  }
1378  }
1379 }
1380 
1381 #endif
Generator of reals on a beta distribution.
Definition: NormalExp.h:684
BetaGen(_Scalar _a=1, _Scalar _b=1)
Construct a new beta generator.
Definition: NormalExp.h:700
Generator of reals on a Cauchy distribution.
Definition: NormalExp.h:629
CauchyGen(_Scalar _a=0, _Scalar _b=1)
Construct a new Cauchy generator.
Definition: NormalExp.h:643
Generator of reals on a chi-squared distribution.
Definition: NormalExp.h:587
ChiSquaredGen(_Scalar n=1)
Construct a new chi-squared generator.
Definition: NormalExp.h:598
Generator of reals on an exponential distribution.
Definition: NormalExp.h:258
ExponentialGen(_Scalar _lambda=1)
Construct a new exponential generator.
Definition: NormalExp.h:272
Generator of reals on an extreme value distribution.
Definition: NormalExp.h:537
ExtremeValueGen(_Scalar _a=0, _Scalar _b=1)
Construct a new extreme value generator.
Definition: NormalExp.h:551
Generator of reals on a Fisher's f distribution.
Definition: NormalExp.h:773
FisherFGen(_Scalar m=1, _Scalar n=1)
Construct a new Fisher's f generator.
Definition: NormalExp.h:784
Generator of reals on a gamma distribution.
Definition: NormalExp.h:309
GammaGen(_Scalar _alpha=1, _Scalar _beta=1)
Construct a new gamma generator.
Definition: NormalExp.h:326
Base class of all univariate random generators.
Definition: Basic.h:33
Generator of reals on a lognormal distribution.
Definition: NormalExp.h:142
LognormalGen(_Scalar _mean=0, _Scalar _stdev=1)
Construct a new lognormal generator.
Definition: NormalExp.h:155
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:370
Generator of reals on a Student's t distribution.
Definition: NormalExp.h:188
StudentTGen(_Scalar _n=1)
Construct a new Student's t generator.
Definition: NormalExp.h:201
Generator of reals on a Weibull distribution.
Definition: NormalExp.h:488
WeibullGen(_Scalar _a=1, _Scalar _b=1)
Construct a new Weibull generator.
Definition: NormalExp.h:502
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:1158
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:1278
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:1086
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:1206
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:1040
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:1065
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:924
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:1324
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:1111
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:852
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:878
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:900
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:1350
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:1228
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:1372
const NormalType< Derived, Urng > normalLike(Derived &o, Urng &&urng)
generates reals on a standard normal distribution (mean = 0, stdev=1)
Definition: NormalExp.h:944
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:1018
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:831
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:1132
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:1255
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:1180
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:1303