/// <summary>
        /// Force a root found by a non-bracketing solver to lie on a specified side,
        /// as if the solver was a bracketing one.
        /// </summary>
        /// <param name="maxEval">maximal number of new evaluations of the function
        /// (evaluations already done for finding the root should have already been
        /// subtracted from this number)</param>
        /// <param name="f">function to solve</param>
        /// <param name="bracketing">bracketing solver to use for shifting the root</param>
        /// <param name="baseRoot">original root found by a previous non-bracketing solver</param>
        /// <param name="min">minimal bound of the search interval</param>
        /// <param name="max">maximal bound of the search interval</param>
        /// <param name="allowedSolution">the kind of solutions that the root-finding
        /// algorithm may accept as solutions.</param>
        /// <returns>a root approximation, on the specified side of the exact root</returns>
        /// <exception cref="NullArgumentException"> if <c>function</c> is <c>null</c>.</exception>
        public static double forceSide(int maxEval, UnivariateFunction f, BracketedUnivariateSolver <UnivariateFunction> bracketing, double baseRoot, double min, double max, AllowedSolution allowedSolution)
        {
            if (allowedSolution == AllowedSolution.ANY_SIDE)
            {
                // no further bracketing required
                return(baseRoot);
            }

            // find a very small interval bracketing the root
            double step = FastMath.max(bracketing.getAbsoluteAccuracy(),
                                       FastMath.abs(baseRoot * bracketing.getRelativeAccuracy()));
            double xLo           = FastMath.max(min, baseRoot - step);
            double fLo           = f.value(xLo);
            double xHi           = FastMath.min(max, baseRoot + step);
            double fHi           = f.value(xHi);
            int    remainingEval = maxEval - 2;

            while (remainingEval > 0)
            {
                if ((fLo >= 0 && fHi <= 0) || (fLo <= 0 && fHi >= 0))
                {
                    // compute the root on the selected side
                    return(bracketing.solve(remainingEval, f, xLo, xHi, baseRoot, allowedSolution));
                }

                // try increasing the interval
                Boolean changeLo = false;
                Boolean changeHi = false;
                if (fLo < fHi)
                {
                    // increasing function
                    if (fLo >= 0)
                    {
                        changeLo = true;
                    }
                    else
                    {
                        changeHi = true;
                    }
                }
                else if (fLo > fHi)
                {
                    // decreasing function
                    if (fLo <= 0)
                    {
                        changeLo = true;
                    }
                    else
                    {
                        changeHi = true;
                    }
                }
                else
                {
                    // unknown variation
                    changeLo = true;
                    changeHi = true;
                }

                // update the lower bound
                if (changeLo)
                {
                    xLo = FastMath.max(min, xLo - step);
                    fLo = f.value(xLo);
                    remainingEval--;
                }

                // update the higher bound
                if (changeHi)
                {
                    xHi = FastMath.min(max, xHi + step);
                    fHi = f.value(xHi);
                    remainingEval--;
                }
            }

            throw new NoBracketingException(new LocalizedFormats("FAILED_BRACKETING"),
                                            xLo, xHi, fLo, fHi,
                                            maxEval - remainingEval, maxEval, baseRoot,
                                            min, max);
        }
Exemple #2
0
        /// <summary>
        /// Force a root found by a non-bracketing solver to lie on a specified side,
        /// as if the solver were a bracketing one.
        /// </summary>
        /// <param name="maxEval"> maximal number of new evaluations of the function
        /// (evaluations already done for finding the root should have already been subtracted
        /// from this number) </param>
        /// <param name="f"> function to solve </param>
        /// <param name="bracketing"> bracketing solver to use for shifting the root </param>
        /// <param name="baseRoot"> original root found by a previous non-bracketing solver </param>
        /// <param name="min"> minimal bound of the search interval </param>
        /// <param name="max"> maximal bound of the search interval </param>
        /// <param name="allowedSolution"> the kind of solutions that the root-finding algorithm may
        /// accept as solutions. </param>
        /// <returns> a root approximation, on the specified side of the exact root </returns>
        /// <exception cref="NoBracketingException"> if the function has the same sign at the
        /// endpoints. </exception>
//JAVA TO C# CONVERTER WARNING: 'final' parameters are not available in .NET:
//ORIGINAL LINE: public static double forceSide(final int maxEval, final org.apache.commons.math3.analysis.UnivariateFunction f, final BracketedUnivariateSolver<org.apache.commons.math3.analysis.UnivariateFunction> bracketing, final double baseRoot, final double min, final double max, final AllowedSolution allowedSolution) throws org.apache.commons.math3.exception.NoBracketingException
        public static double ForceSide(int maxEval, UnivariateFunction f, BracketedUnivariateSolver <UnivariateFunction> bracketing, double baseRoot, double min, double max, AllowedSolution allowedSolution)
        {
            if (allowedSolution == AllowedSolution.ANY_SIDE)
            {
                // no further bracketing required
                return(baseRoot);
            }

            // find a very small interval bracketing the root
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double step = org.apache.commons.math3.util.FastMath.max(bracketing.getAbsoluteAccuracy(), org.apache.commons.math3.util.FastMath.abs(baseRoot * bracketing.getRelativeAccuracy()));
            double step          = FastMath.max(bracketing.getAbsoluteAccuracy(), FastMath.Abs(baseRoot * bracketing.getRelativeAccuracy()));
            double xLo           = FastMath.Max(min, baseRoot - step);
            double fLo           = f.Value(xLo);
            double xHi           = FastMath.Min(max, baseRoot + step);
            double fHi           = f.Value(xHi);
            int    remainingEval = maxEval - 2;

            while (remainingEval > 0)
            {
                if ((fLo >= 0 && fHi <= 0) || (fLo <= 0 && fHi >= 0))
                {
                    // compute the root on the selected side
                    return(bracketing.Solve(remainingEval, f, xLo, xHi, baseRoot, allowedSolution));
                }

                // try increasing the interval
                bool changeLo = false;
                bool changeHi = false;
                if (fLo < fHi)
                {
                    // increasing function
                    if (fLo >= 0)
                    {
                        changeLo = true;
                    }
                    else
                    {
                        changeHi = true;
                    }
                }
                else if (fLo > fHi)
                {
                    // decreasing function
                    if (fLo <= 0)
                    {
                        changeLo = true;
                    }
                    else
                    {
                        changeHi = true;
                    }
                }
                else
                {
                    // unknown variation
                    changeLo = true;
                    changeHi = true;
                }

                // update the lower bound
                if (changeLo)
                {
                    xLo = FastMath.Max(min, xLo - step);
                    fLo = f.Value(xLo);
                    remainingEval--;
                }

                // update the higher bound
                if (changeHi)
                {
                    xHi = FastMath.Min(max, xHi + step);
                    fHi = f.Value(xHi);
                    remainingEval--;
                }
            }

            throw new NoBracketingException(LocalizedFormats.FAILED_BRACKETING, xLo, xHi, fLo, fHi, maxEval - remainingEval, maxEval, baseRoot, min, max);
        }