📄 ep8_10.cpp
字号:
/*8.10 矩形法(rectangle)积分近似计算公式为:dx(y0+y1+...+y(n-1));
梯形法(ladder)积分近似计算公式为:dx(y0+2*(y1+y2+...+y(n-i))+yn)/2
辛普生法(simpson)积分近似计算公式(n为偶数)为:dx(y0+yn+4*(y1+y3+...+y(n-1))+2*(y2+y4+...+y(n-2))))
被积函数用派生类引入。
基类(integer)成员数据包括:积分上下限b和a;分区数n;步长step=(b-a)/n,积分值result。定义积分函数integerate()为虚函数,它只显示提示信息。
派生的矩形法类(rectangle)重定义integerate(),采用矩形法作积分运算。
派生的梯形法类(ladder)和辛普生法(simpson)类似。
请编程,用三种方法对下列被积函数
(1) sin(x),下限为0.0和上限为π/2;
(2) exp(x),下限为0.0和上限为1.0;
(3) 4.0/(1+x*x),下限为0.0和上限为1.0。
进行定积分计算,并比较积分精度。*/
#include<iostream>
#include<cmath>
using namespace std;
class Base{
protected:
double result,a,b,step;//Intevalue积分值,a积分下限,b积分上限
int n;
public:
virtual double fun(double x)=0;//被积函数声明为纯虚函数
virtual void Integerate(){
cout<<"这里是积分函数"<<endl;
}
Base(double ra=0,double rb=0,int nn=2000){
a=ra;
b=rb;
n=nn;
result=0;
}
void Print(){
cout.precision(15);
cout<<"积分值="<<result<<endl;
}
};
class Rectangle:public Base{
public:
void Integerate(){
int i;
step=(b-a)/n;
for(i=0;i<=n;i++) result+=fun(a+step*i);
result*=step;
}
Rectangle(double ra,double rb,int nn):Base(ra,rb,nn){}
};
class Ladder:public Base{
public:
void Integerate(){
int i;
step=(b-a)/n;
result=fun(a)+fun(b);
for(i=1;i<n;i++) result+=2*fun(a+step*i);
result*=step/2;
}
Ladder(double ra,double rb,int nn):Base(ra,rb,nn){}
};
class Simpson:public Base{
public:
void Integerate(){
int i;
step=(b-a)/n;
result=fun(a)+fun(b);
for(i=1;i<n;i+=2) result+=4*fun(a+step*i);
for(i=2;i<n;i+=2) result+=2*fun(a+step*i);
result*=step/3;
}
Simpson(double ra,double rb,int nn):Base(ra,rb,nn){}
};
class sinR:public Rectangle{//矩形法和梯形法采用并列结构
public:
sinR(double ra,double rb,int nn):Rectangle(ra,rb,nn){}
double fun(double x){return sin(x);}
};
class sinL:public Ladder{
public:
sinL(double ra,double rb,int nn):Ladder(ra,rb,nn){}
double fun(double x){return sin(x);}
};
class expR:public Rectangle{
public:
expR(double ra,double rb,int nn):Rectangle(ra,rb,nn){}
double fun(double x){return exp(x);}
};
class expL:public Ladder{
public:
expL(double ra,double rb,int nn):Ladder(ra,rb,nn){}
double fun(double x){return exp(x);}
};
class otherR:public Rectangle{
public:
otherR(double ra,double rb,int nn):Rectangle(ra,rb,nn){}
double fun(double x){return (4.0/(1+x*x));}
};
class otherL:public Ladder{
public:
otherL(double ra,double rb,int nn):Ladder(ra,rb,nn){}
double fun(double x){return (4.0/(1+x*x));}
};
class sinS:public Simpson{//辛普生法采用层次结构
public:
sinS(double ra,double rb,int nn):Simpson(ra,rb,nn){}
double fun(double x){return sin(x);}
};
class expS:public sinS{
public:
expS(double ra,double rb,int nn):sinS(ra,rb,nn){}
double fun(double x){return exp(x);}
};
class otherS:public expS{
public:
otherS(double ra,double rb,int nn):expS(ra,rb,nn){}
double fun(double x){return (4.0/(1+x*x));}
};
int main(){
Base *bp;
sinR sr(0.0,3.1415926535/2.0,100);
bp=&sr;
bp->Integerate();//动态,可以访问派生类定义的被积函数
bp->Print();
sinL sl(0.0,3.1415926535/2.0,100);
bp=&sl;
bp->Integerate();//动态,可以访问派生类定义的被积函数
bp->Print();
sinS ss(0.0,3.1415926535/2.0,100);
bp=&ss;
bp->Integerate();//动态,在层次中选
bp->Print();
expR er(0.0,1.0,100);
bp=&er;
bp->Integerate();//动态,可以访问派生类定义的被积函数
bp->Print();
expL el(0.0,1.0,100);
bp=⪙
bp->Integerate();//动态,可以访问派生类定义的被积函数
bp->Print();
expS es(0.0,1.0,100);
bp=&es;
bp->Integerate();//动态,在层次中选
bp->Print();
otherR or(0.0,1.0,100);
bp=∨
bp->Integerate();//动态,可以访问派生类定义的被积函数
bp->Print();
otherL ol(0.0,1.0,100);//增加到100000也达不到辛普生法的精度
bp=&ol;
bp->Integerate();//动态,可以访问派生类定义的被积函数
bp->Print();
otherS os(0.0,1.0,100);
bp=&os;
bp->Integerate();//动态,在层次中选
bp->Print();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -