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.FastMath;
021 import org.apache.commons.math.util.MathUtils;
022
023 /**
024 * Simple implementation of the {@link RealConvergenceChecker} interface using
025 * only objective function values.
026 * <p>
027 * Convergence is considered to have been reached if either the relative
028 * difference between the objective function values is smaller than a
029 * threshold or if either the absolute difference between the objective
030 * function values is smaller than another threshold.
031 * </p>
032 * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 ao??t 2010) $
033 * @since 2.0
034 */
035 public class SimpleScalarValueChecker implements RealConvergenceChecker {
036
037 /** Default relative threshold. */
038 private static final double DEFAULT_RELATIVE_THRESHOLD = 100 * MathUtils.EPSILON;
039
040 /** Default absolute threshold. */
041 private static final double DEFAULT_ABSOLUTE_THRESHOLD = 100 * MathUtils.SAFE_MIN;
042
043 /** Relative tolerance threshold. */
044 private final double relativeThreshold;
045
046 /** Absolute tolerance threshold. */
047 private final double absoluteThreshold;
048
049 /** Build an instance with default threshold.
050 */
051 public SimpleScalarValueChecker() {
052 this.relativeThreshold = DEFAULT_RELATIVE_THRESHOLD;
053 this.absoluteThreshold = DEFAULT_ABSOLUTE_THRESHOLD;
054 }
055
056 /** Build an instance with a specified threshold.
057 * <p>
058 * In order to perform only relative checks, the absolute tolerance
059 * must be set to a negative value. In order to perform only absolute
060 * checks, the relative tolerance must be set to a negative value.
061 * </p>
062 * @param relativeThreshold relative tolerance threshold
063 * @param absoluteThreshold absolute tolerance threshold
064 */
065 public SimpleScalarValueChecker(final double relativeThreshold,
066 final double absoluteThreshold) {
067 this.relativeThreshold = relativeThreshold;
068 this.absoluteThreshold = absoluteThreshold;
069 }
070
071 /** {@inheritDoc} */
072 public boolean converged(final int iteration,
073 final RealPointValuePair previous,
074 final RealPointValuePair current) {
075 final double p = previous.getValue();
076 final double c = current.getValue();
077 final double difference = FastMath.abs(p - c);
078 final double size = FastMath.max(FastMath.abs(p), FastMath.abs(c));
079 return (difference <= (size * relativeThreshold)) || (difference <= absoluteThreshold);
080 }
081 }