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

Visual C++

  1. //OrdinaryDifferentialEguation.inl 求解常微分方程(组)头文件
  2. // Ver 1.0.0.0
  3. // 版权所有(C) 何渝, 2002
  4. // 最后修改: 2002.5.31.
  5. #ifndef _ORDINARYDIFFERENTIALEGUATION_INL //避免多次编译
  6. #define _ORDINARYDIFFERENTIALEGUATION_INL
  7. //定步长全区间积分的欧拉法
  8. template <class _Ty>
  9. void ODE_EulerContentStep(_Ty t, valarray<_Ty>& y,  
  10. _Ty h, int k, matrix<_Ty>& z)
  11. {
  12. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  13. valarray<_Ty> d(n);
  14.     for(int i=0; i<n; i++)
  15. z(i,0)=y[i];
  16.     for(int j=1; j<k; j++)
  17. _Ty x=t+(j-1)*h;
  18.         FunctionValueECS(x,y,d);
  19.         for(i=0; i<n; i++)
  20.           y[i]=z(i,j-1)+h*d[i];
  21.         x=t+j*h;
  22.         FunctionValueECS(x,y,d);
  23.         for(i=0; i<n; i++)
  24.           d[i]=z(i,j-1)+h*d[i];
  25.         for(i=0; i<n; i++)
  26. y[i]=(y[i]+d[i])/2.0;
  27.             z(i,j)=y[i];
  28. }
  29. }
  30. }
  31. //变步长积分欧拉法
  32. template <class _Ty>
  33. void ODE_EulerVariationalStep(_Ty t, _Ty h, valarray<_Ty>& y, _Ty eps)
  34. {
  35. int j, m(1);
  36.     _Ty p(1.0+eps), x, q, hh=h;
  37. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  38.     valarray<_Ty> a(n), b(n), c(n), d(n);
  39.     for(int i=0; i<n; i++) a[i] = y[i];
  40.     while(p>eps || FloatEqual(p,eps))
  41. for(i=0; i<n; i++)
  42. {
  43. b[i]=y[i];
  44. y[i]=a[i];
  45. }
  46.         for(j=0; j<m; j++)
  47. {
  48. for(i=0; i<n; i++) c[i]=y[i];
  49.             x=t+j*hh;
  50.             FunctionValueEVS(x,y,d);
  51.             for(i=0; i<n; i++)
  52. y[i]=c[i]+hh*d[i];
  53.             x=t+(j+1)*hh;
  54.             FunctionValueEVS(x,y,d);
  55.             for(i=0; i<n; i++)
  56. d[i]=c[i]+hh*d[i];
  57.             for(i=0; i<n; i++)
  58. y[i]=(y[i]+d[i])/2.0;
  59. }
  60.         p = 0.0;
  61.         for(i=0; i<n; i++)
  62. q=Abs(y[i]-b[i]);
  63.             if(q>p) p=q;
  64.         }
  65.         hh /= 2.0;
  66. m = m + m;
  67.     }
  68. }
  69. //全区间定步长积分维梯法
  70. template <class _Ty>
  71. void ODE_WittyContentStep(_Ty t, valarray<_Ty>& y,  
  72. _Ty h, int k, matrix<_Ty>& z)
  73. {
  74.     int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  75. valarray<_Ty> a(n), d(n);
  76.     for(int i=0; i<n; i++) z(i,0)=y[i];
  77.     FunctionValueWCS(t,y,d);
  78.     for(int j=1; j<k; j++)
  79.     { 
  80. for(i=0; i<n; i++)
  81. a[i]=z(i,j-1)+h*d[i]/2.0;
  82.         _Ty x=t+(j-0.5)*h;
  83.         FunctionValueWCS(x,a,y);
  84.         for(i=0; i<n; i++)
  85.         { 
  86. d[i]=2.0*y[i]-d[i];
  87.             z(i,j)=z(i,j-1)+h*y[i];
  88.         }
  89.     }
  90. }
  91. //全区间定步长积分龙格-库塔法
  92. template <class _Ty>
  93. void ODE_RungeKuttaContentStep(_Ty t, valarray<_Ty>& y,  
  94. _Ty h, int k, matrix<_Ty>& z)
  95. {
  96.     _Ty a[4], tt;
  97. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  98. valarray<_Ty> b(n), d(n);
  99.     a[0] = h / 2.0;
  100. a[1] = a[0];
  101.     a[2] = a[3] = h;
  102.     for(int i=0; i<n; i++) z(i,0)=y[i];
  103.     for(int l=1; l<k; l++)
  104.     { 
  105. FunctionValueRKCS(t, y, d);
  106.         for(i=0; i<n; i++) b[i]=y[i];
  107.         for(int j=0; j<=2; j++)
  108.         {
  109. for(i=0; i<n; i++)
  110.             {
  111. y[i]=z(i,l-1)+a[j]*d[i];
  112.                 b[i]=b[i]+a[j+1]*d[i]/3.0;
  113.             }
  114.             tt=t+a[j];
  115.             FunctionValueRKCS(tt, y, d);
  116.         }
  117.         for(i=0; i<n; i++)
  118.           y[i]=b[i]+h*d[i]/6.0;
  119.         for(i=0; i<n; i++)
  120.           z(i,l)=y[i];
  121.         t=t+h;
  122.     }
  123. }
  124. //变步长积分龙格-库塔法
  125. template <class _Ty>
  126. void ODE_RungeKuttaVariationalStep(_Ty t, _Ty h, 
  127. valarray<_Ty>& y, _Ty eps)
  128. {
  129. int m(1), j, k;
  130.     _Ty hh(h), dt,x(t),tt,q,a[4];
  131. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  132. valarray<_Ty> g(n), b(n), c(n), d(n), e(n);
  133.     _Ty p=1.0+eps;
  134.     for(int i=0; i<n; i++) c[i]=y[i];
  135.     while(p>eps || FloatEqual(p,eps))
  136.     {
  137. a[0]=hh/2.0; 
  138. a[1]=a[0];
  139. a[2] = a[3] = hh;
  140.         for(i=0; i<n; i++)
  141.         {
  142. g[i]=y[i];
  143. y[i]=c[i];
  144. }
  145.         dt=h/m; 
  146. t=x;
  147.         for(j=0; j<m; j++)
  148.         {
  149. FunctionValueRKVS(t, y, d);
  150.             for(i=0; i<n; i++) 
  151.             {
  152. b[i]=y[i]; 
  153. e[i]=y[i];
  154. }
  155.             for(k=0; k<=2; k++)
  156.             {
  157. for(i=0; i<n; i++)
  158. {
  159. y[i]=e[i]+a[k]*d[i];
  160.                     b[i]=b[i]+a[k+1]*d[i]/3.0;
  161.                 }
  162.                 tt=t+a[k];
  163.                 FunctionValueRKVS(tt, y, d);
  164.             }
  165.             for(i=0; i<n; i++)
  166.               y[i]=b[i]+hh*d[i]/6.0;
  167.             t += dt;
  168.         }
  169.         p = 0.0;
  170.         for(i=0; i<n; i++)
  171.         {
  172. q = Abs(y[i]-g[i]);
  173.             if(q>p) p = q;
  174.         }
  175.         hh /= 2.0;
  176. m = m + m;
  177.     }
  178. }
  179. //变步长积分基尔法
  180. template <class _Ty>
  181. void ODE_GillVariationalStep(_Ty t, _Ty h, valarray<_Ty>& y,
  182. _Ty eps, valarray<_Ty>& q)
  183. {
  184.     int i,k,m(1),ii;
  185.     _Ty x(t),hh(h),r,s,t0,dt,qq;
  186.     _Ty a[4]={0.5, 0.29289321881, 1.7071067812, 0.166666667};
  187.     _Ty b[4]={2.0,1.0,1.0,2.0};
  188.     _Ty c[4],e[4]={0.5,0.5,1.0,1.0};
  189. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  190. valarray<_Ty> g(n), u(n), v(n), d(n);
  191.     for(i=0; i<3; i++) c[i]=a[i];
  192.     c[3]=0.5;
  193.     _Ty p=1.0+eps;
  194.     for(int j=0; j<n; j++) u[j]=y[j];
  195.     while(p>eps || FloatEqual(p,eps))
  196.     {
  197. for(j=0; j<n; j++)
  198. {
  199. v[j]=y[j];
  200. y[j]=u[j];
  201. g[j]=q[j];
  202. }
  203.         dt=h/m; 
  204. t=x;
  205.         for(k=0; k<m; k++)
  206.         { 
  207. FunctionValueGVS(t,y,d);
  208.             for(ii=0; ii<=3; ii++)
  209.             {
  210. for(j=0; j<n; j++)
  211.                   d[j]=d[j]*hh;
  212.                 for(j=0; j<n; j++)
  213.                 {
  214. r=(a[ii]*(d[j]-b[ii]*g[j])+y[j])-y[j];
  215.                     y[j]=y[j]+r;
  216.                     s=g[j]+3.0*r;
  217.                     g[j]=s-c[ii]*d[j];
  218.                 }
  219.                 t0=t+e[ii]*hh;
  220.                 FunctionValueGVS(t0,y,d);
  221.             }
  222.             t=t+dt;
  223.         }
  224.         p=0.0;
  225.         for(j=0; j<n; j++)
  226.         {
  227. qq=Abs(y[j]-v[j]);
  228.             if(qq>p) p=qq;
  229.         }
  230.         hh=hh/2.0; 
  231. m=m+m;
  232.     }
  233.     for(j=0; j<n; j++) q[j]=g[j];
  234. }
  235. //全区间变步长积分基尔法
  236. template <class _Ty>
  237. void ODE_GillVariationalStepInterval(_Ty t, _Ty h, valarray<_Ty>& y,
  238. _Ty eps, int k, matrix<_Ty>& z)
  239. {
  240.     int j,m,kk,ii;
  241.     _Ty aa(t),hh,x,p,dt,r,s,t0,qq;
  242.     _Ty a[4]={0.5, 0.29289321881, 1.7071067812, 0.166666667};
  243.     _Ty b[4]={2.0,1.0,1.0,2.0};
  244.     _Ty c[4],e[4]={0.5,0.5,1.0,1.0};
  245. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  246. valarray<_Ty> g(n), q(n), u(n), v(n), d(n);
  247.     
  248.     for(int i=0; i<3; i++) c[i]=a[i];
  249.     c[3]=0.5;
  250.     
  251.     for(i=0; i<n; i++) 
  252.     {
  253. z(i,0) = y[i];
  254. q[i] = 0.0;
  255. }
  256.     for(i=2; i<=k; i++)
  257.     {
  258. x=aa+(i-2)*h;
  259. m=1;
  260. hh=h;
  261.         p=1.0+eps;
  262.         for(j=0; j<n; j++) u[j]=y[j];
  263.         while(p>eps || FloatEqual(p,eps))
  264.         {
  265. for(j=0; j<n; j++)
  266. v[j]=y[j];
  267. y[j]=u[j];
  268. g[j]=q[j];
  269. }
  270.             dt=h/m; 
  271. t=x;
  272.             for(kk=0; kk<m; kk++)
  273.             {
  274. FunctionValueGVSI(t,y,d);
  275.                 for(ii=0; ii<4; ii++)
  276.                 {
  277. for(j=0; j<n; j++)
  278.                       d[j]=d[j]*hh;
  279.                     for(j=0; j<n; j++)
  280.                     {
  281. r=(a[ii]*(d[j]-b[ii]*g[j])+y[j])-y[j];
  282.                         y[j]=y[j]+r;
  283.                         s=g[j]+3.0*r;
  284.                         g[j]=s-c[ii]*d[j];
  285.                     }
  286.                     t0=t+e[ii]*hh;
  287.                     FunctionValueGVSI(t0,y,d);
  288.                 }
  289.                 t += dt;
  290.             }
  291.             p=0.0;
  292.             for(j=0; j<n; j++)
  293.             { 
  294. qq=Abs(y[j]-v[j]);
  295.                 if(qq>p) p=qq;
  296.             }
  297.             hh /= 2.0; 
  298. m=m+m;
  299.         }
  300.         for(j=0; j<n; j++)
  301.         { 
  302. q[j]=g[j];
  303. z(j,i-1)=y[j];
  304. }
  305.     }
  306. }
  307. //变步长积分默森法
  308. template <class _Ty>
  309. void ODE_MersonVariationalStep(_Ty t, _Ty h, int n, valarray<_Ty>& y,
  310. _Ty eps, int k, matrix<_Ty>& z)
  311. {
  312.     int j,m,nn;
  313.     _Ty aa(t),bb,x,hh,p,dt,t0,qq;
  314.     valarray<_Ty> a(n), b(n), c(n), u(n), v(n), d(n);
  315.         
  316.     for(int i=0; i<n; i++) z(i,0)=y[i];
  317.     for(i=1; i<k; i++)
  318.     { 
  319. x=aa+(i-1)*h; 
  320. nn=1; 
  321. hh=h;
  322.         for(j=0; j<n; j++) u[j]=y[j];
  323.         p=1.0+eps;
  324.         while(p>eps || FloatEqual(p,eps))
  325.         {
  326. for(j=0; j<n; j++)
  327. {
  328. v[j]=y[j]; 
  329. y[j]=u[j];
  330. }
  331.             dt=h/nn; t=x;
  332.             for(m=0; m<nn; m++)
  333. FunctionValueMVS(t,y,d);
  334.                 for(j=0; j<n; j++)
  335.                 {
  336. a[j]=d[j];
  337. y[j]=y[j]+hh*d[j]/3.0;
  338. }
  339.                 t0=t+hh/3.0;
  340.                 FunctionValueMVS(t0,y,d);
  341.                 for(j=0; j<n; j++)
  342.                 {
  343. b[j]=d[j];
  344. y[j]=y[j]+hh*(d[j]-a[j])/6.0;
  345. }
  346.                 FunctionValueMVS(t0,y,d);
  347.                 for(j=0; j<n; j++)
  348.                 {
  349. b[j]=d[j];
  350.                     bb=(d[j]-4.0*(b[j]+a[j]/4.0)/9.0)/8.0;
  351.                     y[j]=y[j]+3.0*hh*bb;
  352.                 }
  353.                 t0=t+hh/2.0;
  354.                 FunctionValueMVS(t0,y,d);
  355.                 for(j=0; j<n; j++)
  356.                 { c[j]=d[j];
  357.                     qq=d[j]-15.0*(b[j]-a[j]/5.0)/16.0;
  358.                     y[j]=y[j]+2.0*hh*qq;
  359.                 }
  360.                 t0=t+hh;
  361.                 FunctionValueMVS(t0,y,d);
  362.                 for(j=0; j<n; j++)
  363.                 { 
  364. qq=c[j]-9.0*(b[j]-2.0*a[j]/9.0)/8.0;
  365.                     qq=d[j]-8.0*qq;
  366.                     y[j]=y[j]+hh*qq/6.0;
  367.                 }
  368.                 t += dt;
  369.             }
  370.             p=0.0;
  371.             for(j=0; j<n; j++)
  372.             { qq=Abs(y[j]-v[j]);
  373.                 if(qq>p) p=qq;
  374.             }
  375.             hh /= 2.0;
  376. nn=nn+nn;
  377.         }
  378.         for(j=0; j<n; j++) z(j,i)=y[j];
  379.     }
  380. }
  381. //积分一步连分式法
  382. template <class _Ty>
  383. void ODE_Fraction(_Ty t, _Ty h, valarray<_Ty>& y, _Ty eps)
  384. {
  385. int i,j,k(1),m,nn(1),it(1);
  386. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  387.     _Ty x(t),hh(h),dd,q,p,g[10];
  388. valarray<_Ty> e(n), b(10*n), w(n), u(n), v(n), d(n);
  389.     for(j=0; j<n; j++) v[j]=y[j];
  390. g[0]=hh;
  391.     Fraction1(x,hh,y,w,d,e);
  392.     for(j=0; j<n; j++)
  393.     { 
  394. b[j]=y[j];
  395. u[j]=y[j];
  396. }
  397.     while(it==1)
  398.     { 
  399. nn=nn+nn; 
  400. hh=hh/2.0;
  401. it=0;
  402.         g[k]=hh;
  403.         for(j=0; j<n; j++) y[j]=v[j];
  404.         t=x;
  405.         for(j=0; j<nn; j++)
  406.         { 
  407. Fraction1(t,hh,y,w,d,e);
  408.             t=t+hh;
  409.         }
  410.         for(j=0; j<n; j++)
  411.         { 
  412. dd=y[j]; 
  413. m=0;
  414.             for(i=0; i<k; i++)
  415.               if(m==0)
  416.               {
  417.   q=dd-b[i*n+j];
  418.                   if(FloatEqual(q,0.0)) m=1;
  419.                   else dd=(g[k]-g[i])/q;
  420.               }
  421.             b[k*n+j]=dd;
  422.             if(m!=0) b[k*n+j]=1.0e+35;
  423.         }
  424.         for(j=0; j<n; j++)
  425.         {
  426. dd=0.0;
  427.             for(i=k-1; i>=0; i--)
  428. dd=-g[i]/(b[(i+1)*n+j]+dd);
  429.             y[j]=dd+b[j];
  430.         }
  431.         p=0.0;
  432.         for(j=0; j<n; j++)
  433.         { 
  434. q=Abs(y[j]-u[j]);
  435.             if(q>p) p=q;
  436.         }
  437.         if((p>eps || FloatEqual(p,eps))&&(k<7))
  438.         { 
  439. for(j=0; j<n; j++) u[j]=y[j];
  440.             k=k+1; 
  441. it=1;
  442.         }
  443.     }
  444. }
  445. //积分一步连分式法ODE_Fraction()辅助函数
  446. template <class _Ty>
  447. void Fraction1(_Ty t, _Ty h, valarray<_Ty>& y, valarray<_Ty>& b, 
  448. valarray<_Ty>& d, valarray<_Ty>& e)
  449. {
  450.     _Ty a[4],tt;
  451. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  452.     
  453. a[0]=h/2.0;
  454. a[1]=a[0];
  455. a[2]=h; 
  456. a[3]=h;
  457.     FunctionValueF(t,y,d);
  458.     for(int i=0; i<n; i++)
  459. {
  460. b[i]=y[i];
  461. e[i]=y[i];
  462. }
  463.     for(int k=0; k<=2; k++)
  464.     {
  465. for(i=0; i<n; i++)
  466.         {
  467. y[i]=e[i]+a[k]*d[i];
  468.             b[i]=b[i]+a[k+1]*d[i]/3.0;
  469.         }
  470.         tt=t+a[k];
  471.         FunctionValueF(tt,y,d);
  472.     }
  473.     for(i=0; i<n; i++)
  474.       y[i]=b[i]+h*d[i]/6.0;
  475. }
  476. //全区间积分连分式法
  477. template <class _Ty>
  478. void ODE_FractionInterval(_Ty t, _Ty h, valarray<_Ty>& y,
  479. _Ty eps, int k, matrix<_Ty>& z)
  480. {
  481. int j,kk,l,m,nn,it;
  482.     _Ty x,hh,dd,tt,q,p,g[10];
  483. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  484. valarray<_Ty> e(n), b(10*n), w(n), u(n), v(n), d(n);
  485.     for(int i=0; i<n; i++) z(i,0)=y[i];
  486.     for(i=1; i<k; i++)
  487.     { 
  488. for(j=0; j<n; j++) v[j]=y[j];
  489.         x=t+(i-1)*h; 
  490. nn=1; 
  491. hh=h; 
  492. g[0]=hh;
  493.         Fraction2(x,hh,y,w,d,e);
  494.         for(j=0; j<n; j++)
  495.         {
  496. b[j]=y[j];
  497. u[j]=y[j];
  498. }
  499.         kk=1;
  500. it=1;
  501.         while(it==1)
  502.         {
  503. nn=nn+nn; 
  504. hh=hh/2.0;
  505. it=0;
  506.             g[kk]=hh;
  507.             for(j=0; j<n; j++) y[j]=v[j];
  508.             tt=x;
  509.             for(j=0; j<nn; j++)
  510.             {
  511. Fraction2(t,hh,y,w,d,e);
  512.                 tt=tt+hh;
  513.             }
  514.             for(j=0; j<n; j++)
  515.             { 
  516. dd=y[j]; 
  517. l=0;
  518.                 for(m=0; m<kk; m++)
  519.                   if(l==0)
  520.                   {
  521.   q=dd-b[m*n+j];
  522.                       if(Abs(q)+1.0==1.0) l=1;
  523.                       else dd=(g[kk]-g[m])/q;
  524.                   }
  525.                 b[kk*n+j]=dd;
  526.                 if(l!=0) b[kk*n+j]=1.0e+35;
  527.             }
  528.             for(j=0; j<n; j++)
  529.             { 
  530. dd=0.0;
  531.                 for(m=kk-1; m>=0; m--)
  532. dd=-g[m]/(b[(m+1)*n+j]+dd);
  533.                 y[j]=dd+b[j];
  534.             }
  535.             p=0.0;
  536.             for(j=0; j<n; j++)
  537.             { 
  538. q=Abs(y[j]-u[j]);
  539.                 if(q>p) p=q;
  540.             }
  541.             if((p>eps || FloatEqual(p,eps))&&(kk<7))
  542.             { for(j=0; j<n; j++) u[j]=y[j];
  543.                 kk=kk+1; it=1;
  544.             }
  545.         }
  546.         for(j=0; j<n; j++)
  547.           z(j,i)=y[j];
  548.     }
  549. }
  550. //全区间积分连分式法辅助函数
  551. template <class _Ty>
  552. void Fraction2(_Ty t, _Ty h, valarray<_Ty>& y, valarray<_Ty>& b, 
  553. valarray<_Ty>& d, valarray<_Ty>& e)
  554. {
  555.     int i,k;
  556.     _Ty a[4],tt;
  557. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  558.     a[0]=h/2.0; 
  559. a[1]=a[0];
  560. a[2]=h;
  561. a[3]=h;
  562.     FunctionValueFI(t,y,d);
  563.     for(i=0; i<n; i++) 
  564. {
  565. b[i]=y[i]; 
  566. e[i]=y[i];
  567. }
  568.     for(k=0; k<3; k++)
  569.     { 
  570. for(i=0; i<n; i++)
  571.         {
  572. y[i]=e[i]+a[k]*d[i];
  573.             b[i]=b[i]+a[k+1]*d[i]/3.0;
  574.         }
  575.         tt=t+a[k];
  576.         FunctionValueFI(tt,y,d);
  577.     }
  578.     for(i=0; i<n; i++)
  579.       y[i]=b[i]+h*d[i]/6.0;
  580. }
  581. //全区间积分双边法
  582. template <class _Ty>
  583. void ODE_BothSidesInterval(_Ty t, _Ty h, valarray<_Ty>& y,
  584.     _Ty eps, int k, matrix<_Ty>& z)
  585. {
  586.     _Ty a(t), qq;
  587. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  588. valarray<_Ty> d(n), w(n), u(n), v(n), p(n);
  589.     for(int i=0; i<n; i++)
  590. {
  591. p[i]=0.0;
  592. z(i,0)=y[i];
  593. }
  594.     FunctionValueBSI(t,y,d);
  595.     for(int j=0; j<n; j++) u[j]=d[j];
  596.     BothSidesInterval(t,h,y,eps); //辅助函数
  597.     t=a+h;
  598.     FunctionValueBSI(t,y,d);
  599.     for(j=0; j<n; j++)
  600.     { 
  601. z(j,1)=y[j]; v[j]=d[j];}
  602.     for(j=0; j<n; j++)
  603.     { 
  604. p[j]=-4.0*z(j,1)+5.0*z(j,0)+2.0*h*(2.0*v[j]+u[j]);
  605.         y[j]=p[j];
  606.     }
  607.     t=a+2.0*h;
  608.     FunctionValueBSI(t,y,d);
  609.     for(j=0; j<n; j++)
  610.     { 
  611. qq=2.0*h*(d[j]-2.0*v[j]-2.0*u[j])/3.0;
  612.         qq=qq+4.0*z(j,1)-3.0*z(j,0);
  613.         z(j,2)=(p[j]+qq)/2.0;
  614.         y[j]=z(j,2);
  615.     }
  616.     for(i=3; i<k; i++)
  617.     { 
  618. t=a+(i-1)*h;
  619.         FunctionValueBSI(t,y,d);
  620.         for(j=0; j<n; j++)
  621.         {
  622. u[j]=v[j];
  623. v[j]=d[j];
  624. }
  625.         for(j=0; j<n; j++)
  626.         { 
  627. qq=-4.0*z(j,i-1)+5.0*z(j,i-2);
  628.             p[j]=qq+2.0*h*(2.0*v[j]+u[j]);
  629.             y[j]=p[j];
  630.         }
  631.         t=t+h;
  632.         FunctionValueBSI(t,y,d);
  633.         for(j=0; j<n; j++)
  634.         { 
  635. qq=2.0*h*(d[j]-2.0*v[j]-2.0*u[j])/3.0;
  636.             qq=qq+4.0*z(j,i-1)-3.0*z(j,i-2);
  637.             y[j]=(p[j]+qq)/2.0;
  638.             z(j,i)=y[j];
  639.         }
  640.     }
  641. }
  642. //全区间积分双边法辅助函数
  643. template <class _Ty>
  644. void BothSidesInterval(_Ty t, _Ty h, valarray<_Ty>& y, _Ty eps)
  645.     int m(1), j, k;
  646.     _Ty hh(h), dt,x(t), tt, q, a[4];
  647. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  648. valarray<_Ty> d(n), b(n), c(n), e(n), g(n);
  649.     
  650.     _Ty p=1.0+eps;
  651.     for(int i=0; i<n; i++) c[i]=y[i];
  652.     while(p>eps || FloatEqual(p,eps))
  653.     { 
  654. a[0]=hh/2.0;
  655. a[1]=a[0]; 
  656. a[2]=hh;
  657. a[3]=hh;
  658.         for(i=0; i<n; i++)
  659.         {
  660. g[i]=y[i]; 
  661. y[i]=c[i];
  662. }
  663.         dt=h/m; 
  664. t=x;
  665.         for(j=0; j<m; j++)
  666.         {
  667. FunctionValueBSI(t,y,d);
  668.             for(i=0; i<n; i++) 
  669.             {
  670. b[i]=y[i];
  671. e[i]=y[i];
  672. }
  673.             for(k=0; k<3; k++)
  674.             { 
  675. for(i=0; i<n; i++)
  676.                 {
  677. y[i]=e[i]+a[k]*d[i];
  678.                     b[i]=b[i]+a[k+1]*d[i]/3.0;
  679.                 }
  680.                 tt=t+a[k];
  681.                 FunctionValueBSI(tt,y,d);
  682.             }
  683.             for(i=0; i<n; i++)
  684.               y[i]=b[i]+hh*d[i]/6.0;
  685.             t=t+dt;
  686.         }
  687.         p=0.0;
  688.         for(i=0; i<n; i++)
  689.         { 
  690. q=Abs(y[i]-g[i]);
  691.             if(q>p) p=q;
  692.         }
  693.         hh=hh/2.0;
  694. m=m+m;
  695.     }
  696. }
  697. //全区间积分阿当姆斯预报-校正法
  698. template <class _Ty>
  699. void ODE_AdamsInterval(_Ty t, _Ty h, valarray<_Ty>& y,
  700. _Ty eps, int k, matrix<_Ty>& z)
  701. {
  702.     int j,m;
  703.     _Ty a(t), q;
  704. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  705. valarray<_Ty> b(4*n), e(n), s(n), g(n), d(n);
  706.     
  707.     for(int i=0; i<n; i++) z(i,0)=y[i];
  708.     FunctionValueAI(t,y,d);
  709.     for(i=0; i<n; i++) b[i]=d[i];
  710.     for(i=1; i<4; i++)
  711.       if(i<k)
  712.       { 
  713.   t=a+i*h;
  714.           AdamsInterval(t,h,y,eps); //辅助函数
  715.           for(j=0; j<n; j++) z(j,i)=y[j];
  716.           FunctionValueAI(t,y,d);
  717.           for(j=0; j<n; j++) b[i*n+j]=d[j];
  718.       }
  719.     for(i=4; i<k; i++)
  720.     { 
  721. for(j=0; j<n; j++)
  722.         { 
  723. q=55.0*b[3*n+j]-59.0*b[2*n+j];
  724.             q=q+37.0*b[n+j]-9.0*b[j];
  725.             y[j]=z(j,i-1)+h*q/24.0;
  726.             b[j]=b[n+j];
  727.             b[n+j]=b[n+n+j];
  728.             b[n+n+j]=b[n+n+n+j];
  729.         }
  730.         t=a+i*h;
  731.         FunctionValueAI(t,y,d);
  732.         for(m=0; m<n; m++) b[n+n+n+m]=d[m];
  733.         for(j=0; j<n; j++)
  734.         { 
  735. q=9.0*b[3*n+j]+19.0*b[n+n+j]-5.0*b[n+j]+b[j];
  736.             y[j]=z(j,i-1)+h*q/24.0;
  737.             z(j,i)=y[j];
  738.         }
  739.         FunctionValueAI(t,y,d);
  740.         for(m=0; m<n; m++) b[3*n+m]=d[m];
  741.     }
  742. }
  743. //全区间积分阿当姆斯预报-校正法辅助函数
  744. template <class _Ty>
  745. void AdamsInterval(_Ty t, _Ty h, valarray<_Ty>& y, _Ty eps)
  746. {
  747.     int m(1), j, k;
  748. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  749.     _Ty hh(h), dt, x(t), tt, q, a[4];
  750. valarray<_Ty> g(n), b(n), c(n), d(n), e(n);
  751.     
  752.     _Ty p=1.0+eps;
  753.     for(int i=0; i<n; i++) c[i]=y[i];
  754.     while(p>eps || FloatEqual(p,eps))
  755.     { 
  756. a[0]=hh/2.0;
  757. a[1]=a[0]; 
  758. a[2]=hh;
  759. a[3]=hh;
  760.         for(i=0; i<n; i++)
  761.         {
  762. g[i]=y[i]; 
  763. y[i]=c[i];
  764. }
  765.         dt=h/m; t=x;
  766.         for(j=0; j<m; j++)
  767.         { 
  768. FunctionValueAI(t,y,d);
  769.             for(i=0; i<n; i++) 
  770.             {
  771. b[i]=y[i];
  772. e[i]=y[i];
  773. }
  774.             for(k=0; k<3; k++)
  775.             { 
  776. for(i=0; i<n; i++)
  777.                 {
  778. y[i]=e[i]+a[k]*d[i];
  779.                     b[i]=b[i]+a[k+1]*d[i]/3.0;
  780.                 }
  781.                 tt=t+a[k];
  782.                 FunctionValueAI(tt,y,d);
  783.             }
  784.             for(i=0; i<n; i++)
  785.               y[i]=b[i]+hh*d[i]/6.0;
  786.             t=t+dt;
  787.         }
  788.         p=0.0;
  789.         for(i=0; i<n; i++)
  790.         {
  791. q=Abs(y[i]-g[i]);
  792.             if(q>p) p=q;
  793.         }
  794.         hh=hh/2.0;
  795. m=m+m;
  796.     }
  797. }
  798. //全区间积分哈明法
  799. template <class _Ty>
  800. void ODE_HammingInterval(_Ty t, _Ty h, valarray<_Ty>& y,
  801. _Ty eps, int k, matrix<_Ty>& z)
  802. {
  803.     int j,m;
  804.     _Ty a(t), q;
  805. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  806. valarray<_Ty> d(n), w(n), u(n), v(n), b(4*n), g(n);
  807.     
  808.     for(int i=0; i<n; i++) z(i,0)=y[i];
  809.     FunctionValueHI(t,y,d);
  810.     for(i=0; i<n; i++) b[i]=d[i];
  811.     for(i=1; i<=3; i++)
  812.       if(i<k)
  813.       { 
  814.   t=a+i*h;
  815.           HammingInterval(t,h,y,eps);
  816.           for(m=0; m<n; m++) z(m,i)=y[m];
  817.           FunctionValueHI(t,y,d);
  818.           for(m=0; m<n; m++) b[i*n+m]=d[m];
  819.       }
  820.     for(i=0; i<n; i++) u[i]=0.0;
  821.     for(i=4; i<k; i++)
  822.     { 
  823. for(j=0; j<n; j++)
  824.         {
  825. q=2.0*b[3*n+j]-b[n+n+j]+2.0*b[n+j];
  826.             y[j]=z(j,i-4)+4.0*h*q/3.0;
  827.         }
  828.         for(j=0; j<n; j++)
  829. y[j]=y[j]+112.0*u[j]/121.0;
  830.         t=a+i*h;
  831.         FunctionValueHI(t,y,d);
  832.         for(j=0; j<n; j++)
  833.         { 
  834. q=9.0*z(j,i-1)-z(j,i-3);
  835.             q=(q+3.0*h*(d[j]+2.0*b[3*n+j]-b[n+n+j]))/8.0;
  836.             u[j]=q-y[j];
  837.             z(j,i)=q-9.0*u[j]/121.0;
  838.             y[j]=z(j,i);
  839.             b[n+j]=b[n+n+j];
  840.             b[n+n+j]=b[n+n+n+j];
  841.         }
  842.         FunctionValueHI(t,y,d);
  843.         for(m=0; m<n; m++) b[3*n+m]=d[m];
  844.     }
  845. }
  846. //全区间积分哈明法辅助函数
  847. template <class _Ty>
  848. void HammingInterval(_Ty t, _Ty h, valarray<_Ty>& y, _Ty eps)
  849.     int m(1), j, k;
  850.     _Ty hh(h), dt, x(t), tt, q, a[4];
  851. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  852. valarray<_Ty> g(n), b(n), c(n), d(n), e(n);
  853.     
  854. _Ty p=1.0+eps;
  855.     for(int i=0; i<n; i++) c[i]=y[i];
  856.     while(p>eps || FloatEqual(p,eps))
  857.     { 
  858. a[0]=hh/2.0; 
  859. a[1]=a[0]; 
  860. a[2]=hh;
  861. a[3]=hh;
  862.         for(i=0; i<n; i++)
  863.         {
  864. g[i]=y[i]; 
  865. y[i]=c[i];
  866. }
  867.         dt=h/m;
  868. t=x;
  869.         for(j=0; j<m; j++)
  870.         {
  871. FunctionValueHI(t,y,d);
  872.             for(i=0; i<n; i++) 
  873.             {
  874. b[i]=y[i];
  875. e[i]=y[i];
  876. }
  877.             for(k=0; k<3; k++)
  878.             { 
  879. for(i=0; i<n; i++)
  880.                 {
  881. y[i]=e[i]+a[k]*d[i];
  882.                     b[i]=b[i]+a[k+1]*d[i]/3.0;
  883.                 }
  884.                 tt=t+a[k];
  885.                 FunctionValueHI(t,y,d);
  886.             }
  887.             for(i=0; i<n; i++)
  888. y[i]=b[i]+hh*d[i]/6.0;
  889.             t=t+dt;
  890.         }
  891.         p=0.0;
  892.         for(i=0; i<n; i++)
  893.         { 
  894. q=Abs(y[i]-g[i]);
  895.             if(q>p) p=q;
  896.         }
  897.         hh=hh/2.0; 
  898. m=m+m;
  899.     }
  900. }
  901. //积分一步特雷纳法
  902. template <class _Ty>
  903. void ODE_Treanor(_Ty t, _Ty h, valarray<_Ty>& y)
  904. {
  905. //extern void gtnr1f();
  906.     _Ty s,aa,bb,dd,g,dy,dy1;
  907. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  908. valarray<_Ty> w(4*n), q(4*n), r(4*n), d(n), p(n);
  909.     
  910.     for(int j=0; j<n; j++) w[j]=y[j];
  911.     FunctionValueT(t,y,d);
  912.     for(j=0; j<n; j++)
  913.     {
  914. q[j]=d[j]; 
  915. y[j]=w[j]+h*d[j]/2.0;
  916.         w[n+j]=y[j];
  917.     }
  918.     s=t+h/2.0;
  919.     FunctionValueT(t,y,d);
  920.     for(j=0; j<n; j++)
  921.     { 
  922. q[n+j]=d[j];
  923.         y[j]=w[j]+h*d[j]/2.0;
  924.         w[n+n+j]=y[j];
  925.     }
  926.     FunctionValueT(t,y,d);
  927.     for(j=0; j<n; j++) q[n+n+j]=d[j];
  928.     for(j=0; j<n; j++)
  929.     { 
  930. aa=q[n+n+j]-q[n+j];
  931.         bb=w[n+n+j]-w[n+j];
  932.         if(-aa*bb*h>0.0)
  933.         {
  934. p[j]=-aa/bb; dd=-p[j]*h;
  935.             r[j]=exp(dd);
  936.             r[n+j]=(r[j]-1.0)/dd;
  937.             r[n+n+j]=(r[n+j]-1.0)/dd;
  938.             r[3*n+j]=(r[n+n+j]-1.0)/dd;
  939.         }
  940.         else p[j]=0.0;
  941.         if(p[j]<0.0||FloatEqual(p[j],0.0)) g=q[n+n+j];
  942.         else
  943.         { 
  944. g=2.0*(q[n+n+j]-q[j])*r[n+n+j];
  945.             g=g+(q[j]-q[n+j])*r[n+j]+q[n+j];
  946.         }
  947.         w[3*n+j]=w[j]+g*h;
  948.         y[j]=w[3*n+j];
  949.     }
  950.     s=t+h;
  951.     FunctionValueT(t,y,d);
  952.     for(j=0; j<n; j++) q[3*n+j]=d[j];
  953.     for(j=0; j<n; j++)
  954.     { 
  955. if(p[j]<0.0||FloatEqual(p[j],0.0))
  956.         { 
  957. dy=q[j]+2.0*(q[n+j]+q[n+n+j]);
  958.             dy=(dy+q[n+n+n+j])*h/6.0;
  959.         }
  960.         else
  961.         {
  962. dy=-3.0*(q[j]+p[j]*w[j])+2.0*(q[n+j]+p[j]*w[n+j]);
  963.             dy=dy+2.0*(q[n+n+j]+p[j]*w[n+n+j]);
  964.             dy=dy-(q[n+n+n+j]+p[j]*w[n+n+n+j]);
  965.             dy=dy*r[n+n+j]+q[j]*r[n+j];
  966.             dy1=q[j]-q[n+j]-q[n+n+j]+q[n+n+n+j];
  967.             dy1=dy1+(w[j]-w[n+j]-w[n+n+j]+w[n+n+n+j])*p[j];
  968.             dy=(dy+4.0*dy1*r[n+n+n+j])*h;
  969.         }
  970.         y[j]=w[j]+dy;
  971.     }
  972. }
  973. //全区间积分特雷纳法
  974. template <class _Ty>
  975. void ODE_TreanorInterval(_Ty t, _Ty h, valarray<_Ty>& y,
  976. int k, matrix<_Ty>& z)
  977. {
  978.     _Ty a(t),s,aa,bb,dd,g,dy,dy1;
  979. int n = y.size(); //微分方程组中方程的个数,也是未知函数的个数
  980. valarray<_Ty> w(4*n), q(4*n), r(4*n), d(n), p(n);
  981.     
  982.     for(int j=0; j<n; j++) z(j,0)=y[j];
  983.     for(int i=1; i<k; i++)
  984.     {
  985. t=a+(i-1)*h;
  986.         for(j=0; j<n; j++) w[j]=y[j];
  987.         FunctionValueTI(s,y,d);
  988.         for(j=0; j<n; j++)
  989.         { 
  990. q[j]=d[j]; 
  991. y[j]=w[j]+h*d[j]/2.0;
  992.             w[n+j]=y[j];
  993.         }
  994.         s=t+h/2.0;
  995.         FunctionValueTI(s,y,d);
  996.         for(j=0; j<n; j++)
  997.         { 
  998. q[n+j]=d[j];
  999.             y[j]=w[j]+h*d[j]/2.0;
  1000.             w[n+n+j]=y[j];
  1001.         }
  1002.         FunctionValueTI(s,y,d);
  1003.         for(j=0; j<n; j++) q[n+n+j]=d[j];
  1004.         for(j=0; j<n; j++)
  1005.         { 
  1006. aa=q[n+n+j]-q[n+j];
  1007.             bb=w[n+n+j]-w[n+j];
  1008.             if(-aa*bb*h>0.0)
  1009.             {
  1010. p[j]=-aa/bb; dd=-p[j]*h;
  1011.                 r[j]=exp(dd);
  1012.                 r[n+j]=(r[j]-1.0)/dd;
  1013.                 r[n+n+j]=(r[n+j]-1.0)/dd;
  1014.                 r[3*n+j]=(r[n+n+j]-1.0)/dd;
  1015.             }
  1016.             else p[j]=0.0;
  1017.             if(p[j]<0.0||FloatEqual(p[j],0.0)) g=q[n+n+j];
  1018.             else
  1019.             { 
  1020. g=2.0*(q[n+n+j]-q[j])*r[n+n+j];
  1021.                 g=g+(q[j]-q[n+j])*r[n+j]+q[n+j];
  1022.             }
  1023.             w[3*n+j]=w[j]+g*h;
  1024.             y[j]=w[3*n+j];
  1025.         }
  1026.         s=t+h;
  1027.         FunctionValueTI(s,y,d);
  1028.         for(j=0; j<n; j++) q[3*n+j]=d[j];
  1029.         for(j=0; j<n; j++)
  1030.         { 
  1031. if(p[j]<0.0||FloatEqual(p[j],0.0))
  1032.             { 
  1033. dy=q[j]+2.0*(q[n+j]+q[n+n+j]);
  1034.                 dy=(dy+q[n+n+n+j])*h/6.0;
  1035.             }
  1036.             else
  1037.             { 
  1038. dy=-3.0*(q[j]+p[j]*w[j])+2.0*(q[n+j]+p[j]*w[n+j]);
  1039.                 dy=dy+2.0*(q[n+n+j]+p[j]*w[n+n+j]);
  1040.                 dy=dy-(q[n+n+n+j]+p[j]*w[n+n+n+j]);
  1041.                 dy=dy*r[n+n+j]+q[j]*r[n+j];
  1042.                 dy1=q[j]-q[n+j]-q[n+n+j]+q[n+n+n+j];
  1043.                 dy1=dy1+(w[j]-w[n+j]-w[n+n+j]+w[n+n+n+j])*p[j];
  1044.                 dy=(dy+4.0*dy1*r[n+n+n+j])*h;
  1045.             }
  1046.             y[j]=w[j]+dy;
  1047.             z(j,i)=y[j];
  1048.         }
  1049.     }
  1050. }
  1051. //积分刚性方程组吉尔法
  1052. template <class _Ty>
  1053. int ODE_Gear(_Ty a, _Ty b, _Ty hmin, _Ty hmax, _Ty h, _Ty eps, 
  1054. valarray<_Ty>& y0, int k, valarray<_Ty>& t, matrix<_Ty>& z)
  1055. {
  1056.     int kf(1),jt(0),nn(0),nq(1),m(2),irt1,irt(1),j,nqd,idb;
  1057.     int iw,j1,j2,nt,nqw,l;
  1058.     _Ty aa[7],hw(h),hd,rm,t0(a),td,r,dd,pr1,pr2,pr3,rr;
  1059.     _Ty enq1,enq2,enq3,eup,e,edwn,bnd,r1;
  1060.     _Ty pp[7][3] = 
  1061. {
  1062. {2.0,3.0,1.0}, {4.5,6.0,1.0},
  1063.         {7.333,9.167,0.5}, {10.42,12.5,0.1667},
  1064.         {13.7,15.98,0.04133}, {17.15,1.0,0.008267},
  1065.         {1.0,1.0,1.0}
  1066. };
  1067. int n = y0.size(); //微分方程组中方程的个数,也是未知函数的个数
  1068. valarray<_Ty> d(n), s(10*n), s02(n), ym(n), er(n);
  1069. valarray<_Ty> yy(n), y(8*n), iis(n), jjs(n);
  1070. matrix<_Ty> p(n,n);
  1071.     aa[1]=-1.0;
  1072.     for(int i=0; i<8*n; i++) y[i]=0.0;
  1073.     for(i=0; i<n; i++) 
  1074.     {
  1075. y[i*8]=y0[i];
  1076. yy[i]=y[i*8];
  1077. }
  1078.     FunctionValueG(t0,yy,d);
  1079.     for(i=0; i<n; i++) y[i*8+1]=h*d[i];
  1080.     for(i=0; i<n; i++) ym[i]=1.0;
  1081.   l20:
  1082.     irt=1;
  1083. kf=1; 
  1084. nn=nn+1;
  1085.     t[nn-1]=t0;
  1086.     for(i=0; i<n; i++) z(i,nn-1)=y[i*8];
  1087.     if((t0>b||FloatEqual(t0,b))||(nn==k)) return(kf);
  1088.     
  1089. for(i=0; i<n; i++)
  1090.       for(j=0; j<m; j++) s[i*10+j]=y[i*8+j];
  1091.     hd=hw;
  1092.     if(h!=hd)
  1093.     {
  1094. rm=h/hd;
  1095. irt1=0;
  1096.         rr=Abs(hmin/hd);
  1097.         if(rm<rr) rm=rr;
  1098.         rr=Abs(hmax/hd);
  1099.         if(rm>rr) rm=rr;
  1100. r=1.0; 
  1101. irt1=irt1+1;
  1102.         for(j=1; j<m; j++)
  1103.         { 
  1104. r=r*rm;
  1105.             for(i=0; i<n; i++)
  1106.               y[i*8+j]=s[i*10+j]*r;
  1107.         }
  1108.         h=hd*rm;
  1109.         for(i=0; i<n; i++)
  1110. y[i*8]=s[i*10];
  1111.         idb=m;
  1112.     }
  1113.     nqd=nq;
  1114. td=t0;
  1115. rm=1.0;
  1116.     if(jt>0) goto l80;
  1117.   l60:
  1118.     switch(nq)
  1119.     { 
  1120. case 1: aa[0]=-1.0;
  1121. break;
  1122.         case 2: aa[0]=-2.0/3.0;
  1123. aa[2]=-1.0/3.0; 
  1124. break;
  1125.         case 3: aa[0]=-6.0/11.0; 
  1126. aa[2]=aa[0];
  1127.                 aa[3]=-1.0/11.0; 
  1128. break;
  1129.         case 4: aa[0]=-0.48; 
  1130. aa[2]=-0.7;
  1131. aa[3]=-0.2;
  1132.                 aa[4]=-0.02; 
  1133. break;
  1134.         case 5: aa[0]=-120.0/274.0;
  1135. aa[2]=-225.0/274.0;
  1136.                 aa[3]=-85.0/274.0; 
  1137. aa[4]=-15.0/274.0;
  1138.                 aa[5]=-1.0/274.0; 
  1139. break;
  1140.         case 6: aa[0]=-720.0/1764.0; 
  1141. aa[2]=-1624.0/1764.0;
  1142.                 aa[3]=-735.0/1764.0;
  1143. aa[4]=-175.0/1764.0;
  1144.                 aa[5]=-21.0/1764.0; 
  1145. aa[6]=-1.0/1764.0;
  1146.                 break;
  1147.         default: return(-2);
  1148.     }
  1149.     m=nq+1; 
  1150. idb=m;
  1151.     enq2=0.5/(nq+1.0);
  1152. enq3=0.5/(nq+2.0);
  1153.     enq1=0.5/(nq+0.0);
  1154.     eup=pp[nq-1][1]*eps;
  1155. eup=eup*eup;
  1156.     e=pp[nq-1][0]*eps;
  1157. e=e*e;
  1158.     edwn=pp[nq-1][2]*eps;
  1159. edwn=edwn*edwn;
  1160.     if(edwn==0.0)
  1161.     {
  1162. for(i=0; i<n; i++)
  1163.           for(j=0; j<m; j++)
  1164.             y[i*8+j]=s[i*10+j];
  1165.         h=hd;
  1166. nq=nqd; 
  1167. jt=nq;
  1168. return(-4);
  1169.     }
  1170.     bnd=eps*enq3/(n+0.0);
  1171.     iw=1;
  1172.     if(irt==2)
  1173.     { 
  1174. r1=1.0;
  1175.         for(j=1; j<m; j++)
  1176.         {
  1177. r1=r1*r;
  1178.             for(i=0; i<n; i++)
  1179. y[i*8+j]=y[i*8+j]*r1;
  1180.         }
  1181.         idb=m;
  1182.         for(i=0; i<n; i++)
  1183.           if(ym[i]<Abs(y[i*8]))
  1184. ym[i]=Abs(y[i*8]);
  1185.         jt=nq;
  1186.         goto l20;
  1187.     }
  1188.   l80:
  1189.     t0=t0+h;
  1190.     for(j=2; j<=m; j++)
  1191.       for(j1=j; j1<=m; j1++)
  1192.       { 
  1193.   j2=m-j1+j-1;
  1194.           for(i=0; i<n; i++)
  1195. y[i*8+j2-1]=y[i*8+j2-1]+y[i*8+j2];
  1196.       }
  1197.     for(i=0; i<n; i++) er[i]=0.0;
  1198.     j1=1; 
  1199. nt=1;
  1200.     for(l=0; l<=2; l++)
  1201.     {
  1202. if((j1!=0)&&(nt!=0))
  1203.         {
  1204. for(i=0; i<n; i++) yy[i]=y[i*8];
  1205.             FunctionValueG(t0,yy,d);
  1206.             if(iw>=1)
  1207.             {
  1208. for(i=0; i<n; i++) yy[i]=y[i*8];
  1209.                 JacobiMatrix(t0,yy,p); //计算雅可比矩阵的函数
  1210.                 r=aa[0]*h;
  1211.                 for(i=0; i<n; i++)
  1212.                   for(j=0; j<n; j++)
  1213.                     p(i,j)=p(i,j)*r;
  1214.                 for(i=0; i<n; i++)
  1215.                   p(i,i)=1.0+p(i,i);
  1216.                 iw=-1;
  1217.                 jjs[0]=MatrixInversionGS(p); //全选主元高斯-约当法求矩阵逆
  1218.                 j1=jjs[0];
  1219.             }
  1220.             if(jjs[0]!=0)
  1221.             {
  1222. for(i=0; i<n; i++)
  1223. s02[i]=y[i*8+1]-d[i]*h;
  1224.                 for(i=0; i<n; i++)
  1225.                 { 
  1226. dd=0.0;
  1227.                     for(j=0; j<n; j++)
  1228. dd=dd+s02[j]*p(i,j);
  1229.                     s[i*10+8]=dd;
  1230.                 }
  1231.                 nt=n;
  1232.                 for(i=0; i<n; i++)
  1233.                 { 
  1234. y[i*8]=y[i*8]+aa[0]*s[i*10+8];
  1235.                     y[i*8+1]=y[i*8+1]-s[i*10+8];
  1236.                     er[i]=er[i]+s[i*10+8];
  1237.                     if(Abs(s[i*10+8])<=(bnd*ym[i]))
  1238. nt=nt-1;
  1239.                 }
  1240.             }
  1241.         }
  1242.     }
  1243.     if(nt>0)
  1244.     {
  1245. t0=td;
  1246.         if((h>(hmin*1.00001))||(iw>=0))
  1247.         {
  1248. if(iw!=0) rm=0.25*rm;
  1249.             iw=1;
  1250. irt1=2;
  1251.             rr=Abs(hmin/hd);
  1252.             if(rm<rr) rm=rr;
  1253.             rr=Abs(hmax/hd);
  1254.             if(rm>rr) rm=rr;
  1255.             r=1.0;
  1256.             for(j=1; j<m; j++)
  1257.             {
  1258. r=r*rm;
  1259.                 for(i=0; i<n; i++)
  1260. y[i*8+j]=s[i*10+j]*r;
  1261.             }
  1262.             h=hd*rm;
  1263.             for(i=0; i<n; i++)
  1264.               y[i*8]=s[i*10];
  1265.             idb=m;
  1266.             goto l80;
  1267.         }
  1268.         for(i=0; i<n; i++)
  1269.           for(j=0; j<m; j++)
  1270.             y[i*8+j]=s[i*10+j];
  1271.         h=hd; 
  1272. nq=nqd;
  1273. jt=nq;
  1274. return(-3);
  1275.     }
  1276.     dd=0.0;
  1277.     for(i=0; i<n; i++)
  1278. dd=dd+(er[i]/ym[i])*(er[i]/ym[i]);
  1279.     iw=0;
  1280.     if(dd<=e)
  1281.     { 
  1282. if(m>=3)
  1283.           for(j=2; j<m; j++)
  1284.             for(i=0; i<n; i++)
  1285.               y[i*8+j]=y[i*8+j]+aa[j]*er[i];
  1286.         kf=1;
  1287. hw=h;
  1288.         if(idb>1)
  1289.         {
  1290. idb=idb-1;
  1291.             if(idb<=1)
  1292.               for(i=0; i<n; i++)
  1293.                 s[i*10+9]=er[i];
  1294.             for(i=0; i<n; i++)
  1295.       if(ym[i]<Abs(y[i*8])) ym[i]=Abs(y[i*8]);
  1296.             jt=nq;
  1297.             goto l20;
  1298.         }
  1299.     }
  1300.     if(dd>e)
  1301.     { 
  1302. kf=kf-2;
  1303.         if(h<=(hmin*1.00001))
  1304.         {
  1305.             hw=h;
  1306. jt=nq; 
  1307. return(-1);
  1308.         }
  1309.         t0=td;
  1310.         if(kf<=-5)
  1311.         { 
  1312. if(nq==1)
  1313.             {
  1314. for(i=0; i<n; i++)
  1315.                   for(j=0; j<m; j++)
  1316.                     y[i*8+j]=s[i*10+j];
  1317.                 h=hd;
  1318. nq=nqd;
  1319. jt=nq;
  1320. return(-4);
  1321.             }
  1322.             for(i=0; i<n; i++) yy[i]=y[i*8];
  1323.             FunctionValueG(t0,yy,d);
  1324.             r=h/hd;
  1325.             for(i=0; i<n; i++)
  1326.             { 
  1327. y[i*8]=s[i*10];
  1328.                 s[i*10+1]=hd*d[i];
  1329.                 y[i*8+1]=s[i*10+1]*r;
  1330.             }
  1331.             nq=1;
  1332. kf=1;
  1333. goto l60;
  1334.         }
  1335.     }
  1336.     pr2=log(dd/e);
  1337. pr2=enq2*pr2;
  1338. pr2=exp(pr2);
  1339.     pr2=1.2*pr2;
  1340.     pr3=1.0e+20;
  1341.     if(nq<7)
  1342.       if(kf>-1)
  1343.       {
  1344.   dd=0.0;
  1345.           for(i=0; i<n; i++)
  1346.           {
  1347.   pr3=(er[i]-s[i*10+9])/ym[i];
  1348.               dd=dd+pr3*pr3;
  1349.           }
  1350.           pr3=log(dd/eup);
  1351.   pr3=enq3*pr3;
  1352.           pr3=exp(pr3);
  1353.   pr3=1.4*pr3;
  1354.       }
  1355.     pr1=1.0e+20;
  1356.     if(nq>1)
  1357.     { 
  1358. dd=0.0;
  1359.         for(i=0; i<n; i++)
  1360.         {
  1361. pr1=y[i*8+m-1]/ym[i];
  1362.             dd=dd+pr1*pr1;
  1363.         }
  1364.         pr1=log(dd/edwn); 
  1365. pr1=enq1*pr1;
  1366.         pr1=exp(pr1);
  1367. pr1=1.3*pr1;
  1368.     }
  1369.     if(pr2<=pr3)
  1370.     { 
  1371. if(pr2>pr1)
  1372. {
  1373. r=1.0e+04;
  1374.             if(pr1>1.0e-04) r=1.0/pr1;
  1375.             nqw=nq-1;
  1376.         }
  1377.         else
  1378.         { 
  1379. nqw=nq;
  1380. r=1.0e+04;
  1381.             if(pr2>1.0e-04) r=1.0/pr2;
  1382.         }
  1383.     }
  1384.     else
  1385.     { 
  1386. if(pr3<pr1)
  1387.         { 
  1388. r=1.0e+04;
  1389.             if(pr3>1.0e-04) r=1.0/pr3;
  1390.             nqw=nq+1;
  1391.         }
  1392.         else
  1393.         { 
  1394. r=1.0e+04;
  1395.             if(pr1>1.0e-04) r=1.0/pr1;
  1396.             nqw=nq-1;
  1397.         }
  1398.     }
  1399.     idb=10;
  1400.     if(kf==1)
  1401.       if(r<1.1)
  1402.       { 
  1403.   for(i=0; i<n; i++)
  1404.             if(ym[i]<Abs(y[i*8])) ym[i]=Abs(y[i*8]);
  1405.           jt=nq; goto l20;
  1406.       }
  1407.     if(nqw>nq)
  1408.       for(i=0; i<n; i++)
  1409.         y[i*8+nqw]=er[i]*aa[m-1]/(m+0.0);
  1410.     m=nqw+1;
  1411.     if(kf==1)
  1412.     { 
  1413. irt=2; 
  1414. rr=hmax/Abs(h);
  1415.         if(r>rr) r=rr;
  1416.         h=h*r; 
  1417. hw=h;
  1418.         if(nq==nqw)
  1419.         {
  1420. r1=1.0;
  1421.             for(j=1; j<m; j++)
  1422.             {
  1423. r1=r1*r;
  1424.                 for(i=0; i<n; i++)
  1425.                   y[i*8+j]=y[i*8+j]*r1;
  1426.             }
  1427.             idb=m;
  1428.             for(i=0; i<n; i++)
  1429.               if(ym[i]<Abs(y[i*8])) ym[i]=Abs(y[i*8]);
  1430.             jt=nq;
  1431. goto l20;
  1432.         }
  1433.         nq=nqw;
  1434.         goto l60;
  1435.     }
  1436.     rm=rm*r;
  1437. irt1=3;
  1438.     rr=Abs(hmin/hd);
  1439.     if(rm<rr) rm=rr;
  1440.     rr=Abs(hmax/hd);
  1441.     if(rm>rr) rm=rr;
  1442.     r=1.0;
  1443.     for(j=1; j<m; j++)
  1444.     {
  1445. r=r*rm;
  1446.         for(i=0; i<n; i++)
  1447.           y[i*8+j]=s[i*10+j]*r;
  1448.     }
  1449.     h=hd*rm;
  1450.     for(i=0; i<n; i++)
  1451.       y[i*8]=s[i*10];
  1452.     idb=m;
  1453.     if(nqw==nq) goto l80;
  1454.     nq=nqw; goto l60;
  1455. }
  1456. //二阶微分方程边值问题数值解法
  1457. template <class _Ty>
  1458. void ODE_LinearBoundaryValude(_Ty a, _Ty b, _Ty ya, _Ty yb, int n, 
  1459. valarray<_Ty>& y)
  1460. {
  1461.     int i,k,nn,m1;
  1462.     _Ty h,x;
  1463. valarray<_Ty> g(6*n), d(2*n), z(4);
  1464.     h=(b-a)/(n-1.0);
  1465. nn=2*n-1;
  1466.     g[0]=1.0;
  1467. g[1]=0.0;
  1468.     y[0]=ya; 
  1469. y[n-1]=yb;
  1470.     g[3*n-3]=1.0;
  1471. g[3*n-4]=0.0;
  1472.     for(i=2; i<n; i++)
  1473.     { 
  1474. x=a+(i-1)*h;
  1475.         FunctionValueLBV(x,z);
  1476.         k=3*(i-1)-1;
  1477.         g[k]=z[0]-h*z[1]/2.0;
  1478.         g[k+1]=h*h*z[2]-2.0*z[0];
  1479.         g[k+2]=z[0]+h*z[1]/2.0;
  1480.         y[i-1]=h*h*z[3];
  1481.     }
  1482.     m1=3*n-2;
  1483. valarray<_Ty> gg(m1);
  1484. for(i=0;i<m1;i++) gg[i] = g[i];
  1485. LE_TridiagonalEquationGauss(gg,y); //求解三对角方程组
  1486. for(i=0;i<m1;i++) g[i] = gg[i];
  1487.     h=h/2.0;
  1488.     g[0]=1.0; 
  1489. g[1]=0.0;
  1490.     d[0]=ya; 
  1491. d[nn-1]=yb;
  1492.     g[3*nn-3]=1.0;
  1493. g[3*nn-4]=0.0;
  1494.     for(i=2; i<nn; i++)
  1495.     { 
  1496. x=a+(i-1)*h;
  1497.         FunctionValueLBV(x,z);
  1498.         k=3*(i-1)-1;
  1499.         g[k]=z[0]-h*z[1]/2.0;
  1500.         g[k+1]=h*h*z[2]-2.0*z[0];
  1501.         g[k+2]=z[0]+h*z[1]/2.0;
  1502.         d[i-1]=h*h*z[3];
  1503.     }
  1504.     m1=3*nn-2;
  1505. valarray<_Ty> ggg(m1), ddd(nn);
  1506. for(i=0;i<m1;i++) ggg[i] = g[i];
  1507. for(i=0;i<nn;i++) ddd[i] = d[i];
  1508. LE_TridiagonalEquationGauss(ggg,ddd); //求解三对角方程组
  1509.     for(i=0;i<m1;i++) g[i] = ggg[i];
  1510. for(i=0;i<nn;i++) d[i] = ddd[i];
  1511. for(i=2; i<n; i++)
  1512.     { 
  1513. k=i+i-1;
  1514.         y[i-1]=(4.0*d[k-1]-y[i-1])/3.0;
  1515.     }
  1516. }
  1517. #endif // _ORDINARYDIFFERENTIALEGUATION_INL