C++ 数值积分.docx
《C++ 数值积分.docx》由会员分享,可在线阅读,更多相关《C++ 数值积分.docx(8页珍藏版)》请在冰豆网上搜索。
C++数值积分
一、数值积分(定积分)的基本思想
1、定积分的意义:
细分—求和—取极限。
2、Newton—Leibniz公式
其中,
被积函数
的原函数。
3、数值积分的基本思想
在积分区间内“细分—求和—控制精度”。
数值积分是通过计算机进行的,不可以取极限,否则出现时间无限情况。
不取极限的积分是不精确的,因此需要进行精度控制。
二、实用的Newton—Cotes求积公式
牛顿、科特斯是两位伟大的科学家,他们在数值积分领域也做出了伟大的贡献,他们导出了任意阶的牛顿—科特斯求积公式。
其中最简单的两个公式具有非常实用的价值。
1、一阶Newton—Cotes求积公式
一阶Newton—Cotes求积公式也叫梯形公式,它具有一次代数精度,也就是说,只有当被积函数是0次或1次多项式时(直线),该公式是精确的,在其它情况下只是近似解。
2、二阶Newton—Cotes求积公式
二阶Newton—Cotes求积公式也叫Simposon公式,它具有三次代数精度,也就是说,只有当被积函数是0次、1次、2次、3次多项式时,该公式是精确的,在其它情况下只是近似解。
另有:
四阶Newton—Cotes求积公式定名为Cotes求积公式,也是实用的求积公式。
三、复化梯形求积公式及其程序设计
1、算法:
将积分区间[a,b]等分成n个子区间:
其中:
然后,在每个子区间上使用梯形求积公式计算积分值,再将这些积分值求和就是总的积分值。
…………………………………………
即:
2、程序设计思路
1)设计一个函数用来计算被积函数值。
2)设计一个函数实现复化梯形求积
3)主函数中进行数据准备、函数调用、结果输出。
3、源程序:
#include
doublef(doublex)
{
doubley;
y=x*x*x;
returny;
}
doubletn(doublea,doubleb,intn)
{
doubleh=(b-a)/n;
doublet=0.0;
doublexk;
for(intk=1;k<=n-1;k++)
{
xk=a+k*h;
t+=f(xk);
}
t=h*(f(a)+f(b))/2+t*h;
returnt;
}
voidmain()
{
doublea=0.0;
doubleb=4.0;
intn=1024;
cout<}
四、变步长梯形求积及其程序设计
在采用复化梯形求积时,要求将积分区间划分成若干个子区间,然后在每个子区间上应用梯形求积公式并求和。
从“积分精度”的角度来看,我们希望积分子区间的长度越小越好,当积分区间达到无穷小时,就是理论上的精确积分值。
从程序的“运行效率”角度来看,我们又希望积分子区间的长度不能太小,否则计算工作量“太大”。
合适选择子区间的大小,可以兼顾“积分精度”和“计算效率”两方面的要求。
然而,对于给定的精度要求,事先确定子区间的长度也是很困难的。
例如,对于上例,当要求精确到小数点后面3位时,划分多少个子区间合适?
当要求精确到小数点后面6位时,又应该划分多少个子区间合适?
这样的问题很难回答。
但“变步长梯形求积”可以解决上述问题。
1、积分区间n等分时的复化梯形求积公式
设对积分区间[a,b]进行n等分,则步长
,在该积分区间上共有n+1个求积结点:
。
由复化梯形公式有:
2、积分区间2n等分时的复化梯形求积公式
在上述情况下,若将步长分半,即在每相邻两结点
的中点
处增加一个求积结点,则:
3、n等分与2n等分求积的关系
4、程序设计思路
1)设计一个函数用来计算被积函数值。
2)设计一个函数实现变步长梯形求积:
步长变化:
,
,
,…。
积分停止:
当相邻两次的积分值足够接近。
有时有附加条件:
至少要几分区间。
3)主函数中进行数据准备、函数调用、结果输出。
#include
#include
doublef(doublex)
{
doubley;
y=x*x*x;
returny;
}
doublet2ntn(doublea,doubleb)
{
intn=1;
doublehn=b-a;
doubletn=0.0;
doublet2n=(f(a)+f(b))*hn/2.0;
while(fabs(t2n-tn)>1e-6)
{
tn=t2n;
t2n=0.0;
for(intk=0;k<=n-1;k++)
t2n+=f(a+hn/2.0+k*hn);
t2n=tn/2.0+t2n*hn/2.0;
n=n*2;
hn=hn/2.0;
}
returnt2n;
}
voidmain()
{
doublea=0.0;
doubleb=4.0;
cout<}
五、复化Simposon求积及其程序设计
1、算法:
将积分区间[a,b]等分成n个子区间:
其中:
然后,在每个子区间上使用Simposon求积公式计算积分值,再将这些积分值求和就是总的积分值。
………………………………
即:
2、程序设计思路
1)设计一个函数用来计算被积函数值。
2)设计一个函数实现复化Simposon求积
3)主函数中进行数据准备、函数调用、结果输出。
课堂练习:
写出实现复化Simposon求积算法的源程序
#include
doublef(doublex)
{
doubley;
y=x*x*x;
returny;
}
doublesn(doublea,doubleb,intn)
{
doubleh=(b-a)/n;
doublesk=0.0,sk2=0.0;
doublexk;
doublexk2;
for(intk=1;k<=n-1;k++)
{
xk=a+k*h;
sk+=f(xk);
}
for(k=0;k<=n-1;k++)
{
xk2=a+k*h+0.5*h;
sk2+=f(xk2);
}
returnh/6.0*(f(a)+f(b)+2.0*sk+4.0*sk2);
}
voidmain()
{
doublea=0.0;
doubleb=4.0;
intn=1024;
cout<}