Exemplo n.º 1
0
        /// <summary>
        /// Checks that (x-y) > threshold
        /// </summary>
        /// <remarks>Should be consistent with wilcox.test(x, y, mu=threshold, alternative="greater") from R</remarks>
        public MannWhitneyResult IsGreater(double[] x, double[] y, Threshold threshold = null)
        {
            threshold = threshold ?? RelativeThreshold.Default;
            double thresholdValue = threshold.GetValue(x);

            int n = x.Length, m = y.Length;

            if (Math.Min(n, m) < 3 || Math.Max(n, m) < 5)
            {
                return(null); // Test can't be applied
            }
            var xy = new double[n + m];

            for (int i = 0; i < n; i++)
            {
                xy[i] = x[i];
            }
            for (int i = 0; i < m; i++)
            {
                xy[n + i] = y[i] + thresholdValue;
            }
            var index = new int[n + m];

            for (int i = 0; i < n + m; i++)
            {
                index[i] = i;
            }
            Array.Sort(index, (i, j) => xy[i].CompareTo(xy[j]));

            var ranks = new double[n + m];

            for (int i = 0; i < n + m;)
            {
                int j = i;
                while (j + 1 < n + m && Math.Abs(xy[index[j + 1]] - xy[index[i]]) < 1e-9)
                {
                    j++;
                }
                double rank = (i + j + 2) / 2.0;
                for (int k = i; k <= j; k++)
                {
                    ranks[k] = rank;
                }
                i = j + 1;
            }

            double ux = 0;

            for (int i = 0; i < n + m; i++)
            {
                if (index[i] < n)
                {
                    ux += ranks[i];
                }
            }
            ux -= n * (n + 1) / 2.0;
            double uy = n * m - ux;

            if (n + m <= BinomialCoefficientHelper.MaxAcceptableN)
            {
                double pValue = 1 - PValueForSmallN(n, m, ux - 1);
                return(new MannWhitneyResult(ux, uy, pValue, threshold));
            }
            else
            {
                double mu     = n * m / 2.0;
                double su     = Math.Sqrt(n * m * (n + m + 1) / 12.0);
                double z      = (ux - mu) / su;
                double pValue = 1 - NormalDistribution.Gauss(z);
                return(new MannWhitneyResult(ux, uy, pValue, threshold));
            }
        }