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  template<typename Rng>
114  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
115  {
116  using namespace Eigen::internal;
117  return stdnorm(std::forward<Rng>(rng)) * stdev + mean;
118  }
119 
120  template<typename Packet, typename Rng>
121  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
122  {
123  using namespace Eigen::internal;
124  return padd(pmul(
125  stdnorm.template packetOp<Packet>(std::forward<Rng>(rng)),
126  pset1<Packet>(stdev)
127  ), pset1<Packet>(mean));
128  }
129  };
130 
136  template<typename _Scalar>
137  class LognormalGen : public GenBase<LognormalGen<_Scalar>, _Scalar>
138  {
139  static_assert(std::is_floating_point<_Scalar>::value, "lognormalDist needs floating point types.");
140  NormalGen<_Scalar> norm;
141 
142  public:
143  using Scalar = _Scalar;
144 
151  LognormalGen(_Scalar _mean = 0, _Scalar _stdev = 1)
152  : norm{ _mean, _stdev }
153  {
154  }
155 
156  LognormalGen(const LognormalGen&) = default;
157  LognormalGen(LognormalGen&&) = default;
158 
159  template<typename Rng>
160  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
161  {
162  using namespace Eigen::internal;
163  return std::exp(norm(std::forward<Rng>(rng)));
164  }
165 
166  template<typename Packet, typename Rng>
167  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
168  {
169  using namespace Eigen::internal;
170  return pexp(norm.template packetOp<Packet>(std::forward<Rng>(rng)));
171  }
172  };
173 
179  template<typename _Scalar>
180  class StudentTGen : public GenBase<StudentTGen<_Scalar>, _Scalar>
181  {
182  static_assert(std::is_floating_point<_Scalar>::value, "studentT needs floating point types.");
184  _Scalar n;
185 
186  public:
187  using Scalar = _Scalar;
188 
194  StudentTGen(_Scalar _n = 1)
195  : n{ _n }
196  {
197  }
198 
199  StudentTGen(const StudentTGen&) = default;
200  StudentTGen(StudentTGen&&) = default;
201 
202  template<typename Rng>
203  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
204  {
205  using namespace Eigen::internal;
206  _Scalar v1, v2, sx;
207  while (1)
208  {
209  v1 = 2 * ur(rng) - 1;
210  v2 = 2 * ur(rng) - 1;
211  sx = v1 * v1 + v2 * v2;
212  if (sx && sx < 1) break;
213  }
214 
215  _Scalar fx = std::sqrt(n * (std::pow(sx, -2 / n) - 1) / sx);
216  return fx * v1;
217  }
218 
219  template<typename Packet, typename Rng>
220  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
221  {
222  using namespace Eigen::internal;
223  Packet u1 = ur.template packetOp<Packet>(rng),
224  u2 = ur.template packetOp<Packet>(rng);
225 
226  u1 = psub(pset1<Packet>(1), u1);
227  auto pn = pset1<Packet>(n);
228  auto radius = psqrt(pmul(pn,
229  psub(pexp(pmul(plog(u1), pset1<Packet>(-2 / n))), pset1<Packet>(1))
230  ));
231  auto theta = pmul(pset1<Packet>(2 * constant::pi), u2);
232  Packet sintheta, costheta;
233 
234  //psincos(theta, sintheta, costheta);
235  return pmul(radius, psin(theta));
236  }
237  };
238 
239  template<typename> class GammaGen;
240 
246  template<typename _Scalar>
247  class ExponentialGen : public GenBase<ExponentialGen<_Scalar>, _Scalar>
248  {
249  friend GammaGen<_Scalar>;
250  static_assert(std::is_floating_point<_Scalar>::value, "expDist needs floating point types.");
252  _Scalar lambda = 1;
253 
254  public:
255  using Scalar = _Scalar;
256 
262  ExponentialGen(_Scalar _lambda = 1)
263  : lambda{ _lambda }
264  {
265  }
266 
267  ExponentialGen(const ExponentialGen&) = default;
268  ExponentialGen(ExponentialGen&&) = default;
269 
270  template<typename Rng>
271  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
272  {
273  using namespace Eigen::internal;
274  return -std::log(1 - ur(std::forward<Rng>(rng))) / lambda;
275  }
276 
277  template<typename Packet, typename Rng>
278  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
279  {
280  using namespace Eigen::internal;
281  return pnegate(pdiv(plog(
282  psub(pset1<Packet>(1), ur.template packetOp<Packet>(std::forward<Rng>(rng)))
283  ), pset1<Packet>(lambda)));
284  }
285  };
286 
287  template<typename> class NegativeBinomialGen;
288 
294  template<typename _Scalar>
295  class GammaGen : OptCacheStore, public GenBase<GammaGen<_Scalar>, _Scalar>
296  {
297  template<typename _Ty>
298  friend class NegativeBinomialGen;
299  static_assert(std::is_floating_point<_Scalar>::value, "gammaDist needs floating point types.");
300  int cache_rest_cnt = 0;
302  _Scalar alpha, beta, px, sqrt;
303 
304  public:
305  using Scalar = _Scalar;
306 
313  GammaGen(_Scalar _alpha = 1, _Scalar _beta = 1)
314  : alpha{ _alpha }, beta{ _beta }
315  {
316  px = constant::e / (alpha + constant::e);
317  sqrt = std::sqrt(2 * alpha - 1);
318  }
319 
320  GammaGen(const GammaGen&) = default;
321  GammaGen(GammaGen&&) = default;
322 
323  template<typename Rng>
324  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
325  {
326  using namespace Eigen::internal;
327  if (alpha < 1)
328  {
329  _Scalar ux, vx, xx, qx;
330  while (1)
331  {
332  ux = expon.ur(rng);
333  vx = expon.ur.nzur_scalar(rng);
334 
335  if (ux < px)
336  {
337  xx = std::pow(vx, 1 / alpha);
338  qx = std::exp(-xx);
339  }
340  else
341  {
342  xx = 1 - std::log(vx);
343  qx = std::pow(xx, alpha - 1);
344  }
345 
346  if (expon.ur(rng) < qx)
347  {
348  return beta * xx;
349  }
350  }
351  }
352  if (alpha == 1)
353  {
354  return beta * expon(rng);
355  }
356  int count;
357  if ((count = alpha) == alpha && count < 20)
358  {
359  _Scalar yx;
360  yx = expon.ur.nzur_scalar(rng);
361  while (--count)
362  {
363  yx *= expon.ur.nzur_scalar(rng);
364  }
365  return -beta * std::log(yx);
366  }
367 
368  while (1)
369  {
370  _Scalar yx, xx;
371  yx = std::tan(constant::pi * expon.ur(rng));
372  xx = sqrt * yx + alpha - 1;
373  if (xx <= 0) continue;
374  if (expon.ur(rng) <= (1 + yx * yx)
375  * std::exp((alpha - 1) * std::log(xx / (alpha - 1)) - sqrt * yx))
376  {
377  return beta * xx;
378  }
379  }
380  }
381 
382  template<typename Packet, typename Rng>
383  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
384  {
385  using namespace Eigen::internal;
386  using RUtils = RandUtils<Packet, Rng>;
387  auto& cm = Rand::detail::CompressMask<sizeof(Packet)>::get_inst();
388 
389  RUtils ru;
390  if (alpha < 1)
391  {
392  while (1)
393  {
394  Packet ux = ru.uniform_real(rng);
395  Packet vx = ru.nonzero_uniform_real(rng);
396 
397  Packet xx = pexp(pmul(pset1<Packet>(1 / alpha), plog(vx)));
398  Packet qx = pexp(pnegate(xx));
399 
400  Packet xx2 = psub(pset1<Packet>(1), plog(vx));
401  Packet qx2 = pexp(pmul(plog(xx2), pset1<Packet>(alpha - 1)));
402 
403  auto c = pcmplt(ux, pset1<Packet>(px));
404  xx = pblendv(c, xx, xx2);
405  qx = pblendv(c, qx, qx2);
406 
407  ux = ru.uniform_real(rng);
408  Packet cands = pmul(pset1<Packet>(beta), xx);
409  bool full = false;
410  cache_rest_cnt = cm.compress_append(cands, pcmplt(ux, qx),
411  OptCacheStore::template get<Packet>(), cache_rest_cnt, full);
412  if (full) return cands;
413  }
414  }
415  if (alpha == 1)
416  {
417  return pmul(pset1<Packet>(beta),
418  expon.template packetOp<Packet>(rng)
419  );
420  }
421  int count;
422  if ((count = alpha) == alpha && count < 20)
423  {
424  RUtils ru;
425  Packet ux, yx;
426  yx = ru.nonzero_uniform_real(rng);
427  while (--count)
428  {
429  yx = pmul(yx, ru.nonzero_uniform_real(rng));
430  }
431  return pnegate(pmul(pset1<Packet>(beta), plog(yx)));
432  }
433  else
434  {
435  while (1)
436  {
437  Packet alpha_1 = pset1<Packet>(alpha - 1);
438  Packet ys, yc;
439  psincos(pmul(pset1<Packet>(constant::pi), ru.uniform_real(rng)), ys, yc);
440  Packet yx = pdiv(ys, yc);
441  Packet xx = padd(pmul(pset1<Packet>(sqrt), yx), alpha_1);
442  auto c = pcmplt(pset1<Packet>(0), xx);
443  Packet ux = ru.uniform_real(rng);
444  Packet ub = pmul(padd(pmul(yx, yx), pset1<Packet>(1)),
445  pexp(psub(
446  pmul(alpha_1, plog(pdiv(xx, alpha_1))),
447  pmul(yx, pset1<Packet>(sqrt))
448  ))
449  );
450  c = pand(c, pcmple(ux, ub));
451  Packet cands = pmul(pset1<Packet>(beta), xx);
452  bool full = false;
453  cache_rest_cnt = cm.compress_append(cands, c,
454  OptCacheStore::template get<Packet>(), cache_rest_cnt, full);
455  if (full) return cands;
456  }
457  }
458  }
459  };
460 
466  template<typename _Scalar>
467  class WeibullGen : public GenBase<WeibullGen<_Scalar>, _Scalar>
468  {
469  static_assert(std::is_floating_point<_Scalar>::value, "weilbullDist needs floating point types.");
471  _Scalar a = 1, b = 1;
472 
473  public:
474  using Scalar = _Scalar;
475 
482  WeibullGen(_Scalar _a = 1, _Scalar _b = 1)
483  : a{ _a }, b{ _b }
484  {
485  }
486 
487  WeibullGen(const WeibullGen&) = default;
488  WeibullGen(WeibullGen&&) = default;
489 
490  template<typename Rng>
491  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
492  {
493  using namespace Eigen::internal;
494  return std::pow(-std::log(1 - ur(std::forward<Rng>(rng))), 1 / a) * b;
495  }
496 
497  template<typename Packet, typename Rng>
498  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
499  {
500  using namespace Eigen::internal;
501  return pmul(pexp(pmul(plog(pnegate(plog(
502  psub(pset1<Packet>(1), ur.template packetOp<Packet>(std::forward<Rng>(rng)))
503  ))), pset1<Packet>(1 / a))), pset1<Packet>(b));
504  }
505  };
506 
512  template<typename _Scalar>
513  class ExtremeValueGen : public GenBase<ExtremeValueGen<_Scalar>, _Scalar>
514  {
515  static_assert(std::is_floating_point<_Scalar>::value, "extremeValueDist needs floating point types.");
517  _Scalar a = 0, b = 1;
518 
519  public:
520  using Scalar = _Scalar;
521 
528  ExtremeValueGen(_Scalar _a = 0, _Scalar _b = 1)
529  : a{ _a }, b{ _b }
530  {
531  }
532 
533  ExtremeValueGen(const ExtremeValueGen&) = default;
534  ExtremeValueGen(ExtremeValueGen&&) = default;
535 
536  template<typename Rng>
537  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
538  {
539  using namespace Eigen::internal;
540  return (a - b * std::log(-std::log(ur.nzur_scalar(std::forward<Rng>(rng)))));
541  }
542 
543  template<typename Packet, typename Rng>
544  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
545  {
546  using namespace Eigen::internal;
547  using RUtils = RandUtils<Packet, Rng>;
548  return psub(pset1<Packet>(a),
549  pmul(plog(pnegate(plog(RUtils{}.nonzero_uniform_real(std::forward<Rng>(rng))))), pset1<Packet>(b))
550  );
551  }
552  };
553 
559  template<typename _Scalar>
560  class ChiSquaredGen : public GenBase<ChiSquaredGen<_Scalar>, _Scalar>
561  {
562  static_assert(std::is_floating_point<_Scalar>::value, "chiSquaredDist needs floating point types.");
564  public:
565  using Scalar = _Scalar;
566 
572  ChiSquaredGen(_Scalar n = 1)
573  : gamma{ n * _Scalar(0.5), 2 }
574  {
575  }
576 
577  ChiSquaredGen(const ChiSquaredGen&) = default;
578  ChiSquaredGen(ChiSquaredGen&&) = default;
579 
580  template<typename Rng>
581  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
582  {
583  return gamma(rng);
584  }
585 
586  template<typename Packet, typename Rng>
587  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
588  {
589  return gamma.template packetOp<Packet>(rng);
590  }
591  };
592 
598  template<typename _Scalar>
599  class CauchyGen : public GenBase<CauchyGen<_Scalar>, _Scalar>
600  {
601  static_assert(std::is_floating_point<_Scalar>::value, "cauchyDist needs floating point types.");
603  _Scalar a = 0, b = 1;
604 
605  public:
606  using Scalar = _Scalar;
607 
614  CauchyGen(_Scalar _a = 0, _Scalar _b = 1)
615  : a{ _a }, b{ _b }
616  {
617  }
618 
619  CauchyGen(const CauchyGen&) = default;
620  CauchyGen(CauchyGen&&) = default;
621 
622  template<typename Rng>
623  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
624  {
625  using namespace Eigen::internal;
626  return a + b * std::tan(constant::pi * (ur(std::forward<Rng>(rng)) - 0.5));
627  }
628 
629  template<typename Packet, typename Rng>
630  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
631  {
632  using namespace Eigen::internal;
633  Packet s, c;
634  psincos(pmul(pset1<Packet>(constant::pi),
635  psub(ur.template packetOp<Packet>(std::forward<Rng>(rng)), pset1<Packet>(0.5))
636  ), s, c);
637  return padd(pset1<Packet>(a),
638  pmul(pset1<Packet>(b), pdiv(s, c))
639  );
640  }
641  };
642 
643  template<typename> class FisherFGen;
644 
650  template<typename _Scalar>
651  class BetaGen : OptCacheStore, public GenBase<BetaGen<_Scalar>, _Scalar>
652  {
653  friend FisherFGen<_Scalar>;
654  static_assert(std::is_floating_point<_Scalar>::value, "betaDist needs floating point types.");
655  int cache_rest_cnt = 0;
657  _Scalar a, b;
658  GammaGen<_Scalar> gd1, gd2;
659 
660  public:
661  using Scalar = _Scalar;
662 
668  BetaGen(_Scalar _a = 1, _Scalar _b = 1)
669  : a{ _a }, b{ _b },
670  gd1{ _a }, gd2{ _b }
671  {
672  }
673 
674  BetaGen(const BetaGen&) = default;
675  BetaGen(BetaGen&&) = default;
676 
677  template<typename Rng>
678  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
679  {
680  using namespace Eigen::internal;
681  if (a < 1 && b < 1)
682  {
683  _Scalar x, p1, p2;
684  while (1)
685  {
686  p1 = std::pow(ur(rng), 1 / a);
687  p2 = std::pow(ur(rng), 1 / b);
688  x = p1 + p2;
689  if (x <= 1) break;
690  }
691  return p1 / x;
692  }
693  else
694  {
695  _Scalar p1 = gd1(rng), p2 = gd2(rng);
696  return p1 / (p1 + p2);
697  }
698  }
699 
700  template<typename Packet, typename Rng>
701  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
702  {
703  using namespace Eigen::internal;
704  if (a < 1 && b < 1)
705  {
706  auto& cm = Rand::detail::CompressMask<sizeof(Packet)>::get_inst();
707  Packet x, p1, p2;
708  while (1)
709  {
710  p1 = pexp(pmul(plog(ur.template packetOp<Packet>(rng)), pset1<Packet>(1 / a)));
711  p2 = pexp(pmul(plog(ur.template packetOp<Packet>(rng)), pset1<Packet>(1 / b)));
712  x = padd(p1, p2);
713  Packet cands = pdiv(p1, x);
714  bool full = false;
715  cache_rest_cnt = cm.compress_append(cands, pcmple(x, pset1<Packet>(1)),
716  OptCacheStore::template get<Packet>(), cache_rest_cnt, full);
717  if (full) return cands;
718  }
719  }
720  else
721  {
722  auto p1 = gd1.template packetOp<Packet>(rng),
723  p2 = gd2.template packetOp<Packet>(rng);
724  return pdiv(p1, padd(p1, p2));
725  }
726  }
727  };
728 
734  template<typename _Scalar>
735  class FisherFGen : public GenBase<FisherFGen<_Scalar>, _Scalar>
736  {
737  static_assert(std::is_floating_point<_Scalar>::value, "fisherF needs floating point types.");
739  public:
740  using Scalar = _Scalar;
741 
747  FisherFGen(_Scalar m = 1, _Scalar n = 1)
748  : beta{ m * _Scalar(0.5), n * _Scalar(0.5) }
749  {
750  }
751 
752  FisherFGen(const FisherFGen&) = default;
753  FisherFGen(FisherFGen&&) = default;
754 
755  template<typename Rng>
756  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
757  {
758  using namespace Eigen::internal;
759  auto x = beta(std::forward<Rng>(rng));
760  return beta.b / beta.a * x / (1 - x);
761  }
762 
763  template<typename Packet, typename Rng>
764  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
765  {
766  using namespace Eigen::internal;
767  auto x = beta.template packetOp<Packet>(std::forward<Rng>(rng));
768  return pdiv(pmul(pset1<Packet>(beta.b / beta.a), x), psub(pset1<Packet>(1), x));
769  }
770  };
771 
772 
773  template<typename Derived, typename Urng>
774  using BetaType = CwiseNullaryOp<internal::scalar_rng_adaptor<BetaGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
775 
789  template<typename Derived, typename Urng>
790  inline const BetaType<Derived, Urng>
791  beta(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
792  {
793  return {
794  rows, cols, { std::forward<Urng>(urng), BetaGen<typename Derived::Scalar>{a, b} }
795  };
796  }
797 
810  template<typename Derived, typename Urng>
811  inline const BetaType<Derived, Urng>
812  betaLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
813  {
814  return {
815  o.rows(), o.cols(), { std::forward<Urng>(urng), BetaGen<typename Derived::Scalar>{a, b} }
816  };
817  }
818 
819  template<typename Derived, typename Urng>
820  using CauchyType = CwiseNullaryOp<internal::scalar_rng_adaptor<CauchyGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
821 
836  template<typename Derived, typename Urng>
837  inline const CauchyType<Derived, Urng>
838  cauchy(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
839  {
840  return {
841  rows, cols, { std::forward<Urng>(urng), CauchyGen<typename Derived::Scalar>{a, b} }
842  };
843  }
844 
858  template<typename Derived, typename Urng>
859  inline const CauchyType<Derived, Urng>
860  cauchyLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
861  {
862  return {
863  o.rows(), o.cols(), { std::forward<Urng>(urng), CauchyGen<typename Derived::Scalar>{a, b} }
864  };
865  }
866 
867  template<typename Derived, typename Urng>
868  using NormalType = CwiseNullaryOp<internal::scalar_rng_adaptor<StdNormalGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
869 
882  template<typename Derived, typename Urng>
883  inline const NormalType<Derived, Urng>
884  normal(Index rows, Index cols, Urng&& urng)
885  {
886  return {
887  rows, cols, { std::forward<Urng>(urng) }
888  };
889  }
890 
902  template<typename Derived, typename Urng>
903  inline const NormalType<Derived, Urng>
904  normalLike(Derived& o, Urng&& urng)
905  {
906  return {
907  o.rows(), o.cols(), { std::forward<Urng>(urng) }
908  };
909  }
910 
911  template<typename Derived, typename Urng>
912  using Normal2Type = CwiseNullaryOp<internal::scalar_rng_adaptor<NormalGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
913 
928  template<typename Derived, typename Urng>
929  inline const Normal2Type<Derived, Urng>
930  normal(Index rows, Index cols, Urng&& urng, typename Derived::Scalar mean, typename Derived::Scalar stdev = 1)
931  {
932  return {
933  rows, cols, { std::forward<Urng>(urng), NormalGen<typename Derived::Scalar>{mean, stdev} }
934  };
935  }
936 
950  template<typename Derived, typename Urng>
951  inline const Normal2Type<Derived, Urng>
952  normalLike(Derived& o, Urng&& urng, typename Derived::Scalar mean, typename Derived::Scalar stdev = 1)
953  {
954  return {
955  o.rows(), o.cols(), { std::forward<Urng>(urng), NormalGen<typename Derived::Scalar>{mean, stdev} }
956  };
957  }
958 
959  template<typename Derived, typename Urng>
960  using LognormalType = CwiseNullaryOp<internal::scalar_rng_adaptor<LognormalGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
961 
976  template<typename Derived, typename Urng>
977  inline const LognormalType<Derived, Urng>
978  lognormal(Index rows, Index cols, Urng&& urng, typename Derived::Scalar mean = 0, typename Derived::Scalar stdev = 1)
979  {
980  return {
981  rows, cols, { std::forward<Urng>(urng), LognormalGen<typename Derived::Scalar>{mean, stdev} }
982  };
983  }
984 
998  template<typename Derived, typename Urng>
999  inline const LognormalType<Derived, Urng>
1000  lognormalLike(Derived& o, Urng&& urng, typename Derived::Scalar mean = 0, typename Derived::Scalar stdev = 1)
1001  {
1002  return {
1003  o.rows(), o.cols(), { std::forward<Urng>(urng), LognormalGen<typename Derived::Scalar>{mean, stdev} }
1004  };
1005  }
1006 
1007  template<typename Derived, typename Urng>
1008  using StudentTType = CwiseNullaryOp<internal::scalar_rng_adaptor<StudentTGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1009 
1023  template<typename Derived, typename Urng>
1024  inline const StudentTType<Derived, Urng>
1025  studentT(Index rows, Index cols, Urng&& urng, typename Derived::Scalar n = 1)
1026  {
1027  return {
1028  rows, cols, { std::forward<Urng>(urng), StudentTGen<typename Derived::Scalar>{n} }
1029  };
1030  }
1031 
1044  template<typename Derived, typename Urng>
1045  inline const StudentTType<Derived, Urng>
1046  studentTLike(Derived& o, Urng&& urng, typename Derived::Scalar n = 1)
1047  {
1048  return {
1049  o.rows(), o.cols(), { std::forward<Urng>(urng), StudentTGen<typename Derived::Scalar>{n} }
1050  };
1051  }
1052 
1053  template<typename Derived, typename Urng>
1054  using ExponentialType = CwiseNullaryOp<internal::scalar_rng_adaptor<ExponentialGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1055 
1069  template<typename Derived, typename Urng>
1070  inline const ExponentialType<Derived, Urng>
1071  exponential(Index rows, Index cols, Urng&& urng, typename Derived::Scalar lambda = 1)
1072  {
1073  return {
1074  rows, cols, { std::forward<Urng>(urng), ExponentialGen<typename Derived::Scalar>{lambda} }
1075  };
1076  }
1077 
1090  template<typename Derived, typename Urng>
1091  inline const ExponentialType<Derived, Urng>
1092  exponentialLike(Derived& o, Urng&& urng, typename Derived::Scalar lambda = 1)
1093  {
1094  return {
1095  o.rows(), o.cols(), { std::forward<Urng>(urng), ExponentialGen<typename Derived::Scalar>{lambda} }
1096  };
1097  }
1098 
1099  template<typename Derived, typename Urng>
1100  using GammaType = CwiseNullaryOp<internal::scalar_rng_adaptor<GammaGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1101 
1116  template<typename Derived, typename Urng>
1117  inline const GammaType<Derived, Urng>
1118  gamma(Index rows, Index cols, Urng&& urng, typename Derived::Scalar alpha = 1, typename Derived::Scalar beta = 1)
1119  {
1120  return {
1121  rows, cols, { std::forward<Urng>(urng), GammaGen<typename Derived::Scalar>{alpha, beta} }
1122  };
1123  }
1124 
1138  template<typename Derived, typename Urng>
1139  inline const GammaType<Derived, Urng>
1140  gammaLike(Derived& o, Urng&& urng, typename Derived::Scalar alpha = 1, typename Derived::Scalar beta = 1)
1141  {
1142  return {
1143  o.rows(), o.cols(), { std::forward<Urng>(urng), GammaGen<typename Derived::Scalar>{alpha, beta} }
1144  };
1145  }
1146 
1147  template<typename Derived, typename Urng>
1148  using WeibullType = CwiseNullaryOp<internal::scalar_rng_adaptor<WeibullGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1149 
1164  template<typename Derived, typename Urng>
1165  inline const WeibullType<Derived, Urng>
1166  weibull(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
1167  {
1168  return {
1169  rows, cols, { std::forward<Urng>(urng), WeibullGen<typename Derived::Scalar>{a, b} }
1170  };
1171  }
1172 
1186  template<typename Derived, typename Urng>
1187  inline const WeibullType<Derived, Urng>
1188  weibullLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 1, typename Derived::Scalar b = 1)
1189  {
1190  return {
1191  o.rows(), o.cols(), { std::forward<Urng>(urng), WeibullGen<typename Derived::Scalar>{a, b} }
1192  };
1193  }
1194 
1195  template<typename Derived, typename Urng>
1196  using ExtremeValueType = CwiseNullaryOp<internal::scalar_rng_adaptor<ExtremeValueGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1197 
1213  template<typename Derived, typename Urng>
1214  inline const ExtremeValueType<Derived, Urng>
1215  extremeValue(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
1216  {
1217  return {
1218  rows, cols, { std::forward<Urng>(urng), ExtremeValueGen<typename Derived::Scalar>{a, b} }
1219  };
1220  }
1221 
1236  template<typename Derived, typename Urng>
1237  inline const ExtremeValueType<Derived, Urng>
1238  extremeValueLike(Derived& o, Urng&& urng, typename Derived::Scalar a = 0, typename Derived::Scalar b = 1)
1239  {
1240  return {
1241  o.rows(), o.cols(), { std::forward<Urng>(urng), ExtremeValueGen<typename Derived::Scalar>{a, b} }
1242  };
1243  }
1244 
1245  template<typename Derived, typename Urng>
1246  using ChiSquaredType = CwiseNullaryOp<internal::scalar_rng_adaptor<ChiSquaredGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1247 
1261  template<typename Derived, typename Urng>
1262  inline const ChiSquaredType<Derived, Urng>
1263  chiSquared(Index rows, Index cols, Urng&& urng, typename Derived::Scalar n = 1)
1264  {
1265  return {
1266  rows, cols, { std::forward<Urng>(urng), ChiSquaredGen<typename Derived::Scalar>{n} }
1267  };
1268  }
1269 
1282  template<typename Derived, typename Urng>
1283  inline const ChiSquaredType<Derived, Urng>
1284  chiSquaredLike(Derived& o, Urng&& urng, typename Derived::Scalar n = 1)
1285  {
1286  return {
1287  o.rows(), o.cols(), { std::forward<Urng>(urng), ChiSquaredGen<typename Derived::Scalar>{n} }
1288  };
1289  }
1290 
1291  template<typename Derived, typename Urng>
1292  using FisherFType = CwiseNullaryOp<internal::scalar_rng_adaptor<FisherFGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1293 
1308  template<typename Derived, typename Urng>
1309  inline const FisherFType<Derived, Urng>
1310  fisherF(Index rows, Index cols, Urng&& urng, typename Derived::Scalar m = 1, typename Derived::Scalar n = 1)
1311  {
1312  return {
1313  rows, cols, { std::forward<Urng>(urng), FisherFGen<typename Derived::Scalar>{m, n} }
1314  };
1315  }
1316 
1330  template<typename Derived, typename Urng>
1331  inline const FisherFType<Derived, Urng>
1332  fisherFLike(Derived& o, Urng&& urng, typename Derived::Scalar m = 1, typename Derived::Scalar n = 1)
1333  {
1334  return {
1335  o.rows(), o.cols(), { std::forward<Urng>(urng), FisherFGen<typename Derived::Scalar>{m, n} }
1336  };
1337  }
1338  }
1339 }
1340 
1341 #endif
Eigen::Rand::normalLike
const NormalType< Derived, Urng > normalLike(Derived &o, Urng &&urng)
generates reals on a standard normal distribution (mean = 0, stdev=1)
Definition: NormalExp.h:904
Eigen::Rand::GenBase
Base class of all univariate random generators.
Definition: Basic.h:33
Eigen::Rand::NormalGen::NormalGen
NormalGen(_Scalar _mean=0, _Scalar _stdev=1)
Construct a new normal generator.
Definition: NormalExp.h:105
Eigen::Rand::cauchyLike
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:860
Eigen::Rand::LognormalGen
Generator of reals on a lognormal distribution.
Definition: NormalExp.h:138
Eigen::Rand::GammaGen
Generator of reals on a gamma distribution.
Definition: NormalExp.h:296
Eigen::Rand::studentT
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:1025
Eigen::Rand::FisherFGen::FisherFGen
FisherFGen(_Scalar m=1, _Scalar n=1)
Construct a new Fisher's f generator.
Definition: NormalExp.h:747
Eigen::Rand::exponentialLike
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:1092
Eigen::Rand::exponential
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:1071
Eigen::Rand::studentTLike
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:1046
Eigen::Rand::betaLike
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:812
Eigen::Rand::normal
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:884
Eigen::Rand::BetaGen::BetaGen
BetaGen(_Scalar _a=1, _Scalar _b=1)
Construct a new beta generator.
Definition: NormalExp.h:668
Eigen::Rand::ExponentialGen
Generator of reals on an exponential distribution.
Definition: NormalExp.h:248
Eigen::Rand::ChiSquaredGen
Generator of reals on a chi-squared distribution.
Definition: NormalExp.h:561
Eigen::Rand::gammaLike
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:1140
Eigen::Rand::ExtremeValueGen
Generator of reals on an extreme value distribution.
Definition: NormalExp.h:514
Eigen::Rand::weibull
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:1166
Eigen::Rand::chiSquared
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:1263
Eigen::Rand::UniformRealGen
Generator of reals in a range [0, 1)
Definition: Basic.h:306
Eigen::Rand::beta
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:791
Eigen::Rand::StudentTGen::StudentTGen
StudentTGen(_Scalar _n=1)
Construct a new Student's t generator.
Definition: NormalExp.h:194
Eigen::Rand::lognormal
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:978
Eigen::Rand::extremeValue
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:1215
Eigen::Rand::LognormalGen::LognormalGen
LognormalGen(_Scalar _mean=0, _Scalar _stdev=1)
Construct a new lognormal generator.
Definition: NormalExp.h:151
Eigen::Rand::WeibullGen
Generator of reals on a Weibull distribution.
Definition: NormalExp.h:468
Eigen::Rand::CauchyGen::CauchyGen
CauchyGen(_Scalar _a=0, _Scalar _b=1)
Construct a new Cauchy generator.
Definition: NormalExp.h:614
Eigen::Rand::chiSquaredLike
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:1284
Eigen::Rand::ExtremeValueGen::ExtremeValueGen
ExtremeValueGen(_Scalar _a=0, _Scalar _b=1)
Construct a new extreme value generator.
Definition: NormalExp.h:528
Eigen::Rand::extremeValueLike
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:1238
Eigen::Rand::fisherF
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:1310
Eigen::Rand::FisherFGen
Generator of reals on a Fisher's f distribution.
Definition: NormalExp.h:736
Eigen::Rand::fisherFLike
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:1332
Eigen::Rand::StdNormalGen
Generator of reals on the standard normal distribution.
Definition: NormalExp.h:27
Eigen::Rand::cauchy
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:838
Eigen::Rand::gamma
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:1118
Eigen::Rand::WeibullGen::WeibullGen
WeibullGen(_Scalar _a=1, _Scalar _b=1)
Construct a new Weibull generator.
Definition: NormalExp.h:482
Eigen::Rand::lognormalLike
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:1000
Eigen::Rand::weibullLike
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:1188
Eigen::Rand::ExponentialGen::ExponentialGen
ExponentialGen(_Scalar _lambda=1)
Construct a new exponential generator.
Definition: NormalExp.h:262
Eigen::Rand::ChiSquaredGen::ChiSquaredGen
ChiSquaredGen(_Scalar n=1)
Construct a new chi-squared generator.
Definition: NormalExp.h:572
Eigen::Rand::BetaGen
Generator of reals on a beta distribution.
Definition: NormalExp.h:652
Eigen::Rand::NegativeBinomialGen
Generator of integers on a negative binomial distribution.
Definition: GammaPoisson.h:30
Eigen::Rand::GammaGen::GammaGen
GammaGen(_Scalar _alpha=1, _Scalar _beta=1)
Construct a new gamma generator.
Definition: NormalExp.h:313
Eigen::Rand::NormalGen
Generator of reals on a normal distribution.
Definition: NormalExp.h:91
Eigen::Rand::CauchyGen
Generator of reals on a Cauchy distribution.
Definition: NormalExp.h:600
Eigen::Rand::StudentTGen
Generator of reals on a Student's t distribution.
Definition: NormalExp.h:181