com.opengamma.strata.math.impl.integration.GaussLegendreWeightAndAbscissaFunction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of strata-math Show documentation
Show all versions of strata-math Show documentation
Mathematic support for Strata
/*
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.math.impl.integration;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.collect.tuple.Pair;
import com.opengamma.strata.math.impl.function.DoubleFunction1D;
import com.opengamma.strata.math.impl.function.special.LegendrePolynomialFunction;
import com.opengamma.strata.math.impl.rootfinding.NewtonRaphsonSingleRootFinder;
/**
* Class that generates weights and abscissas for Gauss-Legendre quadrature.
* The weights $w_i$ are given by:
* $$
* \begin{align*}
* w_i = \frac{2}{(1 - x_i^2) L_i'(x_i)^2}
* \end{align*}
* $$
* where $x_i$ is the $i^{th}$ root of the orthogonal polynomial and $L_i'$ is
* the first derivative of the $i^{th}$ polynomial. The orthogonal polynomial
* is generated by
* {@link LegendrePolynomialFunction}.
*/
public class GaussLegendreWeightAndAbscissaFunction implements QuadratureWeightAndAbscissaFunction {
private static final LegendrePolynomialFunction LEGENDRE = new LegendrePolynomialFunction();
private static final NewtonRaphsonSingleRootFinder ROOT_FINDER = new NewtonRaphsonSingleRootFinder(1e-15);
/**
* {@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[] polynomials = LEGENDRE.getPolynomialsAndFirstDerivative(n);
Pair 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);
}
private double getInitialRootGuess(int i, int n) {
return Math.cos(Math.PI * (i + 0.75) / (n + 0.5));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy