double RateGamma::cmpPointChi2 (double prob, double v) { /* returns z so that Prob{x<z}=prob where x is Chi2 distributed with df=v returns -1 if in error. 0.000002<prob<0.999998 RATNEST FORTRAN by Best DJ & Roberts DE (1975) The percentage points of the Chi2 distribution. Applied Statistics 24: 385-388. (AS91) Converted into C by Ziheng Yang, Oct. 1993. */ double e=.5e-6, aa=.6931471805, p=prob, g; double xx, c, ch, a=0,q=0,p1=0,p2=0,t=0,x=0,b=0,s1,s2,s3,s4,s5,s6; if (p<.000002 || p>.999998 || v<=0) return (-1); g = cmpLnGamma (v/2); xx=v/2; c=xx-1; if (v >= -1.24*log(p)) goto l1; ch=pow((p*xx*exp(g+xx*aa)), 1/xx); if (ch-e<0) return (ch); goto l4; l1: if (v>.32) goto l3; ch=0.4; a=log(1-p); l2: q=ch; p1=1+ch*(4.67+ch); p2=ch*(6.73+ch*(6.66+ch)); t=-0.5+(4.67+2*ch)/p1 - (6.73+ch*(13.32+3*ch))/p2; ch-=(1-exp(a+g+.5*ch+c*aa)*p2/p1)/t; if (fabs(q/ch-1)-.01 <= 0) goto l4; else goto l2; l3: x=cmpPointNormal (p); p1=0.222222/v; ch=v*pow((x*sqrt(p1)+1-p1), 3.0); if (ch>2.2*v+6) ch=-2*(log(1-p)-c*log(.5*ch)+g); l4: do { q=ch; p1=.5*ch; if ((t=cmpIncompleteGamma (p1, xx, g))<0) { return (-1); } p2=p-t; t=p2*exp(xx*aa+g+p1-c*log(ch)); b=t/ch; a=0.5*t-b*c; s1=(210+a*(140+a*(105+a*(84+a*(70+60*a))))) / 420; s2=(420+a*(735+a*(966+a*(1141+1278*a))))/2520; s3=(210+a*(462+a*(707+932*a)))/2520; s4=(252+a*(672+1182*a)+c*(294+a*(889+1740*a)))/5040; s5=(84+264*a+c*(175+606*a))/2520; s6=(120+c*(346+127*c))/5040; ch+=t*(1+0.5*t*s1-b*c*(s1-b*(s2-b*(s3-b*(s4-b*(s5-b*s6)))))); } while (fabs(q/ch-1) > e); return (ch); } //end of function cmpPointChi2
void StopRule::cmpLamdaMat (int k, DoubleMatrix &lamdaMat) { int i, j; lamdaMat.resize(k); for (i = 0; i < k; i ++) lamdaMat[i].resize(k); double muy_ = cmpMuy (k); for (i = 0; i < k; i ++) for (j = 0; j <= i; j ++) { /* lamdaMat[i][j] = (cmpGamma (2*muy_ + i + 1) * cmpGamma (muy_ + j + 1) ) / ( cmpGamma (muy_ + i + 1) * cmpGamma (j + 1) );*/ // to fix divide by zero PROBLEM! lamdaMat[i][j] = cmpLnGamma (2*muy_ + i + 1) + cmpLnGamma (muy_ + j + 1) - cmpLnGamma (muy_ + i + 1) - cmpLnGamma (j + 1); //if (i == 98 && j == 97) // std::cout << i << "," << j << " -> " << lamdaMat[i][j] << endl; lamdaMat[i][j] = exp(lamdaMat[i][j]); lamdaMat[j][i] = lamdaMat[i][j]; } }
void RateGamma::computeRatesMean () { int i; double lnga1=cmpLnGamma(gamma_shape+1); double *freqK = new double[ncategory]; for (i=0; i<ncategory-1; i++) /* cutting points, Eq. 9 */ freqK[i]=cmpPointChi2((i+1.0)/ncategory, 2.0 * gamma_shape) / (2.0 * gamma_shape); for (i=0; i<ncategory-1; i++) /* Eq. 10 */ freqK[i]=cmpIncompleteGamma(freqK[i]*gamma_shape, gamma_shape+1, lnga1); rates[0] = freqK[0]*ncategory; rates[ncategory-1] = (1-freqK[ncategory-2])*ncategory; for (i=1; i<ncategory-1; i++) rates[i] = (freqK[i]-freqK[i-1])*ncategory; delete [] freqK; }