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 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 SimpleVectorialPointChecker 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 SimpleVectorialPointChecker() { 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 SimpleVectorialPointChecker(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.getPointRef(); 76 final double[] c = current.getPointRef(); 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