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 }