Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id EE1E8E2F0 for ; Tue, 20 Nov 2012 19:29:43 +0000 (UTC) Received: (qmail 36771 invoked by uid 500); 20 Nov 2012 19:29:43 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 36691 invoked by uid 500); 20 Nov 2012 19:29:43 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 36684 invoked by uid 99); 20 Nov 2012 19:29:43 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 20 Nov 2012 19:29:43 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 20 Nov 2012 19:29:39 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 602222388900 for ; Tue, 20 Nov 2012 19:29:18 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: commits@commons.apache.org From: erans@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20121120192918.602222388900@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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. + *
+ * 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 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> extends AbstractConvergenceChecker { /** + * 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= 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. + *
+ * 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 { /** + * 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. + *
+ * 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 { /** + * 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.