@Test public void test() { GaussianQuadratureData other = new GaussianQuadratureData(X, W); assertEquals(F, other); assertEquals(F.hashCode(), other.hashCode()); other = new GaussianQuadratureData(W, W); assertFalse(F.equals(other)); other = new GaussianQuadratureData(X, X); assertFalse(F.equals(other)); assertArrayEquals(F.getAbscissas(), X, 0); assertArrayEquals(F.getWeights(), W, 0); } }
/** * If a function $g(x)$ can be written as $W(x)f(x)$, where the weight function $W(x)$ corresponds * to one of the Gaussian quadrature forms, then we may approximate the integral of $g(x)$ over * a specific range as $\int^b_a g(x) dx =\int^b_a W(x)f(x) dx \approx \sum_{i=0}^{N-1} w_i f(x_i)$, * were the abscissas $x_i$ and the weights $w_i$ have been precomputed. This is accurate * if $f(x)$ can be approximated by a polynomial. * * @param polyFunction The function $f(x)$ rather than the full function $g(x) = W(x)f(x)$ * This should be well approximated by a polynomial. * @return The integral */ public double integrateFromPolyFunc(Function<Double, Double> polyFunction) { ArgChecker.notNull(polyFunction, "polyFunction"); double[] abscissas = quadrature.getAbscissas(); int n = abscissas.length; double[] weights = quadrature.getWeights(); double sum = 0; for (int i = 0; i < n; i++) { sum += polyFunction.apply(abscissas[i]) * weights[i]; } return sum; }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNullAbscissas() { new GaussianQuadratureData(null, W); }
protected void assertResults(final GaussianQuadratureData f, final double[] x, final double[] w) { final double[] x1 = f.getAbscissas(); final double[] w1 = f.getWeights(); for (int i = 0; i < x.length; i++) { assertEquals(x1[i], x[i], EPS); assertEquals(w1[i], w[i], EPS); } } }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNullWeights() { new GaussianQuadratureData(X, null); }
@Test public void test() { final int n = 12; final GaussianQuadratureData f1 = GAUSS_LEGENDRE.generate(n); final GaussianQuadratureData f2 = GAUSS_JACOBI_GL_EQUIV.generate(n); final GaussianQuadratureData f3 = GAUSS_JACOBI_CHEBYSHEV_EQUIV.generate(n); final double[] w1 = f1.getWeights(); final double[] w2 = f2.getWeights(); final double[] x1 = f1.getAbscissas(); final double[] x2 = f2.getAbscissas(); assertTrue(w1.length == w2.length); assertTrue(x1.length == x2.length); for (int i = 0; i < n; i++) { assertEquals(w1[i], w2[i], EPS); assertEquals(x1[i], -x2[i], EPS); } final double[] w3 = f3.getWeights(); final double[] x3 = f3.getAbscissas(); final double chebyshevWeight = Math.PI / n; final Function<Integer, Double> chebyshevAbscissa = new Function<Integer, Double>() { @Override public Double apply(final Integer x) { return -Math.cos(Math.PI * (x + 0.5) / n); } }; for (int i = 0; i < n; i++) { assertEquals(chebyshevWeight, w3[i], EPS); assertEquals(chebyshevAbscissa.apply(i), -x3[i], EPS); } }
@Test(expectedExceptions = IllegalArgumentException.class) public void testWrongLength() { new GaussianQuadratureData(X, new double[] {1, 2, 3 }); }
/** * {@inheritDoc} */ @Override public GaussianQuadratureData generate(int n) { ArgChecker.isTrue(n > 0); int mid = (n + 1) / 2; double[] x = new double[n]; double[] w = new double[n]; Pair<DoubleFunction1D, DoubleFunction1D>[] polynomials = LEGENDRE.getPolynomialsAndFirstDerivative(n); Pair<DoubleFunction1D, DoubleFunction1D> pair = polynomials[n]; DoubleFunction1D function = pair.getFirst(); DoubleFunction1D derivative = pair.getSecond(); for (int i = 0; i < mid; i++) { double root = ROOT_FINDER.getRoot(function, derivative, getInitialRootGuess(i, n)); x[i] = -root; x[n - i - 1] = root; double dp = derivative.applyAsDouble(root); w[i] = 2 / ((1 - root * root) * dp * dp); w[n - i - 1] = w[i]; } return new GaussianQuadratureData(x, w); }
@Override public GaussianQuadratureData generate(int n) { ArgChecker.isTrue(n > 0); double[] x = new double[n]; double[] w = new double[n]; boolean odd = n % 2 != 0; int m = (n + 1) / 2 - (odd ? 1 : 0); Pair<DoubleFunction1D, DoubleFunction1D>[] polynomials = HERMITE.getPolynomialsAndFirstDerivative(n); Pair<DoubleFunction1D, DoubleFunction1D> pair = polynomials[n]; DoubleFunction1D function = pair.getFirst(); DoubleFunction1D derivative = pair.getSecond(); double root = 0; for (int i = 0; i < m; i++) { root = getInitialRootGuess(root, i, n, x); root = ROOT_FINDER.getRoot(function, derivative, root); double dp = derivative.applyAsDouble(root); x[i] = -root; x[n - 1 - i] = root; w[i] = 2. / (dp * dp); w[n - 1 - i] = w[i]; } if (odd) { double dp = derivative.applyAsDouble(0.0); w[m] = 2. / dp / dp; } return new GaussianQuadratureData(x, w); }
/** * {@inheritDoc} */ @Override public GaussianQuadratureData generate(int n) { ArgChecker.isTrue(n > 0, "n > 0"); Pair<DoubleFunction1D, DoubleFunction1D>[] polynomials = JACOBI.getPolynomialsAndFirstDerivative(n, _alpha, _beta); Pair<DoubleFunction1D, DoubleFunction1D> pair = polynomials[n]; DoubleFunction1D previous = polynomials[n - 1].getFirst(); DoubleFunction1D function = pair.getFirst(); DoubleFunction1D derivative = pair.getSecond(); double[] x = new double[n]; double[] w = new double[n]; double root = 0; for (int i = 0; i < n; i++) { double d = 2 * n + _c; root = getInitialRootGuess(root, i, n, x); root = ROOT_FINDER.getRoot(function, derivative, root); x[i] = root; w[i] = GAMMA_FUNCTION.applyAsDouble(_alpha + n) * GAMMA_FUNCTION.applyAsDouble(_beta + n) / CombinatoricsUtils.factorialDouble(n) / GAMMA_FUNCTION.applyAsDouble(n + _c + 1) * d * Math.pow(2, _c) / (derivative.applyAsDouble(root) * previous.applyAsDouble(root)); } return new GaussianQuadratureData(x, w); }
/** * {@inheritDoc} */ @Override public GaussianQuadratureData generate(int n) { ArgChecker.isTrue(n > 0); Pair<DoubleFunction1D, DoubleFunction1D>[] polynomials = LAGUERRE.getPolynomialsAndFirstDerivative(n, _alpha); Pair<DoubleFunction1D, DoubleFunction1D> pair = polynomials[n]; DoubleFunction1D p1 = polynomials[n - 1].getFirst(); DoubleFunction1D function = pair.getFirst(); DoubleFunction1D derivative = pair.getSecond(); double[] x = new double[n]; double[] w = new double[n]; double root = 0; for (int i = 0; i < n; i++) { root = ROOT_FINDER.getRoot(function, derivative, getInitialRootGuess(root, i, n, x)); x[i] = root; w[i] = -GAMMA_FUNCTION.applyAsDouble(_alpha + n) / CombinatoricsUtils.factorialDouble(n) / (derivative.applyAsDouble(root) * p1.applyAsDouble(root)); } return new GaussianQuadratureData(x, w); }