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

Visual C++

  1. // Extremum.inl 计算极值函数(方法)定义头文件
  2. // Ver 1.0.0.0
  3. // 版权所有(C) 何渝, 2002
  4. // 最后修改: 2002.5.31.
  5. #ifndef _EXTREMUM_INL //避免多次编译
  6. #define _EXTREMUM_INL
  7. //一维极值连分式法
  8. template <class _Ty>
  9. void ExtremumFraction1D(valarray<_Ty>& x, _Ty eps, 
  10. int k, valarray<int>& js)
  11. {
  12.     _Ty xx,h1,dx,y[10],b[10],h2(0);
  13. valarray<_Ty> z(2);
  14.     int jt = 1;
  15. js[0] = 0;
  16.     while(jt == 1)
  17.     {
  18. int j=0;
  19.         while(j<=7)
  20.         {
  21. if(j <=2) 
  22. xx=x[0]+0.01*j;
  23.             else xx=h2;
  24.             FunctionValueEF1D(xx,z);
  25.             if(Abs(z[1]) < eps)
  26.             {
  27. jt=0; 
  28. j=10;
  29. }
  30.             else
  31.             {
  32. h1=z[1]; 
  33. h2=xx;
  34.                 if(j==0)
  35. {
  36. y[0]=h1;
  37. b[0]=h2;
  38. }
  39.                 else
  40.                 {
  41. y[j]=h1;
  42. int m=0;
  43. int i=0;
  44.                     while((m==0)&&(i<=j-1))
  45. {
  46. if(FloatEqual((h2-b[i]),0)) 
  47. m=1;
  48. else
  49. h2=(h1-y[i])/(h2-b[i]);
  50.                         i=i+1;
  51. }
  52.                     b[j]=h2;
  53.                     if(m!=0)
  54. b[j]=1.0e+35;
  55.                     h2=0.0;
  56.                     for(i=j-1; i>=0; i--)
  57. h2=-y[i]/(b[i+1]+h2);
  58.                     h2=h2+b[0];
  59.                 }
  60.                 j=j+1;
  61.             }
  62.         }
  63.         x[0]=h2;
  64.         js[0]=js[0]+1;
  65.         if(js[0]==k)  jt=0;
  66.     }
  67.     xx = x[0];
  68.     FunctionValueEF1D(xx,z);
  69. x[1] = z[0];
  70.     if(Abs(x[0]) < 1.0 || FloatEqual(Abs(x[0]), 1)) dx=1.0e-05;
  71.     else dx = Abs(x[0] * 1.0e-05);
  72.     xx = x[0] - dx;
  73.     FunctionValueEF1D(xx,z);
  74. h1 = z[0];
  75.     xx = x[0] + dx;
  76.     FunctionValueEF1D(xx,z);
  77. h2 = z[0];
  78.     js[1] = -1;
  79.     if((h1 + h2 - 2.0 * x[1]) < 0.0 || FloatEqual((h1 + h2 - 2.0 * x[1]),0)) js[1]=1;
  80. }
  81. //n维极值连分式法
  82. template <class _Ty>
  83. void ExtremumFractionND(valarray<_Ty>& x, _Ty eps, 
  84. int k, valarray<int>& js)
  85. {
  86.     int i,j,m,l,jt(1),il;
  87.     _Ty y[10],b[10],p,z,t,h1,h2(0),f,dx;
  88. int n = x.size()-1; //自变量个数
  89.     js[0] = 0;
  90. //jt = 1;
  91. //h2 = 0;
  92.     while(jt == 1)
  93.     {
  94. t=0.0; 
  95. js[0]=js[0]+1;
  96.         for(i=1; i<=n; i++)
  97.         {
  98. f=FunctionValueEFND(x,i);
  99.             t=t+Abs(f);
  100.         }
  101.         if(t<eps) jt=0;
  102.         else
  103.         {
  104. for(i = 0; i < n; i++)
  105.               { 
  106. il=5;
  107.                 while(il!=0)
  108.                 {
  109. j=0;
  110. t=x[i];
  111. il=il-1;
  112.                     while(j<=7)
  113.                     {
  114. if(j<=2) z=t+j*0.01;
  115.                         else z=h2;
  116.                         x[i]=z;
  117.                         f=FunctionValueEFND(x,i+1);
  118.                         if(FloatEqual(f,0))
  119.                         {
  120. j=10;
  121. il=0;
  122. }
  123.                         else
  124.                         {
  125. h1=f;
  126. h2=z;
  127.                             if(j==0)
  128.                             {
  129. y[0]=h1;
  130. b[0]=h2;
  131. }
  132.                             else
  133.                             {
  134. y[j]=h1;
  135. m=0;
  136. l=0;
  137.                                 while((m==0)&&(l<=j-1))
  138.                                 {
  139. p=h2-b[l];
  140.                                     if(FloatEqual(p,0)) m=1;
  141.                                     else h2=(h1-y[l])/p;
  142.                                     l=l+1;
  143.                                 }
  144.                                 b[j]=h2;
  145.                                 if(m!=0) b[j]=1.0e+35;
  146.                                 h2=0.0;
  147.                                 for(l=j-1; l>=0; l--)
  148.                                 h2=-y[l]/(b[l+1]+h2);
  149.                                 h2=h2+b[0];
  150.                             }
  151.                             j=j+1;
  152.                         }
  153.                     }
  154.                     x[i]=h2; 
  155.                 }
  156.                 x[i]=z;
  157.             }
  158.             if(js[0]==k) jt=0;
  159.         }
  160.     }
  161.     js[1]=1;
  162.     f=FunctionValueEFND(x,0); 
  163. x[n]=f;
  164.     dx=0.00001;
  165. t=x[0];
  166.     x[0]=t+dx;
  167. h1=FunctionValueEFND(x,0);
  168.     x[0]=t-dx;
  169. h2=FunctionValueEFND(x,0);
  170.     x[0]=t;
  171.     t=h1+h2-2.0*f;
  172.     if(t>0.0) js[1]=-1;
  173.     j=1; jt=1;
  174.     while(jt==1)
  175.     {
  176. j=j+1;
  177. dx=0.00001;
  178. jt=0;
  179.         t=x[j-1];
  180.         x[j-1]=t+dx;
  181. h2=FunctionValueEFND(x,0);
  182.         x[j-1]=t-dx;
  183. h1=FunctionValueEFND(x,0);
  184.         x[j-1]=t;
  185. t=h1+h2-2.0*f;
  186.         if((t*js[1]<0.0)&&(j<n)) jt=1;
  187.     }
  188.     if(t*js[1]>0.0) js[1]=0;
  189. }
  190. //线性规划
  191. template <class _Ty>
  192. int ExtremumLinePrograming(matrix<_Ty>& a, valarray<_Ty>& b, 
  193. valarray<_Ty>& c, valarray<_Ty>& x)
  194. {
  195.     _Ty y;
  196. int m = b.size(); //不等式约束条件的个数
  197. int n = c.size() - m; //变量个数
  198. valarray<int> js(m);
  199. matrix<_Ty> p(m, m);
  200. matrix<_Ty> d(m, (m+n));
  201. for(int i = 0; i < m; i++) js[i] = n + i;
  202.     int mn = m + n;
  203. _Ty s(0);
  204.     while(1==1)
  205.     {
  206. for(i = 0; i < m; i++)
  207.           for(int j = 0; j < m; j++)
  208.   p(i,j) = a(i, js[j]);
  209.         int l=MatrixInversionGS(p);
  210.         if(l==0)
  211.         {
  212. x[n]=s;
  213.             return(l);
  214.         }
  215. d = p * a; //矩阵相乘
  216.         
  217.         for(i=0; i<mn; i++) x[i]=0.0;
  218.         for(i=0; i<m; i++)
  219.         {
  220. s=0.0;
  221.             for(int j=0; j<m; j++)
  222.               s=s + p(i,j) * b[j];
  223.             x[js[i]]=s;
  224.         }
  225.         int k = -1;
  226. _Ty dd=1.0e-35;
  227.         for(int j = 0; j < mn; j++)
  228.         {
  229. _Ty z(0);
  230.             for(i=0; i<m; i++)
  231.               z = z + c[js[i]] * d(i, j);
  232.             z = z - c[j];
  233.             if(z > dd)
  234. {
  235. dd = z;
  236. k = j;
  237. }
  238.         }
  239.         if(k == -1)
  240.           {
  241. s=0.0;
  242.             for(j=0; j<n; j++)
  243. s = s + c[j] * x[j];
  244. x[n] = s;
  245.             return(1);
  246.         }
  247.         j = -1;
  248.         dd = 1.0e+20;
  249.         for(i=0; i<m; i++)
  250. if(d(i, k) >= 1.0e-20 )
  251.             { 
  252.   y=x[js[i]] / d(i, k);
  253.               if(y < dd)
  254.   {
  255.   dd = y; 
  256.   j = i;
  257.   }
  258. }
  259.         if(j==-1) 
  260.         {
  261. x[n]=s;
  262.             return(0);
  263.         }
  264.         js[j]=k;
  265.     }
  266. }
  267. //n维极值单形调优法
  268. template <class _Ty>
  269. int ExtremumSimplexND(_Ty d, _Ty u, _Ty v, valarray<_Ty>& x,  
  270. _Ty eps, int k, matrix<_Ty>& xx, valarray<_Ty>& f)
  271. {
  272. int r,g,l;
  273. _Ty fe,ft,ff;
  274. int n = x.size() - 1; //变量个数
  275. valarray<_Ty> xt(n);
  276. valarray<_Ty> xf(n);
  277. valarray<_Ty> xe(n);
  278.     int kk=0;
  279. _Ty nn=1.0*n;
  280.     _Ty fr=sqrt(nn+1.0);
  281.     _Ty fl=d*(fr-1.0)/(1.414*nn);
  282.     _Ty fg=d*(fr+nn-1.0)/(1.414*nn);
  283.     for(int i=0; i<n; i++)
  284.     for(int j=0; j<=n; j++)
  285.        xx(i,j) = 0;
  286.     for(i=1; i<=n; i++)
  287.     for(int j=0; j<n; j++)
  288.        xx(j,i) = fl;
  289.     for(i=1; i<=n; i++)
  290.        xx((i-1),i) = fg;
  291.     for(i=0; i<=n; i++)
  292.     { 
  293. for(int j=0; j<n; j++) xt[j]=xx(j,i);
  294.         f[i]=FunctionValueESND(xt,n);
  295.     }
  296.     ft=1.0+eps;
  297.     while((kk<k)&&(ft>eps))
  298.     {
  299. kk=kk+1;
  300.         fr=f[0]; fl=f[0]; r=0; l=0;
  301.         for(i=1; i<=n; i++)
  302.         {
  303. if(f[i]>fr)
  304. {
  305. r=i;
  306. fr=f[i];
  307. }
  308.             if(f[i]<fl)
  309. {
  310. l=i;
  311. fl=f[i];
  312. }
  313.         }
  314.         g=0;
  315. fg=f[0];
  316.         int j=0;
  317.         if(r==0)
  318. {
  319. g=1;
  320. fg=f[1];
  321. j=1;
  322. }
  323.         for(i=j+1; i<=n; i++)
  324. if((i!=r)&&(f[i]>fg))
  325.             {
  326. g=i;
  327. fg=f[i];
  328. }
  329.         for(j=0; j<n; j++)
  330.         {
  331. xf[j]=0.0;
  332.             for(i=0; i<=n; i++)
  333. if(i!=r) xf[j]=xf[j]+xx(j,i)/nn;
  334.             xt[j]=2.0*xf[j]-xx(j,r);
  335.         }
  336.         ft=FunctionValueESND(xt,n);
  337.         if(ft<f[l])
  338.         {
  339. for(j=0; j<n; j++) xf[j]=(1.0+u)*xt[j]-u*xf[j];
  340.             ff=FunctionValueESND(xf,n);
  341.             if(ff<f[l])
  342.             {
  343. for(j=0; j<n; j++) xx(j,r)=xf[j];
  344.                 f[r]=ff;
  345.             }
  346.             else
  347. {
  348. for(j=0; j<n; j++) xx(j,r)=xt[j];
  349.                 f[r]=ft;
  350.             }
  351.         }
  352.         else
  353.         {
  354. if(ft<=f[g])
  355.             {
  356. for(j=0; j<=n-1; j++) xx(j,r)=xt[j];
  357.                 f[r]=ft;
  358.             }
  359.             else 
  360.             {
  361. if(ft<=f[r])
  362.                 {
  363. for(j=0; j<=n-1; j++) xx(j,r)=xt[j];
  364.                     f[r]=ft;
  365.                 }
  366.                 for(j=0; j<n; j++) xf[j]=v*xx(j,r)+(1.0-v)*xf[j];
  367.                 ff=FunctionValueESND(xf,n);
  368.                 if(ff>f[r])
  369.                   for(i=0; i<=n; i++)
  370.                   {
  371.   for(j=0; j<=n-1; j++)
  372.   {
  373.   xx(j,i)=(xx(j,i)+xx(j,l))/2.0;
  374.                           x[j]=xx(j,i);
  375.   xe[j]=x[j];
  376.                       }
  377.                       fe=FunctionValueESND(xe,n);
  378.   f[i]=fe;
  379.                   }
  380.                 else
  381.                 {
  382. for(j=0; j<=n-1; j++) xx(j,r)=xf[j];
  383.                     f[r]=ff;
  384.                 }
  385.             }
  386.         }
  387.         ff=0.0;
  388. ft=0.0;
  389.         for(i=0; i<=n; i++)
  390.         {
  391. ff=ff+f[i]/(1.0+nn);
  392.             ft=ft+f[i]*f[i];
  393.         }
  394.         ft=(ft-(1.0+n)*ff*ff)/nn;
  395.     }
  396.     for(int j=0; j<n; j++)
  397.     {
  398. x[j] = 0.0;
  399.         for(i=0; i<=n; i++) x[j] = x[j] + xx(j,i) / (1.0+nn);
  400.         xe[j] = x[j];
  401.     }
  402.     fe = FunctionValueESND(xe,n);
  403. x[n] = fe;
  404.     return(kk);
  405. }
  406. //n维极值复形调优法
  407. template <class _Ty>
  408. int ExtremumComplexND(int m, valarray<_Ty>& a, valarray<_Ty>& b,
  409. _Ty alpha, _Ty eps, valarray<_Ty>& x, matrix<_Ty>& xx, int k)
  410. {
  411.     int r, g, kt, jt, kk;
  412.     _Ty fj, fr, fg, z;
  413. double rr = 0; //随机数种子
  414. int n = a.size(); //变量个数
  415. valarray<_Ty> c(m);
  416. valarray<_Ty> d(m);
  417. valarray<_Ty> w(m);
  418. valarray<_Ty> xt(m);
  419. valarray<_Ty> xf(m);
  420.     for(int i=0; i<n; i++) xx(i,0) = x[i];
  421.     xx(n,0) = FunctionValueTarget(x,n);
  422.     for(int j=1; j<2*n; j++)
  423.     {
  424. for(i=0; i<n; i++)
  425. {
  426. xx(i,j) = a[i] + (b[i] - a[i]) * rand_01_One(rr);
  427.             x[i] = xx(i,j);
  428.         }
  429.         int it = 1;
  430.         while(it==1)
  431.         {
  432. it = 0;
  433. r = 0;
  434. g = 0;
  435.             while((r<n)&&(g==0))
  436.             {
  437. if((a[r]<=x[r])&&(b[r]>=x[r])) r = r + 1;
  438.                 else g = 1;
  439.             }
  440.             if(g==0)
  441.             {
  442. ConditionValue(n,m,x,c,d,w);
  443.                 r = 0;
  444.                 while((r<m)&&(g==0))
  445.                 {
  446. if((c[r]<=w[r])&&(d[r]>=w[r])) r=r+1;
  447.                     else g=1;
  448.                 }
  449.             }
  450.             if(g!=0)
  451.             {
  452. for(r=0; r<n; r++)
  453.                 {
  454. z = 0.0;
  455.                     for(g=0; g<j; g++) z = z + xx(r,g) / (1.0*j);
  456.                     xx(r,j) = (xx(r,j) + z) / 2.0;
  457.                     x[r]=xx(r,j);
  458.                 }
  459.                 it = 1;
  460.             }
  461.             else xx(n,j) = FunctionValueTarget(x,n);
  462.         }
  463.     }
  464.     kk = 1;
  465. int it = 1;
  466.     while(it==1)
  467.     {
  468. it = 0;
  469.         fr = xx(n,0);
  470. r = 0;
  471.         for(i=1; i<2*n; i++)
  472.           if(xx(n,i)>fr)
  473.           {
  474.   r = i;
  475.   fr = xx(n,i);
  476.   }
  477.         g = 0;
  478. j = 0;
  479. fg = xx(n,0);
  480.         if(r==0)
  481.         {
  482. g = 1;
  483. j = 1;
  484. fg = xx(n,1);
  485. }
  486.         for(i=j+1; i<2*n; i++)
  487.           if(i!=r)
  488.             if(xx(n,i)>fg)
  489.             {
  490. g = i;
  491. fg = xx(n,i);
  492. }
  493.         for(i=0; i<n; i++)
  494.         {
  495. xf[i] = 0.0;
  496.             for(j=0; j<2*n; j++)
  497.               if(j!=r) xf[i]=xf[i]+xx(i,j)/(2.0*n-1.0);
  498.             xt[i]=(1.0+alpha)*xf[i]-alpha*xx(i,r);
  499.         }
  500.         jt = 1;
  501.         while(jt==1)
  502.         {
  503. jt = 0;
  504.             z = FunctionValueTarget(xt,n);
  505.             while(z>fg)
  506.             {
  507. for(i=0; i<n; i++) xt[i]=(xt[i]+xf[i])/2.0;
  508.                 z = FunctionValueTarget(xt,n);
  509.             }
  510.             j=0;
  511.             for(i=0; i<n; i++)
  512.             { 
  513. if(a[i]>xt[i])
  514.                 {
  515. xt[i]=xt[i]+0.000001;
  516. j=1;
  517. }
  518. if(b[i]<xt[i])
  519.                 {
  520. xt[i]=xt[i]-0.000001;
  521. j=1;
  522. }
  523.             }
  524.             if(j!=0) jt=1;
  525.             else
  526.             {
  527. ConditionValue(n,m,xt,c,d,w);
  528.                 j=0;
  529. kt=1;
  530.                 while((kt==1)&&(j<m))
  531.                 {
  532. if((c[j]<=w[j])&&(d[j]>=w[j])) j=j+1;
  533.                     else kt=0;
  534.                 }
  535.                 if(j<m)
  536.                 { 
  537. for(i=0; i<n; i++) xt[i]=(xt[i]+xf[i])/2.0;
  538.                     jt=1;
  539.                 }
  540.             }
  541.         }
  542.         for(i=0; i<n; i++) xx(i,r)=xt[i];
  543.         xx(n,r) = z;
  544.         fr = 0.0; 
  545. fg = 0.0;
  546.         for(j=0; j<2*n; j++)
  547.         {
  548. fj = xx(n,j);
  549.             fr = fr + fj / (2.0*n);
  550.             fg = fg + fj * fj;
  551.         }
  552.         fr = (fg - 2.0 * n * fr * fr) / (2.0 * n - 1.0);
  553.         if(fr>=eps)
  554.         {
  555. kk = kk + 1;
  556.             if(kk<k) it = 1;
  557.         }
  558.     }
  559.     for(i=0; i<n; i++)
  560.     {
  561. x[i] = 0.0;
  562.         for(j=0; j<2*n; j++) x[i]=x[i]+xx(i,j)/(2.0*n);
  563.     }
  564.     z = FunctionValueTarget(x,n);
  565. x[n] = z;
  566.     return(kk);
  567. }
  568. //确定1维函数极小值点所在区间
  569. template <class _Ty>
  570. void MinimizerInterval(_Ty& ax, _Ty& bx, _Ty& cx, _Ty& fa, _Ty& fb, _Ty& fc)
  571. {
  572.     _Ty r,q,dum,gold = 1.0 + GoldNo;
  573.     _Ty u,ulim,fu,tiny = 1e-20;
  574. int glimit = 100;
  575.     fa = FunctionValue(ax);
  576.     fb = FunctionValue(bx);
  577.     if (fb > fa)
  578. {
  579.         dum = ax;
  580.         ax = bx;
  581.         bx = dum;
  582.         dum = fb;
  583.         fb = fa;
  584.         fa = dum;
  585.     }
  586.     cx = bx + gold * (bx - ax);
  587.     fc = FunctionValue(cx);
  588. while (fb >= fc)
  589. {
  590.         r = (bx - ax) * (fb - fc);
  591.         q = (bx - cx) * (fb - fa);
  592.         dum = q - r;
  593.         if (Abs(dum) < tiny)
  594. {
  595. dum = tiny;
  596. }
  597.         u = bx - ((bx - cx) * q - (bx - ax) * r) / (2 * dum);
  598.         ulim = bx + glimit * (cx - bx);
  599.         if ((bx - u) * (u - cx) > 0)
  600. {
  601.             fu = FunctionValue(u);
  602.             if (fu < fc)
  603. {
  604.                 ax = bx;
  605.                 fa = fb;
  606.                 bx = u;
  607.                 fb = fu;
  608.                 return;
  609. }
  610.             else
  611. {
  612. if (fu > fb)
  613. {
  614. cx = u;
  615. fc = fu;
  616. return;
  617. }
  618.             }
  619.             u = cx + gold * (cx - bx);
  620.             fu = FunctionValue(u);
  621. }
  622.         else
  623. {
  624. if ((cx - u) * (u - ulim) > 0)
  625. {
  626. fu = FunctionValue(u);
  627. if (fu < fc)
  628. {
  629. bx = cx;
  630. cx = u;
  631. u = cx + gold * (cx - bx);
  632. fb = fc;
  633. fc = fu;
  634. fu = FunctionValue(u);
  635. }
  636.             }
  637. else
  638. {
  639. if ((u - ulim) * (ulim - cx) > 0 || FloatEqual((u - ulim) * (ulim - cx),0))
  640. {
  641. u = ulim;
  642. fu = FunctionValue(u);
  643. }
  644. else
  645. {
  646. u = cx + gold * (cx - bx);
  647. fu = FunctionValue(u);
  648. }
  649. }
  650. }
  651. ax = bx;
  652. bx = cx;
  653. cx = u;
  654. fa = fb;
  655. fb = fc;
  656. fc = fu;
  657. }
  658. }
  659. //确定一维函数极小值点所在区间(重载)
  660. template <class _Ty>
  661. int MinimizerInterval(_Ty& ax, _Ty& bx, _Ty& cx, int& sign, 
  662. _Ty b, _Ty& fa, _Ty& fb, _Ty& fc)
  663. {
  664.     _Ty r,q,dum,gold = GoldNo + 1.0;
  665.     _Ty u,ulim,fu,tiny = 1e-20;
  666. int glimit = 100;
  667.     fa = FunctionValue(ax);
  668.     fb = FunctionValue(bx);
  669.     if (fb > fa)
  670. {
  671. sign = -1;
  672. fa *= sign;
  673. fb *= sign;
  674.     }
  675.     cx = bx + gold * (bx - ax);
  676. fc = sign * FunctionValue(cx);
  677. while (fb >= fc)
  678. {
  679.         r = (bx - ax) * (fb - fc);
  680.         q = (bx - cx) * (fb - fa);
  681.         dum = q - r;
  682.         if (Abs(dum) < tiny)
  683. {
  684. dum = tiny;
  685. }
  686.         u = bx - ((bx - cx) * q - (bx - ax) * r) / (2 * dum);
  687.         ulim = bx + glimit * (cx - bx);
  688. if(u > b) //超出f(x)右边界
  689. {
  690. cout<<"  The MinimizerInterval exceed right border. Program is over!"<<endl;
  691. return 0;
  692. }
  693.         if ((bx - u) * (u - cx) > 0)
  694. {
  695.             fu = sign * FunctionValue(u);
  696.             if (fu < fc)
  697. {
  698.                 ax = bx;
  699.                 fa = fb;
  700.                 bx = u;
  701.                 fb = fu;
  702.                 return 1;
  703. }
  704.             else
  705. {
  706. if (fu > fb)
  707. {
  708. cx = u;
  709. fc = fu;
  710. return 1;
  711. }
  712.             }
  713.             u = cx + gold * (cx - bx);
  714.             fu = sign * FunctionValue(u);
  715. }
  716.         else
  717. {
  718. if ((cx - u) * (u - ulim) > 0)
  719. {
  720. fu = sign * FunctionValue(u);
  721. if (fu < fc)
  722. {
  723. bx = cx;
  724. cx = u;
  725. u = cx + gold * (cx - bx);
  726. fb = fc;
  727. fc = fu;
  728. fu = sign * FunctionValue(u);
  729. }
  730.             }
  731. else
  732. {
  733. if ((u - ulim) * (ulim - cx) > 0 || FloatEqual((u - ulim) * (ulim - cx),0))
  734. {
  735. u = ulim;
  736. fu = sign * FunctionValue(u);
  737. }
  738. else
  739. {
  740. u = cx + gold * (cx - bx);
  741. fu = sign * FunctionValue(u);
  742. }
  743. }
  744. }
  745. ax = bx;
  746. bx = cx;
  747. cx = u;
  748. fa = fb;
  749. fb = fc;
  750. fc = fu;
  751. }
  752. return 1;
  753. }
  754. //1维函数极小值的黄金分割法
  755. template <class _Ty>
  756. _Ty ExtremumGold1D(_Ty ax, _Ty bx, _Ty cx, int sign, _Ty tol, _Ty& xmin)
  757. {
  758.     _Ty x0,x1,x2,x3,f0,f1,f2,f3,r = GoldNo;
  759.     _Ty c = 1.0 - GoldNo;
  760.     x0 = ax;
  761.     x3 = cx;
  762.     if (Abs(cx - bx) > Abs(bx - ax))
  763. {
  764. x1 = bx;
  765.         x2 = bx + c * (cx - bx);
  766. }
  767.     else
  768. {
  769.         x2 = bx;
  770.         x1 = bx - c * (bx - ax);
  771.     }
  772.     f1 = sign * FunctionValue(x1);
  773.     f2 = sign * FunctionValue(x2);
  774.     while (Abs(x3 - x0) > tol * (Abs(x1) + Abs(x2)))
  775. {
  776.         if (f2 < f1)
  777. {
  778.             x0 = x1;
  779.             x1 = x2;
  780.             x2 = r * x1 + c * x3;
  781.             f0 = f1;
  782.             f1 = f2;
  783.             f2 = sign * FunctionValue(x2);
  784. }
  785.         else
  786. {
  787.             x3 = x2;
  788.             x2 = x1;
  789.             x1 = r * x2 + c * x0;
  790.             f3 = f2;
  791.             f2 = f1;
  792.             f1 = sign * FunctionValue(x1);
  793.         }
  794.     }
  795.     if (f1 < f2)
  796. {
  797.         xmin = x1;
  798. if (sign == -1)
  799. f1 = sign * f1;
  800.         return f1;
  801. }
  802.     else
  803. {
  804.         xmin = x2;
  805. if (sign == -1)
  806. f2 = sign * f2;
  807.         return f2;
  808.     }
  809. }
  810. //1维函数极小值点的不用导数布伦特(Brent)法
  811. template <class _Ty>
  812. _Ty ExtremumBrentNonDerivative1D(_Ty ax, _Ty bx, _Ty cx, int sign, 
  813. _Ty tol, _Ty& xmin)
  814. {
  815.     int done,iter,itmax = 100;
  816.     _Ty d,fu,r,q,p,xm,tol1,tol2,a,b,cgold = 1.0 - GoldNo;
  817.     _Ty u,etemp,dum,v,w,x,e,fx,fv1,fw,zeps = DOUBLEERROR;
  818.     a = ax;
  819.     if (cx < ax)
  820. {
  821. a = cx;
  822. }
  823.     b = ax;
  824.     if (cx > ax)
  825. {
  826. b = cx;
  827. }
  828.     v = bx;
  829.     w = v;
  830.     x = v;
  831.     e = 0.0;
  832.     fx = sign * FunctionValue(x);
  833.     fv1 = fx;
  834.     fw = fx;
  835.     for (iter = 1; iter<=itmax; iter++)
  836. {
  837.         xm = 0.5 * (a + b);
  838.         tol1 = tol * Abs(x) + zeps;
  839.         tol2 = 2.0 * tol1;
  840.         if (Abs(x - xm) <= tol2 - 0.5 * (b - a))
  841. {
  842. break;
  843. }
  844.         done = -1;
  845.         if (Abs(e) > tol1)
  846. {
  847.             r = (x - w) * (fx - fv1);
  848.             q = (x - v) * (fx - fw);
  849.             p = (x - v) * q - (x - w) * r;
  850.             q = 2.0 * (q - r);
  851.             if (q > 0.0)
  852. {
  853. p = -p;
  854. }
  855.             q = Abs(q);
  856.             etemp = e;
  857.             e = d;
  858.             dum = Abs(0.5 * q * etemp);
  859.             if (Abs(p) < dum && p > q * (a - x) && p < q * (b - x))
  860. {
  861.                 d = p / q;
  862.                 u = x + d;
  863.                 if (u - a < tol2 || b - u < tol2)
  864. {
  865.                     d = Abs(tol1) * Sgn(xm - x);
  866.                 }
  867.                 done = 0;
  868.             }
  869.         }
  870.         if (done)
  871. {
  872.             if (x > xm || FloatEqual(x,xm))
  873. {
  874.                 e = a - x;
  875. }
  876.             else
  877. {
  878.                 e = b - x;
  879.             }
  880.             d = cgold * e;
  881.         }
  882.         if (Abs(d) > tol1 || FloatEqual(d,tol1))
  883. {
  884.             u = x + d;
  885. }
  886.         else
  887. {
  888.             u = x + Abs(tol1) * Sgn(d);
  889.         }
  890.         fu = sign * FunctionValue(u);
  891.         if (fu < fx || FloatEqual(fu,fx))
  892. {
  893.             if (u > x || FloatEqual(u,x))
  894. {
  895.                 a = x;
  896. }
  897.             else
  898. {
  899.                 b = x;
  900.             }
  901.             v = w;
  902.             fv1 = fw;
  903.             w = x;
  904.             fw = fx;
  905.             x = u;
  906.             fx = fu;
  907. }
  908.         else
  909. {
  910.             if (u < x)
  911. {
  912.                 a = u;
  913. }
  914.             else
  915. {
  916.                 b = u;
  917.             }
  918.             if (fu < fw || FloatEqual(fu,fw) || FloatEqual(w,x))
  919. {
  920.                 v = w;
  921.                 fv1 = fw;
  922.                 w = u;
  923.                 fw = fu;
  924. }
  925.             else
  926. {
  927. if (fu < fv1 || FloatEqual(fu,fv1) ||  FloatEqual(v,x) ||  FloatEqual(v,w))
  928. {
  929. v = u;
  930. fv1 = fu;
  931. }
  932.             }
  933.         }
  934.     }
  935.     if (iter > itmax)
  936. {
  937. cout<<" ExtremumBrentNonDerivative1D exceed maximum iterations."<<endl;
  938. }
  939.     xmin = x;
  940.     if(sign == -1) 
  941. {
  942. fx *= sign;
  943. }
  944. return fx;
  945. }
  946. #endif // _EXTREMUM_INL