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    }