예제 #1
0
        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));
        }
예제 #3
0
        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);
        }
예제 #4
0
        /// <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);
            }
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
 /// <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));
 }
예제 #7
0
 /// <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));
        }
예제 #9
0
        /// <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);
        }
예제 #10
0
        /// <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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        /// <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);
            }
        }
예제 #14
0
        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);
        }
예제 #15
0
 protected override void EndProcessing()
 {
     WriteObject(Special.Binomial(N, K));
 }
예제 #16
0
 /// <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));
 }