in commons-numbers-gamma/src/main/java/org/apache/commons/numbers/gamma/BoostBeta.java [1140:1238]
private static double betaSmallBLargeASeries(double a, double b, double x, double y, double s0, double mult,
Policy pol, boolean normalised) {
//
// This is DiDonato and Morris's BGRAT routine, see Eq's 9 through 9.6.
//
// Some values we'll need later, these are Eq 9.1:
//
final double bm1 = b - 1;
final double t = a + bm1 / 2;
double lx;
double u;
if (y < 0.35) {
lx = Math.log1p(-y);
} else {
lx = Math.log(x);
}
u = -t * lx;
// and from from 9.2:
final double h = BoostGamma.regularisedGammaPrefix(b, u);
if (h <= Double.MIN_NORMAL) {
// Update:
// Boost returns s0.
// If this is zero then compute an expected sub-normal value
// using the classic continued fraction representation.
if (s0 == 0) {
return ibetaFraction(a, b, x, y, pol, normalised);
}
return s0;
}
double prefix;
if (normalised) {
prefix = h / GammaRatio.delta(a, b);
prefix /= Math.pow(t, b);
} else {
prefix = BoostGamma.fullIgammaPrefix(b, u) / Math.pow(t, b);
}
prefix *= mult;
//
// now we need the quantity Pn, unfortunately this is computed
// recursively, and requires a full history of all the previous values
// so no choice but to declare a big table and hope it's big enough...
//
final double[] p = new double[PN_SIZE];
// see 9.3.
p[0] = 1;
//
// Now an initial value for J, see 9.6:
//
double j = BoostGamma.gammaQ(b, u, pol) / h;
//
// Now we can start to pull things together and evaluate the sum in Eq 9:
//
// Value at N = 0
double sum = s0 + prefix * j;
// some variables we'll need:
// 2*N+1
int tnp1 = 1;
double lx2 = lx / 2;
lx2 *= lx2;
double lxp = 1;
final double t4 = 4 * t * t;
double b2n = b;
for (int n = 1; n < PN_SIZE; ++n) {
//
// begin by evaluating the next Pn from Eq 9.4:
//
tnp1 += 2;
p[n] = 0;
int tmp1 = 3;
for (int m = 1; m < n; ++m) {
final double mbn = m * b - n;
p[n] += mbn * p[n - m] / BoostGamma.uncheckedFactorial(tmp1);
tmp1 += 2;
}
p[n] /= n;
p[n] += bm1 / BoostGamma.uncheckedFactorial(tnp1);
//
// Now we want Jn from Jn-1 using Eq 9.6:
//
j = (b2n * (b2n + 1) * j + (u + b2n + 1) * lxp) / t4;
lxp *= lx2;
b2n += 2;
//
// pull it together with Eq 9:
//
final double r = prefix * p[n] * j;
final double previous = sum;
sum += r;
// Update:
// This continues until convergence at machine epsilon
// |r| < eps * |sum|; r < 1
// |r| / eps < |sum|; r > 1
if (sum == previous) {
break;
}
}
return sum;
}