commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From er...@apache.org
Subject svn commit: r1411807 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math3/optimization/ test/java/org/apache/commons/math3/optimization/fitting/
Date Tue, 20 Nov 2012 19:29:17 GMT
Author: erans
Date: Tue Nov 20 19:29:16 2012
New Revision: 1411807

URL: http://svn.apache.org/viewvc?rev=1411807&view=rev
Log:
MATH-902
Added a constructor in the custom checkers that enables normal termination
of an optimization algorithm (i.e. returning the curent best point after a
selected number of iterations have been performed).

Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimplePointChecker.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleValueChecker.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleVectorValueChecker.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/fitting/PolynomialFitterTest.java

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimplePointChecker.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimplePointChecker.java?rev=1411807&r1=1411806&r2=1411807&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimplePointChecker.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimplePointChecker.java
Tue Nov 20 19:29:16 2012
@@ -19,6 +19,7 @@ package org.apache.commons.math3.optimiz
 
 import org.apache.commons.math3.util.FastMath;
 import org.apache.commons.math3.util.Pair;
+import org.apache.commons.math3.exception.NotStrictlyPositiveException;
 
 /**
  * Simple implementation of the {@link ConvergenceChecker} interface using
@@ -28,6 +29,10 @@ import org.apache.commons.math3.util.Pai
  * difference between each point coordinate are smaller than a threshold
  * or if either the absolute difference between the point coordinates are
  * smaller than another threshold.
+ * <br/>
+ * The {@link #converged(int,Pair,Pair) converged} method will also return
+ * {@code true} if the number of iterations has been set (see
+ * {@link #SimplePointChecker(double,double,int) this constructor}).
  *
  * @param <PAIR> Type of the (point, value) pair.
  * The type of the "value" part of the pair (not used by this class).
@@ -38,11 +43,26 @@ import org.apache.commons.math3.util.Pai
 public class SimplePointChecker<PAIR extends Pair<double[], ? extends Object>>
     extends AbstractConvergenceChecker<PAIR> {
     /**
+     * If {@link #maxIterationCount} is set to this value, the number of
+     * iterations will never cause {@link #converged(int,Pair,Pair>)}
+     * to return {@code true}.
+     */
+    private static final int ITERATION_CHECK_DISABLED = -1;
+    /**
+     * Number of iterations after which the
+     * {@link #converged(int,PointVectorValuePair,PointVectorValuePair)} method
+     * will return true (unless the check is disabled).
+     */
+    private final int maxIterationCount;
+
+    /**
      * Build an instance with default threshold.
      * @deprecated See {@link AbstractConvergenceChecker#AbstractConvergenceChecker()}
      */
     @Deprecated
-    public SimplePointChecker() {}
+    public SimplePointChecker() {
+        maxIterationCount = ITERATION_CHECK_DISABLED;
+    }
 
     /**
      * Build an instance with specified thresholds.
@@ -56,12 +76,38 @@ public class SimplePointChecker<PAIR ext
     public SimplePointChecker(final double relativeThreshold,
                               final double absoluteThreshold) {
         super(relativeThreshold, absoluteThreshold);
+        maxIterationCount = ITERATION_CHECK_DISABLED;
+    }
+
+    /**
+     * Builds an instance with specified thresholds.
+     * In order to perform only relative checks, the absolute tolerance
+     * must be set to a negative value. In order to perform only absolute
+     * checks, the relative tolerance must be set to a negative value.
+     *
+     * @param relativeThreshold Relative tolerance threshold.
+     * @param absoluteThreshold Absolute tolerance threshold.
+     * @param maxIter Maximum iteration count. Setting it to a negative
+     * value will disable this stopping criterion.
+     * @throws NotStrictlyPositiveException if {@code maxIter <= 0}.
+     *
+     * @since 3.1
+     */
+    public SimplePointChecker(final double relativeThreshold,
+                              final double absoluteThreshold,
+                              final int maxIter) {
+        super(relativeThreshold, absoluteThreshold);
+
+        if (maxIter <= 0) {
+            throw new NotStrictlyPositiveException(maxIter);
+        }
+        maxIterationCount = maxIter;
     }
 
     /**
      * Check if the optimization algorithm has converged considering the
      * last two points.
-     * This method may be called several time from the same algorithm
+     * This method may be called several times from the same algorithm
      * iteration with different points. This can be detected by checking the
      * iteration number at each call if needed. Each time this method is
      * called, the previous and current point correspond to points with the
@@ -72,12 +118,18 @@ public class SimplePointChecker<PAIR ext
      * @param iteration Index of current iteration
      * @param previous Best point in the previous iteration.
      * @param current Best point in the current iteration.
-     * @return {@code true} if the algorithm has converged.
+     * @return {@code true} if the arguments satify the convergence criterion.
      */
     @Override
     public boolean converged(final int iteration,
                              final PAIR previous,
                              final PAIR current) {
+        if (maxIterationCount != ITERATION_CHECK_DISABLED) {
+            if (iteration >= maxIterationCount) {
+                return true;
+            }
+        }
+
         final double[] p = previous.getKey();
         final double[] c = current.getKey();
         for (int i = 0; i < p.length; ++i) {

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleValueChecker.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleValueChecker.java?rev=1411807&r1=1411806&r2=1411807&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleValueChecker.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleValueChecker.java
Tue Nov 20 19:29:16 2012
@@ -18,6 +18,7 @@
 package org.apache.commons.math3.optimization;
 
 import org.apache.commons.math3.util.FastMath;
+import org.apache.commons.math3.exception.NotStrictlyPositiveException;
 
 /**
  * Simple implementation of the {@link ConvergenceChecker} interface using
@@ -27,6 +28,10 @@ import org.apache.commons.math3.util.Fas
  * difference between the objective function values is smaller than a
  * threshold or if either the absolute difference between the objective
  * function values is smaller than another threshold.
+ * <br/>
+ * The {@link #converged(int,PointValuePair,PointValuePair) converged}
+ * method will also return {@code true} if the number of iterations has been set
+ * (see {@link #SimpleValueChecker(double,double,int) this constructor}).
  *
  * @version $Id$
  * @since 3.0
@@ -34,11 +39,27 @@ import org.apache.commons.math3.util.Fas
 public class SimpleValueChecker
     extends AbstractConvergenceChecker<PointValuePair> {
     /**
+     * If {@link #maxIterationCount} is set to this value, the number of
+     * iterations will never cause
+     * {@link #converged(int,PointValuePair,PointValuePair)}
+     * to return {@code true}.
+     */
+    private static final int ITERATION_CHECK_DISABLED = -1;
+    /**
+     * Number of iterations after which the
+     * {@link #converged(int,PointValuePair,PointValuePair)} method
+     * will return true (unless the check is disabled).
+     */
+    private final int maxIterationCount;
+
+    /**
      * Build an instance with default thresholds.
      * @deprecated See {@link AbstractConvergenceChecker#AbstractConvergenceChecker()}
      */
     @Deprecated
-    public SimpleValueChecker() {}
+    public SimpleValueChecker() {
+        maxIterationCount = ITERATION_CHECK_DISABLED;
+    }
 
     /** Build an instance with specified thresholds.
      *
@@ -52,6 +73,33 @@ public class SimpleValueChecker
     public SimpleValueChecker(final double relativeThreshold,
                               final double absoluteThreshold) {
         super(relativeThreshold, absoluteThreshold);
+        maxIterationCount = ITERATION_CHECK_DISABLED;
+    }
+
+    /**
+     * Builds an instance with specified thresholds.
+     *
+     * In order to perform only relative checks, the absolute tolerance
+     * must be set to a negative value. In order to perform only absolute
+     * checks, the relative tolerance must be set to a negative value.
+     *
+     * @param relativeThreshold relative tolerance threshold
+     * @param absoluteThreshold absolute tolerance threshold
+     * @param maxIter Maximum iteration count. Setting it to a negative
+     * value will disable this stopping criterion.
+     * @throws NotStrictlyPositiveException if {@code maxIter <= 0}.
+     *
+     * @since 3.1
+     */
+    public SimpleValueChecker(final double relativeThreshold,
+                              final double absoluteThreshold,
+                              final int maxIter) {
+        super(relativeThreshold, absoluteThreshold);
+
+        if (maxIter <= 0) {
+            throw new NotStrictlyPositiveException(maxIter);
+        }
+        maxIterationCount = maxIter;
     }
 
     /**
@@ -74,6 +122,12 @@ public class SimpleValueChecker
     public boolean converged(final int iteration,
                              final PointValuePair previous,
                              final PointValuePair current) {
+        if (maxIterationCount != ITERATION_CHECK_DISABLED) {
+            if (iteration >= maxIterationCount) {
+                return true;
+            }
+        }
+
         final double p = previous.getValue();
         final double c = current.getValue();
         final double difference = FastMath.abs(p - c);

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleVectorValueChecker.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleVectorValueChecker.java?rev=1411807&r1=1411806&r2=1411807&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleVectorValueChecker.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleVectorValueChecker.java
Tue Nov 20 19:29:16 2012
@@ -18,6 +18,7 @@
 package org.apache.commons.math3.optimization;
 
 import org.apache.commons.math3.util.FastMath;
+import org.apache.commons.math3.exception.NotStrictlyPositiveException;
 
 /**
  * Simple implementation of the {@link ConvergenceChecker} interface using
@@ -27,6 +28,10 @@ import org.apache.commons.math3.util.Fas
  * difference between the objective function values is smaller than a
  * threshold or if either the absolute difference between the objective
  * function values is smaller than another threshold for all vectors elements.
+ * <br/>
+ * The {@link #converged(int,PointVectorValuePair,PointVectorValuePair) converged}
+ * method will also return {@code true} if the number of iterations has been set
+ * (see {@link #SimpleVectorValueChecker(double,double,int) this constructor}).
  *
  * @version $Id$
  * @since 3.0
@@ -34,11 +39,27 @@ import org.apache.commons.math3.util.Fas
 public class SimpleVectorValueChecker
     extends AbstractConvergenceChecker<PointVectorValuePair> {
     /**
+     * If {@link #maxIterationCount} is set to this value, the number of
+     * iterations will never cause
+     * {@link #converged(int,PointVectorValuePair,PointVectorValuePair)}
+     * to return {@code true}.
+     */
+    private static final int ITERATION_CHECK_DISABLED = -1;
+    /**
+     * Number of iterations after which the
+     * {@link #converged(int,PointVectorValuePair,PointVectorValuePair)} method
+     * will return true (unless the check is disabled).
+     */
+    private final int maxIterationCount;
+
+    /**
      * Build an instance with default thresholds.
      * @deprecated See {@link AbstractConvergenceChecker#AbstractConvergenceChecker()}
      */
     @Deprecated
-    public SimpleVectorValueChecker() {}
+    public SimpleVectorValueChecker() {
+        maxIterationCount = ITERATION_CHECK_DISABLED;
+    }
 
     /**
      * Build an instance with specified thresholds.
@@ -51,14 +72,42 @@ public class SimpleVectorValueChecker
      * @param absoluteThreshold absolute tolerance threshold
      */
     public SimpleVectorValueChecker(final double relativeThreshold,
-                                       final double absoluteThreshold) {
+                                    final double absoluteThreshold) {
         super(relativeThreshold, absoluteThreshold);
+        maxIterationCount = ITERATION_CHECK_DISABLED;
+    }
+
+    /**
+     * Builds an instance with specified tolerance thresholds and
+     * iteration count.
+     *
+     * In order to perform only relative checks, the absolute tolerance
+     * must be set to a negative value. In order to perform only absolute
+     * checks, the relative tolerance must be set to a negative value.
+     *
+     * @param relativeThreshold Relative tolerance threshold.
+     * @param absoluteThreshold Absolute tolerance threshold.
+     * @param maxIter Maximum iteration count. Setting it to a negative
+     * value will disable this stopping criterion.
+     * @throws NotStrictlyPositiveException if {@code maxIter <= 0}.
+     *
+     * @since 3.1
+     */
+    public SimpleVectorValueChecker(final double relativeThreshold,
+                                    final double absoluteThreshold,
+                                    final int maxIter) {
+        super(relativeThreshold, absoluteThreshold);
+
+        if (maxIter <= 0) {
+            throw new NotStrictlyPositiveException(maxIter);
+        }
+        maxIterationCount = maxIter;
     }
 
     /**
      * Check if the optimization algorithm has converged considering the
      * last two points.
-     * This method may be called several time from the same algorithm
+     * This method may be called several times from the same algorithm
      * iteration with different points. This can be detected by checking the
      * iteration number at each call if needed. Each time this method is
      * called, the previous and current point correspond to points with the
@@ -69,12 +118,18 @@ public class SimpleVectorValueChecker
      * @param iteration Index of current iteration
      * @param previous Best point in the previous iteration.
      * @param current Best point in the current iteration.
-     * @return {@code true} if the algorithm has converged.
+     * @return {@code true} if the arguments satify the convergence criterion.
      */
     @Override
     public boolean converged(final int iteration,
                              final PointVectorValuePair previous,
                              final PointVectorValuePair current) {
+        if (maxIterationCount != ITERATION_CHECK_DISABLED) {
+            if (iteration >= maxIterationCount) {
+                return true;
+            }
+        }
+
         final double[] p = previous.getValueRef();
         final double[] c = current.getValueRef();
         for (int i = 0; i < p.length; ++i) {

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/fitting/PolynomialFitterTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/fitting/PolynomialFitterTest.java?rev=1411807&r1=1411806&r2=1411807&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/fitting/PolynomialFitterTest.java
(original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/fitting/PolynomialFitterTest.java
Tue Nov 20 19:29:16 2012
@@ -147,6 +147,28 @@ public class PolynomialFitterTest {
     }
 
     /**
+     * This test shows that the user can set the maximum number of iterations
+     * to avoid running for too long.
+     * Even if the real problem is that the tolerance is way too stringent, it
+     * is possible to get the best solution so far, i.e. a checker will return
+     * the point when the maximum iteration count has been reached.
+     */
+    @Test
+    public void testMath798WithToleranceTooLowButNoException() {
+        final double tol = 1e-100;
+        final double[] init = new double[] { 0, 0 };
+        final int maxEval = 10000; // Trying hard to fit.
+        final SimpleVectorValueChecker checker = new SimpleVectorValueChecker(tol, tol, maxEval);
+
+        final double[] lm = doMath798(new LevenbergMarquardtOptimizer(checker), maxEval,
init);
+        final double[] gn = doMath798(new GaussNewtonOptimizer(checker), maxEval, init);
+
+        for (int i = 0; i <= 1; i++) {
+            Assert.assertEquals(lm[i], gn[i], 1e-15);
+        }
+    }
+
+    /**
      * @param optimizer Optimizer.
      * @param maxEval Maximum number of function evaluations.
      * @param init First guess.



Mime
View raw message