You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2023/06/29 21:55:30 UTC

[commons-math] branch master updated: MATH-1658: Enable passing a "ConvergenceChecker" as "OptimizationData".

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 2fb5f6aa9 MATH-1658: Enable passing a "ConvergenceChecker" as "OptimizationData".
2fb5f6aa9 is described below

commit 2fb5f6aa950cae4cca7997bfd3990e35eda4cef2
Author: Gilles Sadowski <gi...@gmail.com>
AuthorDate: Thu Jun 29 23:49:51 2023 +0200

    MATH-1658: Enable passing a "ConvergenceChecker" as "OptimizationData".
---
 .../commons/math4/legacy/optim/BaseOptimizer.java  |  8 ++-
 .../math4/legacy/optim/ConvergenceChecker.java     |  2 +-
 .../math4/legacy/optim/BaseOptimizerTest.java      | 77 ++++++++++++++++++++++
 src/changes/changes.xml                            |  3 +
 4 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/BaseOptimizer.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/BaseOptimizer.java
index 4ebd6fb18..3e16d7b28 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/BaseOptimizer.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/BaseOptimizer.java
@@ -39,7 +39,7 @@ public abstract class BaseOptimizer<PAIR> {
     private static final MaxIterCallback MAX_ITER_CALLBACK = new MaxIterCallback();
 
     /** Convergence checker. */
-    private final ConvergenceChecker<PAIR> checker;
+    private ConvergenceChecker<PAIR> checker;
     /** Maximum number of evaluations. */
     private int maxEvaluations;
     /** Maximum number of iterations. */
@@ -141,6 +141,7 @@ public abstract class BaseOptimizer<PAIR> {
      * <ul>
      *  <li>{@link MaxEval}</li>
      *  <li>{@link MaxIter}</li>
+     *  <li>{@link ConvergenceChecker}</li>
      * </ul>
      * @return a point/value pair that satisfies the convergence criteria.
      * @throws TooManyEvaluationsException if the maximal number of
@@ -210,6 +211,7 @@ public abstract class BaseOptimizer<PAIR> {
      * <ul>
      *  <li>{@link MaxEval}</li>
      *  <li>{@link MaxIter}</li>
+     *  <li>{@link ConvergenceChecker}</li>
      * </ul>
      */
     protected void parseOptimizationData(OptimizationData... optData) {
@@ -224,6 +226,10 @@ public abstract class BaseOptimizer<PAIR> {
                 maxIterations = ((MaxIter) data).getMaxIter();
                 continue;
             }
+            if (data instanceof ConvergenceChecker) {
+                checker = (ConvergenceChecker<PAIR>) data;
+                continue;
+            }
         }
     }
 
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/ConvergenceChecker.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/ConvergenceChecker.java
index 63f7cca2a..221af27fc 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/ConvergenceChecker.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/ConvergenceChecker.java
@@ -42,7 +42,7 @@ package org.apache.commons.math4.legacy.optim;
  *
  * @since 3.0
  */
-public interface ConvergenceChecker<PAIR> {
+public interface ConvergenceChecker<PAIR> extends OptimizationData {
     /**
      * Check if the optimization algorithm has converged.
      *
diff --git a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/optim/BaseOptimizerTest.java b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/optim/BaseOptimizerTest.java
new file mode 100644
index 000000000..69d4ac812
--- /dev/null
+++ b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/optim/BaseOptimizerTest.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math4.legacy.optim;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+/**
+ * Tests for {@link BaseOptimizer}.
+ */
+public class BaseOptimizerTest {
+    @Test
+    public void testDefault() {
+        final DummyOptimizer dummy = new DummyOptimizer(null);
+
+        final Object result = dummy.optimize();
+
+        // No default checker.
+        Assert.assertEquals(null, dummy.getConvergenceChecker());
+        // Default "MaxIter".
+        Assert.assertEquals(Integer.MAX_VALUE, dummy.getMaxIterations());
+        // Default "MaxEval".
+        Assert.assertEquals(0, dummy.getMaxEvaluations());
+    }
+
+    @Test
+    public void testParseOptimizationData() {
+        final DummyOptimizer dummy = new DummyOptimizer(null);
+
+        final ConvergenceChecker<Object> checker = new ConvergenceChecker<Object>() {
+                @Override
+                public boolean converged(int iteration,
+                                         Object previous,
+                                         Object current) {
+                    return true;
+                }
+            };
+
+        final int maxEval = 123;
+        final int maxIter = 4;
+        final Object result = dummy.optimize(checker,
+                                             new MaxEval(maxEval),
+                                             new MaxIter(maxIter));
+
+        Assert.assertEquals(checker, dummy.getConvergenceChecker());
+        Assert.assertEquals(maxIter, dummy.getMaxIterations());
+        Assert.assertEquals(maxEval, dummy.getMaxEvaluations());
+    }
+}
+
+class DummyOptimizer extends BaseOptimizer<Object> {
+    /**
+     * @param checker Checker.
+     */
+    DummyOptimizer(ConvergenceChecker<Object> checker) {
+        super(checker);
+    }
+
+    @Override
+    protected Object doOptimize() {
+        return new Object();
+    }
+}
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 4242b6c40..7cdfff9d3 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -96,6 +96,9 @@ Caveat:
  to support the whole codebase (it was one of the main reasons for
  creating more focused components).
 ">
+      <action dev="erans" type="update" issue="MATH-1658">
+        Allow convergence checker to be specified as "OptimizationData".
+      </action>
       <action dev="erans" type="update" issue="MATH-1657" due-to="François Laferrière">
         Small refactoring of the "evaluation counter" in optimizers' base class:
         Provide (protected) accessor (to replace method "computeObjectiveValue").