58{
59
60namespace Funct
61{
62
76 , bool xm1, bool lower_tail
77 )
78{
79#ifdef STK_BETARATIO_DEBUG
80 stk_cout <<
_T(
"BetaRatio_ae(") << a <<
_T(
", ") << b <<
_T(
", ") << x <<
_T(
")\n");
81#endif
82
84
86
87 Real D = (xm1 ? -
log1p(-x) : -log(x)) * nu;
88
89 if (D == 0.) return lower_tail ? 1. : 0.;
90 if (Arithmetic<Real>::isInfinite(D)) return lower_tail ? 0. : 1.;
91
92 nu *= 12*nu;
93
97
100
101 term *= bm1;
102
103
104 term *= (b)*(b+1)/nu;
106 den += coef;
107 a_k += (ak_term *= D/(b+1));
108 num += coef * a_k;
109
110 term *= (b+2)*(b+3)/nu;
112 den += coef;
113 a_k += (ak_term *= D/(b+2));
114 a_k += (ak_term *= D/(b+3));
115 num += coef * a_k;
116
117 term *= (b+4)*(b+5)/nu;
119 den += coef;
120 a_k += (ak_term *= D/(b+4));
121 a_k += (ak_term *= D/(b+5));
122 num += coef * a_k;
123
124 term *= (b+6)*(b+7)/nu;
126 den += coef;
127 a_k += (ak_term *= D/(b+6));
128 a_k += (ak_term *= D/(b+7));
129 num += coef * a_k;
130
131 term *= (b+8)*(b+9)/nu;
133 den += coef;
134 a_k += (ak_term *= D/(b+8));
135 a_k += (ak_term *= D/(b+9));
136 num += coef * a_k;
137
138 term *= (b+10)*(b+11)/nu;
140 den += coef;
141 a_k += (ak_term *= D/(b+10));
142 a_k += (ak_term *= D/(b+11));
143 num += coef * a_k;
144
145 term *= (b+12)*(b+13)/nu;
147 den += coef;
148 a_k += (ak_term *= D/(b+12));
149 a_k += (ak_term *= D/(b+13));
150 num += coef * a_k;
151
152 term *= (b+14)*(b+15)/nu;
154 den += coef;
155 a_k += (ak_term *= D/(b+14));
156 a_k += (ak_term *= D/(b+15));
157 num += coef * a_k;
158
163}
164
181 , bool xm1, bool lower_tail
182 )
183{
184#ifdef STK_BETARATIO_DEBUG
185 stk_cout <<
_T(
"BetaRatio_sr(") << a <<
_T(
", ") << b <<
_T(
", ") << x <<
_T(
")\n");
186#endif
187
188 Real s = a+b, sx = s*x, sy = s*(1-x);
189
190 Real bt = ( Const::_1_SQRT2PI_*sqrt((a*b)/s)
193 )
195 )
196 );
197 Real y = (0.5 - x) + 0.5;
198 if (xm1) std::swap(x,y);
199
200 if (!bt) return lower_tail ? 0. : 1.;
201
202 int n = 1;
204 do
205 {
206 sum += (term = (c *= (1.-b/n)*x) / (a+n));
207 ++n;
208 }
209 while (std::abs(term) > std::abs(sum) * Arithmetic<Real>::epsilon());
210
211 return lower_tail ? bt*(1./a +
sum) : (1.-bt/a-bt*
sum);
212}
213
229static Real serie_up( Real
const& a, Real
const& b, Real x,
bool xm1,
int n)
230{
231
232 if (n==1)
return b1(a, b, x, xm1)/a;
233
234
235 Real s = a+b, sx=s*x, sy = s- sx;
236 Real x0 = (xm1) ? (0.5 -x) + 0.5 : x;
237 int l = std::min(std::max(0, (int)round( xm1 ? (sy-a+1)/x : (sx-a+1)/x0)), n-1);
238 Real sum1 = 0., sum2 = 1., s0 = s+l, a0 = a+l;
239
240 for (int k=n-l-2; k>=0; --k) { sum2 = 1. + sum2 *x0*(s0+k)/(a0+k+1);}
241
242 if (l>0)
243 {
244 sum1 = 1.;
245 for (int k=1; k<l; ++k) { sum1 = 1.+ sum1*(a+k)/((s+k-1)*x0);}
246 sum1 /= ((s0-1)*x0);
247 }
248
249 return b1(a+l, b, x, xm1) *(sum2/a0 + sum1);
250}
251
265 , bool xm1, bool lower_tail
266 )
267{
268#ifdef STK_BETARATIO_DEBUG
269 stk_cout <<
_T(
"BetaRatio_up(") << a <<
_T(
", ") << b <<
_T(
", ") << x <<
_T(
")\n");
270#endif
271
273
275
276 if (!a0) { --n; a0=1.;}
277
278 Real c= serie_up(a0, b, x, xm1, n) * (lower_tail ? - 1. : 1.);
279 return (b<=15) ?
betaRatio_sr(a0, b, x, xm1, lower_tail) +c
281}
282
303 , bool xm1, bool lower_tail
304 )
305{
306#ifdef STK_BETARATIO_DEBUG
307 stk_cout <<
_T(
"BetaRatio_cf(") << a <<
_T(
", ") << b <<
_T(
", ") << x <<
_T(
")\n");
308#endif
309
310 Real s = a+b, sx = s*x, sy = s-sx;
311
312
313
314
315 Real bt =
b1(a, b, x, xm1);
316 if (bt*Arithmetic<Real>::epsilon() == 0.) return lower_tail ? 0. : 1.;
317
318
319 Real Nold = 0, Ncur = 1.;
320
321 Real Dold = 1., Dcur = xm1 ? 1.-sy/(a+1.) : 1.-sx/(a+1.);
322
323 if (std::abs(Dcur) > 4294967296.)
324 {
325 Ncur /= Dcur;
326 Dold /= Dcur;
327 Dcur = 1.;
328 }
329
330 const Real x_4 = xm1 ? (0.125 - x/4.) + 0.125 : x/4.;
331 const Real cte_b1 = xm1 ? x/2. + 0.5 : (0.5 - x/2.) + 0.5;
332 const Real cte_b2 = xm1 ? (a-1.)*(b+s-1.)*((0.25-x/2.)+0.25) : (a-1.)*(b+s-1.)*x/2.;
333 const Real cte_a1 = a*(a-2.)*(b+s)*(b+s-2.), cte_a2 = (a-1.)*(b+s-1.)*x_4;
334
336
337 Real ap2n = a+2., ap2nm1 = a+1.,ap2nm2 = a;
338
339 for (int n=1; ; n++, ap2n += 2., ap2nm1 += 2., ap2nm2 += 2.)
340 {
341
342 Real a_n = (cte_a2/ap2nm1 - x_4) * (x_4 + cte_a2/ap2nm1) - cte_a1*(x_4/ap2n)*(x_4/ap2nm2) ;
343
344 if (a_n*Arithmetic<Real>::epsilon() == 0.) break;
345
346 Real b_n = cte_b1 - cte_b2/(ap2nm1*(ap2n+1));
347
348 Real anew = b_n * Ncur + a_n * Nold;
349 Nold = Ncur;
350 Ncur = anew;
351
352 if (Ncur*Arithmetic<Real>::epsilon() == 0.) { cf =0.; break;}
353 anew = b_n * Dcur + a_n * Dold;
354 Dold = Dcur;
355 Dcur = anew;
356
357 if (std::abs(Dcur) > 4294967296.)
358 {
359 Ncur /= Dcur;
360 Nold /= Dcur;
361 Dold /= Dcur;
362 Dcur = 1.;
363 }
364
365 if (std::abs(Ncur) > 4294967296.)
366 {
367 Ncur /= 4294967296.;
368 Nold /= 4294967296.;
369 Dold /= 4294967296.;
370 Dcur /= 4294967296.;
371 }
372
373 if (std::abs(Dcur) != 0)
374 {
376 cf = Ncur/Dcur;
377
378 if (std::abs(cf - cfold) < std::abs(cf)*Arithmetic<Real>::epsilon()) { break;}
379 }
380 }
381 return lower_tail ? bt*cf/a : 1-bt*cf/a;
382}
383
394static Real coefs_odd_se(std::vector<Real> &A)
395{
396
397 int n = A.size()-1;
398 int l = n/2;
399
400
401 Real U2lp1 =A[1]*A[n-1], T2lp1 =0;
402 for (int k=2; k<l; k++)
403 {
404 U2lp1 += A[k] * A[n-k];
405 T2lp1 += A[k+1]*A[n+1-k];
406 }
407
408 Real res = -( A[2]*A[n]*(n-1.)
409 + 2* U2lp1 + (n+2.) * T2lp1
410 + A[l]*A[l] + (l+1.) * A[l+1]*A[l+1]
411 ) / ((n+2.) * A[1]);
412
413 A.push_back(res);
414
415 return res;
416}
417
428static Real coefs_even_se( std::vector<Real> &A)
429{
430
431 int n = A.size()-1;
432 int l = (n+1)/2;
433
434 Real U2l =A[1]*A[n-1], T2l =0;
435
436 for (int k=2; k<l; k++)
437 {
438 U2l += A[k]*A[n-k];
439 T2l += A[k+1] *A[n+1-k];
440 }
441
442 Real res = -(A[2]*A[n]*(n-1.) + 2.*U2l + (n+2.) * T2l ) / ((n+2.) * A[1]);
443
444 A.push_back(res);
445
446 return res;
447}
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
487 , bool xm1, bool lower_tail
488 )
489{
490#ifdef STK_BETARATIO_DEBUG
491 stk_cout <<
_T(
"BetaRatio_se(") << a <<
_T(
", ") << b <<
_T(
", ") << x <<
_T(
")\n");
492#endif
493
494 Real s = a+b, p = a/s, q = b/s, sx = s*x, sy = s-sx;
495
497 Real z = (((x<p)&&!xm1)||((x>q)&&xm1)) ? -std::sqrt(z2) : std::sqrt(z2);
498
500
501 Real dnorm = Const::_1_SQRT2PI_ * exp(-z2/2.);
502
503 if (dnorm < Arithmetic<Real>::epsilon()) return pnorm;
504
505
506 Real a1 = std::sqrt(a)*std::sqrt(b)/s,
a2 = (b - a)/(3.*s), a2_a1 =
a2/
a1, sqrts = std::sqrt(s);
507
508
509 std::vector<Real> A, B;
510 A.reserve(10);
511 A.push_back(p);
514 A.push_back(
a1 * (a2_a1/2.+0.5) * (a2_a1/2.-0.5));
515 A.push_back(-0.4*
a2*((a2_a1/2.+0.5) * (a2_a1/2.-0.5)+1.));
516
518 + (A[3] * 3. * z
519 + (A[4] * 4. * (2+ z2)
520 + (coefs_odd_se(A) * 5. * z * (3 + z2)
521 + (coefs_even_se(A) * 6. * (2*4 + z2 * (4. + z2))
522 + (coefs_odd_se(A) * 7. * z *(5*3 + z2*(5 + z2))
523 + (coefs_even_se(A) * 8. * (2*4*6 + z2 * (4*6 + z2 *(6 + z2)))
524 + (coefs_odd_se(A) * 9. * z * (7*5*3 + z2 * (7*5 + z2 * (7+z2)))
525 + (coefs_even_se(A) * 10. * (2*4*6*8 + z2 * (4*6*8 + z2 *(6*8 + z2 * (8 + z2))))
526 + (coefs_odd_se(A) * 11. * z * (9*7*5*3 + z2 * (9*7*5 + z2 * (9*7+z2 * (9 + z2))))
527 )/sqrts)/sqrts)/sqrts)/sqrts)/sqrts)/sqrts)/sqrts)/sqrts)/sqrts)/sqrts;
528 Real den =
a1 + (A[3] + (A[5] + (A[7] + (A[9] + A[11] * 11./s) * 9./s)*7./s)*5./s)*3./s;
529
530
531 Real ratio = num/den;
532
533 return lower_tail ? pnorm - ratio * dnorm : pnorm + ratio * dnorm;
534}
535
536
537
538
539
540
541
542
543
544
545
546
547Real betaRatio( Real
const& a, Real
const& b, Real
const& x,
bool lower_tail)
548{
549
550 if (
isNA(a) ||
isNA(b) ||
isNA(x) )
return Arithmetic<Real>::NA();
551
552 if ((a<=0)||(b<=0))
555}
557{
558
559 if (x<=0) return lower_tail ? 0. : 1.;
560 if (x>=1) return lower_tail ? 1. : 0.;
561
563
564 if (std::max(a,b)<=15)
565 {
566 if ((a<=1 && x <=0.5)||(b<=1 && x>=0.5))
567 {
568 return (x <=0.5) ?
betaRatio_sr(a, b, x,
false, lower_tail)
570 }
571
572 if (a<=1)
return betaRatio_up(b, a, x,
true, !lower_tail);
573
574 if (b<=1)
return betaRatio_up(a, b, x,
false, lower_tail);
575
576 return (x <=0.5) ?
betaRatio_up(a, b, x,
false, lower_tail)
578 }
579
580 if (std::min(a,b)<=1)
581 {
582
583
584 if (a>=15)
return betaRatio_ae(a, b, x,
false, lower_tail);
585
586 if (b>=15)
return betaRatio_ae(b, a, x,
true, !lower_tail);
587 }
588
589
590 if ((std::min(a,b)<=60))
591 {
592
595 }
596
597 if ((x<0.97*p)||(x>1.03*p))
598 {
599
600 return (x < p) ?
betaRatio_cf(a, b, x,
false, lower_tail)
602 }
603
604 return (a<b) ?
betaRatio_se(a-1, b-1, x,
false, lower_tail)
606}
607
608}
609
610}
611
612#undef d1
613#undef d2
614#undef d3
615#undef d4
616#undef d5
617#undef d6
618#undef d7
619#undef d8
620
621#endif
#define STKDOMAIN_ERROR_2ARG(Where, Arg1, Arg2, Error)
#define stk_cout
Standard stk output stream.
#define _T(x)
Let x unmodified.
Real dev0(Real const &a, Real const &b)
compute the partial deviance .
Real betaRatio_se(Real const &a, Real const &b, Real const &x, bool xm1, bool lower_tail)
Compute the incomplete beta function ratio I_x(a,b) using the serie expansion method.
Real betaRatio_ae(Real const &a, Real const &b, Real const &x, bool xm1, bool lower_tail)
Compute the incomplete beta function ratio I_x(a,b) using the asymptotic expansion method.
Real log1p(Real const &x)
compute the function .
Real betaRatio(Real const &a, Real const &b, Real const &x, bool lower_tail=true)
Compute the incomplete beta function ratio Compute the beta ratio function.
Real betaRatio_cf(Real const &a, Real const &b, Real x, bool xm1, bool lower_tail=true)
Compute the incomplete beta function ratio using the continued fraction method.
Real betaRatio_up(Real const &a, Real const &b, Real const &x, bool xm1, bool lower_tail)
Compute the incomplete beta function ratio I_x(a,b) using its recurrence formula and its asymptotic e...
Real betaRatio_sr(Real const &a, Real const &b, Real x, bool xm1, bool lower_tail)
Compute the incomplete beta function ratio I_x(a,b) using its series representation.
Real poisson_pdf_raw(Real const &x, Real const &lambda)
Compute the Poisson density.
Real lgammaStirlingError(Real const &z)
Compute the error when we compute using the Stirling's formula.
Real normal_cdf_raw(Real const &x)
Compute the cumulative distribution function of the normal density.
Real gammaRatioQ(Real const &a, Real const &x)
Compute the incomplete gamma function ratio Q(a,x).
Real gammaRatioP(Real const &a, Real const &x)
Compute the incomplete gamma function ratio P(a,x).
bool isNA(Type const &x)
utility method allowing to know if a value is a NA (Not Available) value
Arrays::SumOp< Lhs, Rhs >::result_type sum(Lhs const &lhs, Rhs const &rhs)
convenience function for summing two arrays
double Real
STK fundamental type of Real values.
Real betaRatio_raw(Real const &a, Real const &b, Real const &x, bool lower_tail)