001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.math3.analysis.integration.gauss; 018 019 import java.math.BigDecimal; 020 021 import org.apache.commons.math3.util.Pair; 022 023 /** 024 * Class that provides different ways to compute the nodes and weights to be 025 * used by the {@link GaussIntegrator Gaussian integration rule}. 026 * 027 * @since 3.1 028 * @version $Id: GaussIntegratorFactory.java 1364420 2012-07-22 20:01:12Z tn $ 029 */ 030 public class GaussIntegratorFactory { 031 /** Generator of Gauss-Legendre integrators. */ 032 private final BaseRuleFactory<Double> legendre = new LegendreRuleFactory(); 033 /** Generator of Gauss-Legendre integrators. */ 034 private final BaseRuleFactory<BigDecimal> legendreHighPrecision = new LegendreHighPrecisionRuleFactory(); 035 036 /** 037 * Creates an integrator of the given order, and whose call to the 038 * {@link GaussIntegrator#integrate(org.apache.commons.math3.analysis.UnivariateFunction) 039 * integrate} method will perform an integration on the natural interval 040 * {@code [-1 , 1]}. 041 * 042 * @param numberOfPoints Order of the integration rule. 043 * @return a Gauss-Legendre integrator. 044 */ 045 public GaussIntegrator legendre(int numberOfPoints) { 046 return new GaussIntegrator(getRule(legendre, numberOfPoints)); 047 } 048 049 /** 050 * Creates an integrator of the given order, and whose call to the 051 * {@link GaussIntegrator#integrate(org.apache.commons.math3.analysis.UnivariateFunction) 052 * integrate} method will perform an integration on the given interval. 053 * 054 * @param numberOfPoints Order of the integration rule. 055 * @param lowerBound Lower bound of the integration interval. 056 * @param upperBound Upper bound of the integration interval. 057 * @return a Gauss-Legendre integrator. 058 */ 059 public GaussIntegrator legendre(int numberOfPoints, 060 double lowerBound, 061 double upperBound) { 062 return new GaussIntegrator(transform(getRule(legendre, numberOfPoints), 063 lowerBound, upperBound)); 064 } 065 066 /** 067 * Creates an integrator of the given order, and whose call to the 068 * {@link GaussIntegrator#integrate(org.apache.commons.math3.analysis.UnivariateFunction) 069 * integrate} method will perform an integration on the natural interval 070 * {@code [-1 , 1]}. 071 * 072 * @param numberOfPoints Order of the integration rule. 073 * @return a Gauss-Legendre integrator. 074 */ 075 public GaussIntegrator legendreHighPrecision(int numberOfPoints) { 076 return new GaussIntegrator(getRule(legendreHighPrecision, numberOfPoints)); 077 } 078 079 /** 080 * Creates an integrator of the given order, and whose call to the 081 * {@link GaussIntegrator#integrate(org.apache.commons.math3.analysis.UnivariateFunction) 082 * integrate} method will perform an integration on the given interval. 083 * 084 * @param numberOfPoints Order of the integration rule. 085 * @param lowerBound Lower bound of the integration interval. 086 * @param upperBound Upper bound of the integration interval. 087 * @return a Gauss-Legendre integrator. 088 */ 089 public GaussIntegrator legendreHighPrecision(int numberOfPoints, 090 double lowerBound, 091 double upperBound) { 092 return new GaussIntegrator(transform(getRule(legendreHighPrecision, numberOfPoints), 093 lowerBound, upperBound)); 094 } 095 096 /** 097 * @param factory Integration rule factory. 098 * @param numberOfPoints Order of the integration rule. 099 * @return the integration nodes and weights. 100 */ 101 private static Pair<double[], double[]> getRule(BaseRuleFactory<? extends Number> factory, 102 int numberOfPoints) { 103 return factory.getRule(numberOfPoints); 104 } 105 106 /** 107 * Performs a change of variable so that the integration can be performed 108 * on an arbitrary interval {@code [a, b]}. 109 * It is assumed that the natural interval is {@code [-1, 1]}. 110 * 111 * @param rule Original points and weights. 112 * @param a Lower bound of the integration interval. 113 * @param b Lower bound of the integration interval. 114 * @return the points and weights adapted to the new interval. 115 */ 116 private static Pair<double[], double[]> transform(Pair<double[], double[]> rule, 117 double a, 118 double b) { 119 final double[] points = rule.getFirst(); 120 final double[] weights = rule.getSecond(); 121 122 // Scaling 123 final double scale = (b - a) / 2; 124 final double shift = a + scale; 125 126 for (int i = 0; i < points.length; i++) { 127 points[i] = points[i] * scale + shift; 128 weights[i] *= scale; 129 } 130 131 return new Pair<double[], double[]>(points, weights); 132 } 133 }