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.math.optimization; 019 020 import org.apache.commons.math.util.MathUtils; 021 022 /** 023 * Simple implementation of the {@link VectorialConvergenceChecker} interface using 024 * only point coordinates. 025 * <p> 026 * Convergence is considered to have been reached if either the relative 027 * difference between each point coordinate are smaller than a threshold 028 * or if either the absolute difference between the point coordinates are 029 * smaller than another threshold. 030 * </p> 031 * @version $Revision: 795972 $ $Date: 2009-07-20 15:34:06 -0400 (Mon, 20 Jul 2009) $ 032 * @since 2.0 033 */ 034 public class SimpleVectorialPointChecker implements VectorialConvergenceChecker { 035 036 /** Default relative threshold. */ 037 private static final double DEFAULT_RELATIVE_THRESHOLD = 100 * MathUtils.EPSILON; 038 039 /** Default absolute threshold. */ 040 private static final double DEFAULT_ABSOLUTE_THRESHOLD = 100 * MathUtils.SAFE_MIN; 041 042 /** Relative tolerance threshold. */ 043 private final double relativeThreshold; 044 045 /** Absolute tolerance threshold. */ 046 private final double absoluteThreshold; 047 048 /** Build an instance with default threshold. 049 */ 050 public SimpleVectorialPointChecker() { 051 this.relativeThreshold = DEFAULT_RELATIVE_THRESHOLD; 052 this.absoluteThreshold = DEFAULT_ABSOLUTE_THRESHOLD; 053 } 054 055 /** Build an instance with a specified threshold. 056 * <p> 057 * In order to perform only relative checks, the absolute tolerance 058 * must be set to a negative value. In order to perform only absolute 059 * checks, the relative tolerance must be set to a negative value. 060 * </p> 061 * @param relativeThreshold relative tolerance threshold 062 * @param absoluteThreshold absolute tolerance threshold 063 */ 064 public SimpleVectorialPointChecker(final double relativeThreshold, 065 final double absoluteThreshold) { 066 this.relativeThreshold = relativeThreshold; 067 this.absoluteThreshold = absoluteThreshold; 068 } 069 070 /** {@inheritDoc} */ 071 public boolean converged(final int iteration, 072 final VectorialPointValuePair previous, 073 final VectorialPointValuePair current) { 074 final double[] p = previous.getPointRef(); 075 final double[] c = current.getPointRef(); 076 for (int i = 0; i < p.length; ++i) { 077 final double pi = p[i]; 078 final double ci = c[i]; 079 final double difference = Math.abs(pi - ci); 080 final double size = Math.max(Math.abs(pi), Math.abs(ci)); 081 if ((difference > (size * relativeThreshold)) && 082 (difference > absoluteThreshold)) { 083 return false; 084 } 085 } 086 return true; 087 } 088 089 }