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); }
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); }