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 }