public void doc()
        {
            var grubb = new GrubbDistribution(samples: 8);

            double chf  = grubb.CumulativeHazardFunction(x: 1.27);                          // 0.25670891803568036
            double cdf  = grubb.DistributionFunction(x: 1.27);                              // 0.22640663992932097
            double ccdf = grubb.ComplementaryDistributionFunction(x: 1.27);                 // 0.773593360070679
            double icdf = grubb.InverseDistributionFunction(p: cdf);                        // 1.27

            string str = grubb.ToString(System.Globalization.CultureInfo.InvariantCulture); // "B(x; α = 0.42, β = 1.57)

            Assert.AreEqual(0.25670891803568036, chf);
            Assert.AreEqual(0.22640663992932097, cdf);
            Assert.AreEqual(0.773593360070679, ccdf);
            Assert.AreEqual(1.27, icdf, 1e-10);
            Assert.AreEqual("Grubb(x; n = 8)", str);

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

            Assert.AreEqual(1.1684847650106549, range1.Min);
            Assert.AreEqual(2.031652001549944, range1.Max);
            Assert.AreEqual(1.1468556105506391, range2.Min);
            Assert.AreEqual(2.2208334515104258, range2.Max);
            Assert.AreEqual(1.1468556105506391, range3.Min);
            Assert.AreEqual(2.2208334515104258, range3.Max);
        }
        public void cdf()
        {
            double[] x = Vector.Range(0.0, 1.0, stepSize: 1e-3);

            var target = new GrubbDistribution(42);

            double[] cdf = x.Apply(xi => target.InverseDistributionFunction(xi));

            double min = cdf.Min();
            double max = cdf.Max();

            Assert.AreEqual(6.3264373484457685, max, 1e-10);
            Assert.AreEqual(max, target.Support.Max, 1e-10);

            Assert.AreEqual(1.9451708565372674, min, 1e-10);

            Assert.AreEqual(0, target.DistributionFunction(-1));
            Assert.AreEqual(0, target.DistributionFunction(0));
            Assert.AreEqual(0, target.DistributionFunction(min));
            Assert.AreEqual(0, target.DistributionFunction(min - 1e-10));
            double actual = target.DistributionFunction(min + 1e-10);

            Assert.AreEqual(2.5226376543230344E-10, actual, 1e-10);
        }
        public void cdf2()
        {
            var    target = new GrubbDistribution(3);
            double cdf;

            cdf = target.DistributionFunction(0);
            Assert.AreEqual(0, cdf, 1e-8);

            cdf = target.DistributionFunction(0.8);
            Assert.AreEqual(0.23089631020036727, cdf, 1e-8);

            cdf = target.DistributionFunction(0.1);
            Assert.AreEqual(0, cdf, 1e-8);

            cdf = target.DistributionFunction(1);
            Assert.AreEqual(0.49999999999999845, cdf, 1e-8);

            cdf = target.DistributionFunction(1.1);
            Assert.AreEqual(0.70489468240783792, cdf, 1e-8);

            cdf = target.DistributionFunction(1.1547005383792517); // precision error if not handled
            Assert.AreEqual(1, cdf, 1e-8);
        }
        public void cdf()
        {
            double[] x = Vector.Range(0.0, 1.0, stepSize: 1e-3);

            var target = new GrubbDistribution(7);

            double[] cdf = x.Apply(xi => target.InverseDistributionFunction(xi));

            double min = cdf.Min();
            double max = cdf.Max();

            Assert.AreEqual(2.2677868380553634, max, 1e-10);
            Assert.AreEqual(max, target.Support.Max, 1e-10);

            Assert.AreEqual(1.0688047803397081, min, 1e-10);
            Assert.AreEqual(min, target.Support.Min, 1e-10);

            double actual;

            Assert.AreEqual(0, target.DistributionFunction(-1));
            Assert.AreEqual(0, target.DistributionFunction(0));
            Assert.AreEqual(0, target.DistributionFunction(1));
            Assert.AreEqual(0, target.DistributionFunction((max - min) / 2.0));
            Assert.AreEqual(0.33127709351171297d, target.DistributionFunction(1.27), 1e-8);
            Assert.AreEqual(0, target.DistributionFunction(min));
            Assert.AreEqual(0, target.DistributionFunction(min - 1e-10));
            actual = target.DistributionFunction(min + 1e-10);
            Assert.AreEqual(2.5226376543230344E-10, actual, 1e-10);

            Assert.AreEqual(1, target.DistributionFunction(max), 1e-10);
            Assert.AreEqual(1, target.DistributionFunction(max - 1e-10), 1e-10);
            actual = target.DistributionFunction(max + 1e-10);
            Assert.AreEqual(1, actual, 1e-10);
        }