Repository: commons-math
Updated Branches:
  refs/heads/feature-MATH-1333 [created] 160696e7f


MATH-1333

Unit test showing the problem.  Thanks to Connor Petty for the report.

Assumption made in the code is wrong.


Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/160696e7
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/160696e7
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/160696e7

Branch: refs/heads/feature-MATH-1333
Commit: 160696e7faa591e14658aec12fc159efdb65cf12
Parents: 12c9a04
Author: Gilles <er...@apache.org>
Authored: Wed Mar 9 16:47:09 2016 +0100
Committer: Gilles <er...@apache.org>
Committed: Wed Mar 9 16:47:09 2016 +0100

----------------------------------------------------------------------
 .../math4/analysis/solvers/MullerSolver.java    |  9 ++++--
 .../analysis/solvers/MullerSolverTest.java      | 31 ++++++++++++++++++++
 2 files changed, 38 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-math/blob/160696e7/src/main/java/org/apache/commons/math4/analysis/solvers/MullerSolver.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/analysis/solvers/MullerSolver.java 
b/src/main/java/org/apache/commons/math4/analysis/solvers/MullerSolver.java
index b714399..d7fc189 100644
--- a/src/main/java/org/apache/commons/math4/analysis/solvers/MullerSolver.java
+++ b/src/main/java/org/apache/commons/math4/analysis/solvers/MullerSolver.java
@@ -29,8 +29,6 @@ import org.apache.commons.math4.util.FastMath;
  * <p>
  * Muller's method applies to both real and complex functions, but here we
  * restrict ourselves to real functions.
- * This class differs from {@link MullerSolver} in the way it avoids complex
- * operations.</p><p>
  * Muller's original method would have function evaluation at complex point.
  * Since our f(x) is real, we have to find ways to avoid that. Bracketing
  * condition is one way to go: by requiring bracketing in every iteration,
@@ -161,6 +159,13 @@ public class MullerSolver extends AbstractUnivariateSolver 
{
             // xplus and xminus are two roots of parabola and at least
             // one of them should lie in (x0, x2)
             final double x = isSequence(x0, xplus, x2) ? xplus : xminus;
+
+            // XXX debug
+            if (!isSequence(x0, x, x2)) {
+                System.out.println("x=" + x + " x0=" + x0 + " x2=" + x2);
+                throw new 
org.apache.commons.math4.exception.MathInternalError();
+            }
+
             final double y = computeObjectiveValue(x);
 
             // check for convergence

http://git-wip-us.apache.org/repos/asf/commons-math/blob/160696e7/src/test/java/org/apache/commons/math4/analysis/solvers/MullerSolverTest.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/commons/math4/analysis/solvers/MullerSolverTest.java 
b/src/test/java/org/apache/commons/math4/analysis/solvers/MullerSolverTest.java
index e82be52..2bb0b1b 100644
--- 
a/src/test/java/org/apache/commons/math4/analysis/solvers/MullerSolverTest.java
+++ 
b/src/test/java/org/apache/commons/math4/analysis/solvers/MullerSolverTest.java
@@ -147,4 +147,35 @@ public final class MullerSolverTest {
             // expected
         }
     }
+
+    @Test
+    public void testMath1333() {
+        final UnivariateFunction logFunction = new UnivariateFunction() {
+                private double log1pe(double x) {
+                    if (x > 0) {
+                        return x + FastMath.log1p(FastMath.exp(-x));
+                    } else {
+                        return FastMath.log1p(FastMath.exp(x));
+                    }
+                }
+
+                @Override
+                public double value(double x) {
+                    final double a = 0.15076136473214652;
+                    final double b = 4.880819340168248;
+                    final double c = -2330.4196672490493;
+                    final double d = 1.1871451743330544E-16;
+                    //aa*log(1+e^(bbx+c))+d - 0.01 * x - 20 * 0.01
+                    return a * a * log1pe(b * b * x + c) + d - 0.01 * x - 20 * 
0.01;
+                }
+            };
+
+        final UnivariateSolver solver = new MullerSolver(0.25);
+        final double min = 20;
+        final double max = 100.04173804515072;
+        final double result = solver.solve(1000, logFunction, min, max, 100 / 
(double) 3);
+
+        Assert.assertTrue(result + " < " + min, result >= min);
+        Assert.assertTrue(result + " > " + max, result <= max);
+    }
 }

Reply via email to