def test_h_roots(): rootf = orth.h_roots evalf = orth.eval_hermite weightf = orth.hermite(5).weight_func verify_gauss_quad(rootf, evalf, weightf, -np.inf, np.inf, 5) verify_gauss_quad(rootf, evalf, weightf, -np.inf, np.inf, 25, atol=1e-13) verify_gauss_quad(rootf, evalf, weightf, -np.inf, np.inf, 100, atol=1e-12) # Golub-Welsch branch x, w = orth.h_roots(5, False) y, v, m = orth.h_roots(5, True) assert_allclose(x, y, 1e-14, 1e-14) assert_allclose(w, v, 1e-14, 1e-14) muI, muI_err = integrate.quad(weightf, -np.inf, np.inf) assert_allclose(m, muI, rtol=muI_err) # Asymptotic branch (switch over at n >= 150) x, w = orth.h_roots(200, False) y, v, m = orth.h_roots(200, True) assert_allclose(x, y, 1e-14, 1e-14) assert_allclose(w, v, 1e-14, 1e-14) assert_allclose(sum(v), m, 1e-14, 1e-14) assert_raises(ValueError, orth.h_roots, 0) assert_raises(ValueError, orth.h_roots, 3.3)
def test_h_roots(): verify_gauss_quad(orth.h_roots, orth.eval_hermite, 5) verify_gauss_quad(orth.h_roots, orth.eval_hermite, 25, atol=1e-13) verify_gauss_quad(orth.h_roots, orth.eval_hermite, 100, atol=1e-12) x, w = orth.h_roots(5, False) y, v, m = orth.h_roots(5, True) assert_allclose(x, y, 1e-14, 1e-14) assert_allclose(w, v, 1e-14, 1e-14) assert_raises(ValueError, orth.h_roots, 0) assert_raises(ValueError, orth.h_roots, 3.3)
def __init__(self, order): r""" Initialize a new quadrature rule. :param order: The order :math:`R` of the Gauss-Hermite quadrature. :raise: :py:class:`ValueError` if the ``order`` is not 1 or above. """ #: The order :math:`R` of the Gauss-Hermite quadrature. self.order = order # Qudrature has to have at least a single (node,weight) pair. if not self.order > 0: raise ValueError("Quadrature rule has to be of order 1 at least.") nodes, weights = h_roots(self.order) self.number_nodes = nodes.size h = self._hermite_recursion(nodes) weights = 1.0/((h**2) * self.order) #: The quadrature nodes :math:`\gamma_i`. self.nodes = nodes.reshape((1,self.number_nodes)) #: The quadrature weights :math:`\omega_i`. self.weights = weights[-1,:] self.weights = self.weights.reshape((1,self.number_nodes))
def __init__(self, order): r"""Initialize a new quadrature rule. :param order: The order :math:`R` of the Gauss-Hermite quadrature. :raise: :py:class:`ValueError` if the ``order`` is not 1 or above. """ # The space dimension of the quadrature rule. self._dimension = 1 # The order R of the Gauss-Hermite quadrature. self._order = order # Qudrature has to have at least a single (node,weight) pair. if not self._order > 0: raise ValueError("Quadrature rule has to be of order 1 at least.") nodes, weights = h_roots(self._order) # The number of nodes in this quadrature rule self._number_nodes = nodes.size # We deal with real values only, but the array we get from h_roots is of complex dtype h = self._hermite_recursion(real(nodes)) weights = 1.0 / ((h**2) * self._order) # The quadrature nodes \gamma. self._nodes = nodes.reshape((1, self._number_nodes)) # The quadrature weights \omega. self._weights = weights[-1, :] self._weights = self._weights.reshape((1, self._number_nodes))
def __init__(self, order): r"""Initialize a new quadrature rule. :param order: The order :math:`R` of the Gauss-Hermite quadrature. :raise: :py:class:`ValueError` if the ``order`` is not 1 or above. """ # The space dimension of the quadrature rule. self._dimension = 1 # The order R of the Gauss-Hermite quadrature. self._order = order # Qudrature has to have at least a single (node,weight) pair. if not self._order > 0: raise ValueError("Quadrature rule has to be of order 1 at least.") nodes, weights = h_roots(self._order) # The number of nodes in this quadrature rule self._number_nodes = nodes.size # We deal with real values only, but the array we get from h_roots is of complex dtype h = self._hermite_recursion(real(nodes)) weights = 1.0/((h**2) * self._order) # The quadrature nodes \gamma. self._nodes = nodes.reshape((1,self._number_nodes)) # The quadrature weights \omega. self._weights = weights[-1,:] self._weights = self._weights.reshape((1,self._number_nodes))
def setQuadrature(self,maxOrder): super(Normal,self).setQuadrature(maxOrder) #standard hermite quadrature pts,wts = quads.h_roots(self.quadOrd) self.pts,self.wts,self.quadOrds=super(Normal,self).checkPoints(pts,wts) self.pts=pts self.wts=wts
def setQuadrature(self, maxOrder): super(Normal, self).setQuadrature(maxOrder) #standard hermite quadrature pts, wts = quads.h_roots(self.quadOrd) self.pts, self.wts, self.quadOrds = super(Normal, self).checkPoints(pts, wts) self.pts = pts self.wts = wts
def setQuadrature(self,maxOrder): super(Normal,self).setQuadrature(maxOrder) #standard hermite quadrature pts,wts = quads.h_roots(self.quadOrd) self.pts,self.wts,self.quadOrds=super(Normal,self).checkPoints(pts,wts) self.quaddict = {} for o,order in enumerate(self.quadOrds): self.quaddict[order]=(self.pts[o],self.wts[o])
def setQuadrature(self, maxOrder): super(Normal, self).setQuadrature(maxOrder) #standard hermite quadrature pts, wts = quads.h_roots(self.quadOrd) self.pts, self.wts, self.quadOrds = super(Normal, self).checkPoints(pts, wts) self.quaddict = {} for o, order in enumerate(self.quadOrds): self.quaddict[order] = (self.pts[o], self.wts[o])
def setQuadrature(self, inputfile=None, order=2, verbose=False): if verbose: print 'set quadrature for', self.name #get order from input file if inputfile != None: self.order = inputfile('Variables/' + self.name + '/order', 2) else: self.order = order #standard legendre quadrature self.pts, self.wts = quads.h_roots(self.order)
def setQuadrature(self,inputfile=None,order=2,verbose=False): if verbose: print 'set quadrature for',self.name #get order from input file if inputfile != None: self.order=inputfile('Variables/'+self.name+'/order',2) else: self.order=order #standard legendre quadrature self.pts,self.wts = quads.h_roots(self.order)
def gauss_hermite_rule(npts, mk, vk): """ Compute the points and weights for the Gauss-Hermite quadrature with the normalized Gaussian N(0, h2) as a weighting function. """ x, w = h_roots(npts) x *= np.sqrt(2 * vk) x += mk w /= np.sqrt(np.pi) return x, w
def quadrature(self,n): return so.h_roots(n) #print '' #print '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' #print '!!! WARNING: OrthogonalPolynomial was redefined for consistency with BasisFunction' #print '!!! now n is the order = maximal degree + 1 ' #print '!!! i.e. n is the number of functions (n was the degree before) ' #print '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' #print '' if __name__ == "__main__":
def test_h_roots(): verify_gauss_quad(orth.h_roots, orth.eval_hermite, 5) verify_gauss_quad(orth.h_roots, orth.eval_hermite, 25, atol=1e-13) verify_gauss_quad(orth.h_roots, orth.eval_hermite, 100, atol=1e-12) # Golub-Welsch branch x, w = orth.h_roots(5, False) y, v, m = orth.h_roots(5, True) assert_allclose(x, y, 1e-14, 1e-14) assert_allclose(w, v, 1e-14, 1e-14) # Asymptotic branch (switch over at n >= 150) x, w = orth.h_roots(200, False) y, v, m = orth.h_roots(200, True) assert_allclose(x, y, 1e-14, 1e-14) assert_allclose(w, v, 1e-14, 1e-14) assert_allclose(sum(v), m, 1e-14, 1e-14) assert_raises(ValueError, orth.h_roots, 0) assert_raises(ValueError, orth.h_roots, 3.3)
def test_h_roots(self): # this test is copied from numpy's TestGauss in test_hermite.py x, w = orth.h_roots(100) n = np.arange(100) v = eval_hermite(n[:, np.newaxis], x[np.newaxis,:]) vv = np.dot(v*w, v.T) vd = 1 / np.sqrt(vv.diagonal()) vv = vd[:, np.newaxis] * vv * vd assert_almost_equal(vv, np.eye(100)) # check that the integral of 1 is correct assert_almost_equal(w.sum(), np.sqrt(np.pi))
def h_roots(n, method='newton'): ''' Returns the roots (x) of the nth order Hermite polynomial, H_n(x), and weights (w) to use in Gaussian Quadrature over [-inf,inf] with weighting function exp(-x**2). Parameters ---------- n : integer number of roots method : 'newton' or 'eigenvalue' uses Newton Raphson to find zeros of the Hermite polynomial (Fast) or eigenvalue of the jacobi matrix (Slow) to obtain the nodes and weights, respectively. Returns ------- x : ndarray roots w : ndarray weights Example ------- >>> import numpy as np >>> x, w = h_roots(10) >>> np.allclose(np.sum(x*w), -5.2516042729766621e-19) True See also -------- qrule, gaussq References ---------- [1] Golub, G. H. and Welsch, J. H. (1969) 'Calculation of Gaussian Quadrature Rules' Mathematics of Computation, vol 23,page 221-230, [2]. Stroud and Secrest (1966), 'gaussian quadrature formulas', prentice-hall, Englewood cliffs, n.j. ''' if not method.startswith('n'): return ort.h_roots(n) return _h_roots_newton(n)
def h_roots(n, method='newton'): ''' Returns the roots (x) of the nth order Hermite polynomial, H_n(x), and weights (w) to use in Gaussian Quadrature over [-inf,inf] with weighting function exp(-x**2). Parameters ---------- n : integer number of roots method : 'newton' or 'eigenvalue' uses Newton Raphson to find zeros of the Hermite polynomial (Fast) or eigenvalue of the jacobi matrix (Slow) to obtain the nodes and weights, respectively. Returns ------- x : ndarray roots w : ndarray weights Example ------- >>> import numpy as np >>> [x,w] = h_roots(10) >>> np.sum(x*w) -5.2516042729766621e-19 See also -------- qrule, gaussq References ---------- [1] Golub, G. H. and Welsch, J. H. (1969) 'Calculation of Gaussian Quadrature Rules' Mathematics of Computation, vol 23,page 221-230, [2]. Stroud and Secrest (1966), 'gaussian quadrature formulas', prentice-hall, Englewood cliffs, n.j. ''' if not method.startswith('n'): return ort.h_roots(n) else: sqrt = np.sqrt max_iter = 10 releps = 3e-14 C = [9.084064e-01, 5.214976e-02, 2.579930e-03, 3.986126e-03] # PIM4=0.7511255444649425 PIM4 = np.pi ** (-1. / 4) # The roots are symmetric about the origin, so we have to # find only half of them. m = int(np.fix((n + 1) / 2)) # Initial approximations to the roots go into z. anu = 2.0 * n + 1 rhs = np.arange(3, 4 * m, 4) * np.pi / anu r3 = rhs ** (1. / 3) r2 = r3 ** 2 theta = r3 * (C[0] + r2 * (C[1] + r2 * (C[2] + r2 * C[3]))) z = sqrt(anu) * np.cos(theta) L = zeros((3, len(z))) k0 = 0 kp1 = 1 for _its in xrange(max_iter): # Newtons method carried out simultaneously on the roots. L[k0, :] = 0 L[kp1, :] = PIM4 for j in xrange(1, n + 1): # Loop up the recurrence relation to get the Hermite # polynomials evaluated at z. km1 = k0 k0 = kp1 kp1 = np.mod(kp1 + 1, 3) L[kp1, :] = (z * sqrt(2 / j) * L[k0, :] - np.sqrt((j - 1) / j) * L[km1, :]) # L now contains the desired Hermite polynomials. # We next compute pp, the derivatives, # by the relation (4.5.21) using p2, the polynomials # of one lower order. pp = sqrt(2 * n) * L[k0, :] dz = L[kp1, :] / pp z = z - dz # Newtons formula. if not np.any(abs(dz) > releps): break else: warnings.warn('too many iterations!') x = np.empty(n) w = np.empty(n) x[0:m] = z # Store the root x[n - 1:n - m - 1:-1] = -z # and its symmetric counterpart. w[0:m] = 2. / pp ** 2 # Compute the weight w[n - 1:n - m - 1:-1] = w[0:m] # and its symmetric counterpart. return x, w
""" def a(self,i): return 0. def b(self,i): return 2. def c(self,i): return -2.*float(i-1) def quadrature(self,n): return so.h_roots(n) #print '' #print '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' #print '!!! WARNING: OrthogonalPolynomial was redefined for consistency with BasisFunction' #print '!!! now n is the order = maximal degree + 1 ' #print '!!! i.e. n is the number of functions (n was the degree before) ' #print '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' #print '' if __name__ == "__main__": """standalone: tests""" np.set_printoptions(linewidth=132) print 'Gauss-Hermit quadratur rules' for J in range(2,7): print 'x[',J,']=',so.h_roots(J)[0] print 'w[',J,']=',so.h_roots(J)[1] print 'Chebyshev' ChebyshevPolynomial().test(5) print 'Laguerre' LaguerrePolynomial().test(5) print 'Legendre' LegendrePolynomial().test(5) print 'Hermite' HermitePolynomial().test(5)
def h_roots(n, method='newton'): ''' Returns the roots (x) of the nth order Hermite polynomial, H_n(x), and weights (w) to use in Gaussian Quadrature over [-inf,inf] with weighting function exp(-x**2). Parameters ---------- n : integer number of roots method : 'newton' or 'eigenvalue' uses Newton Raphson to find zeros of the Hermite polynomial (Fast) or eigenvalue of the jacobi matrix (Slow) to obtain the nodes and weights, respectively. Returns ------- x : ndarray roots w : ndarray weights Example ------- >>> import numpy as np >>> [x,w] = h_roots(10) >>> np.sum(x*w) -5.2516042729766621e-19 See also -------- qrule, gaussq References ---------- [1] Golub, G. H. and Welsch, J. H. (1969) 'Calculation of Gaussian Quadrature Rules' Mathematics of Computation, vol 23,page 221-230, [2]. Stroud and Secrest (1966), 'gaussian quadrature formulas', prentice-hall, Englewood cliffs, n.j. ''' if not method.startswith('n'): return ort.h_roots(n) else: sqrt = np.sqrt max_iter = 10 releps = 3e-14 C = [9.084064e-01, 5.214976e-02, 2.579930e-03, 3.986126e-03] #PIM4=0.7511255444649425 PIM4 = np.pi ** (-1. / 4) # The roots are symmetric about the origin, so we have to # find only half of them. m = int(np.fix((n + 1) / 2)) # Initial approximations to the roots go into z. anu = 2.0 * n + 1 rhs = np.arange(3, 4 * m, 4) * np.pi / anu r3 = rhs ** (1. / 3) r2 = r3 ** 2 theta = r3 * (C[0] + r2 * (C[1] + r2 * (C[2] + r2 * C[3]))) z = sqrt(anu) * np.cos(theta) L = zeros((3, len(z))) k0 = 0 kp1 = 1 for _its in xrange(max_iter): #Newtons method carried out simultaneously on the roots. L[k0, :] = 0 L[kp1, :] = PIM4 for j in xrange(1, n + 1): #%Loop up the recurrence relation to get the Hermite #%polynomials evaluated at z. km1 = k0 k0 = kp1 kp1 = np.mod(kp1 + 1, 3) L[kp1, :] = z * sqrt(2 / j) * L[k0, :] - np.sqrt((j - 1) / j) * L[km1, :] # L now contains the desired Hermite polynomials. # We next compute pp, the derivatives, # by the relation (4.5.21) using p2, the polynomials # of one lower order. pp = sqrt(2 * n) * L[k0, :] dz = L[kp1, :] / pp z = z - dz # Newtons formula. if not np.any(abs(dz) > releps): break else: warnings.warn('too many iterations!') x = np.empty(n) w = np.empty(n) x[0:m] = z # Store the root x[n - 1:n - m - 1:-1] = -z # and its symmetric counterpart. w[0:m] = 2. / pp ** 2 # Compute the weight w[n - 1:n - m - 1:-1] = w[0:m] # and its symmetric counterpart. return x, w