/// <summary>
        /// Returns the regularized gamma function Q(a, x) = 1 - P(a, x).
        /// The implementation of this method is based on:
        /// <list type="bullet">
        /// <item>
        /// <a href="http://mathworld.wolfram.com/RegularizedGammaFunction.html">
        /// Regularized Gamma Function</a>, equation (1).
        /// </item>
        /// <item>
        /// <a href="http://functions.wolfram.com/GammaBetaErf/GammaRegularized/10/0003/">
        /// Regularized incomplete gamma function: Continued fraction representations
        /// (formula 06.08.10.0003)</a>
        /// </item>
        /// </list>
        /// </summary>
        /// <param name="a">the a parameter.</param>
        /// <param name="x">the value.</param>
        /// <param name="epsilon">When the absolute value of the nth item in the
        /// series is less than epsilon the approximation ceases to calculate
        /// further elements in the series.</param>
        /// <param name="maxIterations">Maximum number of "iterations" to complete.</param>
        /// <returns>the regularized gamma function P(a, x)</returns>
        /// <exception cref="MaxCountExceededException"> if the algorithm fails to converge.
        /// </exception>
        public static double regularizedGammaQ(double a, double x, double epsilon, int maxIterations)
        {
            double ret;

            if (Double.IsNaN(a) || Double.IsNaN(x) || (a <= 0.0) || (x < 0.0))
            {
                ret = Double.NaN;
            }
            else if (x == 0.0)
            {
                ret = 1.0;
            }
            else if (x < a + 1.0)
            {
                // use regularizedGammaP because it should converge faster in this
                // case.
                ret = 1.0 - regularizedGammaP(a, x, epsilon, maxIterations);
            }
            else
            {
                // create continued fraction
                ContinuedFraction cf = new ContinuedFractionHelper(a);

                ret = 1.0 / cf.evaluate(x, epsilon, maxIterations);
                ret = FastMath.exp(-x + (a * FastMath.log(x)) - logGamma(a)) * ret;
            }

            return(ret);
        }
        /// <summary>
        /// Returns the regularized beta function I(x, a, b).<para/>
        /// The implementation of this method is based on:
        /// <list type="bullet">
        /// <item>
        /// <a href="http://mathworld.wolfram.com/RegularizedBetaFunction.html">
        /// Regularized Beta Function</a>.</item>
        /// <item>
        /// <a href="http://functions.wolfram.com/06.21.10.0001.01">
        /// Regularized Beta Function</a>.</item>
        /// </list>
        /// </summary>
        /// <param name="x">the value.</param>
        /// <param name="a">Parameter <c>a</c>.</param>
        /// <param name="b">Parameter <c>b</c>.</param>
        /// <param name="epsilon">When the absolute value of the nth item in the
        /// series is less than epsilon the approximation ceases to calculate
        /// further elements in the series.</param>
        /// <param name="maxIterations">Maximum number of "iterations" to complete.</param>
        /// <returns>the regularized beta function I(x, a, b)</returns>
        /// <exception cref="MaxCountExceededException">
        /// if the algorithm fails to converge.</exception>
        public static double regularizedBeta(double x, double a, double b, double epsilon, int maxIterations)
        {
            double ret;

            if (Double.IsNaN(x) ||
                Double.IsNaN(a) ||
                Double.IsNaN(b) ||
                x < 0 ||
                x > 1 ||
                a <= 0 ||
                b <= 0)
            {
                ret = Double.NaN;
            }
            else if (x > (a + 1) / (2 + b + a) &&
                     1 - x <= (b + 1) / (2 + b + a))
            {
                ret = 1 - regularizedBeta(1 - x, b, a, epsilon, maxIterations);
            }
            else
            {
                ContinuedFraction fraction = new ContinuedFractionHelper(a, b);
                ret = FastMath.exp((a * FastMath.log(x)) + (b * FastMath.log1p(-x)) -
                                   FastMath.log(a) - logBeta(a, b)) *
                      1.0 / fraction.evaluate(x, epsilon, maxIterations);
            }

            return(ret);
        }