public void HypergeometricIncompleteBeta() { foreach (double a in abcs) { if (a <= 0.0) { continue; } foreach (double b in abcs) { if (b <= 0.0) { continue; } foreach (double x in xs) { if ((x < 0.0) || (x > 1.0)) { continue; } Assert.IsTrue(TestUtilities.IsNearlyEqual( Math.Pow(x, a) * Math.Pow(1.0 - x, b) * AdvancedMath.Hypergeometric2F1(a + b, 1.0, a + 1.0, x) / a, AdvancedMath.Beta(a, b, x) )); } } } }
public void HypergeometricIntegral() { // A&S 15.3.1 // F(a, b, c, x) = \frac{\Gamma(c)}{\Gamma(b) \Gamma(c - b)} // \int_{0}^{1} \! dt \, t^{b-1} (1 - t)^{c - b - 1} (1 - x t)^{-a} // Choose limits on a, b, c so that singularities of integrand are numerically integrable. foreach (double a in TestUtilities.GenerateRealValues(1.0, 10.0, 2)) { foreach (double b in TestUtilities.GenerateRealValues(0.6, 10.0, 2)) { foreach (double c in TestUtilities.GenerateRealValues(b + 0.6, 10.0, 2)) { foreach (double x in xs) { double I = FunctionMath.Integrate( t => Math.Pow(t, b - 1.0) * Math.Pow(1.0 - t, c - b - 1.0) * Math.Pow(1.0 - x * t, -a), Interval.FromEndpoints(0.0, 1.0) ); double B = AdvancedMath.Beta(b, c - b); Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.Hypergeometric2F1(a, b, c, x), I / B)); } } } } }
/// <summary> /// Initializes a new β distribution. /// </summary> /// <param name="alpha">The left shape parameter, which controls the form of the distribution near x=0.</param> /// <param name="beta">The right shape parameter, which controls the form of the distribution near x=1.</param> /// <remarks> /// <para>The <paramref name="alpha"/> shape parameter controls the form of the distribution near x=0. The /// <paramref name="beta"/> shape parameter controls the form of the distribution near z=1. If a shape parameter /// is less than one, the PDF diverges on the side of the distribution it controls. If a shape parameter /// is greater than one, the PDF goes to zero on the side of the distribution it controls. If the left and right /// shape parameters are equal, the distribution is symmetric about x=1/2.</para> /// </remarks> /// <exception cref="ArgumentOutOfRangeException"><paramref name="alpha"/> or <paramref name="beta"/> is non-positive.</exception> public BetaDistribution(double alpha, double beta) { if (alpha <= 0.0) { throw new ArgumentOutOfRangeException(nameof(alpha)); } if (beta <= 0.0) { throw new ArgumentOutOfRangeException(nameof(beta)); } this.a = alpha; this.b = beta; // cache value of B(alpha, beta) to avoid having to re-calculate it whenever needed this.bigB = AdvancedMath.Beta(alpha, beta); // get a beta generator if (alpha < 0.75 && beta < 0.75) { this.betaRng = new JoehnkBetaGenerator(alpha, beta); } else if (alpha > 1.0 && beta > 1.0) { this.betaRng = new ChengBetaGenerator(alpha, beta); } else { this.betaRng = DeviateGeneratorFactory.GetBetaGenerator(alpha, beta); } // get a beta inverter this.betaInverter = new BetaInverter(alpha, beta); }
public void EllipticFBetaRelationship() { foreach (double phi in TestUtilities.GenerateUniformRealValues(0.0, Math.PI / 2.0, 8)) { Assert.IsTrue(TestUtilities.IsNearlyEqual( AdvancedMath.EllipticF(phi, 1.0 / Math.Sqrt(2.0)), AdvancedMath.Beta(1.0 / 2.0, 1.0 / 4.0, 1.0 - MoreMath.Pow(Math.Cos(phi), 4)) / Math.Sqrt(8.0) )); } }
/// <inheritdoc /> public override double ProbabilityDensity(double x) { if (Math.Abs(x) > 1.0) { return(0.0); } else { return(Math.Pow((1.0 - x) * (1.0 + x), (n - 4) / 2.0) / AdvancedMath.Beta(0.5, (n - 2) / 2.0)); } }
/// <inheritdoc /> public override double LeftProbability(double x) { double t2 = x * x; if (x < 0.0) { return(0.5 * AdvancedMath.Beta(0.5 * nu, 0.5, nu / (nu + t2)) / AdvancedMath.Beta(0.5, 0.5 * nu)); } else { return(0.5 * (1.0 + AdvancedMath.Beta(0.5, 0.5 * nu, t2 / (nu + t2)) / AdvancedMath.Beta(0.5, 0.5 * nu))); } }
/// <inheritdoc /> public override double RightExclusiveProbability(int k) { if (k < 0) { return(1.0); } else if (k >= n) { return(0.0); } else { // use direct summation in tails return(AdvancedMath.Beta(k + 1, n - k, p) / AdvancedMath.Beta(k + 1, n - k)); } }
/// <inheritdoc /> public override double ProbabilityMass(int k) { if (k < 0) { return(0.0); } else { return( //AdvancedIntegerMath.BinomialCoefficient(k + r - 1, k) * MoreMath.Pow(p, k) * Math.Pow(q, r) / AdvancedMath.Beta(r, k + 1) / (k + r) ); // note: n \choose k = \frac{1}{(n+1) B(n - k + 1, k + 1)} } }
/// <inheritdoc /> public override double LeftProbability(double x) { if (x <= -1.0) { return(0.0); } else if (x < 0.0) { return(AdvancedMath.Beta((n - 2) / 2.0, 0.5, (1.0 - x) * (1.0 + x)) / AdvancedMath.Beta((n - 2) / 2.0, 0.5) / 2.0); } else if (x < 1.0) { return((1.0 + AdvancedMath.Beta(0.5, (n - 2) / 2.0, x * x) / AdvancedMath.Beta(0.5, (n - 2) / 2.0)) / 2.0); } else { return(1.0); } }
/// <summary> /// Initializes a new β distribution. /// </summary> /// <param name="alpha">The left shape parameter, which controls the form of the distribution near x=0.</param> /// <param name="beta">The right shape parameter, which controls the form of the distribution near x=1.</param> /// <remarks> /// <para>The <paramref name="alpha"/> shape parameter controls the form of the distribution near x=0. The /// <paramref name="beta"/> shape parameter controls the form of the distribution near z=1. If a shape parameter /// is less than one, the PDF diverges on the side of the distribution it controls. If a shape parameter /// is greater than one, the PDF goes to zero on the side of the distribution it controls. If the left and right /// shapre parameters are equal, the distribution is symmetric about x=1/2.</para> /// </remarks> /// <seealso href="http://en.wikipedia.org/wiki/Beta_distribution" /> public BetaDistribution(double alpha, double beta) { if (alpha <= 0.0) { throw new ArgumentOutOfRangeException("alpha"); } if (beta <= 0.0) { throw new ArgumentOutOfRangeException("beta"); } this.alpha = alpha; this.beta = beta; // cache value of B(alpha, beta) to avoid having to re-calculate it whenever needed this.bigB = AdvancedMath.Beta(alpha, beta); // get a beta generator this.betaRng = DeviateGeneratorFactory.GetBetaGenerator(alpha, beta); // get a beta inverter this.betaInverter = new BetaInverter(alpha, beta); }
/// <inheritdoc /> public override double ProbabilityDensity(double x) { return(Math.Pow(1.0 + x * x / nu, -0.5 * (nu + 1.0)) / AdvancedMath.Beta(0.5, 0.5 * nu) / Math.Sqrt(nu)); }