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_