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 * http://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 package org.apache.commons.math4.legacy.analysis.integration.gauss; 18 19 import org.apache.commons.math4.legacy.core.Pair; 20 import java.math.BigDecimal; 21 22 /** 23 * Class that provides different ways to compute the nodes and weights to be 24 * used by the {@link GaussIntegrator Gaussian integration rule}. 25 * 26 * @since 3.1 27 */ 28 public class GaussIntegratorFactory { 29 /** Generator of Gauss-Legendre integrators. */ 30 private final BaseRuleFactory<Double> legendre = new LegendreRuleFactory(); 31 /** Generator of Gauss-Legendre integrators. */ 32 private final BaseRuleFactory<BigDecimal> legendreHighPrecision = new LegendreHighPrecisionRuleFactory(); 33 /** Generator of Gauss-Hermite integrators. */ 34 private final BaseRuleFactory<Double> hermite = new HermiteRuleFactory(); 35 /** Generator of Gauss-Laguerre integrators. */ 36 private final BaseRuleFactory<Double> laguerre = new LaguerreRuleFactory(); 37 38 /** 39 * Creates a Gauss-Laguerre integrator of the given order. 40 * The call to the 41 * {@link GaussIntegrator#integrate(org.apache.commons.math4.legacy.analysis.UnivariateFunction) 42 * integrate} method will perform an integration on the interval 43 * \([0, +\infty)\): the computed value is the improper integral of 44 * \(e^{-x} f(x)\) 45 * where \(f(x)\) is the function passed to the 46 * {@link SymmetricGaussIntegrator#integrate(org.apache.commons.math4.legacy.analysis.UnivariateFunction) 47 * integrate} method. 48 * 49 * @param numberOfPoints Order of the integration rule. 50 * @return a Gauss-Legendre integrator. 51 * @since 4.0 52 */ 53 public GaussIntegrator laguerre(int numberOfPoints) { 54 return new GaussIntegrator(getRule(laguerre, numberOfPoints)); 55 } 56 57 /** 58 * Creates a Gauss-Legendre integrator of the given order. 59 * The call to the 60 * {@link GaussIntegrator#integrate(org.apache.commons.math4.legacy.analysis.UnivariateFunction) 61 * integrate} method will perform an integration on the natural interval 62 * {@code [-1 , 1]}. 63 * 64 * @param numberOfPoints Order of the integration rule. 65 * @return a Gauss-Legendre integrator. 66 */ 67 public GaussIntegrator legendre(int numberOfPoints) { 68 return new GaussIntegrator(getRule(legendre, numberOfPoints)); 69 } 70 71 /** 72 * Creates a Gauss-Legendre integrator of the given order. 73 * The call to the 74 * {@link GaussIntegrator#integrate(org.apache.commons.math4.legacy.analysis.UnivariateFunction) 75 * integrate} method will perform an integration on the given interval. 76 * 77 * @param numberOfPoints Order of the integration rule. 78 * @param lowerBound Lower bound of the integration interval. 79 * @param upperBound Upper bound of the integration interval. 80 * @return a Gauss-Legendre integrator. 81 * @throws org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException if number of points is not positive 82 */ 83 public GaussIntegrator legendre(int numberOfPoints, 84 double lowerBound, 85 double upperBound) { 86 return new GaussIntegrator(transform(getRule(legendre, numberOfPoints), 87 lowerBound, upperBound)); 88 } 89 90 /** 91 * Creates a Gauss-Legendre integrator of the given order. 92 * The call to the 93 * {@link GaussIntegrator#integrate(org.apache.commons.math4.legacy.analysis.UnivariateFunction) 94 * integrate} method will perform an integration on the natural interval 95 * {@code [-1 , 1]}. 96 * 97 * @param numberOfPoints Order of the integration rule. 98 * @return a Gauss-Legendre integrator. 99 * @throws org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException if number of points is not positive 100 */ 101 public GaussIntegrator legendreHighPrecision(int numberOfPoints) { 102 return new GaussIntegrator(getRule(legendreHighPrecision, numberOfPoints)); 103 } 104 105 /** 106 * Creates an integrator of the given order, and whose call to the 107 * {@link GaussIntegrator#integrate(org.apache.commons.math4.legacy.analysis.UnivariateFunction) 108 * integrate} method will perform an integration on the given interval. 109 * 110 * @param numberOfPoints Order of the integration rule. 111 * @param lowerBound Lower bound of the integration interval. 112 * @param upperBound Upper bound of the integration interval. 113 * @return a Gauss-Legendre integrator. 114 * @throws org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException if number of points is not positive 115 */ 116 public GaussIntegrator legendreHighPrecision(int numberOfPoints, 117 double lowerBound, 118 double upperBound) { 119 return new GaussIntegrator(transform(getRule(legendreHighPrecision, numberOfPoints), 120 lowerBound, upperBound)); 121 } 122 123 /** 124 * Creates a Gauss-Hermite integrator of the given order. 125 * The call to the 126 * {@link SymmetricGaussIntegrator#integrate(org.apache.commons.math4.legacy.analysis.UnivariateFunction) 127 * integrate} method will perform a weighted integration on the interval 128 * \([-\infty, +\infty]\): the computed value is the improper integral of 129 * \(e^{-x^2}f(x)\) 130 * where \(f(x)\) is the function passed to the 131 * {@link SymmetricGaussIntegrator#integrate(org.apache.commons.math4.legacy.analysis.UnivariateFunction) 132 * integrate} method. 133 * 134 * @param numberOfPoints Order of the integration rule. 135 * @return a Gauss-Hermite integrator. 136 */ 137 public SymmetricGaussIntegrator hermite(int numberOfPoints) { 138 return new SymmetricGaussIntegrator(getRule(hermite, numberOfPoints)); 139 } 140 141 /** 142 * @param factory Integration rule factory. 143 * @param numberOfPoints Order of the integration rule. 144 * @return the integration nodes and weights. 145 * @throws org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException if number of points is not positive 146 * @throws org.apache.commons.math4.legacy.exception.DimensionMismatchException if the elements of the rule pair do not 147 * have the same length. 148 */ 149 private static Pair<double[], double[]> getRule(BaseRuleFactory<? extends Number> factory, 150 int numberOfPoints) { 151 return factory.getRule(numberOfPoints); 152 } 153 154 /** 155 * Performs a change of variable so that the integration can be performed 156 * on an arbitrary interval {@code [a, b]}. 157 * It is assumed that the natural interval is {@code [-1, 1]}. 158 * 159 * @param rule Original points and weights. 160 * @param a Lower bound of the integration interval. 161 * @param b Lower bound of the integration interval. 162 * @return the points and weights adapted to the new interval. 163 */ 164 private static Pair<double[], double[]> transform(Pair<double[], double[]> rule, 165 double a, 166 double b) { 167 final double[] points = rule.getFirst(); 168 final double[] weights = rule.getSecond(); 169 170 // Scaling 171 final double scale = (b - a) / 2; 172 final double shift = a + scale; 173 174 for (int i = 0; i < points.length; i++) { 175 points[i] = points[i] * scale + shift; 176 weights[i] *= scale; 177 } 178 179 return new Pair<>(points, weights); 180 } 181 }