Пример #1
0
        /// <summary>
        /// Prepare for computation.
        /// Subclasses must call this method if they override any of the
        /// {@code solve} methods.
        /// </summary>
        /// <param name="maxEval"> Maximum number of evaluations. </param>
        /// <param name="f"> the integrand function </param>
        /// <param name="lower"> the min bound for the interval </param>
        /// <param name="upper"> the upper bound for the interval </param>
        /// <exception cref="NullArgumentException"> if {@code f} is {@code null}. </exception>
        /// <exception cref="MathIllegalArgumentException"> if {@code min >= max}. </exception>
//JAVA TO C# CONVERTER WARNING: 'final' parameters are not available in .NET:
//ORIGINAL LINE: protected void setup(final int maxEval, final org.apache.commons.math3.analysis.UnivariateFunction f, final double lower, final double upper) throws org.apache.commons.math3.exception.NullArgumentException, org.apache.commons.math3.exception.MathIllegalArgumentException
        protected internal virtual void Setup(int maxEval, UnivariateFunction f, double lower, double upper)
        {
            // Checks.
            MathUtils.CheckNotNull(f);
            UnivariateSolverUtils.VerifyInterval(lower, upper);

            // Reset.
            min         = lower;
            max         = upper;
            function    = f;
            evaluations = evaluations.WithMaximalCount(maxEval).withStart(0);
            count       = count.WithStart(0);
        }
        /// <summary>
        /// Prepare for computation.
        /// Subclasses must call this method if they override any of the
        /// {@code solve} methods.
        /// </summary>
        /// <param name="maxEval"> Maximum number of evaluations. </param>
        /// <param name="f"> the integrand function </param>
        /// <param name="lower"> the min bound for the interval </param>
        /// <param name="upper"> the upper bound for the interval </param>
        /// <exception cref="NullArgumentException"> if {@code f} is {@code null}. </exception>
        /// <exception cref="MathIllegalArgumentException"> if {@code min >= max}. </exception>
        protected internal virtual void Setup(int maxEval, UnivariateFunction f, double lower, double upper)
        {
            // Checks.
            MyUtils.CheckNotNull(f);
            UnivariateSolverUtils.VerifyInterval(lower, upper);

            // Reset.
            this.min      = lower;
            this.max      = upper;
            this.function = f;
            this.evaluations.MaximalCount = maxEval;
            this.evaluations.ResetCount();
            this.iterations.ResetCount();
        }
        /// <inheritdoc/>
        /// <remarks>
        /// The default implementation returns
        /// <list type="bullet">
        /// <item><see cref="getSupportLowerBound()"/> for <c>p = 0</c>,</item>
        /// <item><see cref="getSupportUpperBound()"/> for <c>p = 1</c>.</item>
        /// </list>
        /// </remarks>
        public double inverseCumulativeProbability(double p)
        {
            /*
             * IMPLEMENTATION NOTES
             * --------------------
             * Where applicable, use is made of the one-sided Chebyshev inequality
             * to bracket the root. This inequality states that
             * P(X - mu >= k * sig) <= 1 / (1 + k^2),
             * mu: mean, sig: standard deviation. Equivalently
             * 1 - P(X < mu + k * sig) <= 1 / (1 + k^2),
             * F(mu + k * sig) >= k^2 / (1 + k^2).
             *
             * For k = sqrt(p / (1 - p)), we find
             * F(mu + k * sig) >= p,
             * and (mu + k * sig) is an upper-bound for the root.
             *
             * Then, introducing Y = -X, mean(Y) = -mu, sd(Y) = sig, and
             * P(Y >= -mu + k * sig) <= 1 / (1 + k^2),
             * P(-X >= -mu + k * sig) <= 1 / (1 + k^2),
             * P(X <= mu - k * sig) <= 1 / (1 + k^2),
             * F(mu - k * sig) <= 1 / (1 + k^2).
             *
             * For k = sqrt((1 - p) / p), we find
             * F(mu - k * sig) <= p,
             * and (mu - k * sig) is a lower-bound for the root.
             *
             * In cases where the Chebyshev inequality does not apply, geometric
             * progressions 1, 2, 4, ... and -1, -2, -4, ... are used to bracket
             * the root.
             */
            if (p < 0.0 || p > 1.0)
            {
                throw new OutOfRangeException <Double>(p, 0, 1);
            }

            double lowerBound = getSupportLowerBound();

            if (p == 0.0)
            {
                return(lowerBound);
            }

            double upperBound = getSupportUpperBound();

            if (p == 1.0)
            {
                return(upperBound);
            }

            double  mu  = getNumericalMean();
            double  sig = FastMath.sqrt(getNumericalVariance());
            Boolean chebyshevApplies;

            chebyshevApplies = !(Double.IsInfinity(mu) || Double.IsNaN(mu) ||
                                 Double.IsInfinity(sig) || Double.IsNaN(sig));

            if (lowerBound == Double.NegativeInfinity)
            {
                if (chebyshevApplies)
                {
                    lowerBound = mu - sig * FastMath.sqrt((1d - p) / p);
                }
                else
                {
                    lowerBound = -1.0;
                    while (cumulativeProbability(lowerBound) >= p)
                    {
                        lowerBound *= 2.0;
                    }
                }
            }

            if (upperBound == Double.PositiveInfinity)
            {
                if (chebyshevApplies)
                {
                    upperBound = mu + sig * FastMath.sqrt(p / (1d - p));
                }
                else
                {
                    upperBound = 1.0;
                    while (cumulativeProbability(upperBound) < p)
                    {
                        upperBound *= 2.0;
                    }
                }
            }

            UnivariateFunction toSolve = new UnivariateFunctionHelper(p);

            double x = UnivariateSolverUtils.solve(toSolve,
                                                   lowerBound,
                                                   upperBound,
                                                   getSolverAbsoluteAccuracy());

            if (!isSupportConnected())
            {
                /* Test for plateau. */
                double dx = getSolverAbsoluteAccuracy();
                if (x - dx >= getSupportLowerBound())
                {
                    double px = cumulativeProbability(x);
                    if (cumulativeProbability(x - dx) == px)
                    {
                        upperBound = x;
                        while (upperBound - lowerBound > dx)
                        {
                            double midPoint = 0.5 * (lowerBound + upperBound);
                            if (cumulativeProbability(midPoint) < px)
                            {
                                lowerBound = midPoint;
                            }
                            else
                            {
                                upperBound = midPoint;
                            }
                        }
                        return(upperBound);
                    }
                }
            }
            return(x);
        }