def __init__(self, npoints: int, alpha: float = 0): r"""Generate grid on :math:`[0, \infty)` based on generalized Gauss-Laguerre quadrature. Parameters ---------- npoints : int Number of grid points. alpha : float, optional Value of the parameter :math:`alpha` which must be larger than -1. Returns ------- OneDGrid A 1-D grid instance containing points and weights. """ if npoints <= 1: raise ValueError( f"Argument npoints must be an integer > 1, given {npoints}") if alpha <= -1: raise ValueError( f"Argument alpha must be larger than -1, given {alpha}") # compute points and weights for Generalized Gauss-Laguerre quadrature points, weights = roots_genlaguerre(npoints, alpha) weights *= np.exp(points) * np.power(points, -alpha) super().__init__(points, weights, (0, np.inf))
def GaussLaguerre(npoints, alpha=0): r"""Generate 1D grid on [0, inf) interval based on Generalized Gauss-Laguerre quadrature. The fundamental definition of Generalized Gauss-Laguerre quadrature is: .. math:: \int_{0}^{\infty} x^\alpha e^{-x} f(x) dx \approx \sum_{i=1}^n w_i f(x_i) However, to integrate function :math:`g(x)` over [0, inf), this is re-written as: .. math:: \int_{0}^{\infty} g(x)dx \approx \sum_{i=1}^n \frac{w_i}{x_i^\alpha e^{-x_i}} g(x_i) = \sum_{i=1}^n w_i' g(x_i) Parameters ---------- npoints : int Number of grid points. alpha : float, optional Value of parameter :math:`alpha` which should be larger than -1. Returns ------- OneDGrid A 1D grid instance. """ if alpha <= -1: raise ValueError(f"Alpha need to be bigger than -1, given {alpha}") points, weights = roots_genlaguerre(npoints, alpha) weights = weights * np.exp(points) * np.power(points, -alpha) return OneDGrid(points, weights, (0, np.inf))
def GaussLaguerre(npoints, alpha=0): r"""Generate a grid based on generalized Gauss-Laguerre grid. Generalizeed Gauss Laguerre grid is defined as: .. math:: \int_{0}^{\infty} x^{\alpha}e^{-x} f(x)dx \approx \sum_{i=1}^n w_i f(x_i) This integration grid is defined as : .. math:: \int_{0}^{\infty} f(x)dx \approx \sum_{i=1}^n \frac{w_i}{x_i^{\alpha} e^{-x_i}} f(x_i) = \sum_{i=1}^n w_i' f(x_i) Parameters ---------- npoints : int Number of points in the grid alpha : float, default to 0, required to be > -1 parameter alpha value Returns ------- OneDGrid A grid instance with points and weights, (0, inf) """ if alpha <= -1: raise ValueError(f"Alpha need to be bigger than -1, given {alpha}") points, weights = roots_genlaguerre(npoints, alpha) weights = weights * np.exp(points) * np.power(points, -alpha) return OneDGrid(points, weights)
def laguerre(function, order, *args, **kwargs): """ Evaluate integral of <function> object, of 1 variable and parameters: integral[0, +infinity] {dx exp(-x) function(x, **args)} Args: :function <function> f(x, *args, **kwargs) :order <int> order of the quadrature or <tuple> (order, alpha) where alpha is float for the associated Laguerre integration (dx x^alpha exp(-x) *f(x)) *args and **kwargs will be passed to the function (check argument introduction in case of several function management) """ if not order in GaussianQuadrature._roots_weights_Laguerre: if isinstance(order, tuple): x_i, w_i = roots_genlaguerre(order[0], alpha=order[1]) else: x_i, w_i = roots_laguerre(order, mu=False) GaussianQuadrature._roots_weights_Laguerre[order] = (x_i, w_i) else: x_i, w_i = GaussianQuadrature._roots_weights_Laguerre.get(order) # integral = 0.0 # for i in range(len(x_i)): # integral += w_i[i] * function(x_i[i], *args, **kwargs) integral = np.dot(w_i, function(x_i, *args, **kwargs)) #print("order", order, "=",integral) return integral
def gauss_genlaguerre(n, alpha): ''' Generalized Gauss-Laguerre quadrature: A rule of order 2*n-1 on the ray with respect to the weight function w(x) = x**alpha*exp(-x). ''' return special.roots_genlaguerre(n, alpha)
def test_roots_genlaguerre(): rootf = lambda a: lambda n, mu: sc.roots_genlaguerre(n, a, mu) evalf = lambda a: lambda n, x: orth.eval_genlaguerre(n, a, x) weightf = lambda a: lambda x: x**a * np.exp(-x) vgq = verify_gauss_quad vgq(rootf(-0.5), evalf(-0.5), weightf(-0.5), 0., np.inf, 5) vgq(rootf(-0.5), evalf(-0.5), weightf(-0.5), 0., np.inf, 25, atol=1e-13) vgq(rootf(-0.5), evalf(-0.5), weightf(-0.5), 0., np.inf, 100, atol=1e-12) vgq(rootf(0.1), evalf(0.1), weightf(0.1), 0., np.inf, 5) vgq(rootf(0.1), evalf(0.1), weightf(0.1), 0., np.inf, 25, atol=1e-13) vgq(rootf(0.1), evalf(0.1), weightf(0.1), 0., np.inf, 100, atol=1.6e-13) vgq(rootf(1), evalf(1), weightf(1), 0., np.inf, 5) vgq(rootf(1), evalf(1), weightf(1), 0., np.inf, 25, atol=1e-13) vgq(rootf(1), evalf(1), weightf(1), 0., np.inf, 100, atol=1.03e-13) vgq(rootf(10), evalf(10), weightf(10), 0., np.inf, 5) vgq(rootf(10), evalf(10), weightf(10), 0., np.inf, 25, atol=1e-13) vgq(rootf(10), evalf(10), weightf(10), 0., np.inf, 100, atol=1e-12) vgq(rootf(50), evalf(50), weightf(50), 0., np.inf, 5) vgq(rootf(50), evalf(50), weightf(50), 0., np.inf, 25, atol=1e-13) vgq(rootf(50), evalf(50), weightf(50), 0., np.inf, 100, rtol=1e-14, atol=2e-13) x, w = sc.roots_genlaguerre(5, 2, False) y, v, m = sc.roots_genlaguerre(5, 2, True) assert_allclose(x, y, 1e-14, 1e-14) assert_allclose(w, v, 1e-14, 1e-14) muI, muI_err = integrate.quad(weightf(2.), 0., np.inf) assert_allclose(m, muI, rtol=muI_err) assert_raises(ValueError, sc.roots_genlaguerre, 0, 2) assert_raises(ValueError, sc.roots_genlaguerre, 3.3, 2) assert_raises(ValueError, sc.roots_genlaguerre, 3, -1.1)
def gamma(n, alpha, scale=1): ''' Generalized Gauss-Laguerre quadrature: A rule of order 2*n-1 on the ray with respect to the PDF of a gamma distribution with arbitrary scale and shape parameter `alpha`. ''' return special.roots_genlaguerre(n, alpha) nodes *= scale weights /= np.sum(weights) return nodes, weights
def test_roots_genlaguerre(): rootf = lambda a: lambda n, mu: sc.roots_genlaguerre(n, a, mu) evalf = lambda a: lambda n, x: orth.eval_genlaguerre(n, a, x) weightf = lambda a: lambda x: x**a * np.exp(-x) vgq = verify_gauss_quad vgq(rootf(-0.5), evalf(-0.5), weightf(-0.5), 0., np.inf, 5) vgq(rootf(-0.5), evalf(-0.5), weightf(-0.5), 0., np.inf, 25, atol=1e-13) vgq(rootf(-0.5), evalf(-0.5), weightf(-0.5), 0., np.inf, 100, atol=1e-12) vgq(rootf(0.1), evalf(0.1), weightf(0.1), 0., np.inf, 5) vgq(rootf(0.1), evalf(0.1), weightf(0.1), 0., np.inf, 25, atol=1e-13) vgq(rootf(0.1), evalf(0.1), weightf(0.1), 0., np.inf, 100, atol=1e-13) vgq(rootf(1), evalf(1), weightf(1), 0., np.inf, 5) vgq(rootf(1), evalf(1), weightf(1), 0., np.inf, 25, atol=1e-13) vgq(rootf(1), evalf(1), weightf(1), 0., np.inf, 100, atol=1e-13) vgq(rootf(10), evalf(10), weightf(10), 0., np.inf, 5) vgq(rootf(10), evalf(10), weightf(10), 0., np.inf, 25, atol=1e-13) vgq(rootf(10), evalf(10), weightf(10), 0., np.inf, 100, atol=1e-12) vgq(rootf(50), evalf(50), weightf(50), 0., np.inf, 5) vgq(rootf(50), evalf(50), weightf(50), 0., np.inf, 25, atol=1e-13) vgq(rootf(50), evalf(50), weightf(50), 0., np.inf, 100, rtol=1e-14, atol=2e-13) x, w = sc.roots_genlaguerre(5, 2, False) y, v, m = sc.roots_genlaguerre(5, 2, True) assert_allclose(x, y, 1e-14, 1e-14) assert_allclose(w, v, 1e-14, 1e-14) muI, muI_err = integrate.quad(weightf(2.), 0., np.inf) assert_allclose(m, muI, rtol=muI_err) assert_raises(ValueError, sc.roots_genlaguerre, 0, 2) assert_raises(ValueError, sc.roots_genlaguerre, 3.3, 2) assert_raises(ValueError, sc.roots_genlaguerre, 3, -1.1)
def GaussLaguerre(npoints, alpha=0): """Generate Gauss-Laguerre grid. Parameters ---------- npoints : int Number of points in the grid alpha : int, default to 0, required to be > -1 parameter alpha value Returns ------- OneDGrid A grid instance with points and weights """ if alpha <= -1: raise ValueError(f"Alpha need to be bigger than -1, given {alpha}") points, weights = roots_genlaguerre(npoints, alpha) return OneDGrid(points, weights)
def get_quadrature_laguerre_1d(n, alpha): """ Get knots and weights of Laguerre polynomials (gamma distribution). knots, weights = Grid.get_quadrature_laguerre_1d(n) Parameters ---------- n: int number of knots alpha: float Parameter of Laguerre polynomial Returns ------- knots: np.ndarray knots of the grid weights: np.ndarray weights of the grid """ n = np.int(n) knots, weights = roots_genlaguerre(n=n, alpha=alpha) return knots, weights
def init_roots(self): self.bT_pts = special.roots_genlaguerre(n=self.bT_npts, alpha=1.0) self.bL_pts = special.roots_legendre(n=self.bL_npts) print("Roots for betagammaT: ", self.convert_to_betagammaT(self.bT_pts[0])) print("Roots for y: ", self.convert_to_y(self.bL_pts[0]))