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 VectorialConvergenceChecker} interface using
     25  * only objective function values.
     26  * <p>
     27  * Convergence is considered to have been reached if either the relative
     28  * difference between the objective function values is smaller than a
     29  * threshold or if either the absolute difference between the objective
     30  * function values is smaller than another threshold for all vectors elements.
     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 SimpleVectorialValueChecker implements VectorialConvergenceChecker {
     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 SimpleVectorialValueChecker() {
     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 SimpleVectorialValueChecker(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 VectorialPointValuePair previous,
     74                              final VectorialPointValuePair current) {
     75         final double[] p        = previous.getValueRef();
     76         final double[] c        = current.getValueRef();
     77         for (int i = 0; i < p.length; ++i) {
     78             final double pi         = p[i];
     79             final double ci         = c[i];
     80             final double difference = FastMath.abs(pi - ci);
     81             final double size       = FastMath.max(FastMath.abs(pi), FastMath.abs(ci));
     82             if ((difference > (size * relativeThreshold)) &&
     83                 (difference > absoluteThreshold)) {
     84                 return false;
     85             }
     86         }
     87         return true;
     88     }
     89 
     90 }
     91