/// <summary> /// Returns the probability of an event occuring in k out of n trials, given /// that the probability of the event occuring in any one trial is p. /// </summary> /// <param name="p">Probability that the event occurs in any one trial.</param> /// <param name="n">Number of trials.</param> /// <param name="k">Number of times the event occurs in n trials.</param> /// <returns></returns> public static double BinomialProbabilityDensityFunction(double p, int n, int k) { //# of combinations can exceed max double for n > 1020 if (n > 1020) { double logB = MMath.LogCombin(n, k) + k * Math.Log(p) + (n - k) * Math.Log(1 - p); return(Math.Exp(logB)); } return(MMath.Combinations(n, k) * Math.Pow(p, k) * Math.Pow(1 - p, n - k)); }
/// <summary> /// Returns the PDF of a beta distribution with shape parameters a and b. /// f(x) = x^(a-1) * (1-x)^(b-1) / B(a,b) /// </summary> /// <param name="x">Value of the random variable for which the PDF is beign evaluated. x is between 0 and 1.</param> /// <param name="a">Number of trials.</param> /// <param name="b">Number of times the event occurs in n trials.</param> /// <returns></returns> public static double BetaProbabilityDensityFunction(double x, double a, double b) { if (x < 0 || x > 1) { throw new ArgumentException("x must be between 0 and 1"); } double B = MMath.BetaFunction(a, b); double d = Math.Pow(x, a - 1) * Math.Pow(1 - x, b - 1) / B; return(d); }
/// <summary> /// The Irwin-Hall distribution results from the sum on n independent standard uniform variables /// </summary> /// <param name="x">The value at which to evaluate the distribution.</param> /// <param name="n">The number of standard uniform variables.</param> public static double IrwinHallProbabilityDensityFunction(double x, int n) { if (x < 0 || x > n) { return(0.0); } double d = 0; for (int i = 0; i <= n; i++) { d += Math.Pow(-1, i) * MMath.Combinations(n, i) * Math.Pow(x - i, n - 1) * Math.Sign(x - i); } d *= 0.5; d /= MMath.Factorial(n - 1); return(d); }
/// <summary> /// Returns the PDF of the F distribution. /// </summary> /// <param name="x">Value at which the distribution is evaluated.</param> /// <param name="k1">Degrees of freedom for numerator chi-sqared distribution. k1 > 0.</param> /// <param name="k2">Degrees of freedom for denominator chi-sqared distribution. k2 > 0.</param> public static double FProbabilityDensityFunction(double x, int k1, int k2) { if (k1 <= 0 || k2 <= 0) { throw new ArgumentException("k1 and k2 must be greater than 0."); } if (x == 0) { return(0.0); } double a1 = Math.Pow(k1 * x, 0.5 * k1); double a2 = Math.Pow(k2, 0.5 * k2); double a3 = Math.Pow(k1 * x + k2, 0.5 * (k1 + k2)); double a = a1 * a2 / a3; double b = MMath.BetaFunction(0.5 * k1, 0.5 * k2); double c = x * b; return(a / c); }
/// <summary> /// Returns the CDF of Student's t distribution. /// </summary> /// <param name="x">Value at which the distribution is evaluated.</param> /// <param name="k">Degrees of freedom.</param> public static double StudentsTCumulativeDensityFunction(double x, double k) { //Tested against Excel for //df = 1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 100, 200, 30, 400, 500 and //x = -7.0, -6.9, -6.8, ..., 7.0 //maximum discrepancy was less than 0.04% if (double.IsNaN(x)) { return(double.NaN); } if (x == 0) { return(0.5); } if (x > 0) { double x2 = k / (x * x + k); return(1.0 - 0.5 * MMath.RegularizedIncompleteBetaFunction(x2, 0.5 * k, 0.5)); } return(1.0 - StudentsTCumulativeDensityFunction(-x, k)); }
/// <summary> /// The PDF of the Poisson distribution. /// The probability of n iid events occuring in an interval, if the expected number of event is lambda. /// </summary> /// <param name="lambda">Equals both the mean and variance of the distribution.</param> /// <param name="n">The number of events.</param> public static double PoissonProbabilityDensityFunction(double lambda, int n) { return(Math.Pow(lambda, n) * Math.Exp(-lambda) / MMath.Factorial(n)); }