commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From l..@apache.org
Subject svn commit: r1144831 - /commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java
Date Sun, 10 Jul 2011 11:11:59 GMT
Author: luc
Date: Sun Jul 10 11:11:58 2011
New Revision: 1144831

URL: http://svn.apache.org/viewvc?rev=1144831&view=rev
Log:
added a forceSide method to UnivariateRealsolversUtils to allow selecting a bracketing side
even for non-bracketing solvers like Bren or Newton

Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java?rev=1144831&r1=1144830&r2=1144831&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java
Sun Jul 10 11:11:58 2011
@@ -17,11 +17,11 @@
 package org.apache.commons.math.analysis.solvers;
 
 import org.apache.commons.math.analysis.UnivariateRealFunction;
-import org.apache.commons.math.exception.util.LocalizedFormats;
-import org.apache.commons.math.exception.NullArgumentException;
 import org.apache.commons.math.exception.NoBracketingException;
-import org.apache.commons.math.exception.NumberIsTooLargeException;
 import org.apache.commons.math.exception.NotStrictlyPositiveException;
+import org.apache.commons.math.exception.NullArgumentException;
+import org.apache.commons.math.exception.NumberIsTooLargeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
 import org.apache.commons.math.util.FastMath;
 
 /**
@@ -77,9 +77,93 @@ public class UnivariateRealSolverUtils {
         return solver.solve(Integer.MAX_VALUE, function, x0, x1);
     }
 
+    /** Force a root found by a non-bracketing solver to lie on a specified side,
+     * as if the solver was a bracketing one.
+     * @param 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 f function to solve
+     * @param bracketing bracketing solver to use for shifting the root
+     * @param baseRoot original root found by a previous non-bracketing solver
+     * @param min minimal bound of the search interval
+     * @param max maximal bound of the search interval
+     * @param allowedSolutions the kind of solutions that the root-finding algorithm may
+     * accept as solutions.
+     */
+    public static double forceSide(final int maxEval, final UnivariateRealFunction f,
+                                   final BracketedUnivariateRealSolver<UnivariateRealFunction>
bracketing,
+                                   final double baseRoot, final double min, final double
max,
+                                   final AllowedSolutions allowedSolutions) {
+
+        if (allowedSolutions == AllowedSolutions.ANY_SIDE) {
+            // no further bracketing required
+            return baseRoot;
+        }
+
+        // find a very small interval bracketing the root
+        final double step = FastMath.max(bracketing.getAbsoluteAccuracy(),
+                                         FastMath.abs(baseRoot * bracketing.getRelativeAccuracy()));
+        double xLo        = baseRoot - step;
+        double fLo        = f.value(xLo);
+        double xHi        = baseRoot + step;
+        double fHi        = f.value(xHi);
+        int remainingEval = maxEval - 2;
+        while ((remainingEval > 0) && (xLo >= min) && (xHi <= max))
{
+
+            if ((fLo > 0 && fHi < 0) || (fLo < 0 && fHi > 0))
{
+                // compute the root on the selected side
+                return bracketing.solve(remainingEval, f, xLo, xHi, baseRoot, allowedSolutions);
+            }
+
+            // 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 -= step;
+                fLo  = f.value(xLo);
+                remainingEval--;
+            }
+
+            // update the higher bound
+            if (changeHi) {
+                xHi += step;
+                fHi  = f.value(xHi);
+                remainingEval--;
+            }
+
+        }
+
+        throw new NoBracketingException(LocalizedFormats.FAILED_BRACKETING,
+                                        xLo, xHi, fLo, fHi,
+                                        maxEval - remainingEval, maxEval, baseRoot,
+                                        min, max);
+
+    }
+
     /**
      * This method attempts to find two values a and b satisfying <ul>
-    * <li> <code> lowerBound <= a < initial < b <= upperBound</code>
</li>
+     * <li> <code> lowerBound <= a < initial < b <= upperBound</code>
</li>
      * <li> <code> f(a) * f(b) < 0 </code></li>
      * </ul>
      * If f is continuous on <code>[a,b],</code> this means that <code>a</code>



Mime
View raw message