/**
         * The implementation of the inverse error function.
         * @param p
         * @param q
         * @param s
         * @return
         */
        private static double erfInvImpl(double p, double q, double s)
        {
            double result;

            if (p <= 0.5)
            {
                float  y = 0.0891314744949340820313f;
                double g = p * (p + 10);
                double r = Evaluate.polynomial(p, Coefficients.ervInvImpAn) / Evaluate.polynomial(p, Coefficients.ervInvImpAd);
                result = (g * y) + (g * r);
            }
            else if (q >= 0.25)
            {
                float  y  = 2.249481201171875f;
                double g  = MathFunctions.sqrt(-2 * MathFunctions.ln(q));
                double xs = q - 0.25;
                double r  = Evaluate.polynomial(xs, Coefficients.ervInvImpBn) / Evaluate.polynomial(xs, Coefficients.ervInvImpBd);
                result = g / (y + r);
            }
            else
            {
                double x = MathFunctions.sqrt(-MathFunctions.ln(q));
                if (x < 3)
                {
                    float  y  = 0.807220458984375f;
                    double xs = x - 1.125;
                    double r  = Evaluate.polynomial(xs, Coefficients.ervInvImpCn) / Evaluate.polynomial(xs, Coefficients.ervInvImpCd);
                    result = (y * x) + (r * x);
                }
                else if (x < 6)
                {
                    float  y  = 0.93995571136474609375f;
                    double xs = x - 3;
                    double r  = Evaluate.polynomial(xs, Coefficients.ervInvImpDn) / Evaluate.polynomial(xs, Coefficients.ervInvImpDd);
                    result = (y * x) + (r * x);
                }
                else if (x < 18)
                {
                    float  y  = 0.98362827301025390625f;
                    double xs = x - 6;
                    double r  = Evaluate.polynomial(xs, Coefficients.ervInvImpEn) / Evaluate.polynomial(xs, Coefficients.ervInvImpEd);
                    result = (y * x) + (r * x);
                }
                else if (x < 44)
                {
                    float  y  = 0.99714565277099609375f;
                    double xs = x - 18;
                    double r  = Evaluate.polynomial(xs, Coefficients.ervInvImpFn) / Evaluate.polynomial(xs, Coefficients.ervInvImpFd);
                    result = (y * x) + (r * x);
                }
                else
                {
                    float  y  = 0.99941349029541015625f;
                    double xs = x - 44;
                    double r  = Evaluate.polynomial(xs, Coefficients.ervInvImpGn) / Evaluate.polynomial(xs, Coefficients.ervInvImpGd);
                    result = (y * x) + (r * x);
                }
            }
            return(s * result);
        }
        /**
         * Calculates the inverse error function evaluated at x.
         * @param x
         * @param invert
         * @return
         */
        private static double erfImp(double z, bool invert)
        {
            if (z < 0)
            {
                if (!invert)
                {
                    return(-erfImp(-z, false));
                }
                if (z < -0.5)
                {
                    return(2 - erfImp(-z, true));
                }
                return(1 + erfImp(-z, false));
            }
            double result;

            if (z < 0.5)
            {
                if (z < 1e-10)
                {
                    result = (z * 1.125) + (z * 0.003379167095512573896158903121545171688);
                }
                else
                {
                    result = (z * 1.125) + (z * Evaluate.polynomial(z, Coefficients.erfImpAn) / Evaluate.polynomial(z, Coefficients.erfImpAd));
                }
            }
            else if ((z < 110) || ((z < 110) && invert))
            {
                invert = !invert;
                double r, b;
                if (z < 0.75)
                {
                    r = Evaluate.polynomial(z - 0.5, Coefficients.erfImpBn) / Evaluate.polynomial(z - 0.5, Coefficients.erfImpBd);
                    b = 0.3440242112F;
                }
                else if (z < 1.25)
                {
                    r = Evaluate.polynomial(z - 0.75, Coefficients.erfImpCn) / Evaluate.polynomial(z - 0.75, Coefficients.erfImpCd);
                    b = 0.419990927F;
                }
                else if (z < 2.25)
                {
                    r = Evaluate.polynomial(z - 1.25, Coefficients.erfImpDn) / Evaluate.polynomial(z - 1.25, Coefficients.erfImpDd);
                    b = 0.4898625016F;
                }
                else if (z < 3.5)
                {
                    r = Evaluate.polynomial(z - 2.25, Coefficients.erfImpEn) / Evaluate.polynomial(z - 2.25, Coefficients.erfImpEd);
                    b = 0.5317370892F;
                }
                else if (z < 5.25)
                {
                    r = Evaluate.polynomial(z - 3.5, Coefficients.erfImpFn) / Evaluate.polynomial(z - 3.5, Coefficients.erfImpFd);
                    b = 0.5489973426F;
                }
                else if (z < 8)
                {
                    r = Evaluate.polynomial(z - 5.25, Coefficients.erfImpGn) / Evaluate.polynomial(z - 5.25, Coefficients.erfImpGd);
                    b = 0.5571740866F;
                }
                else if (z < 11.5)
                {
                    r = Evaluate.polynomial(z - 8, Coefficients.erfImpHn) / Evaluate.polynomial(z - 8, Coefficients.erfImpHd);
                    b = 0.5609807968F;
                }
                else if (z < 17)
                {
                    r = Evaluate.polynomial(z - 11.5, Coefficients.erfImpIn) / Evaluate.polynomial(z - 11.5, Coefficients.erfImpId);
                    b = 0.5626493692F;
                }
                else if (z < 24)
                {
                    r = Evaluate.polynomial(z - 17, Coefficients.erfImpJn) / Evaluate.polynomial(z - 17, Coefficients.erfImpJd);
                    b = 0.5634598136F;
                }
                else if (z < 38)
                {
                    r = Evaluate.polynomial(z - 24, Coefficients.erfImpKn) / Evaluate.polynomial(z - 24, Coefficients.erfImpKd);
                    b = 0.5638477802F;
                }
                else if (z < 60)
                {
                    r = Evaluate.polynomial(z - 38, Coefficients.erfImpLn) / Evaluate.polynomial(z - 38, Coefficients.erfImpLd);
                    b = 0.5640528202F;
                }
                else if (z < 85)
                {
                    r = Evaluate.polynomial(z - 60, Coefficients.erfImpMn) / Evaluate.polynomial(z - 60, Coefficients.erfImpMd);
                    b = 0.5641309023F;
                }
                else
                {
                    r = Evaluate.polynomial(z - 85, Coefficients.erfImpNn) / Evaluate.polynomial(z - 85, Coefficients.erfImpNd);
                    b = 0.5641584396F;
                }
                double g = MathFunctions.exp(-z * z) / z;
                result = (g * b) + (g * r);
            }
            else
            {
                result = 0;
                invert = !invert;
            }
            if (invert)
            {
                result = 1 - result;
            }
            return(result);
        }