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

Visual C++

  1. //NonLinearEquation.inl  非线性方程(组)求解函数(方法)定义
  2. // Ver 1.0.0.0
  3. // 版权所有(C) 何渝, 2002
  4. // 最后修改: 2002.5.31.
  5. #ifndef _NONLINEAREQUATION_INL
  6. #define _NONLINEAREQUATION_INL
  7. //用二分法搜索方程f(x)=0在区间[a,b]内的全部实根
  8. template <class _Ty>
  9. inline size_t 
  10. RootHalves(_Ty a, _Ty b, _Ty step, _Ty eps, valarray<_Ty>& x, size_t m)
  11. {
  12.     int n(0), js;
  13.     _Ty z=a, z1, y, y1, z0, y0;
  14.    
  15. y = FunctionValueRH(z);
  16.     while((z<=b+step/2.0)&&(n!=m))
  17.   if(Abs(y) < eps)
  18.       {
  19. n = n + 1;
  20. x[n-1] = z;
  21. z = z + step / 2.0;
  22. y=FunctionValueRH(z);
  23.       }
  24.       else
  25.       {
  26. z1=z+step;
  27. y1=FunctionValueRH(z1);
  28.         if(Abs(y1)<eps)
  29.         {
  30. n=n+1;
  31. x[n-1]=z1;
  32.             z=z1+step/2.0;
  33. y=FunctionValueRH(z);
  34.         }
  35.         else
  36. if(y*y1>0.0)
  37.             {
  38. y=y1;
  39. z=z1;
  40. }
  41.             else
  42.             {
  43. js=0;
  44.                 while(js==0)
  45.                 {
  46. if(Abs(z1-z)<eps)
  47.                     {
  48. n=n+1;
  49. x[n-1]=(z1+z)/2.0;
  50.                         z=z1+step/2.0;
  51. y=FunctionValueRH(z);
  52.                         js=1;
  53.                     }
  54.                     else
  55.                     {
  56. z0=(z1+z)/2.0;
  57. y0=FunctionValueRH(z0);
  58.                         if(Abs(y0)<eps)
  59.                         {
  60. x[n]=z0; n=n+1; js=1;
  61.                             z=z0+step/2.0;
  62. y=FunctionValueRH(z);
  63.                         }
  64.                         else
  65. if((y*y0) < 0.0)
  66. {
  67. z1 = z0;
  68. y1 = y0;
  69. }
  70. else
  71. {
  72. z = z0;
  73. y = y0;
  74. }
  75.                       }
  76.                   }
  77.               }
  78.           }
  79. }
  80.     return(n); //返回搜索到的实根个数
  81. }
  82. //牛顿(Newton)法求解非线性方程一个实根
  83. template <class _Ty>
  84. inline int 
  85. RootNewton( _Ty& x, _Ty eps, size_t js)
  86.     int k = 1, r = js;
  87.     _Ty  x1;
  88. _Ty x0 = x;
  89. valarray<_Ty> y(2);
  90.     FunctionValueRN(x0, y);
  91.     _Ty d=eps + 1.0;
  92.     while((d > eps || FloatEqual(d, eps))&&(r != 0))
  93.     {
  94. if(FloatEqual(y[1],0)) return(-1);
  95.         x1 = x0 - y[0] / y[1];
  96.         FunctionValueRN(x1,y);
  97.         d=Abs(x1 - x0);
  98. _Ty p=Abs(y[0]);
  99.         if(p > d) d = p;
  100.         x0 = x1;
  101. r -= 1;
  102.     }
  103.     x = x1;
  104.     k = js - r;
  105.     return(k);
  106. }
  107. //埃特金(Aitken)法求解非线性方程一个实根
  108. template <class _Ty>
  109. inline int 
  110. RootAitken( _Ty& x, _Ty eps, size_t js)
  111. {
  112.     _Ty u, v, x0;
  113.     int r(0), flag(0);
  114. x0 = x;
  115.     while((flag == 0) && (r != js))
  116.     {
  117. r++; 
  118.         u = FunctionValueRA(x0);
  119. v = FunctionValueRA(u);
  120.         if(Abs(u-v)<eps)
  121. {
  122. x0 = v;
  123. flag = 1;
  124. }
  125.         else x0=v-(v-u)*(v-u)/(v-2.0*u+x0);
  126.     }
  127.     x = x0;
  128. r = js - r;
  129.     return(r);
  130. }
  131. //连分式(Fraction)法求解非线性方程一个实根
  132. template <class _Ty>
  133. inline int 
  134. RootFraction(_Ty& x, _Ty eps)
  135. {
  136. int r(10), i, j, m, it;
  137.     _Ty x0, q(1.0e+35), h(0), z;
  138. valarray<_Ty> a(10), y(10);
  139. x0 = x; 
  140.     while(r!=0)
  141.     { 
  142. r = r - 1; 
  143. j = 0; 
  144. it = r;
  145.         while(j<=7)
  146.         {
  147. if(j<=2)
  148. z = x0 + 0.1 * j;
  149.             else
  150. z = h;
  151.             y[j] = FunctionValueRF(z);
  152.             h = z;
  153.             if(j==0)
  154. a[0] = z;
  155.             else
  156.             {
  157. m = 0;
  158. i = 0;
  159.                 while((m==0)&&(i<j))
  160.                 {
  161. if(FloatEqual((h-a[i]),0))
  162. m = 1;
  163.                     else
  164. h=(y[j]-y[i])/(h-a[i]);
  165.                     i++;
  166.                 }
  167.                 a[j] = h;
  168.                 if(m!=0) a[j]=q;
  169.                 h=0.0;
  170.                 for(i=j-1; i>=0; i--)
  171.                 {
  172. if(FloatEqual((a[i+1]+h),0))
  173. h = q;
  174.                     else
  175. h=-y[i]/(a[i+1]+h);
  176.                 }
  177.                 h = h + a[0];
  178.             }
  179.             if(Abs(y[j])>=eps) j++;
  180.             else 
  181. {
  182. j = 10;
  183. r = 0;
  184. }
  185.         }
  186.         x0 = h;
  187.     }
  188.     x = h;
  189.     return(10-it);
  190. }
  191. //QR法求代数方程全部根
  192. template <class _Ty, class _Tz>
  193. inline int 
  194. RootQR(valarray<_Ty>& a, valarray<_Tz>& x, _Ty eps, size_t jt)
  195. {
  196. int i, j, n;
  197.     n = x.size(); //多项式方程的次数
  198. matrix<_Ty> q(n, n);
  199.     for(j=0; j<n; j++)
  200. q(0,j) = -a[n-j-1] / a[n];
  201.     for(j=1; j<n; j++)
  202. for(i=0; i<n; i++)
  203. q(j,i) = 0;
  204. for(i=0; i<n-1; i++)
  205.       q(i+1, i) = 1;
  206. i = EigenvalueVectorHessenbergQR(q,x,eps,jt); //求全部特征值的QR方法
  207.     
  208. return(i);
  209. }
  210. //牛顿下山(NewtonHillDown)法求解实系数代数方程全部根(实根和复根)
  211. template <class _Ty, class _Tz>
  212. inline int 
  213. RootNewtonHillDown(valarray<_Ty>& a, valarray<_Tz>& cx)
  214. {
  215. int m, i, jt, k, is, it, n;
  216.     _Ty t, x, y, x1, y1, dx, dy, dd, dc, c, g, g1;
  217. _Ty w, u, p, q, pq, v, u1, v1;
  218.   
  219.     n = cx.size(); //多项式方程的次数
  220.     m = n;
  221.     while((m > 0) && (FloatEqual(a[m], 0.0))) m--;
  222.     if(m <= 0) return(-1);
  223.     
  224. for(i = 0; i <= m; i++) a[i] /= a[m];
  225.     for(i = 0; i <= m / 2; i++)
  226.     {
  227. w = a[i];
  228. a[i] = a[m - i];
  229. a[m - i] = w;
  230. }
  231.     k = m;
  232. is = 0;
  233. w = 1.0;
  234.     jt = 1;
  235.     while(jt == 1)
  236.     {
  237. pq = Abs(a[k]);
  238. while(pq < LONGDOUBLEERROR)
  239.         {
  240. cx[k - 1] = complex<_Ty>(0.0, 0.0);
  241. k = k - 1;
  242.             if(k == 1)
  243.             {
  244. cx[0] = complex<_Ty>(-a[1] * w / a[0], 0.0);
  245.                 return(1);
  246.             }
  247.             pq = Abs(a[k]);
  248.         }
  249. q = log(pq);
  250. q = q / (1.0 * k);
  251. q = exp(q);
  252.         p = q;
  253. w = w * p;
  254.         for(i = 1; i <= k; i++)
  255.         {
  256. a[i] /= q;
  257. q *= p;
  258. }
  259.         x = 0.0001;
  260. x1 = x; 
  261. y = 0.2;
  262. y1 = y; 
  263. dx = 1.0;
  264.         g = 1.0e+37; 
  265.  
  266. zjn:    u = a[0];
  267. v = 0.0;
  268.         for(i = 1; i <= k; i++)
  269.         { 
  270. p = u * x1;
  271. q = v * y1;
  272.             pq = (u + v) * (x1 + y1);
  273.             u = p - q + a[i];
  274. v = pq - p - q;
  275.         }
  276.         g1 = u * u + v * v;
  277.         if(g1 >= g)
  278.         { 
  279. if(is != 0)
  280. it = 1;
  281. g65(x, y, x1, y1, dx, dy, dd, dc, c, k, is, it);
  282. if(it == 0)
  283. goto zjn;
  284. }
  285. else
  286. {
  287. g60(t, x, y, x1, y1, dx, dy, p, q, k, it);
  288. if(t >= 1.0e-03)  goto zjn;
  289. if(g > 1.0e-18)
  290. {
  291. it = 0;
  292. g65(x, y, x1, y1, dx, dy, dd, dc, c, k, is, it);
  293. if(it == 0) goto zjn;
  294. }
  295. }
  296. g90(cx , a, x, y, p, q, w, k);
  297.         }
  298.         else
  299.         {
  300. g = g1;
  301. x = x1;
  302. y = y1;
  303. is = 0;
  304.             if(g <= 1.0e-22)
  305. g90(cx, a, x, y, p, q, w, k);
  306.             else
  307.             {
  308. u1 = k * a[0]; 
  309. v1 = 0.0;
  310.                 for(i = 2; i <= k; i++)
  311.                 {
  312. p = u1 * x;
  313. q = v1 * y;
  314. pq = (u1 + v1) * (x + y);
  315.                     u1 = p - q + (k - i + 1) * a[i - 1];
  316.                     v1 = pq - p - q;
  317.                 }
  318.                 p = u1 * u1 + v1 * v1;
  319.                 if(p <= 1.0e-20)
  320.                 {
  321. it = 0;
  322.                     g65(x, y, x1, y1, dx, dy, dd, dc, c, k, is, it);
  323.                     if(it == 0) goto zjn;
  324.                     g90(cx, a, x, y, p, q, w, k);
  325.                 }
  326.                 else
  327.                 {
  328. dx = (u * u1 + v * v1) / p;
  329.                     dy = (u1 * v - v1 * u) / p;
  330.                     t = 1.0 + 4.0 / k;
  331.                     g60(t, x, y, x1, y1, dx, dy, p, q, k, it);
  332.                     if(t >= 1.0e-03) goto zjn;
  333.                     if(g > 1.0e-18)
  334.                     {
  335. it = 0;
  336.                         g65(x, y, x1, y1, dx, dy, dd, dc, c, k, is, it);
  337.                         if(it == 0) goto zjn;
  338.                     }
  339.                     g90(cx, a, x, y, p, q, w, k);
  340.                 }
  341.             }
  342.         }
  343.         if(k == 1) jt = 0;
  344.         else jt = 1;
  345.     }
  346.     return(1);
  347. }
  348. //牛顿下山(NewtonHillDown)法求解复系数代数方程全部根(实根和复根)
  349. //重载RootNewtonHillDown()
  350. template <class _Ty>
  351. inline int 
  352. RootNewtonHillDown(complex<_Ty> a[], valarray<complex<_Ty> >& cx)
  353. {
  354. int m, i, jt, k, is, it, n;
  355.     _Ty t, x, y, x1, y1, dx, dy, dd, dc, c, g, g1, mo, sb, xb;
  356. _Ty w, u, p, q, pq, v, u1, v1;
  357.     
  358. n = cx.size(); //多项式方程的次数
  359.     m = n;
  360.     while((m > 0) && (FloatEqual(Abs(a[m]), 0))) m--;
  361.     if(m <= 0) return(-1);
  362.     mo = Abs(a[m]);
  363. for(i = 0; i <= m; i++) a[i] /= mo;
  364.     for(i = 0; i <= m / 2; i++)
  365.     {
  366. swap(a[i], a[m-i]);
  367. }
  368.     k = m;
  369. is = 0;
  370. w = 1.0;
  371.     jt = 1;
  372.     while(jt == 1)
  373.     {
  374. pq = Abs(a[k]);
  375. while(pq < LONGDOUBLEERROR)
  376.         {
  377. cx[k - 1] = complex<_Ty>(0.0, 0.0);
  378. k--;
  379.             if(k == 1)
  380.             {
  381. mo = a[0].real() * a[0].real() + a[0].imag() * a[0].imag();
  382. sb = -w * (a[0].real() * a[1].real() + a[0].imag() * a[1].imag()) / mo;
  383. xb =  w * (a[1].real() * a[0].real() - a[0].imag() * a[1].imag()) / mo;
  384. cx[0] = complex<_Ty>(sb, xb);
  385.                 return(1); 
  386.             }
  387. pq = Abs(a[k]);
  388.         }
  389. q = log(pq);
  390. q = q / (1.0 * k);
  391. q = exp(q);
  392.         p = q;
  393. w = w * p;
  394.         
  395. for(i = 1; i <= k; i++)
  396.         {
  397. a[i] /= q;
  398. q *= p;
  399. }
  400.         
  401. x = 0.0001;
  402. x1 = x; 
  403. y = 0.2;
  404. y1 = y; 
  405. dx = 1.0;
  406.         g = 1.0e+37; 
  407.  
  408. zjn:   
  409. u = a[0].real();
  410. v = a[0].imag();
  411.         
  412. for(i = 1; i <= k; i ++)
  413.         { 
  414. p = u * x1;
  415. q = v * y1;
  416.             pq = (u + v) * (x1 + y1);
  417.             u = p - q + a[i].real();
  418. v = pq - p - q + a[i].imag();
  419.         }
  420.         g1 = u * u + v * v;
  421.         if(g1 >= g)
  422.         { 
  423. if(is != 0)
  424. it = 1;
  425. g65(x, y, x1, y1, dx, dy, dd, dc, c, k, is, it);
  426. if(it == 0)
  427. goto zjn;
  428. }
  429. else
  430. {
  431. gg60(t, x, y, x1, y1, dx, dy, p, q, k, it);
  432. if(t >= 1.0e-03)  goto zjn;
  433. if(g > 1.0e-18)
  434. {
  435. it = 0;
  436. g65(x, y, x1, y1, dx, dy, dd, dc, c, k, is, it);
  437. if(it == 0) goto zjn;
  438. }
  439. }
  440. gg90(cx, a, x, y, p, q, w, k);
  441.         }
  442.         else
  443.         {
  444. g = g1;
  445. x = x1;
  446. y = y1;
  447. is = 0;
  448.             if(g <= 1.0e-22)
  449. gg90(cx, a, x, y, p, q, w, k);
  450.             else
  451.             {
  452. u1 = k * a[0].real(); 
  453. v1 = a[0].imag();
  454.                 for(i = 2; i <= k; i++)
  455.                 {
  456. p = u1 * x;
  457. q = v1 * y;
  458. pq = (u1 + v1) * (x + y);
  459.                     u1 = p - q + (k - i + 1) * a[i - 1].real();
  460.                     v1 = pq - p - q + (k - i + 1) * a[i - 1].imag();
  461.                 }
  462.                 p = u1 * u1 + v1 * v1;
  463.                 if(p <= 1.0e-20)
  464.                 {
  465. it = 0;
  466.                     g65(x, y, x1, y1, dx, dy, dd, dc, c, k, is, it);
  467.                     if(it == 0) goto zjn;
  468.                     gg90(cx, a, x, y, p, q, w, k);
  469.                 }
  470.                 else
  471.                 {
  472. dx = (u * u1 + v * v1) / p;
  473.                     dy = (u1 * v - v1 * u) / p;
  474.                     t = 1.0 + 4.0 / k;
  475.                     gg60(t, x, y, x1, y1, dx, dy, p, q, k, it);
  476.                     if(t >= 1.0e-03) goto zjn;
  477.                     if(g > 1.0e-18)
  478.                     {
  479. it = 0;
  480.                         g65(x, y, x1, y1, dx, dy, dd, dc, c, k, is, it);
  481.                         if(it == 0) goto zjn;
  482.                     }
  483.                     gg90(cx, a, x, y, p, q, w, k);
  484.                 }
  485.             }
  486.         }
  487.         if(k == 1) jt = 0;
  488.         else jt = 1;
  489.     }
  490.     return 1;
  491. }
  492. //牛顿下山法(NewtonHillDown)子函数
  493. template <class _Ty>
  494. inline void
  495. g60(_Ty& t, _Ty& x, _Ty& y, _Ty& x1, _Ty& y1, _Ty& dx, _Ty& dy, 
  496. _Ty& p, _Ty& q, int& k, int& it)
  497. it = 1;
  498.     while(it == 1)
  499.     {
  500. t = t / 1.67;
  501. it = 0;
  502.         x1 = x - t * dx;
  503.         y1 = y - t * dy;
  504.         if(k >= 50)
  505. {
  506. p = sqrt(x1 * x1 + y1 * y1);
  507.             q = exp(85.0 / k);
  508.             if(p >= q) it = 1;
  509.         }
  510.     }
  511. }
  512. //牛顿下山法(NewtonHillDown)子函数
  513. template <class _Ty>
  514. inline void
  515. gg60(_Ty& t, _Ty& x, _Ty& y, _Ty& x1, _Ty& y1, _Ty& dx, _Ty& dy, 
  516. _Ty& p, _Ty& q, int& k, int& it)
  517. it = 1;
  518.     while(it == 1)
  519.     {
  520. t = t / 1.67;
  521. it = 0;
  522.         x1 = x - t * dx;
  523.         y1 = y - t * dy;
  524.         if(k >= 30)
  525. {
  526. p = sqrt(x1 * x1 + y1 * y1);
  527.             q = exp(75.0 / k);
  528.             if(p >= q) it = 1;
  529.         }
  530.     }
  531. return;
  532. }
  533. //牛顿下山法(NewtonHillDown)子函数
  534. template <class _Ty, class _Tz>
  535. inline void
  536. g90(valarray<_Tz> &cx, valarray<_Ty> &a, _Ty& x, _Ty& y, _Ty& p, _Ty& q, _Ty& w, int &k)
  537. {
  538. int i;
  539.     if(Abs(y) <= 1.0e-06)
  540.     {
  541. p = -x;
  542. y = 0.0;
  543. q = 0.0;
  544. }
  545.     else
  546.     {
  547. p = -2.0 * x;
  548. q = x * x + y * y;
  549.         cx[k - 1] = complex<_Ty>(x * w, -y * w);
  550.         k = k-1;
  551.     }
  552.     for(i = 1; i <= k; i ++)
  553.     {
  554. a[i] = a[i] - a[i - 1] * p;
  555.         a[i + 1] = a[i + 1] - a[i - 1] * q;
  556.     }
  557.     cx[k - 1] = complex<_Ty>(x * w, y * w);
  558.     k = k - 1;
  559.     if(k == 1)
  560. cx[0] = complex<_Ty>(-a[1] * w / a[0], 0.0);
  561. }
  562. //牛顿下山法(NewtonHillDown)子函数
  563. template <class _Ty, class _Tz>
  564. inline void
  565. gg90(valarray<_Tz> &cx, complex<_Ty> a[], _Ty& x, _Ty& y, _Ty& p, _Ty& q, _Ty& w, int &k)
  566. {
  567. int i;
  568.     double mo, sb, xb;    
  569. for (i = 1; i <= k; i ++)
  570.   xb = a[i].real() + a[i-1].real() * x - a[i - 1].imag() * y;
  571.   sb = a[i].imag() + a[i-1].real() * y + a[i - 1].imag() * x;
  572.   a[i] = complex<_Ty>(xb, sb); 
  573. }
  574.     
  575.     cx[k - 1] = complex<_Ty>(x * w, y * w); 
  576. k --;
  577. if(k == 1)
  578. {
  579. mo = Abs(a[0])*Abs(a[0]);
  580. sb = -w * (a[0].real() * a[1].real() + a[0].imag() * a[1].imag()) / mo;
  581. xb =  w * (a[1].real() * a[0].imag() - a[0].real() * a[1].imag()) / mo;
  582. cx[0] = complex<_Ty>(sb, xb);
  583. }
  584.     return;
  585. }
  586. //牛顿下山法(NewtonHillDown)子函数
  587. template <class _Ty>
  588. inline void
  589. g65(_Ty& x, _Ty& y, _Ty& x1, _Ty& y1, _Ty& dx, _Ty& dy, _Ty& dd, _Ty& dc, _Ty& c, 
  590. int& k, int& is, int& it)
  591. {
  592. if(it == 0)
  593.     {
  594. is = 1;
  595.         dd = sqrt(dx * dx + dy * dy);
  596.         if(dd > 1.0) dd = 1.0;
  597.         dc = 6.28 / (4.5 * k);
  598. c = 0.0;
  599.     }
  600.     while(true)
  601.     {
  602. c += dc;
  603.         dx = dd * cos(c); 
  604. dy = dd * sin(c);
  605.         x1 = x + dx; 
  606. y1 = y + dy;
  607.         if(c <= 6.29)
  608.         {
  609. it = 0;
  610. return;
  611. }
  612. dd /= 1.67;
  613. if(dd <= 1.0e-07)
  614. {
  615. it = 1;
  616. return;
  617. }
  618. c = 0.0;
  619. }
  620. }
  621. //梯度(Gradient)法(最速下降)求解非线性方程组一组实根
  622. template <class _Ty>
  623. inline int 
  624. RootGradient(_Ty eps, valarray<_Ty>& x, size_t js)
  625.     int r, j;
  626.     _Ty f, d, s;
  627. int n = x.size(); //方程的个数,也是未知数的个数
  628. std::valarray<_Ty> y(n); //定义一维数组对象y
  629.     r = js;
  630.     f = FunctionValueRG(x,y);
  631.     while(f>=eps)
  632.     {
  633. r = r - 1;
  634.         if(r==0) return(js);
  635.         d = 0;
  636.         
  637. for(j=0; j<n; j++) d=d+y[j]*y[j];
  638.         if(FloatEqual(d,0)) return(-1);
  639.         s = f / d;
  640.         for(j=0; j<n; j++) x[j]=x[j]-s*y[j];
  641.         f=FunctionValueRG(x, y);
  642.     }
  643.     return(js-r);
  644. }
  645. //拟牛顿(QuasiNewton)法求解非线性方程组一组实根
  646. template <class _Ty>
  647. inline int 
  648. RootQuasiNewton(_Ty eps, _Ty t, _Ty h, valarray<_Ty>& x, int k)
  649. {
  650.     int i, j, l;
  651.     _Ty am, z, beta, d;
  652. int n = x.size(); //方程组中各方程个数,也是未知数个数
  653. matrix<_Ty> a(n, n); //定义二维数组对象a
  654. valarray<_Ty> b(n); //定义一维数组对象b
  655. valarray<_Ty> y(n); //定义一维数组对象y
  656.     
  657. l = k;
  658. am = 1.0 + eps;
  659.     while(am>=eps)
  660.     {
  661. FunctionValueRSN(x, b);
  662.         am = 0.0;
  663.         for(i=0; i<n; i++)
  664.         {
  665. z = Abs(b[i]);
  666.             if(z>am) am = z;
  667.         }
  668.         if(am>=eps)
  669.         {
  670. l--;
  671.             if(l==0)
  672. {
  673. cout << "Fail!" << endl;
  674. return(0);
  675. }
  676.             for(j=0; j<n; j++)
  677.             {
  678. z = x[j];
  679. x[j] += h;
  680.                 FunctionValueRSN(x, y);
  681.                 for(i=0; i<n; i++) 
  682. a(i,j) = y[i];
  683.                 x[j] = z;
  684.             }
  685. if(LE_TotalChoiceGauss(a, b) == 0)
  686. {
  687. cout << "Fail!" << endl;
  688. return(-1); //矩阵a奇异
  689. }
  690.             beta = 1.0;
  691.             for(i=0; i<n; i++) beta -= b[i];
  692.             
  693. if(FloatEqual(beta,0))
  694. {
  695. cout << "Fail!" << endl;
  696. return(-2); //beta=0
  697. }
  698.             d = h / beta;
  699.             
  700. for(i=0; i<n; i++) x[i]=x[i]-d*b[i];
  701.             h = t * h;
  702.         }
  703.     }
  704.     return(k-l); //正常结束,返回迭代次数
  705. }
  706. //非线性方程组最小二乘解的广义逆法
  707. template <class _Ty>
  708. int RootLeastSquareGeneralizedInverse(int m, _Ty eps1, _Ty eps2, valarray<_Ty>& x, int ka)
  709. {
  710.     int i, j, k, l, kk, jt;
  711. bool yn;
  712.     _Ty y[10],b[10],alpha,z,h2,y1,y2,y3,y0,h1;
  713. int n = x.size(); //非线性方程组中未知数个数
  714.     
  715. matrix<_Ty> p(m, n);
  716.     matrix<_Ty> pp(n, m);
  717.     matrix<_Ty> u(m, m);
  718.     matrix<_Ty> v(n, n);
  719. valarray<_Ty> w(ka);
  720. valarray<_Ty> d(m);
  721. valarray<_Ty> dx(n);
  722.     l = 60; 
  723. alpha = 1.0;
  724.     while(l > 0)
  725. {
  726. FunctionValueRLSGI(x, d); //计算非线性方程组左边函数值
  727.         JacobiMatrix(x, p); //计算雅可比矩阵
  728.         
  729. //最小二乘的广义逆法求解线性方程组
  730. jt = LE_LinearLeastSquareGeneralizedInverse(p, d, dx, pp, eps2, u, v);
  731.         if(jt < 0) return(jt);
  732.         
  733. j = 0;
  734. jt = 1;
  735. h2 = 0.0;
  736.         
  737. while(jt == 1)
  738. {
  739. jt = 0;
  740.             
  741. if(j < 3) z = alpha + 0.01 * j;
  742.             else z = h2;
  743.             
  744. for(i = 0; i < n; i++) w[i] = x[i] - z * dx[i];
  745.             
  746. FunctionValueRLSGI(w, d);
  747.             y1 = 0.0;
  748.             
  749. for(i = 0; i < m; i++) y1 = y1 + d[i] * d[i];
  750.             for(i = 0; i < n; i++) w[i] = x[i] - (z + 0.00001) * dx[i];
  751.             
  752. FunctionValueRLSGI(w, d);
  753.             
  754. y2 = 0.0;
  755.             for(i = 0; i < m; i++) y2 = y2 + d[i] * d[i];
  756.             
  757. y0 =(y2 - y1) / 0.00001;
  758.            
  759. if(Abs(y0) > 1.0e-10)
  760. {
  761. h1 = y0;
  762. h2 = z;
  763.                 
  764. if(j == 0)
  765. y[0] = h1;
  766. b[0] = h2;
  767. }
  768.                 else
  769. {
  770. y[j] = h1;
  771. kk = k = 0;
  772.                     while((kk == 0) && (k < j))
  773. {
  774. y3 = h2 - b[k];
  775. yn = FloatEqual(y3, 0);
  776. if(yn) kk = 1;
  777. else h2 = (h1 - y[k]) / y3;
  778. k++;
  779. }
  780.                     
  781. b[j] = h2;
  782.                     
  783. if(kk != 0) b[j] = 1.0e+35;
  784.                     
  785. h2 = 0.0;
  786.                     
  787. for(k = j - 1; k >= 0; k--)
  788. h2 = -y[k] / (b[k + 1] + h2);
  789.                     h2 = h2 + b[0];
  790. }
  791.                 
  792. j++;
  793.                 
  794. if(j <= 7) jt = 1;
  795.                 else z = h2;
  796. }
  797. }
  798.         
  799. alpha = z;
  800. y1 = y2 = 0.0;
  801.        
  802. for(i = 0; i <= n-1; i ++)
  803. {
  804. dx[i] = -alpha * dx[i];
  805.             x[i] = x[i] + dx[i];
  806.             y1 = y1 + Abs(dx[i]);
  807.             y2 = y2 + Abs(x[i]);
  808. }
  809.         
  810. if(y1 < eps1 * y2) return(1);
  811.         l--;
  812. }
  813.     return(0);
  814. }
  815. //蒙特卡洛(MonteCarlo)法求解f(x)=0的一个实根
  816. //f(x)的自变量为与系数都为实数
  817. template <class _Ty>
  818. inline void 
  819. RootMonteCarloReal(_Ty& x, _Ty b, int m, _Ty eps)
  820. {
  821.    // extern double mrnd1();
  822.     //extern double dmtclf();
  823.     //int k;
  824.     _Ty x1, y1;
  825.     _Ty a = b;
  826. size_t k = 1;
  827. double r = 1.0;
  828. _Ty xx = x;
  829. _Ty y = FunctionValueMCR(xx); //计算函数值
  830.     while(a>eps||FloatEqual(a,eps))
  831.     {
  832. x1 = rand_01_One(r); //取随机数
  833. x1 = -a + 2.0 * a * x1;
  834.         x1 = xx + x1; 
  835. y1 = FunctionValueMCR(x1); //计算函数值
  836.         k++;
  837.         if(Abs(y1)>Abs(y)||FloatEqual(Abs(y1),Abs(y)))
  838.         {
  839. if(k>m)
  840. {
  841. k = 1; 
  842. a /= 2.0;
  843. }
  844. }
  845.         else
  846.         {
  847. k = 1;
  848. xx = x1;
  849. y = y1;
  850.             if(Abs(y) < eps)
  851.             {
  852. x=xx;
  853. exit(0);
  854. }
  855.         }
  856.     }
  857.     x = xx;
  858. }
  859. //蒙特卡洛(MonteCarlo)法求解f(x)=0的一个复根
  860. //f(x)的自变量为复数,或自变量与系数都为复数(不能都为实数)
  861. template <class _Tz, class _Ty>
  862. inline void 
  863. RootMonteCarloComplex(_Tz& cxy, _Ty b, int m, _Ty eps)
  864. {
  865.     size_t k = 1;
  866. _Tz xxyy(cxy);
  867.     _Ty a = b;
  868. double r(1);
  869. _Ty z, z1;
  870.     z = FunctionModule(xxyy);
  871.     while(a > eps || FloatEqual(a,eps))
  872.     {
  873. _Ty tempx = -a + 2.0 *a * rand_01_One(r);
  874. _Ty tempy = -a + 2.0 *a * rand_01_One(r);
  875. _Tz x1y1(tempx,tempy);
  876. x1y1 += xxyy;
  877.         z1 = FunctionModule(x1y1);
  878.         
  879. k++;
  880.         if(z1 > z || FloatEqual(z1,z))
  881.         {
  882. if(k > m)
  883. {
  884. k = 1;
  885. a = a / 2.0;
  886. }
  887. }
  888.         else
  889.         {
  890. k = 1;
  891. xxyy = x1y1;
  892. z = z1;
  893.             if(z < eps)
  894. {
  895. cxy = xxyy;
  896. exit(0);
  897. }
  898.           }
  899.       }
  900.     cxy = xxyy;
  901. }
  902. //蒙特卡洛(MonteCarlo)法求解f(x)=0的一组实根
  903. //f(x)的自变量为与系数都为实数
  904. template <class _Ty>
  905. inline void 
  906. RootMonteCarloGroupReal(valarray<_Ty>& x, _Ty b, int m, _Ty eps)
  907. {
  908.     _Ty a=b;
  909. size_t k=1;
  910. double r=1.0;
  911. int n = x.size(); //方程个数,也是未知量的个数
  912. valarray<_Ty> y(n);
  913. _Ty z = FunctionModule(x);
  914.     while(a>eps||FloatEqual(a,eps))
  915.     {
  916. for(size_t i = 0; i < n; i++)
  917. y[i] = -a + 2.0 * a * rand_01_One(r) + x[i];
  918.         _Ty z1 = FunctionModule(y);
  919.         
  920. k++;
  921.         if(z1 > z || FloatEqual(z1,z))
  922.         {
  923. if(k > m)
  924. {
  925. k = 1;
  926. a = a / 2.0;
  927. }
  928. }
  929.         else
  930.         {
  931. k = 1; 
  932.             for(i = 0; i < n; i++) x[i] = y[i];
  933.             z = z1;
  934.             
  935. if(z < eps) exit(0);
  936.         }
  937.     }
  938. }
  939. #endif //_NONLINEAREQUATION_INL