高斯求积公式matlab程序_选择积分方法—高斯积分

无限区间 (1)梯形法则,(2)辛普森法则,(3)龙伯格积分法或(4)高斯积分法,有一些适用的指导原则。

通常,更高阶的方法对于平滑函数更好。 如果不是,那么使用更简单的方法会更好,因为数据的变化不会反映在采样点上。 梯形法则适用于在均匀间隔的采样点处积分来自实验的数据。 这对于表现不佳的函数是有好处的。 辛普森的规则依赖于被积函数的更高阶的近似,以便准确。 而高斯积分是非常准确的,如果你需要均匀间隔的采样点,它不是令人满意的。

高斯积分

######################################################################
#
# Functions to calculate integration points and weights for Gaussian
# quadrature
#
# x,w = gaussxw(N) returns integration points x and integration
#           weights w such that sum_i w[i]*f(x[i]) is the Nth-order
#           Gaussian approximation to the integral int_{-1}^1 f(x) dx
# x,w = gaussxwab(N,a,b) returns integration points and weights
#           mapped to the interval [a,b], so that sum_i w[i]*f(x[i])
#           is the Nth-order Gaussian approximation to the integral
#           int_a^b f(x) dx
#
# This code finds the zeros of the nth Legendre polynomial using
# Newton's method, starting from the approximation given in Abramowitz
# and Stegun 22.16.6.  The Legendre polynomial itself is evaluated
# using the recurrence relation given in Abramowitz and Stegun
# 22.7.10.  The function has been checked against other sources for
# values of N up to 1000.  It is compatible with version 2 and version
# 3 of Python.
#
# Written by Mark Newman , June 4, 2011
# You may use, share, or modify this file freely
#
##################%####################################################

from numpy import ones,copy,cos,tan,pi,linspace

def gaussxw(N):

    # Initial approximation to roots of the Legendre polynomial
    a = linspace(3,4*N-1,N)/(4*N+2)
    x = cos(pi*a+1/(8*N*N*tan(a)))

    # Find roots using Newton's method
    epsilon = 1e-15
    delta = 1.0
    while delta>epsilon:
        p0 = ones(N,float)
        p1 = copy(x)
        for k in range(1,N):
            p0,p1 = p1,((2*k+1)*x*p1-k*p0)/(k+1)
        dp = (N+1)*(p0-x*p1)/(1-x*x)
        dx = p1/dp
        x -= dx
        delta = max(abs(dx))

    # Calculate the weights
    w = 2*(N+1)*(N+1)/(N*N*(1-x*x)*dp*dp)

    return x,w

def gaussxwab(N,a,b):
    x,w = gaussxw(N)
    return 0.5*(b-a)*x+0.5*(b+a),0.5*(b-a)*w

计算实例

使用高斯积分的数值算法求解高斯积分

做积分变换

得到

from gaussxw import gaussxwab
from math import exp

def f(z):
    return exp(-z**2/(1-z)**2)/(1-z)**2

N = 50
a = 0.0
b = 1.0
x,w = gaussxwab(N,a,b)
s = 0.0
for k in range(N):
    s += w[k]*f(x[k])
print(s)

the value of the actual integral is √π/2, and Gaussian quadrature is accurate to machine precision.

Gaussian quadrature


重写基本积分公式(6.3)通常很有用,这样我们就可以将加权函数W(x)与被积函数分开:

高斯求积方法, N个点和权重选择的近似误差消失如果g (x)是一个(2 N-1)度多项式。为了得到这个不可思议的优化,点

最终在[a, b]上有一个特定的分布。一般情况下,如果g(x)是光滑的,或者可以通过提出一些W(x)来使其光滑(表6.2.4),那么对于相同数量的点,高斯算法将比梯形规则和辛普森规则产生更高的精度。有时被积函数可能不是光滑的,因为它在不同的区域有不同的行为。在这些情况下,分别对每个区域进行积分,然后将答案相加是有意义的。事实上,一些“智能”积分子例程决定使用多少个区间以及在每个区间中使用什么规则。

表6.2.4所示规则均为高斯分布,一般形式为(6.32)。我们可以看到,在一种情况下权重函数是指数函数,在另一种情况下是高斯函数,在几种情况下是可积分奇点。与等间距规则不同,在区间的极值处从来不存在积分点,而点的值和权值随着点的个数N的变化而变化。虽然我们将离开高斯点的推导和权重数值方法的引用,我们注意,对于普通高斯(Gauss-Legendre)积分,然后点易变成零的勒让德多项式,权重0相关的微分,

。在数学函数库中,生成这些点和权重的子例程是标准的,可以在[A&S 72]之类的表中找到,或者可以计算。我们提供的高斯子例程还将点缩放到指定区域。为了检查您的观点是否正确,您可能需要将它们与表6.1中的四点集进行比较。

映射积分点

高斯求积公式matlab程序_选择积分方法—高斯积分_第1张图片

高斯求积公式matlab程序_选择积分方法—高斯积分_第2张图片

Legendre polynomials勒让德多项式

高斯求积公式matlab程序_选择积分方法—高斯积分_第3张图片

高斯求积公式matlab程序_选择积分方法—高斯积分_第4张图片

高斯求积公式matlab程序_选择积分方法—高斯积分_第5张图片

高斯求积公式matlab程序_选择积分方法—高斯积分_第6张图片

高斯求积公式matlab程序_选择积分方法—高斯积分_第7张图片

高斯求积公式matlab程序_选择积分方法—高斯积分_第8张图片

高斯求积公式matlab程序_选择积分方法—高斯积分_第9张图片

GaussPoints.py

# GaussPoints.py: N point Gaussian quadrature pts & Wts generation

import numpy as np

def GaussPoints(Npts, a, b, x, w, eps):
    m = 0; i = 0; j = 0; t = 0.; t1 = 0.; pp = 0.
    p1 = 0.; p2 = 0.; p3 = 0.  
    m = int((Npts+1)/2)
    for i in range(1, m+1):
        t = np.cos(np.pi*(float(i)-0.25)/(float(Npts)+0.5))
        t1 = 1 
        while((abs(t-t1)) >=  eps):
            p1 = 1. ;  p2 = 0.  
            for j in range(1, Npts + 1):
                p3 = p2;   p2 = p1 
                p1 = ((2.*float(j)-1)*t*p2 - (float(j)-1.)*p3)/(float(j))
            pp = Npts*(t*p1 - p2)/(t*t - 1.) 
            t1 = t
            t = t1 - p1/pp
        x[i-1] =  -t
        x[Npts-i] = t 
        w[i-1] = 2./( (1.-t*t)*pp*pp) 
        w[Npts-i] = w[i-1]
        
    for j in range(0, Npts):               # Scale [-1,+1] to [a,b]
            x[j] = x[j]*(b-a)/2. + (b+a)/2. 
            w[j] = w[j]*(b-a)/2. 
from numpy import *;  from GaussPoints import GaussPoints

Npts = 10; Ans = 0;  a = 0.;  b = 1.;  eps = 3.E-14
w = zeros(2001, float);  x = zeros(2001, float)       # Arrays

def f(x):  return exp(x)                           # Integrand 

GaussPoints(Npts, a, b, x, w, eps)      #  eps: precison of pts  
for i in  range(0,Npts): Ans += f(x[i])*w[i]   # Sum integrands
print ('n Npts =', Npts, ',   Ans =', Ans)
print (' eps =',eps, ', Error =', Ans-(exp(1)-1) )

你可能感兴趣的:(高斯求积公式matlab程序)