/// <summary>
        ///   Constructs a Grubb's test.
        /// </summary>
        ///
        public GrubbTest(double[] samples, GrubbTestHypothesis hypothesis = GrubbTestHypothesis.ThereAreOutliers)
        {
            this.NumberOfSamples   = samples.Length;
            this.Mean              = samples.Mean();
            this.StandardDeviation = samples.StandardDeviation(Mean);

            // Compute Grubb's statistic
            this.min = this.max = samples[0] - Mean;
            for (int i = 1; i < samples.Length; i++)
            {
                double z = samples[i] - Mean;
                if (z > max)
                {
                    max = z;
                }
                if (z < min)
                {
                    min = z;
                }
            }
            this.abs = Math.Max(-min, max);

            this.Statistic             = g(hypothesis) / StandardDeviation;
            this.StatisticDistribution = new GrubbDistribution(NumberOfSamples);
            this.Tail       = DistributionTail.OneUpper;
            this.Hypothesis = hypothesis;

            // Compute the transformed p-value
            this.PValue = StatisticToPValue(Statistic);
        }
        private double g(GrubbTestHypothesis hypothesis)
        {
            switch (hypothesis)
            {
            case GrubbTestHypothesis.ThereAreOutliers:
                return(abs);

            case GrubbTestHypothesis.TheMaximumIsAnOutlier:
                return(max);

            case GrubbTestHypothesis.TheMinimumIsAnOutlier:
                return(-min);
            }

            throw new ArgumentOutOfRangeException("hypothesis");
        }