public static double IncompleteBeta(double aa, double bb, double xx)
{
double a, b, t, x, xc, w, y;
bool flag;
if (aa <= 0.0 || bb <= 0.0) throw new
ArithmeticException("ibeta: Domain error!");
if ((xx <= 0.0) || (xx >= 1.0))
{
if (xx == 0.0) return 0.0;
if (xx == 1.0) return 1.0;
throw new ArithmeticException("ibeta: Domain error!");
}
flag = false;
if ((bb*xx) <= 1.0 && xx <= 0.95)
{
t = pseries(aa, bb, xx);
return t;
}
w = 1.0 - xx;
/* Reverse a and b if x is greater than the mean. */
if (xx > (aa/(aa + bb)))
{
flag = true;
a = bb;
b = aa;
xc = xx;
x = w;
}
else
{
a = aa;
b = bb;
xc = w;
x = xx;
}
if (flag && (b*x) <= 1.0 && x <= 0.95)
{
t = pseries(a, b, x);
if (t <= MACHEP) t = 1.0 - MACHEP;
else t = 1.0 - t;
return t;
}
/* Choose expansion for better convergence. */
y = x*(a + b - 2.0) - (a - 1.0);
if (y < 0.0)
w = incbcf(a, b, x);
else
w = incbd(a, b, x)/xc;
/* Multiply w by the factor
a b _ _ _
x (1-x) | (a+b) / ( a | (a) | (b) ) . */
y = a * Math.Log(x);
t = b * Math.Log(xc);
if ((a + b) < MAXGAM && Math.Abs(y) < MAXLOG && Math.Abs(t) < MAXLOG)
{
t = Math.Pow(xc, b);
t *= Math.Pow(x, a);
t /= a;
t *= w;
t *= Gamma(a + b)/(Gamma(a)*Gamma(b));
if (flag)
{
if (t <= MACHEP) t = 1.0 - MACHEP;
else t = 1.0 - t;
}
return t;
}
/* Resort to logarithms. */
y += t + LogGamma(a + b) - LogGamma(a) - LogGamma(b);
y += Math.Log(w / a);
if (y < MINLOG)
t = 0.0;
else
t = Math.Exp(y);
if (flag)
{
if (t <= MACHEP) t = 1.0 - MACHEP;
else t = 1.0 - t;
}
return t;
}