All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.math3.analysis.integration.BaseAbstractUnivariateIntegrator Maven / Gradle / Ivy

There is a newer version: 2.12.15
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.math3.analysis.integration;

import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.solvers.UnivariateSolverUtils;
import org.apache.commons.math3.exception.MathIllegalArgumentException;
import org.apache.commons.math3.exception.MaxCountExceededException;
import org.apache.commons.math3.exception.NotStrictlyPositiveException;
import org.apache.commons.math3.exception.NullArgumentException;
import org.apache.commons.math3.exception.NumberIsTooSmallException;
import org.apache.commons.math3.exception.TooManyEvaluationsException;
import org.apache.commons.math3.util.IntegerSequence;
import org.apache.commons.math3.util.MathUtils;

/**
 * Provide a default implementation for several generic functions.
 *
 * @since 1.2
 */
public abstract class BaseAbstractUnivariateIntegrator implements UnivariateIntegrator {

    /** Default absolute accuracy. */
    public static final double DEFAULT_ABSOLUTE_ACCURACY = 1.0e-15;

    /** Default relative accuracy. */
    public static final double DEFAULT_RELATIVE_ACCURACY = 1.0e-6;

    /** Default minimal iteration count. */
    public static final int DEFAULT_MIN_ITERATIONS_COUNT = 3;

    /** Default maximal iteration count. */
    public static final int DEFAULT_MAX_ITERATIONS_COUNT = Integer.MAX_VALUE;

    /** The iteration count.
     * @deprecated as of 3.6, this field has been replaced with {@link #incrementCount()}
     */
    @Deprecated
    protected org.apache.commons.math3.util.Incrementor iterations;

    /** The iteration count. */
    private IntegerSequence.Incrementor count;

    /** Maximum absolute error. */
    private final double absoluteAccuracy;

    /** Maximum relative error. */
    private final double relativeAccuracy;

    /** minimum number of iterations */
    private final int minimalIterationCount;

    /** The functions evaluation count. */
    private IntegerSequence.Incrementor evaluations;

    /** Function to integrate. */
    private UnivariateFunction function;

    /** Lower bound for the interval. */
    private double min;

    /** Upper bound for the interval. */
    private double max;

    /**
     * Construct an integrator with given accuracies and iteration counts.
     * 

* The meanings of the various parameters are: *

    *
  • relative accuracy: * this is used to stop iterations if the absolute accuracy can't be * achieved due to large values or short mantissa length. If this * should be the primary criterion for convergence rather then a * safety measure, set the absolute accuracy to a ridiculously small value, * like {@link org.apache.commons.math3.util.Precision#SAFE_MIN Precision.SAFE_MIN}.
  • *
  • absolute accuracy: * The default is usually chosen so that results in the interval * -10..-0.1 and +0.1..+10 can be found with a reasonable accuracy. If the * expected absolute value of your results is of much smaller magnitude, set * this to a smaller value.
  • *
  • minimum number of iterations: * minimal iteration is needed to avoid false early convergence, e.g. * the sample points happen to be zeroes of the function. Users can * use the default value or choose one that they see as appropriate.
  • *
  • maximum number of iterations: * usually a high iteration count indicates convergence problems. However, * the "reasonable value" varies widely for different algorithms. Users are * advised to use the default value supplied by the algorithm.
  • *
* * @param relativeAccuracy relative accuracy of the result * @param absoluteAccuracy absolute accuracy of the result * @param minimalIterationCount minimum number of iterations * @param maximalIterationCount maximum number of iterations * @exception NotStrictlyPositiveException if minimal number of iterations * is not strictly positive * @exception NumberIsTooSmallException if maximal number of iterations * is lesser than or equal to the minimal number of iterations */ protected BaseAbstractUnivariateIntegrator(final double relativeAccuracy, final double absoluteAccuracy, final int minimalIterationCount, final int maximalIterationCount) throws NotStrictlyPositiveException, NumberIsTooSmallException { // accuracy settings this.relativeAccuracy = relativeAccuracy; this.absoluteAccuracy = absoluteAccuracy; // iterations count settings if (minimalIterationCount <= 0) { throw new NotStrictlyPositiveException(minimalIterationCount); } if (maximalIterationCount <= minimalIterationCount) { throw new NumberIsTooSmallException(maximalIterationCount, minimalIterationCount, false); } this.minimalIterationCount = minimalIterationCount; this.count = IntegerSequence.Incrementor.create().withMaximalCount(maximalIterationCount); @SuppressWarnings("deprecation") org.apache.commons.math3.util.Incrementor wrapped = org.apache.commons.math3.util.Incrementor.wrap(count); this.iterations = wrapped; // prepare evaluations counter, but do not set it yet evaluations = IntegerSequence.Incrementor.create(); } /** * Construct an integrator with given accuracies. * @param relativeAccuracy relative accuracy of the result * @param absoluteAccuracy absolute accuracy of the result */ protected BaseAbstractUnivariateIntegrator(final double relativeAccuracy, final double absoluteAccuracy) { this(relativeAccuracy, absoluteAccuracy, DEFAULT_MIN_ITERATIONS_COUNT, DEFAULT_MAX_ITERATIONS_COUNT); } /** * Construct an integrator with given iteration counts. * @param minimalIterationCount minimum number of iterations * @param maximalIterationCount maximum number of iterations * @exception NotStrictlyPositiveException if minimal number of iterations * is not strictly positive * @exception NumberIsTooSmallException if maximal number of iterations * is lesser than or equal to the minimal number of iterations */ protected BaseAbstractUnivariateIntegrator(final int minimalIterationCount, final int maximalIterationCount) throws NotStrictlyPositiveException, NumberIsTooSmallException { this(DEFAULT_RELATIVE_ACCURACY, DEFAULT_ABSOLUTE_ACCURACY, minimalIterationCount, maximalIterationCount); } /** {@inheritDoc} */ public double getRelativeAccuracy() { return relativeAccuracy; } /** {@inheritDoc} */ public double getAbsoluteAccuracy() { return absoluteAccuracy; } /** {@inheritDoc} */ public int getMinimalIterationCount() { return minimalIterationCount; } /** {@inheritDoc} */ public int getMaximalIterationCount() { return count.getMaximalCount(); } /** {@inheritDoc} */ public int getEvaluations() { return evaluations.getCount(); } /** {@inheritDoc} */ public int getIterations() { return count.getCount(); } /** Increment the number of iterations. * @exception MaxCountExceededException if the number of iterations * exceeds the allowed maximum number */ protected void incrementCount() throws MaxCountExceededException { count.increment(); } /** * @return the lower bound. */ protected double getMin() { return min; } /** * @return the upper bound. */ protected double getMax() { return max; } /** * Compute the objective function value. * * @param point Point at which the objective function must be evaluated. * @return the objective function value at specified point. * @throws TooManyEvaluationsException if the maximal number of function * evaluations is exceeded. */ protected double computeObjectiveValue(final double point) throws TooManyEvaluationsException { try { evaluations.increment(); } catch (MaxCountExceededException e) { throw new TooManyEvaluationsException(e.getMax()); } return function.value(point); } /** * Prepare for computation. * Subclasses must call this method if they override any of the * {@code solve} methods. * * @param maxEval Maximum number of evaluations. * @param f the integrand function * @param lower the min bound for the interval * @param upper the upper bound for the interval * @throws NullArgumentException if {@code f} is {@code null}. * @throws MathIllegalArgumentException if {@code min >= max}. */ protected void setup(final int maxEval, final UnivariateFunction f, final double lower, final double upper) throws NullArgumentException, MathIllegalArgumentException { // Checks. MathUtils.checkNotNull(f); UnivariateSolverUtils.verifyInterval(lower, upper); // Reset. min = lower; max = upper; function = f; evaluations = evaluations.withMaximalCount(maxEval).withStart(0); count = count.withStart(0); } /** {@inheritDoc} */ public double integrate(final int maxEval, final UnivariateFunction f, final double lower, final double upper) throws TooManyEvaluationsException, MaxCountExceededException, MathIllegalArgumentException, NullArgumentException { // Initialization. setup(maxEval, f, lower, upper); // Perform computation. return doIntegrate(); } /** * Method for implementing actual integration algorithms in derived * classes. * * @return the root. * @throws TooManyEvaluationsException if the maximal number of evaluations * is exceeded. * @throws MaxCountExceededException if the maximum iteration count is exceeded * or the integrator detects convergence problems otherwise */ protected abstract double doIntegrate() throws TooManyEvaluationsException, MaxCountExceededException; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy