00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 #ifndef UNCMIN_H_
00181 #define UNCMIN_H_
00182 
00183 #include <cstdio>
00184 #include <cmath>
00185 
00186 #ifdef BOOST_NO_STDC_NAMESPACE
00187 
00188 namespace std
00189 { using ::sqrt; using ::pow; using ::fabs; using ::log; using ::FILE; using ::fprintf;}
00190 #endif
00191 
00192 #ifndef BOOST_NO_LIMITS
00193 
00194 #include <limits>
00195 #else
00196 
00197 #include <float.h>
00198 #endif
00199 
00200 
00201 
00202 template<class V, class M, class FUNC> class Uncmin
00203 {
00204 
00205 public:
00206 
00207   typedef FUNC function_type;   
00208 
00209   
00210   Uncmin(FUNC *f);
00211   
00212   
00213   Uncmin(int d = 1);
00214 
00215   
00216   ~Uncmin();
00217 
00218   
00219   int Minimize(V &start, V &xpls, double &fpls, V &gpls, M &hpls);
00220 
00221   
00222 
00223   int Minimize(V &start, V &xpls, double &fpls, V &gpls);
00224 
00225   
00226   FUNC *GetFunction();
00227 
00228   
00229   void SetFunction(FUNC *f);
00230 
00231   
00232   void SetFuncExpensive(int iexp);
00233 
00234   
00235   int SetScaleArg(V typsiz);
00236 
00237   
00238   void SetScaleFunc(double fscale);
00239 
00240   
00241   void SetNumDigits(double ndigit);
00242 
00243   
00244   void SetMaxIter(int maxiter);
00245 
00246   
00247   void SetTolerances(double step, double grad, double macheps = -1.0);
00248 
00249   
00250   void SetMaxStep(double stepmx);
00251 
00252   
00253   void SetTrustRegionRadius(double dlt);
00254 
00255   
00256   void SetChecks(int check_gradient, int check_hessian = 0);
00257 
00258   
00259   void SetPrint(std::FILE *file, int print_results, int print_iterations = 0);
00260 
00261   
00262 
00263   void SetMethod(int method);
00264 
00265   
00266   void GetStoppingCriteria(double &gradtol, double &steptol, int &iterations);
00267 
00268 
00269   int GetMessage();
00270 
00271 private:
00272 
00273   FUNC *minclass; 
00274 
00275 
00276   int algorithm; 
00277 
00278   std::FILE *mfile; 
00279 
00280   int n; 
00281 
00282   double epsm; 
00283 
00284 
00285   double mLastGradCrit;  
00286   
00287 
00288   double mLastStepCrit; 
00289 
00290   
00291   int mLastIteration; 
00292 
00293 
00294   int mLastMessage; 
00295 
00296   
00297 
00298   int iexp;  
00299   
00300   
00301 
00302   int iagflg; 
00303   int iahflg; 
00304 
00305   int fCheckGradient; 
00306 
00307   int fCheckHessian; 
00308 
00309   int fPrintResults; 
00310 
00311   int fPrintIterationResults; 
00312 
00313   
00314 
00315   V typsiz; 
00316 
00317   double fscale; 
00318 
00319   int ndigit; 
00320 
00321   int itnlim; 
00322 
00323   double mdlt; 
00324 
00325   double gradtl; 
00326 
00327   double steptl; 
00328   
00329   double stepmx; 
00330 
00331   
00332 
00333   void dfault();
00334 
00335   int optchk(V &x, V &sx, int &msg, int &method);
00336 
00337   void fstofd(V &xpls, double fpls, V &g, V &sx, double rnoise);
00338 
00339   void fstofd(V &xpls, V &fpls, M &a, V &sx, double rnoise, V &fhat);
00340 
00341   int grdchk(V &x, double f, V &g, V &typsiz, V &sx, double fscale, double rnf, double analtl,
00342       V &gest, int &msg);
00343 
00344   void optstp(V &xpls, double fpls, V &gpls, V &x, int &itncnt, int &icscmx, int &itrmcd, V &sx,
00345       double &fscale, int &itnlim, int &iretcd, bool &mxtake, int &msg);
00346 
00347   void hsnint(M &a, V &sx, int method);
00348 
00349   void sndofd(V &xpls, double &fpls, M &a, V &sx, double &rnoise, V &stepsz, V &anbr);
00350 
00351   int heschk(V &x, double &f, V &g, M &a, V &typsiz, V &sx, double rnf, double analtl, int &iagflg,
00352       V &udiag, V &wrk1, V &wrk2, int &msg);
00353 
00354   void result(V &x, double &f, V &g, M &a, V &p, int &itncnt, int iflg);
00355 
00356   void bakslv(M &a, V &x, V &b);
00357 
00358   void chlhsn(M &a, V &sx, V &udiag);
00359 
00360   void choldc(M &a, double diagmx, double tol, double &addmax);
00361 
00362   void dogdrv(V &x, double &f, V &g, M &a, V &p, V &xpls, double &fpls, V &sx, double &dlt,
00363       int &iretcd, bool &mxtake, V &sc, V &wrk1, V &wrk2, V &wrk3);
00364 
00365   void dogstp(V &g, M &a, V &p, V &sx, double rnwtln, double &dlt, bool &nwtake, bool &fstdog,
00366       V &ssd, V &v, double &cln, double &eta, V &sc);
00367 
00368   void forslv(M &a, V &x, V &b);
00369 
00370   void fstocd(V &x, V &sx, double rnoise, V &g);
00371 
00372   void hookdr(V &x, double &f, V &g, M &a, V &udiag, V &p, V &xpls, double &fpls, V &sx,
00373       double &dlt, int &iretcd, bool &mxtake, double &amu, double &dltp, double &phi,
00374       double &phip0, V &sc, V &xplsp, V &wrk0, int &itncnt);
00375 
00376   void hookst(V &g, M &a, V &udiag, V &p, V &sx, double rnwtln, double &dlt, double &amu,
00377       double &dltp, double &phi, double &phip0, bool &fstime, V &sc, bool &nwtake, V &wrk0);
00378 
00379   void lltslv(M &a, V &x, V &b);
00380 
00381   void lnsrch(V &x, double &f, V &g, V &p, V &xpls, double &fpls, bool &mxtake, int &iretcd, V &sx);
00382 
00383   void mvmltl(M &a, V &x, V &y);
00384 
00385   void mvmlts(M &a, V &x, V &y);
00386 
00387   void mvmltu(M &a, V &x, V &y);
00388 
00389   void qraux1(M &r, int i);
00390 
00391   void qraux2(M &r, int i, double a, double b);
00392 
00393   void qrupdt(M &a, V &u, V &v);
00394 
00395   void secfac(V &x, V &g, M &a, V &xpls, V &gpls, int &itncnt, double rnf, int &iagflg,
00396       bool &noupdt, V &s, V &y, V &u, V &w);
00397 
00398   void secunf(V &x, V &g, M &a, V &udiag, V &xpls, V &gpls, int &itncnt, double rnf, int &iagflg,
00399       bool &noupdt, V &s, V &y, V &t);
00400 
00401   void tregup(V &x, double &f, V &g, M &a, V &sc, V &sx, bool &nwtake, double &dlt, int &iretcd,
00402       V &xplsp, double &fplsp, V &xpls, double &fpls, bool &mxtake, int method, V &udiag);
00403 
00404   double ddot(V &x, V &y);
00405 
00406   double dnrm2(V &x);
00407 
00408   double max(double a, double b);
00409 
00410   double min(double a, double b);
00411 
00412 };
00413 
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421 
00422 
00423 
00424 
00425 
00426 
00427 
00428 
00429 
00430 
00431 
00432 
00433 
00434 
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 
00443 
00444 
00445 
00446 
00447 
00448 
00449 template<class V, class M, class FUNC> Uncmin<V, M, FUNC>::Uncmin(FUNC *f) :
00450   minclass(f)
00451 {
00452   if (minclass)
00453     n = minclass->dim();
00454   else
00455     n = 0;
00456 
00457   mfile = 0;
00458 
00459   mLastGradCrit = 0.0;
00460   mLastStepCrit = 0.0;
00461   mLastIteration = 0;
00462   mLastMessage = 0;
00463 
00464   
00465   dfault();
00466 }
00467 
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480 
00481 
00482 
00483 
00484 
00485 template<class V, class M, class FUNC> Uncmin<V, M, FUNC>::Uncmin(int d) :
00486   minclass(0), typsiz(d)
00487 {
00488 
00489   n = d;
00490 
00491   mfile = 0;
00492 
00493   mLastGradCrit = 0.0;
00494   mLastStepCrit = 0.0;
00495   mLastIteration = 0;
00496   mLastMessage = 0;
00497 
00498   
00499   dfault();
00500 
00501 }
00502 
00503 
00504 
00505 
00506 template<class V, class M, class FUNC> Uncmin<V, M, FUNC>::~Uncmin()
00507 {
00508 
00509 }
00510 
00511 
00512 
00513 
00514 
00515 
00516 
00517 
00518 
00519 
00520 
00521 
00522 
00523 
00524 
00525 
00526 
00527 
00528 
00529 
00530 
00531 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::SetFuncExpensive(int iexp)
00532 {
00533   this->iexp = iexp;
00534 }
00535 
00536 
00537 
00538 
00539 
00540 
00541 
00542 
00543 
00544 
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 
00554 template<class V, class M, class FUNC> int Uncmin<V, M, FUNC>::SetScaleArg(V typsiz)
00555 {
00556   if (typsiz.size() != n)
00557     return 1;
00558 
00559   this->typsiz = typsiz;
00560 
00561   return 0;
00562 }
00563 
00564 
00565 
00566 
00567 
00568 
00569 
00570 
00571 
00572 
00573 
00574 
00575 
00576 
00577 
00578 
00579 
00580 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::SetScaleFunc(double fscale)
00581 {
00582   this->fscale = fscale;
00583 }
00584 
00585 
00586 
00587 
00588 
00589 
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598 
00599 
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::SetNumDigits(double ndigit)
00608 {
00609   this->ndigit = ndigit;
00610 }
00611 
00612 
00613 
00614 
00615 
00616 
00617 
00618 
00619 
00620 
00621 
00622 
00623 
00624 
00625 
00626 
00627 
00628 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::SetMaxIter(int maxiter)
00629 {
00630   this->itnlim = maxiter;
00631 }
00632 
00633 
00634 
00635 
00636 
00637 
00638 
00639 
00640 
00641 
00642 
00643 
00644 
00645 
00646 
00647 
00648 
00649 
00650 
00651 
00652 
00653 
00654 
00655 
00656 
00657 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::SetTolerances(double step,
00658     double grad, double macheps)
00659 {
00660   if (macheps <= 0.0) 
00661   {
00662 
00663 #ifdef BOOST_NO_LIMITS
00664     epsm = DBL_EPSILON; 
00665 #else
00666     
00667     epsm = std::numeric_limits<double>::epsilon();
00668 #endif
00669 
00670   }
00671   else
00672   {
00673     epsm = macheps;
00674   }
00675 
00676   if (grad <= 0.0)
00677   {
00678     gradtl = std::pow(epsm, 1.0/3.0); 
00679   }
00680   else
00681   {
00682     gradtl = grad;
00683   }
00684 
00685   if (step <= 0.0)
00686   {
00687     steptl = std::sqrt(epsm); 
00688   }
00689   else
00690   {
00691     steptl = step;
00692   }
00693 
00694 }
00695 
00696 
00697 
00698 
00699 
00700 
00701 
00702 
00703 
00704 
00705 
00706 
00707 
00708 
00709 
00710 
00711 
00712 
00713 
00714 
00715 
00716 
00717 
00718 
00719 
00720 
00721 
00722 
00723 
00724 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::SetMaxStep(double stepmx)
00725 {
00726   this->stepmx = stepmx;
00727 }
00728 
00729 
00730 
00731 
00732 
00733 
00734 
00735 
00736 
00737 
00738 
00739 
00740 
00741 
00742 
00743 
00744 
00745 
00746 
00747 
00748 
00749 
00750 
00751 
00752 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::SetTrustRegionRadius(double dlt)
00753 {
00754   this->mdlt = dlt;
00755 }
00756 
00757 
00758 
00759 
00760 
00761 
00762 
00763 
00764 
00765 
00766 
00767 template<class V, class M, class FUNC> FUNC * Uncmin<V, M, FUNC>::GetFunction()
00768 {
00769   return minclass;
00770 }
00771 
00772 
00773 
00774 
00775 
00776 
00777 
00778 
00779 
00780 
00781 
00782 
00783 
00784 
00785 
00786 
00787 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::SetFunction(FUNC *f)
00788 {
00789   minclass = f;
00790 
00791   
00792   if (n != f->dim())
00793   {
00794     n = f->dim();
00795     V defaultTypSiz(n, 1.0);
00796     typsiz = defaultTypSiz;
00797   }
00798 }
00799 
00800 
00801 
00802 
00803 
00804 
00805 
00806 
00807 
00808 
00809 
00810 
00811 
00812 
00813 
00814 
00815 
00816 
00817 
00818 
00819 
00820 
00821 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::SetChecks(int check_gradient,
00822     int check_hessian)
00823 {
00824   fCheckGradient = check_gradient;
00825   fCheckHessian = check_hessian;
00826 }
00827 
00828 
00829 
00830 
00831 
00832 
00833 
00834 
00835 
00836 
00837 
00838 
00839 
00840 
00841 
00842 
00843 
00844 
00845 
00846 
00847 
00848 
00849 
00850 
00851 
00852 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::SetPrint(std::FILE *file,
00853     int print_results, int print_iterations)
00854 {
00855 
00856   mfile = file;
00857 
00858   if (!file)
00859   {
00860     fPrintResults = 0;
00861     fPrintIterationResults = 0;
00862   }
00863   else
00864   {
00865     fPrintResults = print_results;
00866     fPrintIterationResults = print_iterations;
00867   }
00868 
00869 }
00870 
00871 
00872 
00873 
00874 
00875 
00876 
00877 
00878 
00879 
00880 
00881 
00882 
00883 
00884 
00885 
00886 
00887 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::SetMethod(int method)
00888 {
00889   if (method == 2 || method == 3)
00890     algorithm = method;
00891   else
00892     algorithm = 1; 
00893 }
00894 
00895 
00896 
00897 
00898 
00899 
00900 
00901 
00902 
00903 
00904 
00905 
00906 
00907 
00908 
00909 
00910 
00911 
00912 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::GetStoppingCriteria(
00913     double &gradtol, double &steptol, int &iterations)
00914 {
00915   gradtol = mLastGradCrit;
00916   steptol = mLastStepCrit;
00917   iterations = mLastIteration;
00918 }
00919 
00920 
00921 
00922 
00923 
00924 
00925 
00926 
00927 
00928 
00929 
00930 
00931 
00932 
00933 
00934 
00935 
00936 
00937 
00938 
00939 
00940 
00941 
00942 
00943 
00944 
00945 
00946 
00947 
00948 
00949 template<class V, class M, class FUNC> inline int Uncmin<V, M, FUNC>::GetMessage()
00950 {
00951   return mLastMessage;
00952 }
00953 
00954 
00955 
00956 
00957 
00958 
00959 
00960 
00961 
00962 
00963 
00964 
00965 
00966 
00967 
00968 
00969 
00970 
00971 
00972 
00973 
00974 
00975 
00976 
00977 
00978 
00979 
00980 
00981 
00982 
00983 
00984 
00985 
00986 
00987 
00988 
00989 
00990 
00991 
00992 
00993 
00994 
00995 
00996 
00997 
00998 
00999 
01000 
01001 template<class V, class M, class FUNC> int Uncmin<V, M, FUNC>::Minimize(V &start, V &xpls,
01002     double &fpls, V &gpls, M &hpls)
01003 {
01004 
01005   bool noupdt;
01006   bool mxtake;
01007 
01008   int i, j, num5, remain, ilow, ihigh;
01009   int icscmx;
01010   int iretcd;
01011   int itncnt;
01012 
01013   
01014 
01015 
01016 
01017 
01018 
01019 
01020 
01021 
01022   int itrmcd;
01023 
01024   double rnf, analtl, dltsav, amusav, dlpsav, phisav, phpsav;
01025 
01026   double f;
01027 
01028   double amu = 0.0;
01029   double dltp = 0.0;
01030   double phi = 0.0;
01031   double phip0 = 0.0;
01032 
01033   int method = algorithm;
01034 
01035   mLastGradCrit = 0.0;
01036   mLastStepCrit = 0.0;
01037   mLastIteration = 0;
01038   mLastMessage = -9999;
01039 
01040   iagflg = minclass->HasAnalyticGradient();
01041   iahflg = minclass->HasAnalyticHessian();
01042 
01043   
01044 
01045 
01046 
01047 
01048 
01049 
01050 
01051 
01052 
01053 
01054   int msg = (fCheckGradient == 0) * 1 + (fCheckHessian == 0) * 2 + (fPrintResults == 0) * 4
01055       + (fPrintIterationResults != 0) * 8;
01056 
01057   
01058   if (start.size() != n || xpls.size() != n || gpls.size() != n || hpls.num_rows() != n
01059       || hpls.num_columns() != n) 
01060   {
01061     mLastMessage = -3;
01062     return -1;
01063   }
01064 
01065   
01066   if (!(minclass->ValidParameters(start)))
01067   {
01068     mLastMessage = -20;
01069     return -1;
01070   }
01071 
01072   
01073   M &a = hpls;
01074   V udiag(n); 
01075   V g(n); 
01076   V p(n); 
01077   V sx(n); 
01078   V wrk0(n), wrk1(n), wrk2(n), wrk3(n);
01079 
01080   V x(start);
01081 
01082   double dlt = mdlt;
01083 
01084   dltsav = amusav = dlpsav = phisav = phpsav = 0.0;
01085 
01086   
01087 
01088   for (i = 1; i <= n; i++)
01089   {
01090     p(i) = 0.0;
01091   }
01092 
01093   itncnt = 0;
01094   iretcd = -1;
01095 
01096   
01097   if (optchk(x, sx, msg, method))
01098   {
01099     mLastMessage = msg;
01100     return -1;
01101   }
01102 
01103   rnf = max(std::pow(10.0, -ndigit), epsm);
01104   analtl = max(.01, std::sqrt(rnf));
01105 
01106   if (!(msg & 4))
01107   {
01108     num5 = n/5;
01109     remain = n%5;
01110 
01111     std::fprintf(mfile, "\n\nOPTDRV          Typical x\n\n");
01112 
01113     ilow = -4;
01114     ihigh = 0;
01115 
01116     for (i = 1; i <= num5; i++)
01117     {
01118       ilow += 5;
01119       ihigh += 5;
01120 
01121       std::fprintf(mfile, "%d--%d     ", ilow, ihigh);
01122 
01123       for (j = 1; j <= 5; j++)
01124       {
01125         std::fprintf(mfile, "%lf  ", (double) typsiz(ilow+j-1));
01126       }
01127       std::fprintf(mfile, "\n");
01128     }
01129 
01130     ilow += 5;
01131     ihigh = ilow + remain - 1;
01132 
01133     std::fprintf(mfile, "%d--%d     ", ilow, ihigh);
01134 
01135     for (j = 1; j <= remain; j++)
01136     {
01137       std::fprintf(mfile, "%lf  ", (double) typsiz(ilow+j-1));
01138     }
01139 
01140     std::fprintf(mfile, "\n");
01141 
01142     std::fprintf(mfile, "\n\nOPTDRV      Scaling vector for x\n\n");
01143 
01144     ilow = -4;
01145     ihigh = 0;
01146 
01147     for (i = 1; i <= num5; i++)
01148     {
01149       ilow += 5;
01150       ihigh += 5;
01151 
01152       std::fprintf(mfile, "%d--%d     ", ilow, ihigh);
01153 
01154       for (j = 1; j <= 5; j++)
01155       {
01156         std::fprintf(mfile, "%lf  ", (double) sx(ilow+j-1));
01157       }
01158       std::fprintf(mfile, "\n");
01159     }
01160 
01161     ilow += 5;
01162     ihigh = ilow + remain - 1;
01163 
01164     std::fprintf(mfile, "%d--%d     ", ilow, ihigh);
01165 
01166     for (j = 1; j <= remain; j++)
01167     {
01168       std::fprintf(mfile, "%lf  ", (double) sx(ilow+j-1));
01169     }
01170 
01171     std::fprintf(mfile, "\n");
01172 
01173     std::fprintf(mfile, "\n\nOPTDRV      Typical f = %f\n", fscale);
01174     std::fprintf(mfile, "OPTDRV      Number of good digits in");
01175     std::fprintf(mfile, " f_to_minimize = %d\n", ndigit);
01176     std::fprintf(mfile, "OPTDRV      Gradient flag");
01177     std::fprintf(mfile, " = %d\n", iagflg);
01178     std::fprintf(mfile, "OPTDRV      Hessian flag");
01179     std::fprintf(mfile, " = %d\n", iahflg);
01180     std::fprintf(mfile, "OPTDRV      Expensive function calculation flag");
01181     std::fprintf(mfile, " = %d\n", iexp);
01182     std::fprintf(mfile, "OPTDRV      Method to use");
01183     std::fprintf(mfile, " = %d\n", method);
01184     std::fprintf(mfile, "OPTDRV      Iteration limit");
01185     std::fprintf(mfile, " = %d\n", itnlim);
01186     std::fprintf(mfile, "OPTDRV      Machine epsilon");
01187     std::fprintf(mfile, " = %e\n", epsm);
01188     std::fprintf(mfile, "OPTDRV      Maximum step size");
01189     std::fprintf(mfile, " = %f\n", stepmx);
01190     std::fprintf(mfile, "OPTDRV      Step tolerance");
01191     std::fprintf(mfile, " = %e\n", steptl);
01192     std::fprintf(mfile, "OPTDRV      Gradient tolerance");
01193     std::fprintf(mfile, " = %e\n", gradtl);
01194     std::fprintf(mfile, "OPTDRV      Trust region radius");
01195     std::fprintf(mfile, " = %f\n", dlt);
01196     std::fprintf(mfile, "OPTDRV      Relative noise in");
01197     std::fprintf(mfile, " f_to_minimize = %e\n", rnf);
01198     std::fprintf(mfile, "OPTDRV      Analytical fd tolerance");
01199     std::fprintf(mfile, " = %e\n", analtl);
01200   }
01201 
01202   
01203   f = minclass->f_to_minimize(x);
01204 
01205   
01206   
01207   if (iagflg == 0)
01208   {
01209     fstofd(x, f, g, sx, rnf);
01210   }
01211   else
01212   {
01213     minclass->gradient(x, g);
01214 
01215     if (!(msg & 1))
01216     {
01217       if (grdchk(x, f, g, typsiz, sx, fscale, rnf, analtl, wrk1, msg))
01218       {
01219         mLastMessage = msg;
01220         return -1; 
01221       }
01222     }
01223   }
01224 
01225   optstp(x, f, g, wrk1, itncnt, icscmx, itrmcd, sx, fscale, itnlim, iretcd, mxtake, msg);
01226 
01227   if (itrmcd != 0)
01228   {
01229     fpls = f;
01230 
01231     for (i = 1; i <= n; i++)
01232     {
01233       xpls(i) = x(i);
01234       gpls(i) = g(i);
01235     }
01236   }
01237   else
01238   {
01239     if (iexp == 1)
01240     {
01241       
01242       
01243 
01244       hsnint(a, sx, method);
01245     }
01246     else
01247     {
01248       
01249       
01250       
01251 
01252       if (iahflg == 0)
01253       {
01254         if (iagflg == 1)
01255         {
01256           fstofd(x, g, a, sx, rnf, wrk1);
01257         }
01258         else
01259         {
01260           sndofd(x, f, a, sx, rnf, wrk1, wrk2);
01261         }
01262       }
01263       else
01264       {
01265         if (msg & 2)
01266         {
01267           minclass->hessian(x, a);
01268         }
01269         else
01270         {
01271           if (heschk(x, f, g, a, typsiz, sx, rnf, analtl, iagflg, udiag, wrk1, wrk2, msg))
01272           {
01273             mLastMessage = msg;
01274             return -1; 
01275           }
01276           
01277           
01278           
01279         }
01280       }
01281     }
01282 
01283     if (!(msg & 4))
01284       result(x, f, g, a, p, itncnt, 1);
01285 
01286     
01287     while (itrmcd == 0)
01288     {
01289       itncnt++;
01290       mLastIteration = itncnt; 
01291 
01292       
01293       
01294       
01295       
01296       if (iexp != 1 || method == 3)
01297       {
01298         chlhsn(a, sx, udiag);
01299       }
01300 
01301       
01302       for (i = 1; i <= n; i++)
01303       {
01304         wrk1(i) = -g(i);
01305       }
01306 
01307       lltslv(a, p, wrk1);
01308 
01309       
01310       
01311       if (iagflg == 0 && method != 1)
01312       {
01313         dltsav = dlt;
01314 
01315         if (method != 2)
01316         {
01317           amusav = amu;
01318           dlpsav = dltp;
01319           phisav = phi;
01320           phpsav = phip0;
01321         }
01322       }
01323 
01324       if (method == 1)
01325       {
01326         lnsrch(x, f, g, p, xpls, fpls, mxtake, iretcd, sx);
01327         if (iretcd == -7) 
01328         {
01329           mLastMessage = iretcd;
01330           return -1;
01331         }
01332       }
01333       else if (method == 2)
01334       {
01335         dogdrv(x, f, g, a, p, xpls, fpls, sx, dlt, iretcd, mxtake, wrk0, wrk1, wrk2, wrk3);
01336       }
01337       else
01338       {
01339         hookdr(x, f, g, a, udiag, p, xpls, fpls, sx, dlt, iretcd, mxtake, amu, dltp, phi, phip0,
01340             wrk0, wrk1, wrk2, itncnt);
01341       }
01342 
01343       
01344       
01345       if (iretcd == 1 && iagflg == 0)
01346       {
01347         
01348         iagflg = -1;
01349 
01350         if (!(msg & 4))
01351         {
01352           std::fprintf(mfile, "\nOPTDRV      Shift from forward to central");
01353           std::fprintf(mfile, " differences");
01354           std::fprintf(mfile, "\nOPTDRV      in iteration %d", itncnt);
01355           std::fprintf(mfile, "\n");
01356         }
01357 
01358         fstocd(x, sx, rnf, g);
01359 
01360         if (method == 1)
01361         {
01362           
01363           for (i = 1; i <= n; i++)
01364           {
01365             wrk1(i) = -g(i);
01366           }
01367 
01368           lltslv(a, p, wrk1);
01369 
01370           lnsrch(x, f, g, p, xpls, fpls, mxtake, iretcd, sx);
01371           if (iretcd == -7) 
01372           {
01373             mLastMessage = iretcd;
01374             return -1;
01375           }
01376         }
01377         else
01378         {
01379           dlt = dltsav;
01380           if (method == 2)
01381           {
01382             
01383             for (i = 1; i <= n; i++)
01384             {
01385               wrk1(i) = -g(i);
01386             }
01387 
01388             lltslv(a, p, wrk1);
01389 
01390             dogdrv(x, f, g, a, p, xpls, fpls, sx, dlt, iretcd, mxtake, wrk0, wrk1, wrk2, wrk3);
01391           }
01392           else
01393           {
01394             amu = amusav;
01395             dltp = dlpsav;
01396             phi = phisav;
01397             phip0 = phpsav;
01398 
01399             chlhsn(a, sx, udiag);
01400 
01401             
01402             for (i = 1; i <= n; i++)
01403             {
01404               wrk1(i) = -g(i);
01405             }
01406 
01407             lltslv(a, p, wrk1);
01408 
01409             hookdr(x, f, g, a, udiag, p, xpls, fpls, sx, dlt, iretcd, mxtake, amu, dltp, phi,
01410                 phip0, wrk0, wrk1, wrk2, itncnt);
01411           }
01412         }
01413       }
01414       
01415       for (i = 1; i <= n; i++)
01416       {
01417         p(i) = xpls(i) - x(i);
01418       }
01419 
01420       
01421       if (iagflg == -1)
01422       {
01423         
01424         fstocd(xpls, sx, rnf, gpls);
01425       }
01426       else if (iagflg == 0)
01427       {
01428         
01429         fstofd(xpls, fpls, gpls, sx, rnf);
01430       }
01431       else
01432       {
01433         
01434         minclass->gradient(xpls, gpls);
01435       }
01436 
01437       
01438       optstp(xpls, fpls, gpls, x, itncnt, icscmx, itrmcd, sx, fscale, itnlim, iretcd, mxtake, msg);
01439 
01440       if (itrmcd == 0)
01441       {
01442         
01443         if (iexp != 0)
01444         {
01445           if (method == 3)
01446           {
01447             secunf(x, g, a, udiag, xpls, gpls, itncnt, rnf, iagflg, noupdt, wrk1, wrk2, wrk3);
01448           }
01449           else
01450           {
01451             secfac(x, g, a, xpls, gpls, itncnt, rnf, iagflg, noupdt, wrk0, wrk1, wrk2, wrk3);
01452           }
01453         }
01454         else
01455         {
01456           if (iahflg == 1)
01457           {
01458             minclass->hessian(xpls, a);
01459           }
01460           else
01461           {
01462             if (iagflg == 1)
01463             {
01464               fstofd(xpls, gpls, a, sx, rnf, wrk1);
01465             }
01466             else
01467             {
01468               sndofd(xpls, fpls, a, sx, rnf, wrk1, wrk2);
01469             }
01470           }
01471         }
01472 
01473         if (msg & 8)
01474         {
01475           result(xpls, fpls, gpls, a, p, itncnt, 1);
01476         }
01477 
01478         
01479         f = fpls;
01480 
01481         for (i = 1; i <= n; i++)
01482         {
01483           x(i) = xpls(i);
01484           g(i) = gpls(i);
01485         }
01486       }
01487     }
01488 
01489     
01490     
01491     
01492     
01493     if (itrmcd == 3)
01494     {
01495       fpls = f;
01496 
01497       for (i = 1; i <= n; i++)
01498       {
01499         xpls(i) = x(i);
01500         gpls(i) = g(i);
01501       }
01502     }
01503   }
01504 
01505   
01506   if (!(msg & 4))
01507   {
01508     result(xpls, fpls, gpls, a, p, itncnt, 0);
01509   }
01510   mLastMessage = itrmcd;
01511   return (itrmcd >= 0 && itrmcd <= 3) ? 0 : 1;
01512 }
01513 
01514 
01515 
01516 
01517 
01518 
01519 
01520 
01521 
01522 
01523 
01524 
01525 
01526 
01527 
01528 
01529 
01530 
01531 
01532 
01533 template<class V, class M, class FUNC> int Uncmin<V, M, FUNC>::Minimize(V &start, V &xpls,
01534     double &fpls, V &gpls)
01535 {
01536 
01537   M *a = new M(n,n);
01538 
01539   int result = Minimize(start, xpls, fpls, gpls, *a);
01540 
01541   delete a;
01542 
01543   return result;
01544 }
01545 
01546 
01547 
01548 
01549 
01550 
01551 
01552 
01553 
01554 
01555 
01556 
01557 
01558 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::dfault()
01559 {
01560   
01561   algorithm = 1;
01562 
01563   
01564   typsiz.newsize(n);
01565   typsiz = 1.0;
01566 
01567   fscale = 1.0;
01568 
01569   
01570   mdlt = -1.0;
01571 
01572   SetTolerances(-1.0, -1.0, -1.0);
01573 
01574   stepmx = 0.0;
01575 
01576   
01577   iexp = 0;
01578   ndigit = -1;
01579   itnlim = 150;
01580   iagflg = 0;
01581   iahflg = 0;
01582 
01583   fCheckGradient = 0;
01584   fCheckHessian = 0;
01585   fPrintResults = 0;
01586   fPrintIterationResults = 0;
01587 }
01588 
01589 
01590 
01591 
01592 
01593 
01594 
01595 
01596 
01597 
01598 
01599 
01600 
01601 
01602 
01603 
01604 
01605 
01606 
01607 
01608 
01609 
01610 
01611 
01612 template<class V, class M, class FUNC> int Uncmin<V, M, FUNC>::optchk(V &x, V &sx, int &msg,
01613     int &method)
01614 {
01615   int i;
01616   double stpsiz;
01617 
01618   
01619   
01620   bool printMessages = !(msg & 4);
01621 
01622   if (method< 1 || method> 3)method = 1;
01623   if (iagflg != 1 && iagflg != 0) iagflg = 1;
01624   if (iahflg != 1 && iahflg != 0) iahflg = 1;
01625   if (iexp != 0 && iexp != 1) iexp = 1;
01626 
01627   if (!(msg & 1) && iagflg == 0)
01628   {
01629     if (printMessages)
01630     {
01631       std::fprintf(mfile, "\n\nOPTCHK   User requests that analytic gradient");
01632       std::fprintf(mfile, " be accepted as properly coded,\n");
01633       std::fprintf(mfile, "OPTCHK   but an analytic gradient is not");
01634       std::fprintf(mfile, " supplied,\n");
01635       std::fprintf(mfile, "OPTCHK   msg = %d,\n", msg);
01636       std::fprintf(mfile, "OPTCHK   iagflg = %d.\n\n", iagflg);
01637     }
01638     msg = -1;
01639     return 1;
01640   }
01641 
01642   if (!(msg & 2) && iahflg == 0)
01643   {
01644     if (printMessages)
01645     {
01646       std::fprintf(mfile, "\n\nOPTCHK   User requests that analytic Hessian");
01647       std::fprintf(mfile, " be accepted as properly coded,\n");
01648       std::fprintf(mfile, "OPTCHK   but an analytic Hessian is not");
01649       std::fprintf(mfile, " supplied,\n");
01650       std::fprintf(mfile, "OPTCHK   msg = %d,\n", msg);
01651       std::fprintf(mfile, "OPTCHK   iahflg = %d.\n\n", iahflg);
01652     }
01653     msg = -2;
01654     return 1;
01655   }
01656 
01657   
01658 
01659   if (n <= 0)
01660   {
01661     if (printMessages) std::fprintf(mfile, "\n\nOPTCHK   Illegal dimension, n = %d\n\n", n);
01662 
01663     msg = -3;
01664     return 1;
01665   }
01666 
01667   if (n == 1 && printMessages)
01668   {
01669     std::fprintf(mfile, "\n\nOPTCHK   !!!WARNING!!!  This class is ");
01670     std::fprintf(mfile, "inefficient for problems of size 1.\n");
01671     std::fprintf(mfile, "OPTCHK   You might want to use a more appropriate routine.\n\n");
01672   }
01673 
01674   
01675   for (i = 1; i <= n; i++)
01676   {
01677     if (typsiz(i) == 0) typsiz(i) = 1.0;
01678     if (typsiz(i) < 0.0) typsiz(i) = -typsiz(i);
01679     sx(i) = 1.0/typsiz(i);
01680   }
01681 
01682   
01683   if (stepmx <= 0.0)
01684   {
01685     stpsiz = 0.0;
01686 
01687     for (i = 1; i <= n; i++)
01688     {
01689       stpsiz += x(i)*x(i)*sx(i)*sx(i);
01690     }
01691 
01692     stpsiz = std::sqrt(stpsiz);
01693 
01694     stepmx = max(1000.0*stpsiz,1000.0);
01695   }
01696 
01697   
01698   if (fscale == 0) fscale = 1.0;
01699   if (fscale < 0.0) fscale = -fscale;
01700 
01701   
01702   if (gradtl < 0.0)
01703   {
01704     if (printMessages) std::fprintf(mfile, "\n\nOPTCHK   Illegal tolerance, gradtl = %lf\n\n", gradtl);
01705 
01706     msg = -4;
01707     return 1;
01708   }
01709 
01710   
01711   if (itnlim < 0)
01712   {
01713     if (printMessages)
01714     {
01715       std::fprintf(mfile, "\n\nOPTCHK   Illegal iteration limit,");
01716       std::fprintf(mfile, " itnlim = %d\n\n", itnlim);
01717     }
01718     msg = -5;
01719     return 1;
01720   }
01721 
01722   
01723   if (ndigit == 0)
01724   {
01725     if (printMessages)
01726     {
01727       std::fprintf(mfile, "\n\nOPTCHK   Minimization function has no good");
01728       std::fprintf(mfile, " digits, ndigit = %d\n\n", ndigit);
01729     }
01730 
01731     msg = -6;
01732     return 1;
01733   }
01734 
01735   if (ndigit < 0) ndigit = (int)(-std::log(epsm)/std::log(10.0));
01736 
01737   
01738   if (mdlt <= 0.0) mdlt = -1.0;
01739   if (mdlt > stepmx) mdlt = stepmx;
01740 
01741   return 0;
01742 }
01743 
01744 
01745 
01746 
01747 
01748 
01749 
01750 
01751 
01752 
01753 
01754 
01755 
01756 
01757 
01758 
01759 
01760 
01761 
01762 
01763                                                   
01764 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::fstofd(V &xpls, double fpls, V &g,
01765     V &sx, double rnoise)                            
01766 {                                                    
01767   double xmult, stepsz, xtmpj, fhat;                 
01768   int j;                                             
01769                                                      
01770   xmult = std::sqrt(rnoise);
01771 
01772   
01773 
01774   for (j = 1; j <= n; j++)
01775   {
01776     stepsz = xmult*max(std::fabs(xpls(j)), 1.0/sx(j));
01777     xtmpj = xpls(j);
01778     xpls(j) = xtmpj + stepsz;
01779 
01780     fhat = minclass->f_to_minimize(xpls);
01781 
01782     xpls(j) = xtmpj;
01783 
01784     g(j) = (fhat - fpls)/stepsz;
01785   }
01786 }
01787 
01788 
01789 
01790 
01791 
01792 
01793 
01794 
01795 
01796 
01797 
01798 
01799 
01800 
01801 
01802 
01803 
01804 
01805 
01806 
01807 
01808 
01809 
01810                                                   
01811 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::fstofd(V &xpls, V &fpls, M &a,
01812     V &sx, double rnoise, V &fhat)
01813 {
01814   double xmult, stepsz, xtmpj;
01815   int i, j, nm1;
01816 
01817   xmult = std::sqrt(rnoise);
01818 
01819   for (j = 1; j <= n; j++)
01820   {
01821     stepsz = xmult * max(std::fabs(xpls(j)), 1.0/sx(j));
01822     xtmpj = xpls(j);
01823     xpls(j) = xtmpj + stepsz;
01824 
01825     minclass->gradient(xpls, fhat);
01826 
01827     xpls(j) = xtmpj;
01828 
01829     for (i = 1; i <= n; i++)
01830     {
01831       a(i, j) = (fhat(i) - fpls(i))/stepsz;
01832     }
01833   }
01834 
01835   nm1 = n - 1;
01836 
01837   for (j = 1; j <= nm1; j++)
01838   {
01839     for (i = j+1; i <= n; i++)
01840     {
01841       a(i, j) = (a(i,j) + a(j,i))/2.0;
01842     }
01843   }
01844   return;
01845 }
01846 
01847 
01848 
01849 
01850 
01851 
01852 
01853 
01854 
01855 
01856 
01857 
01858 
01859 
01860 
01861 
01862 
01863 
01864 
01865 
01866 
01867 
01868 
01869 
01870 
01871 
01872 
01873 
01874 
01875 
01876                                                   
01877 template<class V, class M, class FUNC> int Uncmin<V, M, FUNC>::grdchk(V &x, double f, V &g,
01878     V &typsiz, V &sx, double fscale, double rnf, double analtl, V &gest, int &msg)
01879 {
01880   double gs;
01881   int ker, i;
01882 
01883   
01884   
01885   fstofd(x, f, gest, sx, rnf);
01886 
01887   ker = 0;
01888 
01889   for (i = 1; i <= n; i++)
01890   {
01891     gs = max(std::fabs(f), fscale)/max(std::fabs(x(i)), typsiz(i));
01892 
01893     if (std::fabs(g(i) - gest(i)) > max(std::fabs(g(i)), gs)*analtl)
01894       ker = 1;
01895   }
01896 
01897   if (ker == 0)
01898     return 0;
01899 
01900   if (!(msg & 4))
01901   {
01902     std::fprintf(mfile, "\nThere appears to be an error in the coding");
01903     std::fprintf(mfile, " of the gradient method.\n\n\n");
01904     std::fprintf(mfile, "Component   Analytic   Finite Difference\n\n");
01905 
01906     for (i = 1; i <= n; i++)
01907     {
01908       std::fprintf(mfile, "%d  %lf  %lf\n", i, (double) g(i), (double) gest(i));
01909     }
01910   }
01911   msg = -21;
01912   return 1;
01913 }
01914 
01915 
01916 
01917 
01918 
01919 
01920 
01921 
01922 
01923 
01924 
01925 
01926 
01927 
01928 
01929 
01930 
01931 
01932 
01933 
01934 
01935 
01936 
01937 
01938 
01939 
01940 
01941 
01942 
01943 
01944 
01945 
01946 
01947 
01948 
01949 
01950 
01951 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::optstp(V &xpls, double fpls,
01952     V &gpls, V &x, int &itncnt, int &icscmx, int &itrmcd, V &sx, double &fscale, int &itnlim,
01953     int &iretcd, bool &mxtake, int &msg)
01954 {
01955   int i;
01956   double d, rgx, relgrd, rsx = 0.0, relstp; 
01957 
01958   itrmcd = 0;
01959 
01960   
01961   if (iretcd == 1)
01962   {
01963     itrmcd = 3;
01964 
01965     if (!(msg & 4))
01966     {
01967       std::fprintf(mfile, "\n\nOPTSTP    The last global step failed");
01968       std::fprintf(mfile, " to locate a point lower than x.\n");
01969       std::fprintf(mfile, "OPTSTP    Either x is an approximate local");
01970       std::fprintf(mfile, " minimum of the function,\n");
01971       std::fprintf(mfile, "OPTSTP    the function is too nonlinear for");
01972       std::fprintf(mfile, " this algorithm, or\n");
01973       std::fprintf(mfile, "OPTSTP    steptl is too large.\n");
01974     }
01975     return;
01976   }
01977   else
01978   {
01979     
01980     d = max(std::fabs(fpls), fscale);
01981     rgx = 0.0;
01982 
01983     for (i = 1; i <= n; i++)
01984     {
01985       relgrd = std::fabs(gpls(i))*max(std::fabs(xpls(i)), 1.0/sx(i))/d;
01986       rgx = max(rgx, relgrd);
01987     }
01988     mLastGradCrit = rgx; 
01989 
01990     
01991     
01992     if (itncnt > 0)
01993     {
01994       rsx = 0.0;
01995 
01996       for (i = 1; i <= n; i++)
01997       {
01998         relstp = std::fabs(xpls(i) - x(i))/ max(std::fabs(xpls(i)), 1.0/sx(i));
01999 
02000         rsx = max(rsx, relstp);
02001       }
02002       mLastStepCrit = rsx;
02003     }
02004     
02005     if (rgx <= gradtl)
02006     {
02007       itrmcd = 1;
02008 
02009       if (!(msg & 4))
02010       {
02011         std::fprintf(mfile, "\n\nOPTSTP    The relative gradient is close");
02012         std::fprintf(mfile, " to zero.\n");
02013         std::fprintf(mfile, "OPTSTP    The current iterate is probably");
02014         std::fprintf(mfile, " a solution.\n");
02015       }
02016       return;
02017     }
02018     if (itncnt == 0)
02019       return;
02020 
02021     
02022     if (rsx <= steptl)
02023     {
02024       itrmcd = 2;
02025 
02026       if (!(msg & 4))
02027       {
02028         std::fprintf(mfile, "\n\nOPTSTP    Successive iterates are within");
02029         std::fprintf(mfile, " steptl.\n");
02030         std::fprintf(mfile, "OPTSTP    The current iterate is probably");
02031         std::fprintf(mfile, " a solution.\n");
02032       }
02033       return;
02034     }
02035 
02036     
02037     if (itncnt >= itnlim)
02038     {
02039       itrmcd = 4;
02040 
02041       if (!(msg & 4))
02042       {
02043         std::fprintf(mfile, "\n\nOPTSTP    The iteration limit was reached.\n");
02044         std::fprintf(mfile, "OPTSTP    The algorithm failed.\n");
02045       }
02046 
02047       return;
02048     }
02049 
02050     
02051     if (!mxtake)
02052     {
02053       icscmx = 0;
02054 
02055       return;
02056     }
02057 
02058     if (!(msg & 4))
02059     {
02060       std::fprintf(mfile, "\n\nOPTSTP    Step of maximum length (stepmx)");
02061       std::fprintf(mfile, " taken.\n");
02062     }
02063 
02064     icscmx++;
02065 
02066     if (icscmx < 5)
02067       return;
02068 
02069     itrmcd = 5;
02070 
02071     if (!(msg & 4))
02072     {
02073       std::fprintf(mfile, "\n\nOPTSTP    Maximum step size exceeded");
02074       std::fprintf(mfile, " five consecutive times.\n");
02075       std::fprintf(mfile, "OPTSTP    Either the function is unbounded");
02076       std::fprintf(mfile, " below,\n");
02077       std::fprintf(mfile, "OPTSTP    becomes asymptotic to a finite value");
02078       std::fprintf(mfile, " from above in some direction, or\n");
02079       std::fprintf(mfile, "OPTSTP    stepmx is too small.\n");
02080     }
02081   }
02082 }
02083 
02084 
02085 
02086 
02087 
02088 
02089 
02090 
02091 
02092 
02093 
02094 
02095 
02096 
02097 
02098 
02099 
02100 
02101 
02102 
02103 
02104 
02105 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::hsnint(M &a, V &sx, int method)
02106 {
02107   int i, j;
02108 
02109   for (j = 1; j <= n; j++)
02110   {
02111     if (method == 3)
02112     {
02113       a(j, j) = sx(j)*sx(j);
02114     }
02115     else
02116     {
02117       a(j, j) = sx(j);
02118     }
02119 
02120     for (i = j + 1; i <= n; i++)
02121     {
02122       a(i, j) = 0.0;
02123     }
02124   }
02125   return;
02126 }
02127 
02128 
02129 
02130 
02131 
02132 
02133 
02134 
02135 
02136 
02137 
02138 
02139 
02140 
02141 
02142 
02143 
02144 
02145 
02146 
02147 
02148 
02149 
02150 
02151 
02152 
02153 
02154 
02155 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::sndofd(V &xpls, double &fpls, M &a,
02156     V &sx, double &rnoise, V &stepsz, V &anbr)
02157 {
02158   double xmult, xtmpi, xtmpj, fhat;
02159   int i, j;
02160 
02161   
02162   
02163   xmult = std::pow(rnoise, 1.0/3.0);
02164 
02165   for (i = 1; i <= n; i++)
02166   {
02167     stepsz(i) = xmult*max(std::fabs(xpls(i)),1.0/sx(i));
02168     xtmpi = xpls(i);
02169     xpls(i) = xtmpi + stepsz(i);
02170 
02171     anbr(i) = minclass->f_to_minimize(xpls);
02172     xpls(i) = xtmpi;
02173   }
02174 
02175   
02176   for (i = 1; i <= n; i++)
02177   {
02178     xtmpi = xpls(i);
02179     xpls(i) = xtmpi + 2.0*stepsz(i);
02180     fhat = minclass->f_to_minimize(xpls);
02181     a(i, i) = ((fpls - anbr(i)) + (fhat - anbr(i)))/
02182     (stepsz(i)*stepsz(i));
02183 
02184     
02185     if (i != n)
02186     {
02187       xpls(i) = xtmpi + stepsz(i);
02188 
02189       for (j = i+1; j <= n; j++)
02190       {
02191         xtmpj = xpls(j);
02192         xpls(j) = xtmpj + stepsz(j);
02193         fhat = minclass->f_to_minimize(xpls);
02194         a(j, i) = ((fpls - anbr(i)) + (fhat - anbr(j)))/
02195         (stepsz(i)*stepsz(j));
02196         xpls(j) = xtmpj;
02197       }
02198     }
02199     xpls(i) = xtmpi;
02200   }
02201 }
02202 
02203 
02204 
02205 
02206 
02207 
02208 
02209 
02210 
02211 
02212 
02213 
02214 
02215 
02216 
02217 
02218 
02219 
02220 
02221 
02222 
02223 
02224 
02225 
02226 
02227 
02228 
02229 
02230 
02231 
02232 
02233 
02234 
02235 template<class V, class M, class FUNC> int Uncmin<V, M, FUNC>::heschk(V &x, double &f, V &g, M &a,
02236     V &typsiz, V &sx, double rnf, double analtl, int &iagflg, V &udiag, V &wrk1, V &wrk2, int &msg)
02237 {
02238   int i, j, ker;
02239   double hs;
02240 
02241   
02242   if (iagflg == 1)
02243     fstofd(x, g, a, sx, rnf, wrk1);
02244   else
02245     sndofd(x, f, a, sx, rnf, wrk1, wrk2);
02246 
02247   ker = 0;
02248 
02249   
02250   
02251   for (j = 1; j <= n; j++)
02252   {
02253     udiag(j) = a(j,j);
02254 
02255     for (i = j + 1; i <= n; i++)
02256     {
02257       a(j, i) = a(i,j);
02258     }
02259   }
02260 
02261   
02262   
02263   minclass->hessian(x, a);
02264 
02265   for (j = 1; j <= n; j++)
02266   {
02267     hs = max(std::fabs(g(j)), 1.0)/max(std::fabs(x(j)), typsiz(j));
02268 
02269     if (std::fabs(a(j, j) - udiag(j)) > max(std::fabs(udiag(j)), hs)*analtl)
02270       ker = 1;
02271 
02272     for (i = j + 1; i <= n; i++)
02273     {
02274       if (std::fabs(a(i, j) - a(j, i)) > max(std::fabs(a(i, j)), hs)*analtl)
02275         ker = 1;
02276     }
02277   }
02278   if (ker == 0)
02279     return 0;
02280 
02281   if (!(msg & 4))
02282   {
02283     std::fprintf(mfile, "\nThere appears to be an error in the coding");
02284     std::fprintf(mfile, " of the Hessian method.\n\n\n");
02285     std::fprintf(mfile, "Row   Column   Analytic   Finite Difference\n\n");
02286 
02287     for (i = 1; i <= n; i++)
02288     {
02289       for (j = 1; j < i; j++)
02290       {
02291         std::fprintf(mfile, "%d  %d  %lf  %lf\n", i, j, (double) a(i, j), (double) a(j, i));
02292       }
02293       std::fprintf(mfile, "%d  %d  %lf  %lf\n", i, i, (double) a(i, i), (double) udiag(i));
02294     }
02295   }
02296   msg = -22;
02297   return 1;
02298 }
02299 
02300 
02301 
02302 
02303 
02304 
02305 
02306 
02307 
02308 
02309 
02310 
02311 
02312 
02313 
02314 
02315 
02316 
02317 
02318 
02319 
02320 
02321 
02322 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::result(V &x, double &f, V &g, M &a,
02323     V &p, int &itncnt, int iflg)
02324 {
02325   int i, j, iii, num5, remain, iii5, iiir;
02326   int ilow, ihigh;
02327 
02328   num5 = n/5;
02329   remain = n%5;
02330 
02331   
02332   std::fprintf(mfile, "\n\nRESULT      Iterate k = %d\n", itncnt);
02333 
02334   if (iflg != 0)
02335   {
02336     
02337     std::fprintf(mfile, "\n\nRESULT      Step\n\n");
02338 
02339     ilow = -4;
02340     ihigh = 0;
02341 
02342     for (i = 1; i <= num5; i++)
02343     {
02344       ilow += 5;
02345       ihigh += 5;
02346 
02347       std::fprintf(mfile, "%d--%d     ", ilow, ihigh);
02348 
02349       for (j = 1; j <= 5; j++)
02350       {
02351         std::fprintf(mfile, "%lf  ", (double) p(ilow+j-1));
02352       }
02353 
02354       std::fprintf(mfile, "\n");
02355     }
02356 
02357     ilow += 5;
02358     ihigh = ilow + remain - 1;
02359 
02360     std::fprintf(mfile, "%d--%d     ", ilow, ihigh);
02361 
02362     for (j = 1; j <= remain; j++)
02363     {
02364       std::fprintf(mfile, "%lf  ", (double) p(ilow+j-1));
02365     }
02366 
02367     std::fprintf(mfile, "\n");
02368   }
02369 
02370   
02371   std::fprintf(mfile, "\n\nRESULT      Current x\n\n");
02372 
02373   ilow = -4;
02374   ihigh = 0;
02375 
02376   for (i = 1; i <= num5; i++)
02377   {
02378     ilow += 5;
02379     ihigh += 5;
02380 
02381     std::fprintf(mfile, "%d--%d     ", ilow, ihigh);
02382 
02383     for (j = 1; j <= 5; j++)
02384     {
02385       std::fprintf(mfile, "%lf  ", (double) x(ilow+j-1));
02386     }
02387     std::fprintf(mfile, "\n");
02388   }
02389 
02390   ilow += 5;
02391   ihigh = ilow + remain - 1;
02392 
02393   std::fprintf(mfile, "%d--%d     ", ilow, ihigh);
02394 
02395   for (j = 1; j <= remain; j++)
02396   {
02397     std::fprintf(mfile, "%lf  ", (double) x(ilow+j-1));
02398   }
02399 
02400   std::fprintf(mfile, "\n");
02401 
02402   
02403   std::fprintf(mfile, "\n\nRESULT      f_to_minimize at x = %lf\n", f);
02404 
02405   
02406   std::fprintf(mfile, "\n\nRESULT      Gradient at x\n\n");
02407 
02408   ilow = -4;
02409   ihigh = 0;
02410 
02411   for (i = 1; i <= num5; i++)
02412   {
02413     ilow += 5;
02414     ihigh += 5;
02415 
02416     std::fprintf(mfile, "%d--%d     ", ilow, ihigh);
02417 
02418     for (j = 1; j <= 5; j++)
02419     {
02420       std::fprintf(mfile, "%lf  ", (double) g(ilow+j-1));
02421     }
02422     std::fprintf(mfile, "\n");
02423   }
02424 
02425   ilow += 5;
02426   ihigh = ilow + remain - 1;
02427 
02428   std::fprintf(mfile, "%d--%d     ", ilow, ihigh);
02429 
02430   for (j = 1; j <= remain; j++)
02431   {
02432     std::fprintf(mfile, "%lf  ", (double) g(ilow+j-1));
02433   }
02434 
02435   std::fprintf(mfile, "\n");
02436 
02437   
02438   if (iflg != 0)
02439   {
02440     std::fprintf(mfile, "\n\nRESULT      Hessian at x\n\n");
02441 
02442     for (iii = 1; iii <= n; iii++)
02443     {
02444       iii5 = iii/5;
02445       iiir = iii%5;
02446 
02447       ilow = -4;
02448       ihigh = 0;
02449 
02450       for (i = 1; i <= iii5; i++)
02451       {
02452         ilow += 5;
02453         ihigh += 5;
02454 
02455         std::fprintf(mfile, "i = %d, j = ", iii);
02456         std::fprintf(mfile, "%d--%d     ", ilow, ihigh);
02457 
02458         for (j = 1; j <= 5; j++)
02459         {
02460           std::fprintf(mfile, "%lf  ", (double) a(iii, ilow+j-1));
02461         }
02462         std::fprintf(mfile, "\n");
02463       }
02464       ilow += 5;
02465       ihigh = ilow + iiir - 1;
02466 
02467       std::fprintf(mfile, "i = %d, j = ", iii);
02468       std::fprintf(mfile, "%d--%d     ", ilow, ihigh);
02469 
02470       for (j = 1; j <= iiir; j++)
02471       {
02472         std::fprintf(mfile, "%lf  ", (double) a(iii, ilow+j-1));
02473       }
02474 
02475       std::fprintf(mfile, "\n");
02476     }
02477   }
02478 }
02479 
02480 
02481 
02482 
02483 
02484 
02485 
02486 
02487 
02488 
02489 
02490 
02491 
02492 
02493 
02494 
02495 
02496 
02497 
02498 
02499 
02500 
02501 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::bakslv(M &a, V &x, V &b)
02502 {
02503   int i, ip1, j;
02504   double sum;
02505 
02506   
02507   i = n;
02508   x(i) = b(i)/a(i,i);
02509 
02510   while (i > 1)
02511   {
02512     ip1 = i;
02513     i--;
02514 
02515     sum = 0.0;
02516 
02517     for (j = ip1; j <= n; j++)
02518     {
02519       sum += a(j, i)*x(j);
02520     }
02521     x(i) = (b(i) - sum)/a(i,i);
02522   }
02523 }
02524 
02525 
02526 
02527 
02528 
02529 
02530 
02531 
02532 
02533 
02534 
02535 
02536 
02537 
02538 
02539 
02540 
02541 
02542 
02543 
02544 
02545 
02546 
02547 
02548 
02549 
02550 
02551 
02552 
02553 
02554 
02555 
02556 
02557 
02558 
02559 
02560 
02561 
02562 
02563 
02564 
02565 
02566 
02567 
02568 
02569 
02570 
02571 
02572 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::chlhsn(M &a, V &sx, V &udiag)
02573 {
02574   int i, j, im1, jm1;
02575   double tol, diagmx, diagmn, posmax, amu, offmax, evmin, evmax, offrow, sdd;
02576 
02577   double addmax;
02578 
02579   
02580   
02581   for (j = 1; j <= n; j++)
02582   {
02583     for (i = j; i <= n; i++)
02584     {
02585       a(i, j) /= (sx(i)*sx(j));
02586     }
02587   }
02588 
02589   
02590   
02591   
02592   
02593   tol = std::sqrt(epsm);
02594 
02595   diagmx = a(1, 1);
02596   diagmn = a(1, 1);
02597 
02598   for (i = 2; i <= n; i++)
02599   {
02600     if (a(i, i) < diagmn)
02601       diagmn = a(i, i);
02602     if (a(i, i) > diagmx)
02603       diagmx = a(i, i);
02604   }
02605   posmax = max(diagmx, 0.0);
02606 
02607   
02608   if (diagmn <= posmax*tol)
02609   {
02610     amu = tol*(posmax - diagmn) - diagmn;
02611 
02612     if (amu == 0.0)
02613     {
02614       
02615       offmax = 0.0;
02616 
02617       for (i = 2; i <= n; i++)
02618       {
02619         im1 = i - 1;
02620 
02621         for (j = 1; j <= im1; j++)
02622         {
02623           if (std::fabs(a(i, j)) > offmax)
02624             offmax = std::fabs(a(i, j));
02625         }
02626       }
02627       amu = offmax;
02628 
02629       if (amu == 0.0)
02630       {
02631         amu = 1.0;
02632       }
02633       else
02634       {
02635         amu *= 1.0 + tol;
02636       }
02637     }
02638 
02639     
02640     for (i = 1; i <= n; i++)
02641     {
02642       a(i, i) += amu;
02643     }
02644 
02645     diagmx += amu;
02646   }
02647 
02648   
02649   
02650   
02651   
02652   for (j = 1; j <= n; j++)
02653   {
02654     udiag(j) = a(j,j);
02655     for (i = j + 1; i <= n; i++)
02656     {
02657       a(j, i) = a(i,j);
02658     }
02659   }
02660   choldc(a, diagmx, tol, addmax);
02661 
02662   
02663   
02664   
02665   
02666   
02667   
02668   if (addmax > 0.0)
02669   {
02670     
02671     for (j = 1; j <= n; j++)
02672     {
02673       a(j, j) = udiag(j);
02674 
02675       for (i = j + 1; i <= n; i++)
02676       {
02677         a(i, j) = a(j,i);
02678       }
02679     }
02680 
02681     
02682     
02683     evmin = 0.0;
02684     evmax = a(1, 1);
02685     for (i = 1; i <= n; i++)
02686     {
02687       offrow = 0.0;
02688       im1 = i - 1;
02689 
02690       for (j = 1; j <= im1; j++)
02691       {
02692         offrow += std::fabs(a(i, j));
02693       }
02694 
02695       for (j = i + 1; j <= n; j++)
02696       {
02697         offrow += std::fabs(a(j, i));
02698       }
02699 
02700       evmin = min(evmin, a(i, i) - offrow);
02701       evmax = max(evmax, a(i, i) + offrow);
02702     }
02703     sdd = tol*(evmax - evmin) - evmin;
02704 
02705     
02706     amu = min(sdd, addmax);
02707 
02708     for (i = 1; i <= n; i++)
02709     {
02710       a(i, i) += amu;
02711       udiag(i) = a(i,i);
02712     }
02713 
02714     
02715     choldc(a, 0.0, tol, addmax);
02716   }
02717 
02718   
02719   for (j = 1; j <= n; j++)
02720   {
02721     for (i = j; i <= n; i++)
02722     {
02723       a(i, j) *= sx(i);
02724     }
02725 
02726     jm1 = j - 1;
02727 
02728     for (i = 1; i <= jm1; i++)
02729     {
02730       a(i, j) *= sx(i)*sx(j);
02731     }
02732 
02733     udiag(j) *= sx(j)*sx(j);
02734   }
02735   return;
02736 }
02737 
02738 
02739 
02740 
02741 
02742 
02743 
02744 
02745 
02746 
02747 
02748 
02749 
02750 
02751 
02752 
02753 
02754 
02755 
02756 
02757 
02758 
02759 
02760 
02761 
02762 
02763 
02764 
02765 
02766  
02767 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::choldc(M &a, double diagmx,
02768     double tol, double &addmax)
02769 {
02770   int i, j, jm1, jp1, k;
02771   double aminl, amnlsq, offmax, sum, temp;
02772 
02773   addmax = 0.0;
02774   aminl = std::sqrt(diagmx*tol);
02775   amnlsq = aminl*aminl;
02776 
02777   
02778   for (j = 1; j <= n; j++)
02779   {
02780     
02781     sum = 0.0;
02782     jm1 = j - 1;
02783     jp1 = j + 1;
02784 
02785     for (k = 1; k <= jm1; k++)
02786     {
02787       sum += a(j, k)*a(j, k);
02788     }
02789     temp = a(j, j) - sum;
02790 
02791     if (temp >= amnlsq)
02792     {
02793       a(j, j) = std::sqrt(temp);
02794     }
02795     else
02796     {
02797       
02798       offmax = 0.0;
02799 
02800       for (i = jp1; i <= n; i++)
02801       {
02802         if (std::fabs(a(i, j)) > offmax)
02803           offmax = std::fabs(a(i, j));
02804       }
02805       if (offmax <= amnlsq)
02806         offmax = amnlsq;
02807 
02808       
02809       a(j, j) = std::sqrt(offmax);
02810       addmax = max(addmax, offmax-temp);
02811     }
02812 
02813     
02814     for (i = jp1; i <= n; i++)
02815     {
02816       sum = 0.0;
02817 
02818       for (k = 1; k <= jm1; k++)
02819       {
02820         sum += a(i, k)*a(j, k);
02821       }
02822       a(i, j) = (a(i,j) - sum)/a(j,j);
02823     }
02824   }
02825 }
02826 
02827 
02828 
02829 
02830 
02831 
02832 
02833 
02834 
02835 
02836 
02837 
02838 
02839 
02840 
02841 
02842 
02843 
02844 
02845 
02846 
02847 
02848 
02849 
02850 
02851 
02852 
02853 
02854 
02855 
02856 
02857 
02858 
02859 
02860 
02861 
02862 
02863 
02864 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::dogdrv(V &x, double &f, V &g, M &a,
02865     V &p, V &xpls, double &fpls, V &sx, double &dlt, int &iretcd, bool &mxtake, V &sc, V &wrk1,
02866     V &wrk2, V &wrk3)
02867 {
02868   int i;
02869   double tmp, rnwtln;
02870   double fplsp;
02871   double cln;
02872   double eta;
02873   bool fstdog;
02874   bool nwtake;
02875 
02876   iretcd = 4;
02877   fstdog = true;
02878   tmp = 0.0;
02879 
02880   for (i = 1; i <= n; i++)
02881   {
02882     tmp += sx(i)*sx(i)*p(i)*p(i);
02883   }
02884   rnwtln = std::sqrt(tmp);
02885 
02886   while (iretcd > 1)
02887   {
02888     
02889     dogstp(g, a, p, sx, rnwtln, dlt, nwtake, fstdog, wrk1, wrk2, cln, eta, sc);
02890 
02891     
02892     tregup(x, f, g, a, sc, sx, nwtake, dlt, iretcd, wrk3, fplsp, xpls, fpls, mxtake, 2, wrk1);
02893   }
02894 }
02895 
02896 
02897 
02898 
02899 
02900 
02901 
02902 
02903 
02904 
02905 
02906 
02907 
02908 
02909 
02910 
02911 
02912 
02913 
02914 
02915 
02916 
02917 
02918 
02919 
02920 
02921 
02922 
02923 
02924 
02925 
02926 
02927 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::dogstp(V &g, M &a, V &p, V &sx,
02928     double rnwtln, double &dlt, bool &nwtake, bool &fstdog, V &ssd, V &v, double &cln, double &eta,
02929     V &sc)
02930 {
02931   double alpha, beta, tmp, dot1, dot2, alam;
02932   int i, j;
02933 
02934   
02935   if (rnwtln <= dlt)
02936   {
02937     nwtake = true;
02938 
02939     for (i = 1; i <= n; i++)
02940     {
02941       sc(i) = p(i);
02942     }
02943     dlt = rnwtln;
02944   }
02945   else
02946   {
02947     
02948     
02949     nwtake = false;
02950 
02951     if (fstdog)
02952     {
02953       
02954       fstdog = false;
02955       alpha = 0.0;
02956 
02957       for (i = 1; i <= n; i++)
02958       {
02959         alpha += (g(i)*g(i))/(sx(i)*sx(i));
02960       }
02961 
02962       beta = 0.0;
02963 
02964       for (i = 1; i <= n; i++)
02965       {
02966         tmp = 0.0;
02967 
02968         for (j = i; j <= n; j++)
02969         {
02970           tmp += (a(j, i)*g(j))/(sx(j)*sx(j));
02971         }
02972         beta += tmp*tmp;
02973       }
02974 
02975       for (i = 1; i <= n; i++)
02976       {
02977         ssd(i) = -(alpha/beta)*g(i)/sx(i);
02978       }
02979 
02980       cln = alpha*std::sqrt(alpha)/beta;
02981 
02982       eta = .2 + (.8*alpha*alpha)/(-beta*ddot(g, p));
02983 
02984       for (i = 1; i <= n; i++)
02985       {
02986         v(i) = eta*sx(i)*p(i) - ssd(i);
02987       }
02988 
02989       if (dlt == -1.0)
02990         dlt = min(cln, stepmx);
02991     }
02992     if (eta*rnwtln <= dlt)
02993     {
02994       
02995       for (i = 1; i <= n; i++)
02996       {
02997         sc(i) = (dlt/rnwtln)*p(i);
02998       }
02999     }
03000     else
03001     {
03002       if (cln >= dlt)
03003       {
03004         
03005         for (i = 1; i <= n; i++)
03006         {
03007           sc(i) = (dlt/cln)*ssd(i)/sx(i);
03008         }
03009       }
03010       else
03011       {
03012         
03013         
03014         dot1 = ddot(v, ssd); 
03015         dot2 = ddot(v, v); 
03016 
03017         alam = (-dot1 + std::sqrt((dot1*dot1) - dot2*(cln*cln - dlt*dlt)))/dot2;
03018 
03019         for (i = 1; i <= n; i++)
03020         {
03021           sc(i) = (ssd(i) + alam*v(i))/sx(i);
03022         }
03023       }
03024     }
03025   }
03026 }
03027 
03028 
03029 
03030 
03031 
03032 
03033 
03034 
03035 
03036 
03037 
03038 
03039 
03040 
03041 
03042 
03043 
03044 
03045 
03046 
03047 
03048 
03049 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::forslv(M &a, V &x, V &b)
03050 {
03051   int i, im1, j;
03052   double sum;
03053 
03054   
03055   x(1) = b(1)/a(1, 1);
03056 
03057   for (i = 2; i <= n; i++)
03058   {
03059     sum = 0.0;
03060     im1 = i - 1;
03061 
03062     for (j = 1; j <= im1; j++)
03063     {
03064       sum += a(i, j)*x(j);
03065     }
03066     x(i) = (b(i) - sum)/a(i,i);
03067   }
03068 }
03069 
03070 
03071 
03072 
03073 
03074 
03075 
03076 
03077 
03078 
03079 
03080 
03081 
03082 
03083 
03084 
03085 
03086 
03087 
03088 
03089 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::fstocd(V &x, V &sx, double rnoise,
03090     V &g)
03091 {
03092   double stepi, xtempi, fplus, fminus, xmult;
03093   int i;
03094 
03095   
03096   
03097   xmult = std::pow(rnoise, 1.0/3.0);
03098 
03099   for (i = 1; i <= n; i++)
03100   {
03101     stepi = xmult*max(std::fabs(x(i)), 1.0/sx(i));
03102     xtempi = x(i);
03103 
03104     x(i) = xtempi + stepi;
03105     fplus = minclass->f_to_minimize(x);
03106 
03107     x(i) = xtempi - stepi;
03108     fminus = minclass->f_to_minimize(x);
03109 
03110     x(i) = xtempi;
03111 
03112     g(i) = (fplus - fminus)/(2.0*stepi);
03113   }
03114 }
03115 
03116 
03117 
03118 
03119 
03120 
03121 
03122 
03123 
03124 
03125 
03126 
03127 
03128 
03129 
03130 
03131 
03132 
03133 
03134 
03135 
03136 
03137 
03138 
03139 
03140 
03141 
03142 
03143 
03144 
03145 
03146 
03147 
03148 
03149 
03150 
03151 
03152 
03153 
03154 
03155 
03156 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::hookdr(V &x, double &f, V &g, M &a,
03157     V &udiag, V &p, V &xpls, double &fpls, V &sx, double &dlt, int &iretcd, bool &mxtake,
03158     double &amu, double &dltp, double &phi, double &phip0, V &sc, V &xplsp, V &wrk0, int &itncnt)
03159 {
03160   int i, j;
03161   bool fstime;
03162   bool nwtake;
03163   double tmp, rnwtln, alpha, beta;
03164 
03165   double fplsp;
03166 
03167   iretcd = 4;
03168   fstime = true;
03169 
03170   tmp = 0.0;
03171 
03172   for (i = 1; i <= n; i++)
03173   {
03174     tmp += sx(i)*sx(i)*p(i)*p(i);
03175   }
03176   rnwtln = std::sqrt(tmp);
03177 
03178   if (itncnt == 1)
03179   {
03180     amu = 0.0;
03181 
03182     
03183     
03184     if (dlt == -1.0)
03185     {
03186       alpha = 0.0;
03187 
03188       for (i = 1; i <= n; i++)
03189       {
03190         alpha += (g(i)*g(i))/(sx(i)*sx(i));
03191       }
03192       beta = 0.0;
03193 
03194       for (i = 1; i <= n; i++)
03195       {
03196         tmp = 0.0;
03197 
03198         for (j = i; j <= n; j++)
03199         {
03200           tmp += (a(j, i)*g(j))/(sx(j)*sx(j));
03201         }
03202         beta += tmp*tmp;
03203       }
03204       dlt = alpha*std::sqrt(alpha)/beta;
03205       dlt = min(dlt, stepmx);
03206     }
03207   }
03208   while (iretcd > 1)
03209   {
03210     
03211     hookst(g, a, udiag, p, sx, rnwtln, dlt, amu, dltp, phi, phip0, fstime, sc, nwtake, wrk0);
03212 
03213     dltp = dlt;
03214 
03215     
03216     tregup(x, f, g, a, sc, sx, nwtake, dlt, iretcd, xplsp, fplsp, xpls, fpls, mxtake, 3, udiag);
03217   }
03218 }
03219 
03220 
03221 
03222 
03223 
03224 
03225 
03226 
03227 
03228 
03229 
03230 
03231 
03232 
03233 
03234 
03235 
03236 
03237 
03238 
03239 
03240 
03241 
03242 
03243 
03244 
03245 
03246 
03247 
03248 
03249 
03250 
03251 
03252 
03253 
03254 
03255 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::hookst(V &g, M &a, V &udiag, V &p,
03256     V &sx, double rnwtln, double &dlt, double &amu, double &dltp, double &phi, double &phip0,
03257     bool &fstime, V &sc, bool &nwtake, V &wrk0)
03258 {
03259   double hi, alo;
03260   double phip, amulo, amuup, stepln;
03261   int i, j;
03262   bool done;
03263 
03264   double addmax;
03265 
03266   
03267   
03268   phip = 0.0;
03269   hi = 1.5;
03270   alo = .75;
03271 
03272   if (rnwtln <= hi*dlt)
03273   {
03274     
03275     nwtake = true;
03276 
03277     for (i = 1; i <= n; i++)
03278     {
03279       sc(i) = p(i);
03280     }
03281 
03282     dlt = min(dlt, rnwtln);
03283     amu = 0.0;
03284 
03285     return;
03286   }
03287   else
03288   {
03289     
03290     nwtake = false;
03291 
03292     if (amu > 0.0)
03293     {
03294       amu -= (phi + dltp)*((dltp - dlt) + phi)/(dlt*phip);
03295     }
03296 
03297     phi = rnwtln - dlt;
03298 
03299     if (fstime)
03300     {
03301       for (i = 1; i <= n; i++)
03302       {
03303         wrk0(i) = sx(i)*sx(i)*p(i);
03304       }
03305       
03306       forslv(a, wrk0, wrk0);
03307       phip0 = -std::pow(dnrm2(wrk0), 2)/rnwtln;
03308       fstime = false;
03309     }
03310     phip = phip0;
03311     amulo = -phi/phip;
03312 
03313     amuup = 0.0;
03314 
03315     for (i = 1; i <= n; i++)
03316     {
03317       amuup += (g(i)*g(i))/(sx(i)*sx(i));
03318     }
03319     amuup = std::sqrt(amuup)/dlt;
03320 
03321     done = false;
03322 
03323     
03324     while (!done)
03325     {
03326       if (amu < amulo || amu > amuup)
03327       {
03328         amu = max(std::sqrt(amulo*amuup),amuup*.001);
03329       }
03330 
03331       
03332       
03333       for (j = 1; j <= n; j++)
03334       {
03335         a(j,j) = udiag(j) + amu*sx(j)*sx(j);
03336 
03337         for (i = j + 1; i <= n; i++)
03338         {
03339           a(i,j) = a(j,i);
03340         }
03341       }
03342 
03343       
03344       choldc(a,0.0,std::sqrt(epsm),addmax);
03345 
03346       
03347       for (i = 1; i <= n; i++)
03348       {
03349         wrk0(i) = -g(i);
03350       }
03351 
03352       lltslv(a,sc,wrk0);
03353 
03354       
03355       
03356       stepln = 0.0;
03357 
03358       for (i = 1; i <= n; i++)
03359       {
03360         stepln += sx(i)*sx(i)*sc(i)*sc(i);
03361       }
03362 
03363       stepln = std::sqrt(stepln);
03364       phi = stepln - dlt;
03365 
03366       for (i = 1; i <= n; i++)
03367       {
03368         wrk0(i) = sx(i)*sx(i)*sc(i);
03369       }
03370 
03371       forslv(a,wrk0,wrk0);
03372 
03373       phip = -std::pow(dnrm2(wrk0),2)/stepln;
03374 
03375       if ((alo*dlt <= stepln && stepln <= hi*dlt) ||
03376       (amuup-amulo <= 0.0))
03377       {
03378         
03379         done = true;
03380       }
03381       else
03382       {
03383         
03384         amulo = max(amulo,amu-(phi/phip));
03385         if (phi < 0.0) amuup = min(amuup,amu);
03386         amu -= (stepln*phi)/(dlt*phip);
03387       }
03388     }
03389   }
03390 }
03391 
03392 
03393 
03394 
03395 
03396 
03397 
03398 
03399 
03400 
03401 
03402 
03403 
03404 
03405 
03406 
03407 
03408 
03409 
03410 
03411 
03412 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::lltslv(M &a, V &x, V &b)
03413 {
03414   
03415   forslv(a, x, b);
03416   
03417   bakslv(a, x, x);
03418 }
03419 
03420 
03421 
03422 
03423 
03424 
03425 
03426 
03427 
03428 
03429 
03430 
03431 
03432 
03433 
03434 
03435 
03436 
03437 
03438 
03439 
03440 
03441 
03442 
03443 
03444 
03445 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::lnsrch(V &x, double &f, V &g, V &p,
03446     V &xpls, double &fpls, bool &mxtake, int &iretcd, V &sx)
03447 {
03448   int i;
03449   double tmp, sln, scl, slp, rln, rmnlmb, almbda, tlmbda;
03450   double t1, t2, t3, a, b, disc, pfpls, plmbda;
03451 
03452   pfpls = 0.0;
03453   plmbda = 0.0;
03454 
03455   mxtake = false;
03456   iretcd = 2;
03457 
03458   tmp = 0.0;
03459 
03460   for (i = 1; i <= n; i++)
03461   {
03462     tmp += sx(i)*sx(i)*p(i)*p(i);
03463   }
03464   sln = std::sqrt(tmp);
03465 
03466   if (sln > stepmx)
03467   {
03468     
03469     scl = stepmx/sln;
03470     p *= scl; 
03471     sln = stepmx;
03472   }
03473   slp = ddot(g, p);
03474   rln = 0.0;
03475 
03476   for (i = 1; i <= n; i++)
03477   {
03478     rln = max(rln, std::fabs(p(i))/max(std::fabs(x(i)), 1.0/sx(i)));
03479   }
03480 
03481   rmnlmb = steptl/rln;
03482   almbda = 1.0;
03483 
03484   
03485   
03486   int iteration = 0; 
03487   while (iretcd >= 2)
03488   {
03489     for (i = 1; i <= n; i++)
03490     {
03491       xpls(i) = x(i) + almbda*p(i);
03492     }
03493     
03494     if (!(minclass->ValidParameters(xpls)))
03495     {
03496       almbda *= 0.1;
03497       if (almbda < rmnlmb)
03498       {
03499         iretcd = 1; 
03500         return;
03501       }
03502       continue;
03503     }
03504 
03505     fpls = minclass->f_to_minimize(xpls);
03506 
03507     if (fpls <= (f + slp*.0001*almbda))
03508     {
03509       
03510       iretcd = 0;
03511       if (almbda == 1.0 && sln > .99*stepmx)
03512         mxtake = true;
03513     }
03514     else
03515     {
03516       
03517       
03518       
03519       if (++iteration > 100)
03520       {
03521         iretcd = -7;
03522         if (fPrintResults)
03523         {
03524           std::fprintf(mfile, "\n\n\nLNSRCH      Number of iterations exceeded.\n");
03525           std::fprintf(mfile, "LNSRCH      fpls = %e\n", fpls);
03526         }
03527         return;
03528       } 
03529 
03530       if (almbda < rmnlmb)
03531       {
03532         
03533         iretcd = 1;
03534       }
03535       else
03536       {
03537         
03538         if (iteration == 1)
03539         {
03540           
03541           tlmbda = -slp/(2.0*(fpls - f - slp));
03542         }
03543         else
03544         {
03545           
03546           t1 = fpls - f - almbda*slp;
03547           t2 = pfpls - f - plmbda*slp;
03548           t3 = 1.0/(almbda - plmbda);
03549           a = t3*(t1/(almbda*almbda) - t2/(plmbda*plmbda));
03550           b = t3*(t2*almbda/(plmbda*plmbda) - t1*plmbda/(almbda*almbda));
03551           disc = b*b - 3.0*a*slp;
03552 
03553           if (disc > b*b)
03554           {
03555             
03556             double signone = (a < 0.0) ? -1.0 : 1.0;
03557             tlmbda = (-b + signone*std::sqrt(disc))/(3.0*a);
03558           }
03559           else
03560           {
03561             
03562             double signone = (a < 0.0) ? -1.0 : 1.0;
03563             tlmbda = (-b - signone*std::sqrt(disc))/(3.0*a);
03564           }
03565 
03566           if (tlmbda > .5*almbda)
03567             tlmbda = .5*almbda;
03568         }
03569         plmbda = almbda;
03570         pfpls = fpls;
03571 
03572         if (tlmbda < almbda/10.0)
03573         {
03574           almbda *= .1;
03575         }
03576         else
03577         {
03578           almbda = tlmbda;
03579         }
03580       }
03581     }
03582   }
03583 }
03584 
03585 
03586 
03587 
03588 
03589 
03590 
03591 
03592 
03593 
03594 
03595 
03596 
03597 
03598 
03599 
03600 
03601 
03602 
03603 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::mvmltl(M &a, V &x, V &y)
03604 {
03605   double sum;
03606   int i, j;
03607 
03608   for (i = 1; i <= n; i++)
03609   {
03610     sum = 0.0;
03611     for (j = 1; j <= i; j++)
03612     {
03613       sum += a(i, j)*x(j);
03614     }
03615     y(i) = sum;
03616   }
03617 }
03618 
03619 
03620 
03621 
03622 
03623 
03624 
03625 
03626 
03627 
03628 
03629 
03630 
03631 
03632 
03633 
03634 
03635 
03636 
03637 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::mvmlts(M &a, V &x, V &y)
03638 {
03639   double sum;
03640   int i, j;
03641 
03642   for (i = 1; i <= n; i++)
03643   {
03644     sum = 0.0;
03645 
03646     for (j = 1; j <= i; j++)
03647     {
03648       sum += a(i, j)*x(j);
03649     }
03650     for (j = i + 1; j <= n; j++)
03651     {
03652       sum += a(j, i)*x(j);
03653     }
03654     y(i) = sum;
03655   }
03656 }
03657 
03658 
03659 
03660 
03661 
03662 
03663 
03664 
03665 
03666 
03667 
03668 
03669 
03670 
03671 
03672 
03673 
03674 
03675 
03676 
03677 
03678 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::mvmltu(M &a, V &x, V &y)
03679 {
03680   double sum;
03681   int i, j;
03682 
03683   for (i = 1; i <= n; i++)
03684   {
03685     sum = 0.0;
03686     for (j = i; j <= n; j++)
03687     {
03688       sum += a(j, i)*x(j);
03689     }
03690     y(i) = sum;
03691   }
03692 }
03693 
03694 
03695 
03696 
03697 
03698 
03699 
03700 
03701 
03702 
03703 
03704 
03705 
03706 
03707 
03708 
03709 
03710 
03711 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::qraux1(M &r, int i)
03712 {
03713   double tmp;
03714   int j, ip1;
03715 
03716   ip1 = i + 1;
03717 
03718   for (j = i; j <= n; j++)
03719   {
03720     tmp = r(i, j);
03721     r(i, j) = r(ip1,j);
03722     r(ip1, j) = tmp;
03723   }
03724 }
03725 
03726 
03727 
03728 
03729 
03730 
03731 
03732 
03733 
03734 
03735 
03736 
03737 
03738 
03739 
03740 
03741 
03742 
03743 
03744 
03745 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::qraux2(M &r, int i, double a,
03746     double b)
03747 {
03748   double den, c, s, y, z;
03749   int j, ip1;
03750 
03751   ip1 = i + 1;
03752 
03753   den = std::sqrt(a*a + b*b);
03754   c = a/den;
03755   s = b/den;
03756 
03757   for (j = i; j <= n; j++)
03758   {
03759     y = r(i, j);
03760     z = r(ip1, j);
03761     r(i, j) = c*y - s*z;
03762     r(ip1, j) = s*y + c*z;
03763   }
03764 }
03765 
03766 
03767 
03768 
03769 
03770 
03771 
03772 
03773 
03774 
03775 
03776 
03777 
03778 
03779 
03780 
03781 
03782 
03783 
03784 
03785 
03786 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::qrupdt(M &a, V &u, V &v)
03787 {
03788   int k, km1, ii, i, j;
03789   double t1, t2;
03790 
03791   
03792   k = n;
03793 
03794   while (u(k) == 0 && k > 1)
03795   {
03796     k--;
03797   }
03798 
03799   
03800   
03801   
03802   km1 = k - 1;
03803 
03804   for (ii = 1; ii <= km1; ii++)
03805   {
03806     i = km1 - ii + 1;
03807 
03808     if (u(i) == 0.0)
03809     {
03810       qraux1(a, i);
03811       u(i) = u(i+1);
03812     }
03813     else
03814     {
03815       qraux2(a, i, u(i), -u(i+1));
03816       u(i) = std::sqrt(u(i)*u(i) + u(i+1)*u(i+1));
03817     }
03818   }
03819 
03820   
03821   for (j = 1; j <= n; j++)
03822   {
03823     a(1, j) += u(1)*v(j);
03824   }
03825 
03826   
03827   
03828   km1 = k - 1;
03829 
03830   for (i = 1; i <= km1; i++)
03831   {
03832     if (a(i, i) == 0.0)
03833     {
03834       qraux1(a, i);
03835     }
03836     else
03837     {
03838       t1 = a(i, i);
03839       t2 = -a(i+1, i);
03840 
03841       qraux2(a, i, t1, t2);
03842     }
03843   }
03844 }
03845 
03846 
03847 
03848 
03849 
03850 
03851 
03852 
03853 
03854 
03855 
03856 
03857 
03858 
03859 
03860 
03861 
03862 
03863 
03864 
03865 
03866 
03867 
03868 
03869 
03870 
03871 
03872 
03873 
03874 
03875 
03876 
03877 
03878 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::secfac(V &x, V &g, M &a, V &xpls,
03879     V &gpls, int &itncnt, double rnf, int &iagflg, bool &noupdt, V &s, V &y, V &u, V &w)
03880 {
03881   bool skpupd;
03882   int i, j, im1;
03883   double den1, snorm2, ynrm2, den2, alp, reltol;
03884 
03885   if (itncnt == 1)
03886     noupdt = true;
03887 
03888   for (i = 1; i <= n; i++)
03889   {
03890     s(i) = xpls(i) - x(i);
03891     y(i) = gpls(i) - g(i);
03892   }
03893 
03894   den1 = ddot(s, y); 
03895   snorm2 = dnrm2(s); 
03896   ynrm2 = dnrm2(y); 
03897 
03898   if (den1 >= std::sqrt(epsm)*snorm2*ynrm2)
03899   {
03900     mvmltu(a, s, u);
03901     den2 = ddot(u, u); 
03902 
03903     
03904     alp = std::sqrt(den1/den2);
03905 
03906     if (noupdt)
03907     {
03908       for (j = 1; j <= n; j++)
03909       {
03910         u(j) *= alp;
03911 
03912         for (i = j; i <= n; i++)
03913         {
03914           a(i, j) *= alp;
03915         }
03916       }
03917       noupdt = false;
03918       
03919       alp = 1.0;
03920     }
03921     skpupd = true;
03922 
03923     
03924     mvmltl(a, u, w);
03925 
03926     i = 1;
03927 
03928     if (iagflg == 0)
03929     {
03930       reltol = std::sqrt(rnf);
03931     }
03932     else
03933     {
03934       reltol = rnf;
03935     }
03936 
03937     while (i <= n && skpupd)
03938     {
03939       if (std::fabs(y(i) - w(i)) >= reltol*max(std::fabs(g(i)), std::fabs(gpls(i))))
03940       {
03941         skpupd = false;
03942       }
03943       else
03944       {
03945         i++;
03946       }
03947     }
03948     if (!skpupd)
03949     {
03950       
03951       for (i = 1; i <= n; i++)
03952       {
03953         w(i) = y(i) - alp*w(i);
03954       }
03955       
03956       alp /= den1;
03957 
03958       
03959       for (i = 1; i <= n; i++)
03960       {
03961         u(i) *= alp;
03962       }
03963 
03964       
03965       for (i = 2; i <= n; i++)
03966       {
03967         im1 = i - 1;
03968 
03969         for (j = 1; j <= im1; j++)
03970         {
03971           a(j, i) = a(i,j);
03972           a(i, j) = 0.0;
03973         }
03974       }
03975 
03976       
03977       qrupdt(a, u, w);
03978 
03979       
03980       
03981       
03982       for (i = 2; i <= n; i++)
03983       {
03984         im1 = i - 1;
03985 
03986         for (j = 1; j <= im1; j++)
03987         {
03988           a(i, j) = a(j,i);
03989         }
03990       }
03991     }
03992   }
03993 }
03994 
03995 
03996 
03997 
03998 
03999 
04000 
04001 
04002 
04003 
04004 
04005 
04006 
04007 
04008 
04009 
04010 
04011 
04012 
04013 
04014 
04015 
04016 
04017 
04018 
04019 
04020 
04021 
04022 
04023 
04024 
04025 
04026 
04027 
04028 
04029 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::secunf(V &x, V &g, M &a, V &udiag,
04030     V &xpls, V &gpls, int &itncnt, double rnf, int &iagflg, bool &noupdt, V &s, V &y, V &t)
04031 {
04032   double den1, snorm2, ynrm2, den2, gam, tol;
04033   int i, j;
04034   bool skpupd;
04035 
04036   
04037   
04038   for (j = 1; j <= n; j++)
04039   {
04040     a(j, j) = udiag(j);
04041 
04042     for (i = j+1; i <= n; i++)
04043     {
04044       a(i, j) = a(j,i);
04045     }
04046   }
04047   if (itncnt == 1)
04048     noupdt = true;
04049 
04050   for (i = 1; i <= n; i++)
04051   {
04052     s(i) = xpls(i) - x(i);
04053     y(i) = gpls(i) - g(i);
04054   }
04055 
04056   den1 = ddot(s, y); 
04057 
04058   snorm2 = dnrm2(s); 
04059 
04060   ynrm2 = dnrm2(y); 
04061 
04062   if (den1 >= std::sqrt(epsm)*snorm2*ynrm2)
04063   {
04064     mvmlts(a, s, t);
04065 
04066     den2 = ddot(s, t); 
04067 
04068     if (noupdt)
04069     {
04070       
04071       gam = den1/den2;
04072 
04073       den2 = gam*den2;
04074 
04075       for (j = 1; j <= n; j++)
04076       {
04077         t(j) *= gam;
04078 
04079         for (i = j; i <= n; i++)
04080         {
04081           a(i, j) *= gam;
04082         }
04083       }
04084       noupdt = false;
04085     }
04086 
04087     skpupd = true;
04088 
04089     
04090     for (i = 1; i <= n; i++)
04091     {
04092       tol = rnf*max(std::fabs(g(i)), std::fabs(gpls(i)));
04093       if (iagflg == 0)
04094         tol /= std::sqrt(rnf);
04095 
04096       if (std::fabs(y(i) - t(i)) >= tol)
04097       {
04098         skpupd = false;
04099         break;
04100       }
04101     }
04102 
04103     if (!skpupd)
04104     {
04105       
04106       for (j = 1; j <= n; j++)
04107       {
04108         for (i = j; i <= n; i++)
04109         {
04110           a(i, j) += y(i)*y(j)/den1 - t(i)*t(j)/den2;
04111         }
04112       }
04113     }
04114   }
04115 }
04116 
04117 
04118 
04119 
04120 
04121 
04122 
04123 
04124 
04125 
04126 
04127 
04128 
04129 
04130 
04131 
04132 
04133 
04134 
04135 
04136 
04137 
04138 
04139 
04140 
04141 
04142 
04143 
04144 
04145 
04146 
04147 
04148 
04149 
04150 
04151 
04152 
04153 
04154 
04155 
04156 
04157 
04158 
04159 
04160 
04161 
04162 template<class V, class M, class FUNC> void Uncmin<V, M, FUNC>::tregup(V &x, double &f, V &g, M &a,
04163     V &sc, V &sx, bool &nwtake, double &dlt, int &iretcd, V &xplsp, double &fplsp, V &xpls,
04164     double &fpls, bool &mxtake, int method, V &udiag)
04165 {
04166   int i, j;
04167   double rln, temp, dltf, slp, dltmp, dltfp;
04168 
04169   mxtake = false;
04170 
04171   for (i = 1; i <= n; i++)
04172   {
04173     xpls(i) = x(i) + sc(i);
04174   }
04175   fpls = minclass->f_to_minimize(xpls);
04176 
04177   dltf = fpls - f;
04178 
04179   slp = ddot(g, sc); 
04180 
04181   if (iretcd == 4)
04182     fplsp = 0.0;
04183 
04184   if ((iretcd == 3) && ((fpls >= fplsp) || (dltf > .0001*slp)))
04185   {
04186     
04187     iretcd = 0;
04188 
04189     for (i = 1; i <= n; i++)
04190     {
04191       xpls(i) = xplsp(i);
04192     }
04193     fpls = fplsp;
04194     dlt *= .5;
04195   }
04196   else
04197   {
04198     
04199     if (dltf > .0001*slp)
04200     {
04201       rln = 0.0;
04202 
04203       for (i = 1; i <= n; i++)
04204       {
04205         rln = max(rln, std::fabs(sc(i))/ max(std::fabs(xpls(i)), 1.0/sx(i)));
04206       }
04207 
04208       if (rln < steptl)
04209       {
04210         
04211         iretcd = 1;
04212       }
04213       else
04214       {
04215         
04216         iretcd = 2;
04217 
04218         dltmp = -slp*dlt/(2.0*(dltf - slp));
04219 
04220         if (dltmp < .1*dlt)
04221         {
04222           dlt *= .1;
04223         }
04224         else
04225         {
04226           dlt = dltmp;
04227         }
04228       }
04229     }
04230     else
04231     {
04232       
04233       dltfp = 0.0;
04234 
04235       if (method == 2)
04236       {
04237         for (i = 1; i <= n; i++)
04238         {
04239           temp = 0.0;
04240 
04241           for (j = i; j <= n; j++)
04242           {
04243             temp += a(j, i)*sc(j);
04244           }
04245           dltfp += temp*temp;
04246         }
04247       }
04248       else
04249       {
04250         for (i = 1; i <= n; i++)
04251         {
04252           dltfp += udiag(i)*sc(i)*sc(i);
04253           temp = 0.0;
04254 
04255           for (j = i+1; j <= n; j++)
04256           {
04257             temp += a(i, j)*sc(i)*sc(j);
04258           }
04259           dltfp += 2.0*temp;
04260         }
04261       }
04262       dltfp = slp + dltfp/2.0;
04263 
04264       if ((iretcd != 2) && (std::fabs(dltfp - dltf) <= .1*std::fabs(dltf)) && (!nwtake) && (dlt
04265           <= .99*stepmx))
04266       {
04267         
04268         iretcd = 3;
04269 
04270         for (i = 1; i <= n; i++)
04271         {
04272           xplsp(i) = xpls(i);
04273         }
04274         fplsp = fpls;
04275         dlt = min(2.0*dlt, stepmx);
04276       }
04277       else
04278       {
04279         
04280         iretcd = 0;
04281 
04282         if (dlt > .99*stepmx)
04283           mxtake = true;
04284 
04285         if (dltf >= .1*dltfp)
04286         {
04287           
04288           dlt *= .5;
04289         }
04290         else
04291         {
04292           
04293           if (dltf <= .75*dltfp)
04294             dlt = min(2.0*dlt, stepmx);
04295         }
04296       }
04297     }
04298   }
04299 }
04300 
04301 
04302 
04303 
04304 
04305 
04306 
04307 
04308 
04309 
04310 
04311 
04312 
04313 
04314 
04315 
04316 template<class V, class M, class FUNC> double Uncmin<V, M, FUNC>::ddot(V &x, V &y)
04317 {
04318   typename V::iterator ix = x.begin();
04319   typename V::iterator iy = y.begin();
04320   double prod = 0.0;
04321 
04322   
04323   for (int n = x.size(); n--; ++ix, ++iy)
04324   {
04325     prod += *ix * *iy;
04326   }
04327 
04328   return prod;
04329 }
04330 
04331 
04332 
04333 
04334 
04335 
04336 
04337 
04338 
04339 
04340 
04341 
04342 
04343 
04344 
04345 
04346 
04347 
04348 
04349 
04350 
04351 
04352 
04353 
04354 
04355 template<class V, class M, class FUNC> double Uncmin<V, M, FUNC>::dnrm2(V &x)
04356 {
04357 
04358   double absxi, norm, scale, ssq, fac;
04359   int ix;
04360   int nelem = x.size();
04361 
04362   if (nelem < 1)
04363   {
04364     norm = 0.0;
04365   }
04366   else if (nelem == 1)
04367   {
04368     norm = std::fabs(x(1));
04369   }
04370   else
04371   {
04372     scale = 0.0;
04373     ssq = 1.0;
04374 
04375     for (ix = 1; ix <= nelem; ++ix)
04376     {
04377       if (x(ix) != 0.0)
04378       {
04379         absxi = std::fabs(x(ix));
04380 
04381         if (scale < absxi)
04382         {
04383           fac = scale/absxi;
04384           ssq = 1.0 + ssq*fac*fac;
04385           scale = absxi;
04386         }
04387         else
04388         {
04389           fac = absxi/scale;
04390           ssq += fac*fac;
04391         }
04392       }
04393     }
04394     norm = scale*std::sqrt(ssq);
04395   }
04396   return norm;
04397 }
04398 
04399 
04400 
04401 
04402 
04403 
04404 
04405 
04406 
04407 
04408 
04409 
04410 
04411 
04412 
04413 
04414 template<class V, class M, class FUNC> double Uncmin<V, M, FUNC>::max(double a, double b)
04415 {
04416   return (a > b) ? a : b;
04417 }
04418 
04419 
04420 
04421 
04422 
04423 
04424 
04425 
04426 
04427 
04428 
04429 
04430 
04431 
04432 
04433 
04434 template<class V, class M, class FUNC> double Uncmin<V, M, FUNC>::min(double a, double b)
04435 {
04436   return (a > b) ? b : a;
04437 }
04438 
04439 #endif // UNCMIN_H_