/// <inheritdoc /> public override double InverseLeftProbability(double P) { if ((P < 0.0) || (P > 1.0)) { throw new ArgumentOutOfRangeException(nameof(P)); } BetaDistribution b = new BetaDistribution(nu / 2.0, 1.0 / 2.0); if (P <= 0.5) { double x = b.InverseLeftProbability(2.0 * P); return(-Math.Sqrt(nu * (1.0 - x) / x)); } else { double Q = 1.0 - P; double x = b.InverseLeftProbability(2.0 * Q); return(Math.Sqrt(nu * (1.0 - x) / x)); } }
/// <inheritdoc /> public override double InverseLeftProbability(double P) { double y = beta.InverseLeftProbability(P); return(nu2 / nu1 * y / (1.0 - y)); }
public void BetaInversion() { // test that beta distribution is accurately inverted over a wide range of a, b, P foreach (double a in TestUtilities.GenerateRealValues(0.01, 100.0, 8)) { foreach (double b in cs) { BetaDistribution B = new BetaDistribution(a, b); foreach (double P in probabilities) { Console.WriteLine("a={0} b={1} P={2}", a, b, P); double x = B.InverseLeftProbability(P); Console.WriteLine(" x={0} P(x)={1}", x, B.LeftProbability(x)); // we would like to test that P(x) = P, but floating point limitations prevent us from meeting this standard // P(x) changes so fast at extremes that sometimes even the minimal change in x causes a change // in P(x) larger than our target precision; so instead we test that our routine gets us // as close as it can, by checking that P(x-e) < P < P(x+e) double Px = B.LeftProbability(x); double Pxm = B.LeftProbability(Math.Min(0.0, x * (1.0 - TestUtilities.TargetPrecision))); double Pxp = B.LeftProbability(Math.Max(x * (1.0 + TestUtilities.TargetPrecision), 1.0)); Assert.IsTrue((Pxm <= P) && (P <= Pxp)); } } } }
public void Repro() { double I = 0.9998063099306; double a = 0.00034509911609819255; double b = 6.8453983996634218; var bd = new BetaDistribution(a, b); double x = bd.InverseLeftProbability(I); Console.WriteLine(x); Console.WriteLine(bd.LeftProbability(x)); Console.WriteLine(I); }
public void BetaExercise() { double[] c = new double[] { 1.0 / 32768.0, 1.0 / 1024.0, 1.0 / 64.0, 1.0 / 8.0, 1.0 / 2.0, 1.0, 2.0, 8.0, 64.0, 1024.0, 32768.0 }; double[] p = new double[] { 1.0 / 65536.0, 1.0 / 256.0, 1.0 / 16.0, 1.0 / 4.0, 1.0 - 1.0 / 4.0, 1.0 - 1.0 / 16.0, 1.0 - 1.0 / 256.0 }; Stopwatch s = Stopwatch.StartNew(); double sum = 0.0; foreach (double a in c) { foreach (double b in c) { BetaDistribution BD = new BetaDistribution(a, b); foreach (double x in p) { //Console.WriteLine("a={0} b={1} P={2}", a, b, x); //Console.WriteLine(BD.InverseLeftProbability(x)); sum += BD.InverseLeftProbability(x); } } } s.Stop(); Console.WriteLine(sum); Console.WriteLine(s.ElapsedMilliseconds); }
public void Bug7684() { // These values caused incomplete Beta to be called with argument outside the interval [0,1]. double I1 = 0.9999902; double a1 = 0.0000434313636267175; double b1 = 18474.36071078790000; BetaDistribution D1 = new BetaDistribution(a1, b1); double x1 = D1.InverseLeftProbability(I1); Console.WriteLine("{0} {1} {2}", x1, D1.LeftProbability(x1), I1); double I2 = 0.9998063099306; double a2 = 0.00034509911609819255; double b2 = 6.8453983996634218; BetaDistribution D2 = new BetaDistribution(a2, b2); double x2 = D2.InverseLeftProbability(I2); Console.WriteLine("{0} {1} {2}", x2, D2.LeftProbability(x2), I2); }
/// <inheritdoc /> public override double InverseLeftProbability(double P) { if ((P < 0.0) || (P > 1.0)) throw new ArgumentOutOfRangeException("P"); BetaDistribution b = new BetaDistribution(nu / 2.0, 1.0 / 2.0); if (P <= 0.5) { double x = b.InverseLeftProbability(2.0 * P); return (-Math.Sqrt(nu * (1.0 - x) / x)); } else { double Q = 1.0 - P; double x = b.InverseLeftProbability(2.0 * Q); return (Math.Sqrt(nu * (1.0 - x) / x)); } }