复化梯形法-复化矩形法-变步长梯形-变步长辛普森.docx
陕西科技大学切城教成斑用C+的积分其实积分的思想就是,微分一求和取极限,如果是用纯手工法那就是先对一个函数微分,再求出它的面积,在取极限,因为我们的计算速度和计算量有限,现在有了计算机这个速度很快的机器,我们可以把微分后的每个小的面积加起来,为了满足精度,我们可以加大分区,即使实现不了微分出无限小的极限情况,我们也至少可以用有限次去接近他,下面我分析了四种不同的积分方法,和一个综合通用程序。积分的根本思想1、思路:微分一求和一取极限。2、NewtonLeibniz公式其中,E(X)被积函数/()的原函数。3,用计算机积分的思路在积分区间内“微分一求和一控制精度"。因为计算机求和不可以取极限,也就是不可以无限次的加下去,所以要控制精度。二.现有的理论1、一阶求积公式梯形公式他只能精确计算被积函数为0、1次多项式时的积分。2、二阶求积分公式一一牛顿、科特斯公式他只能精确计算被积函数为0、1、2、3次多项式时的积分。三.四种实现方法1复化矩形法将积分区间a,b等分成n个子区间:那么h=(b-a)n,区间端点值Xk=a+kh源程序:#include<iostream,h>#include<math.h>doublef(doublex)计算被积函数doubley;y=log(l+x)(l+x*x):被积函数returny:doubleTn(doublea,doubleb,intn)求Tndoublet=0.0;doublexk;区间端点值doubletl,t2;用来判断精度dodoubleh=(b-a)n;for(intk=l;k<=n-l;k+)每一小段的矩形叠加tl=t;xk=a+k*h;t+=h*f(xk);t2=t;n+;如果精度不够就对区间再次细分,直到到达精度要求while(fabs(tl-t2)<=le-7);判断计算精度returnt;voidmain()doublea=0.0;积分下线doubleb=2.0;积分上限intn=1024;把区间分为1024段cout«Tn(a,b,n)<<endl;输出积分结果执行结果:2复化梯形法方法和复化矩形法类似,只是把原来的矩形小面积变成了梯形小面积,但是精确度明显提高了,也就是说到达同样的精度需要的时间少了。变形一下:源程序:include<iostream,h>#include<math.h>doublef(doublex)计算被积函数doubley;y=log(l+x)(l+x*x);被积函数returny:doubleTn(doublea,doubleb,intn)求Tndoublet=0.0;doublexk;区间端点值doubletl,t2,h=(b-a)n;用来判断精度doh=(b-a)/n;for(intk=l:k<=n-l:k+)余项叠加,相当于每一个小梯形相加tl=t;xk=a+k*h;t+=f(xk);t2=t;n+;如果精度不够就对区间再次细分,直到到达精度要求while(fabs(tl-t2)<=le-7);判断计算精度t=h*(f(a)+f(b)2+t*h;加上初项就是积分结果了returnt;voidmain()积分下线积分上线把区间分为1024段doublea=0.0;doubleb=2.0;intn=1024;cout«Tn(a,b,n)<<endl;输出积分结果执行结果:3 .变步长梯形法上面我们在应用复化积分法的时候会对区间进行分割,但是在要求精度是我们也不知道事先应该分割成多少段,分的少了精度达不到,分的多了计算量太大,为了解决这个问题我在上面加了一个循环,来不断地对区间进行再次划分,直到到达精度要求,变步长积分法与我用的方法类似,只不过变步长积分法的区间划分时成倍增加的。实现方法;由复化梯形法知道;步长h=(b-a)n现在将步长分半,即在相邻两节点xqXa+的中点X1=1®+/G处增加2一个求积节点,那么变形一下:源程序:#include<iostream.h>#include<math.h>doublef(doublex)计算被积函数的值doubley;y=log(l+x)(l+x*x):returny;doublet2ntn(doublea9doubleb)intn=l;doublehn=ba;原步长doubletn=O.0;doublet2n=(f(a)+f(b)*hn2.0;while(fabs(t2n-tn)>le-7)判断精度tn=t2n;t2n=0.0;for(intk=O;k<=n-l;k+)循环叠加t2n+=f(a+hn2.0+k*hn);t2n=tn2.0+t2n*hn2.0;n=n*2;hn=hn2.0;步长分半returnt2n;voidmain()(doublea=0.0;doubleb=2.0;cout<<t2ntn(a,b)<<endl;执行结果:4 .变步长辛普森法之前的积分斜边都是直线,如果用抛物线接近就会更准确复化辛普森求积公式然后就只要每企让他的积分区间加倍就行直到到达要求的精度#include<stdio.h>#include<iostream.h>#include<rath.h>doublea=0.0,b=2.0,e=le-7;积分上下线,和精度要求intn=1024;doublef(doublex)Doubley;y=logl+x)(l+x*x);被积函数returny;Iloatsimpson()inti;doubles,sn,s2n,p,x,h;h=(ba)n;步长s=f(a)+f(b);p=;x=a+h;积分端点for(i=l;i<=n-l;i+)if(i%2)!=0)p=p+4*f(x);"在区间中间时乘4x=x+h;elses=s+2*f(x);"积分端点时乘2x=x+h;s=s+p;"第一次求和s2n=s*h3;积分值dosn=s2n;x=a+h?2;"变步长s=s-p/2;P=O;for(i=l;i<=n;i+)"变步长只需要加就行了p=p+4*f();x=x+h;s=s+p;n=n*2;h=h2;s2n=s*h3;while(fabs(s2n-sn)>e);控制精度returns2n;voidmain()cout<<simpson()<<endl;执行结果:幽用C+写的综合程序include<stdio.h>#include<iostream.h>#include<math.h>classBjhs抽象类public:virtualdoublef(doublex)=0;虚计算被积函数virtualvoidprint()=0;输出函数virtualdoubleTn0=0;/虚函数;classFhjxipublicBjhs复化矩形法类public:Fhjx()a=O;b=2;e=le7;n=1024;/构造函数付初值doublef(doublex);"计算被积函数doubleTn()求Tndoublet=0.0;doublexk;区间端点值doubletl,t2;用来判断精度dodoubleh=(b-a)/n;for(intk=l;k<=n-l;k+)每一小段的矩形叠加tl=t;xk=a+k*h;t+=h*f(xk);t2=t;n+;/如果精度不够就对区间再次细分,直到到达精度要求while(fabs(tl-t2)<=e);判断计算精度returnt;voidprint()输出eoutU用复化矩形法计算的结果.<<Tn()<<endl;private:doublea,b,e;intn;:doubleFhjx:f(doublex)外联函数doubley;y=log(l+x)(l+x*x);/被积函数returny:classFhtx:publicBjhs复化梯形法public:Fhtx()a=0;b=2;e=le-7;n=1024:doublef(doublex);计算被积函数doubleTn()求Tndoublet=0.0;doublexk;区间端点值doubletl,t2,h=(b-a)n;用来判断精度doh=(ba)/n;for(intk=l;k<=n-l;k+)余项叠加,相当于每一个小梯形相加tl=t;xk=a+k*h;t+=f(xk);t2=t;n+;"如果精度不够就对区间再次细分,直到到达精度要求while(fabs(tl-t2)<=le-7);判断计算精度t=h*(f(a)+f(b)2+t*h;加上初项就是积分结果了returnt;voidprint()CoUt«"用复化梯形法计算的结果"Tn()<<endl;private:doublea,b,e;intn;:doubleFhtx:f(doublex)doubley:y=log(l+x)/(l+x*x);被积函数returny;classBbctxipublicBjhs变步长梯形法public:BbCtXOa=0;b=2;e=le-7;n=l;tn=O;doublef(doublex);计算被积函数的值doubleTn()doublehn=ba;原步长doublet2n=(f(a)+f(b)*hn2.0;while(fabs(t211-tn)>e)判断精度tn=t2n;t2n=0.0;for(intk=0;k<=n-l;k+)循环叠加t2n+=f(a+hn2.0+k*hn);t2n=tn2.0+t2n*hn2.0;n=n*2;hn=hn2.0;/步长分半returnt2n;voidprint()COUt«"用变步长梯形法计算的结果"Tn()«endl;private:doublea,b,e;doubletn;intn;;doubleBbctx:f(doublex)doubley;y=log(l+x)(l+x*x);被积函数returny;classBbcxpsipublicBjhs变步长辛普森法public:Bbcxps()n=1024:a=0:b=2;e=le7;积分上下线,和精度要求doublef(doublex):doubleTn()inti;doubles,sn,s2n,p,x,h;h=(b-a)n;步长s=f(a)+f(b);P=O:x=a+h:积分端点for(i=l;i<=n-l;i+)if(i%2)!=0)判奇偶,也就是看哪点乘几P=+4*f(x);"在区间中间时乘4x=x+h:elses=s+2*f(x);积分端点时乘2x=x+h;s=s+p:第一次求和s2n=s*h3;积分值dosn=s2n;x=a+h2;变步长s=sp2;P=O;for(i=l;i<=n;i+)变步长只需要加就行了p=p+4*f(x);x=x+h;s=s+p;n=n*2;h=h2;s2n=s*h3;while(fabs(s2n-sn)<=e);控制精度returns2n;voidprint()CoUtG"用变步长辛普森法计算的结果"Tn()<<endl;private:doublea,b,e,p;intn;:doubleBbcxps:f(doublex)doubley:y=log(l+x)/(l+x*x);被积函数returny;voiddisplay(Bjhs&q)/输出函数q-Tn();q.print();:voidmai110选择你想要的方法,用SWitCh语句chara;Fhjxb;Fhtxc;Bbctxd;Bbcxpse;COUt«*求函数y=log(l+x)/(l÷x*x)的积分值"endl;CoUtG"请输入你要选用的方法的编号YOndl;CoUt«"A.复化矩形法B.复化梯形法*«endl;cout<<"C.变步长梯形法D.变步长辛普森法"endl;cin>>a;switch(a)case,A,:display(b);break;case,B,:display(c);break;case,C,:display(d);break;case,D,:display(e);break;default:CoUt«"输入代码错误"<<endl;break;执行结果: