commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From l..@apache.org
Subject svn commit: r1573307 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math3/fitting/leastsquares/ test/java/org/apache/commons/math3/fitting/leastsquares/
Date Sun, 02 Mar 2014 14:02:21 GMT
Author: luc
Date: Sun Mar  2 14:02:21 2014
New Revision: 1573307

URL: http://svn.apache.org/r1573307
Log:
Fix checker seeing not old point

ConvergenceCheckers always saw previous.getPoint() to equal
current.getPoint() because the optimizers used the same array and did
not make a copy of the previous point. Fixed by using a new array for
each model evaluation and LSP.evaluate() now makes its own copy of the
state vector as well.

Path provided by Evan Ward.

JIRA: MATH-1103

Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/GaussNewtonOptimizer.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/LeastSquaresFactory.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/LevenbergMarquardtOptimizer.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/leastsquares/AbstractLeastSquaresOptimizerAbstractTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/leastsquares/EvaluationTest.java

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/GaussNewtonOptimizer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/GaussNewtonOptimizer.java?rev=1573307&r1=1573306&r2=1573307&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/GaussNewtonOptimizer.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/GaussNewtonOptimizer.java
Sun Mar  2 14:02:21 2014
@@ -197,9 +197,7 @@ public class GaussNewtonOptimizer implem
             throw new NullArgumentException();
         }
 
-        final int nC = lsp.getParameterSize();
-
-        final RealVector currentPoint = lsp.getStart();
+        RealVector currentPoint = lsp.getStart();
 
         // iterate until convergence is reached
         Evaluation current = null;
@@ -227,9 +225,7 @@ public class GaussNewtonOptimizer implem
             // solve the linearized least squares problem
             final RealVector dX = this.decomposition.solve(weightedJacobian, currentResiduals);
             // update the estimated parameters
-            for (int i = 0; i < nC; ++i) {
-                currentPoint.setEntry(i, currentPoint.getEntry(i) + dX.getEntry(i));
-            }
+            currentPoint = currentPoint.add(dX);
         }
     }
 

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/LeastSquaresFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/LeastSquaresFactory.java?rev=1573307&r1=1573306&r2=1573307&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/LeastSquaresFactory.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/LeastSquaresFactory.java
Sun Mar  2 14:02:21 2014
@@ -332,7 +332,8 @@ public class LeastSquaresFactory {
                     value.getFirst(),
                     value.getSecond(),
                     this.target,
-                    point);
+                    // copy so optimizer can change point without changing our instance
+                    point.copy());
         }
 
         /**

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/LevenbergMarquardtOptimizer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/LevenbergMarquardtOptimizer.java?rev=1573307&r1=1573306&r2=1573307&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/LevenbergMarquardtOptimizer.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/LevenbergMarquardtOptimizer.java
Sun Mar  2 14:02:21 2014
@@ -328,7 +328,7 @@ public class LevenbergMarquardtOptimizer
         // Evaluate the function at the starting point and calculate its norm.
         evaluationCounter.incrementCount();
         //value will be reassigned in the loop
-        Evaluation current = problem.evaluate(new ArrayRealVector(currentPoint, false));
+        Evaluation current = problem.evaluate(new ArrayRealVector(currentPoint));
         double[] currentResiduals = current.getResiduals().toArray();
         double currentCost = current.getCost();
 
@@ -445,7 +445,7 @@ public class LevenbergMarquardtOptimizer
 
                 // Evaluate the function at x + p and calculate its norm.
                 evaluationCounter.incrementCount();
-                current = problem.evaluate(new ArrayRealVector(currentPoint,false));
+                current = problem.evaluate(new ArrayRealVector(currentPoint));
                 currentResiduals = current.getResiduals().toArray();
                 currentCost = current.getCost();
 

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/leastsquares/AbstractLeastSquaresOptimizerAbstractTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/leastsquares/AbstractLeastSquaresOptimizerAbstractTest.java?rev=1573307&r1=1573306&r2=1573307&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/leastsquares/AbstractLeastSquaresOptimizerAbstractTest.java
(original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/leastsquares/AbstractLeastSquaresOptimizerAbstractTest.java
Sun Mar  2 14:02:21 2014
@@ -21,6 +21,7 @@ import org.apache.commons.math3.analysis
 import org.apache.commons.math3.exception.ConvergenceException;
 import org.apache.commons.math3.exception.DimensionMismatchException;
 import org.apache.commons.math3.fitting.leastsquares.LeastSquaresOptimizer.Optimum;
+import org.apache.commons.math3.fitting.leastsquares.LeastSquaresProblem.Evaluation;
 import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
 import org.apache.commons.math3.linear.Array2DRowRealMatrix;
 import org.apache.commons.math3.linear.ArrayRealVector;
@@ -28,6 +29,7 @@ import org.apache.commons.math3.linear.B
 import org.apache.commons.math3.linear.DiagonalMatrix;
 import org.apache.commons.math3.linear.RealMatrix;
 import org.apache.commons.math3.linear.RealVector;
+import org.apache.commons.math3.optim.ConvergenceChecker;
 import org.apache.commons.math3.optim.SimpleVectorValueChecker;
 import org.apache.commons.math3.util.FastMath;
 import org.apache.commons.math3.util.Pair;
@@ -37,6 +39,10 @@ import org.junit.Test;
 import java.io.IOException;
 import java.util.Arrays;
 
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.sameInstance;
+
 /**
  * Some of the unit tests are re-implementations of the MINPACK <a
  * href="http://www.netlib.org/minpack/ex/file17">file17</a> and <a
@@ -525,6 +531,33 @@ public abstract class AbstractLeastSquar
         doTestStRD(StatisticalReferenceDatasetFactory.createHahn1(), optimizer, 1E-7, 1E-4);
     }
 
+    @Test
+    public void testPointCopy() {
+        LinearProblem problem = new LinearProblem(new double[][]{
+                {1, 0, 0},
+                {-1, 1, 0},
+                {0, -1, 1}
+        }, new double[]{1, 1, 1});
+        //mutable boolean
+        final boolean[] checked = {false};
+
+        final LeastSquaresBuilder builder = problem.getBuilder()
+                .checker(new ConvergenceChecker<Evaluation>() {
+                    public boolean converged(int iteration, Evaluation previous, Evaluation
current) {
+                        Assert.assertThat(
+                                previous.getPoint(),
+                                not(sameInstance(current.getPoint())));
+                        Assert.assertArrayEquals(new double[3], previous.getPoint().toArray(),
0);
+                        Assert.assertArrayEquals(new double[] {1, 2, 3}, current.getPoint().toArray(),
TOl);
+                        checked[0] = true;
+                        return true;
+                    }
+                });
+        Optimum optimum = optimizer.optimize(builder.build());
+
+        Assert.assertThat(checked[0], is(true));
+    }
+
     class LinearProblem {
         private final RealMatrix factors;
         private final double[] target;

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/leastsquares/EvaluationTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/leastsquares/EvaluationTest.java?rev=1573307&r1=1573306&r2=1573307&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/leastsquares/EvaluationTest.java
(original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/leastsquares/EvaluationTest.java
Sun Mar  2 14:02:21 2014
@@ -199,4 +199,22 @@ public class EvaluationTest {
                                 expected[i], actual, 1e-6 * expected[i]);
         }
     }
+
+    @Test
+    public void testEvaluateCopiesPoint() throws IOException {
+        //setup
+        StatisticalReferenceDataset dataset
+                = StatisticalReferenceDatasetFactory.createKirby2();
+        LeastSquaresProblem lsp = builder(dataset).build();
+        RealVector point = new ArrayRealVector(lsp.getParameterSize());
+
+        //action
+        Evaluation evaluation = lsp.evaluate(point);
+
+        //verify
+        Assert.assertNotSame(point, evaluation.getPoint());
+        point.setEntry(0, 1);
+        Assert.assertEquals(evaluation.getPoint().getEntry(0), 0, 0);
+    }
+
 }



Mime
View raw message