    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017
    018    package org.apache.commons.math3.optimization.univariate;
    019
    020    import org.apache.commons.math3.util.FastMath;
    021    import org.apache.commons.math3.exception.NotStrictlyPositiveException;
    022    import org.apache.commons.math3.optimization.AbstractConvergenceChecker;
    023
    024    /**
    025     * Simple implementation of the
    026     * {@link org.apache.commons.math3.optimization.ConvergenceChecker} interface
    027     * that uses only objective function values.
    028     *
    029     * Convergence is considered to have been reached if either the relative
    030     * difference between the objective function values is smaller than a
    031     * threshold or if either the absolute difference between the objective
    032     * function values is smaller than another threshold.
    033     * <br/>
    034     * The {@link #converged(int,UnivariatePointValuePair,UnivariatePointValuePair)
    035     * converged} method will also return {@code true} if the number of iterations
    036     * has been set (see {@link #SimpleUnivariateValueChecker(double,double,int)
    037     * this constructor}).
    038     *
    039     * @version $Id: SimpleUnivariateValueChecker.java 1422230 2012-12-15 12:11:13Z erans $
    040     * @deprecated As of 3.1 (to be removed in 4.0).
    041     * @since 3.1
    042     */
    043    @Deprecated
    044    public class SimpleUnivariateValueChecker
    045        extends AbstractConvergenceChecker<UnivariatePointValuePair> {
    046        /**
    047         * If {@link #maxIterationCount} is set to this value, the number of
    048         * iterations will never cause
    049         * {@link #converged(int,UnivariatePointValuePair,UnivariatePointValuePair)}
    050         * to return {@code true}.
    051         */
    052        private static final int ITERATION_CHECK_DISABLED = -1;
    053        /**
    054         * Number of iterations after which the
    055         * {@link #converged(int,UnivariatePointValuePair,UnivariatePointValuePair)}
    056         * method will return true (unless the check is disabled).
    057         */
    058        private final int maxIterationCount;
    059
    060        /**
    061         * Build an instance with default thresholds.
    062         * @deprecated See {@link AbstractConvergenceChecker#AbstractConvergenceChecker()}
    063         */
    064        @Deprecated
    065        public SimpleUnivariateValueChecker() {
    066            maxIterationCount = ITERATION_CHECK_DISABLED;
    067        }
    068
    069        /** Build an instance with specified thresholds.
    070         *
    071         * In order to perform only relative checks, the absolute tolerance
    072         * must be set to a negative value. In order to perform only absolute
    073         * checks, the relative tolerance must be set to a negative value.
    074         *
    075         * @param relativeThreshold relative tolerance threshold
    076         * @param absoluteThreshold absolute tolerance threshold
    077         */
    078        public SimpleUnivariateValueChecker(final double relativeThreshold,
    079                                            final double absoluteThreshold) {
    080            super(relativeThreshold, absoluteThreshold);
    081            maxIterationCount = ITERATION_CHECK_DISABLED;
    082        }
    083
    084        /**
    085         * Builds an instance with specified thresholds.
    086         *
    087         * In order to perform only relative checks, the absolute tolerance
    088         * must be set to a negative value. In order to perform only absolute
    089         * checks, the relative tolerance must be set to a negative value.
    090         *
    091         * @param relativeThreshold relative tolerance threshold
    092         * @param absoluteThreshold absolute tolerance threshold
    093         * @param maxIter Maximum iteration count.
    094         * @throws NotStrictlyPositiveException if {@code maxIter <= 0}.
    095         *
    096         * @since 3.1
    097         */
    098        public SimpleUnivariateValueChecker(final double relativeThreshold,
    099                                            final double absoluteThreshold,
    100                                            final int maxIter) {
    101            super(relativeThreshold, absoluteThreshold);
    102
    103            if (maxIter <= 0) {
    104                throw new NotStrictlyPositiveException(maxIter);
    105            }
    106            maxIterationCount = maxIter;
    107        }
    108
    109        /**
    110         * Check if the optimization algorithm has converged considering the
    111         * last two points.
    112         * This method may be called several time from the same algorithm
    113         * iteration with different points. This can be detected by checking the
    114         * iteration number at each call if needed. Each time this method is
    115         * called, the previous and current point correspond to points with the
    116         * same role at each iteration, so they can be compared. As an example,
    117         * simplex-based algorithms call this method for all points of the simplex,
    118         * not only for the best or worst ones.
    119         *
    120         * @param iteration Index of current iteration
    121         * @param previous Best point in the previous iteration.
    122         * @param current Best point in the current iteration.
    123         * @return {@code true} if the algorithm has converged.
    124         */
    125        @Override
    126        public boolean converged(final int iteration,
    127                                 final UnivariatePointValuePair previous,
    128                                 final UnivariatePointValuePair current) {
    129            if (maxIterationCount != ITERATION_CHECK_DISABLED) {
    130                if (iteration >= maxIterationCount) {
    131                    return true;
    132                }
    133            }
    134
    135            final double p = previous.getValue();
    136            final double c = current.getValue();
    137            final double difference = FastMath.abs(p - c);
    138            final double size = FastMath.max(FastMath.abs(p), FastMath.abs(c));
    139            return difference <= size * getRelativeThreshold() ||
    140                difference <= getAbsoluteThreshold();
    141        }
    142    }