|
STK++ 1.0
|
00001 /*--------------------------------------------------------------------*/ 00002 /* Copyright (C) 2004-2007 Serge Iovleff 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as 00006 published by the Free Software Foundation; either version 2 of the 00007 License, or (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public 00015 License along with this program; if not, write to the 00016 Free Software Foundation, Inc., 00017 59 Temple Place, 00018 Suite 330, 00019 Boston, MA 02111-1307 00020 USA 00021 00022 Contact : Serge.Iovleff@stkpp.org 00023 */ 00024 00025 /* 00026 * Project: Analysis 00027 * Purpose: Implementation of functions around the beta function ratio 00028 * Author: Serge Iovleff, serge.iovleff@stkpp.org 00029 **/ 00030 00036 #include "../include/STK_Funct_betaRatio.h" 00037 #include "../include/STK_Funct_gammaRatio.h" 00038 #include "../include/STK_ISerie.h" 00039 #include "../include/STK_Algo.h" 00040 #include "../include/STK_Funct_gamma.h" 00041 #include "../include/STK_Funct_util.h" 00042 #include "../include/STK_Funct_raw.h" 00043 00044 #include "../../Arrays/include/STK_Vector.h" 00045 00046 namespace STK 00047 { 00048 00049 namespace Funct 00050 { 00051 00073 static Real betaRatio_cf( Real const& a 00074 , Real const& b 00075 , Real const& x 00076 , bool lower_tail = true 00077 , Integer const& iterMax = 1000 00078 ) 00079 { 00080 // Constants 00081 Real sum = a+b, y = (0.5 -x) + 0.5, res; 00082 /* Compute the Function: 00083 * B(a,b,x,y) = \frac{\Gamma(a+b)}{\Gamma(a) \Gamma(b)} x^{a} (1-x)^{b} 00084 */ 00085 Real bt = ( Const::_1_SQRT2PI_*sqrt((a*b)/sum) 00086 * exp( ( gammaLnStirlingError(sum) 00087 -gammaLnStirlingError(a) 00088 -gammaLnStirlingError(b) 00089 ) 00090 -(dev0(a, sum*x) + dev0(b, y*sum)) 00091 ) 00092 ); 00093 if (bt == 0.) return lower_tail ? 0. : 1.; 00094 00095 // initialize b_n 00096 Real bn = (1+a*y-b*x)/(a+1); // b_1 00097 // initialize numerator 00098 Real Nold = 0, Ncur = 1.; // = a_1 = 1 00099 // initialize denominator 00100 Real Dold = 1, Dcur = bn; // = b_1 00101 00102 // normalize if necessary 00103 if (abs(Dcur) > 4294967296.0) 00104 { 00105 Ncur /= Dcur; 00106 Dold /= Dcur; 00107 Dcur = 1.; 00108 } 00109 00110 // auxiliary constant variable 00111 const Real cte= (0.5-sum*x)+0.5; 00112 // dn (can be reused) 00113 Real dn = (a*sum*x)/(a+1); 00114 // result 00115 Real cf = 1/Dcur; 00116 // auxiliary variables 00117 Real ap2n = a+2, apn = a+1; 00118 // iterations 00119 for (Integer n=1; /*n<=iterMax*/; n++, apn++, ap2n += 2) 00120 { 00121 // compute auxiliaries variables 00122 Real nx = n*x, cn = n*(b*x-nx)/(ap2n-1); 00123 // compute a_n 00124 Real an = (cn/ap2n)*(dn/(ap2n-2)); 00125 // check trivial case) 00126 if (an == 0.) break; 00127 // update d_n 00128 dn = apn*(sum*x+nx)/(ap2n+1); 00129 // compute bn 00130 bn = cte + cn + dn; 00131 // compute numerator and denominator 00132 Real anew = bn * Ncur + an * Nold; 00133 Nold = Ncur; 00134 Ncur = anew; 00135 anew = bn * Dcur + an * Dold; 00136 Dold = Dcur; 00137 Dcur = anew; 00138 // normalize if necessary 00139 if (abs(Dcur) > 4294967296.0) 00140 { 00141 Ncur /= Dcur; 00142 Nold /= Dcur; 00143 Dold /= Dcur; 00144 Dcur = 1.; 00145 } 00146 // normalize if necessary with 2^32 00147 if (abs(Ncur) > 4294967296.0) 00148 { 00149 Ncur /= 4294967296.0; 00150 Nold /= 4294967296.0; 00151 Dold /= 4294967296.0; 00152 Dcur /= 4294967296.0; 00153 } 00154 // test D_n not too small 00155 if (abs(Dcur) != 0) 00156 { 00157 Real cfold = cf; 00158 cf = Ncur/Dcur; 00159 // check cv 00160 if (abs(cf - cfold) < abs(cf)*Arithmetic<Real>::epsilon()) 00161 { 00162 res = lower_tail ? bt*cf/a : 1-bt*cf/a; 00163 break; 00164 } 00165 } 00166 } 00167 #ifdef STK_DEBUG 00168 // result 00169 res = lower_tail ? bt*cf/a : 1-bt*cf/a; 00170 if (!Arithmetic<Real>::isFinite(res)) 00171 { 00172 std::cout << "in cf : bt= " << bt 00173 << " cf = " << cf 00174 << " a = " << a 00175 << "lt = " << lower_tail 00176 << "\n"; 00177 } 00178 return res; 00179 #else 00180 return lower_tail ? bt*cf/a : 1-bt*cf/a; 00181 #endif 00182 00183 } 00184 00185 /* @ingroup Analysis 00186 * @brief compute the coefs of the beta Ratio function in 00187 * its asymptotic expansion. 00188 * 00189 * Given the n-1 first coefs, compute and return the n-th 00190 * coefficient. The value is stored back to the Vector. The 00191 * formula for computing the coefficient is 00192 * \[ 00193 * a_{n} 00194 * = \frac{b-1}{(2n+1)!}+\frac{1}{n} 00195 * \sum_{k=1}^{n-1} \left[ 00196 * \frac{kb-n}{(2k+1)!} p_{n-k} 00197 * \right] 00198 * \f] 00199 * @param A vector of dimension 1:(n-1), n>=2, of the coefs 00200 * @param b second parameter of the beta function 00201 */ 00202 //static Real coefs_ae(Real const& b, Vector &A) 00203 //{ 00204 // // get the number of exising coefs 00205 // Integer n = A.size(); 00206 // // initialize the sum 00207 // Real sum = 0.0; 00208 // // update sum 00209 // for (Integer k=1; k<n; k++) 00210 // { 00211 // sum += (k*b/n-1)*A[n-k]/(factorial(2*k+1)); 00212 // } 00213 // // compute result 00214 // sum += (b-1)/factorial(2*n+1); 00215 // // save it in A 00216 // A.push_back(sum); 00217 // // and return it 00218 // return sum; 00219 //} 00220 00221 #define d1(z) (0.5) 00222 #define d2(z) (z/8. - 1./20.) 00223 #define d3(z) (z*(z/48.-1./40.)+1./105.) 00224 #define d4(z) (z*(z*(z/384.-1./160.)+101./16800.)-3./1400.) 00225 #define d5(z) (z*(z*(z*(z/3840.-1./960.)+61./33600.)-13./8400.) \ 00226 +1./1925.) 00227 #define d6(z) (z*(z*(z*(z*(z/46080.-1./7680.)+143./403200.) \ 00228 -59./112000.)+7999./19404000.)-691./5255250.) 00229 #define d7(z) (z*(z*(z*(z*(z*(z/645120.-1./76800.)+41./806400.) \ 00230 -11./96000.)+5941./38808000.)-2357./21021000.)+6./175175.) 00231 #define d8(z) (z*(z*(z*(z*(z*(z*(z/10321920.-1./921600.)+37./6451200.) \ 00232 -73./4032000.)+224137./6209280000.)-449747./10090080000.) \ 00233 +52037./1681680000.)-10851./1191190000.) 00234 00235 00249 static inline Real betaRatio_ae( Real const& a 00250 , Real const& b 00251 , Real const& x 00252 , bool xm1 00253 , bool lower_tail 00254 ) 00255 { 00256 // Compute b-1 00257 Real bm1 = b-1; 00258 // compute \nu = a+(b-1)/2 00259 Real nu = a+bm1/2.; 00260 // compute D = -\nu*log(x) 00261 Real D = (xm1 ? -log1p(-x) : -log(x)) * nu; 00262 // check trivial case 00263 if (D == 0.) return lower_tail ? 1. : 0.; 00264 if (Arithmetic<Real>::isInfinite(D)) return lower_tail ? 0. : 1.; 00265 // compute 12*\nu^2 00266 nu *= 12*nu; 00267 // variables for the series 00268 Real term = 1.; 00269 Real ak_term = 1.; 00270 Real a_k = 1.; 00271 // numerator and denominator 00272 Real den = term; 00273 Real num = 0.; 00274 // update term 00275 term *= bm1; 00276 // Generalized bernouilli coefs 00277 // coef 1 (d_1 = 1/2) 00278 term *= (b)*(b+1)/nu; 00279 Real coef = term/2; // d_1 = 1/2 00280 den += coef; 00281 a_k += (ak_term *= D/(b+1)); 00282 num += coef * a_k; 00283 // coef 2 00284 term *= (b+2)*(b+3)/nu; 00285 coef = d2(bm1)*term; 00286 den += coef; 00287 a_k += (ak_term *= D/(b+2)); 00288 a_k += (ak_term *= D/(b+3)); 00289 num += coef * a_k; 00290 // coef 3 00291 term *= (b+4)*(b+5)/nu; 00292 coef = d3(bm1)*term; 00293 den += coef; 00294 a_k += (ak_term *= D/(b+4)); 00295 a_k += (ak_term *= D/(b+5)); 00296 num += coef * a_k; 00297 // coef 4 00298 term *= (b+6)*(b+7)/nu; 00299 coef = d4(bm1)*term; 00300 den += coef; 00301 a_k += (ak_term *= D/(b+6)); 00302 a_k += (ak_term *= D/(b+7)); 00303 num += coef * a_k; 00304 // coef 5 00305 term *= (b+8)*(b+9)/nu; 00306 coef = d5(bm1)*term; 00307 den += coef; 00308 a_k += (ak_term *= D/(b+8)); 00309 a_k += (ak_term *= D/(b+9)); 00310 num += coef * a_k; 00311 // coef 6 00312 term *= (b+10)*(b+11)/nu; 00313 coef = d6(bm1)*term; 00314 den += coef; 00315 a_k += (ak_term *= D/(b+10)); 00316 a_k += (ak_term *= D/(b+11)); 00317 num += coef * a_k; 00318 // coef 7 00319 term *= (b+12)*(b+13)/nu; 00320 coef = d7(bm1)*term; 00321 den += coef; 00322 a_k += (ak_term *= D/(b+12)); 00323 a_k += (ak_term *= D/(b+13)); 00324 num += coef * a_k; 00325 // coef 8 00326 term *= (b+14)*(b+15)/nu; 00327 coef = d8(bm1)*term; 00328 den += coef; 00329 a_k += (ak_term *= D/(b+14)); 00330 a_k += (ak_term *= D/(b+15)); 00331 num += coef * a_k; 00332 // result (P or Q ?) 00333 return lower_tail ? gammaRatioQ(b, D) 00334 + (num / den) * poisson_pdf_raw(b, D) 00335 : gammaRatioP(b, D) 00336 - (num / den) * poisson_pdf_raw(b, D); 00337 } 00338 00351 static inline Real serie_up( Real const& s 00352 , Real const& a 00353 , Real const& x 00354 , Integer const& n 00355 ) 00356 { 00357 // initilize d0 and sum 00358 Real sum = 1./a; 00359 Real di = 1./a; 00360 // compute \sum_{i=0}^{n-1} \frac{d_i x^i}{a} 00361 for (Integer i=1; i<n; i++) 00362 sum += (di *= x*(s-1+i)/(a+i)); 00363 // return result 00364 return sum; 00365 } 00366 00380 static inline Real betaRatio_up( Real const& a 00381 , Real const& b 00382 , Real const& x 00383 , bool xm1 00384 , bool lower_tail 00385 ) 00386 { 00387 // number of iterations 00388 Integer n = Integer(a); 00389 // compute residual 00390 Real a0 = a-n; 00391 // zero case 00392 if (!a0) { --n; a0=1.;} 00393 // sum 00394 Real s= a0+b; 00395 // compute x and 1-x 00396 Real x0, y; 00397 if (xm1) 00398 { x0 = (0.5 -x) + 0.5; y =x;} 00399 else 00400 { x0 = x; y = (0.5 -x) + 0.5;} 00401 /* Compute the constant 00402 * B(a,b,x,y) = \frac{\Gamma(a+b)}{\Gamma(a) \Gamma(b)} x^a (1-x)^b 00403 * using saddle-point expansion 00404 */ 00405 Real bt = ( Const::_1_SQRT2PI_*sqrt((a0*b)/s) 00406 * exp( ( gammaLnStirlingError(s) 00407 -gammaLnStirlingError(a0) 00408 -gammaLnStirlingError(b) 00409 ) 00410 -(dev0(a0, s*x0) + dev0(b, y*s)) 00411 ) 00412 ); 00413 // check trivial case 00414 if (!bt) 00415 return betaRatio_ae(b, a0, x, !xm1, !lower_tail); 00416 // compute serie 00417 bt *= serie_up(s, a0, x0, n); 00418 // general case 00419 return lower_tail ? betaRatio_ae(b, a0, x, !xm1, !lower_tail) - bt 00420 : betaRatio_ae(b, a0, x, !xm1, !lower_tail) + bt; 00421 } 00422 00441 static Real betaRatio_sr( Real const& a 00442 , Real const& b 00443 , Real const& x 00444 , bool lower_tail 00445 ) 00446 { 00447 // Constant 00448 Real sum = a+b; 00449 // compute B(a,b,x,y) = \frac{\Gamma(a+b)}{\Gamma(a) \Gamma(b)} x^{a} 00450 Real bt = ( Const::_1_SQRT2PI_*sqrt((a*b)/sum) 00451 * exp( sum*x 00452 + ( gammaLnStirlingError(sum) 00453 -(gammaLnStirlingError(a)+gammaLnStirlingError(b)) 00454 ) 00455 -(dev0(a, sum*x) + dev0(b, sum)) 00456 ) 00457 ); 00458 // check factor 00459 if (!bt) return lower_tail ? 0. : 1.; 00460 // parameters 00461 Real term, n= 1., c = 1.; 00462 // sum = \sum_{n=1}^\infty (1-b/n) x^n /(a+n) 00463 sum = 0.0; 00464 do 00465 { 00466 sum += (term = (c *= (1-b/n)*x) / (a+n)); 00467 ++n; 00468 } 00469 while (abs(term) > abs(sum) * Arithmetic<Real>::epsilon()); 00470 // return result 00471 return lower_tail ? bt*(1/a + sum) 00472 : (1-bt/a)-(bt*sum); 00473 } 00474 00486 static Real coefs_odd_se( Real const& std, Real const& qmp, Vector &A) 00487 { 00488 // get the number of exising coefs (should be even) 00489 Integer n = A.size(); 00490 Integer t = n/2; 00491 // know case 00492 if (t==1) 00493 { 00494 // compute result 00495 Real sum = (qmp/3+std)*(qmp/3-std)/(4*std); 00496 // save it in A 00497 A.push_back(sum); 00498 // and return it 00499 return sum; 00500 } 00501 // initialize the sums 00502 Real sum, sum1 =0, sum2 =0; 00503 // update sum 00504 for (Integer k=1, k1=2; k<t; k++, k1++) 00505 { 00506 sum1 += A[k1]*A[n+1-k]; 00507 sum2 += A[k] *A[n-k]; 00508 } 00509 // compute the result 00510 sum = ( ((qmp*A[n] - A[t]*A[t])/2 - sum2)/(t+1) 00511 - sum1- A[t+1]*A[t+1]/2 00512 )/std; 00513 // save it in A 00514 A.push_back(sum); 00515 // and return it 00516 return sum; 00517 } 00518 00530 static Real coefs_even_se( Real const& std, Real const& qmp, Vector &A) 00531 { 00532 // get the number of exising coefs (should be odd) 00533 Integer n = A.size(); 00534 Integer t = n/2; 00535 // know case 00536 if (t==1) 00537 { 00538 // compute result 00539 Real sum = -qmp*(1+A[3]/std)*2/15; 00540 // save it in A 00541 A.push_back(sum); 00542 // and return it 00543 return sum; 00544 } 00545 // initialize the sums 00546 Real sum, sum1 =0, sum2 =0; 00547 // update sum 00548 for (Integer k=1, k1=2; k<=t; k++, k1++) 00549 { 00550 sum1 += A[k1]*A[n+1-k]; 00551 sum2 += A[k] *A[n-k]; 00552 } 00553 // compute the result 00554 sum = ( (qmp*A[n] - 2*sum2)/(n+2) - sum1)/std; 00555 // save it in A 00556 A.push_back(sum); 00557 // and return it 00558 return sum; 00559 } 00560 00574 static Real betaRatio_se( Real const& a 00575 , Real const& b 00576 , Real const& x 00577 , bool xm1 00578 , bool lower_tail 00579 , Integer const& iterMax = 20 00580 ) 00581 { 00582 // parameters 00583 Real s = a+b; 00584 Real p = a/s, q = b/s; 00585 Real sx = s*x; 00586 Real sy = s-sx; 00587 //Real D = a*log(x/p)+b*log(y/q); 00588 Real D = (xm1 ? dev0(a, sy)+dev0(b, sx) : dev0(a, sx)+dev0(b, sy)); 00589 00590 Real z2 = 2 * D; 00591 Real z = (((x<p)&&!xm1)||((x>q)&&xm1)) ? -sqrt(z2) : sqrt(z2); 00592 00593 // Compute normal cdf 00594 Real pnorm = lower_tail ? normal_cdf_raw( z) : normal_cdf_raw(-z); 00595 #ifdef STK_DEBUG 00596 if (!Arithmetic<Real>::isFinite(pnorm)) 00597 { 00598 stk_cout << _T(" a= ") << a 00599 << _T(" b= ") << b 00600 << _T(" x= ") << x 00601 << _T(" p= ") << p 00602 << _T(" q= ") << q 00603 << _T(" D= ") << D 00604 << _T("\n"); 00605 } 00606 #endif 00607 // Compute normal pdf 00608 Real dnorm = Const::_1_SQRT2PI_ * exp(-D); 00609 // check large values of z 00610 if (!dnorm) return pnorm; 00611 // epsilon value for the serie 00612 Real eps = Arithmetic<Real>::epsilon()*pnorm; 00613 00614 // auxiliary variables 00615 Real std = sqrt(a)*sqrt(b)/s, qmp = q - p; 00616 00617 // serie coefs 00618 Vector A(2); 00619 A.reserve(iterMax); // reserve enough space 00620 A[1] = std; 00621 A[2] = qmp/3; 00622 // variables for the series 00623 Real odd_term = 1; 00624 Real even_term = 2/sqrt(s); 00625 00626 Real sum1_term = z, sum1 = z; 00627 Real sum2_term = 1, sum2 = 1; 00628 00629 // variables for the numerator and the denominator 00630 Real num = qmp*even_term/3; // = A[2]*even_term; 00631 Real den = std; // = A[1]; 00632 00633 // compute ratio 00634 Real res = num/den; 00635 00636 // computation 00637 for (Integer k=1; k<iterMax; k++) 00638 { 00639 // odd_term : (2k+1)!!/(a+b)^k 00640 odd_term *= (2*k+1)/s; 00641 // even_term (2*k)!!/(a+b)^{k+1/2} 00642 even_term *= 2*(k+1)/s; 00643 00644 // compute a_{2k+1} 00645 Real a_n = coefs_odd_se(std, qmp, A); 00646 // check result 00647 if (Arithmetic<Real>::isFinite(a_n)) 00648 { 00649 // denominator \sum_0^k (2j+1)!!a_{2j+1}/(a+b)^j 00650 den += odd_term * a_n; 00651 // num+=\sum_1^k (2k+1)!!a_{2k+1}/(a+b)^k (\sum_1^k z^{2j-1}/(2j-1)!!) 00652 num += odd_term * a_n * sum1; 00653 00654 // compute a_{2k+2} 00655 a_n = coefs_even_se(std, qmp, A); 00656 // check result 00657 if (Arithmetic<Real>::isFinite(a_n)) 00658 { 00659 // update sum2_term = z^{2k}/(2k)!! 00660 // update sum2 = \sum_0^k z^{2j}/(2j)!! 00661 sum2 += (sum2_term *= z2/(2*k)); 00662 // num+=\sum_0^k (2k+2)!!a_{2k+2}/(a+b)^k (\sum_1^k z^{2j}/(2j)!!) 00663 num += even_term * a_n * sum2; 00664 } 00665 } 00666 // test cv 00667 Real old_res = res; 00668 res = num/den; 00669 if (abs(old_res - res)*dnorm < eps) 00670 { break;} 00671 00672 // update sum1_term = z^{2k+1}/(2k+1)!! 00673 // update sum1 = \sum_1^{k+1} z^{2j-1}/(2j-1)!! 00674 sum1 += (sum1_term *= z2/(2*k+1)); 00675 } 00676 #ifdef STK_DEBUG 00677 // result 00678 Real result = lower_tail ? pnorm - res * dnorm 00679 : pnorm + res * dnorm; 00680 if (!Arithmetic<Real>::isFinite(result)) 00681 { 00682 std::cout << "Error in betRatio_se\n" 00683 << "pnorm = " << pnorm 00684 << " res = " << res 00685 << " dnorm = " << dnorm 00686 << "lt = " << lower_tail 00687 << "\n"; 00688 } 00689 return result; 00690 #else 00691 // result 00692 return lower_tail ? pnorm - res * dnorm 00693 : pnorm + res * dnorm; 00694 #endif 00695 } 00696 00709 Real betaRatio( Real const& a, Real const& b, Real const& x 00710 , bool lower_tail) 00711 { 00712 // Check if a and x are available 00713 if ( Arithmetic<Real>::isNA(a) 00714 || Arithmetic<Real>::isNA(b) 00715 || Arithmetic<Real>::isNA(x) 00716 ) return Arithmetic<Real>::NA(); 00717 // Negative parameter not allowed 00718 if ((a<=0)||(b<=0)) 00719 throw domain_error("Funct::betaRatio(a,b,x) " 00720 "Negative parameter a or b"); 00721 // trivial case 00722 if (x<=0) return lower_tail ? 0. : 1.; 00723 if (x>=1) return lower_tail ? 1. : 0.; 00724 // compute 1-x 00725 Real y = (0.5 - x) + 0.5; 00726 // parameters 00727 Real p=a/(a+b); 00728 Real q=b/(a+b); 00729 // small a or b 00730 if (min(a,b)<=1) 00731 { 00732 // case b<=1 and a>=15 00733 if (a>=15) 00734 return betaRatio_ae(a, b, x, false, lower_tail); 00735 // case a<=1 and b>=15 00736 if (b>=15) 00737 return betaRatio_ae(b, a, x, true, !lower_tail); 00738 // ((a<15) and (b<15) and (min(a,b)<=1)) 00739 return (x<=0.5) ? betaRatio_sr(a, b, x, lower_tail) 00740 : betaRatio_sr(b, a, y, !lower_tail); 00741 } 00742 // (1<a<=15) and (1<b<=15) 00743 if (max(a,b)<=15) 00744 { 00745 // general case 00746 return (x < p) ? betaRatio_cf(a, b, x, lower_tail) 00747 : betaRatio_cf(b, a, y, !lower_tail); 00748 } 00749 // ((1<a<=15) and (15<b)) or ((15<a) and (1<b<=15)) 00750 if (min(a,b)<=15) 00751 { 00752 return (a<=15) ? betaRatio_up(a, b, x, false, lower_tail) 00753 : betaRatio_up(b, a, x, true, !lower_tail); 00754 } 00755 00756 // Real x0, y0, a0, b0, p0, q0; 00757 // bool flag; 00758 // if (x>p) 00759 // { x0=y; y0=x; a0=b; b0=a; flag = !lower_tail; p0=q; q0=p;} 00760 // else 00761 // { x0=x; y0=y; a0=a; b0=b; p0=p; q0=q; flag = lower_tail;} 00762 // // center region for x 00763 // if ((x0>1.03*p0)&&(y0<0.97*q0)) 00764 // return betaRatio_se(a0-1, b0-1, x0, false, flag); 00765 // return betaRatio_cf(a0, b0, x0, flag); 00766 // (a>15) and (b>15) and (a<b) 00767 if (a<b) 00768 { 00769 // center region for x in [p , q] 00770 if ((x>=p-0.01*(q-p))&&(y<=q+0.01*(q-p))) 00771 return betaRatio_se(a-1, b-1, x, false, lower_tail); 00772 // extreme values 00773 return (x<p) ? betaRatio_cf(a, b, x, lower_tail) 00774 : betaRatio_cf(b, a, y, !lower_tail); 00775 } 00776 // (a>15) and (b>15) and (b<a) 00777 // center region for x in [q, p] 00778 if ((x>=q-0.01*(p-q))&&(y<=p+0.01*(p-q))) 00779 return betaRatio_se(b-1, a-1, x, true, !lower_tail); 00780 // extreme values 00781 return (x<p) ? betaRatio_cf(a, b, x, lower_tail) 00782 : betaRatio_cf(b, a, y, !lower_tail); 00783 } 00784 00785 } // namespace Funct 00786 00787 } // namespace STK