Inheritance: UnivariateContinuousDistribution
コード例 #1
0
        public void ConstructorTest()
        {
            double[] ranks = { 1, 2, 3, 4, 5 };

            var mannWhitney = new MannWhitneyDistribution(ranks, n1: 2, n2: 3);

            double mean = mannWhitney.Mean;     // 2.7870954605658511
            double median = mannWhitney.Median; // 1.5219615583481305
            double var = mannWhitney.Variance;  // 18.28163603621158

            double cdf = mannWhitney.DistributionFunction(x: 4); // 0.6
            double pdf = mannWhitney.ProbabilityDensityFunction(x: 4); // 0.2
            double lpdf = mannWhitney.LogProbabilityDensityFunction(x: 4); // -1.6094379124341005

            double ccdf = mannWhitney.ComplementaryDistributionFunction(x: 4); // 0.4
            double icdf = mannWhitney.InverseDistributionFunction(p: cdf); // 3.6666666666666661

            double hf = mannWhitney.HazardFunction(x: 4); // 0.5
            double chf = mannWhitney.CumulativeHazardFunction(x: 4); // 0.916290731874155

            string str = mannWhitney.ToString(); // MannWhitney(u; n1 = 2, n2 = 3)

            Assert.AreEqual(3.0, mean);
            Assert.AreEqual(3.0000006357828775, median);
            Assert.AreEqual(3.0, var);
            Assert.AreEqual(0.916290731874155, chf);
            Assert.AreEqual(0.6, cdf);
            Assert.AreEqual(0.2, pdf);
            Assert.AreEqual(-1.6094379124341005, lpdf);
            Assert.AreEqual(0.5, hf);
            Assert.AreEqual(0.4, ccdf);
            Assert.AreEqual(3.6666666666666661, icdf);
            Assert.AreEqual("MannWhitney(u; n1 = 2, n2 = 3)", str);
        }
コード例 #2
0
        /// <summary>
        ///   Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>
        ///   A new object that is a copy of this instance.
        /// </returns>
        ///
        public override object Clone()
        {
            var clone = new MannWhitneyDistribution(NumberOfSamples1, NumberOfSamples2);

            clone.exact         = exact;
            clone.table         = table;
            clone.n1            = n1;
            clone.n2            = n2;
            clone.Correction    = Correction;
            clone.approximation = (NormalDistribution)approximation.Clone();
            return(clone);
        }
コード例 #3
0
        public void ConstructorTest()
        {
            double[] ranks = { 1, 2, 3, 4, 5 };

            var mannWhitney = new MannWhitneyDistribution(ranks, n1: 2, n2: 3);

            double mean = mannWhitney.Mean;     // 2.7870954605658511
            double median = mannWhitney.Median; // 1.5219615583481305
            double var = mannWhitney.Variance;  // 18.28163603621158
            try { double mode = mannWhitney.Mode; Assert.Fail(); }
            catch { }

            double cdf = mannWhitney.DistributionFunction(x: 4); // 0.6
            double pdf = mannWhitney.ProbabilityDensityFunction(x: 4); // 0.2
            double lpdf = mannWhitney.LogProbabilityDensityFunction(x: 4); // -1.6094379124341005

            double ccdf = mannWhitney.ComplementaryDistributionFunction(x: 4); // 0.4
            double icdf = mannWhitney.InverseDistributionFunction(p: cdf); // 3.6666666666666661

            double hf = mannWhitney.HazardFunction(x: 4); // 0.5
            double chf = mannWhitney.CumulativeHazardFunction(x: 4); // 0.916290731874155

            string str = mannWhitney.ToString(); // MannWhitney(u; n1 = 2, n2 = 3)

            Assert.AreEqual(3.0, mean);
            Assert.AreEqual(3.0000006357828775, median);
            Assert.AreEqual(3.0, var);
            Assert.AreEqual(0.916290731874155, chf);
            Assert.AreEqual(0.6, cdf);
            Assert.AreEqual(0.2, pdf);
            Assert.AreEqual(-1.6094379124341005, lpdf);
            Assert.AreEqual(0.5, hf);
            Assert.AreEqual(0.4, ccdf);
            Assert.AreEqual(3.6666666666666661, icdf);
            Assert.AreEqual("MannWhitney(u; n1 = 2, n2 = 3)", str);

            var range1 = mannWhitney.GetRange(0.95);
            var range2 = mannWhitney.GetRange(0.99);
            var range3 = mannWhitney.GetRange(0.01);

            Assert.AreEqual(0.00000095367431640625085, range1.Min);
            Assert.AreEqual(5.9999995430310555, range1.Max);
            Assert.AreEqual(0, range2.Min);
            Assert.AreEqual(6.000000194140088, range2.Max);
            Assert.AreEqual(0, range3.Min);
            Assert.AreEqual(6.000000194140088, range3.Max);
        }
コード例 #4
0
        private void init(int n1, int n2, double[] ranks, bool?exact)
        {
            int n = n1 + n2;

            this.n1 = n1;
            this.n2 = n2;

            // From https://en.wikipedia.org/wiki/Mann%E2%80%93Whitney_U_test: For large samples, U
            // is approximately normally distributed. In that case, the standardized value is given
            // by z = (U - mean) / stdDev where:
            double mean   = (n1 * n2) / 2.0;
            double stdDev = Math.Sqrt((n1 * n2 * (n + 1)) / 12.0);

            bool hasVectors = ranks != null;

            // For small samples (< 30) the distribution can be exact
            this.exact = hasVectors && (n1 <= 30 && n2 <= 30);

            if (exact.HasValue)
            {
                if (exact.Value && !hasVectors)
                {
                    throw new ArgumentException("exact", "Cannot use exact method if rank vectors are not specified.");
                }
                this.exact = exact.Value; // force
            }

            if (hasVectors)
            {
                // Apply correction to the variance
                double correction = MannWhitneyDistribution.correction(ranks);
                stdDev = Math.Sqrt((n1 * n2 * ((n + 1.0) - correction)) / 12.0);

                if (this.exact)
                {
                    initExactMethod(ranks);
                }
            }

            this.approximation = new NormalDistribution(mean, stdDev);
        }
コード例 #5
0
        private void init(int n1, int n2, double[] ranks, bool?exact)
        {
            if (n1 <= 0)
            {
                throw new ArgumentOutOfRangeException("n1", "The number of observations in the first sample (n1) must be higher than zero.");
            }

            if (n2 <= 0)
            {
                throw new ArgumentOutOfRangeException("n2", "The number of observations in the second sample (n2) must be higher than zero.");
            }

            if (n1 > n2)
            {
                Trace.TraceWarning("Creating a MannWhitneyDistribution where the first sample is larger than the second sample. If possible, please re-organize your samples such that the first sample is smaller than the second sample.");
            }

            if (ranks != null)
            {
                if (ranks.Length <= 1)
                {
                    throw new ArgumentOutOfRangeException("ranks", "The rank vector must contain a minimum of 2 elements.");
                }

                for (int i = 0; i < ranks.Length; i++)
                {
                    if (ranks[i] < 0)
                    {
                        throw new ArgumentOutOfRangeException("The rank values cannot be negative.");
                    }
                }
            }

            int n = n1 + n2;

            this.n1 = n1;
            this.n2 = n2;

            // From https://en.wikipedia.org/wiki/Mann%E2%80%93Whitney_U_test: For large samples, U
            // is approximately normally distributed. In that case, the standardized value is given
            // by z = (U - mean) / stdDev where:
            double mean   = ((double)n1 * n2) / 2.0;
            double stdDev = Math.Sqrt(((double)n1 * n2 * (n + 1)) / 12.0);

            bool hasVectors = ranks != null;

            // For small samples (< 30) the distribution can be exact
            this.exact = hasVectors && (n1 <= 30 && n2 <= 30);

            if (exact.HasValue)
            {
                if (exact.Value && !hasVectors)
                {
                    throw new ArgumentException("exact", "Cannot use exact method if rank vectors are not specified.");
                }
                this.exact = exact.Value; // force
            }

            if (hasVectors)
            {
                // Apply correction to the variance
                double correction = MannWhitneyDistribution.correction(ranks);
                double a          = ((double)n1 * n2) / 12.0;
                double b          = (n + 1.0) - correction;
                stdDev = Math.Sqrt(a * b);

                if (this.exact)
                {
                    initExactMethod(ranks);
                }
            }

            this.approximation = new NormalDistribution(mean, stdDev);
        }
コード例 #6
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);
        }
コード例 #7
0
        public void MedianTest()
        {
            double[] ranks = { 1, 1, 2, 3, 4, 7, 5 };

            int n1 = 4;
            int n2 = 3;

            Assert.AreEqual(n1 + n2, ranks.Length);


            var target = new MannWhitneyDistribution(ranks, n1, n2);

            Assert.AreEqual(target.Median, target.InverseDistributionFunction(0.5));
        }
コード例 #8
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);
            }

        }