(整理)复化梯形法复化矩形法变步长梯形变步长辛普森
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
陕西科技大学
机械教改班
用C++的积分
其实积分的思想就是,微分—>求和—>取极限,如果是用纯手工法那就是先对一个函数微分,再求出它的面积,在取极限,因为我们的计算速度和计算量有限,现在有了计算机这个速度很快的机器,我们可以把微分后的每个小的面积加起来,为了满足精度,我们可以加大分区,即使实现不了微分出无限小的极限情况,我们也至少可以用有限次去接近他,下面我分析了四种不同的积分方法,和一个综合通用程序。
一.积分的基本思想
1、思路:微分—>求和—>取极限。
2、Newton —Leibniz 公式 ⎰-=b
a a F
b F dx x f )
()()( 其中,)(x F 被积函数
)(x f 的原函数。 3、用计算机积分的思路
在积分区间内“微分—>求和—>控制精度”。因为计算机求和不可以取极限,也就是不可以无限次的加下去,所以要控制精度。
二.现有的理论
1、一阶求积公式---梯形公式
⎰=+-=b a T b f a f a b dx x f )]()([2
)( 他只能精确计算被积函数为0、1次多项式时的积分。 2、二阶求积分公式——牛顿、科特斯公式 ⎰=+++-=b
a S
b f a b f a f a b dx x f )]()2(4)([6)(
他只能精确计算被积函数为0、1、2、3次多项式时的积分。
三.四种实现方法
1.复化矩形法
将积分区间[a,b]等分成n 个子区间:
],[],[],[],[],[112322110n n n n x x x x x x x x x x ---、、、 则h=(b-a)/n,区间端点值k x =a+kh
)hf(x ))f(x x (x I 11121=-=
)()()x (22232x hf x f x I =-=
............................
)()()(111n ---=-=n n n n x hf x f x x I
∑==n
i i x hf T 1n )(
源程序:
#include
#include
double f(double x) //计算被积函数
{
double y;
y=log(1+x)/(1+x*x); //被积函数
return y;
}
double Tn(double a,double b,int n) //求Tn
{
double t=0.0;
double xk; //区间端点值
double t1,t2; //用来判断精度
do
{
double h=(b-a)/n;
for(int k=1;k<=n-1;k++) //每一小段的矩形叠加
{
t1=t;
xk=a+k*h;
t+=h*f(xk);
t2=t;
}
n++; //如果精度不够就对区间再次细分,直到达到精度要求 }
while(fabs(t1-t2)<=1e-7); //判断计算精度
return t;
}
void main()
{
double a=0.0; //积分下线
double b=2.0; //积分上限
int n=1024; //把区间分为1024段
cout< } 执行结果: 2.复化梯形法 方法和复化矩形法类似,只是把原来的矩形小面积变成了梯形小面积,但是精确度明显提高了,也就是说达到同样的精度需要的时间少了。 ⎥⎦⎤⎢⎣⎡++=∑∑-==111)(2)()(2n k k n i i x f b f a f h I 变形一下: ∑-=++=11 n )()]()([21n k k x f h b f a f h T 源程序: #include #include double f(double x) //计算被积函数 { double y; y=log(1+x)/(1+x*x); //被积函数 return y; } double Tn(double a,double b,int n) //求Tn { double t=0.0; double xk; //区间端点值 double t1,t2,h=(b-a)/n; //用来判断精度 do { h=(b-a)/n; for(int k=1;k<=n-1;k++) //余项叠加,相当于每一个小梯形相加 { t1=t; xk=a+k*h; t+=f(xk); t2=t; } n++; //如果精度不够就对区间再次细分,直到达到精度要求 } while(fabs(t1-t2)<=1e-7); //判断计算精度 t=h*(f(a)+f(b))/2+t*h; //加上初项就是积分结果了 return t; } void main() { double a=0.0; //积分下线 double b=2.0; //积分上线 int n=1024; //把区间分为1024段 cout< } 执行结果: 3.变步长梯形法 上面我们在应用复化积分法的时候会对区间进行分割,但是在要求精度是我们也不知道事先应该分割成多少段,分的少了精度达不到,分的多了计算量太大,为了解决这个问题我在上面加了一个循环,来不断地对区间进行再次划分,直到达到精度要求,变步长积分法与我用的方法类似,只不过变步长积分法的区间划分时成倍增加的。 实现方法; 由复化梯形法知道; ∑-=++=11 n )()]()([21n k k x f h b f a f h T 步长h=(b-a)/n 现在将步长分半,即在相邻两节点[]1,+k k x x 的中点)(2 1121 +++=k k k x x x 处增加一个求积节点,那么 []∑∑-=+-=⋅+⋅++=102 1112)(2)(24)()(n k k n n k k n n n x f h x f h b f a f h T 变形一下: