Home | History | Annotate | Download | only in optimization
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package org.apache.commons.math.optimization;
     19 
     20 import org.apache.commons.math.util.FastMath;
     21 import org.apache.commons.math.util.MathUtils;
     22 
     23 /**
     24  * Simple implementation of the {@link RealConvergenceChecker} interface using
     25  * only point coordinates.
     26  * <p>
     27  * Convergence is considered to have been reached if either the relative
     28  * difference between each point coordinate are smaller than a threshold
     29  * or if either the absolute difference between the point coordinates are
     30  * smaller than another threshold.
     31  * </p>
     32  * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 aot 2010) $
     33  * @since 2.0
     34  */
     35 public class SimpleRealPointChecker implements RealConvergenceChecker {
     36 
     37     /** Default relative threshold. */
     38     private static final double DEFAULT_RELATIVE_THRESHOLD = 100 * MathUtils.EPSILON;
     39 
     40     /** Default absolute threshold. */
     41     private static final double DEFAULT_ABSOLUTE_THRESHOLD = 100 * MathUtils.SAFE_MIN;
     42 
     43     /** Relative tolerance threshold. */
     44     private final double relativeThreshold;
     45 
     46     /** Absolute tolerance threshold. */
     47     private final double absoluteThreshold;
     48 
     49    /** Build an instance with default threshold.
     50      */
     51     public SimpleRealPointChecker() {
     52         this.relativeThreshold = DEFAULT_RELATIVE_THRESHOLD;
     53         this.absoluteThreshold = DEFAULT_ABSOLUTE_THRESHOLD;
     54     }
     55 
     56     /** Build an instance with a specified threshold.
     57      * <p>
     58      * In order to perform only relative checks, the absolute tolerance
     59      * must be set to a negative value. In order to perform only absolute
     60      * checks, the relative tolerance must be set to a negative value.
     61      * </p>
     62      * @param relativeThreshold relative tolerance threshold
     63      * @param absoluteThreshold absolute tolerance threshold
     64      */
     65     public SimpleRealPointChecker(final double relativeThreshold,
     66                                  final double absoluteThreshold) {
     67         this.relativeThreshold = relativeThreshold;
     68         this.absoluteThreshold = absoluteThreshold;
     69     }
     70 
     71     /** {@inheritDoc} */
     72     public boolean converged(final int iteration,
     73                              final RealPointValuePair previous,
     74                              final RealPointValuePair current) {
     75         final double[] p        = previous.getPoint();
     76         final double[] c        = current.getPoint();
     77         for (int i = 0; i < p.length; ++i) {
     78             final double difference = FastMath.abs(p[i] - c[i]);
     79             final double size       = FastMath.max(FastMath.abs(p[i]), FastMath.abs(c[i]));
     80             if ((difference > (size * relativeThreshold)) && (difference > absoluteThreshold)) {
     81                 return false;
     82             }
     83         }
     84         return true;
     85     }
     86 
     87 }
     88