BaseAbstractFieldUnivariateIntegrator.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus.analysis.integration;

  22. import org.hipparchus.CalculusFieldElement;
  23. import org.hipparchus.Field;
  24. import org.hipparchus.analysis.CalculusFieldUnivariateFunction;
  25. import org.hipparchus.analysis.solvers.UnivariateSolverUtils;
  26. import org.hipparchus.exception.LocalizedCoreFormats;
  27. import org.hipparchus.exception.MathIllegalArgumentException;
  28. import org.hipparchus.exception.MathIllegalStateException;
  29. import org.hipparchus.exception.NullArgumentException;
  30. import org.hipparchus.util.Incrementor;
  31. import org.hipparchus.util.MathUtils;

  32. /**
  33.  * Provide a default implementation for several generic functions.
  34.  *
  35.  * @param <T> Type of the field elements.
  36.  * @since 2.0
  37.  */
  38. public abstract class BaseAbstractFieldUnivariateIntegrator<T extends CalculusFieldElement<T>> implements FieldUnivariateIntegrator<T> {

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

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

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

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

  47.     /** The iteration count. */
  48.     protected final Incrementor iterations;

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

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

  53.     /** minimum number of iterations */
  54.     private final int minimalIterationCount;

  55.     /** The functions evaluation count. */
  56.     private Incrementor evaluations;

  57.     /** Field to which function argument and value belong. */
  58.     private final Field<T> field;

  59.     /** Function to integrate. */
  60.     private CalculusFieldUnivariateFunction<T> function;

  61.     /** Lower bound for the interval. */
  62.     private T min;

  63.     /** Upper bound for the interval. */
  64.     private T max;

  65.     /**
  66.      * Construct an integrator with given accuracies and iteration counts.
  67.      * <p>
  68.      * The meanings of the various parameters are:
  69.      * <ul>
  70.      *   <li>relative accuracy:
  71.      *       this is used to stop iterations if the absolute accuracy can't be
  72.      *       achieved due to large values or short mantissa length. If this
  73.      *       should be the primary criterion for convergence rather then a
  74.      *       safety measure, set the absolute accuracy to a ridiculously small value,
  75.      *       like {@link org.hipparchus.util.Precision#SAFE_MIN Precision.SAFE_MIN}.</li>
  76.      *   <li>absolute accuracy:
  77.      *       The default is usually chosen so that results in the interval
  78.      *       -10..-0.1 and +0.1..+10 can be found with a reasonable accuracy. If the
  79.      *       expected absolute value of your results is of much smaller magnitude, set
  80.      *       this to a smaller value.</li>
  81.      *   <li>minimum number of iterations:
  82.      *       minimal iteration is needed to avoid false early convergence, e.g.
  83.      *       the sample points happen to be zeroes of the function. Users can
  84.      *       use the default value or choose one that they see as appropriate.</li>
  85.      *   <li>maximum number of iterations:
  86.      *       usually a high iteration count indicates convergence problems. However,
  87.      *       the "reasonable value" varies widely for different algorithms. Users are
  88.      *       advised to use the default value supplied by the algorithm.</li>
  89.      * </ul>
  90.      *
  91.      * @param field field to which function argument and value belong
  92.      * @param relativeAccuracy relative accuracy of the result
  93.      * @param absoluteAccuracy absolute accuracy of the result
  94.      * @param minimalIterationCount minimum number of iterations
  95.      * @param maximalIterationCount maximum number of iterations
  96.      * @exception MathIllegalArgumentException if minimal number of iterations
  97.      * is not strictly positive
  98.      * @exception MathIllegalArgumentException if maximal number of iterations
  99.      * is lesser than or equal to the minimal number of iterations
  100.      */
  101.     protected BaseAbstractFieldUnivariateIntegrator(final Field<T> field,
  102.                                                     final double relativeAccuracy,
  103.                                                     final double absoluteAccuracy,
  104.                                                     final int minimalIterationCount,
  105.                                                     final int maximalIterationCount)
  106.         throws MathIllegalArgumentException {

  107.         // accuracy settings
  108.         this.relativeAccuracy      = relativeAccuracy;
  109.         this.absoluteAccuracy      = absoluteAccuracy;

  110.         // iterations count settings
  111.         if (minimalIterationCount <= 0) {
  112.             throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_TOO_SMALL_BOUND_EXCLUDED,
  113.                                                    minimalIterationCount, 0);
  114.         }
  115.         if (maximalIterationCount <= minimalIterationCount) {
  116.             throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_TOO_SMALL_BOUND_EXCLUDED,
  117.                                                    maximalIterationCount, minimalIterationCount);
  118.         }
  119.         this.minimalIterationCount = minimalIterationCount;
  120.         this.iterations            = new Incrementor(maximalIterationCount);

  121.         // prepare evaluations counter, but do not set it yet
  122.         evaluations = new Incrementor();

  123.         this.field = field;

  124.     }

  125.     /**
  126.      * Construct an integrator with given accuracies.
  127.      * @param field field to which function argument and value belong
  128.      * @param relativeAccuracy relative accuracy of the result
  129.      * @param absoluteAccuracy absolute accuracy of the result
  130.      */
  131.     protected BaseAbstractFieldUnivariateIntegrator(final Field<T> field,
  132.                                                     final double relativeAccuracy,
  133.                                                     final double absoluteAccuracy) {
  134.         this(field, relativeAccuracy, absoluteAccuracy,
  135.              DEFAULT_MIN_ITERATIONS_COUNT, DEFAULT_MAX_ITERATIONS_COUNT);
  136.     }

  137.     /**
  138.      * Construct an integrator with given iteration counts.
  139.      * @param field field to which function argument and value belong
  140.      * @param minimalIterationCount minimum number of iterations
  141.      * @param maximalIterationCount maximum number of iterations
  142.      * @exception MathIllegalArgumentException if minimal number of iterations
  143.      * is not strictly positive
  144.      * @exception MathIllegalArgumentException if maximal number of iterations
  145.      * is lesser than or equal to the minimal number of iterations
  146.      */
  147.     protected BaseAbstractFieldUnivariateIntegrator(final Field<T> field,
  148.                                                     final int minimalIterationCount,
  149.                                                     final int maximalIterationCount)
  150.         throws MathIllegalArgumentException {
  151.         this(field, DEFAULT_RELATIVE_ACCURACY, DEFAULT_ABSOLUTE_ACCURACY,
  152.              minimalIterationCount, maximalIterationCount);
  153.     }

  154.     /** Get the field to which function argument and value belong.
  155.      * @return field to which function argument and value belong
  156.      */
  157.     public Field<T> getField() {
  158.         return field;
  159.     }

  160.     /** {@inheritDoc} */
  161.     @Override
  162.     public double getRelativeAccuracy() {
  163.         return relativeAccuracy;
  164.     }

  165.     /** {@inheritDoc} */
  166.     @Override
  167.     public double getAbsoluteAccuracy() {
  168.         return absoluteAccuracy;
  169.     }

  170.     /** {@inheritDoc} */
  171.     @Override
  172.     public int getMinimalIterationCount() {
  173.         return minimalIterationCount;
  174.     }

  175.     /** {@inheritDoc} */
  176.     @Override
  177.     public int getMaximalIterationCount() {
  178.         return iterations.getMaximalCount();
  179.     }

  180.     /** {@inheritDoc} */
  181.     @Override
  182.     public int getEvaluations() {
  183.         return evaluations.getCount();
  184.     }

  185.     /** {@inheritDoc} */
  186.     @Override
  187.     public int getIterations() {
  188.         return iterations.getCount();
  189.     }

  190.     /** Get the lower bound.
  191.      * @return the lower bound.
  192.      */
  193.     protected T getMin() {
  194.         return min;
  195.     }

  196.     /** Get the upper bound.
  197.      * @return the upper bound.
  198.      */
  199.     protected T getMax() {
  200.         return max;
  201.     }

  202.     /**
  203.      * Compute the objective function value.
  204.      *
  205.      * @param point Point at which the objective function must be evaluated.
  206.      * @return the objective function value at specified point.
  207.      * @throws MathIllegalStateException if the maximal number of function
  208.      * evaluations is exceeded.
  209.      */
  210.     protected T computeObjectiveValue(final T point)
  211.         throws MathIllegalStateException {
  212.         evaluations.increment();
  213.         return function.value(point);
  214.     }

  215.     /**
  216.      * Prepare for computation.
  217.      * Subclasses must call this method if they override any of the
  218.      * {@code solve} methods.
  219.      *
  220.      * @param maxEval Maximum number of evaluations.
  221.      * @param f the integrand function
  222.      * @param lower the min bound for the interval
  223.      * @param upper the upper bound for the interval
  224.      * @throws NullArgumentException if {@code f} is {@code null}.
  225.      * @throws MathIllegalArgumentException if {@code min >= max}.
  226.      */
  227.     protected void setup(final int maxEval,
  228.                          final CalculusFieldUnivariateFunction<T> f,
  229.                          final T lower, final T upper)
  230.         throws MathIllegalArgumentException, NullArgumentException {

  231.         // Checks.
  232.         MathUtils.checkNotNull(f);
  233.         UnivariateSolverUtils.verifyInterval(lower.getReal(), upper.getReal());

  234.         // Reset.
  235.         min = lower;
  236.         max = upper;
  237.         function = f;
  238.         evaluations = evaluations.withMaximalCount(maxEval);
  239.         iterations.reset();
  240.     }

  241.     /** {@inheritDoc} */
  242.     @Override
  243.     public T integrate(final int maxEval, final CalculusFieldUnivariateFunction<T> f,
  244.                        final T lower, final T upper)
  245.         throws MathIllegalArgumentException, MathIllegalStateException, NullArgumentException {

  246.         // Initialization.
  247.         setup(maxEval, f, lower, upper);

  248.         // Perform computation.
  249.         return doIntegrate();

  250.     }

  251.     /**
  252.      * Method for implementing actual integration algorithms in derived
  253.      * classes.
  254.      *
  255.      * @return the root.
  256.      * @throws MathIllegalStateException if the maximal number of evaluations
  257.      * is exceeded.
  258.      * @throws MathIllegalStateException if the maximum iteration count is exceeded
  259.      * or the integrator detects convergence problems otherwise
  260.      */
  261.     protected abstract T doIntegrate()
  262.         throws MathIllegalStateException;

  263. }