View Javadoc
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  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.analysis.integration.gauss;
23  
24  import org.hipparchus.CalculusFieldElement;
25  import org.hipparchus.Field;
26  import org.hipparchus.exception.MathIllegalArgumentException;
27  import org.hipparchus.util.Pair;
28  
29  /**
30   * Class that provides different ways to compute the nodes and weights to be
31   * used by the {@link GaussIntegrator Gaussian integration rule}.
32   * @param <T> Type of the field elements.
33   * @since 2.0
34   */
35  public class FieldGaussIntegratorFactory<T extends CalculusFieldElement<T>> {
36  
37      /** Generator of Gauss-Legendre integrators. */
38      private final FieldRuleFactory<T> legendre;
39      /** Generator of Gauss-Hermite integrators. */
40      private final FieldRuleFactory<T> hermite;
41      /** Generator of Gauss-Laguerre integrators. */
42      private final FieldRuleFactory<T> laguerre;
43  
44      /** Simple constructor.
45       * @param field field to which function argument and value belong
46       */
47      public FieldGaussIntegratorFactory(final Field<T> field) {
48          legendre = new FieldLegendreRuleFactory<>(field);
49          hermite  = new FieldHermiteRuleFactory<>(field);
50          laguerre = new FieldLaguerreRuleFactory<>(field);
51      }
52  
53      /**
54       * Creates a Gauss-Laguerre integrator of the given order.
55       * The call to the
56       * {@link GaussIntegrator#integrate(org.hipparchus.analysis.UnivariateFunction)
57       * integrate} method will perform an integration on the interval
58       * \([0, +\infty)\): the computed value is the improper integral of
59       * \(e^{-x} f(x)\)
60       * where \(f(x)\) is the function passed to the
61       * {@link SymmetricGaussIntegrator#integrate(org.hipparchus.analysis.UnivariateFunction)
62       * integrate} method.
63       *
64       * @param numberOfPoints Order of the integration rule.
65       * @return a Gauss-Legendre integrator.
66       */
67      public FieldGaussIntegrator<T> laguerre(int numberOfPoints) {
68          return new FieldGaussIntegrator<>(laguerre.getRule(numberOfPoints));
69      }
70  
71      /**
72       * Creates a Gauss-Legendre integrator of the given order.
73       * The call to the
74       * {@link FieldGaussIntegrator#integrate(org.hipparchus.analysis.CalculusFieldUnivariateFunction)
75       * integrate} method will perform an integration on the natural interval
76       * {@code [-1 , 1]}.
77       *
78       * @param numberOfPoints Order of the integration rule.
79       * @return a Gauss-Legendre integrator.
80       */
81      public FieldGaussIntegrator<T> legendre(int numberOfPoints) {
82          return new FieldGaussIntegrator<>(legendre.getRule(numberOfPoints));
83      }
84  
85      /**
86       * Creates a Gauss-Legendre integrator of the given order.
87       * The call to the
88       * {@link FieldGaussIntegrator#integrate(org.hipparchus.analysis.CalculusFieldUnivariateFunction)
89       * integrate} method will perform an integration on the given interval.
90       *
91       * @param numberOfPoints Order of the integration rule.
92       * @param lowerBound Lower bound of the integration interval.
93       * @param upperBound Upper bound of the integration interval.
94       * @return a Gauss-Legendre integrator.
95       * @throws MathIllegalArgumentException if number of points is not positive
96       */
97      public FieldGaussIntegrator<T> legendre(int numberOfPoints,
98                                              T lowerBound,
99                                              T upperBound)
100         throws MathIllegalArgumentException {
101         return new FieldGaussIntegrator<>(transform(legendre.getRule(numberOfPoints),
102                                                     lowerBound, upperBound));
103     }
104 
105     /**
106      * Creates a Gauss-Hermite integrator of the given order.
107      * The call to the
108      * {@link SymmetricGaussIntegrator#integrate(org.hipparchus.analysis.UnivariateFunction)
109      * integrate} method will perform a weighted integration on the interval
110      * \([-\infty, +\infty]\): the computed value is the improper integral of
111      * \(e^{-x^2}f(x)\)
112      * where \(f(x)\) is the function passed to the
113      * {@link SymmetricGaussIntegrator#integrate(org.hipparchus.analysis.UnivariateFunction)
114      * integrate} method.
115      *
116      * @param numberOfPoints Order of the integration rule.
117      * @return a Gauss-Hermite integrator.
118      */
119     public SymmetricFieldGaussIntegrator<T> hermite(int numberOfPoints) {
120         return new SymmetricFieldGaussIntegrator<>(hermite.getRule(numberOfPoints));
121     }
122 
123     /**
124      * Performs a change of variable so that the integration can be performed
125      * on an arbitrary interval {@code [a, b]}.
126      * It is assumed that the natural interval is {@code [-1, 1]}.
127      *
128      * @param rule Original points and weights.
129      * @param a Lower bound of the integration interval.
130      * @param b Lower bound of the integration interval.
131      * @return the points and weights adapted to the new interval.
132      */
133     private Pair<T[], T[]> transform(Pair<T[], T[]> rule, T a, T b) {
134         final T[] points = rule.getFirst();
135         final T[] weights = rule.getSecond();
136 
137         // Scaling
138         final T scale = b.subtract(a).multiply(0.5);
139         final T shift = a.add(scale);
140 
141         for (int i = 0; i < points.length; i++) {
142             points[i]  = points[i].multiply(scale).add(shift);
143             weights[i] = weights[i].multiply(scale);
144         }
145 
146         return new Pair<>(points, weights);
147     }
148 
149 }