/// <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); }
/// <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); }