EigenRand  0.3.0
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  while (1)
48  {
49  v1 = 2 * ur(rng) - 1;
50  v2 = 2 * ur(rng) - 1;
51  sx = v1 * v1 + v2 * v2;
52  if (sx && sx < 1) break;
53  }
54  _Scalar fx = std::sqrt((_Scalar)-2.0 * std::log(sx) / sx);
55  OptCacheStore::get<_Scalar>() = fx * v2;
56  return fx * v1;
57  }
58 
59  template<typename Packet, typename Rng>
60  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
61  {
62  using namespace Eigen::internal;
63  if (valid)
64  {
65  valid = false;
66  return OptCacheStore::template get<Packet>();
67  }
68  valid = true;
69  Packet u1 = ur.template packetOp<Packet>(rng),
70  u2 = ur.template packetOp<Packet>(rng);
71 
72  u1 = psub(pset1<Packet>(1), u1);
73 
74  auto radius = psqrt(pmul(pset1<Packet>(-2), plog(u1)));
75  auto theta = pmul(pset1<Packet>(2 * constant::pi), u2);
76  Packet sintheta, costheta;
77 
78  psincos(theta, sintheta, costheta);
79  OptCacheStore::template get<Packet>() = pmul(radius, costheta);
80  return pmul(radius, sintheta);
81  }
82  };
83 
89  template<typename _Scalar>
90  class NormalGen : public GenBase<NormalGen<_Scalar>, _Scalar>
91  {
92  static_assert(std::is_floating_point<_Scalar>::value, "normalDist needs floating point types.");
93  StdNormalGen<_Scalar> stdnorm;
94  _Scalar mean = 0, stdev = 1;
95 
96  public:
97  using Scalar = _Scalar;
98 
105  NormalGen(_Scalar _mean = 0, _Scalar _stdev = 1)
106  : mean{ _mean }, stdev{ _stdev }
107  {
108  }
109 
110  NormalGen(const NormalGen&) = default;
111  NormalGen(NormalGen&&) = default;
112 
113  NormalGen& operator=(const NormalGen&) = default;
114  NormalGen& operator=(NormalGen&&) = default;
115 
116  template<typename Rng>
117  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
118  {
119  using namespace Eigen::internal;
120  return stdnorm(std::forward<Rng>(rng)) * stdev + mean;
121  }
122 
123  template<typename Packet, typename Rng>
124  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
125  {
126  using namespace Eigen::internal;
127  return padd(pmul(
128  stdnorm.template packetOp<Packet>(std::forward<Rng>(rng)),
129  pset1<Packet>(stdev)
130  ), pset1<Packet>(mean));
131  }
132  };
133 
139  template<typename _Scalar>
140  class LognormalGen : public GenBase<LognormalGen<_Scalar>, _Scalar>
141  {
142  static_assert(std::is_floating_point<_Scalar>::value, "lognormalDist needs floating point types.");
143  NormalGen<_Scalar> norm;
144 
145  public:
146  using Scalar = _Scalar;
147 
154  LognormalGen(_Scalar _mean = 0, _Scalar _stdev = 1)
155  : norm{ _mean, _stdev }
156  {
157  }
158 
159  LognormalGen(const LognormalGen&) = default;
160  LognormalGen(LognormalGen&&) = default;
161 
162  LognormalGen& operator=(const LognormalGen&) = default;
163  LognormalGen& operator=(LognormalGen&&) = default;
164 
165  template<typename Rng>
166  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
167  {
168  using namespace Eigen::internal;
169  return std::exp(norm(std::forward<Rng>(rng)));
170  }
171 
172  template<typename Packet, typename Rng>
173  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
174  {
175  using namespace Eigen::internal;
176  return pexp(norm.template packetOp<Packet>(std::forward<Rng>(rng)));
177  }
178  };
179 
185  template<typename _Scalar>
186  class StudentTGen : public GenBase<StudentTGen<_Scalar>, _Scalar>
187  {
188  static_assert(std::is_floating_point<_Scalar>::value, "studentT needs floating point types.");
190  _Scalar n;
191 
192  public:
193  using Scalar = _Scalar;
194 
200  StudentTGen(_Scalar _n = 1)
201  : n{ _n }
202  {
203  }
204 
205  StudentTGen(const StudentTGen&) = default;
206  StudentTGen(StudentTGen&&) = default;
207 
208  StudentTGen& operator=(const StudentTGen&) = default;
209  StudentTGen& operator=(StudentTGen&&) = default;
210 
211  template<typename Rng>
212  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
213  {
214  using namespace Eigen::internal;
215  _Scalar v1, v2, sx;
216  while (1)
217  {
218  v1 = 2 * ur(rng) - 1;
219  v2 = 2 * ur(rng) - 1;
220  sx = v1 * v1 + v2 * v2;
221  if (sx && sx < 1) break;
222  }
223 
224  _Scalar fx = std::sqrt(n * (std::pow(sx, -2 / n) - 1) / sx);
225  return fx * v1;
226  }
227 
228  template<typename Packet, typename Rng>
229  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
230  {
231  using namespace Eigen::internal;
232  Packet u1 = ur.template packetOp<Packet>(rng),
233  u2 = ur.template packetOp<Packet>(rng);
234 
235  u1 = psub(pset1<Packet>(1), u1);
236  auto pn = pset1<Packet>(n);
237  auto radius = psqrt(pmul(pn,
238  psub(pexp(pmul(plog(u1), pset1<Packet>(-2 / n))), pset1<Packet>(1))
239  ));
240  auto theta = pmul(pset1<Packet>(2 * constant::pi), u2);
241  //Packet sintheta, costheta;
242  //psincos(theta, sintheta, costheta);
243  return pmul(radius, psin(theta));
244  }
245  };
246 
247  template<typename> class GammaGen;
248 
254  template<typename _Scalar>
255  class ExponentialGen : public GenBase<ExponentialGen<_Scalar>, _Scalar>
256  {
257  friend GammaGen<_Scalar>;
258  static_assert(std::is_floating_point<_Scalar>::value, "expDist needs floating point types.");
260  _Scalar lambda = 1;
261 
262  public:
263  using Scalar = _Scalar;
264 
270  ExponentialGen(_Scalar _lambda = 1)
271  : lambda{ _lambda }
272  {
273  }
274 
275  ExponentialGen(const ExponentialGen&) = default;
276  ExponentialGen(ExponentialGen&&) = default;
277 
278  ExponentialGen& operator=(const ExponentialGen&) = default;
279  ExponentialGen& operator=(ExponentialGen&&) = default;
280 
281  template<typename Rng>
282  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
283  {
284  using namespace Eigen::internal;
285  return -std::log(1 - ur(std::forward<Rng>(rng))) / lambda;
286  }
287 
288  template<typename Packet, typename Rng>
289  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
290  {
291  using namespace Eigen::internal;
292  return pnegate(pdiv(plog(
293  psub(pset1<Packet>(1), ur.template packetOp<Packet>(std::forward<Rng>(rng)))
294  ), pset1<Packet>(lambda)));
295  }
296  };
297 
298  template<typename> class NegativeBinomialGen;
299 
305  template<typename _Scalar>
306  class GammaGen : OptCacheStore, public GenBase<GammaGen<_Scalar>, _Scalar>
307  {
308  template<typename _Ty>
309  friend class NegativeBinomialGen;
310  static_assert(std::is_floating_point<_Scalar>::value, "gammaDist needs floating point types.");
311  int cache_rest_cnt = 0;
313  _Scalar alpha, beta, px, sqrt;
314 
315  public:
316  using Scalar = _Scalar;
317 
324  GammaGen(_Scalar _alpha = 1, _Scalar _beta = 1)
325  : alpha{ _alpha }, beta{ _beta }
326  {
327  px = constant::e / (alpha + constant::e);
328  sqrt = std::sqrt(2 * alpha - 1);
329  }
330 
331  GammaGen(const GammaGen&) = default;
332  GammaGen(GammaGen&&) = default;
333 
334  GammaGen& operator=(const GammaGen&) = default;
335  GammaGen& operator=(GammaGen&&) = default;
336 
337  template<typename Rng>
338  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
339  {
340  using namespace Eigen::internal;
341  if (alpha < 1)
342  {
343  _Scalar ux, vx, xx, qx;
344  while (1)
345  {
346  ux = expon.ur(rng);
347  vx = expon.ur.nzur_scalar(rng);
348 
349  if (ux < px)
350  {
351  xx = std::pow(vx, 1 / alpha);
352  qx = std::exp(-xx);
353  }
354  else
355  {
356  xx = 1 - std::log(vx);
357  qx = std::pow(xx, alpha - 1);
358  }
359 
360  if (expon.ur(rng) < qx)
361  {
362  return beta * xx;
363  }
364  }
365  }
366  if (alpha == 1)
367  {
368  return beta * expon(rng);
369  }
370  int count;
371  if ((count = alpha) == alpha && count < 20)
372  {
373  _Scalar yx;
374  yx = expon.ur.nzur_scalar(rng);
375  while (--count)
376  {
377  yx *= expon.ur.nzur_scalar(rng);
378  }
379  return -beta * std::log(yx);
380  }
381 
382  while (1)
383  {
384  _Scalar yx, xx;
385  yx = std::tan(constant::pi * expon.ur(rng));
386  xx = sqrt * yx + alpha - 1;
387  if (xx <= 0) continue;
388  if (expon.ur(rng) <= (1 + yx * yx)
389  * std::exp((alpha - 1) * std::log(xx / (alpha - 1)) - sqrt * yx))
390  {
391  return beta * xx;
392  }
393  }
394  }
395 
396  template<typename Packet, typename Rng>
397  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
398  {
399  using namespace Eigen::internal;
400  using RUtils = RandUtils<Packet, Rng>;
401  auto& cm = Rand::detail::CompressMask<sizeof(Packet)>::get_inst();
402 
403  RUtils ru;
404  if (alpha < 1)
405  {
406  while (1)
407  {
408  Packet ux = ru.uniform_real(rng);
409  Packet vx = ru.nonzero_uniform_real(rng);
410 
411  Packet xx = pexp(pmul(pset1<Packet>(1 / alpha), plog(vx)));
412  Packet qx = pexp(pnegate(xx));
413 
414  Packet xx2 = psub(pset1<Packet>(1), plog(vx));
415  Packet qx2 = pexp(pmul(plog(xx2), pset1<Packet>(alpha - 1)));
416 
417  auto c = pcmplt(ux, pset1<Packet>(px));
418  xx = pblendv(c, xx, xx2);
419  qx = pblendv(c, qx, qx2);
420 
421  ux = ru.uniform_real(rng);
422  Packet cands = pmul(pset1<Packet>(beta), xx);
423  bool full = false;
424  cache_rest_cnt = cm.compress_append(cands, pcmplt(ux, qx),
425  OptCacheStore::template get<Packet>(), cache_rest_cnt, full);
426  if (full) return cands;
427  }
428  }
429  if (alpha == 1)
430  {
431  return pmul(pset1<Packet>(beta),
432  expon.template packetOp<Packet>(rng)
433  );
434  }
435  int count;
436  if ((count = alpha) == alpha && count < 20)
437  {
438  RUtils ru;
439  Packet ux, yx;
440  yx = ru.nonzero_uniform_real(rng);
441  while (--count)
442  {
443  yx = pmul(yx, ru.nonzero_uniform_real(rng));
444  }
445  return pnegate(pmul(pset1<Packet>(beta), plog(yx)));
446  }
447  else
448  {
449  while (1)
450  {
451  Packet alpha_1 = pset1<Packet>(alpha - 1);
452  Packet ys, yc;
453  psincos(pmul(pset1<Packet>(constant::pi), ru.uniform_real(rng)), ys, yc);
454  Packet yx = pdiv(ys, yc);
455  Packet xx = padd(pmul(pset1<Packet>(sqrt), yx), alpha_1);
456  auto c = pcmplt(pset1<Packet>(0), xx);
457  Packet ux = ru.uniform_real(rng);
458  Packet ub = pmul(padd(pmul(yx, yx), pset1<Packet>(1)),
459  pexp(psub(
460  pmul(alpha_1, plog(pdiv(xx, alpha_1))),
461  pmul(yx, pset1<Packet>(sqrt))
462  ))
463  );
464  c = pand(c, pcmple(ux, ub));
465  Packet cands = pmul(pset1<Packet>(beta), xx);
466  bool full = false;
467  cache_rest_cnt = cm.compress_append(cands, c,
468  OptCacheStore::template get<Packet>(), cache_rest_cnt, full);
469  if (full) return cands;
470  }
471  }
472  }
473  };
474 
480  template<typename _Scalar>
481  class WeibullGen : public GenBase<WeibullGen<_Scalar>, _Scalar>
482  {
483  static_assert(std::is_floating_point<_Scalar>::value, "weilbullDist needs floating point types.");
485  _Scalar a = 1, b = 1;
486 
487  public:
488  using Scalar = _Scalar;
489 
496  WeibullGen(_Scalar _a = 1, _Scalar _b = 1)
497  : a{ _a }, b{ _b }
498  {
499  }
500 
501  WeibullGen(const WeibullGen&) = default;
502  WeibullGen(WeibullGen&&) = default;
503 
504  WeibullGen& operator=(const WeibullGen&) = default;
505  WeibullGen& operator=(WeibullGen&&) = default;
506 
507  template<typename Rng>
508  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
509  {
510  using namespace Eigen::internal;
511  return std::pow(-std::log(1 - ur(std::forward<Rng>(rng))), 1 / a) * b;
512  }
513 
514  template<typename Packet, typename Rng>
515  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
516  {
517  using namespace Eigen::internal;
518  return pmul(pexp(pmul(plog(pnegate(plog(
519  psub(pset1<Packet>(1), ur.template packetOp<Packet>(std::forward<Rng>(rng)))
520  ))), pset1<Packet>(1 / a))), pset1<Packet>(b));
521  }
522  };
523 
529  template<typename _Scalar>
530  class ExtremeValueGen : public GenBase<ExtremeValueGen<_Scalar>, _Scalar>
531  {
532  static_assert(std::is_floating_point<_Scalar>::value, "extremeValueDist needs floating point types.");
534  _Scalar a = 0, b = 1;
535 
536  public:
537  using Scalar = _Scalar;
538 
545  ExtremeValueGen(_Scalar _a = 0, _Scalar _b = 1)
546  : a{ _a }, b{ _b }
547  {
548  }
549 
550  ExtremeValueGen(const ExtremeValueGen&) = default;
551  ExtremeValueGen(ExtremeValueGen&&) = default;
552 
553  ExtremeValueGen& operator=(const ExtremeValueGen&) = default;
554  ExtremeValueGen& operator=(ExtremeValueGen&&) = default;
555 
556  template<typename Rng>
557  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
558  {
559  using namespace Eigen::internal;
560  return (a - b * std::log(-std::log(ur.nzur_scalar(std::forward<Rng>(rng)))));
561  }
562 
563  template<typename Packet, typename Rng>
564  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
565  {
566  using namespace Eigen::internal;
567  using RUtils = RandUtils<Packet, Rng>;
568  return psub(pset1<Packet>(a),
569  pmul(plog(pnegate(plog(RUtils{}.nonzero_uniform_real(std::forward<Rng>(rng))))), pset1<Packet>(b))
570  );
571  }
572  };
573 
579  template<typename _Scalar>
580  class ChiSquaredGen : public GenBase<ChiSquaredGen<_Scalar>, _Scalar>
581  {
582  static_assert(std::is_floating_point<_Scalar>::value, "chiSquaredDist needs floating point types.");
584  public:
585  using Scalar = _Scalar;
586 
592  ChiSquaredGen(_Scalar n = 1)
593  : gamma{ n * _Scalar(0.5), 2 }
594  {
595  }
596 
597  ChiSquaredGen(const ChiSquaredGen&) = default;
598  ChiSquaredGen(ChiSquaredGen&&) = default;
599 
600  ChiSquaredGen& operator=(const ChiSquaredGen&) = default;
601  ChiSquaredGen& operator=(ChiSquaredGen&&) = default;
602 
603  template<typename Rng>
604  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
605  {
606  return gamma(rng);
607  }
608 
609  template<typename Packet, typename Rng>
610  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
611  {
612  return gamma.template packetOp<Packet>(rng);
613  }
614  };
615 
621  template<typename _Scalar>
622  class CauchyGen : public GenBase<CauchyGen<_Scalar>, _Scalar>
623  {
624  static_assert(std::is_floating_point<_Scalar>::value, "cauchyDist needs floating point types.");
626  _Scalar a = 0, b = 1;
627 
628  public:
629  using Scalar = _Scalar;
630 
637  CauchyGen(_Scalar _a = 0, _Scalar _b = 1)
638  : a{ _a }, b{ _b }
639  {
640  }
641 
642  CauchyGen(const CauchyGen&) = default;
643  CauchyGen(CauchyGen&&) = default;
644 
645  CauchyGen& operator=(const CauchyGen&) = default;
646  CauchyGen& operator=(CauchyGen&&) = default;
647 
648  template<typename Rng>
649  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
650  {
651  using namespace Eigen::internal;
652  return a + b * std::tan(constant::pi * (ur(std::forward<Rng>(rng)) - 0.5));
653  }
654 
655  template<typename Packet, typename Rng>
656  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
657  {
658  using namespace Eigen::internal;
659  Packet s, c;
660  psincos(pmul(pset1<Packet>(constant::pi),
661  psub(ur.template packetOp<Packet>(std::forward<Rng>(rng)), pset1<Packet>(0.5))
662  ), s, c);
663  return padd(pset1<Packet>(a),
664  pmul(pset1<Packet>(b), pdiv(s, c))
665  );
666  }
667  };
668 
669  template<typename> class FisherFGen;
670 
676  template<typename _Scalar>
677  class BetaGen : OptCacheStore, public GenBase<BetaGen<_Scalar>, _Scalar>
678  {
679  friend FisherFGen<_Scalar>;
680  static_assert(std::is_floating_point<_Scalar>::value, "betaDist needs floating point types.");
681  int cache_rest_cnt = 0;
683  _Scalar a, b;
684  GammaGen<_Scalar> gd1, gd2;
685 
686  public:
687  using Scalar = _Scalar;
688 
694  BetaGen(_Scalar _a = 1, _Scalar _b = 1)
695  : a{ _a }, b{ _b },
696  gd1{ _a }, gd2{ _b }
697  {
698  }
699 
700  BetaGen(const BetaGen&) = default;
701  BetaGen(BetaGen&&) = default;
702 
703  BetaGen& operator=(const BetaGen&) = default;
704  BetaGen& operator=(BetaGen&&) = default;
705 
706  template<typename Rng>
707  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
708  {
709  using namespace Eigen::internal;
710  if (a < 1 && b < 1)
711  {
712  _Scalar x, p1, p2;
713  while (1)
714  {
715  p1 = std::pow(ur(rng), 1 / a);
716  p2 = std::pow(ur(rng), 1 / b);
717  x = p1 + p2;
718  if (x <= 1) break;
719  }
720  return p1 / x;
721  }
722  else
723  {
724  _Scalar p1 = gd1(rng), p2 = gd2(rng);
725  return p1 / (p1 + p2);
726  }
727  }
728 
729  template<typename Packet, typename Rng>
730  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
731  {
732  using namespace Eigen::internal;
733  if (a < 1 && b < 1)
734  {
735  auto& cm = Rand::detail::CompressMask<sizeof(Packet)>::get_inst();
736  Packet x, p1, p2;
737  while (1)
738  {
739  p1 = pexp(pmul(plog(ur.template packetOp<Packet>(rng)), pset1<Packet>(1 / a)));
740  p2 = pexp(pmul(plog(ur.template packetOp<Packet>(rng)), pset1<Packet>(1 / b)));
741  x = padd(p1, p2);
742  Packet cands = pdiv(p1, x);
743  bool full = false;
744  cache_rest_cnt = cm.compress_append(cands, pcmple(x, pset1<Packet>(1)),
745  OptCacheStore::template get<Packet>(), cache_rest_cnt, full);
746  if (full) return cands;
747  }
748  }
749  else
750  {
751  auto p1 = gd1.template packetOp<Packet>(rng),
752  p2 = gd2.template packetOp<Packet>(rng);
753  return pdiv(p1, padd(p1, p2));
754  }
755  }
756  };
757 
763  template<typename _Scalar>
764  class FisherFGen : public GenBase<FisherFGen<_Scalar>, _Scalar>
765  {
766  static_assert(std::is_floating_point<_Scalar>::value, "fisherF needs floating point types.");
768  public:
769  using Scalar = _Scalar;
770 
776  FisherFGen(_Scalar m = 1, _Scalar n = 1)
777  : beta{ m * _Scalar(0.5), n * _Scalar(0.5) }
778  {
779  }
780 
781  FisherFGen(const FisherFGen&) = default;
782  FisherFGen(FisherFGen&&) = default;
783 
784  FisherFGen& operator=(const FisherFGen&) = default;
785  FisherFGen& operator=(FisherFGen&&) = default;
786 
787  template<typename Rng>
788  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
789  {
790  using namespace Eigen::internal;
791  auto x = beta(std::forward<Rng>(rng));
792  return beta.b / beta.a * x / (1 - x);
793  }
794 
795  template<typename Packet, typename Rng>
796  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
797  {
798  using namespace Eigen::internal;
799  auto x = beta.template packetOp<Packet>(std::forward<Rng>(rng));
800  return pdiv(pmul(pset1<Packet>(beta.b / beta.a), x), psub(pset1<Packet>(1), x));
801  }
802  };
803 
804 
805  template<typename Derived, typename Urng>
806  using BetaType = CwiseNullaryOp<internal::scalar_rng_adaptor<BetaGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
807 
821  template<typename Derived, typename Urng>
822  inline const BetaType<Derived, Urng>
823  beta(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
824  {
825  return {
826  rows, cols, { std::forward<Urng>(urng), BetaGen<typename Derived::Scalar>{a, b} }
827  };
828  }
829 
842  template<typename Derived, typename Urng>
843  inline const BetaType<Derived, Urng>
844  betaLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
845  {
846  return {
847  o.rows(), o.cols(), { std::forward<Urng>(urng), BetaGen<typename Derived::Scalar>{a, b} }
848  };
849  }
850 
851  template<typename Derived, typename Urng>
852  using CauchyType = CwiseNullaryOp<internal::scalar_rng_adaptor<CauchyGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
853 
868  template<typename Derived, typename Urng>
869  inline const CauchyType<Derived, Urng>
870  cauchy(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
871  {
872  return {
873  rows, cols, { std::forward<Urng>(urng), CauchyGen<typename Derived::Scalar>{a, b} }
874  };
875  }
876 
890  template<typename Derived, typename Urng>
891  inline const CauchyType<Derived, Urng>
892  cauchyLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
893  {
894  return {
895  o.rows(), o.cols(), { std::forward<Urng>(urng), CauchyGen<typename Derived::Scalar>{a, b} }
896  };
897  }
898 
899  template<typename Derived, typename Urng>
900  using NormalType = CwiseNullaryOp<internal::scalar_rng_adaptor<StdNormalGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
901 
914  template<typename Derived, typename Urng>
915  inline const NormalType<Derived, Urng>
916  normal(Index rows, Index cols, Urng&& urng)
917  {
918  return {
919  rows, cols, { std::forward<Urng>(urng) }
920  };
921  }
922 
934  template<typename Derived, typename Urng>
935  inline const NormalType<Derived, Urng>
936  normalLike(Derived& o, Urng&& urng)
937  {
938  return {
939  o.rows(), o.cols(), { std::forward<Urng>(urng) }
940  };
941  }
942 
943  template<typename Derived, typename Urng>
944  using Normal2Type = CwiseNullaryOp<internal::scalar_rng_adaptor<NormalGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
945 
960  template<typename Derived, typename Urng>
961  inline const Normal2Type<Derived, Urng>
962  normal(Index rows, Index cols, Urng&& urng, typename Derived::Scalar mean, typename Derived::Scalar stdev = 1)
963  {
964  return {
965  rows, cols, { std::forward<Urng>(urng), NormalGen<typename Derived::Scalar>{mean, stdev} }
966  };
967  }
968 
982  template<typename Derived, typename Urng>
983  inline const Normal2Type<Derived, Urng>
984  normalLike(Derived& o, Urng&& urng, typename Derived::Scalar mean, typename Derived::Scalar stdev = 1)
985  {
986  return {
987  o.rows(), o.cols(), { std::forward<Urng>(urng), NormalGen<typename Derived::Scalar>{mean, stdev} }
988  };
989  }
990 
991  template<typename Derived, typename Urng>
992  using LognormalType = CwiseNullaryOp<internal::scalar_rng_adaptor<LognormalGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
993 
1008  template<typename Derived, typename Urng>
1009  inline const LognormalType<Derived, Urng>
1010  lognormal(Index rows, Index cols, Urng&& urng, typename Derived::Scalar mean = 0, typename Derived::Scalar stdev = 1)
1011  {
1012  return {
1013  rows, cols, { std::forward<Urng>(urng), LognormalGen<typename Derived::Scalar>{mean, stdev} }
1014  };
1015  }
1016 
1030  template<typename Derived, typename Urng>
1031  inline const LognormalType<Derived, Urng>
1032  lognormalLike(Derived& o, Urng&& urng, typename Derived::Scalar mean = 0, typename Derived::Scalar stdev = 1)
1033  {
1034  return {
1035  o.rows(), o.cols(), { std::forward<Urng>(urng), LognormalGen<typename Derived::Scalar>{mean, stdev} }
1036  };
1037  }
1038 
1039  template<typename Derived, typename Urng>
1040  using StudentTType = CwiseNullaryOp<internal::scalar_rng_adaptor<StudentTGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1041 
1055  template<typename Derived, typename Urng>
1056  inline const StudentTType<Derived, Urng>
1057  studentT(Index rows, Index cols, Urng&& urng, typename Derived::Scalar n = 1)
1058  {
1059  return {
1060  rows, cols, { std::forward<Urng>(urng), StudentTGen<typename Derived::Scalar>{n} }
1061  };
1062  }
1063 
1076  template<typename Derived, typename Urng>
1077  inline const StudentTType<Derived, Urng>
1078  studentTLike(Derived& o, Urng&& urng, typename Derived::Scalar n = 1)
1079  {
1080  return {
1081  o.rows(), o.cols(), { std::forward<Urng>(urng), StudentTGen<typename Derived::Scalar>{n} }
1082  };
1083  }
1084 
1085  template<typename Derived, typename Urng>
1086  using ExponentialType = CwiseNullaryOp<internal::scalar_rng_adaptor<ExponentialGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1087 
1101  template<typename Derived, typename Urng>
1102  inline const ExponentialType<Derived, Urng>
1103  exponential(Index rows, Index cols, Urng&& urng, typename Derived::Scalar lambda = 1)
1104  {
1105  return {
1106  rows, cols, { std::forward<Urng>(urng), ExponentialGen<typename Derived::Scalar>{lambda} }
1107  };
1108  }
1109 
1122  template<typename Derived, typename Urng>
1123  inline const ExponentialType<Derived, Urng>
1124  exponentialLike(Derived& o, Urng&& urng, typename Derived::Scalar lambda = 1)
1125  {
1126  return {
1127  o.rows(), o.cols(), { std::forward<Urng>(urng), ExponentialGen<typename Derived::Scalar>{lambda} }
1128  };
1129  }
1130 
1131  template<typename Derived, typename Urng>
1132  using GammaType = CwiseNullaryOp<internal::scalar_rng_adaptor<GammaGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1133 
1148  template<typename Derived, typename Urng>
1149  inline const GammaType<Derived, Urng>
1150  gamma(Index rows, Index cols, Urng&& urng, typename Derived::Scalar alpha = 1, typename Derived::Scalar beta = 1)
1151  {
1152  return {
1153  rows, cols, { std::forward<Urng>(urng), GammaGen<typename Derived::Scalar>{alpha, beta} }
1154  };
1155  }
1156 
1170  template<typename Derived, typename Urng>
1171  inline const GammaType<Derived, Urng>
1172  gammaLike(Derived& o, Urng&& urng, typename Derived::Scalar alpha = 1, typename Derived::Scalar beta = 1)
1173  {
1174  return {
1175  o.rows(), o.cols(), { std::forward<Urng>(urng), GammaGen<typename Derived::Scalar>{alpha, beta} }
1176  };
1177  }
1178 
1179  template<typename Derived, typename Urng>
1180  using WeibullType = CwiseNullaryOp<internal::scalar_rng_adaptor<WeibullGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1181 
1196  template<typename Derived, typename Urng>
1197  inline const WeibullType<Derived, Urng>
1198  weibull(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
1199  {
1200  return {
1201  rows, cols, { std::forward<Urng>(urng), WeibullGen<typename Derived::Scalar>{a, b} }
1202  };
1203  }
1204 
1218  template<typename Derived, typename Urng>
1219  inline const WeibullType<Derived, Urng>
1220  weibullLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
1221  {
1222  return {
1223  o.rows(), o.cols(), { std::forward<Urng>(urng), WeibullGen<typename Derived::Scalar>{a, b} }
1224  };
1225  }
1226 
1227  template<typename Derived, typename Urng>
1228  using ExtremeValueType = CwiseNullaryOp<internal::scalar_rng_adaptor<ExtremeValueGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1229 
1245  template<typename Derived, typename Urng>
1246  inline const ExtremeValueType<Derived, Urng>
1247  extremeValue(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
1248  {
1249  return {
1250  rows, cols, { std::forward<Urng>(urng), ExtremeValueGen<typename Derived::Scalar>{a, b} }
1251  };
1252  }
1253 
1268  template<typename Derived, typename Urng>
1269  inline const ExtremeValueType<Derived, Urng>
1270  extremeValueLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
1271  {
1272  return {
1273  o.rows(), o.cols(), { std::forward<Urng>(urng), ExtremeValueGen<typename Derived::Scalar>{a, b} }
1274  };
1275  }
1276 
1277  template<typename Derived, typename Urng>
1278  using ChiSquaredType = CwiseNullaryOp<internal::scalar_rng_adaptor<ChiSquaredGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1279 
1293  template<typename Derived, typename Urng>
1294  inline const ChiSquaredType<Derived, Urng>
1295  chiSquared(Index rows, Index cols, Urng&& urng, typename Derived::Scalar n = 1)
1296  {
1297  return {
1298  rows, cols, { std::forward<Urng>(urng), ChiSquaredGen<typename Derived::Scalar>{n} }
1299  };
1300  }
1301 
1314  template<typename Derived, typename Urng>
1315  inline const ChiSquaredType<Derived, Urng>
1316  chiSquaredLike(Derived& o, Urng&& urng, typename Derived::Scalar n = 1)
1317  {
1318  return {
1319  o.rows(), o.cols(), { std::forward<Urng>(urng), ChiSquaredGen<typename Derived::Scalar>{n} }
1320  };
1321  }
1322 
1323  template<typename Derived, typename Urng>
1324  using FisherFType = CwiseNullaryOp<internal::scalar_rng_adaptor<FisherFGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1325 
1340  template<typename Derived, typename Urng>
1341  inline const FisherFType<Derived, Urng>
1342  fisherF(Index rows, Index cols, Urng&& urng, typename Derived::Scalar m = 1, typename Derived::Scalar n = 1)
1343  {
1344  return {
1345  rows, cols, { std::forward<Urng>(urng), FisherFGen<typename Derived::Scalar>{m, n} }
1346  };
1347  }
1348 
1362  template<typename Derived, typename Urng>
1363  inline const FisherFType<Derived, Urng>
1364  fisherFLike(Derived& o, Urng&& urng, typename Derived::Scalar m = 1, typename Derived::Scalar n = 1)
1365  {
1366  return {
1367  o.rows(), o.cols(), { std::forward<Urng>(urng), FisherFGen<typename Derived::Scalar>{m, n} }
1368  };
1369  }
1370  }
1371 }
1372 
1373 #endif
Generator of reals on a beta distribution.
Definition: NormalExp.h:678
BetaGen(_Scalar _a=1, _Scalar _b=1)
Construct a new beta generator.
Definition: NormalExp.h:694
Generator of reals on a Cauchy distribution.
Definition: NormalExp.h:623
CauchyGen(_Scalar _a=0, _Scalar _b=1)
Construct a new Cauchy generator.
Definition: NormalExp.h:637
Generator of reals on a chi-squared distribution.
Definition: NormalExp.h:581
ChiSquaredGen(_Scalar n=1)
Construct a new chi-squared generator.
Definition: NormalExp.h:592
Generator of reals on an exponential distribution.
Definition: NormalExp.h:256
ExponentialGen(_Scalar _lambda=1)
Construct a new exponential generator.
Definition: NormalExp.h:270
Generator of reals on an extreme value distribution.
Definition: NormalExp.h:531
ExtremeValueGen(_Scalar _a=0, _Scalar _b=1)
Construct a new extreme value generator.
Definition: NormalExp.h:545
Generator of reals on a Fisher's f distribution.
Definition: NormalExp.h:765
FisherFGen(_Scalar m=1, _Scalar n=1)
Construct a new Fisher's f generator.
Definition: NormalExp.h:776
Generator of reals on a gamma distribution.
Definition: NormalExp.h:307
GammaGen(_Scalar _alpha=1, _Scalar _beta=1)
Construct a new gamma generator.
Definition: NormalExp.h:324
Base class of all univariate random generators.
Definition: Basic.h:33
Generator of reals on a lognormal distribution.
Definition: NormalExp.h:141
LognormalGen(_Scalar _mean=0, _Scalar _stdev=1)
Construct a new lognormal generator.
Definition: NormalExp.h:154
Generator of integers on a negative binomial distribution.
Definition: GammaPoisson.h:30
Generator of reals on a normal distribution.
Definition: NormalExp.h:91
NormalGen(_Scalar _mean=0, _Scalar _stdev=1)
Construct a new normal generator.
Definition: NormalExp.h:105
Generator of reals on the standard normal distribution.
Definition: NormalExp.h:27
Generator of reals on a Student's t distribution.
Definition: NormalExp.h:187
StudentTGen(_Scalar _n=1)
Construct a new Student's t generator.
Definition: NormalExp.h:200
Generator of reals in a range [0, 1)
Definition: Basic.h:306
Generator of reals on a Weibull distribution.
Definition: NormalExp.h:482
WeibullGen(_Scalar _a=1, _Scalar _b=1)
Construct a new Weibull generator.
Definition: NormalExp.h:496
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:1150
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:1270
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:1078
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:1198
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:1032
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:1057
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:916
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:1316
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:1103
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:844
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:870
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:892
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:1342
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:1220
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:1364
const NormalType< Derived, Urng > normalLike(Derived &o, Urng &&urng)
generates reals on a standard normal distribution (mean = 0, stdev=1)
Definition: NormalExp.h:936
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:1010
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:823
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:1124
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:1247
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:1172
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:1295