数值积分

#include "stdafx.h"
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "NumberIntegral.h"
#include "Randomicity.h"

//计算二重积分的连分式法
double fpqg2(double a, double b, double eps)
{
 int m,n,k,l,j;
 double bb[10],h[10],hh,s1,s2,t1,t2,x,g,s0,ep,s;
 m=1;
 n=1;
 hh=b-a;
 h[0]=hh;
 s1=pqg1(a,eps);
 s2=pqg1(b,eps);
 t1=hh*(s1+s2)/2.0;
 s0=t1;
 bb[0]=t1;
 ep=1.0+eps;
 while ((ep>=eps)&&(m<=9))
 {
  t2=0.5*t1;
  for (k=0;k<=n-1;k++)
  {
   x=a+(k+0.5)*hh;
   s1=pqg1(x,eps);
   t2=t2+0.5*s1*hh;
  }
  m=m+1;
  h[m-1]=h[m-2]/2.0;
  g=t2;
  l=0;
  j=2;
  while ((l==0)&&(j<=m))
  {
   s=g-bb[j-2];
   if (fabs(s)+1.0==1.0)
    l=1;
   else
    g=(h[m-1]-h[j-2])/s;
   j=j+1;
  }
  bb[m-1]=g;
  if (l!=0)
   bb[m-1]=1.0e+35;
  s=bb[m-1];
  for (j=m;j>=2;j--)
   s=bb[j-2]-h[j-2]/s;
  ep=fabs(s-s0)/(1.0+fabs(s));
  n=n+n;
  t1=t2;
  s0=s;
  hh=hh/2.0;
 }
 return(s);
}

//勒让德-高斯求积法
double flrgs(double a, double b, double eps)
{
 int m,i,j;
 double s,p,ep,h,aa,bb,w,x,g;
 static double t[5]={-0.9061798459,-0.5384693101,0.0,0.5384693101,0.9061798459};
 static double c[5]={0.2369268851,0.4786286705,0.5688888889,0.4786286705,0.2369268851};
 m=1;
 h=b-a;
 s=fabs(0.001*h);
 p=1.0e+35;
 ep=eps+1.0;
 while ((ep>=eps)&&(fabs(h)>s))
 {
  g=0.0;
  for (i=1;i<=m;i++)
  {
   aa=a+(i-1.0)*h;
   bb=a+i*h;
   w=0.0;
   for (j=0;j<=4;j++)
   {
    x=((bb-aa)*t[j]+(bb+aa))/2.0;
    w=w+flrgsf(x)*c[j];
   }
   g=g+w;
  }
  g=g*h/2.0;
  ep=fabs(g-p)/(1.0+fabs(g));
  p=g;
  m=m+1;
  h=(b-a)/m;
 }
 return(g);
}

//自适应梯形求积法
double ffpts(double a, double b, double eps, double d)
{
 double h,t[2],f0,f1,t0,z;
 h=b-a;
 t[0]=0.0;
 f0=ffptsf(a);
 f1=ffptsf(b);
 t0=h*(f0+f1)/2.0;
 ppp(a,b,h,f0,f1,t0,eps,d,t);
 z=t[0];
 return(z);
}

//变步长辛卜生求积法
double fsimp(double a, double b, double eps)
{
 int n,k;
 double h,t1,t2,s1,s2,ep,p,x;
 n=1;
 h=b-a;
 t1=h*(fsimpf(a)+fsimpf(b))/2.0;
 s1=t1;
 ep=eps+1.0;
 while (ep>=eps)
 {
  p=0.0;
  for (k=0;k<=n-1;k++)
  {
   x=a+(k+0.5)*h;
   p=p+fsimpf(x);
  }
  t2=(t1+h*p)/2.0;
  s2=(4.0*t2-t1)/3.0;
  ep=fabs(s2-s1);
  t1=t2;
  s1=s2;
  n=n+n;
  h=h/2.0;
 }
 return(s2);
}

//高振荡函数求积法
void fpart(double a, double b, int m, int n, double fa[], double fb[], double s[])
{
 int mm,k,j;
 double sa[4],sb[4],ca[4],cb[4],sma,smb,cma,cmb;
 sma=sin(m*a);
 smb=sin(m*b);
 cma=cos(m*a);
 cmb=cos(m*b);
 sa[0]=sma;
 sa[1]=cma;
 sa[2]=-sma;
 sa[3]=-cma;
 sb[0]=smb;
 sb[1]=cmb;
 sb[2]=-smb;
 sb[3]=-cmb;
 ca[0]=cma;
 ca[1]=-sma;
 ca[2]=-cma;
 ca[3]=sma;
 cb[0]=cmb;
 cb[1]=-smb;
 cb[2]=-cmb;
 cb[3]=smb;
 s[0]=0.0;
 s[1]=0.0;
 mm=1;
 for (k=0;k<=n-1;k++)
 {
  j=k;
  while(j>=4)
   j=j-4;
  mm=mm*m;
  s[0]=s[0]+(fb[k]*sb[j]-fa[k]*sa[j])/(1.0*mm);
  s[1]=s[1]+(fb[k]*cb[j]-fa[k]*ca[j])/(1.0*mm);
 }
 s[1]=-s[1];
 return;
}

//拉盖尔-高斯求积法
double flags()
{
 int i;
 double x,g;
 static double t[5]={0.26355990,1.41340290,3.59642600,7.08580990,12.64080000};
 static double c[5]={0.6790941054,1.638487956,2.769426772,4.315944000,7.104896230};
 g=0.0;
 for (i=0; i<=4; i++)
 {
  x=t[i];
  g=g+c[i]*flagsf(x);
 }
 return(g);
}

//计算一维积分的连分式法
double ffpqg(double a, double b, double eps)
{
 int m,n,k,l,j;
 double h[10],bb[10],hh,t1,s1,ep,s,x,t2,g;
 m=1;
 n=1;
 hh=b-a;
 h[0]=hh;
 t1=hh*(ffpqgf(a)+ffpqgf(b))/2.0;
 s1=t1;
 bb[0]=s1;
 ep=1.0+eps;
 while ((ep>=eps)&&(m<=9))
 {
  s=0.0;
  for (k=0;k<=n-1;k++)
  {
   x=a+(k+0.5)*hh;
   s=s+ffpqgf(x);
  }
  t2=(t1+hh*s)/2.0;
  m=m+1;
  h[m-1]=h[m-2]/2.0;
  g=t2;
  l=0;
  j=2;
  while ((l==0)&&(j<=m))
  {
   s=g-bb[j-2];
   if(fabs(s)+1.0==1.0)
    l=1;
   else
    g=(h[m-1]-h[j-2])/s;
   j=j+1;
  }
  bb[m-1]=g;
  if(l!=0)
   bb[m-1]=1.0e+35;
  g=bb[m-1];
  for(j=m;j>=2;j--)
   g=bb[j-2]-h[j-2]/g;
  ep=fabs(g-s1);
  s1=g;
  t1=t2;
  hh=hh/2.0;
  n=n+n;
 }
 return(g);
}

//变步长辛卜生二重积分法
double fsim2(double a, double b, double eps)
{
 int n,j;
 double h,d,s1,s2,t1,x,t2,g,s,s0,ep;
 n=1;
 h=0.5*(b-a);
 d=fabs((b-a)*1.0e-06);
 s1=simp1(a,eps);
 s2=simp1(b,eps);
 t1=h*(s1+s2);
 s0=1.0e+35;
 ep=1.0+eps;
 while (((ep>=eps)&&(fabs(h)>d))||(n<16))
 {
  x=a-h;
  t2=0.5*t1;
  for (j=1;j<=n;j++)
  {
   x=x+2.0*h;
   g=simp1(x,eps);
   t2=t2+h*g;
  }
  s=(4.0*t2-t1)/3.0;
  ep=fabs(s-s0)/(1.0+fabs(s));
  n=n+n;
  s0=s;
  t1=t2;
  h=h*0.5;
 }
 return(s);
}

//计算多重积分的蒙特卡洛法
double fmtml(int n, double a[], double b[])
{
 int m,i;
 double r,s,d,*x;
 x=(double *)malloc(n*sizeof(double));
 r=1.0;
 d=10000.0;
 s=0.0;
 for (m=0; m<=9999; m++)
 {
  for (i=0; i<=n-1; i++)
   x[i]=a[i]+(b[i]-a[i])*mrnd1(&r);
  s=s+fmtmlf(n,x)/d;
 }
 for (i=0; i<=n-1; i++)
  s=s*(b[i]-a[i]);
 free(x);
 return(s);
}

//埃尔米待-高斯求积法
double fhmgs()
{
 int i;
 double x,g;
 static double t[5]={-2.02018200,-0.95857190,0.0,0.95857190,2.02018200};
 static double c[5]={1.181469599,0.9865791417,0.9453089237,0.9865791417,1.181469599};
 g=0.0;
 for (i=0; i<=4; i++)
 {
  x=t[i];
  g=g+c[i]*fhmgsf(x);
 }
 return(g);
}

//变步长梯形求积法
double fffts(double a, double b, double eps)
{
 int n,k;
 double fa,fb,h,t1,p,s,x,t;
 fa=ffftsf(a);
 fb=ffftsf(b);
 n=1;
 h=b-a;
 t1=h*(fa+fb)/2.0;
 p=eps+1.0;
 while (p>=eps)
 {
  s=0.0;
  for (k=0;k<=n-1;k++)
  {
   x=a+(k+0.5)*h;
   s=s+ffftsf(x);
  }
  t=(t1+h*s)/2.0;
  p=fabs(t1-t);
  t1=t;
  n=n+n;
  h=h/2.0;
 }
 return(t);
}

//龙贝格求积法
double fromb(double a, double b, double eps)
{
 int m,n,i,k;
 double y[10],h,ep,p,x,s,q;
 h=b-a;
 y[0]=h*(frombf(a)+frombf(b))/2.0;
 m=1;
 n=1;
 ep=eps+1.0;
 while ((ep>=eps)&&(m<=9))
 {
  p=0.0;
  for (i=0;i<=n-1;i++)
  {
   x=a+(i+0.5)*h;
   p=p+frombf(x);
  }
  p=(y[0]+h*p)/2.0;
  s=1.0;
  for (k=1;k<=m;k++)
  {
   s=4.0*s;
   q=(s*p-y[k-1])/(s-1.0);
   y[k-1]=p; p=q;
  }
  ep=fabs(q-y[m-1]);
  m=m+1;
  y[m-1]=q;
  n=n+n;
  h=h/2.0;
 }
 return(q);
}

//计算一维积分的蒙特卡格法
double fmtcl(double a, double b)
{
 int m;
 double r,d,x,s;
 r=1.0;
 s=0.0;
 d=10000.0;
 for (m=0; m<=9999; m++)
 {
  x=a+(b-a)*mrnd1(&r);
  s=s+fmtclf(x)/d;
 }
 s=s*(b-a);
 return(s);
}

//计算多重积分的高斯方法
double fgaus(int n, int js[])
{
 int m,j,k,q,l,*is;
 double y[2],p,s,*x,*a,*b;
 static double t[5]={-0.9061798459,-0.5384693101,0.0,0.5384693101,0.9061798459};
 static double c[5]={0.2369268851,0.4786286705,0.5688888889,0.4786286705,0.2369268851};
 is=(int *)malloc(2*(n+1)*sizeof(int));
 x=(double *)malloc(n*sizeof(double));
 a=(double *)malloc(2*(n+1)*sizeof(double));
 b=(double *)malloc((n+1)*sizeof(double));
 s = 0;
 m=1;
 l=1;
 a[n]=1.0;
 a[2*n+1]=1.0;
 while (l==1)
 {
  for (j=m;j<=n;j++)
  {
   fgauss(j-1,n,x,y);
   a[j-1]=0.5*(y[1]-y[0])/js[j-1];
   b[j-1]=a[j-1]+y[0];
   x[j-1]=a[j-1]*t[0]+b[j-1];
   a[n+j]=0.0;
   is[j-1]=1;
   is[n+j]=1;
  }
  j=n;
  q=1;
  while (q==1)
  {
   k=is[j-1];
   if (j==n)
    p=fgausf(n,x);
   else
    p=1.0;
   a[n+j]=a[n+j+1]*a[j]*p*c[k-1]+a[n+j];
   is[j-1]=is[j-1]+1;
   if (is[j-1]>5)
    if (is[n+j]>=js[j-1])
    {
     j=j-1;
     q=1;
     if (j==0)
     {
      s=a[n+1]*a[0];
      free(is);
      free(x);
      free(a);
      free(b);
      return(s);
     }
    }
    else
    {
     is[n+j]=is[n+j]+1;
     b[j-1]=b[j-1]+a[j-1]*2.0;
     is[j-1]=1;
     k=is[j-1];
     x[j-1]=a[j-1]*t[k-1]+b[j-1];
     if (j==n)
      q=1;
     else
      q=0;
    }
   else
   {
    k=is[j-1];
    x[j-1]=a[j-1]*t[k-1]+b[j-1];
    if (j==n)
     q=1;
    else
     q=0;
   }
  }
  m=j+1;
 }
 return(s);
}

//切比雪夫求积法
double fcbsv(double a, double b, double eps)
{
 int m,i,j;
 double h,d,p,ep,g,aa,bb,s,x;
 static double t[5]={-0.8324975,-0.3745414,0.0,0.3745414,0.8324975};
 m=1;
 h=b-a;
 d=fabs(0.001*h);
 p=1.0e+35;
 ep=1.0+eps;
 while ((ep>=eps)&&(fabs(h)>d))
 {
  g=0.0;
  for (i=1;i<=m;i++)
  {
   aa=a+(i-1.0)*h;
   bb=a+i*h;
   s=0.0;
   for (j=0;j<=4;j++)
   {
    x=((bb-aa)*t[j]+(bb+aa))/2.0;
    s=s+fcbsvf(x);
   }
   g=g+s;
  }
  g=g*h/5.0;
  ep=fabs(g-p)/(1.0+fabs(g));
  p=g;
  m=m+1;
  h=(b-a)/m;
 }
 return(g);
}

double pqg1(double x, double eps)
{
 int m,n,k,l,j;
 double b[10],h[10],y[2],hh,t1,t2,s0,yy,g,ep,s;
 m=1;
 n=1;
 fpqg2s(x,y);
 hh=y[1]-y[0];
 h[0]=hh;
 t1=0.5*hh*(fpqg2f(x,y[0])+fpqg2f(x,y[1]));
 s0=t1;
 b[0]=t1;
 ep=1.0+eps;
 while((ep>=eps)&&(m<=9))
 {
  t2=0.5*t1;
  for(k=0;k<=n-1;k++)
  {
   yy=y[0]+(k+0.5)*hh;
   t2=t2+0.5*hh*fpqg2f(x,yy);
  }
  m=m+1;
  h[m-1]=h[m-2]/2.0;
  g=t2;
  l=0;
  j=2;
  while ((l==0)&&(j<=m))
  {
   s=g-b[j-2];
   if(fabs(s)+1.0==1.0)
    l=1;
   else
    g=(h[m-1]-h[j-2])/s;
   j=j+1;
  }
  b[m-1]=g;
  if (l!=0)
   b[m-1]=1.0e+35;
  s=b[m-1];
  for (j=m;j>=2;j--)
   s=b[j-2]-h[j-2]/s;
  ep=fabs(s-s0)/(1.0+fabs(s));
  n=n+n;
  t1=t2;
  s0=s;
  hh=0.5*hh;
 }
 return(s);
}

void ppp(double x0, double x1, double h, double f0, double f1, double t0, double eps, double d, double t[])
{
 double x,f,t1,t2,p,g,eps1;
 x=x0+h/2.0;
 f=ffptsf(x);
 t1=h*(f0+f)/4.0;
 t2=h*(f+f1)/4.0;
 p=fabs(t0-(t1+t2));
 if((p<eps)||(h/2.0<d))
 {
  t[0]=t[0]+(t1+t2);
  return;
 }
 else
 {
  g=h/2.0;
  eps1=eps/1.4;
  ppp(x0,x,g,f0,f,t1,eps1,d,t);
  ppp(x,x1,g,f,f1,t2,eps1,d,t);
  return;
 }
}

double simp1(double x, double eps)
{
 int n,i;
 double y[2],h,d,t1,yy,t2,g,ep,g0;
 n=1;
 fsim2s(x,y);
 h=0.5*(y[1]-y[0]);
 d=fabs(h*2.0e-06);
 t1=h*(fsim2f(x,y[0])+fsim2f(x,y[1]));
 ep=1.0+eps;
 g0=1.0e+35;
 while (((ep>=eps)&&(fabs(h)>d))||(n<16))
 {
  yy=y[0]-h;
  t2=0.5*t1;
  for(i=1;i<=n;i++)
  {
   yy=yy+2.0*h;
   t2=t2+h*fsim2f(x,yy);
  }
  g=(4.0*t2-t1)/3.0;
  ep=fabs(g-g0)/(1.0+fabs(g));
  n=n+n;
  g0=g;
  t1=t2;
  h=0.5*h;
 }
 return(g);
}

double ffftsf(double x)
{
 double y;
    y = exp(-x * x);
    return(y);
}

double fsimpf(double x)
{
 double y;
 y = log(1.0 + x)/(1.0 + x * x);
 return(y);
}

double ffptsf(double x)
{
 double y;
 y = 1.0/(1.0 + 25.0 * x * x);
 return (y);
}

double frombf(double x)
{
 double y;
 y = x/(4.0 + x * x);
 return (y);
}

double ffpqgf(double x)
{
 double y;
 y = exp(-x * x);
 return(y);
}

double flrgsf(double x)
{
 double y;
 y = x * x + sin(x);
 return (y);
}

double flagsf(double x)
{
 double y;
 y = x * exp(-x);
 return (y);
}

double fhmgsf(double x)
{
 double y;
 y = x * x * exp(-x * x);
 return (y);
}

double fcbsvf(double x)
{
 double y;
 y = x * x + sin(x);
 return (y);
}

double fmtclf(double x)
{
 double y;
 y = x * x + sin(x);
 return (y);
}

void fsim2s(double x, double y[2])
{
 y[0] = -sqrt(1.0 - x * x);
 y[1] = -y[0];
 return;
}

double fsim2f(double x, double y)
{
 double z;
 z = exp(x * x + y * y);
 return (z);
}

void fgauss(int j, int n, double x[], double y[2])
{
 double q;
 n = n;
 switch(j){
 case 0:
  y[0] = 0.0;
  y[1] = 1.0;
  break;
 case 1:
  y[0] = 0.0;
  y[1] = sqrt(1.0 - x[0] * x[0]);
  break;
 case 2:
  q = x[0] * x[0] + x[1] * x[1];
  y[0] = sqrt(q);
  y[1] = sqrt(2.0 - q);
  break;
 default:;
 }
 return;
}

double fgausf(int n, double x[])
{
 double y;
 n = n;
 y = x[2] * x[2];
 return (y);
}

void fpqg2s(double x, double y[2])
{
 y[1] = sqrt(1.0 - x * x);
 y[0] = -y[1];
 return;
}

double fpqg2f(double x, double y)
{
 double z;
 z = exp(x * x + y * y);
 return (z);
}

double fmtmlf(int n, double x[])
{
 int i;
 double f;
 f = 0.0;
 for(i = 0; i < n - 1; i++)
  f = f + x[i] * x[i];
 return (f);
}
                                      ----根据《C语言常用算法程序集》整理

<投票>

 

你可能感兴趣的:(数值积分)