commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Phil Steitz <p...@steitz.com>
Subject Re: 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 Thu, 22 Nov 2012 16:21:51 GMT
On 11/20/12 11:29 AM, erans@apache.org wrote:
> 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;

Could be I am misunderstanding the setup here, but I think this
value may cause a problem with the positivity check below (i.e.
using it will raise NotStrictlyPostiveException).  The test at the
end does not test using this value.  IIUC the code, a test that did
would throw.  Might be better to use Integer.MAX_VALUE or a boolean
flag.  Also, javadoc says negative values for maxIter disable.  The
code actually throws.

Phil
> +    /**
> +     * 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.
>
>
>


-- 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Mime
View raw message