This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-math.git

commit 95457776946b6c30788c120a76d0be3376ef4dc1
Author: aherbert <aherb...@apache.org>
AuthorDate: Thu Oct 13 16:03:26 2022 +0100

    Update test to move towards the previously found optimum
---
 .../LevenbergMarquardtOptimizerTest.java           | 25 +++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git 
a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/fitting/leastsquares/LevenbergMarquardtOptimizerTest.java
 
b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/fitting/leastsquares/LevenbergMarquardtOptimizerTest.java
index 4a76eb3f2..cdac94d1d 100644
--- 
a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/fitting/leastsquares/LevenbergMarquardtOptimizerTest.java
+++ 
b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/fitting/leastsquares/LevenbergMarquardtOptimizerTest.java
@@ -291,25 +291,40 @@ public class LevenbergMarquardtOptimizerTest
 
         // First guess for the center's coordinates and radius.
         final double[] init = { 118, 659, 115 };
-        final Optimum optimum
-            = 
optimizer.optimize(builder(circle).maxIterations(50).start(init).build());
+
+        final Optimum optimum = optimizer.optimize(
+                builder(circle).maxIterations(50).start(init).build());
+
         final int numEval = optimum.getEvaluations();
         Assert.assertTrue(numEval > 1);
 
         // Build a new problem with a validator that amounts to cheating.
+
+        // Note we cannot return a fixed point.
+        // The optimiser relies on computing a predicted reduction in the cost
+        // function (preRed) and an actual reduction (actRed). The ratio 
between them must be
+        // non-zero to indicate the step reduced the cost function. If a 
threshold is not
+        // achieved then the step is rejected and the optimiser can cycle 
through many iterations
+        // not moving anywhere until alternative thresholds reduce to a level 
that terminate
+        // the cycle.
+        // Here we take the current point and move it towards an acceptable 
answer
+        // given the problem (the previous optimum). This should speed up the 
optimiser.
+        // This can still fail to reduce the iterations when the adjusted step 
moves
+        // to a sub-optimal position in the cost function.
         final ParameterValidator cheatValidator
             = new ParameterValidator() {
                     @Override
                     public RealVector validate(RealVector params) {
-                        // Cheat: return the optimum found previously.
-                        return optimum.getPoint();
+                        // Cheat: Move towards the optimum found previously.
+                        final RealVector direction = 
optimum.getPoint().subtract(params);
+                        return params.add(direction.mapMultiply(0.75));
                     }
                 };
 
         final Optimum cheatOptimum
             = 
optimizer.optimize(builder(circle).maxIterations(50).start(init).parameterValidator(cheatValidator).build());
         final int cheatNumEval = cheatOptimum.getEvaluations();
-        Assert.assertTrue(cheatNumEval < numEval);
+        Assert.assertTrue("n=" + numEval + " nc=" + cheatNumEval, cheatNumEval 
< numEval);
         // System.out.println("n=" + numEval + " nc=" + cheatNumEval);
     }
 

Reply via email to