public void DistributionFunctionTest() { double[] ranks = { 1, 2, 3, 4, 5 }; int n1 = 2; int n2 = 3; int N = n1 + n2; Assert.AreEqual(N, ranks.Length); var target = new MannWhitneyDistribution(ranks, n1, n2); // Number of possible combinations is 5!/(3!2!) = 10. int nc = (int)Special.Binomial(5, 3); Assert.AreEqual(10, nc); double[] expected = { 0.0, 0.1, 0.1, 0.2, 0.2, 0.2, 0.1, 0.1, 0.0, 0.0 }; expected = expected.CumulativeSum(); for (int i = 0; i < expected.Length; i++) { // P(U<=i) double actual = target.DistributionFunction(i); Assert.AreEqual(expected[i], actual,1e-10); } }
/// <summary> /// Gets the cumulative distribution function (cdf) for /// this distribution evaluated at point <c>k</c>. /// </summary> /// /// <param name="k">A single point in the distribution range.</param> /// /// <remarks> /// The Cumulative Distribution Function (CDF) describes the cumulative /// probability that a given value or any value smaller than it will occur. /// </remarks> /// public override double DistributionFunction(int k) { if (k < Math.Max(0, n + m - N)) { return(0); } if (k > Math.Min(m, n)) { k = Math.Min(m, n); } // This is a really naive implementation. A better approach // is described in (Trong Wu; An accurate computation of the // hypergeometric distribution function, 1993) double sum = 0; for (int i = 0; i <= k; i++) { sum += (Special.Binomial(m, i) * Special.Binomial(N - m, n - i)); } return(sum / Special.Binomial(N, n)); }
public void ProbabilityDensityFunctionTest() { double[] ranks = { 1, 2, 3, 4, 5 }; int n1 = 2; int n2 = 3; int N = n1 + n2; Assert.AreEqual(N, ranks.Length); var target = new MannWhitneyDistribution(ranks, n1, n2); // Number of possible combinations is 5!/(3!2!) = 10. int nc = (int)Special.Binomial(5, 3); Assert.AreEqual(10, nc); double[] expected = { 0.1, 0.1, 0.2, 0.2, 0.2, 0.1, 0.1, 0.0, 0.0 }; double sum = 0; for (int i = 0; i < expected.Length; i++) { // P(U=i) double actual = target.ProbabilityDensityFunction(i); Assert.AreEqual(expected[i], actual); sum += actual; } Assert.AreEqual(1, sum); }
/// <summary> /// Constructs a Mann-Whitney's U-statistic distribution. /// </summary> /// /// <param name="ranks">The rank statistics.</param> /// <param name="n1">The number of observations in the first sample.</param> /// <param name="n2">The number of observations in the second sample.</param> /// public MannWhitneyDistribution(double[] ranks, int n1, int n2) { this.Ranks = ranks; this.Samples1 = n1; this.Samples2 = n2; int nt = n1 + n2; this.smallSample = (n1 <= 30 && n2 <= 30); if (smallSample) { // For a small sample (< 30) the distribution is exact. int nc = (int)Special.Binomial(nt, n1); table = new double[nc]; int i = 0; // Consider all possible combinations of samples foreach (double[] combination in Combinatorics.Combinations(Ranks, n1)) { table[i++] = USample1(combination, Samples2); } Array.Sort(table); } }
/// <summary> /// Gets the probability mass function (pmf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// /// <param name="k">A single point in the distribution range.</param> /// /// <returns> /// The probability of <c>k</c> occurring /// in the current distribution. /// </returns> /// /// <remarks> /// The Probability Mass Function (PMF) describes the /// probability that a given value <c>x</c> will occur. /// </remarks> /// protected internal override double InnerProbabilityMassFunction(int k) { double a = Special.Binomial(m, k); double b = Special.Binomial(N - m, n - k); double c = Special.Binomial(N, n); return((a * b) / c); }
/// <summary> /// Gets the probability mass function (pmf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// /// <param name="k">A single point in the distribution range.</param> /// /// <returns> /// The probability of <c>k</c> occurring /// in the current distribution. /// </returns> /// /// <remarks> /// The Probability Mass Function (PMF) describes the /// probability that a given value <c>x</c> will occur. /// </remarks> /// public override double ProbabilityMassFunction(int k) { if (k < 0) { return(0); } return(Special.Binomial(k + r - 1, r - 1) * Math.Pow(1 - p, k) * Math.Pow(p, r)); }
/// <summary> /// Gets the probability mass function (pmf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// /// <param name="k">A single point in the distribution range.</param> /// /// <returns> /// The probability of <c>k</c> occurring /// in the current distribution. /// </returns> /// /// <remarks> /// The Probability Mass Function (PMF) describes the /// probability that a given value <c>x</c> will occur. /// </remarks> /// public override double ProbabilityMassFunction(int k) { if (k < 0 || k > numberOfTrials) { return(0); } return(Special.Binomial(numberOfTrials, k) * Math.Pow(probability, k) * Math.Pow(1 - probability, numberOfTrials - k)); }
/// <summary> /// Gets the probability mass function (pmf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// /// <param name="k">A single point in the distribution range.</param> /// /// <returns> /// The probability of <c>k</c> occurring /// in the current distribution. /// </returns> /// /// <remarks> /// The Probability Mass Function (PMF) describes the /// probability that a given value <c>x</c> will occur. /// </remarks> /// public override double ProbabilityMassFunction(int k) { if (k < Math.Max(0, n + m - N) || k > Math.Min(m, n)) { return(0); } return((Special.Binomial(m, k) * Special.Binomial(N - m, n - k)) / Special.Binomial(N, n)); }
/// <summary> /// Gets the probability mass function (pmf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// /// <param name="k">A single point in the distribution range.</param> /// /// <returns> /// The probability of <c>k</c> occurring /// in the current distribution. /// </returns> /// /// <remarks> /// The Probability Mass Function (PMF) describes the /// probability that a given value <c>x</c> will occur. /// </remarks> /// public override double ProbabilityMassFunction(int k) { if (k < Math.Max(0, n + m - N) || k > Math.Min(m, n)) { return(0); } double a = Special.Binomial(m, k); double b = Special.Binomial(N - m, n - k); double c = Special.Binomial(N, n); return((a * b) / c); }
/// <summary> /// Returns the value of the probability density function. /// </summary> /// <param name="x">Value</param> /// <returns>float precision floating point number</returns> public float Function(float x) { if (x < Math.Max(0, k + d - n) || x > Math.Min(d, k)) { return(0); } float a = Special.Binomial(d, x); float b = Special.Binomial(n - d, k - x); float c = Special.Binomial(n, k); return((a * b) / c); }
public void BinomialTest2() { int n = 6; int k = 4; double expected = 15; double actual = Special.Binomial(n, k); Assert.AreEqual(expected, actual); n = 100; k = 47; expected = 8.441348728306404e+28; actual = Special.Binomial(n, k); Assert.AreEqual(expected, actual, 1e+16); }
public void BinomialTest() { int n = 63; int k = 6; double expected = 67945521; double actual; actual = Special.Binomial(n, k); Assert.AreEqual(expected, actual); n = 42; k = 12; expected = 11058116888; actual = Special.Binomial(n, k); Assert.AreEqual(expected, actual); }
/// <summary> /// Constructs a Mann-Whitney's U-statistic distribution. /// </summary> /// /// <param name="ranks">The rank statistics.</param> /// <param name="n1">The number of observations in the first sample.</param> /// <param name="n2">The number of observations in the second sample.</param> /// public MannWhitneyDistribution(double[] ranks, [PositiveInteger] int n1, [PositiveInteger] int n2) { this.Ranks = ranks; this.Samples1 = n1; this.Samples2 = n2; int nt = n1 + n2; if (n1 <= 0) { throw new ArgumentOutOfRangeException("n1", "The first number of samples must be positive."); } if (n2 <= 0) { throw new ArgumentOutOfRangeException("n2", "The second number of samples must be positive."); } this.smallSample = (n1 <= 30 && n2 <= 30); if (smallSample) { // For a small sample (< 30) the distribution is exact. int nc = (int)Special.Binomial(nt, n1); table = new double[nc]; int i = 0; // Consider all possible combinations of samples foreach (double[] combination in Combinatorics.Combinations(Ranks, n1)) { table[i++] = USample1(combination, Samples2); } Array.Sort(table); } }
private void initExactMethod(double[] ranks) { int min = Math.Min(n1, n2); long combinations = (long)Special.Binomial(n1 + n2, min); this.table = new double[combinations]; #if NET35 var seq = EnumerableEx.Zip <double[], long, Tuple <double[], long> >( Combinatorics.Combinations(ranks, min), Vector.Range(combinations), (double[] c, long i) => new Tuple <double[], long>(c, i)); #else var seq = Enumerable.Zip <double[], long, Tuple <double[], long> >( Combinatorics.Combinations(ranks, min), Vector.Range(combinations), (double[] c, long i) => new Tuple <double[], long>(c, i)); #endif Parallel.ForEach(seq, i => { this.table[i.Item2] = MannWhitneyU(i.Item1); }); Array.Sort(table); }
protected override void EndProcessing() { WriteObject(Special.Binomial(N, K)); }
/// <summary> /// Gets the probability mass function (pmf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// /// <param name="k">A single point in the distribution range.</param> /// /// <returns> /// The probability of <c>k</c> occurring /// in the current distribution. /// </returns> /// /// <remarks> /// The Probability Mass Function (PMF) describes the /// probability that a given value <c>x</c> will occur. /// </remarks> /// protected internal override double InnerProbabilityMassFunction(int k) { return(Special.Binomial(k + r - 1, r - 1) * Math.Pow(1 - p, k) * Math.Pow(p, r)); }