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 RealConvergenceChecker} 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: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ 032 * @since 2.0 033 */ 034 public class SimpleRealPointChecker implements RealConvergenceChecker { 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 SimpleRealPointChecker() { 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 SimpleRealPointChecker(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 RealPointValuePair previous, 073 final RealPointValuePair current) { 074 final double[] p = previous.getPoint(); 075 final double[] c = current.getPoint(); 076 for (int i = 0; i < p.length; ++i) { 077 final double difference = Math.abs(p[i] - c[i]); 078 final double size = Math.max(Math.abs(p[i]), Math.abs(c[i])); 079 if ((difference > (size * relativeThreshold)) && (difference > absoluteThreshold)) { 080 return false; 081 } 082 } 083 return true; 084 } 085 086 }