求NewtonCotes系数
- #include<iostream.h>
- #include<math.h>
- # define Precision 0.01//积分精度要求
- #include <iomanip.h>
- #include <windows.h>
- #define jieshu 10 //NewtonCotes的阶数
- double Factorial (long n)
- {
- long s;
- s=1.0;
- while (n>0)
- {
- s=s*n;
- n--;
- }
- return s;
- }
- double function(int n,int k,double t)//被积函数
- {
- double s,d;
- s=1.0;
- for(int j=0;j<=n;j++)
- {
- if(j!=k)
- {
- s=s*(t-j);
- }
- }
- return s;
- }
- double VariableStepSimpson(int n1,int k1,double a,double b,double f(int n1,int k1,double x))//变步长Simpson公式
- {
- int n,k,n2,k2;
- n2=n1;
- k2=k1;
- double h,fa,fb,Tn,T2n,s,s1,s2,xk,p;
- n=1;
- h=b-a;
- fa=f(n2,k2,a);
- fb=f(n2,k2,b);
- Tn=h*(fa+fb)/2.0;//计算T`1`=(b-a)/[f(a)+f(b)];
- s1=Tn;
- p=Precision+1.0;
- while(p>=Precision)
- {
- s=0.0;
- for(k=0;k<n;k++)
- {
- xk=a+(k+0.501)*h;
- s=s+f(n2,k2,xk);
- }
- T2n=(Tn+h*s)/2.0;//计算T2n
- s2=(4.0*T2n-Tn)/3.0;//计算Sn
- p=fabs(s2-s1);
- Tn=T2n;
- s1=s2;
- n=n+n;
- h=h/2.0;
- }
- return s2;
- }
- main()
- {
- HANDLE hOut;
- COORD Position;
- hOut = GetStdHandle(STD_OUTPUT_HANDLE);
- Position.X = 500;
- Position.Y = 500;
- SetConsoleScreenBufferSize(hOut,Position);//设置输出屏幕的大小
- double a[jieshu+1][jieshu+1];
- int n,k;
- double s,s1,t;
- for(n=1;n<=jieshu;n++)
- {
- for(k=0;k<=n;k++)
- {
- a[n][k]=10;
- }
- } //初始化数组
- for(n=1;n<=jieshu;n++)
- {
- for(k=0;k<=n;k++)
- {
- s=VariableStepSimpson(n,k,0,n,function);
- s=s*pow(-1,n-k);
- s1=(n*Factorial(k)*Factorial(n-k));
- s=s/s1;
- a[n][k]=s;
- } //计算系数
- }
- for(n=1;n<jieshu;n++)
- {
- for(k=0;k<=n/2;k++)
- {
- t=(a[n][k]+a[n][n-k])/2;
- a[n][k]=a[n][n-k]=t;
- }
- } //利用对称相等的性质把对称的两个数相加除以2
- for(n=1;n<=jieshu;n++)
- {
- if(n<10)
- {
- cout<<"n="<<n<<" ";
- }
- else
- {
- cout<<"n="<<n<<" ";
- }
- for(k=0;k<=n;k++)
- {
- cout<<setiosflags(ios::fixed)<<setprecision(6)<<a[n][k]<<" ";
- }
- cout<<endl;
- }
- }
xk=a+(k+0.501)*h
#define jieshu 13 //NewtonCotes的阶数
# define Precision 0.001//积分精度要求
程序的运行时间特别长,主要和以上三个因素有关,在xk=a+(k+0.5001)*h中,本应该是乘以0.5的,但是这样运算时,在double function(int n,int k,double t)函数中会得到0,从而使部分运算结果为0(错误),所以就改为0.501了,阶数和积分精度也花了很长运行时间,根据运算的结果,我觉得课本上好像是正确的,-4540/28350=-0.16014109347442680776014109347443 ,-45440/28350= -1.6028218694885361552028218694885,
由于取了0.5001,最后算出的结果Cotes系数不是很对称,最后把对应的两个数相加除以二,这样得到的结果就更加精确,和真实值更加接近
在求积分的时候用了变步长Simpson公式
#define jieshu 13 //NewtonCotes的阶数
# define Precision 0.001//积分精度要求
程序的运行时间特别长,主要和以上三个因素有关,在xk=a+(k+0.5001)*h中,本应该是乘以0.5的,但是这样运算时,在double function(int n,int k,double t)函数中会得到0,从而使部分运算结果为0(错误),所以就改为0.501了,阶数和积分精度也花了很长运行时间,根据运算的结果,我觉得课本上好像是正确的,-4540/28350=-0.16014109347442680776014109347443 ,-45440/28350= -1.6028218694885361552028218694885,
由于取了0.5001,最后算出的结果Cotes系数不是很对称,最后把对应的两个数相加除以二,这样得到的结果就更加精确,和真实值更加接近
在求积分的时候用了变步长Simpson公式
下面是两种情况下运行的结果,第二种花费时间长一些