/// <summary> /// {@inheritDoc} /// </summary> protected internal override double DoSolve() { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double startValue = getStartValue(); double startValue = GetStartValue(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double absoluteAccuracy = getAbsoluteAccuracy(); double absoluteAccuracy = GetAbsoluteAccuracy(); double x0 = startValue; double x1; while (true) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final org.apache.commons.math3.analysis.differentiation.DerivativeStructure y0 = computeObjectiveValueAndDerivative(x0); DerivativeStructure y0 = ComputeObjectiveValueAndDerivative(x0); x1 = x0 - (y0.GetValue() / y0.GetPartialDerivative(1)); if (FastMath.Abs(x1 - x0) <= absoluteAccuracy) { return(x1); } x0 = x1; } }
/// <summary> /// {@inheritDoc} </summary> protected internal override double DoIntegrate() { double oldt = Stage(this, 0); IncrementCount(); while (true) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final int i = getIterations(); int i = GetIterations(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double t = stage(this, i); double t = Stage(this, i); if (i >= GetMinimalIterationCount()) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double delta = org.apache.commons.math3.util.FastMath.abs(t - oldt); double delta = FastMath.Abs(t - oldt); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double rLimit = getRelativeAccuracy() * (org.apache.commons.math3.util.FastMath.abs(oldt) + org.apache.commons.math3.util.FastMath.abs(t)) * 0.5; double rLimit = GetRelativeAccuracy() * (FastMath.Abs(oldt) + FastMath.Abs(t)) * 0.5; if ((delta <= rLimit) || (delta <= GetAbsoluteAccuracy())) { return(t); } } oldt = t; IncrementCount(); } }
/// <summary> /// {@inheritDoc} </summary> protected internal override double DoIntegrate() { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final int m = getMaximalIterationCount() + 1; int m = GetMaximalIterationCount() + 1; double[] previousRow = new double[m]; double[] currentRow = new double[m]; TrapezoidIntegrator qtrap = new TrapezoidIntegrator(); currentRow[0] = qtrap.Stage(this, 0); IncrementCount(); double olds = currentRow[0]; while (true) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final int i = getIterations(); int i = GetIterations(); // switch rows //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double[] tmpRow = previousRow; double[] tmpRow = previousRow; previousRow = currentRow; currentRow = tmpRow; currentRow[0] = qtrap.Stage(this, i); IncrementCount(); for (int j = 1; j <= i; j++) { // Richardson extrapolation coefficient //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double r = (1L << (2 * j)) - 1; double r = (1L << (2 * j)) - 1; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double tIJm1 = currentRow[j - 1]; double tIJm1 = currentRow[j - 1]; currentRow[j] = tIJm1 + (tIJm1 - previousRow[j - 1]) / r; } //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double s = currentRow[i]; double s = currentRow[i]; if (i >= GetMinimalIterationCount()) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double delta = org.apache.commons.math3.util.FastMath.abs(s - olds); double delta = FastMath.Abs(s - olds); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double rLimit = getRelativeAccuracy() * (org.apache.commons.math3.util.FastMath.abs(olds) + org.apache.commons.math3.util.FastMath.abs(s)) * 0.5; double rLimit = GetRelativeAccuracy() * (FastMath.Abs(olds) + FastMath.Abs(s)) * 0.5; if ((delta <= rLimit) || (delta <= GetAbsoluteAccuracy())) { return(s); } } olds = s; } }
/// <summary> /// {@inheritDoc} /// </summary> protected internal override double DoSolve() { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double min = getMin(); double min = GetMin(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double max = getMax(); double max = GetMax(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double initial = getStartValue(); double initial = GetStartValue(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double functionValueAccuracy = getFunctionValueAccuracy(); double functionValueAccuracy = GetFunctionValueAccuracy(); VerifySequence(min, initial, max); // check for zeros before verifying bracketing //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double fMin = computeObjectiveValue(min); double fMin = ComputeObjectiveValue(min); if (FastMath.Abs(fMin) < functionValueAccuracy) { return(min); } //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double fMax = computeObjectiveValue(max); double fMax = ComputeObjectiveValue(max); if (FastMath.Abs(fMax) < functionValueAccuracy) { return(max); } //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double fInitial = computeObjectiveValue(initial); double fInitial = ComputeObjectiveValue(initial); if (FastMath.Abs(fInitial) < functionValueAccuracy) { return(initial); } VerifyBracketing(min, max); if (IsBracketing(min, initial)) { return(Solve(min, initial, fMin, fInitial)); } else { return(Solve(initial, max, fInitial, fMax)); } }
/// <summary> /// {@inheritDoc} /// </summary> protected internal override double DoSolve() { double min = GetMin(); double max = GetMax(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double initial = getStartValue(); double initial = GetStartValue(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double functionValueAccuracy = getFunctionValueAccuracy(); double functionValueAccuracy = GetFunctionValueAccuracy(); VerifySequence(min, initial, max); // Return the initial guess if it is good enough. double yInitial = ComputeObjectiveValue(initial); if (FastMath.Abs(yInitial) <= functionValueAccuracy) { return(initial); } // Return the first endpoint if it is good enough. double yMin = ComputeObjectiveValue(min); if (FastMath.Abs(yMin) <= functionValueAccuracy) { return(min); } // Reduce interval if min and initial bracket the root. if (yInitial * yMin < 0) { return(Brent(min, initial, yMin, yInitial)); } // Return the second endpoint if it is good enough. double yMax = ComputeObjectiveValue(max); if (FastMath.Abs(yMax) <= functionValueAccuracy) { return(max); } // Reduce interval if initial and max bracket the root. if (yInitial * yMax < 0) { return(Brent(initial, max, yInitial, yMax)); } throw new NoBracketingException(min, max, yMin, yMax); }
/// <summary> /// {@inheritDoc} </summary> protected internal override double DoIntegrate() { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double min = getMin(); double min = GetMin(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double diff = getMax() - min; double diff = GetMax() - min; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double midPoint = min + 0.5 * diff; double midPoint = min + 0.5 * diff; double oldt = diff * ComputeObjectiveValue(midPoint); while (true) { IncrementCount(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final int i = getIterations(); int i = GetIterations(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double t = stage(i, oldt, min, diff); double t = Stage(i, oldt, min, diff); if (i >= GetMinimalIterationCount()) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double delta = org.apache.commons.math3.util.FastMath.abs(t - oldt); double delta = FastMath.Abs(t - oldt); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double rLimit = getRelativeAccuracy() * (org.apache.commons.math3.util.FastMath.abs(oldt) + org.apache.commons.math3.util.FastMath.abs(t)) * 0.5; double rLimit = GetRelativeAccuracy() * (FastMath.Abs(oldt) + FastMath.Abs(t)) * 0.5; if ((delta <= rLimit) || (delta <= GetAbsoluteAccuracy())) { return(t); } } oldt = t; } }
/// <summary> /// {@inheritDoc} </summary> protected internal override double DoIntegrate() { TrapezoidIntegrator qtrap = new TrapezoidIntegrator(); if (GetMinimalIterationCount() == 1) { return((4 * qtrap.Stage(this, 1) - qtrap.Stage(this, 0)) / 3.0); } // Simpson's rule requires at least two trapezoid stages. double olds = 0; double oldt = qtrap.Stage(this, 0); while (true) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double t = qtrap.stage(this, getIterations()); double t = qtrap.Stage(this, GetIterations()); IncrementCount(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double s = (4 * t - oldt) / 3.0; double s = (4 * t - oldt) / 3.0; if (GetIterations() >= GetMinimalIterationCount()) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double delta = org.apache.commons.math3.util.FastMath.abs(s - olds); double delta = FastMath.Abs(s - olds); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double rLimit = getRelativeAccuracy() * (org.apache.commons.math3.util.FastMath.abs(olds) + org.apache.commons.math3.util.FastMath.abs(s)) * 0.5; double rLimit = GetRelativeAccuracy() * (FastMath.Abs(olds) + FastMath.Abs(s)) * 0.5; if ((delta <= rLimit) || (delta <= GetAbsoluteAccuracy())) { return(s); } } olds = s; oldt = t; } }
/// <summary> /// {@inheritDoc} </summary> protected internal override double DoIntegrate() { // Compute first estimate with a single step. double oldt = Stage(1); int n = 2; while (true) { // Improve integral with a larger number of steps. //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double t = stage(n); double t = Stage(n); // Estimate the error. //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double delta = org.apache.commons.math3.util.FastMath.abs(t - oldt); double delta = FastMath.Abs(t - oldt); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double limit = org.apache.commons.math3.util.FastMath.max(getAbsoluteAccuracy(), getRelativeAccuracy() * (org.apache.commons.math3.util.FastMath.abs(oldt) + org.apache.commons.math3.util.FastMath.abs(t)) * 0.5); double limit = FastMath.Max(GetAbsoluteAccuracy(), GetRelativeAccuracy() * (FastMath.Abs(oldt) + FastMath.Abs(t)) * 0.5); // check convergence if (GetIterations() + 1 >= GetMinimalIterationCount() && delta <= limit) { return(t); } // Prepare next iteration. //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double ratio = org.apache.commons.math3.util.FastMath.min(4, org.apache.commons.math3.util.FastMath.pow(delta / limit, 0.5 / numberOfPoints)); double ratio = FastMath.Min(4, FastMath.Pow(delta / limit, 0.5 / numberOfPoints)); n = FastMath.Max((int)(ratio * n), n + 1); oldt = t; IncrementCount(); } }
/// <summary> /// {@inheritDoc} /// </summary> protected internal override double DoSolve() { double min = GetMin(); double max = GetMax(); VerifyInterval(min, max); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double absoluteAccuracy = getAbsoluteAccuracy(); double absoluteAccuracy = GetAbsoluteAccuracy(); double m; double fm; double fmin; while (true) { m = UnivariateSolverUtils.Midpoint(min, max); fmin = ComputeObjectiveValue(min); fm = ComputeObjectiveValue(m); if (fm * fmin > 0) { // max and m bracket the root. min = m; } else { // min and m bracket the root. max = m; } if (FastMath.Abs(max - min) <= absoluteAccuracy) { m = UnivariateSolverUtils.Midpoint(min, max); return(m); } } }
/// <summary> /// Search for a zero inside the provided interval. /// This implementation is based on the algorithm described at page 58 of /// the book /// <blockquote> /// <b>Algorithms for Minimization Without Derivatives</b>, /// <it>Richard P. Brent</it>, /// Dover 0-486-41998-3 /// </blockquote> /// </summary> /// <param name="lo"> Lower bound of the search interval. </param> /// <param name="hi"> Higher bound of the search interval. </param> /// <param name="fLo"> Function value at the lower bound of the search interval. </param> /// <param name="fHi"> Function value at the higher bound of the search interval. </param> /// <returns> the value where the function is zero. </returns> private double Brent(double lo, double hi, double fLo, double fHi) { double a = lo; double fa = fLo; double b = hi; double fb = fHi; double c = a; double fc = fa; double d = b - a; double e = d; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double t = getAbsoluteAccuracy(); double t = GetAbsoluteAccuracy(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double eps = getRelativeAccuracy(); double eps = GetRelativeAccuracy(); while (true) { if (FastMath.Abs(fc) < FastMath.Abs(fb)) { a = b; b = c; c = a; fa = fb; fb = fc; fc = fa; } //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double tol = 2 * eps * org.apache.commons.math3.util.FastMath.abs(b) + t; double tol = 2 * eps * FastMath.Abs(b) + t; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double m = 0.5 * (c - b); double m = 0.5 * (c - b); if (FastMath.Abs(m) <= tol || Precision.Equals(fb, 0)) { return(b); } if (FastMath.Abs(e) < tol || FastMath.Abs(fa) <= FastMath.Abs(fb)) { // Force bisection. d = m; e = d; } else { double s = fb / fa; double p; double q; // The equality test (a == c) is intentional, // it is part of the original Brent's method and // it should NOT be replaced by proximity test. if (a == c) { // Linear interpolation. p = 2 * m * s; q = 1 - s; } else { // Inverse quadratic interpolation. q = fa / fc; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double r = fb / fc; double r = fb / fc; p = s * (2 * m * q * (q - r) - (b - a) * (r - 1)); q = (q - 1) * (r - 1) * (s - 1); } if (p > 0) { q = -q; } else { p = -p; } s = e; e = d; if (p >= 1.5 * m * q - FastMath.Abs(tol * q) || p >= FastMath.Abs(0.5 * s * q)) { // Inverse quadratic interpolation gives a value // in the wrong direction, or progress is slow. // Fall back to bisection. d = m; e = d; } else { d = p / q; } } a = b; fa = fb; if (FastMath.Abs(d) > tol) { b += d; } else if (m > 0) { b += tol; } else { b -= tol; } fb = ComputeObjectiveValue(b); if ((fb > 0 && fc > 0) || (fb <= 0 && fc <= 0)) { c = a; fc = fa; d = b - a; e = d; } } }
/// <summary> /// {@inheritDoc} /// </summary> /// <exception cref="ConvergenceException"> if the algorithm failed due to finite /// precision. </exception> protected internal override sealed double DoSolve() { // Get initial solution double x0 = GetMin(); double x1 = GetMax(); double f0 = ComputeObjectiveValue(x0); double f1 = ComputeObjectiveValue(x1); // If one of the bounds is the exact root, return it. Since these are // not under-approximations or over-approximations, we can return them // regardless of the allowed solutions. if (f0 == 0.0) { return(x0); } if (f1 == 0.0) { return(x1); } // Verify bracketing of initial solution. VerifyBracketing(x0, x1); // Get accuracies. //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double ftol = getFunctionValueAccuracy(); double ftol = GetFunctionValueAccuracy(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double atol = getAbsoluteAccuracy(); double atol = GetAbsoluteAccuracy(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double rtol = getRelativeAccuracy(); double rtol = GetRelativeAccuracy(); // Keep track of inverted intervals, meaning that the left bound is // larger than the right bound. bool inverted = false; // Keep finding better approximations. while (true) { // Calculate the next approximation. //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double x = x1 - ((f1 * (x1 - x0)) / (f1 - f0)); double x = x1 - ((f1 * (x1 - x0)) / (f1 - f0)); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double fx = computeObjectiveValue(x); double fx = ComputeObjectiveValue(x); // If the new approximation is the exact root, return it. Since // this is not an under-approximation or an over-approximation, // we can return it regardless of the allowed solutions. if (fx == 0.0) { return(x); } // Update the bounds with the new approximation. if (f1 * fx < 0) { // The value of x1 has switched to the other bound, thus inverting // the interval. x0 = x1; f0 = f1; inverted = !inverted; } else { switch (method) { case org.apache.commons.math3.analysis.solvers.BaseSecantSolver.Method.ILLINOIS: f0 *= 0.5; break; case org.apache.commons.math3.analysis.solvers.BaseSecantSolver.Method.PEGASUS: f0 *= f1 / (f1 + fx); break; case org.apache.commons.math3.analysis.solvers.BaseSecantSolver.Method.REGULA_FALSI: // Detect early that algorithm is stuck, instead of waiting // for the maximum number of iterations to be exceeded. if (x == x1) { throw new ConvergenceException(); } break; default: // Should never happen. throw new MathInternalError(); } } // Update from [x0, x1] to [x0, x]. x1 = x; f1 = fx; // If the function value of the last approximation is too small, // given the function value accuracy, then we can't get closer to // the root than we already are. if (FastMath.Abs(f1) <= ftol) { switch (allowed) { case org.apache.commons.math3.analysis.solvers.AllowedSolution.ANY_SIDE: return(x1); case org.apache.commons.math3.analysis.solvers.AllowedSolution.LEFT_SIDE: if (inverted) { return(x1); } break; case org.apache.commons.math3.analysis.solvers.AllowedSolution.RIGHT_SIDE: if (!inverted) { return(x1); } break; case org.apache.commons.math3.analysis.solvers.AllowedSolution.BELOW_SIDE: if (f1 <= 0) { return(x1); } break; case org.apache.commons.math3.analysis.solvers.AllowedSolution.ABOVE_SIDE: if (f1 >= 0) { return(x1); } break; default: throw new MathInternalError(); } } // If the current interval is within the given accuracies, we // are satisfied with the current approximation. if (FastMath.Abs(x1 - x0) < FastMath.Max(rtol * FastMath.Abs(x1), atol)) { switch (allowed) { case org.apache.commons.math3.analysis.solvers.AllowedSolution.ANY_SIDE: return(x1); case org.apache.commons.math3.analysis.solvers.AllowedSolution.LEFT_SIDE: return(inverted ? x1 : x0); case org.apache.commons.math3.analysis.solvers.AllowedSolution.RIGHT_SIDE: return(inverted ? x0 : x1); case org.apache.commons.math3.analysis.solvers.AllowedSolution.BELOW_SIDE: return((f1 <= 0) ? x1 : x0); case org.apache.commons.math3.analysis.solvers.AllowedSolution.ABOVE_SIDE: return((f1 >= 0) ? x1 : x0); default: throw new MathInternalError(); } } } }
/// <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); }
/// <summary> /// This method attempts to find two values a and b satisfying <ul> /// <li> {@code lowerBound <= a < initial < b <= upperBound} </li> /// <li> {@code f(a) * f(b) <= 0} </li> /// </ul> /// If {@code f} is continuous on {@code [a,b]}, this means that {@code a} /// and {@code b} bracket a root of {@code f}. /// <para> /// The algorithm checks the sign of \( f(l_k) \) and \( f(u_k) \) for increasing /// values of k, where \( l_k = max(lower, initial - \delta_k) \), /// \( u_k = min(upper, initial + \delta_k) \), using recurrence /// \( \delta_{k+1} = r \delta_k + q, \delta_0 = 0\) and starting search with \( k=1 \). /// The algorithm stops when one of the following happens: <ul> /// <li> at least one positive and one negative value have been found -- success!</li> /// <li> both endpoints have reached their respective limits -- NoBracketingException </li> /// <li> {@code maximumIterations} iterations elapse -- NoBracketingException </li></ul> /// </para> /// <para> /// If different signs are found at first iteration ({@code k=1}), then the returned /// interval will be \( [a, b] = [l_1, u_1] \). If different signs are found at a later /// iteration {@code k>1}, then the returned interval will be either /// \( [a, b] = [l_{k+1}, l_{k}] \) or \( [a, b] = [u_{k}, u_{k+1}] \). A root solver called /// with these parameters will therefore start with the smallest bracketing interval known /// at this step. /// </para> /// <para> /// Interval expansion rate is tuned by changing the recurrence parameters {@code r} and /// {@code q}. When the multiplicative factor {@code r} is set to 1, the sequence is a /// simple arithmetic sequence with linear increase. When the multiplicative factor {@code r} /// is larger than 1, the sequence has an asymptotically exponential rate. Note than the /// additive parameter {@code q} should never be set to zero, otherwise the interval would /// degenerate to the single initial point for all values of {@code k}. /// </para> /// <para> /// As a rule of thumb, when the location of the root is expected to be approximately known /// within some error margin, {@code r} should be set to 1 and {@code q} should be set to the /// order of magnitude of the error margin. When the location of the root is really a wild guess, /// then {@code r} should be set to a value larger than 1 (typically 2 to double the interval /// length at each iteration) and {@code q} should be set according to half the initial /// search interval length. /// </para> /// <para> /// As an example, if we consider the trivial function {@code f(x) = 1 - x} and use /// {@code initial = 4}, {@code r = 1}, {@code q = 2}, the algorithm will compute /// {@code f(4-2) = f(2) = -1} and {@code f(4+2) = f(6) = -5} for {@code k = 1}, then /// {@code f(4-4) = f(0) = +1} and {@code f(4+4) = f(8) = -7} for {@code k = 2}. Then it will /// return the interval {@code [0, 2]} as the smallest one known to be bracketing the root. /// As shown by this example, the initial value (here {@code 4}) may lie outside of the returned /// bracketing interval. /// </para> </summary> /// <param name="function"> function to check </param> /// <param name="initial"> Initial midpoint of interval being expanded to /// bracket a root. </param> /// <param name="lowerBound"> Lower bound (a is never lower than this value). </param> /// <param name="upperBound"> Upper bound (b never is greater than this /// value). </param> /// <param name="q"> additive offset used to compute bounds sequence (must be strictly positive) </param> /// <param name="r"> multiplicative factor used to compute bounds sequence </param> /// <param name="maximumIterations"> Maximum number of iterations to perform </param> /// <returns> a two element array holding the bracketing values. </returns> /// <exception cref="NoBracketingException"> if function cannot be bracketed in the search interval </exception> //JAVA TO C# CONVERTER WARNING: 'final' parameters are not available in .NET: //ORIGINAL LINE: public static double[] bracket(final org.apache.commons.math3.analysis.UnivariateFunction function, final double initial, final double lowerBound, final double upperBound, final double q, final double r, final int maximumIterations) throws org.apache.commons.math3.exception.NoBracketingException public static double[] Bracket(UnivariateFunction function, double initial, double lowerBound, double upperBound, double q, double r, int maximumIterations) { if (function == null) { throw new NullArgumentException(LocalizedFormats.FUNCTION); } if (q <= 0) { throw new NotStrictlyPositiveException(q); } if (maximumIterations <= 0) { throw new NotStrictlyPositiveException(LocalizedFormats.INVALID_MAX_ITERATIONS, maximumIterations); } VerifySequence(lowerBound, initial, upperBound); // initialize the recurrence double a = initial; double b = initial; double fa = Double.NaN; double fb = Double.NaN; double delta = 0; for (int numIterations = 0; (numIterations < maximumIterations) && (a > lowerBound || b < upperBound); ++numIterations) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double previousA = a; double previousA = a; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double previousFa = fa; double previousFa = fa; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double previousB = b; double previousB = b; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double previousFb = fb; double previousFb = fb; delta = r * delta + q; a = FastMath.Max(initial - delta, lowerBound); b = FastMath.Min(initial + delta, upperBound); fa = function.Value(a); fb = function.Value(b); if (numIterations == 0) { // at first iteration, we don't have a previous interval // we simply compare both sides of the initial interval if (fa * fb <= 0) { // the first interval already brackets a root return(new double[] { a, b }); } } else { // we have a previous interval with constant sign and expand it, // we expect sign changes to occur at boundaries if (fa * previousFa <= 0) { // sign change detected at near lower bound return(new double[] { a, previousA }); } else if (fb * previousFb <= 0) { // sign change detected at near upper bound return(new double[] { previousB, b }); } } } // no bracketing found throw new NoBracketingException(a, b, fa, fb); }
/// <summary> /// Find a real root in the given interval. /// </summary> /// <param name="min"> Lower bound for the interval. </param> /// <param name="max"> Upper bound for the interval. </param> /// <param name="fMin"> function value at the lower bound. </param> /// <param name="fMax"> function value at the upper bound. </param> /// <returns> the point at which the function value is zero. </returns> /// <exception cref="TooManyEvaluationsException"> if the allowed number of calls to /// the function to be solved has been exhausted. </exception> private double Solve(double min, double max, double fMin, double fMax) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double relativeAccuracy = getRelativeAccuracy(); double relativeAccuracy = GetRelativeAccuracy(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double absoluteAccuracy = getAbsoluteAccuracy(); double absoluteAccuracy = GetAbsoluteAccuracy(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double functionValueAccuracy = getFunctionValueAccuracy(); double functionValueAccuracy = GetFunctionValueAccuracy(); // [x0, x2] is the bracketing interval in each iteration // x1 is the last approximation and an interpolation point in (x0, x2) // x is the new root approximation and new x1 for next round // d01, d12, d012 are divided differences double x0 = min; double y0 = fMin; double x2 = max; double y2 = fMax; double x1 = 0.5 * (x0 + x2); double y1 = ComputeObjectiveValue(x1); double oldx = double.PositiveInfinity; while (true) { // Muller's method employs quadratic interpolation through // x0, x1, x2 and x is the zero of the interpolating parabola. // Due to bracketing condition, this parabola must have two // real roots and we choose one in [x0, x2] to be x. //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double d01 = (y1 - y0) / (x1 - x0); double d01 = (y1 - y0) / (x1 - x0); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double d12 = (y2 - y1) / (x2 - x1); double d12 = (y2 - y1) / (x2 - x1); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double d012 = (d12 - d01) / (x2 - x0); double d012 = (d12 - d01) / (x2 - x0); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double c1 = d01 + (x1 - x0) * d012; double c1 = d01 + (x1 - x0) * d012; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double delta = c1 * c1 - 4 * y1 * d012; double delta = c1 * c1 - 4 * y1 * d012; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double xplus = x1 + (-2.0 * y1) / (c1 + org.apache.commons.math3.util.FastMath.sqrt(delta)); double xplus = x1 + (-2.0 * y1) / (c1 + FastMath.Sqrt(delta)); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double xminus = x1 + (-2.0 * y1) / (c1 - org.apache.commons.math3.util.FastMath.sqrt(delta)); double xminus = x1 + (-2.0 * y1) / (c1 - FastMath.Sqrt(delta)); // xplus and xminus are two roots of parabola and at least // one of them should lie in (x0, x2) //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double x = isSequence(x0, xplus, x2) ? xplus : xminus; double x = IsSequence(x0, xplus, x2) ? xplus : xminus; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double y = computeObjectiveValue(x); double y = ComputeObjectiveValue(x); // check for convergence //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double tolerance = org.apache.commons.math3.util.FastMath.max(relativeAccuracy * org.apache.commons.math3.util.FastMath.abs(x), absoluteAccuracy); double tolerance = FastMath.Max(relativeAccuracy * FastMath.Abs(x), absoluteAccuracy); if (FastMath.Abs(x - oldx) <= tolerance || FastMath.Abs(y) <= functionValueAccuracy) { return(x); } // Bisect if convergence is too slow. Bisection would waste // our calculation of x, hopefully it won't happen often. // the real number equality test x == x1 is intentional and // completes the proximity tests above it bool bisect = (x <x1 && (x1 - x0)> 0.95 * (x2 - x0)) || (x > x1 && (x2 - x1) > 0.95 * (x2 - x0)) || (x == x1); // prepare the new bracketing interval for next iteration if (!bisect) { x0 = x < x1 ? x0 : x1; y0 = x < x1 ? y0 : y1; x2 = x > x1 ? x2 : x1; y2 = x > x1 ? y2 : y1; x1 = x; y1 = y; oldx = x; } else { double xm = 0.5 * (x0 + x2); double ym = ComputeObjectiveValue(xm); if (FastMath.Signum(y0) + FastMath.Signum(ym) == 0.0) { x2 = xm; y2 = ym; } else { x0 = xm; y0 = ym; } x1 = 0.5 * (x0 + x2); y1 = ComputeObjectiveValue(x1); oldx = double.PositiveInfinity; } } }
/// <summary> /// {@inheritDoc} </summary> protected internal override sealed double DoSolve() { // Get initial solution double x0 = GetMin(); double x1 = GetMax(); double f0 = ComputeObjectiveValue(x0); double f1 = ComputeObjectiveValue(x1); // If one of the bounds is the exact root, return it. Since these are // not under-approximations or over-approximations, we can return them // regardless of the allowed solutions. if (f0 == 0.0) { return(x0); } if (f1 == 0.0) { return(x1); } // Verify bracketing of initial solution. VerifyBracketing(x0, x1); // Get accuracies. //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double ftol = getFunctionValueAccuracy(); double ftol = GetFunctionValueAccuracy(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double atol = getAbsoluteAccuracy(); double atol = GetAbsoluteAccuracy(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double rtol = getRelativeAccuracy(); double rtol = GetRelativeAccuracy(); // Keep finding better approximations. while (true) { // Calculate the next approximation. //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double x = x1 - ((f1 * (x1 - x0)) / (f1 - f0)); double x = x1 - ((f1 * (x1 - x0)) / (f1 - f0)); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double fx = computeObjectiveValue(x); double fx = ComputeObjectiveValue(x); // If the new approximation is the exact root, return it. Since // this is not an under-approximation or an over-approximation, // we can return it regardless of the allowed solutions. if (fx == 0.0) { return(x); } // Update the bounds with the new approximation. x0 = x1; f0 = f1; x1 = x; f1 = fx; // If the function value of the last approximation is too small, // given the function value accuracy, then we can't get closer to // the root than we already are. if (FastMath.Abs(f1) <= ftol) { return(x1); } // If the current interval is within the given accuracies, we // are satisfied with the current approximation. if (FastMath.Abs(x1 - x0) < FastMath.Max(rtol * FastMath.Abs(x1), atol)) { return(x1); } } }
/// <summary> /// {@inheritDoc} /// </summary> protected internal override double DoSolve() { double min = GetMin(); double max = GetMax(); // [x1, x2] is the bracketing interval in each iteration // x3 is the midpoint of [x1, x2] // x is the new root approximation and an endpoint of the new interval double x1 = min; double y1 = ComputeObjectiveValue(x1); double x2 = max; double y2 = ComputeObjectiveValue(x2); // check for zeros before verifying bracketing if (y1 == 0) { return(min); } if (y2 == 0) { return(max); } VerifyBracketing(min, max); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double absoluteAccuracy = getAbsoluteAccuracy(); double absoluteAccuracy = GetAbsoluteAccuracy(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double functionValueAccuracy = getFunctionValueAccuracy(); double functionValueAccuracy = GetFunctionValueAccuracy(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double relativeAccuracy = getRelativeAccuracy(); double relativeAccuracy = GetRelativeAccuracy(); double oldx = double.PositiveInfinity; while (true) { // calculate the new root approximation //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double x3 = 0.5 * (x1 + x2); double x3 = 0.5 * (x1 + x2); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double y3 = computeObjectiveValue(x3); double y3 = ComputeObjectiveValue(x3); if (FastMath.Abs(y3) <= functionValueAccuracy) { return(x3); } //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double delta = 1 - (y1 * y2) / (y3 * y3); double delta = 1 - (y1 * y2) / (y3 * y3); // delta > 1 due to bracketing //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double correction = (org.apache.commons.math3.util.FastMath.signum(y2) * org.apache.commons.math3.util.FastMath.signum(y3)) * (x3 - x1) / org.apache.commons.math3.util.FastMath.sqrt(delta); double correction = (FastMath.Signum(y2) * FastMath.Signum(y3)) * (x3 - x1) / FastMath.Sqrt(delta); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double x = x3 - correction; double x = x3 - correction; // correction != 0 //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double y = computeObjectiveValue(x); double y = ComputeObjectiveValue(x); // check for convergence //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double tolerance = org.apache.commons.math3.util.FastMath.max(relativeAccuracy * org.apache.commons.math3.util.FastMath.abs(x), absoluteAccuracy); double tolerance = FastMath.Max(relativeAccuracy * FastMath.Abs(x), absoluteAccuracy); if (FastMath.Abs(x - oldx) <= tolerance) { return(x); } if (FastMath.Abs(y) <= functionValueAccuracy) { return(x); } // prepare the new interval for next iteration // Ridders' method guarantees x1 < x < x2 if (correction > 0.0) { // x1 < x < x3 if (FastMath.Signum(y1) + FastMath.Signum(y) == 0.0) { x2 = x; y2 = y; } else { x1 = x; x2 = x3; y1 = y; y2 = y3; } } else { // x3 < x < x2 if (FastMath.Signum(y2) + FastMath.Signum(y) == 0.0) { x1 = x; y1 = y; } else { x1 = x3; x2 = x; y1 = y3; y2 = y; } } oldx = x; } }
/// <summary> /// {@inheritDoc} /// </summary> protected internal override double DoSolve() { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double min = getMin(); double min = GetMin(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double max = getMax(); double max = GetMax(); VerifyInterval(min, max); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double relativeAccuracy = getRelativeAccuracy(); double relativeAccuracy = GetRelativeAccuracy(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double absoluteAccuracy = getAbsoluteAccuracy(); double absoluteAccuracy = GetAbsoluteAccuracy(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double functionValueAccuracy = getFunctionValueAccuracy(); double functionValueAccuracy = GetFunctionValueAccuracy(); // x2 is the last root approximation // x is the new approximation and new x2 for next round // x0 < x1 < x2 does not hold here double x0 = min; double y0 = ComputeObjectiveValue(x0); if (FastMath.Abs(y0) < functionValueAccuracy) { return(x0); } double x1 = max; double y1 = ComputeObjectiveValue(x1); if (FastMath.Abs(y1) < functionValueAccuracy) { return(x1); } if (y0 * y1 > 0) { throw new NoBracketingException(x0, x1, y0, y1); } double x2 = 0.5 * (x0 + x1); double y2 = ComputeObjectiveValue(x2); double oldx = double.PositiveInfinity; while (true) { // quadratic interpolation through x0, x1, x2 //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double q = (x2 - x1) / (x1 - x0); double q = (x2 - x1) / (x1 - x0); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double a = q * (y2 - (1 + q) * y1 + q * y0); double a = q * (y2 - (1 + q) * y1 + q * y0); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double b = (2 * q + 1) * y2 - (1 + q) * (1 + q) * y1 + q * q * y0; double b = (2 * q + 1) * y2 - (1 + q) * (1 + q) * y1 + q * q * y0; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double c = (1 + q) * y2; double c = (1 + q) * y2; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double delta = b * b - 4 * a * c; double delta = b * b - 4 * a * c; double x; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double denominator; double denominator; if (delta >= 0.0) { // choose a denominator larger in magnitude double dplus = b + FastMath.Sqrt(delta); double dminus = b - FastMath.Sqrt(delta); denominator = FastMath.Abs(dplus) > FastMath.Abs(dminus) ? dplus : dminus; } else { // take the modulus of (B +/- FastMath.sqrt(delta)) denominator = FastMath.Sqrt(b * b - delta); } if (denominator != 0) { x = x2 - 2.0 * c * (x2 - x1) / denominator; // perturb x if it exactly coincides with x1 or x2 // the equality tests here are intentional while (x == x1 || x == x2) { x += absoluteAccuracy; } } else { // extremely rare case, get a random number to skip it x = min + FastMath.Random() * (max - min); oldx = double.PositiveInfinity; } //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double y = computeObjectiveValue(x); double y = ComputeObjectiveValue(x); // check for convergence //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double tolerance = org.apache.commons.math3.util.FastMath.max(relativeAccuracy * org.apache.commons.math3.util.FastMath.abs(x), absoluteAccuracy); double tolerance = FastMath.Max(relativeAccuracy * FastMath.Abs(x), absoluteAccuracy); if (FastMath.Abs(x - oldx) <= tolerance || FastMath.Abs(y) <= functionValueAccuracy) { return(x); } // prepare the next iteration x0 = x1; y0 = y1; x1 = x2; y1 = y2; x2 = x; y2 = y; oldx = x; } }