FieldGaussIntegratorFactory.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.gauss;

  22. import org.hipparchus.CalculusFieldElement;
  23. import org.hipparchus.Field;
  24. import org.hipparchus.exception.MathIllegalArgumentException;
  25. import org.hipparchus.util.Pair;

  26. /**
  27.  * Class that provides different ways to compute the nodes and weights to be
  28.  * used by the {@link GaussIntegrator Gaussian integration rule}.
  29.  * @param <T> Type of the field elements.
  30.  * @since 2.0
  31.  */
  32. public class FieldGaussIntegratorFactory<T extends CalculusFieldElement<T>> {

  33.     /** Generator of Gauss-Legendre integrators. */
  34.     private final FieldRuleFactory<T> legendre;
  35.     /** Generator of Gauss-Hermite integrators. */
  36.     private final FieldRuleFactory<T> hermite;
  37.     /** Generator of Gauss-Laguerre integrators. */
  38.     private final FieldRuleFactory<T> laguerre;

  39.     /** Simple constructor.
  40.      * @param field field to which function argument and value belong
  41.      */
  42.     public FieldGaussIntegratorFactory(final Field<T> field) {
  43.         legendre = new FieldLegendreRuleFactory<>(field);
  44.         hermite  = new FieldHermiteRuleFactory<>(field);
  45.         laguerre = new FieldLaguerreRuleFactory<>(field);
  46.     }

  47.     /**
  48.      * Creates a Gauss-Laguerre integrator of the given order.
  49.      * The call to the
  50.      * {@link GaussIntegrator#integrate(org.hipparchus.analysis.UnivariateFunction)
  51.      * integrate} method will perform an integration on the interval
  52.      * \([0, +\infty)\): the computed value is the improper integral of
  53.      * \(e^{-x} f(x)\)
  54.      * where \(f(x)\) is the function passed to the
  55.      * {@link SymmetricGaussIntegrator#integrate(org.hipparchus.analysis.UnivariateFunction)
  56.      * integrate} method.
  57.      *
  58.      * @param numberOfPoints Order of the integration rule.
  59.      * @return a Gauss-Legendre integrator.
  60.      */
  61.     public FieldGaussIntegrator<T> laguerre(int numberOfPoints) {
  62.         return new FieldGaussIntegrator<>(laguerre.getRule(numberOfPoints));
  63.     }

  64.     /**
  65.      * Creates a Gauss-Legendre integrator of the given order.
  66.      * The call to the
  67.      * {@link FieldGaussIntegrator#integrate(org.hipparchus.analysis.CalculusFieldUnivariateFunction)
  68.      * integrate} method will perform an integration on the natural interval
  69.      * {@code [-1 , 1]}.
  70.      *
  71.      * @param numberOfPoints Order of the integration rule.
  72.      * @return a Gauss-Legendre integrator.
  73.      */
  74.     public FieldGaussIntegrator<T> legendre(int numberOfPoints) {
  75.         return new FieldGaussIntegrator<>(legendre.getRule(numberOfPoints));
  76.     }

  77.     /**
  78.      * Creates a Gauss-Legendre integrator of the given order.
  79.      * The call to the
  80.      * {@link FieldGaussIntegrator#integrate(org.hipparchus.analysis.CalculusFieldUnivariateFunction)
  81.      * integrate} method will perform an integration on the given interval.
  82.      *
  83.      * @param numberOfPoints Order of the integration rule.
  84.      * @param lowerBound Lower bound of the integration interval.
  85.      * @param upperBound Upper bound of the integration interval.
  86.      * @return a Gauss-Legendre integrator.
  87.      * @throws MathIllegalArgumentException if number of points is not positive
  88.      */
  89.     public FieldGaussIntegrator<T> legendre(int numberOfPoints,
  90.                                             T lowerBound,
  91.                                             T upperBound)
  92.         throws MathIllegalArgumentException {
  93.         return new FieldGaussIntegrator<>(transform(legendre.getRule(numberOfPoints),
  94.                                                     lowerBound, upperBound));
  95.     }

  96.     /**
  97.      * Creates a Gauss-Hermite integrator of the given order.
  98.      * The call to the
  99.      * {@link SymmetricGaussIntegrator#integrate(org.hipparchus.analysis.UnivariateFunction)
  100.      * integrate} method will perform a weighted integration on the interval
  101.      * \([-\infty, +\infty]\): the computed value is the improper integral of
  102.      * \(e^{-x^2}f(x)\)
  103.      * where \(f(x)\) is the function passed to the
  104.      * {@link SymmetricGaussIntegrator#integrate(org.hipparchus.analysis.UnivariateFunction)
  105.      * integrate} method.
  106.      *
  107.      * @param numberOfPoints Order of the integration rule.
  108.      * @return a Gauss-Hermite integrator.
  109.      */
  110.     public SymmetricFieldGaussIntegrator<T> hermite(int numberOfPoints) {
  111.         return new SymmetricFieldGaussIntegrator<>(hermite.getRule(numberOfPoints));
  112.     }

  113.     /**
  114.      * Performs a change of variable so that the integration can be performed
  115.      * on an arbitrary interval {@code [a, b]}.
  116.      * It is assumed that the natural interval is {@code [-1, 1]}.
  117.      *
  118.      * @param rule Original points and weights.
  119.      * @param a Lower bound of the integration interval.
  120.      * @param b Lower bound of the integration interval.
  121.      * @return the points and weights adapted to the new interval.
  122.      */
  123.     private Pair<T[], T[]> transform(Pair<T[], T[]> rule, T a, T b) {
  124.         final T[] points = rule.getFirst();
  125.         final T[] weights = rule.getSecond();

  126.         // Scaling
  127.         final T scale = b.subtract(a).multiply(0.5);
  128.         final T shift = a.add(scale);

  129.         for (int i = 0; i < points.length; i++) {
  130.             points[i]  = points[i].multiply(scale).add(shift);
  131.             weights[i] = weights[i].multiply(scale);
  132.         }

  133.         return new Pair<>(points, weights);
  134.     }

  135. }