Integral.inl
上传用户:fxromeo
上传日期:2010-04-08
资源大小:89k
文件大小:14k
开发平台:

Visual C++

  1. // Integral.inl 数值积分头文件
  2. // Ver 1.0.0.0
  3. // 版权所有(C) 2002
  4. // 最后修改: 2002.5.31.
  5. #ifndef _INTEGRAL_INL //避免多次编译
  6. #define _INTEGRAL_INL
  7. //变步长梯形法求积
  8. template <class _Ty>
  9. _Ty IntegralTrapezia(_Ty a, _Ty b, _Ty eps)
  10. {
  11. _Ty t;
  12.     _Ty fa = FunctionValueIT(a);
  13. _Ty fb = FunctionValueIT(b);
  14.     int n(1);
  15. _Ty h = b - a;
  16.     _Ty t1 = h * (fa + fb) / 2.0;
  17.     _Ty p = eps + 1.0;
  18.     while(p > eps || FloatEqual(p, eps))
  19.     {
  20. _Ty s(0);
  21.         for(int k=0; k<n; k++)
  22.         {
  23. _Ty x = a + (k + 0.5) * h;
  24.             s = s + FunctionValueIT(x);
  25.           }
  26.         t = (t1 + h * s) / 2.0;
  27.         p = Abs(t1 - t);
  28.         t1 = t;
  29. n = n + n;
  30. h = h / 2.0;
  31.     }
  32.     return(t);
  33. }
  34. //变步长辛卜生法求积
  35. template <class _Ty>
  36. _Ty IntegralSimpson1D(_Ty a, _Ty b, _Ty eps)
  37. {
  38.     _Ty s2;
  39.     int n(1);
  40. _Ty h = b - a; //步长
  41.     _Ty t1 = h * (FunctionValueIS1D(a) + FunctionValueIS1D(b)) / 2.0;
  42.     _Ty s1 = t1;
  43.     _Ty ep = eps + 1.0;
  44.     while(ep > eps || FloatEqual(ep, eps))
  45.     {
  46. _Ty p(0);
  47.         for(int k=0; k<n; k++)
  48.         {
  49. _Ty x = a + (k + 0.5) * h;
  50.             p = p + FunctionValueIS1D(x);
  51.         }
  52.         _Ty t2 = (t1 + h * p) / 2.0;
  53.         s2 = (4.0 * t2 - t1) / 3.0;
  54.         ep = Abs(s2 - s1);
  55.         t1 = t2;
  56. s1 = s2;
  57. n = n + n;
  58. h = h / 2.0;
  59.     }
  60.     return(s2);
  61. }
  62. //自适应梯形法求积
  63. template <class _Ty>
  64. _Ty IntegralTrapeziaSelfAdapt(_Ty a, _Ty b, _Ty eps, _Ty d)
  65. {
  66.     valarray<_Ty> t(2);
  67.     _Ty h = b - a;
  68. t[0]=0.0;
  69.     _Ty f0 = FunctionValueITSA(a);
  70. _Ty f1 = FunctionValueITSA(b);
  71.     _Ty t0 = h * (f0 + f1) / 2.0;
  72.     ITSA(a,b,h,f0,f1,t0,eps,d,t);
  73.     _Ty z = t[0];
  74. return(z);
  75. }
  76. //自适应梯形法求积辅助函数
  77. template <class _Ty>
  78. int ITSA(_Ty x0, _Ty x1, _Ty h, _Ty f0, _Ty f1, _Ty t0, 
  79. _Ty eps, _Ty d, valarray<_Ty>& t)
  80.     _Ty x = x0 + h / 2.0;
  81. _Ty f = FunctionValueITSA(x);
  82.     _Ty t1=h*(f0+f)/4.0;
  83. _Ty t2=h*(f+f1)/4.0;
  84.     _Ty p=Abs(t0-(t1+t2));
  85.     if((p<eps)||(h/2.0<d))
  86. {
  87. t[0]=t[0]+(t1+t2);
  88. return(0);
  89. }
  90.     else
  91.     {
  92. _Ty g=h/2.0; 
  93. _Ty eps1=eps/1.4;
  94.         ITSA(x0,x,g,f0,f,t1,eps1,d,t);
  95.         ITSA(x,x1,g,f,f1,t2,eps1,d,t);
  96.         return(1);
  97.     }
  98. }
  99. //龙贝格法求积
  100. template <class _Ty>
  101. _Ty IntegralRomberg(_Ty a, _Ty b, _Ty eps)
  102. {
  103.     _Ty y[10], q;
  104.     _Ty h = b - a; //步长
  105.     y[0] = h * (FunctionValueR(a) + FunctionValueR(b)) / 2.0;
  106.     int m(1), n(1);
  107. _Ty ep=eps+1.0;
  108.     while((ep>eps || FloatEqual(ep,eps)) && (m <= 9))
  109.     {
  110. _Ty p(0);
  111.         for(int i=0;i<n;i++)
  112.         {
  113. _Ty x = a + (i + 0.5) * h;
  114.             p = p + FunctionValueR(x);
  115.         }
  116.         p = (y[0] + h * p) / 2.0;
  117.         _Ty s(1);
  118.         for(int k=1; k<=m; k++)
  119.         {
  120. s = 4.0 * s;
  121.             q = (s * p - y[k-1]) / (s - 1.0);
  122.             y[k-1] = p;
  123. p = q;
  124.         }
  125.         ep = Abs(q - y[m-1]);
  126.         m = m + 1;
  127. y[m-1] = q; 
  128. n = n + n;
  129. h = h / 2.0;
  130.     }
  131.     return(q);
  132. }
  133. //一维连分式法求积
  134. template <class _Ty>
  135. _Ty IntegralFraction1D(_Ty a, _Ty b, _Ty eps)
  136. {
  137.     valarray<_Ty> h(10), bb(10);
  138.     int m(1), n(1), k, l, j;
  139.     _Ty g, hh = b - a;
  140. h[0] = hh;
  141.     _Ty t1 = hh * (FunctionValueF1D(a) + FunctionValueF1D(b)) / 2.0;
  142.     _Ty s1 = t1;
  143. bb[0]=s1;
  144. _Ty ep = 1.0 + eps;
  145.     while((ep>eps || FloatEqual(ep,eps)) && (m <= 9))
  146.     { 
  147. _Ty s(0);
  148.         for(k=0; k<n; k++)
  149.         {
  150. _Ty x = a + (k + 0.5) * hh;
  151.             s = s + FunctionValueF1D(x);
  152.         }
  153.         _Ty t2 = (t1 + hh * s) / 2.0;
  154.         m++;
  155.         h[m-1] = h[m-2] / 2.0;
  156.         g = t2;
  157.         l = 0;
  158. j = 2;
  159.         while((l==0) && (j<=m))
  160.         {
  161. s = g - bb[j-2];
  162.             if(FloatEqual(s,0)) l = 1;
  163.             else g = (h[m-1] - h[j-2]) / s;
  164.             j++;
  165.         }
  166.         bb[m-1] = g;
  167.         if(l!=0) bb[m-1] = 1.0e+35;
  168.         g = bb[m-1];
  169.         for(j=m; j>=2; j--) g = bb[j-2] - h[j-2] / g;
  170.         ep = Abs(g-s1);
  171.         s1 = g;
  172. t1 = t2;
  173. hh = hh / 2.0;
  174. n = n + n;
  175.     }
  176.     return(g);
  177. }
  178. //高振荡函数法求积
  179. template <class _Ty>
  180. void IntegralSurge(_Ty a, _Ty b, int m, valarray<_Ty>& fa, 
  181. valarray<_Ty>& fb, valarray<_Ty>& s)
  182. {
  183.     _Ty sa[4],sb[4],ca[4],cb[4];
  184. int n = fa.size(); //给定积分区间两端点上的导数最高阶数+1
  185. int mm=1;
  186.     _Ty sma=sin(m*a);
  187. _Ty smb=sin(m*b);
  188.     _Ty cma=cos(m*a);
  189. _Ty cmb=cos(m*b);
  190.     
  191. sa[0] = ca[3] = sma;
  192. sa[1] = ca[0] = cma;
  193. sa[2] = ca[1] = -sma; 
  194. sa[3] = ca[2] = -cma;
  195.     sb[0] = cb[3] = smb;
  196. sb[1] = cb[0] = cmb;
  197. sb[2] = cb[1] = -smb;
  198. sb[3] = cb[2] = -cmb;
  199.     s[0] = s[1] = 0.0; 
  200.     for(int k=0; k<n; k++)
  201.     {
  202. int j = k;
  203.         while(j>=4) j = j - 4;
  204.         mm = mm * m;
  205.         s[0] = s[0]+(fb[k]*sb[j]-fa[k]*sa[j])/(1.0*mm);
  206.         s[1] = s[1]+(fb[k]*cb[j]-fa[k]*ca[j])/(1.0*mm);
  207.     }
  208.     
  209. s[1] = -s[1];
  210. }
  211. //勒让德-高斯法求积
  212. template <class _Ty>
  213. _Ty IntegralLegendreGauss(_Ty a, _Ty b, _Ty eps)
  214. {
  215.     _Ty t[5] = 
  216. {
  217. -0.9061798459, -0.5384693101, 0.0, 0.5384693101, 0.9061798459
  218. };
  219.     
  220. _Ty c[5] = 
  221. {
  222. 0.2369268851, 0.4786286705, 0.5688888889, 0.4786286705, 0.2369268851
  223. };
  224.     int m(1);
  225. _Ty g;
  226.     _Ty h = b - a;
  227. _Ty s = Abs(0.001 * h);
  228.     _Ty p = 1.0e+35;
  229. _Ty ep = eps + 1.0;
  230.     while((ep > eps || FloatEqual(ep,eps)) && (Abs(h) > s))
  231.     {
  232. g = 0;
  233.         for(int i=1; i<=m; i++)
  234.         {
  235. _Ty aa = a + (i - 1.0) * h;
  236. _Ty bb = a + i * h;
  237.             _Ty w(0);
  238.             for(int j=0; j<5; j++)
  239.             {
  240. _Ty x = ((bb - aa) * t[j] + (bb + aa)) / 2.0;
  241.                 w = w + FunctionValueLegG(x) * c[j];
  242.             }
  243.             g += w;
  244.         }
  245.         g = g * h / 2.0;
  246.         ep = Abs(g - p) / (1.0 + Abs(g));
  247.         p = g;
  248. m++;
  249. h = (b - a) / m;
  250.     }
  251.     return(g);
  252. }
  253. //拉盖尔-高斯法求积
  254. template <class _Ty>
  255. void IntegralLaguerreGauss(_Ty& dValue)
  256. {
  257. _Ty x;
  258. dValue = 0.0;
  259.     long double t[5] = 
  260. 0.26355990, 1.41340290, 3.59642600, 7.08580990, 12.64080000
  261. };
  262.     
  263. long double c[5] = 
  264. {
  265. 0.6790941054, 1.638487956, 2.769426772, 4.315944000, 7.104896230
  266. };
  267.     
  268. for(int i=0; i<5; i++)
  269.     {
  270. x = t[i];
  271. dValue = dValue + c[i] * FunctionValueLagG(x); 
  272. }
  273. }
  274. //埃尔米特-高斯法求积
  275. template <class _Ty >
  276. void IntegralHermiteGauss(_Ty& dValue)
  277. {
  278.     _Ty t[5] = 
  279. {
  280. -2.02018200, -0.95857190, 0.0, 0.95857190, 2.02018200
  281. };
  282.     
  283. _Ty c[5] = 
  284. {
  285. 1.181469599, 0.9865791417,0.9453089237, 0.9865791417,1.181469599
  286. };
  287.     
  288. dValue = 0;
  289.     
  290. for(int i=0; i<5; i++)
  291.     {
  292. _Ty x = t[i];
  293. dValue = dValue + c[i] * FunctionValueHG(x);
  294. }
  295. }
  296. //切比雪夫法求积
  297. template <class _Ty >
  298. _Ty IntegralChebyshev(_Ty a, _Ty b, _Ty eps)
  299. {
  300. _Ty t[5]={-0.8324975, -0.3745414, 0.0, 0.3745414, 0.8324975};
  301. int m(1);
  302. _Ty g;
  303.     _Ty h = b - a;
  304. _Ty d = Abs(0.001 * h);
  305.     _Ty p = 1.0e+35;
  306. _Ty ep = eps + 1.0;
  307.     while((ep > eps || FloatEqual(ep,eps)) && (Abs(h) > d))
  308.     {
  309. g = 0.0;
  310.         for(int i=1; i<=m; i++)
  311.         {
  312. _Ty aa = a + (i - 1.0) * h;
  313. _Ty bb = a + i * h;
  314.             _Ty s(0);
  315. for(int j=0; j<5; j++)
  316.             {
  317. _Ty x = ((bb - aa) * t[j] + (bb + aa)) / 2.0;
  318.                 s = s + FunctionValueCb(x);
  319.             }
  320.             g += s;
  321.         }
  322.         g = g * h / 5.0;
  323.         ep = Abs(g - p) / (1.0 + Abs(g));
  324.         p = g;
  325. m++;
  326. h = (b - a) / m;
  327.     }
  328.     return(g);
  329. }
  330. //一维蒙特卡洛法求积
  331. template <class _Ty >
  332. _Ty IntegralMonteCarlo1D(_Ty a, _Ty b)
  333. {
  334.     _Ty r(1), s(0), d(10000);
  335.     for(int m=0; m<10000; m++)
  336.     {
  337. _Ty x = a + (b - a) * rand_01_One(r); //取随机数
  338.         s = s + FunctionValueMC1D(x) / d; //调用被积函数值
  339.     }
  340.     
  341. s = s * (b - a);
  342.     
  343. return(s);
  344. }
  345. //二重变步长辛卜生法求积
  346. template <class _Ty>
  347. _Ty IntegralSimpson2D(_Ty a, _Ty b, _Ty eps)
  348. {
  349. int n(1);
  350. _Ty h = 0.5 * (b - a); //步长
  351. _Ty d = Abs((b - a) * 1.0e-06);
  352.     _Ty s1 = IntegralSimp2(a, eps); //调用IntegralSimp2函数
  353. _Ty s2 = IntegralSimp2(b, eps);
  354.     _Ty t1 = h * (s1 + s2);
  355.     _Ty s0(1.0e+35), s;
  356. _Ty ep = eps + 1.0;
  357.     while((ep>eps||FloatEqual(ep,eps))&&((Abs(h)>d)||(n<16)))
  358. {
  359. _Ty x = a - h;
  360. _Ty t2 = 0.5 * t1;
  361.         for(int j=1; j<=n; j++)
  362.         {
  363. x = x + 2.0 * h;
  364.             t2 = t2 + h * IntegralSimp2(x,eps);
  365.         }
  366.         s = (4.0 * t2 - t1) / 3.0;
  367.         ep = Abs(s - s0) / (1.0 + Abs(s));
  368.         n = n + n;
  369. s0 = s;
  370. t1 = t2; 
  371. h = h * 0.5;
  372.     }
  373.     return(s);
  374. }
  375. //二重变步长辛卜生法求积辅助函数
  376. template <class _Ty>
  377. _Ty IntegralSimp2(_Ty x, _Ty eps)
  378. {
  379.     valarray<_Ty> y(2);
  380. int n(1);
  381.     FunctionBoundaryIS2D(x, y);
  382.     _Ty h = 0.5 *(y[1] - y[0]);
  383.     _Ty d = Abs(h * 2.0e-06);
  384.     _Ty t1 = h * (FunctionValueIS2D(x, y[0]) + FunctionValueIS2D(x, y[1]));
  385.     _Ty ep = 1.0 + eps;
  386. _Ty g0(1.0e+35), g;
  387.     while((ep>eps||FloatEqual(ep,eps))&&((Abs(h)>d)||(n<16)))
  388.     {
  389. _Ty yy = y[0] - h;
  390.         _Ty t2 = 0.5 * t1;
  391.         for(int i=1; i<=n; i++)
  392.         {
  393. yy = yy + 2.0 * h;
  394.             t2 = t2 + h * FunctionValueIS2D(x, yy);
  395.         }
  396.         g = (4.0 * t2 - t1) / 3.0;
  397.         ep = Abs(g - g0) / (1.0 + Abs(g));
  398.         n = n + n;
  399. g0 = g;
  400. t1 = t2;
  401. h = 0.5 * h;
  402.     }
  403.     return(g);
  404. }
  405. //多重高斯法求积
  406. template <class _Ty >
  407. _Ty IntegralGaussMD(valarray<_Ty>& js)
  408. {
  409.     valarray<_Ty> y(2);
  410. _Ty p, s;
  411.     _Ty t[5] = 
  412. {
  413. -0.9061798459,-0.5384693101,0.0, 0.5384693101,0.9061798459
  414. };
  415.     
  416. _Ty c[5] = 
  417. {
  418. 0.2369268851,0.4786286705,0.5688888889, 0.4786286705,0.2369268851
  419. };
  420. int n = js.size(); //积分重数
  421. valarray<int> is(2*(n+1));
  422.     valarray<_Ty> x(n);
  423.     valarray<_Ty> a(2*(n+1));
  424.     valarray<_Ty> b(n+1);
  425. int m(1), l(1);
  426.     
  427. a[n] = a[2*n+1] = 1.0;
  428.     while(l==1)
  429.     {
  430. for(int j=m; j<=n; j++)
  431.         {
  432. FunctionBoundaryGMD(j-1,x,y);
  433.             a[j-1]=0.5*(y[1]-y[0])/js[j-1];
  434.             b[j-1]=a[j-1]+y[0];
  435.             x[j-1]=a[j-1]*t[0]+b[j-1];
  436.             a[n+j]=0.0;
  437.             is[j-1]=1; is[n+j]=1;
  438.         }
  439.         j = n;
  440. int q = 1;
  441.         while(q==1)
  442.         {
  443. int k = is[j-1];
  444.             if(j==n) p = FunctionValueGMD(x);
  445.             else p = 1.0;
  446.             a[n+j]=a[n+j+1]*a[j]*p*c[k-1]+a[n+j];
  447.             is[j-1] = is[j-1] + 1;
  448.             if(is[j-1] > 5)
  449.               if(is[n+j] >= js[j-1])
  450.               {
  451.   j = j - 1;
  452.   q = 1;
  453.                   if(j==0)
  454.                   {
  455.   s = a[n+1] * a[0]; 
  456.                       return(s);
  457.                   }
  458.               }
  459.               else
  460.               {
  461.   is[n+j]=is[n+j]+1;
  462.                   b[j-1]=b[j-1]+a[j-1]*2.0;
  463.                   is[j-1]=1; k=is[j-1];
  464.                   x[j-1]=a[j-1]*t[k-1]+b[j-1];
  465.                   if(j==n) q = 1;
  466.                   else q = 0;
  467.               }
  468.             else
  469.             {
  470. k = is[j-1];
  471.                 x[j-1] = a[j-1]*t[k-1]+b[j-1];
  472.                 if(j==n) q = 1;
  473.                 else q = 0;
  474.             }
  475.         }
  476.         m = j + 1;
  477.     }
  478. }
  479. //二重连分式法求积
  480. template <class _Ty >
  481. _Ty IntegralFraction2D(_Ty a, _Ty b, _Ty eps)
  482. {
  483.     _Ty bb[10],h[10],x,s;
  484. int m(1), n(1);
  485.     _Ty hh = b - a;
  486. h[0] = hh;
  487.     _Ty s1 = IntegralFraction2D2(a, eps);
  488. _Ty s2 = IntegralFraction2D2(b, eps);
  489.     _Ty t1 = hh * (s1 + s2) / 2.0;
  490.     _Ty s0 = t1;
  491. bb[0] = t1;
  492. _Ty ep = 1.0 + eps;
  493.     while((ep > eps || FloatEqual(ep,eps)) && ( m <= 9))
  494.     {
  495. _Ty t2 = 0.5 * t1;
  496.         for(int k=0; k<n; k++)
  497.         {
  498. x = a + (k + 0.5) * hh;
  499.             s1 = IntegralFraction2D2(x,eps);
  500.             t2 = t2 + 0.5 * s1 * hh;
  501.         }
  502.         m = m + 1;
  503.         h[m-1] = h[m-2] / 2.0;
  504.         _Ty g = t2;
  505. int l(0), j(2);
  506.         while((l==0)&&(j<=m))
  507.          {
  508. s = g - bb[j-2];
  509.             if(FloatEqual(s,0)) l = 1;
  510.             else g = (h[m-1] - h[j-2]) / s;
  511.             j = j + 1;
  512.         }
  513.         bb[m-1] = g;
  514.         if(l!=0) bb[m-1] = 1.0e+35;
  515.         s = bb[m-1];
  516.         for(j=m; j>=2; j--) s = bb[j-2] -h [j-2] / s;
  517.         ep = Abs(s-s0) / (1.0 + Abs(s));
  518.         n = n + n;
  519. t1 = t2; 
  520. s0 = s;
  521. hh = hh / 2.0;
  522.     }
  523.     return(s);
  524. }
  525. //二重连分式法求积辅助函数
  526. template <class _Ty>
  527. _Ty IntegralFraction2D2(_Ty x, _Ty eps)
  528. {
  529.     _Ty b[10],h[10],yy,s;
  530. valarray<_Ty> y(2);
  531.     int m(1), n(1);
  532.     FunctionBoundaryF2D(x, y);
  533.     _Ty hh = y[1] - y[0];
  534. h[0] = hh;
  535.     _Ty t1=0.5*hh*(FunctionValueF2D(x,y[0])+FunctionValueF2D(x,y[1]));
  536.     _Ty s0 = t1;
  537. b[0] = t1;
  538. _Ty ep = 1.0 + eps;
  539.     while((ep > eps || FloatEqual(ep, eps)) && (m <= 9))
  540.     {
  541. _Ty t2 = 0.5 * t1;
  542.         for(int k=0; k<n; k++)
  543.         {
  544. yy = y[0] +(k + 0.5) * hh;
  545.             t2 = t2 + 0.5 * hh * FunctionValueF2D(x, yy);
  546. }
  547.         m = m + 1;
  548.         h[m-1] = h[m-2] / 2.0;
  549.         _Ty g = t2;
  550. int l(0), j(2);
  551.         while((l==0)&&(j<=m))
  552.         {
  553. s = g - b[j-2];
  554.             if(FloatEqual(s,0)) l = 1;
  555.             else g = (h[m-1] - h[j-2]) / s;
  556.             j = j + 1;
  557.         }
  558.         b[m-1] = g;
  559.         if(l!=0) b[m-1] = 1.0e+35;
  560.         s = b[m-1];
  561.         for(j=m; j>=2; j--) s = b[j-2] - h[j-2] / s;
  562.         ep = Abs(s - s0) / (1.0 + Abs(s));
  563.         n = n + n;
  564. t1 = t2;
  565. s0 = s;
  566. hh = 0.5 * hh;
  567.     }
  568.     return(s);
  569. }
  570. //多重蒙特卡洛法求积
  571. template <class _Ty >
  572. _Ty IntegralMonteCarlo2D(valarray<_Ty>& a, valarray<_Ty>& b)
  573. {
  574. int i;
  575. int n = a.size(); //积分的重数
  576. valarray<_Ty> x(n);
  577.     _Ty r(1), d(10000), s(0);
  578.     for(int m=0; m<10000; m++)
  579.     {
  580. for(i=0; i<n; i++)
  581. x[i] = a[i] + (b[i] - a[i]) * rand_01_One(r);
  582.         s = s + FunctionValueMC2D(n, x) / d;
  583.     }
  584.     
  585. for(i=0; i<n; i++) s = s * (b[i] - a[i]);
  586.     
  587. return(s);
  588. }
  589. #endif // _INTEGRAL_INL