Integral.cpp
上传用户:weigute
上传日期:2007-03-02
资源大小:1287k
文件大小:11k
源码类别:

数学计算

开发平台:

Visual C++

  1. //////////////////////////////////////////////////////////////////////
  2. // Integral.cpp
  3. //
  4. // 操作数值积分的类 CIntegral 的实现代码
  5. //
  6. // 周长发编制, 2002/8
  7. //////////////////////////////////////////////////////////////////////
  8. #include "stdafx.h"
  9. #include "Integral.h"
  10. #ifdef _DEBUG
  11. #undef THIS_FILE
  12. static char THIS_FILE[]=__FILE__;
  13. #define new DEBUG_NEW
  14. #endif
  15. //////////////////////////////////////////////////////////////////////
  16. // Construction/Destruction
  17. //////////////////////////////////////////////////////////////////////
  18. //////////////////////////////////////////////////////////////////////
  19. // 基本构造函数
  20. //////////////////////////////////////////////////////////////////////
  21. CIntegral::CIntegral()
  22. {
  23. }
  24. //////////////////////////////////////////////////////////////////////
  25. // 析构函数
  26. //////////////////////////////////////////////////////////////////////
  27. CIntegral::~CIntegral()
  28. {
  29. }
  30. //////////////////////////////////////////////////////////////////////
  31. // 变步长梯形求积法
  32. //
  33. // 调用时,须覆盖计算函数f(x)值的虚函数double Func(double x)
  34. //
  35. // 参数:
  36. // 1. a - Double型变量,积分下限
  37. // 2. b - Double型变量,积分上限,要求b>a
  38. // 3. eps - Double型变量,积分精度要求
  39. //
  40. // 返回值:double 型,积分值
  41. //////////////////////////////////////////////////////////////////////
  42. double CIntegral::GetValueTrapezia(double a, double b, double eps /*= 0.000001*/)
  43. {
  44. int n,k;
  45.     double fa,fb,h,t1,p,s,x,t;
  46.     
  47. // 积分区间端点的函数值
  48. fa=Func(a); 
  49. fb=Func(b);
  50.     
  51. // 迭代初值
  52. n=1; 
  53. h=b-a;
  54.     t1=h*(fa+fb)/2.0;
  55.     p=eps+1.0;
  56. // 迭代计算
  57.     while (p>=eps)
  58.     { 
  59. s=0.0;
  60.         for (k=0;k<=n-1;k++)
  61.         { 
  62. x=a+(k+0.5)*h;
  63.             s=s+Func(x);
  64.         }
  65.         
  66. t=(t1+h*s)/2.0;
  67.         p=fabs(t1-t);
  68.         t1=t; 
  69. n=n+n; 
  70. h=h/2.0;
  71.     }
  72.     
  73. return(t);
  74. }
  75. //////////////////////////////////////////////////////////////////////
  76. // 变步长辛卜生求积法
  77. //
  78. // 调用时,须覆盖计算函数f(x)值的虚函数double Func(double x)
  79. //
  80. // 参数:
  81. // 1. a - Double型变量,积分下限
  82. // 2. b - Double型变量,积分上限,要求b>a
  83. // 3. eps - Double型变量,积分精度要求
  84. //
  85. // 返回值:double 型,积分值
  86. //////////////////////////////////////////////////////////////////////
  87. double CIntegral::GetValueSimpson(double a, double b, double eps /*= 0.000001*/)
  88.     int n,k;
  89.     double h,t1,t2,s1,s2,ep,p,x;
  90. // 计算初值
  91.     n=1; 
  92. h=b-a;
  93.     t1=h*(Func(a)+Func(b))/2.0;
  94.     s1=t1;
  95.     ep=eps+1.0;
  96.     
  97. // 迭代计算
  98. while (ep>=eps)
  99.     { 
  100. p=0.0;
  101.         for (k=0;k<=n-1;k++)
  102.         { 
  103. x=a+(k+0.5)*h;
  104.             p=p+Func(x);
  105.         }
  106.         
  107. t2=(t1+h*p)/2.0;
  108.         s2=(4.0*t2-t1)/3.0;
  109.         ep=fabs(s2-s1);
  110.         t1=t2; s1=s2; n=n+n; h=h/2.0;
  111.     }
  112.     
  113. return(s2);
  114. }
  115. //////////////////////////////////////////////////////////////////////
  116. // 自适应梯形求积法
  117. //
  118. // 调用时,须覆盖计算函数f(x)值的虚函数double Func(double x)
  119. //
  120. // 参数:
  121. // 1. a - Double型变量,积分下限
  122. // 2. b - Double型变量,积分上限,要求b>a
  123. // 3. d - Double型变量,对积分区间进行分割的最小步长,当子区间的宽度
  124. //        小于d时,即使没有满足精度要求,也不再往下进行分割
  125. // 4. eps - Double型变量,积分精度要求
  126. //
  127. // 返回值:double 型,积分值
  128. //////////////////////////////////////////////////////////////////////
  129. double CIntegral::GetValueATrapezia(double a, double b, double d, double eps /*= 0.000001*/)
  130.     double h,t[2],f0,f1,t0,z;
  131. // 迭代初值
  132.     h=b-a; 
  133. t[0]=0.0;
  134.     f0=Func(a); 
  135. f1=Func(b);
  136.     t0=h*(f0+f1)/2.0;
  137. // 递归计算
  138.     ppp(a,b,h,f0,f1,t0,eps,d,t);
  139.     z=t[0]; 
  140. return(z);
  141. }
  142. //////////////////////////////////////////////////////////////////////
  143. // 内部函数
  144. //////////////////////////////////////////////////////////////////////
  145. void CIntegral::ppp(double x0, double x1, double h, double f0, double f1, double t0, double eps, double d, double t[])
  146.     double x,f,t1,t2,p,g,eps1;
  147.     x=x0+h/2.0; 
  148. f=Func(x);
  149.     t1=h*(f0+f)/4.0; 
  150. t2=h*(f+f1)/4.0;
  151.     p=fabs(t0-(t1+t2));
  152.     
  153. if ((p<eps)||(h/2.0<d))
  154.     { 
  155. t[0]=t[0]+(t1+t2); 
  156. return;
  157. }
  158.     else
  159.     { 
  160. g=h/2.0; 
  161. eps1=eps/1.4;
  162. // 递归
  163.         ppp(x0,x,g,f0,f,t1,eps1,d,t);
  164.         ppp(x,x1,g,f,f1,t2,eps1,d,t);
  165.         return;
  166.     }
  167. }
  168. //////////////////////////////////////////////////////////////////////
  169. // 龙贝格求积法
  170. //
  171. // 调用时,须覆盖计算函数f(x)值的虚函数double Func(double x)
  172. //
  173. // 参数:
  174. // 1. a - Double型变量,积分下限
  175. // 2. b - Double型变量,积分上限,要求b>a
  176. // 3. eps - Double型变量,积分精度要求
  177. //
  178. // 返回值:double 型,积分值
  179. //////////////////////////////////////////////////////////////////////
  180. double CIntegral::GetValueRomberg(double a, double b, double eps /*= 0.000001*/)
  181.     int m,n,i,k;
  182.     double y[10],h,ep,p,x,s,q;
  183. // 迭代初值
  184.     h=b-a;
  185.     y[0]=h*(Func(a)+Func(b))/2.0;
  186.     m=1; 
  187. n=1; 
  188. ep=eps+1.0;
  189.     
  190. // 迭代计算
  191. while ((ep>=eps)&&(m<=9))
  192.     { 
  193. p=0.0;
  194.         for (i=0;i<=n-1;i++)
  195.         { 
  196. x=a+(i+0.5)*h;
  197.             p=p+Func(x);
  198.         }
  199.         
  200. p=(y[0]+h*p)/2.0;
  201.         s=1.0;
  202.         for (k=1;k<=m;k++)
  203.         { 
  204. s=4.0*s;
  205.             q=(s*p-y[k-1])/(s-1.0);
  206.             y[k-1]=p; p=q;
  207.         }
  208.         ep=fabs(q-y[m-1]);
  209.         m=m+1; 
  210. y[m-1]=q; 
  211. n=n+n; 
  212. h=h/2.0;
  213.     }
  214.     
  215. return(q);
  216. }
  217. //////////////////////////////////////////////////////////////////////
  218. // 计算一维积分的连分式法
  219. //
  220. // 调用时,须覆盖计算函数f(x)值的虚函数double Func(double x)
  221. //
  222. // 参数:
  223. // 1. a - Double型变量,积分下限
  224. // 2. b - Double型变量,积分上限,要求b>a
  225. // 3. eps - Double型变量,积分精度要求
  226. //
  227. // 返回值:double 型,积分值
  228. //////////////////////////////////////////////////////////////////////
  229. double CIntegral::GetValuePq(double a, double b, double eps /*= 0.000001*/)
  230.     int m,n,k,l,j;
  231.     double h[10],bb[10],hh,t1,s1,ep,s,x,t2,g;
  232. // 迭代初值
  233.     m=1; 
  234. n=1;
  235.     hh=b-a; 
  236. h[0]=hh;
  237.     t1=hh*(Func(a)+Func(b))/2.0;
  238.     s1=t1; 
  239. bb[0]=s1; 
  240. ep=1.0+eps;
  241.     
  242. // 迭代计算
  243. while ((ep>=eps)&&(m<=9))
  244.     { 
  245. s=0.0;
  246.         for (k=0;k<=n-1;k++)
  247.         { 
  248. x=a+(k+0.5)*hh;
  249.             s=s+Func(x);
  250.         }
  251.         
  252. t2=(t1+hh*s)/2.0;
  253.         m=m+1;
  254.         h[m-1]=h[m-2]/2.0;
  255.         g=t2;
  256.         l=0; 
  257. j=2;
  258.         
  259. while ((l==0)&&(j<=m))
  260.         { 
  261. s=g-bb[j-2];
  262.             if (fabs(s)+1.0==1.0) 
  263. l=1;
  264.             else 
  265. g=(h[m-1]-h[j-2])/s;
  266.             
  267. j=j+1;
  268.         }
  269.         
  270. bb[m-1]=g;
  271.         if (l!=0) 
  272. bb[m-1]=1.0e+35;
  273.         
  274. g=bb[m-1];
  275.         for (j=m;j>=2;j--)
  276.            g=bb[j-2]-h[j-2]/g;
  277.         
  278. ep=fabs(g-s1);
  279.         s1=g; 
  280. t1=t2; 
  281. hh=hh/2.0; 
  282. n=n+n;
  283.     }
  284.     
  285. return(g);
  286. }
  287. //////////////////////////////////////////////////////////////////////
  288. // 高振荡函数求积法
  289. //
  290. //
  291. // 参数:
  292. // 1. a - Double型变量,积分下限
  293. // 2. b - Double型变量,积分上限,要求b>a
  294. // 3. m - Double型变量,被积函数中振荡函数的角频率
  295. // 4. n - 给定积分区间两端点上的导数最高阶数+1
  296. // 5. fa - Double型一维数组,长度为n,存放f(x)在积分区间端点x=a处的各阶导数值
  297. // 6. fb - Double型一维数组,长度为n,存放f(x)在积分区间端点x=b处的各阶导数值
  298. // 7. s - Double型一维数组,长度为2,其中s(1)返回f(x)cos(mx)在积分区间的积分值,
  299. //        s(2) 返回f(x)sin(mx)在积分区间的积分值
  300. //
  301. // 返回值:double 型,积分值
  302. //////////////////////////////////////////////////////////////////////
  303. double CIntegral::GetValuePart(double a, double b, int m, int n, double fa[], double fb[], double s[])
  304. int mm,k,j;
  305.     double sa[4],sb[4],ca[4],cb[4],sma,smb,cma,cmb;
  306.     
  307. // 三角函数值
  308. sma=sin(m*a); 
  309. smb=sin(m*b);
  310.     cma=cos(m*a); 
  311. cmb=cos(m*b);
  312.     
  313. // 迭代初值
  314. sa[0]=sma; 
  315. sa[1]=cma; 
  316. sa[2]=-sma; 
  317. sa[3]=-cma;
  318.     sb[0]=smb; 
  319. sb[1]=cmb; 
  320. sb[2]=-smb; 
  321. sb[3]=-cmb;
  322.     ca[0]=cma; 
  323. ca[1]=-sma; 
  324. ca[2]=-cma; 
  325. ca[3]=sma;
  326.     cb[0]=cmb; 
  327. cb[1]=-smb; 
  328. cb[2]=-cmb; 
  329. cb[3]=smb;
  330.     s[0]=0.0; 
  331. s[1]=0.0;
  332.     
  333. mm=1;
  334.     
  335. // 循环迭代
  336. for (k=0;k<=n-1;k++)
  337.     { 
  338. j=k;
  339.         while (j>=4) 
  340. j=j-4;
  341.         
  342. mm=mm*m;
  343.         s[0]=s[0]+(fb[k]*sb[j]-fa[k]*sa[j])/(1.0*mm);
  344.         s[1]=s[1]+(fb[k]*cb[j]-fa[k]*ca[j])/(1.0*mm);
  345.     }
  346.     
  347. s[1]=-s[1];
  348. return s[0];
  349. }
  350. //////////////////////////////////////////////////////////////////////
  351. // 勒让德-高斯求积法
  352. //
  353. // 调用时,须覆盖计算函数f(x)值的虚函数double Func(double x)
  354. //
  355. // 参数:
  356. // 1. a - Double型变量,积分下限
  357. // 2. b - Double型变量,积分上限,要求b>a
  358. // 3. eps - Double型变量,积分精度要求
  359. //
  360. // 返回值:double 型,积分值
  361. //////////////////////////////////////////////////////////////////////
  362. double CIntegral::GetValueLegdGauss(double a, double b, double eps /*= 0.000001*/)
  363.     int m,i,j;
  364.     double s,p,ep,h,aa,bb,w,x,g;
  365. // 勒让德-高斯求积系数
  366.     static double t[5]={-0.9061798459,-0.5384693101,0.0,
  367.                          0.5384693101,0.9061798459};
  368.     static double c[5]={0.2369268851,0.4786286705,0.5688888889,
  369.                         0.4786286705,0.2369268851};
  370. // 迭代初值
  371.     m=1;
  372.     h=b-a; 
  373. s=fabs(0.001*h);
  374.     p=1.0e+35; 
  375. ep=eps+1.0;
  376.     
  377. // 迭代计算
  378. while ((ep>=eps)&&(fabs(h)>s))
  379.     { 
  380. g=0.0;
  381.         for (i=1;i<=m;i++)
  382.         { 
  383. aa=a+(i-1.0)*h; 
  384. bb=a+i*h;
  385.             w=0.0;
  386.             for (j=0;j<=4;j++)
  387.             { 
  388. x=((bb-aa)*t[j]+(bb+aa))/2.0;
  389.                 w=w+Func(x)*c[j];
  390.             }
  391.             
  392. g=g+w;
  393.         }
  394.         
  395. g=g*h/2.0;
  396.         ep=fabs(g-p)/(1.0+fabs(g));
  397.         p=g; 
  398. m=m+1; 
  399. h=(b-a)/m;
  400.     }
  401.     
  402. return(g);
  403. }
  404. //////////////////////////////////////////////////////////////////////
  405. // 拉盖尔-高斯求积法
  406. //
  407. // 调用时,须覆盖计算函数f(x)值的虚函数double Func(double x)
  408. //
  409. // 参数:无
  410. //
  411. // 返回值:double 型,积分值
  412. //////////////////////////////////////////////////////////////////////
  413. double CIntegral::GetValueLgreGauss()
  414. int i;
  415.     double x,g;
  416. // 拉盖尔-高斯求积系数
  417.     static double t[5]={0.26355990, 1.41340290, 3.59642600, 7.08580990, 12.64080000};
  418.     static double c[5]={0.6790941054, 1.638487956, 2.769426772, 4.315944000, 7.104896230};
  419. // 循环计算
  420.     g=0.0;
  421.     for (i=0; i<=4; i++)
  422.     { 
  423. x=t[i]; 
  424. g=g+c[i]*Func(x); 
  425. }
  426.     
  427. return(g);
  428. }
  429. //////////////////////////////////////////////////////////////////////
  430. // 埃尔米特-高斯求积法
  431. //
  432. // 调用时,须覆盖计算函数f(x)值的虚函数double Func(double x)
  433. //
  434. // 参数:无
  435. //
  436. // 返回值:double 型,积分值
  437. //////////////////////////////////////////////////////////////////////
  438. double CIntegral::GetValueHermiteGauss()
  439. int i;
  440.     double x,g;
  441. // 埃尔米特-高斯求积系数
  442.     static double t[5]={-2.02018200, -0.95857190, 0.0,0.95857190, 2.02018200};
  443.     static double c[5]={1.181469599, 0.9865791417, 0.9453089237, 0.9865791417, 1.181469599};
  444. // 循环计算
  445.     g=0.0;
  446.     for (i=0; i<=4; i++)
  447.     { 
  448. x=t[i]; 
  449. g=g+c[i]*Func(x); 
  450. }
  451.     
  452. return(g);
  453. }