42 #include "../VectorTools.h" 43 #include "../NumConstants.h" 57 DEFAULT_GENERATOR->setSeed(seed);
82 assert(dblAlpha > 0.0);
85 else if (dblAlpha > 1.0)
106 vector<size_t> sample(n);
107 for (
unsigned int i = 0; i < n; i++)
112 for (
unsigned int j = 0; test &(j < probs.size()); j++)
114 cumprob += probs[j] / s;
123 sample[i] = probs.size();
144 rgdbl[1] = dblAlpha - 1.0;
145 rgdbl[2] = (dblAlpha - (1.0 / (6.0 * dblAlpha))) / rgdbl[1];
146 rgdbl[3] = 2.0 / rgdbl[1];
147 rgdbl[4] = rgdbl[3] + 2.0;
148 rgdbl[5] = 1.0 / sqrt(dblAlpha);
159 dblRand1 = dblRand2 + rgdbl[5] * (1.0 - 1.86 * dblRand1);
161 while (!(0.0 < dblRand1 && dblRand1 < 1.0));
163 double dblTemp = rgdbl[2] * dblRand2 / dblRand1;
165 if (rgdbl[3] * dblRand1 + dblTemp + 1.0 / dblTemp <= rgdbl[4] ||
166 rgdbl[3] * log(dblRand1) + dblTemp - log(dblTemp) < 1.0)
168 return dblTemp * rgdbl[1];
181 const double dblexp = exp(1.0);
184 double dblRand0 = giveRandomNumberBetweenZeroAndEntry(1.0, generator);
185 double dblRand1 = giveRandomNumberBetweenZeroAndEntry(1.0, generator);
186 if (dblRand0 <= (dblexp / (dblAlpha + dblexp)))
188 dblTemp = pow(((dblAlpha + dblexp) * dblRand0) /
189 dblexp, 1.0 / dblAlpha);
190 if (dblRand1 <= exp(-1.0 * dblTemp))
195 dblTemp = -1.0 * log((dblAlpha + dblexp) * (1.0 - dblRand0) / (dblAlpha * dblexp));
196 if (dblRand1 <= pow(dblTemp, dblAlpha - 1.0))
212 double a0 = -.322232431088, a1 = -1, a2 = -.342242088547, a3 = -.0204231210245;
213 double a4 = -.453642210148e-4, b0 = .0993484626060, b1 = .588581570495;
214 double b2 = .531103462366, b3 = .103537752850, b4 = .0038560700634;
215 double y, z = 0, p = prob, p1;
217 p1 = (p < 0.5 ? p : 1 - p);
221 y = sqrt (log(1 / (p1 * p1)));
222 z = y + ((((y * a4 + a3) * y + a2) * y + a1) * y + a0) / ((((y * b4 + b3) * y + b2) * y + b1) * y + b0);
223 return p < 0.5 ? -z : z;
234 double x = alpha, f = 0, z;
244 return f + (x - 0.5) * log(x) - x + .918938533204673
245 + (((-.000595238095238 * z + .000793650793651) * z - .002777777777778) * z
246 + .083333333333333) / x;
253 double p = alpha, g = ln_gamma_alpha;
254 double accurate = 1e-8, overflow = 1e30;
255 double factor, gin = 0, rn = 0, a = 0, b = 0, an = 0, dif = 0, term = 0;
256 vector<double> pn(6);
263 factor = exp(p * log(x) - x - g);
267 gin = 1; term = 1; rn = p;
270 term *= x / rn; gin += term;
278 a = 1 - p; b = a + x + 1; term = 0;
279 pn[0] = 1; pn[1] = x; pn[2] = x + 1; pn[3] = x * b;
282 a++; b += 2; term++; an = a * term;
283 for (i = 0; i < 2; i++)
285 pn[i + 4] = b * pn[i + 2] - an * pn[i];
289 rn = pn[4] / pn[5]; dif = fabs(gin - rn);
292 if (dif <= accurate * rn)
297 for (i = 0; i < 4; i++)
301 if (fabs(pn[4]) < overflow)
303 for (i = 0; i < 4; i++)
309 gin = 1 - factor * gin;
319 double e = .5e-6, aa = .6931471805, p = prob, g;
320 double xx, c, ch, a = 0, q = 0, p1 = 0, p2 = 0, t = 0, x = 0, b = 0, s1, s2, s3, s4, s5, s6;
322 if (p < .000002 || p > .999998 || v <= 0)
326 xx = v / 2; c = xx - 1;
327 if (v >= -1.24 * log(p))
330 ch = pow((p * xx * exp(g + xx * aa)), 1 / xx);
337 ch = 0.4; a = log(1 - p);
339 q = ch; p1 = 1 + ch * (4.67 + ch); p2 = ch * (6.73 + ch * (6.66 + ch));
340 t = -0.5 + (4.67 + 2 * ch) / p1 - (6.73 + ch * (13.32 + 3 * ch)) / p2;
341 ch -= (1 - exp(a + g + .5 * ch + c * aa) * p2 / p1) / t;
342 if (fabs(q / ch - 1) - .01 <= 0)
349 p1 = 0.222222 / v; ch = v * pow((x * sqrt(p1) + 1 - p1), 3.0);
350 if (ch > 2.2 * v + 6)
351 ch = -2 * (log(1 - p) - c * log(.5 * ch) + g);
353 q = ch; p1 = .5 * ch;
354 if ((t = incompleteGamma (p1, xx, g)) < 0)
356 std::cerr <<
"err IncompleteGamma" << std::endl;
360 t = p2 * exp(xx * aa + g + p1 - c * log(ch));
361 b = t / ch; a = 0.5 * t - b * c;
363 s1 = (210 + a * (140 + a * (105 + a * (84 + a * (70 + 60 * a))))) / 420;
364 s2 = (420 + a * (735 + a * (966 + a * (1141 + 1278 * a)))) / 2520;
365 s3 = (210 + a * (462 + a * (707 + 932 * a))) / 2520;
366 s4 = (252 + a * (672 + 1182 * a) + c * (294 + a * (889 + 1740 * a))) / 5040;
367 s5 = (84 + 264 * a + c * (175 + 606 * a)) / 2520;
368 s6 = (120 + c * (346 + 127 * c)) / 5040;
369 ch += t * (1 + 0.5 * t * s1 - b * c * (s1 - b * (s2 - b * (s3 - b * (s4 - b * (s5 - b * s6))))));
370 if (fabs(q / ch - 1) > e)
385 const static double a[5] = {
386 2.2352520354606839287,
387 161.02823106855587881,
388 1067.6894854603709582,
389 18154.981253343561249,
390 0.065682337918207449113
392 const static double b[4] = {
393 47.20258190468824187,
394 976.09855173777669322,
395 10260.932208618978205,
396 45507.789335026729956
398 const static double c[9] = {
399 0.39894151208813466764,
400 8.8831497943883759412,
401 93.506656132177855979,
402 597.27027639480026226,
403 2494.5375852903726711,
404 6848.1904505362823326,
405 11602.651437647350124,
406 9842.7148383839780218,
407 1.0765576773720192317e-8
409 const static double d[8] = {
410 22.266688044328115691,
411 235.38790178262499861,
412 1519.377599407554805,
413 6485.558298266760755,
414 18615.571640885098091,
415 34900.952721145977266,
416 38912.003286093271411,
417 19685.429676859990727
419 const static double p[6] = {
421 0.1274011611602473639,
422 0.022235277870649807,
423 0.001421619193227893466,
424 2.9112874951168792e-5,
425 0.02307344176494017303
427 const static double q[5] = {
429 0.468238212480865118,
430 0.0659881378689285515,
431 0.00378239633202758244,
432 7.29751555083966205e-5
435 double xden, xnum, temp, del, eps, xsq, y, cum;
448 for (i = 0; i < 3; ++i)
450 xnum = (xnum + a[i]) * xsq;
451 xden = (xden + b[i]) * xsq;
457 temp = x * (xnum + a[3]) / (xden + b[3]);
460 else if (y <= sqrt(32))
466 for (i = 0; i < 7; ++i)
468 xnum = (xnum + c[i]) * y;
469 xden = (xden + d[i]) * y;
471 temp = (xnum + c[7]) / (xden + d[7]);
473 xsq = trunc(y * 16) / 16;
474 del = (y - xsq) * (y + xsq);
475 cum = exp(-xsq * xsq * 0.5) * exp(-del * 0.5) * temp;
480 else if (-37.5193 < x && x < 8.2924)
485 for (i = 0; i < 4; ++i)
487 xnum = (xnum + p[i]) * xsq;
488 xden = (xden + q[i]) * xsq;
490 temp = xsq * (xnum + p[4]) / (xden + q[4]);
491 temp = (1 / sqrt(2 * M_PI) - temp) / y;
493 xsq = trunc(x * 16) / 16;
494 del = (x - xsq) * (x + xsq);
496 cum = exp(-xsq * xsq * 0.5) * exp(-del * 0.5) * temp;
514 return lnGamma(alpha) + lnGamma(beta) - lnGamma(alpha + beta);
527 double const1 = 2.30753;
528 double const2 = 0.27061;
529 double const3 = 0.99229;
530 double const4 = 0.04481;
533 int swap_tail, i_pb, i_inn;
534 double a, adj, logbeta, g, h, pp, prev, qq, r, s, t, tx, w, y, yprev;
536 volatile double xinbta;
538 if (alpha <= 0. || beta < 0.)
539 throw (
"RandomTools::qBeta wih non positive parameters");
541 if (prob < 0. || prob > 1.)
542 throw (
"RandomTools::qBeta wih bad probability");
545 logbeta = lnBeta(alpha, beta);
550 a = prob; pp = alpha; qq = beta; swap_tail = 0;
555 pp = beta; qq = alpha; swap_tail = 1;
561 r = sqrt(-2 * log(a));
562 y = r - (const1 + const2 * r) / (1. + (const3 + const4 * r) * r);
563 if (pp > 1 && qq > 1)
565 r = (y * y - 3.) / 6.;
566 s = 1. / (pp + pp - 1.);
567 t = 1. / (qq + qq - 1.);
569 w = y * sqrt(h + r) / h - (t - s) * (r + 5. / 6. - 2. / (3. * h));
570 xinbta = pp / (pp + qq * exp(w + w));
576 t = r * pow(1. - t + y * sqrt(t), 3.0);
578 xinbta = 1. - exp((log1p(-a) + log(qq) + logbeta) / qq);
581 t = (4. * pp + r - 2.) / t;
583 xinbta = exp((log(a * pp) + logbeta) / pp);
585 xinbta = 1. - 2. / (t + 1.);
599 else if (xinbta > upper)
612 double po = pow(10., -13 - 2.5 / (pp * pp) - 0.5 / (a * a));
613 acu = (lower > po) ? lower : po;
617 for (i_pb = 0; i_pb < 1000; i_pb++)
619 y = incompleteBeta(xinbta, pp, qq);
628 exp(logbeta + r * log(xinbta) + t * log1p(-xinbta));
630 prev = (fabs(adj) > lower) ? fabs(adj) : lower;
632 for (i_inn = 0; i_inn < 1000; i_inn++)
635 if (fabs(adj) < prev)
638 if (tx >= 0. && tx <= 1)
640 if ((prev <= acu) || (fabs(y) <= acu))
641 return swap_tail ? 1 - xinbta : xinbta;
642 if (tx != 0. && tx != 1)
648 if (fabs(tx - xinbta) < 1e-15 * xinbta)
649 return swap_tail ? 1 - xinbta : xinbta;
656 return swap_tail ? 1 - xinbta : xinbta;
672 big = 4.503599627370496e15;
673 biginv = 2.22044604925031308085e-16;
674 maxgam = 171.624376956302725;
678 if ((alpha <= 0) || (beta <= 0))
679 throw Exception(
"RandomTools::incompleteBeta not valid with non-positive parameters");
681 if ((x < 0) || (x > 1))
682 throw Exception(
"RandomTools::incompleteBeta out of bounds limit");
691 if ((beta * x <= 1.0) && (x <= 0.95))
693 return incompletebetaps(alpha, beta, x, maxgam);
697 if (x > alpha / (alpha + beta))
710 if (flag == 1 && (beta * x <= 1.0) && (x <= 0.95) )
712 t = incompletebetaps(alpha, beta, x, maxgam);
719 y = x * (alpha + beta - 2.0) - (alpha - 1.0);
722 w = incompletebetafe(alpha, beta, x, big, biginv);
726 w = incompletebetafe2(alpha, beta, x, big, biginv) / xc;
730 if ( (alpha + beta < maxgam) && (fabs(y) < maxlog) && (fabs(t) < maxlog) )
733 t = t * pow(x, alpha);
736 t = t * exp(lnGamma(alpha + beta) - (lnGamma(alpha) + lnGamma(beta)));
747 y = y + t + lnGamma(alpha + beta) - lnGamma(alpha) - lnGamma(beta);
748 y = y + log(w / alpha);
816 xk = -x * k1 * k2 / (k3 * k4);
817 pk = pkm1 + pkm2 * xk;
818 qk = qkm1 + qkm2 * xk;
823 xk = x * k5 * k6 / (k7 * k8);
824 pk = pkm1 + pkm2 * xk;
825 qk = qkm1 + qkm2 * xk;
836 t = fabs((ans - r) / r);
855 if (fabs(qk) + fabs(pk) > big)
857 pkm2 = pkm2 * biginv;
858 pkm1 = pkm1 * biginv;
859 qkm2 = qkm2 * biginv;
860 qkm1 = qkm1 * biginv;
862 if ((fabs(qk) < biginv) || (fabs(pk) < biginv))
932 xk = -z * k1 * k2 / (k3 * k4);
933 pk = pkm1 + pkm2 * xk;
934 qk = qkm1 + qkm2 * xk;
939 xk = z * k5 * k6 / (k7 * k8);
940 pk = pkm1 + pkm2 * xk;
941 qk = qkm1 + qkm2 * xk;
952 t = fabs((ans - r) / r);
971 if (fabs(qk) + fabs(pk) > big)
973 pkm2 = pkm2 * biginv;
974 pkm1 = pkm1 * biginv;
975 qkm2 = qkm2 * biginv;
976 qkm1 = qkm1 * biginv;
978 if ((fabs(qk) < biginv) || (fabs(pk) < biginv))
1022 u = (n - b) * x / n;
1033 t = exp(lnGamma(a + b) - (lnGamma(a) + lnGamma(b)));
1034 s = s * t * pow(x, a);
1038 t = lnGamma(a + b) - lnGamma(a) - lnGamma(b) + u + log(s);
This class allows to perform a correspondence analysis.
static double VERY_TINY()
This is the interface for the Random Number Generators.
virtual double drawNumber() const =0
Return a random number.