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 VectorialConvergenceChecker} 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 for all vectors elements.
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 SimpleVectorialValueChecker implements VectorialConvergenceChecker {
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 SimpleVectorialValueChecker() {
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 SimpleVectorialValueChecker(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 VectorialPointValuePair previous,
074 final VectorialPointValuePair current) {
075 final double[] p = previous.getValueRef();
076 final double[] c = current.getValueRef();
077 for (int i = 0; i < p.length; ++i) {
078 final double pi = p[i];
079 final double ci = c[i];
080 final double difference = FastMath.abs(pi - ci);
081 final double size = FastMath.max(FastMath.abs(pi), FastMath.abs(ci));
082 if ((difference > (size * relativeThreshold)) &&
083 (difference > absoluteThreshold)) {
084 return false;
085 }
086 }
087 return true;
088 }
089
090 }