/// <summary> /// Multinomial Beta function. /// </summary> /// /// <example> /// Please see <see cref="Beta"/> /// </example> /// public static double Multinomial(params double[] x) { double sum = 0; double prd = 1; for (int i = 0; i < x.Length; i++) { sum += x[i]; prd *= Gamma.Function(x[i]); } return(prd / Gamma.Function(sum)); }
/// <summary> /// Power series for incomplete beta integral. Use when b*x /// is small and x not too close to 1. /// </summary> /// /// <example> /// Please see <see cref="Beta"/> /// </example> /// public static double PowerSeries(double a, double b, double x) { double s, t, u, v, n, t1, z, ai; ai = 1.0 / a; u = (1.0 - b) * x; v = u / (a + 1.0); t1 = v; t = u; n = 2.0; s = 0.0; z = Constants.DoubleEpsilon * ai; while (System.Math.Abs(v) > z) { u = (n - b) * x / n; t *= u; v = t / (a + n); s += v; n += 1.0; } s += t1; s += ai; u = a * System.Math.Log(x); if ((a + b) < Gamma.GammaMax && System.Math.Abs(u) < Constants.LogMax) { t = Gamma.Function(a + b) / (Gamma.Function(a) * Gamma.Function(b)); s = s * t * System.Math.Pow(x, a); } else { t = Gamma.Log(a + b) - Gamma.Log(a) - Gamma.Log(b) + u + System.Math.Log(s); if (t < Constants.LogMin) { s = 0.0; } else { s = System.Math.Exp(t); } } return(s); }
/// <summary> /// Returns the extended factorial definition of a real number. /// </summary> /// public static double Factorial(double n) { return(Gamma.Function(n + 1.0)); }
/// <summary> /// Incomplete (regularized) Beta function Ix(a, b). /// </summary> /// /// <example> /// Please see <see cref="Beta"/> /// </example> /// public static double Incomplete(double a, double b, double x) { double aa, bb, t, xx, xc, w, y; bool flag; if (a <= 0.0) { throw new ArgumentOutOfRangeException("a", "Lower limit must be greater than zero."); } if (b <= 0.0) { throw new ArgumentOutOfRangeException("b", "Upper limit must be greater than zero."); } if ((x <= 0.0) || (x >= 1.0)) { if (x == 0.0) { return(0.0); } if (x == 1.0) { return(1.0); } throw new ArgumentOutOfRangeException("x", "Value must be between 0 and 1."); } flag = false; if ((b * x) <= 1.0 && x <= 0.95) { t = PowerSeries(a, b, x); return(t); } w = 1.0 - x; if (x > (a / (a + b))) { flag = true; aa = b; bb = a; xc = x; xx = w; } else { aa = a; bb = b; xc = w; xx = x; } if (flag && (bb * xx) <= 1.0 && xx <= 0.95) { t = PowerSeries(aa, bb, xx); if (t <= Constants.DoubleEpsilon) { t = 1.0 - Constants.DoubleEpsilon; } else { t = 1.0 - t; } return(t); } y = xx * (aa + bb - 2.0) - (aa - 1.0); if (y < 0.0) { w = Incbcf(aa, bb, xx); } else { w = Incbd(aa, bb, xx) / xc; } y = aa * System.Math.Log(xx); t = bb * System.Math.Log(xc); if ((aa + bb) < Gamma.GammaMax && System.Math.Abs(y) < Constants.LogMax && System.Math.Abs(t) < Constants.LogMax) { t = System.Math.Pow(xc, bb); t *= System.Math.Pow(xx, aa); t /= aa; t *= w; t *= Gamma.Function(aa + bb) / (Gamma.Function(aa) * Gamma.Function(bb)); if (flag) { if (t <= Constants.DoubleEpsilon) { t = 1.0 - Constants.DoubleEpsilon; } else { t = 1.0 - t; } } return(t); } y += t + Gamma.Log(aa + bb) - Gamma.Log(aa) - Gamma.Log(bb); y += System.Math.Log(w / aa); if (y < Constants.LogMin) { t = 0.0; } else { t = System.Math.Exp(y); } if (flag) { if (t <= Constants.DoubleEpsilon) { t = 1.0 - Constants.DoubleEpsilon; } else { t = 1.0 - t; } } return(t); }