commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From er...@apache.org
Subject svn commit: r1154614 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/analysis/solvers/BaseSecantSolver.java test/java/org/apache/commons/math/analysis/solvers/RegulaFalsiSolverTest.java
Date Sat, 06 Aug 2011 22:26:55 GMT
Author: erans
Date: Sat Aug  6 22:26:55 2011
New Revision: 1154614

URL: http://svn.apache.org/viewvc?rev=1154614&view=rev
Log:
MATH-631
Work around infinite loop.

Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/BaseSecantSolver.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/solvers/RegulaFalsiSolverTest.java

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/BaseSecantSolver.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/BaseSecantSolver.java?rev=1154614&r1=1154613&r2=1154614&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/BaseSecantSolver.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/BaseSecantSolver.java
Sat Aug  6 22:26:55 2011
@@ -169,25 +169,37 @@ public abstract class BaseSecantSolver
 
             // Update the bounds with the new approximation.
             if (f1 * fx < 0) {
-                // We had [x0..x1]. We update it to [x1, x]. Note that the
-                // value of x1 has switched to the other bound, thus inverting
+                // The value of x1 has switched to the other bound, thus inverting
                 // the interval.
                 x0 = x1;
                 f0 = f1;
-                x1 = x;
-                f1 = fx;
                 inverted = !inverted;
             } else {
-                // We had [x0..x1]. We update it to [x0, x].
-                if (method == Method.ILLINOIS) {
+                switch (method) {
+                case ILLINOIS:
                     f0 *= 0.5;
-                }
-                if (method == Method.PEGASUS) {
+                    break;
+                case PEGASUS:
                     f0 *= f1 / (f1 + fx);
+                    break;
+                case REGULA_FALSI:
+                    if (x == x1) {
+                        final double delta = FastMath.max(rtol * FastMath.abs(x1),
+                                                          atol);
+                        // Update formula cannot make any progress: Update the
+                        // search interval.
+                        x0 = 0.5 * (x0 + x1 - delta);
+                        f0 = computeObjectiveValue(x0);
+                    }
+                    break;
+                default:
+                    // Should never happen.
+                    throw new MathInternalError();
                 }
-                x1 = x;
-                f1 = fx;
             }
+            // 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

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/solvers/RegulaFalsiSolverTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/solvers/RegulaFalsiSolverTest.java?rev=1154614&r1=1154613&r2=1154614&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/solvers/RegulaFalsiSolverTest.java
(original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/solvers/RegulaFalsiSolverTest.java
Sat Aug  6 22:26:55 2011
@@ -17,6 +17,10 @@
 
 package org.apache.commons.math.analysis.solvers;
 
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.junit.Test;
+import org.junit.Assert;
+
 /**
  * Test case for {@link RegulaFalsiSolver Regula Falsi} solver.
  *
@@ -35,4 +39,18 @@ public final class RegulaFalsiSolverTest
         // even a million iterations. As such, it was disabled.
         return new int[] {3, 7, 8, 19, 18, 11, 67, 55, 288, 151, -1};
     }
+
+    @Test
+    public void testIssue631() {
+        final UnivariateRealFunction f = new UnivariateRealFunction() {
+                @Override
+                public double value(double x) {
+                    return Math.exp(x) - Math.pow(Math.PI, 3.0);
+                }
+            };
+
+        final UnivariateRealSolver solver = new RegulaFalsiSolver();
+        final double root = solver.solve(3624, f, 1, 10);
+        Assert.assertEquals(3.4341896575482003, root, 1e-15);
+	}
 }



Mime
View raw message