目录
0、引言
一、数值积分的积分思想
1、中矩形公式
2、梯形公式
3、辛普森公式
二、求积公式的余项和代数精度
三、插值型求积公式
四、牛顿--柯特斯公式 (N-C公式)
五、复化求积法
1、复化梯形公式
2、复化辛普森公式 (要求 n 为偶数)
六、代码实现
0、引言
在高数中,可以根据
,求得积分。但是如果
存在以下两种情况:
-
是离散函数
- 无法求得原函数
那么对于这种情况,就可以利用数值积分。
所谓数值积分,指利用被积函数
在有限个点上的函数值来计算积分近似值的一种方法。
一、数值积分的积分思想
积分中值定理: ![\int_{a}^{b}f(x)dx = (b-a)f(\xi ),\xi \in [a,b]](https://private.codecogs.com/gif.latex?%5Cint_%7Ba%7D%5E%7Bb%7Df%28x%29dx%20%3D%20%28b-a%29f%28%5Cxi%20%29%2C%5Cxi%20%5Cin%20%5Ba%2Cb%5D)
一重积分可以理解为求面积,积分中值定理可以看成:在
上,函数
与
轴的面积等于以
为长,
中一点函数值
为宽的矩形的面积。
![](https://img-blog.csdnimg.cn/202002181110377.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3MjY0MzIz,size_16,color_FFFFFF,t_70)
1、中矩形公式
![\int_{a}^{b}f(x)dx \approx (b-a)\cdot f(\frac{a+b}{2})](https://private.codecogs.com/gif.latex?%5Cint_%7Ba%7D%5E%7Bb%7Df%28x%29dx%20%5Capprox%20%28b-a%29%5Ccdot%20f%28%5Cfrac%7Ba+b%7D%7B2%7D%29)
2、梯形公式
![\int_{a}^{b}f(x)dx\approx (b-a)\cdot \frac{f(a)+f(b)}{2}](https://private.codecogs.com/gif.latex?%5Cint_%7Ba%7D%5E%7Bb%7Df%28x%29dx%5Capprox%20%28b-a%29%5Ccdot%20%5Cfrac%7Bf%28a%29+f%28b%29%7D%7B2%7D)
3、辛普森公式
![\int_{a}^{b}f(x)dx\approx (b-a)\cdot \frac{1}{6}[f(a)+4f(\frac{a+b}{2})+f(b)]](https://private.codecogs.com/gif.latex?%5Cint_%7Ba%7D%5E%7Bb%7Df%28x%29dx%5Capprox%20%28b-a%29%5Ccdot%20%5Cfrac%7B1%7D%7B6%7D%5Bf%28a%29+4f%28%5Cfrac%7Ba+b%7D%7B2%7D%29+f%28b%29%5D)
一般情况下,可用: ![f(\xi )\approx \sum_{k=0}^{n}w_{k}\cdot f(x_{k})](https://private.codecogs.com/gif.latex?f%28%5Cxi%20%29%5Capprox%20%5Csum_%7Bk%3D0%7D%5E%7Bn%7Dw_%7Bk%7D%5Ccdot%20f%28x_%7Bk%7D%29)
,其中
。
上式称为数值积分的基本公式,
称为求积节点,
称为求积系数。
二、求积公式的余项和代数精度
1、余项
![R\begin{bmatrix} f \end{bmatrix}=\int_{a}^{b}f(x)dx-\sum_{k=0}^{n}A_{k}\cdot f(x_{k})](https://private.codecogs.com/gif.latex?R%5Cbegin%7Bbmatrix%7D%20f%20%5Cend%7Bbmatrix%7D%3D%5Cint_%7Ba%7D%5E%7Bb%7Df%28x%29dx-%5Csum_%7Bk%3D0%7D%5E%7Bn%7DA_%7Bk%7D%5Ccdot%20f%28x_%7Bk%7D%29)
2、代数精度
若数值积分公式对任意的
次的代数多项式都准确成立,而对于
却不能成立,则称该数值积分公式的代数精度为
。
举个例子理解一下: 求梯形公式的代数精度。
解: ![\int_{a}^{b}f(x)dx\approx (b-a)\cdot \frac{f(a)+f(b)}{2}](https://private.codecogs.com/gif.latex?%5Cint_%7Ba%7D%5E%7Bb%7Df%28x%29dx%5Capprox%20%28b-a%29%5Ccdot%20%5Cfrac%7Bf%28a%29+f%28b%29%7D%7B2%7D)
- 当
,
- 当
,
- 当
,
;![](https://private.codecogs.com/gif.latex?)
梯形公式的代数精度为1。
定理:含有 n+1 个节点的插值型数值积分公式的代数精度至少为 n 。
三、插值型求积公式
已知
则拉格朗日插值可表示为:
,
为 基函数。
![\therefore \int_{a}^{b}f(x)dx \approx \int_{a}^{b}L_{n}(x)\cdot dx](https://private.codecogs.com/gif.latex?%5Ctherefore%20%5Cint_%7Ba%7D%5E%7Bb%7Df%28x%29dx%20%5Capprox%20%5Cint_%7Ba%7D%5E%7Bb%7DL_%7Bn%7D%28x%29%5Ccdot%20dx)
![= \int_{a}^{b}\sum_{k}^{n}f(x_{k})\cdot l_{k}(x)\cdot dx](https://private.codecogs.com/gif.latex?%3D%20%5Cint_%7Ba%7D%5E%7Bb%7D%5Csum_%7Bk%7D%5E%7Bn%7Df%28x_%7Bk%7D%29%5Ccdot%20l_%7Bk%7D%28x%29%5Ccdot%20dx)
![= \sum f(x_{k})\cdot \int_{a}^{b}l_{k}(x)dx](https://private.codecogs.com/gif.latex?%3D%20%5Csum%20f%28x_%7Bk%7D%29%5Ccdot%20%5Cint_%7Ba%7D%5E%7Bb%7Dl_%7Bk%7D%28x%29dx)
![= \sum A_{k}\cdot f(x_{k})](https://private.codecogs.com/gif.latex?%3D%20%5Csum%20A_%7Bk%7D%5Ccdot%20f%28x_%7Bk%7D%29)
即为 插值型求积公式。其中 ![A_{k}=\int_{a}^{b}l_{k}(x)dx](https://private.codecogs.com/gif.latex?A_%7Bk%7D%3D%5Cint_%7Ba%7D%5E%7Bb%7Dl_%7Bk%7D%28x%29dx)
四、牛顿--柯特斯公式 (N-C公式)
牛顿-柯斯特求积公式是插值型求积公式的特殊形式,在插值型求积公式中所取节点是等距时称为牛顿-柯斯特公式。
即,N-C公式为等距节点的插值型求积公式。
![](https://img-blog.csdnimg.cn/20200218181027818.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3MjY0MzIz,size_16,color_FFFFFF,t_70)
在[
区间内设置等距的插值节点
.
设节点步长为
则节点 ![x_{k}=a+k\cdot h ,(k=0,1,\cdots ,n)](https://private.codecogs.com/gif.latex?x_%7Bk%7D%3Da+k%5Ccdot%20h%20%2C%28k%3D0%2C1%2C%5Ccdots%20%2Cn%29)
,有
![(0\leq t\leq n)](https://private.codecogs.com/gif.latex?%280%5Cleq%20t%5Cleq%20n%29)
则插值型求积系数:
![A_{k}=\int_{a}^{b}l_{k}(x)dx =\int_{a}^{b}\prod_{j=0;j\neq k}^{n}\frac{x-x_{j}}{x_{k}-x_{j}}dx](https://private.codecogs.com/gif.latex?A_%7Bk%7D%3D%5Cint_%7Ba%7D%5E%7Bb%7Dl_%7Bk%7D%28x%29dx%20%3D%5Cint_%7Ba%7D%5E%7Bb%7D%5Cprod_%7Bj%3D0%3Bj%5Cneq%20k%7D%5E%7Bn%7D%5Cfrac%7Bx-x_%7Bj%7D%7D%7Bx_%7Bk%7D-x_%7Bj%7D%7Ddx)
变量由
,所以变量范围由
;![dx = h\cdot dt](https://private.codecogs.com/gif.latex?dx%20%3D%20h%5Ccdot%20dt)
![=\int_{0}^{n}\prod_{j=0;j\neq k}^{n}\frac{t-j}{k-j}\cdot hdt](https://private.codecogs.com/gif.latex?%3D%5Cint_%7B0%7D%5E%7Bn%7D%5Cprod_%7Bj%3D0%3Bj%5Cneq%20k%7D%5E%7Bn%7D%5Cfrac%7Bt-j%7D%7Bk-j%7D%5Ccdot%20hdt)
,与
无关的提到积分号之外
![=\frac{h}{k(k-1)\cdots 1(-1)(-2)\cdots (-(n-k))}\int_{0}^{n}\prod_{j=0;j\neq k}^{n}(t-j)\cdot dt](https://private.codecogs.com/gif.latex?%3D%5Cfrac%7Bh%7D%7Bk%28k-1%29%5Ccdots%201%28-1%29%28-2%29%5Ccdots%20%28-%28n-k%29%29%7D%5Cint_%7B0%7D%5E%7Bn%7D%5Cprod_%7Bj%3D0%3Bj%5Cneq%20k%7D%5E%7Bn%7D%28t-j%29%5Ccdot%20dt)
![=\frac{\frac{b-a}{n}}{k!(n-k)!}(-1)^{n-k}\int_{0}^{n}\prod_{j=0;j\neq k}^{n}(t-j)\cdot dt](https://private.codecogs.com/gif.latex?%3D%5Cfrac%7B%5Cfrac%7Bb-a%7D%7Bn%7D%7D%7Bk%21%28n-k%29%21%7D%28-1%29%5E%7Bn-k%7D%5Cint_%7B0%7D%5E%7Bn%7D%5Cprod_%7Bj%3D0%3Bj%5Cneq%20k%7D%5E%7Bn%7D%28t-j%29%5Ccdot%20dt)
![=(b-a)\frac{(-1)^{n-k}}{k!(n-k)!\cdot n}\int_{0}^{n}\prod_{j=0;j\neq k}^{n}(t-j)\cdot dt](https://private.codecogs.com/gif.latex?%3D%28b-a%29%5Cfrac%7B%28-1%29%5E%7Bn-k%7D%7D%7Bk%21%28n-k%29%21%5Ccdot%20n%7D%5Cint_%7B0%7D%5E%7Bn%7D%5Cprod_%7Bj%3D0%3Bj%5Cneq%20k%7D%5E%7Bn%7D%28t-j%29%5Ccdot%20dt)
因为
只与
有关,与
,步长
均无关
而该表达式称之为柯斯特求积系数,记为
![C_{k}^{(n)}=\frac{(-1)^{n-k}}{k!(n-k)!\cdot n}\int_{0}^{n}\prod_{j=0;j\neq k}^{n}(t-j)\cdot dt](https://private.codecogs.com/gif.latex?C_%7Bk%7D%5E%7B%28n%29%7D%3D%5Cfrac%7B%28-1%29%5E%7Bn-k%7D%7D%7Bk%21%28n-k%29%21%5Ccdot%20n%7D%5Cint_%7B0%7D%5E%7Bn%7D%5Cprod_%7Bj%3D0%3Bj%5Cneq%20k%7D%5E%7Bn%7D%28t-j%29%5Ccdot%20dt)
求积系数 ![A_{k} = (b-a)C_{k}^{(n)}](https://private.codecogs.com/gif.latex?A_%7Bk%7D%20%3D%20%28b-a%29C_%7Bk%7D%5E%7B%28n%29%7D)
N-C公式为:![\int_{a}^{b}f(x)dx = \sum_{k=0}^{n}A_{k}\cdot f(x_{k})=(b-a)\sum_{k=0}^{n}C_{k}^{(n)}\cdot f(x_{k})](https://private.codecogs.com/gif.latex?%5Cint_%7Ba%7D%5E%7Bb%7Df%28x%29dx%20%3D%20%5Csum_%7Bk%3D0%7D%5E%7Bn%7DA_%7Bk%7D%5Ccdot%20f%28x_%7Bk%7D%29%3D%28b-a%29%5Csum_%7Bk%3D0%7D%5E%7Bn%7DC_%7Bk%7D%5E%7B%28n%29%7D%5Ccdot%20f%28x_%7Bk%7D%29)
1、n = 1 (梯形公式)
![C_{k=0}^{(1)}=\frac{(-1)^{1-0}}{0!(1-0)!\cdot 1}\int_{0}^{1}(t-1)dt=\frac{1}{2}](https://private.codecogs.com/gif.latex?C_%7Bk%3D0%7D%5E%7B%281%29%7D%3D%5Cfrac%7B%28-1%29%5E%7B1-0%7D%7D%7B0%21%281-0%29%21%5Ccdot%201%7D%5Cint_%7B0%7D%5E%7B1%7D%28t-1%29dt%3D%5Cfrac%7B1%7D%7B2%7D)
![C_{k=1}^{(1)}=\frac{(-1)^{1-1}}{1!(1-1)!\cdot 1}\int_{0}^{1}(t-0)dt=\frac{1}{2}](https://private.codecogs.com/gif.latex?C_%7Bk%3D1%7D%5E%7B%281%29%7D%3D%5Cfrac%7B%28-1%29%5E%7B1-1%7D%7D%7B1%21%281-1%29%21%5Ccdot%201%7D%5Cint_%7B0%7D%5E%7B1%7D%28t-0%29dt%3D%5Cfrac%7B1%7D%7B2%7D)
就变成了梯形公式
2、n = 2 (辛普森公式)
,
,![C_{k=2}^{2} = \frac{1}{6}](https://private.codecogs.com/gif.latex?C_%7Bk%3D2%7D%5E%7B2%7D%20%3D%20%5Cfrac%7B1%7D%7B6%7D)
![\therefore \int_{a}^{b}f(x)dx = (b-a)\begin{bmatrix} \frac{1}{6}f(x_{0}+\frac{4}{6}f(x_{1})+\frac{1}{6}f(x_{2}) \end{bmatrix}](https://private.codecogs.com/gif.latex?%5Ctherefore%20%5Cint_%7Ba%7D%5E%7Bb%7Df%28x%29dx%20%3D%20%28b-a%29%5Cbegin%7Bbmatrix%7D%20%5Cfrac%7B1%7D%7B6%7Df%28x_%7B0%7D+%5Cfrac%7B4%7D%7B6%7Df%28x_%7B1%7D%29+%5Cfrac%7B1%7D%7B6%7Df%28x_%7B2%7D%29%20%5Cend%7Bbmatrix%7D)
辛普森公式
3、n=4
,其中 ![x_{k} = a+k\cdot \frac{b-a}{4}](https://private.codecogs.com/gif.latex?x_%7Bk%7D%20%3D%20a+k%5Ccdot%20%5Cfrac%7Bb-a%7D%7B4%7D)
五、复化求积法
当积分区间较大时,C-N求积公式的误差会很大。为减少误差,可以考虑增加节点,但用高次多项式插值导出的公式稳定性不好。所以可以考虑用分段插值函数来代替被积函数。
把
分成n 个区间
,然后给每个区间上用低阶N-C公式求积(设为
),则
![\int_{a}^{b}f(x)dx \approx \sum_{k=1}^{n}I_{k}](https://private.codecogs.com/gif.latex?%5Cint_%7Ba%7D%5E%7Bb%7Df%28x%29dx%20%5Capprox%20%5Csum_%7Bk%3D1%7D%5E%7Bn%7DI_%7Bk%7D)
1、复化梯形公式
![T_{n}= \frac{h}{2}[f(x_{0})+f(x_{1})] + \frac{h}{2}[f(x_{1})+f(x_{2})] + \cdots + \frac{h}{2}[f(x_{n-1})+f(x_{n})]](https://private.codecogs.com/gif.latex?T_%7Bn%7D%3D%20%5Cfrac%7Bh%7D%7B2%7D%5Bf%28x_%7B0%7D%29+f%28x_%7B1%7D%29%5D%20+%20%5Cfrac%7Bh%7D%7B2%7D%5Bf%28x_%7B1%7D%29+f%28x_%7B2%7D%29%5D%20+%20%5Ccdots%20+%20%5Cfrac%7Bh%7D%7B2%7D%5Bf%28x_%7Bn-1%7D%29+f%28x_%7Bn%7D%29%5D)
,其中![h = \frac{b-a}{n}](https://private.codecogs.com/gif.latex?h%20%3D%20%5Cfrac%7Bb-a%7D%7Bn%7D)
拓展:变步长梯形公式
定步长复化求积公式的一个明显缺点是:事先很难估计分划数n使结果达到预期精度。由于适当加密分点,精度会有所改善,为此采用自动加密分点的方法,并利用事后估计来控制加密次数,以判断是否达到预期精度,从而停止计算。
- 对所有已存在的子区间进行二分化,区间数由n变为2n
- 利用区间数为n时的积分值Tn以及新增的节点(即原来各子区间的中点)递推出区间数为2n时的积分值T2n
- 利用两次计算结果的差来估计误差,直到满足精度
公式如下:
,其中 ![H_{n}(h) = h\sum_{k=0}^{n-1}f(a+(k+\frac{1}{2})h)](https://private.codecogs.com/gif.latex?H_%7Bn%7D%28h%29%20%3D%20h%5Csum_%7Bk%3D0%7D%5E%7Bn-1%7Df%28a+%28k+%5Cfrac%7B1%7D%7B2%7D%29h%29)
2、复化辛普森公式 (要求 n 为偶数)
,其中![m = \frac{n}{2}](https://private.codecogs.com/gif.latex?m%20%3D%20%5Cfrac%7Bn%7D%7B2%7D)
六、代码实现
1、C++实现
先计算一个简单的,可以求原函数的。如
,标准答案为
。程序运行结果为:
![](https://img-blog.csdnimg.cn/2020021917193953.png)
可以看出,复化公式的精度更高一些。
现在,如果要求原函数不可求的,如
,程序结果为:
![](https://img-blog.csdnimg.cn/20200219172438416.png)
C++代码:
main文件
#include<iostream>
#include"integral.h"
#include<iomanip>
using namespace std;
const double eps = 1e-8;
int main()
{
double resultT = T(fun2, 1, 2);
cout << "梯形公式计算结果" << "\t" << setprecision(8) << resultT << endl;
double resultS = S(fun2, 1, 2);
cout << "辛普森公式计算结果" << "\t" << setprecision(8) << resultS << endl;
double resultTn = Tn(fun2, 1, 2, 100);
cout << "复化梯形公式计算结果" << "\t" << setprecision(8) << resultTn << endl;
double resultT2n = T2n(fun2, 1, 2, eps);
cout << "变步长梯形公式计算结果" << "\t" << setprecision(8) << resultT2n << endl;
cout << endl;
double resultSn = Sn(fun2, 1, 2);
cout << "复化辛普森公式计算结果" << "\t" << setprecision(8) << resultSn << endl;
}
.h头文件(积分实现部分)
#pragma once
#include<iostream>
using namespace std;
double fun1(double x) {
double y = 1 / x;
return y;
}
double fun2(double x) {
double y = log(3 + pow(x,2)) / (1 + pow(x, 2));
return y;
}
//梯形公式
double T(double(*f)(double), double a, double b) {
double result = 0.0;
result = 0.5 * (b - a) * (f(a) + f(b));
return result;
}
//辛普森公式
double S(double(*f)(double), double a, double b) {
double result = 0.0;
result = 1 / 6.0 * (b - a) * ( f(a) + f(b) + 4 * f( (a + b) / 2.0) );
return result;
}
//复化梯形公式
double Tn(double(*f)(double), double a, double b, int n) {
double result = 0.0;
double h = (b - a) / n;
result = h / 2.0 * (f(a) + f(b));
for (int k = 1; k < n; k++) {
double x = a + k * h;
result += h * f(x);
}
return result;
}
//变步长梯形积分
double T2n(double(*f)(double), double a, double b, double error) {
int n = 1;
double h = (b - a) / n;
double Tn = (f(a) + f(b)) * h / 2.0; //计算 n=1 时的积分,粗略值
double T2n; //步长变为一半后的积分值
bool key = false;
do { //至少循环一次
double Hn = 0.0;
for (int k = 0; k < n; k++) {
double x = a + (k + 0.5) * h;
Hn += h * f(x);
}
T2n = (Tn + Hn) / 2.0;
//判断误差
if (fabs(Tn - T2n) < error) {
key = true;
}
else {
Tn = T2n;
n *= 2;
h /= 2;
}
} while (!key);
return T2n;
}
//复化辛普森公式
double Sn(double(*f)(double), double a, double b) {
int n;
cout << "正在使用复化辛普森公式,请输入分段个数n, 要求为偶数。 n =";
cin >> n;
/*cout << endl;*/
while (n % 2) {
cout << "输入n要求为偶数,请重新输入, n = ";
cin >> n;
cout << endl;
}
double result = 0.0;
double h = (b - a) / n;
result = h / 3.0 * (f(a) + f(b));
for (int k = 1; k < n; k++) {
double x = a + k * h;
if (k % 2 == 0) {
result += h / 3.0 * 2 * f(x);
}
else {
result += h / 3.0 * 4 * f(x);
}
}
return result;
}
2、matlab实现
matlab中自带了函数,例如,
函数、
函数。