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 objective function values. 025 * <p> 026 * Convergence is considered to have been reached if either the relative 027 * difference between the objective function values is smaller than a 028 * threshold or if either the absolute difference between the objective 029 * function values is smaller than another threshold. 030 * </p> 031 * @version $Revision: 799857 $ $Date: 2009-08-01 09:07:12 -0400 (Sat, 01 Aug 2009) $ 032 * @since 2.0 033 */ 034 public class SimpleScalarValueChecker 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 SimpleScalarValueChecker() { 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 SimpleScalarValueChecker(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.getValue(); 075 final double c = current.getValue(); 076 final double difference = Math.abs(p - c); 077 final double size = Math.max(Math.abs(p), Math.abs(c)); 078 return (difference <= (size * relativeThreshold)) || (difference <= absoluteThreshold); 079 } 080 081 }