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 #ifndef LBFGSP_H_SEP_17_2005
00067 #define LBFGSP_H_SEP_17_2005
00068
00069 #include <cmath>
00070 #include <cstdlib>
00071 #include <fstream>
00072 #include "timer.h"
00073 #include "Polynomial.h"
00074
00075 const int LBFGSP_PRINT = -1;
00076
00077
00078
00079
00080
00081
00082
00083 class LBFGSP
00084 {
00085 public:
00086 LBFGSP(const int& maxIter, const double& ftol,
00087 const int& numWts)
00088 : maxIter_(maxIter), ftol_(ftol),
00089 nbd_(NULL), iwa_(NULL), l_(NULL), u_(NULL), g_(NULL), wa_(NULL)
00090 { init(numWts); }
00091
00092 LBFGSP()
00093 : maxIter_(-1), ftol_(-1),
00094 nbd_(NULL), iwa_(NULL), l_(NULL), u_(NULL), g_(NULL), wa_(NULL)
00095 { init(0); }
00096
00097
00098 ~LBFGSP() { destroy(); }
00099
00100
00101 void setMaxIter(const int& iter) { maxIter_ = iter; }
00102
00103 void setFtol(const double& tol) { ftol_ = tol; }
00104
00105
00106 void init(const int& numWts)
00107 {
00108 destroy();
00109 numWts_ = numWts;
00110 int mmax = 17;
00111 nbd_ = new int[numWts_+1];
00112 iwa_ = new int[3*numWts_+1];
00113 l_ = new double[numWts_+1];
00114 u_ = new double[numWts_+1];
00115 g_ = new double[numWts_+1];
00116 wa_ = new double[2*mmax*numWts_+4*numWts_+12*mmax*mmax+12*mmax+1];
00117 }
00118
00119
00120 void reInit(const int& numWts)
00121 {
00122 if (numWts_ == numWts) return;
00123 init(numWts);
00124 }
00125
00126 void destroy()
00127 {
00128 if (nbd_ != NULL) delete [] nbd_;
00129 if (iwa_ != NULL) delete [] iwa_;
00130 if (l_ != NULL) delete [] l_;
00131 if (u_ != NULL) delete [] u_;
00132 if (g_ != NULL) delete [] g_;
00133 if (wa_ != NULL) delete [] wa_;
00134 }
00135
00136 double minimize(const int& numWts, double* const & wts, int& iter,bool& error, PolyNomial& pl)
00137 {
00138 reInit(numWts);
00139 return minimize(iter, error, pl);
00140 }
00141
00142 double startLBFGS(PolyNomial& pl)
00143 {
00144 int m = 5;
00145 double f;
00146 double factr = 0;
00147 double pgtol = 0;
00148
00149 ofstream* itfile = NULL;
00150 int iprint = LBFGSP_PRINT;
00151 if (iprint >= 1) itfile = new ofstream("iterate.dat");
00152
00153
00154
00155
00156 for (int i = 0; i <= numWts_; i++) nbd_[i] = 2;
00157
00158 strcpy(task_,"START");
00159 for (int i = 5; i <= 60; i++) task_[i]=' ';
00160
00161
00162 double* wts = new double[numWts_ + 1];
00163
00164 pl.ClearVarValue();
00165 for(int i = 0; i < numWts_; i++)
00166 {
00167 wts[i+1] = 0;
00168 pl.AppendVarValue(wts[i+1]);
00169 }
00170
00171 setulb(numWts_,m,wts,l_,u_,nbd_,f,g_,factr,pgtol,wa_,iwa_,task_,
00172 iprint,csave_,lsave_,isave_,dsave_,itfile);
00173 pl.ClearVarValue();
00174 for(int i = 0; i < numWts_; i++) pl.AppendVarValue(wts[i+1]);
00175 delete[] wts;
00176 return f;
00177 }
00178
00179
00180 double proceedOneStep(PolyNomial& pl)
00181 {
00182 int m = 5;
00183 double f = -999;
00184 double factr = 0;
00185 double pgtol = 0;
00186
00187 ofstream* itfile = NULL;
00188 int iprint = LBFGSP_PRINT;
00189 if (iprint >= 1) itfile = new ofstream("iterate.dat");
00190 double* wts = new double[numWts_ + 1];
00191 for(int i = 0; i < numWts_; i++) {
00192 wts[i+1] = pl.GetVarValue(i);
00193 }
00194
00195
00196 if (strncmp(task_,"FG",2)==0)
00197 {
00198 f = getValueAndGradient(g_, wts, pl);
00199 setulb(numWts_,m,wts,l_,u_,nbd_,f,g_,factr,pgtol,wa_,iwa_,task_,
00200 iprint,csave_,lsave_,isave_,dsave_,itfile);
00201 pl.ClearVarValue();
00202 for(int i = 0; i < numWts_; i++) pl.AppendVarValue(wts[i+1]);
00203 }
00204 else
00205 {
00206
00207
00208 setulb(numWts_,m,wts,l_,u_,nbd_,f,g_,factr,pgtol,wa_,iwa_,task_,
00209 iprint,csave_,lsave_,isave_,dsave_,itfile);
00210
00211 pl.ClearVarValue();
00212 for(int i = 0; i < numWts_; i++) pl.AppendVarValue(wts[i+1]);
00213 }
00214
00215
00216
00217 delete[] wts;
00218 return pl.ComputePlValue();
00219 }
00220
00221
00222
00223 double minimize(int& iter, bool& error, PolyNomial& pl)
00224 {
00225
00226 error = false;
00227 int m = 5;
00228 double f;
00229 double factr = 0;
00230 double pgtol = 0;
00231
00232 ofstream* itfile = NULL;
00233 int iprint = LBFGSP_PRINT;
00234 if (iprint >= 1) itfile = new ofstream("iterate.dat");
00235 iter = 0;
00236
00237
00238
00239
00240 for (int i = 0; i <= numWts_; i++) nbd_[i] = 2;
00241
00242 strcpy(task_,"START");
00243 for (int i = 5; i <= 60; i++) task_[i]=' ';
00244
00245
00246
00247 double* wts = new double[numWts_ + 1];
00248 pl.ClearVarValue();
00249 for(int i = 0; i < numWts_; i++)
00250 {
00251 wts[i + 1] = 0;
00252 pl.AppendVarValue(wts[i+1]);
00253 }
00254
00255 setulb(numWts_,m,wts,l_,u_,nbd_,f,g_,factr,pgtol,wa_,iwa_,task_,
00256 iprint,csave_,lsave_,isave_,dsave_,itfile);
00257
00258 pl.ClearVarValue();
00259 for(int i = 0; i < numWts_; i++) pl.AppendVarValue(wts[i+1]);
00260
00261 double initialValue = 0, prevValue = 0, newValue;
00262 bool firstIter = true;
00263
00264
00265 while (strncmp(task_,"FG",2)==0 || strncmp(task_,"NEW_X",5)==0)
00266 {
00267 if (strncmp(task_,"FG",2)==0)
00268 {
00269 f = getValueAndGradient(g_, wts, pl);
00270
00271 setulb(numWts_,m,wts,l_,u_,nbd_,f,g_,factr,pgtol,wa_,iwa_,task_,
00272 iprint,csave_,lsave_,isave_,dsave_,itfile);
00273
00274 pl.ClearVarValue();
00275 for(int i = 0; i < numWts_; i++) pl.AppendVarValue(wts[i+1]);
00276
00277 if (firstIter) { firstIter = false; prevValue = f; initialValue = f; }
00278 }
00279 else
00280 {
00281
00282
00283 if (iter+1 > maxIter_) break;
00284 ++iter;
00285 newValue = f;
00286
00287 if (fabs(newValue-prevValue) < ftol_*fabs(prevValue)) break;
00288 prevValue = newValue;
00289 setulb(numWts_,m,wts,l_,u_,nbd_,f,g_,factr,pgtol,wa_,iwa_,task_,
00290 iprint,csave_,lsave_,isave_,dsave_,itfile);
00291 pl.ClearVarValue();
00292 for(int i = 0; i < numWts_; i++) pl.AppendVarValue(wts[i+1]);
00293 }
00294 }
00295
00296
00297
00298
00299
00300 if (strncmp(task_,"ABNO",4) == 0)
00301 {
00302 cout << "ERROR: LBFGSP failed. Returned ABNO" << endl;
00303 error = true;
00304 delete[] wts;
00305 return initialValue;
00306 }
00307
00308 if (strncmp(task_,"ERROR",5)==0)
00309 {
00310 cout << "ERROR: LBFGSP failed. Returned ERROR" << endl;
00311 error = true;
00312 delete[] wts;
00313 return initialValue;
00314 }
00315
00316 if (strncmp(task_,"CONV",4)==0)
00317 {
00318 cout << "LBFGSP converged!" << endl;
00319 }
00320
00321 delete[] wts;
00322
00323 return f;
00324 }
00325
00326
00327 void setUpperBounds(const double* u)
00328 {
00329 if (numWts_ > 0)
00330 {
00331 memcpy(u_+1, u, numWts_*sizeof(double));
00332 }
00333 }
00334
00335 void setLowerBounds(const double* l)
00336 {
00337 if(numWts_ > 0)
00338 {
00339 memcpy(l_+1, l, numWts_*sizeof(double));
00340 }
00341 }
00342
00343 private:
00344 int maxIter_;
00345 double ftol_;
00346 int numWts_;
00347
00348
00349 int* nbd_;
00350 int* iwa_;
00351 double* l_;
00352 double* u_;
00353 double* g_;
00354 double* wa_;
00355
00356 char task_[61];
00357 char csave_[61];
00358 bool lsave_[5];
00359 int isave_[45];
00360 double dsave_[30];
00361
00362
00363 private :
00364
00365 double getValueAndGradient(double* const & g, const double* const & wts, PolyNomial& pl)
00366 {
00367 g[0] = 0;
00368
00369
00370 Array<double> gr = pl.GetGradient();
00371 for(int i = 0; i < gr.size(); i++)
00372 {
00373 g[i+1] = gr[i];
00374 }
00375
00376 return pl.ComputePlValue();
00377 }
00378
00379
00380
00381
00382
00383
00384 int getIdx(const int& i, const int& j, const int& idim)
00385 {
00386 return (j-1)*idim + i;
00387 }
00388
00389
00390 double max(const double& a, const double& b) { if (a>=b) return a; return b; }
00391
00392 double min(const double& a, const double& b) { if (a<=b) return a; return b; }
00393
00394 int min(const int& a, const int& b) { if (a<=b) return a; return b; }
00395
00396 double max(const double& a, const double& b, const double& c)
00397 {
00398 if (a >= b && a >= c) return a;
00399 if (b >= a && b >= c) return b;
00400 assert(c >= a && c >= b);
00401 return c;
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
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
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
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
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 void setulb(const int& n, const int& m, double* const & x,
00594 const double* const & l, const double* const & u,
00595 const int* const & nbd, double& f, double* const & g,
00596 const double& factr, const double& pgtol,
00597 double* const & wa, int* const & iwa,
00598 char* const & task, const int& iprint,
00599 char* const & csave, bool* const & lsave,
00600 int* const & isave, double* const & dsave,
00601 ofstream* itfile)
00602 {
00603 int l1,l2,l3,lws,lr,lz,lt,ld,lsg,lwa,lyg,
00604 lsgo,lwy,lsy,lss,lyy,lwt,lwn,lsnd,lygo;
00605
00606 if (strncmp(task,"START",5)==0)
00607 {
00608 isave[1] = m*n;
00609 isave[2] = m*m;
00610 isave[3] = 4*m*m;
00611 isave[4] = 1;
00612 isave[5] = isave[4] + isave[1];
00613 isave[6] = isave[5] + isave[1];
00614 isave[7] = isave[6] + isave[2];
00615 isave[8] = isave[7] + isave[2];
00616 isave[9] = isave[8] + isave[2];
00617 isave[10] = isave[9] + isave[2];
00618 isave[11] = isave[10] + isave[3];
00619 isave[12] = isave[11] + isave[3];
00620 isave[13] = isave[12] + n;
00621 isave[14] = isave[13] + n;
00622 isave[15] = isave[14] + n;
00623 isave[16] = isave[15] + n;
00624 isave[17] = isave[16] + 8*m;
00625 isave[18] = isave[17] + m;
00626 isave[19] = isave[18] + m;
00627 isave[20] = isave[19] + m;
00628 }
00629 l1 = isave[1];
00630 l2 = isave[2];
00631 l3 = isave[3];
00632 lws = isave[4];
00633 lwy = isave[5];
00634 lsy = isave[6];
00635 lss = isave[7];
00636 lyy = isave[8];
00637 lwt = isave[9];
00638 lwn = isave[10];
00639 lsnd = isave[11];
00640 lz = isave[12];
00641 lr = isave[13];
00642 ld = isave[14];
00643 lt = isave[15];
00644 lwa = isave[16];
00645 lsg = isave[17];
00646 lsgo = isave[18];
00647 lyg = isave[19];
00648 lygo = isave[20];
00649
00650 timer_.reset();
00651
00652 mainlb(n,m,x,l,u,nbd,f,g,factr,pgtol,
00653 &(wa[lws-1]),&(wa[lwy-1]),&(wa[lsy-1]),&(wa[lss-1]),&(wa[lyy-1]),
00654 &(wa[lwt-1]),&(wa[lwn-1]),&(wa[lsnd-1]),&(wa[lz-1]),&(wa[lr-1]),
00655 &(wa[ld-1]),&(wa[lt-1]),&(wa[lwa-1]),&(wa[lsg-1]),&(wa[lsgo-1]),
00656 &(wa[lyg-1]),&(wa[lygo-1]),&(iwa[1-1]),&(iwa[n+1-1]),&(iwa[2*n+1-1]),
00657 task,iprint,csave,lsave,&(isave[22-1]),dsave, itfile);
00658 }
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
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
00725
00726
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
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
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
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 void mainlb(const int& n, const int& m, double* const & x,
00841 const double* const & l, const double* const & u,
00842 const int* const & nbd, double& f, double* const & g,
00843 const double& factr, const double& pgtol,
00844 double* const & ws, double* const & wy, double* const & sy,
00845 double* const & ss, double* const & yy, double* const & wt,
00846 double* const & wn, double* const & snd, double* const & z,
00847 double* const & r, double* const & d, double* const & t,
00848 double* const & wa, double* const & sg, double* const& sgo,
00849 double* const & yg, double* const & ygo, int* const& index,
00850 int* const & iwhere, int* const & indx2, char* const& task,
00851 const int& iprint, char* const& csave, bool * const& lsave,
00852 int* const & isave, double* const & dsave, ofstream* itfile)
00853 {
00854 bool prjctd,cnstnd,boxed,updatd,wrk;
00855 char word[4];
00856 int k,nintol,iback,nskip,
00857 head,col,iter,itail,iupdat,
00858 nint,nfgv,info,ifun=0,
00859 iword,nfree,nact,ileave,nenter;
00860 double theta,fold=0,dr,rr,tol,
00861 xstep,sbgnrm,ddum,dnorm=0,dtd,epsmch,
00862 cpu1=0,cpu2,cachyt,sbtime,lnscht,time1,time2,
00863 gd,gdold=0,stp,stpmx=0,time;
00864 double one=1.0,zero=0.0;
00865
00866 if (iprint > 1) { assert(itfile); }
00867
00868 if (strncmp(task,"START",5)==0)
00869 {
00870 time1 = timer_.time();
00871
00872
00873 epsmch = dpmeps();
00874
00875
00876
00877
00878
00879
00880 col = 0;
00881 head = 1;
00882 theta = one;
00883 iupdat = 0;
00884 updatd = false;
00885
00886
00887 iter = 0;
00888 nfgv = 0;
00889 nint = 0;
00890 nintol = 0;
00891 nskip = 0;
00892 nfree = n;
00893
00894
00895 tol = factr*epsmch;
00896
00897
00898 cachyt = 0;
00899 sbtime = 0;
00900 lnscht = 0;
00901
00902
00903
00904 strcpy(word, "---");
00905
00906
00907 info = 0;
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917 errclb(n,m,factr,l,u,nbd,task,info,k);
00918 if (strncmp(task,"ERROR",5)==0)
00919 {
00920 prn3lb(n,x,f,task,iprint,info,itfile,
00921 iter,nfgv,nintol,nskip,nact,sbgnrm,
00922 zero,nint,word,iback,stp,xstep,k,
00923 cachyt,sbtime,lnscht);
00924 return;
00925 }
00926
00927 prn1lb(n,m,l,u,x,iprint,itfile,epsmch);
00928
00929
00930 active(n,l,u,nbd,x,iwhere,iprint,prjctd,cnstnd,boxed) ;
00931
00932
00933 }
00934 else
00935 {
00936
00937 prjctd = lsave[1];
00938 cnstnd = lsave[2];
00939 boxed = lsave[3];
00940 updatd = lsave[4];
00941
00942 nintol = isave[1];
00943
00944 iback = isave[4];
00945 nskip = isave[5];
00946 head = isave[6];
00947 col = isave[7];
00948 itail = isave[8];
00949 iter = isave[9];
00950 iupdat = isave[10];
00951 nint = isave[12];
00952 nfgv = isave[13];
00953 info = isave[14];
00954 ifun = isave[15];
00955 iword = isave[16];
00956 nfree = isave[17];
00957 nact = isave[18];
00958 ileave = isave[19];
00959 nenter = isave[20];
00960
00961 theta = dsave[1];
00962 fold = dsave[2];
00963 tol = dsave[3];
00964 dnorm = dsave[4];
00965 epsmch = dsave[5];
00966 cpu1 = dsave[6];
00967 cachyt = dsave[7];
00968 sbtime = dsave[8];
00969 lnscht = dsave[9];
00970 time1 = dsave[10];
00971 gd = dsave[11];
00972 stpmx = dsave[12];
00973 sbgnrm = dsave[13];
00974 stp = dsave[14];
00975 gdold = dsave[15];
00976 dtd = dsave[16];
00977
00978
00979
00980
00981 if (strncmp(task,"FG_LN",5)==0) goto goto66;
00982 if (strncmp(task,"NEW_X",5)==0) goto goto777;
00983 if (strncmp(task,"FG_ST",5)==0) goto goto111;
00984 if (strncmp(task,"STOP",4)==0)
00985 {
00986 if (strncmp(&(task[6]),"CPU",3)==0)
00987 {
00988
00989 dcopy(n,t,1,x,1);
00990 dcopy(n,r,1,g,1);
00991 f = fold;
00992 }
00993 goto goto999;
00994 }
00995 }
00996
00997
00998
00999 strcpy(task, "FG_START");
01000
01001 goto goto1000;
01002
01003 goto111:
01004
01005 nfgv = 1;
01006
01007
01008
01009 projgr(n,l,u,nbd,x,g,sbgnrm);
01010
01011 if (iprint >= 1)
01012 {
01013 cout << "At iterate " << iter << ": f=" <<f<<", |proj g|="<<sbgnrm<<endl;
01014 *itfile << "At iterate " << iter << ": nfgv=" << nfgv
01015 << ", sbgnrm=" << sbgnrm << ", f=" << f << endl;
01016 }
01017
01018 if (sbgnrm <= pgtol)
01019 {
01020
01021 strcpy(task,"CONVERGENCE: NORM OF PROJECTED GRADIENT <= PGTOL");
01022 goto goto999;
01023 }
01024
01025
01026
01027 goto222:
01028 if (iprint >= 99) cout << "ITERATION " << (iter + 1) << endl;
01029 iword = -1;
01030
01031 if (!cnstnd && col > 0)
01032 {
01033
01034 dcopy(n,x,1,z,1);
01035 wrk = updatd;
01036 nint = 0;
01037 goto goto333;
01038 }
01039
01040
01041
01042
01043
01044
01045
01046 cpu1 = timer_.time();
01047
01048 cauchy(n,x,l,u,nbd,g,indx2,iwhere,t,d,z,
01049 m,wy,ws,sy,wt,theta,col,head,
01050 &(wa[1-1]),&(wa[2*m+1-1]),&(wa[4*m+1-1]),&(wa[6*m+1-1]),nint,
01051 sg,yg,iprint,sbgnrm,info,epsmch);
01052
01053 if (info > 0)
01054 {
01055
01056 if (iprint >= 1)
01057 cout << "Singular triangular system detected; "
01058 << "refresh the lbfgs memory and restart the iteration." <<endl;
01059 info = 0;
01060 col = 0;
01061 head = 1;
01062 theta = one;
01063 iupdat = 0;
01064 updatd = false;
01065 cpu2 = timer_.time();
01066 cachyt = cachyt + cpu2 - cpu1;
01067 goto goto222;
01068 }
01069 cpu2 = timer_.time();
01070 cachyt = cachyt + cpu2 - cpu1;
01071 nintol = nintol + nint;
01072
01073
01074
01075
01076 freev(n,nfree,index,nenter,ileave,indx2,
01077 iwhere,wrk,updatd,cnstnd,iprint,iter);
01078
01079 nact = n - nfree;
01080
01081 goto333:
01082
01083
01084
01085
01086 if (nfree == 0 || col == 0) goto goto555;
01087
01088
01089
01090
01091
01092
01093
01094 cpu1 = timer_.time();
01095
01096
01097
01098
01099
01100
01101
01102 if (wrk) formk(n,nfree,index,nenter,ileave,indx2,iupdat,
01103 updatd,wn,snd,m,ws,wy,sy,theta,col,head,info);
01104
01105 if (info != 0)
01106 {
01107
01108
01109 if(iprint >= 1)
01110 cout << "Nonpositive definiteness in Cholesky factorization in formk;"
01111 << "refresh the lbfgs memory and restart the iteration." << endl;
01112 info = 0;
01113 col = 0;
01114 head = 1;
01115 theta = one;
01116 iupdat = 0;
01117 updatd = false;
01118 cpu2 = timer_.time() ;
01119 sbtime = sbtime + cpu2 - cpu1;
01120 goto goto222;
01121 }
01122
01123
01124
01125 cmprlb(n,m,x,g,ws,wy,sy,wt,z,r,wa,index,
01126 theta,col,head,nfree,cnstnd,info);
01127
01128 if (info != 0) goto goto444;
01129
01130 subsm(n,m,nfree,index,l,u,nbd,z,r,ws,wy,theta,
01131 col,head,iword,wa,wn,iprint,info);
01132
01133
01134 goto444:
01135 if (info != 0)
01136 {
01137
01138
01139 if(iprint >= 1)
01140 cout << "Singular triangular system detected; "
01141 << "refresh the lbfgs memory and restart the iteration." <<endl;
01142 info = 0;
01143 col = 0;
01144 head = 1;
01145 theta = one;
01146 iupdat = 0;
01147 updatd = false;
01148 cpu2 = timer_.time();
01149 sbtime = sbtime + cpu2 - cpu1;
01150 goto goto222;
01151 }
01152
01153 cpu2 = timer_.time();
01154 sbtime = sbtime + cpu2 - cpu1 ;
01155 goto555:
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165 for (int i = 1; i <= n; i++)
01166 d[i] = z[i] - x[i];
01167
01168 cpu1 = timer_.time();
01169 goto66:
01170
01171 lnsrlb(n,l,u,nbd,x,f,fold,gd,gdold,g,d,r,t,z,stp,dnorm,
01172 dtd,xstep,stpmx,iter,ifun,iback,nfgv,info,task,
01173 boxed,cnstnd,csave,&(isave[22-1]),&(dsave[17-1]));
01174
01175 if (info != 0 || iback >= 20)
01176 {
01177
01178 dcopy(n,t,1,x,1);
01179 dcopy(n,r,1,g,1);
01180 f = fold;
01181 if (col == 0)
01182 {
01183
01184 if (info == 0)
01185 {
01186 info = -9;
01187
01188 nfgv -= 1;
01189 ifun -= 1;
01190 iback -= 1;
01191 }
01192 strcpy(task, "ABNORMAL_TERMINATION_IN_LNSRCH");
01193 iter += 1;
01194 goto goto999;
01195 }
01196 else
01197 {
01198
01199 if(iprint >= 1)
01200 cout << "Bad direction in the line search; "
01201 << "the lbfgs memory and restart the iteration" << endl;
01202 if (info == 0) nfgv = nfgv - 1;
01203 info = 0;
01204 col = 0;
01205 head = 1;
01206 theta = one;
01207 iupdat = 0;
01208 updatd = false;
01209 strcpy(task, "RESTART_FROM_LNSRCH");
01210 cpu2 = timer_.time();
01211 lnscht += cpu2 - cpu1;
01212 goto goto222;
01213 }
01214 }
01215 else
01216 if (strncmp(task,"FG_LN",5)==0)
01217 {
01218
01219 goto goto1000;
01220 }
01221 else
01222 {
01223
01224 cpu2 = timer_.time() ;
01225 lnscht += cpu2 - cpu1;
01226 iter += 1;
01227
01228
01229
01230 projgr(n,l,u,nbd,x,g,sbgnrm);
01231
01232
01233
01234 prn2lb(n,x,f,g,iprint,itfile,iter,nfgv,nact,
01235 sbgnrm,nint,word,iword,iback,stp,xstep);
01236 goto goto1000;
01237 }
01238 goto777:
01239
01240
01241
01242 if (sbgnrm <= pgtol)
01243 {
01244
01245 strcpy(task, "CONVERGENCE: NORM OF PROJECTED GRADIENT <= PGTOL");
01246 goto goto999;
01247 }
01248
01249 ddum = max(fabs(fold), fabs(f), one);
01250 if ((fold - f) <= tol*ddum)
01251 {
01252
01253 strcpy(task, "CONVERGENCE: REL_REDUCTION_OF_F <= FACTR*EPSMCH");
01254 if (iback >= 10) info = -5;
01255
01256 goto goto999;
01257 }
01258
01259
01260
01261 for (int i = 1; i <= n; i++)
01262 r[i] = g[i] - r[i];
01263 rr = ddot(n,r,1,r,1);
01264 if (stp == one)
01265 {
01266 dr = gd - gdold;
01267 ddum = -gdold;
01268 }
01269 else
01270 {
01271 dr = (gd - gdold)*stp;
01272 dscal(n,stp,d,1);
01273 ddum = -gdold*stp;
01274 }
01275
01276 if (dr <= epsmch*ddum)
01277 {
01278
01279 nskip = nskip + 1;
01280 updatd = false;
01281 if (iprint >= 1)
01282 cout << " ys=" << dr << " -gs=" <<ddum<<" BFSG update SKIPPED"<<endl;
01283 goto goto888;
01284 }
01285
01286
01287
01288
01289
01290
01291
01292 updatd = true;
01293 iupdat += 1;
01294
01295
01296
01297 matupd(n,m,ws,wy,sy,ss,d,r,itail,
01298 iupdat,col,head,theta,rr,dr,stp,dtd);
01299
01300
01301
01302
01303
01304
01305 formt(m,wt,sy,ss,col,theta,info);
01306
01307 if (info != 0)
01308 {
01309
01310
01311 if(iprint >= 1)
01312 cout << "Nonpositive definiteness in Cholesky factorization in formt; "
01313 << "refresh the lbfgs memory and restart the iteration." << endl;
01314 info = 0;
01315 col = 0;
01316 head = 1;
01317 theta = one;
01318 iupdat = 0;
01319 updatd = false;
01320 goto goto222;
01321 }
01322
01323
01324
01325
01326
01327
01328 goto888:
01329
01330
01331
01332 goto goto222;
01333
01334 goto999:
01335 time2 = timer_.time();
01336 time = time2 - time1;
01337 prn3lb(n,x,f,task,iprint,info,itfile,
01338 iter,nfgv,nintol,nskip,nact,sbgnrm,
01339 time,nint,word,iback,stp,xstep,k,
01340 cachyt,sbtime,lnscht);
01341 goto1000:
01342
01343
01344 lsave[1] = prjctd;
01345 lsave[2] = cnstnd;
01346 lsave[3] = boxed;
01347 lsave[4] = updatd;
01348
01349 isave[1] = nintol;
01350
01351 isave[4] = iback;
01352 isave[5] = nskip;
01353 isave[6] = head;
01354 isave[7] = col;
01355 isave[8] = itail;
01356 isave[9] = iter;
01357 isave[10] = iupdat;
01358 isave[12] = nint;
01359 isave[13] = nfgv;
01360 isave[14] = info;
01361 isave[15] = ifun;
01362 isave[16] = iword;
01363 isave[17] = nfree;
01364 isave[18] = nact;
01365 isave[19] = ileave;
01366 isave[20] = nenter;
01367
01368 dsave[1] = theta;
01369 dsave[2] = fold;
01370 dsave[3] = tol;
01371 dsave[4] = dnorm;
01372 dsave[5] = epsmch;
01373 dsave[6] = cpu1;
01374 dsave[7] = cachyt;
01375 dsave[8] = sbtime;
01376 dsave[9] = lnscht;
01377 dsave[10] = time1;
01378 dsave[11] = gd;
01379 dsave[12] = stpmx;
01380 dsave[13] = sbgnrm;
01381 dsave[14] = stp;
01382 dsave[15] = gdold;
01383 dsave[16] = dtd;
01384
01385 }
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415 void active(const int& n, const double* const & l,
01416 const double* const & u, const int* const & nbd,
01417 double* const & x, int* const & iwhere, const int& iprint,
01418 bool& prjctd, bool& cnstnd, bool& boxed)
01419 {
01420
01421 int nbdd;
01422 double zero=0.0;
01423
01424
01425 nbdd = 0;
01426 prjctd = false;
01427 cnstnd = false;
01428 boxed = true;
01429
01430
01431
01432 for (int i = 1; i <= n; i++)
01433 {
01434 if (nbd[i] > 0)
01435 {
01436 if (nbd[i] <= 2 && x[i] <= l[i])
01437 {
01438 if (x[i] < l[i])
01439 {
01440 prjctd = true;
01441 x[i] = l[i];
01442 }
01443 nbdd += 1;
01444 }
01445 else
01446 if (nbd[i] >= 2 && x[i] >= u[i])
01447 {
01448 if (x[i] > u[i])
01449 {
01450 prjctd = true;
01451 x[i] = u[i];
01452 }
01453 nbdd += 1;
01454 }
01455 }
01456 }
01457
01458
01459
01460 for (int i = 1; i <= n; i++)
01461 {
01462 if (nbd[i] != 2) boxed = false;
01463 if (nbd[i] == 0)
01464 {
01465
01466 iwhere[i] = -1;
01467
01468 }
01469 else
01470 {
01471 cnstnd = true;
01472 if (nbd[i] == 2 && (u[i]-l[i]) <= zero)
01473 {
01474
01475 iwhere[i] = 3;
01476 }
01477 else
01478 iwhere[i] = 0;
01479 }
01480 }
01481
01482 if (iprint >= 0)
01483 {
01484 if (prjctd)
01485 cout << "The initial X is infeasible. Restart with its projection."
01486 << endl;
01487 if (!cnstnd) cout << "This problem is unconstrained." << endl;
01488 }
01489
01490 if (iprint > 0)
01491 cout << "At X0 " << nbdd << " variables are exactly at the bounds" <<endl;
01492 }
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553 void bmv(const int& m, double* const & sy, double* const & wt,
01554 const int& col, const double* const & v, double* const & p,
01555 int& info)
01556 {
01557
01558 int i2;
01559 double sum;
01560
01561 if (col == 0) return;
01562
01563
01564
01565
01566
01567 p[col+1] = v[col+1];
01568
01569 for (int i = 2; i <= col; i++)
01570 {
01571 i2 = col + i;
01572 sum = 0;
01573 for (int k = 1; k <= i-1; k++)
01574 sum += sy[getIdx(i,k,m)]*v[k]/sy[getIdx(k,k,m)];
01575
01576 p[i2] = v[i2] + sum;
01577 }
01578
01579
01580 dtrsl(wt,m,col,&(p[col+1-1]),11,info);
01581 if (info != 0) return;
01582
01583
01584 for (int i = 1; i <= col; i++)
01585 p[i] = v[i]/sqrt(sy[getIdx(i,i,m)]);
01586
01587
01588
01589
01590
01591 dtrsl(wt,m,col,&(p[col+1-1]),1,info);
01592 if (info != 0) return;
01593
01594
01595
01596 for (int i = 1; i <= col; i++)
01597 p[i] = -p[i]/sqrt(sy[getIdx(i,i,m)]);
01598
01599 for (int i = 1; i <= col; i++)
01600 {
01601 sum = 0;
01602 for (int k = i+1; i <= col; i++)
01603 sum += sy[getIdx(k,i,m)]*p[col+k]/sy[getIdx(i,i,m)];
01604 p[i] += sum;
01605 }
01606 }
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786 void cauchy(const int& n, const double* const & x,
01787 const double* const & l, const double* const & u,
01788 const int* const & nbd, const double* const & g,
01789 int* const & iorder, int* const & iwhere,
01790 double* const & t, double* const & d, double* const & xcp,
01791 const int& m, double* const & wy,
01792 double* const & ws, double* const & sy,
01793 double* const & wt, double& theta,
01794 const int& col, const int& head, double* const & p,
01795 double* const & c, double* const & wbp,
01796 double* const & v, int& nint, const double* const & sg,
01797 const double* const & yg, const int& iprint,
01798 const double& sbgnrm, int& info, const double& epsmch)
01799 {
01800 bool xlower,xupper,bnded;
01801
01802 int col2,nfree,nbreak,pointr,
01803 ibp,nleft,ibkmin,iter;
01804 double f1,f2,dt,dtm,tsum,dibp,zibp,dibp2,bkmin,
01805 tu=0,tl=0,wmc,wmp,wmw,tj,tj0,neggi,
01806 f2_org;
01807 double one=1,zero=0;
01808
01809
01810
01811
01812
01813 if (sbgnrm <= zero)
01814 {
01815 if (iprint >= 0) cout << "Subgnorm = 0. GCP = X." << endl;
01816 dcopy(n,x,1,xcp,1);
01817 return;
01818 }
01819 bnded = true;
01820 nfree = n + 1;
01821 nbreak = 0;
01822 ibkmin = 0;
01823 bkmin = zero;
01824 col2 = 2*col;
01825 f1 = zero;
01826 if (iprint >= 99)
01827 cout << "---------------- CAUCHY entered-------------------" << endl;
01828
01829
01830 for (int i = 1; i <= col2; i++)
01831 p[i] = zero;
01832
01833
01834
01835
01836
01837 for (int i = 1; i <= n; i++)
01838 {
01839 neggi = -g[i];
01840 if (iwhere[i] != 3 && iwhere[i] != -1)
01841 {
01842
01843
01844 if (nbd[i] <= 2) tl = x[i] - l[i];
01845 if (nbd[i] >= 2) tu = u[i] - x[i];
01846
01847
01848
01849 xlower = (nbd[i] <= 2 && tl <= zero);
01850 xupper = (nbd[i] >= 2 && tu <= zero);
01851
01852
01853 iwhere[i] = 0;
01854 if (xlower)
01855 {
01856 if (neggi <= zero) iwhere[i] = 1;
01857 }
01858 else
01859 if (xupper)
01860 {
01861 if (neggi >= zero) iwhere[i] = 2;
01862 }
01863 else
01864 {
01865 if (fabs(neggi) <= zero) iwhere[i] = -3;
01866 }
01867 }
01868 pointr = head;
01869 if (iwhere[i] != 0 && iwhere[i] != -1)
01870 d[i] = zero;
01871 else
01872 {
01873 d[i] = neggi;
01874 f1 -= neggi*neggi;
01875
01876 for (int j = 1; j <= col; j++)
01877 {
01878 p[j] += wy[getIdx(i,pointr,n)] * neggi;
01879 p[col + j] += ws[getIdx(i,pointr,n)] * neggi;
01880 pointr = pointr%m + 1;
01881 }
01882 if (nbd[i] <= 2 && nbd[i] != 0 && neggi < zero)
01883 {
01884
01885 nbreak += 1;
01886 iorder[nbreak] = i;
01887 t[nbreak] = tl/(-neggi);
01888 if (nbreak == 1 || t[nbreak] < bkmin)
01889 {
01890 bkmin = t[nbreak];
01891 ibkmin = nbreak;
01892 }
01893 }
01894 else
01895 if (nbd[i] >= 2 && neggi > zero)
01896 {
01897
01898 nbreak += 1;
01899 iorder[nbreak] = i;
01900 t[nbreak] = tu/neggi;
01901 if (nbreak == 1 || t[nbreak] < bkmin)
01902 {
01903 bkmin = t[nbreak];
01904 ibkmin = nbreak;
01905 }
01906 }
01907 else
01908 {
01909
01910 nfree -= 1;
01911 iorder[nfree] = i;
01912 if (fabs(neggi) > zero) bnded = false;
01913 }
01914 }
01915 }
01916
01917
01918
01919
01920
01921
01922 if (theta != one)
01923 {
01924
01925 dscal(col,theta,&(p[col+1-1]),1);
01926 }
01927
01928
01929
01930 dcopy(n,x,1,xcp,1);
01931
01932 if (nbreak == 0 && nfree == n + 1)
01933 {
01934
01935 if (iprint > 100)
01936 {
01937 cout << "Cauchy X = ";
01938 for (int i = 1; i <= n; i++)
01939 cout << xcp[i] << " ";
01940 cout << endl;
01941 }
01942 return;
01943 }
01944
01945
01946
01947 for (int j = 1; j <= col2; j++)
01948 c[j] = zero;
01949
01950
01951
01952 f2 = -theta*f1;
01953 f2_org = f2;
01954 if (col > 0)
01955 {
01956 bmv(m,sy,wt,col,p,v,info);
01957 if (info != 0) return;
01958 f2 -= ddot(col2,v,1,p,1);
01959 }
01960 dtm = -f1/f2;
01961 tsum = zero;
01962 nint = 1;
01963 if (iprint >= 99)
01964 cout << "There are " << nbreak << " breakpoints" << endl;
01965
01966
01967
01968 if (nbreak == 0) goto goto888;
01969
01970 nleft = nbreak;
01971 iter = 1;
01972
01973 tj = zero;
01974
01975
01976
01977 goto777:
01978
01979
01980
01981
01982 tj0 = tj;
01983 if (iter == 1)
01984 {
01985
01986
01987
01988 tj = bkmin;
01989 ibp = iorder[ibkmin];
01990 }
01991 else
01992 {
01993 if (iter == 2)
01994 {
01995
01996
01997 if (ibkmin != nbreak)
01998 {
01999 t[ibkmin] = t[nbreak];
02000 iorder[ibkmin] = iorder[nbreak];
02001 }
02002
02003
02004 }
02005
02006 hpsolb(nleft,t,iorder,iter-2);
02007 tj = t[nleft];
02008 ibp = iorder[nleft];
02009 }
02010
02011 dt = tj - tj0;
02012
02013 if (dt != zero && iprint >= 100)
02014 {
02015 cout << "Piece " << nint << " --f1, f2 at start point "
02016 << f1 << "," << f2 << endl;
02017 cout << "Distance to the next break point = " << dt << endl;
02018 cout << "Distance to the stationary point = " << dtm << endl;
02019 }
02020
02021
02022
02023 if (dtm < dt) goto goto888;
02024
02025
02026
02027
02028 tsum += dt;
02029 nleft -= 1;
02030 iter += 1;
02031 dibp = d[ibp];
02032 d[ibp] = zero;
02033 if (dibp > zero)
02034 {
02035 zibp = u[ibp] - x[ibp];
02036 xcp[ibp] = u[ibp];
02037 iwhere[ibp] = 2;
02038 }
02039 else
02040 {
02041 zibp = l[ibp] - x[ibp];
02042 xcp[ibp] = l[ibp];
02043 iwhere[ibp] = 1;
02044 }
02045 if (iprint >= 100) cout << "Variable " << ibp << " is fixed." << endl;
02046 if (nleft == 0 && nbreak == n)
02047 {
02048
02049 dtm = dt;
02050 goto goto999;
02051 }
02052
02053
02054
02055 nint += 1;
02056 dibp2 = dibp*dibp;
02057
02058
02059
02060
02061 f1 += dt*f2 + dibp2 - theta*dibp*zibp;
02062 f2 -= theta*dibp2;
02063
02064 if (col > 0)
02065 {
02066
02067 daxpy(col2,dt,p,1,c,1);
02068
02069
02070
02071 pointr = head;
02072 for (int j = 1; j <= col; j++)
02073 {
02074 wbp[j] = wy[getIdx(ibp,pointr,n)];
02075 wbp[col + j] = theta*ws[getIdx(ibp,pointr,n)];
02076 pointr = pointr%m + 1;
02077 }
02078
02079 bmv(m,sy,wt,col,wbp,v,info);
02080 if (info != 0) return;
02081 wmc = ddot(col2,c,1,v,1);
02082 wmp = ddot(col2,p,1,v,1);
02083 wmw = ddot(col2,wbp,1,v,1);
02084
02085
02086 daxpy(col2,-dibp,wbp,1,p,1);
02087
02088
02089 f1 += dibp*wmc;
02090 f2 += 2.0*dibp*wmp - dibp2*wmw;
02091 }
02092
02093 f2 = max(epsmch*f2_org,f2);
02094 if (nleft > 0)
02095 {
02096 dtm = -f1/f2;
02097 goto goto777;
02098
02099 }
02100 else
02101 if(bnded)
02102 {
02103 f1 = zero;
02104 f2 = zero;
02105 dtm = zero;
02106 }
02107 else
02108 dtm = -f1/f2;
02109
02110
02111
02112 goto888:
02113 if (iprint >= 99)
02114 {
02115 cout << endl << "GCP found in this segment" << endl
02116 << "Piece " << nint << " --f1, f2 at start point "
02117 << f1 << "," << f2 << endl
02118 << "Distance to the stationary point = " << dtm << endl;
02119 }
02120
02121 if (dtm <= zero) dtm = zero;
02122 tsum += dtm;
02123
02124
02125
02126
02127 daxpy(n,tsum,d,1,xcp,1);
02128
02129 goto999:
02130
02131
02132
02133
02134 if (col > 0) daxpy(col2,dtm,p,1,c,1);
02135 if (iprint > 100)
02136 {
02137 cout<< "Cauchy X = ";
02138 for (int i = 1; i <=n; i++)
02139 cout << xcp[i] << " ";
02140 cout << endl;
02141 }
02142 if (iprint >= 99)
02143 cout << "---------------- exit CAUCHY----------------------" << endl;
02144 }
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171 void cmprlb(const int& n, const int& m, const double* const & x,
02172 const double* const & g, double* const & ws,
02173 double* const & wy, double* const & sy,
02174 double* const & wt, const double* const & z,
02175 double* const & r, double* const & wa,
02176 const int* const & index, const double& theta,
02177 const int& col, const int& head, const int& nfree,
02178 const bool& cnstnd, int& info)
02179 {
02180
02181 int k,pointr,idx;
02182 double a1,a2;
02183
02184 if (!cnstnd && col > 0)
02185 {
02186 for (int i = 1; i <= n; i++)
02187 r[i] = -g[i];
02188 }
02189 else
02190 {
02191 for (int i = 1; i <= nfree; i++)
02192 {
02193 k = index[i];
02194 r[i] = -theta*(z[k] - x[k]) - g[k];
02195 }
02196 bmv(m,sy,wt,col,&(wa[2*m+1-1]),&(wa[1-1]),info);
02197 if (info != 0)
02198 {
02199 info = -8;
02200 return;
02201 }
02202 pointr = head;
02203 for (int j = 1; j <= col; j++)
02204 {
02205 a1 = wa[j];
02206 a2 = theta*wa[col + j];
02207 for (int i = 1; i <= nfree; i++)
02208 {
02209 k = index[i];
02210 idx = getIdx(k,pointr,n);
02211 r[i] += wy[idx]*a1 + ws[idx]*a2;
02212 }
02213
02214 pointr = pointr%m + 1;
02215 }
02216 }
02217 }
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239 void errclb(const int& n, const int& m, const double& factr,
02240 const double* const & l, const double* const & u,
02241 const int* const & nbd, char* const & task, int& info,
02242 int& k)
02243 {
02244
02245
02246 double zero=0.0;
02247
02248
02249
02250 if (n <= 0) strcpy(task,"ERROR: N <= 0");
02251 if (m <= 0) strcpy(task,"ERROR: M <= 0");
02252 if (factr < zero) strcpy(task,"ERROR: FACTR < 0");
02253
02254
02255 for (int i = 1; i <= n; i++)
02256 {
02257 if (nbd[i] < 0 || nbd[i] > 3)
02258 {
02259
02260 strcpy(task,"ERROR: INVALID NBD");
02261 info = -6;
02262 k = i;
02263 }
02264 if (nbd[i] == 2)
02265 {
02266 if (l[i] > u[i])
02267 {
02268
02269 strcpy(task, "ERROR: NO FEASIBLE SOLUTION");
02270 info = -7;
02271 k = i;
02272 }
02273 }
02274 }
02275 }
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
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
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401 void formk(const int& n, const int& nsub, const int* const & ind,
02402 const int& nenter, const int& ileave,
02403 const int* const & indx2, const int& iupdat,
02404 const bool& updatd, double* const & wn,
02405 double* const & wn1, const int& m,
02406 double* const & ws, double* const & wy,
02407 double* const & sy, const double& theta,
02408 const int& col, const int& head, int& info)
02409 {
02410
02411 int m2,ipntr,jpntr,iy,is,jy,js,is1,js1,k1,
02412 col2,pbegin,pend,dbegin,dend,upcl;
02413 int idx1, idx2;
02414 double temp1,temp2,temp3,temp4;
02415
02416 double zero=0.0;
02417
02418 m2 = 2*m;
02419
02420
02421
02422
02423
02424
02425
02426 if (updatd)
02427 {
02428 if (iupdat > m)
02429 {
02430
02431 for (int jy = 1; jy <= m-1; jy++)
02432 {
02433 js = m + jy;
02434 dcopy(m-jy,&(wn1[getIdx(jy+1,jy+1,m2)-1]),1,
02435 &(wn1[getIdx(jy,jy,m2)-1]),1);
02436 dcopy(m-jy,&(wn1[getIdx(js+1,js+1,m2)-1]),1,
02437 &(wn1[getIdx(js,js,m2)-1]), 1);
02438 dcopy(m-1, &(wn1[getIdx(m+2,jy+1,m2)-1]), 1,
02439 &(wn1[getIdx(m+1,jy,m2)-1]),1);
02440 }
02441 }
02442
02443
02444 pbegin = 1;
02445 pend = nsub;
02446 dbegin = nsub + 1;
02447 dend = n;
02448 iy = col;
02449 is = m + col;
02450 ipntr = head + col - 1;
02451 if (ipntr > m) ipntr -= m ;
02452 jpntr = head;
02453
02454 for (jy = 1; jy <= col; jy++)
02455 {
02456 js = m + jy;
02457 temp1 = zero;
02458 temp2 = zero;
02459 temp3 = zero;
02460
02461 for (int k = pbegin; k <= pend; k++)
02462 {
02463 k1 = ind[k];
02464 temp1 += wy[getIdx(k1,ipntr,n)]*wy[getIdx(k1,jpntr,n)];
02465 }
02466
02467 for (int k = dbegin; k <= dend; k++)
02468 {
02469 k1 = ind[k];
02470 idx1 = getIdx(k1,ipntr,n);
02471 idx2 = getIdx(k1,jpntr,n);
02472 temp2 += ws[idx1] * ws[idx2];
02473 temp3 += ws[idx1] * wy[idx2];
02474 }
02475 wn1[getIdx(iy,jy,m2)] = temp1;
02476 wn1[getIdx(is,js,m2)] = temp2;
02477 wn1[getIdx(is,jy,m2)] = temp3;
02478 jpntr = jpntr%m + 1;
02479 }
02480
02481
02482 jy = col;
02483 jpntr = head + col - 1;
02484 if (jpntr > m) jpntr -= m;
02485 ipntr = head;
02486 for (int i = 1; i <= col; i++)
02487 {
02488 is = m + i;
02489 temp3 = zero;
02490
02491 for (int k = pbegin; k <= pend; k++)
02492 {
02493 k1 = ind[k];
02494 temp3 += ws[getIdx(k1,ipntr,n)]*wy[getIdx(k1,jpntr,n)];
02495 }
02496 ipntr = ipntr%m + 1;
02497 wn1[getIdx(is,jy,m2)] = temp3;
02498 }
02499 upcl = col - 1;
02500 }
02501 else
02502 upcl = col;
02503
02504
02505
02506 ipntr = head;
02507
02508 for (int iy = 1; iy <= upcl; iy++)
02509 {
02510 is = m + iy;
02511 jpntr = head;
02512
02513 for (int jy = 1; jy <= iy; jy++)
02514 {
02515 js = m + jy;
02516 temp1 = zero;
02517 temp2 = zero;
02518 temp3 = zero;
02519 temp4 = zero;
02520 for (int k = 1; k <= nenter; k++)
02521 {
02522 k1 = indx2[k];
02523 idx1 = getIdx(k1,ipntr,n);
02524 idx2 = getIdx(k1,jpntr,n);
02525 temp1 += wy[idx1]*wy[idx2];
02526 temp2 += ws[idx1]*ws[idx2];
02527 }
02528 for (int k = ileave; k <= n; k++)
02529 {
02530 k1 = indx2[k];
02531 idx1 = getIdx(k1,ipntr,n);
02532 idx2 = getIdx(k1,jpntr,n);
02533 temp3 += wy[idx1]*wy[idx2];
02534 temp4 += ws[idx1]*ws[idx2];
02535 }
02536 wn1[getIdx(iy,jy,m2)] += temp1 - temp3;
02537 wn1[getIdx(is,js,m2)] += temp4 - temp2;
02538 jpntr = jpntr%m + 1;
02539 }
02540 ipntr = ipntr%m + 1;
02541 }
02542
02543 ipntr = head;
02544
02545 for (int is = m+1; is <= m + upcl; is++)
02546 {
02547 jpntr = head;
02548 for (int jy = 1; jy <= upcl; jy++)
02549 {
02550 temp1 = zero;
02551 temp3 = zero;
02552
02553 for (int k = 1; k <= nenter; k++)
02554 {
02555 k1 = indx2[k];
02556 temp1 += ws[getIdx(k1,ipntr,n)]*wy[getIdx(k1,jpntr,n)];
02557 }
02558 for (int k = ileave; k <= n; k++)
02559 {
02560 k1 = indx2[k];
02561 temp3 += ws[getIdx(k1,ipntr,n)]*wy[getIdx(k1,jpntr,n)];
02562 }
02563 if (is <= jy + m)
02564 wn1[getIdx(is,jy,m2)] += temp1 - temp3;
02565 else
02566 wn1[getIdx(is,jy,m2)] += temp3 - temp1;
02567
02568 jpntr = jpntr%m + 1;
02569 }
02570 ipntr = ipntr%m + 1;
02571 }
02572
02573
02574
02575 for (int iy = 1; iy <= col; iy++)
02576 {
02577 is = col + iy;
02578 is1 = m + iy;
02579 for (int jy = 1; jy <= iy; jy++)
02580 {
02581 js = col + jy;
02582 js1 = m + jy;
02583 wn[getIdx(jy,iy,m2)] = wn1[getIdx(iy,jy,m2)]/theta;
02584 wn[getIdx(js,is,m2)] = wn1[getIdx(is1,js1,m2)]*theta;
02585 }
02586
02587 for (int jy = 1; jy <= iy-1; jy++)
02588 wn[getIdx(jy,is,m2)] = -wn1[getIdx(is1,jy,m2)];
02589
02590 for (int jy = iy; jy <= col; jy++)
02591 wn[getIdx(jy,is,m2)] = wn1[getIdx(is1,jy,m2)];
02592 wn[getIdx(iy,iy,m2)] += sy[getIdx(iy,iy,m)];
02593 }
02594
02595
02596
02597
02598
02599
02600 dpofa(wn,m2,col,info);
02601 if (info != 0)
02602 {
02603 info = -1;
02604 return;
02605 }
02606
02607
02608 col2 = 2*col;
02609 for (int js = col+1; js <= col2; js++)
02610 dtrsl(wn,m2,col,&(wn[getIdx(1,js,m2)-1]),11,info);
02611
02612
02613
02614
02615
02616
02617 for (int is = col+1; is <= col2; is++)
02618 for (int js = is; js <= col2; js++)
02619 wn[getIdx(is,js,m2)] += ddot(col,&(wn[getIdx(1,is,m2)-1]),1,
02620 &(wn[getIdx(1,js,m2)-1]),1);
02621
02622
02623 dpofa(&(wn[getIdx(col+1,col+1,m2)-1]),m2,col,info);
02624
02625 if (info != 0)
02626 {
02627 info = -2;
02628 return;
02629 }
02630 }
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659 void formt(const int& m, double* const & wt, double* const& sy,
02660 double* const & ss, const int& col, const double& theta,
02661 int& info)
02662 {
02663
02664 int k1, idx;
02665 double ddum;
02666 double zero=0.0;
02667
02668
02669
02670 for (int j = 1; j <= col; j++)
02671 {
02672 idx = getIdx(1,j,m);
02673 wt[idx] = theta*ss[idx];
02674 }
02675
02676 for (int i = 2; i <= col; i++)
02677 for (int j = i; j <= col; j++)
02678 {
02679 k1 = min(i,j) - 1;
02680 ddum = zero;
02681 for (int k = 1; k <= k1; k++)
02682 ddum += sy[getIdx(i,k,m)]*sy[getIdx(j,k,m)]/sy[getIdx(k,k,m)];
02683 wt[getIdx(i,j,m)] = ddum + theta*ss[getIdx(i,j,m)];
02684 }
02685
02686
02687
02688
02689 dpofa(wt,m,col,info);
02690 if (info != 0) info = -3;
02691 }
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732 void freev(const int& n, int& nfree, int* const & index, int& nenter,
02733 int& ileave, int* const & indx2, int* const & iwhere,
02734 bool& wrk, const bool& updatd, const bool& cnstnd,
02735 const int& iprint, const int& iter)
02736 {
02737
02738 int iact,k;
02739
02740 nenter = 0;
02741 ileave = n + 1;
02742 if (iter > 0 && cnstnd)
02743 {
02744
02745 for (int i = 1; i <= nfree; i++)
02746 {
02747 k = index[i];
02748 if (iwhere[k] > 0)
02749 {
02750 ileave -= 1;
02751 indx2[ileave] = k;
02752 if (iprint >= 100)
02753 cout << "Variable " << k<<" leaves the set of free variables"<<endl;
02754 }
02755 }
02756
02757 for (int i = 1+nfree; i <= n; i++)
02758 {
02759 k = index[i];
02760 if (iwhere[k] <= 0)
02761 {
02762 nenter += 1;
02763 indx2[nenter] = k;
02764 if (iprint >= 100)
02765 cout << "Variable " << k<<" enters the set of free variables"<<endl;
02766 }
02767 }
02768 if (iprint >= 99)
02769 cout << n+1-ileave << " variables leave; "
02770 << nenter << " variables enter" << endl;
02771 }
02772 wrk = (ileave < n+1) || (nenter > 0) || updatd;
02773
02774
02775
02776 nfree = 0;
02777 iact = n + 1;
02778 for (int i = 1; i <= n; i++)
02779 {
02780 if (iwhere[i] <= 0)
02781 {
02782 nfree += 1;
02783 index[nfree] = i;
02784 }
02785 else
02786 {
02787 iact -= 1;
02788 index[iact] = i;
02789 }
02790 }
02791
02792 if (iprint >= 99)
02793 cout << nfree << " variables are free at GCP " << iter + 1 << endl;
02794 }
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839 void hpsolb(const int& n, double* const & t, int* const & iorder,
02840 const int& iheap)
02841 {
02842
02843 int i,j,indxin,indxou;
02844 double ddum,out;
02845
02846 if (iheap == 0)
02847 {
02848
02849 for (int k = 2; k <= n; k++)
02850 {
02851 ddum = t[k];
02852 indxin = iorder[k];
02853
02854
02855 i = k;
02856 goto10:
02857 if (i>1)
02858 {
02859 j = i/2;
02860 if (ddum < t[j])
02861 {
02862 t[i] = t[j];
02863 iorder[i] = iorder[j];
02864 i = j;
02865 goto goto10;
02866 }
02867
02868 }
02869 t[i] = ddum;
02870 iorder[i] = indxin;
02871 }
02872 }
02873
02874
02875
02876
02877
02878 if (n > 1)
02879 {
02880 i = 1;
02881 out = t[1];
02882 indxou = iorder[1];
02883 ddum = t[n];
02884 indxin = iorder[n];
02885
02886
02887 goto30:
02888 j = i+i;
02889 if (j <= n-1)
02890 {
02891 if (t[j+1] < t[j]) j = j+1;
02892 if (t[j] < ddum )
02893 {
02894 t[i] = t[j];
02895 iorder[i] = iorder[j];
02896 i = j;
02897 goto goto30;
02898 }
02899 }
02900 t[i] = ddum;
02901 iorder[i] = indxin;
02902
02903
02904
02905 t[n] = out;
02906 iorder[n] = indxou;
02907 }
02908 }
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938 void lnsrlb(const int& n, const double* const & l, const double* const & u,
02939 const int* const& nbd, double* const & x, double& f,
02940 double& fold, double& gd, double& gdold, double* const& g,
02941 double* const& d, double* const& r, double* const& t,
02942 double* const& z, double& stp, double& dnorm, double& dtd,
02943 double& xstep, double& stpmx, const int& iter, int& ifun,
02944 int& iback, int& nfgv, int& info, char* const & task,
02945 const bool& boxed, const bool& cnstnd, char* const & csave,
02946 int* const & isave, double* const & dsave)
02947 {
02948
02949 double a1,a2;
02950 double one=1.0,zero=0.0,big=1e10;
02951 double ftol=1.0e-3,gtol=0.9,xtol=0.1;
02952
02953
02954 if (strncmp(task,"FG_LN",5)==0) goto goto556;
02955
02956 dtd = ddot(n,d,1,d,1);
02957 dnorm = sqrt(dtd);
02958
02959
02960
02961 stpmx = big;
02962 if (cnstnd)
02963 {
02964 if (iter == 0)
02965 stpmx = one;
02966 else
02967 {
02968 for (int i = 1; i <= n; i++)
02969 {
02970 a1 = d[i];
02971 if (nbd[i] != 0)
02972 {
02973 if (a1 < zero && nbd[i] <= 2)
02974 {
02975 a2 = l[i] - x[i];
02976 if (a2 >= zero)
02977 stpmx = zero;
02978 else
02979 if (a1*stpmx < a2)
02980 stpmx = a2/a1;
02981 }
02982 else
02983 if (a1 > zero && nbd[i] >= 2)
02984 {
02985 a2 = u[i] - x[i];
02986 if (a2 <= zero)
02987 stpmx = zero;
02988 else
02989 if (a1*stpmx > a2)
02990 stpmx = a2/a1;
02991 }
02992 }
02993 }
02994 }
02995 }
02996
02997 if (iter == 0 && !boxed)
02998 stp = min(one/dnorm, stpmx);
02999 else
03000 stp = one;
03001
03002 dcopy(n,x,1,t,1);
03003 dcopy(n,g,1,r,1);
03004 fold = f;
03005 ifun = 0;
03006 iback = 0;
03007 strcpy(csave,"START");
03008 goto556:
03009 gd = ddot(n,g,1,d,1);
03010 if (ifun == 0)
03011 {
03012 gdold=gd;
03013 if (gd >= zero)
03014 {
03015
03016
03017 info = -4;
03018 return;
03019 }
03020 }
03021
03022 dcsrch(f,gd,stp,ftol,gtol,xtol,zero,stpmx,csave,isave,dsave);
03023
03024 xstep = stp*dnorm;
03025 if (strncmp(csave,"CONV",4) != 0 && strncmp(csave,"WARN",4) != 0)
03026 {
03027 strcpy(task,"FG_LNSRCH");
03028 ifun += 1;
03029 nfgv += 1;
03030 iback = ifun - 1;
03031 if (stp == one)
03032 dcopy(n,z,1,x,1);
03033 else
03034 {
03035 for (int i = 1; i <= n; i++)
03036 x[i] = stp*d[i] + t[i];
03037 }
03038 }
03039 else
03040 strcpy(task,"NEW_X");
03041 }
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068 void matupd(const int& n, const int& m, double* const & ws,
03069 double* const & wy, double* const & sy, double* const & ss,
03070 double* const & d, double* const & r, int& itail, int& iupdat,
03071 int& col, int& head, double& theta, double& rr, double& dr,
03072 double& stp, double& dtd)
03073 {
03074
03075 int pointr;
03076 double one=1.0;
03077 int idx;
03078
03079
03080 if (iupdat <= m)
03081 {
03082 col = iupdat;
03083 itail = (head+iupdat-2)%m + 1;
03084 }
03085 else
03086 {
03087 itail = itail%m + 1;
03088 head = head%m + 1;
03089 }
03090
03091
03092 idx = getIdx(1,itail,n)-1;
03093 dcopy(n,d,1,&(ws[idx]),1);
03094 dcopy(n,r,1,&(wy[idx]),1);
03095
03096
03097 theta = rr/dr;
03098
03099
03100
03101
03102 if (iupdat > m)
03103 {
03104
03105 for (int j = 1; j <= col-1; j++)
03106 {
03107 dcopy(j,&(ss[getIdx(2,j+1,m)-1]),1,&(ss[getIdx(1,j,m)-1]),1);
03108 dcopy(col-j,&(sy[getIdx(j+1,j+1,m)-1]),1,&(sy[getIdx(j,j,m)-1]),1);
03109 }
03110 }
03111
03112
03113
03114 pointr = head;
03115 for (int j = 1; j <= col-1; j++)
03116 {
03117 idx = getIdx(1,pointr,n)-1;
03118 sy[getIdx(col,j,m)] = ddot(n,d,1,&(wy[idx]),1);
03119 ss[getIdx(j,col,m)] = ddot(n,&(ws[idx]),1,d,1);
03120 pointr = pointr%m + 1;
03121 }
03122
03123 idx = getIdx(col,col,m);
03124 if (stp == one)
03125 ss[idx] = dtd;
03126 else
03127 ss[idx] = stp*stp*dtd;
03128
03129 sy[idx] = dr;
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 void prn1lb(const int& n, const int& m, const double* const & l,
03155 const double* const & u, const double* const & x,
03156 const int& iprint, ofstream* itfile, const double& epsmch)
03157 {
03158
03159
03160 if (iprint >= 0)
03161 {
03162 cout << "RUNNING THE L-BFGS-B CODE, " << endl
03163 << "epsmch = machine precision" << endl
03164 << "it = iteration number" << endl
03165 << "nf = number of function evaluations" << endl
03166 << "nint = number of segments explored during the Cauchy search"
03167 << endl
03168 << "nact = number of active bounds at the generalized Cauchy point"
03169 << endl
03170 << "sub = manner in which the subspace minimization terminated:"
03171 << endl
03172 <<"con = converged, bnd = a bound was reached" << endl
03173 << "itls = number of iterations performed in the line search"
03174 << endl
03175 << "stepl = step length used" << endl
03176 << "tstep = norm of the displacement (total step)" << endl
03177 << "projg = norm of the projected gradient" << endl
03178 << "f = function value" << endl
03179 << "Machine precision = " << epsmch << endl;
03180 cout << "N = " << n << ", M = " << m << endl;
03181 if (iprint >= 1)
03182 {
03183 *itfile << "RUNNING THE L-BFGS-B CODE, epsmch = "
03184 << "it = iteration number" << endl
03185 << "nf = number of function evaluations" << endl
03186 <<"nint = number of segments explored during the Cauchy search"
03187 << endl
03188 <<"nact = number of active bounds at generalized Cauchy point"
03189 << endl
03190 <<"sub =manner in which the subspace minimization terminated:"
03191 << endl
03192 <<"con = converged, bnd = a bound was reached" << endl
03193 << "itls = number of iterations performed in the line search"
03194 << endl
03195 << "stepl = step length used" << endl
03196 << "tstep = norm of the displacement (total step)" << endl
03197 << "projg = norm of the projected gradient" << endl
03198 << "f = function value" << endl
03199 << "Machine precision = " << epsmch << endl;
03200 *itfile << "N = " << n << ", M = " << m << endl;
03201 *itfile << " it nf nint nact sub itls stepl tstep projg"
03202 << " f" << endl;
03203 if (iprint > 100)
03204 {
03205 cout << "L = ";
03206 for (int i = 1; i <= n; i++) cout << l[i] << " ";
03207 cout << endl;
03208 cout << "X0 = ";
03209 for (int i = 1; i <= n; i++) cout << x[i] << " ";
03210 cout << endl;
03211 cout << "U = ";
03212 for (int i = 1; i <= n; i++) cout << u[i] << " ";
03213 cout << endl;
03214 }
03215 }
03216 }
03217 }
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237
03238
03239
03240 void prn2lb(const int& n, const double* const & x, const double& f,
03241 const double* const & g, const int& iprint,
03242 ofstream* itfile, const int& iter, const int& nfgv,
03243 const int& nact, const double& sbgnrm, const int& nint,
03244 char* const & word, const int& iword, const int& iback,
03245 const double& stp, const double& xstep)
03246 {
03247
03248 int imod;
03249
03250
03251 if (iword == 0)
03252 {
03253
03254 strcpy(word, "con");
03255 }
03256 else
03257 if (iword == 1)
03258 {
03259
03260 strcpy(word, "bnd");
03261 }
03262 else
03263 if (iword == 5)
03264 {
03265
03266 strcpy(word, "TNT");
03267
03268 }
03269 else
03270 strcpy(word, "---");
03271
03272 if (iprint >= 99)
03273 {
03274 cout << "LINE SEARCH " << iback <<" times; norm of step = " <<xstep<<endl;
03275 cout << "At iterate " << iter << " f=" << f <<" |proj g|="<<sbgnrm<<endl;
03276 if (iprint > 100)
03277 {
03278 cout << "X = " << endl;
03279 for (int i = 1; i <= n; i++) cout << x[i] << " ";
03280 cout << endl;
03281 cout << "G = " << endl;
03282 for (int i = 1; i <= n; i++) cout << g[i] << " ";
03283 cout << endl;
03284 }
03285 }
03286 else
03287 if (iprint > 0)
03288 {
03289 imod = iter%iprint;
03290 if (imod == 0)
03291 cout << "At iterate " << iter << " f="<<f<< " |proj g|="<<sbgnrm<<endl;
03292 }
03293 if (iprint >= 1)
03294 *itfile << " " << iter << " " << nfgv << " " << nint << " " << nact << " "
03295 << word << " " << iback << " " << stp << " " << xstep << " "
03296 << sbgnrm << " " << f << endl;
03297 }
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321 void prn3lb(const int& n, const double* const & x, double& f,
03322 const char* const & task, const int& iprint,
03323 const int& info, ofstream* itfile, const int& iter,
03324 const int& nfgv, const int& nintol, const int& nskip,
03325 const int& nact, const double& sbgnrm, const double& time,
03326 const int& nint, const char* const & word, const int& iback,
03327 const double& stp,const double& xstep, const int& k,
03328 const double& cachyt, const double& sbtime, const double& lnscht)
03329 {
03330
03331 if (strncmp(task,"ERROR",5)==0) goto goto999;
03332
03333 if (iprint >= 0)
03334 {
03335 cout << " * * *"
03336 << "Tit = total number of iterations" << endl
03337 << "Tnf = total number of function evaluations" << endl
03338 << "Tnint = total number of segments explored during"
03339 << " Cauchy searches" << endl
03340 << "Skip = number of BFGS updates skipped" << endl
03341 << "Nact = number of active bounds at final generalized"
03342 << " Cauchy point" << endl
03343 << "Projg = norm of the final projected gradient" << endl
03344 << "F = final function value" << endl
03345 << " * * *" << endl;
03346
03347 cout << " N Tit Tnf Tnint Skip Nact Projg F" << endl;
03348 cout << " " << n << " " << iter << " " << nfgv << " " << nintol << " "
03349 << nskip << " " << nact << " " << sbgnrm << " " << f << endl;
03350 if (iprint >= 100)
03351 {
03352 cout << "X = ";
03353 for (int i = 1; i <= n; i++)
03354 cout << x[i] << " ";
03355 cout << endl;
03356 }
03357 if (iprint >= 1) cout << " F = " << f << endl;
03358 }
03359
03360 goto999:
03361
03362 if (iprint >= 0)
03363 {
03364 cout << task << endl;
03365 if (info != 0)
03366 {
03367 if (info == -1)
03368 cout << "Matrix in 1st Cholesky factorization in formk is not "
03369 << "Pos. Def." << endl;
03370 if (info == -2)
03371 cout << "Matrix in 2st Cholesky factorization in formk is not "
03372 << "Pos. Def." << endl;
03373 if (info == -3)
03374 cout << "Matrix in the Cholesky factorization in formt is not "
03375 << "Pos. Def." << endl;
03376 if (info == -4)
03377 cout << "Derivative >= 0, backtracking line search impossible."
03378 << endl << "Previous x, f and g restored." << endl
03379 << "Possible causes: 1 error in function or gradient "
03380 <<"evaluation;" << endl
03381 << "2 rounding errors dominate computation." << endl;
03382 if (info == -5)
03383 cout << "Warning: more than 10 function and gradient" << endl
03384 << "evaluations in the last line search. Termination"
03385 << "may possibly be caused by a bad search direction."<<endl;
03386 if (info == -6)
03387 cout << " Input nbd(" << k << ") is invalid."<<endl;
03388 if (info == -7)
03389 cout << " l(" << k << ") > u(" << k << "). No feasible solution."
03390 << endl;
03391 if (info == -8)
03392 cout << "The triangular system is singular" << endl;
03393 if (info == -9)
03394 cout << " Line search cannot locate an adequate point after"<<endl
03395 << " 20 function and gradient evaluations. Previous x, f and"
03396 << " g restored." << endl
03397 << "Possible causes: 1 error in function or gradient "
03398 << "evaluation; 2 rounding error dominate computation"
03399 << endl;
03400 }
03401
03402 if (iprint >= 1)
03403 cout << "Cauchy time " << cachyt << " seconds."<<endl
03404 << "Subspace minimization time " << sbtime << " seconds."<<endl
03405 << "Line search time " << lnscht << " seconds."<<endl;
03406
03407 cout << "Total User time " << time << " seconds." << endl;
03408
03409 if (iprint >= 1)
03410 {
03411 if (info == -4 || info == -9)
03412 {
03413 *itfile << " " << n << " " << iter << " " << nfgv << " " << nintol
03414 << " " << nskip << " " << nact << " " << sbgnrm << " " << f
03415 << endl;
03416 }
03417 *itfile << task << endl;
03418 if (info != 0)
03419 {
03420 if (info == -1)
03421 *itfile << "Matrix in 1st Cholesky factorization in formk is not"
03422 << " Pos. Def." << endl;
03423 if (info == -2)
03424 *itfile << "Matrix in 2st Cholesky factorization in formk is not"
03425 << " Pos. Def." << endl;
03426 if (info == -3)
03427 *itfile << "Matrix in the Cholesky factorization in formt is not"
03428 << " Pos. Def." << endl;
03429 if (info == -4)
03430 *itfile << "Derivative>=0, backtracking line search impossible."
03431 << endl << "Previous x, f and g restored." << endl
03432 << "Possible causes: 1 error in function or gradient "
03433 <<"evaluation;" << endl
03434 << "2 rounding errors dominate computation." << endl;
03435 if (info == -5)
03436 *itfile << "Warning: more than 10 function and gradient" << endl
03437 << "evaluations in the last line search. Termination"
03438 << "may possibly be caused by a bad search direction."
03439 << endl;
03440 if (info == -8)
03441 cout << "The triangular system is singular" << endl;
03442 if (info == -9)
03443 cout << " Line search cannot locate an adequate point after"
03444 << endl
03445 << " 20 function and gradient evaluations. Previous x, f "
03446 << "and g restored." << endl
03447 << "Possible causes: 1 error in function or gradient "
03448 << "evaluation; 2 rounding error dominate computation"
03449 << endl;
03450 }
03451 *itfile << "Total User time " << time << " seconds." << endl;
03452 }
03453 }
03454 }
03455
03456
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476
03477 void projgr(const int& n, const double* const & l, const double* const & u,
03478 const int* const & nbd, const double* const & x,
03479 const double* const & g, double& sbgnrm)
03480 {
03481
03482 double gi;
03483
03484 double zero=0.0;
03485
03486 sbgnrm = zero;
03487 for (int i = 1; i <= n; i++)
03488 {
03489 gi = g[i];
03490 if (nbd[i] != 0)
03491 {
03492 if (gi < zero)
03493 {
03494 if (nbd[i] >= 2) gi = max((x[i]-u[i]),gi);
03495 }
03496 else
03497 {
03498 if (nbd[i] <= 2) gi = min((x[i]-l[i]),gi);
03499 }
03500 }
03501 sbgnrm = max(sbgnrm,fabs(gi));
03502 }
03503 }
03504
03505
03506
03507
03508
03509
03510
03511
03512
03513
03514
03515
03516
03517
03518
03519
03520
03521
03522
03523
03524
03525
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540
03541
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573
03574
03575
03576
03577
03578
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
03604
03605
03606
03607
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635
03636
03637
03638
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652
03653
03654 void subsm(const int& n, const int& m, const int& nsub, const int* const& ind,
03655 const double* const & l, const double* const & u,
03656 const int* const & nbd, double* const & x, double* const & d,
03657 double* const & ws, double* const & wy, const double& theta,
03658 const int& col, const int& head, int& iword, double* const & wv,
03659 double* const & wn, const int& iprint, int& info)
03660 {
03661
03662 int pointr,m2,col2,ibd=0,js,k;
03663 double alpha,dk,temp1,temp2;
03664 double one=1.0,zero=0.0;
03665 int idx;
03666
03667 if (nsub <= 0) return;
03668 if (iprint >= 99)
03669 cout << "----------------SUBSM entered-----------------" << endl;
03670
03671
03672
03673 pointr = head;
03674 for (int i = 1; i <= col; i++)
03675 {
03676 temp1 = zero;
03677 temp2 = zero;
03678 for (int j = 1; j <= nsub; j++)
03679 {
03680 k = ind[j];
03681 idx = getIdx(k,pointr,n);
03682 temp1 += wy[idx]*d[j];
03683 temp2 += ws[idx]*d[j];
03684 }
03685 wv[i] = temp1;
03686 wv[col + i] = theta*temp2;
03687 pointr = pointr%m + 1;
03688 }
03689
03690
03691
03692
03693 m2 = 2*m;
03694 col2 = 2*col;
03695 dtrsl(wn,m2,col2,wv,11,info);
03696
03697 if (info != 0) return;
03698 for (int i = 1; i <= col; i++)
03699 wv[i] = -wv[i];
03700 dtrsl(wn,m2,col2,wv,01,info);
03701
03702 if (info != 0) return;
03703
03704
03705
03706 pointr = head;
03707 for (int jy = 1; jy <= col; jy++)
03708 {
03709 js = col + jy;
03710 for (int i = 1; i <= nsub; i++)
03711 {
03712 k = ind[i];
03713 idx = getIdx(k,pointr,n);
03714 d[i] += wy[idx]*wv[jy]/theta + ws[idx]*wv[js];
03715 }
03716 pointr = pointr%m + 1;
03717 }
03718
03719 for (int i = 1; i <= nsub; i++)
03720 d[i] /= theta;
03721
03722
03723
03724 alpha = one;
03725 temp1 = alpha;
03726
03727 for (int i = 1; i <= nsub; i++)
03728 {
03729 k = ind[i];
03730 dk = d[i];
03731 if (nbd[k] != 0)
03732 {
03733 if (dk < zero && nbd[k] <= 2)
03734 {
03735 temp2 = l[k] - x[k];
03736 if (temp2 >= zero)
03737 temp1 = zero;
03738 else
03739 if (dk*alpha < temp2)
03740 temp1 = temp2/dk;
03741 }
03742 else
03743 if (dk > zero && nbd[k] >= 2)
03744 {
03745 temp2 = u[k] - x[k];
03746 if (temp2 <= zero)
03747 temp1 = zero;
03748 else
03749 if (dk*alpha > temp2)
03750 temp1 = temp2/dk;
03751 }
03752 if (temp1 < alpha)
03753 {
03754 alpha = temp1;
03755 ibd = i;
03756 }
03757 }
03758 }
03759
03760
03761 if (alpha < one)
03762 {
03763 dk = d[ibd];
03764 k = ind[ibd];
03765 if (dk > zero)
03766 {
03767 x[k] = u[k];
03768 d[ibd] = zero;
03769 }
03770 else
03771 if (dk < zero)
03772 {
03773 x[k] = l[k];
03774 d[ibd] = zero;
03775 }
03776 }
03777
03778 for (int i = 1; i <= nsub; i++)
03779 {
03780 k = ind[i];
03781 x[k] += alpha*d[i];
03782 }
03783
03784 if (iprint >= 99)
03785 {
03786 if (alpha < one)
03787 cout << "ALPHA = " << alpha << " backtrack to the BOX" << endl;
03788 else
03789 cout << "SM solution inside the box" << endl;
03790
03791 if (iprint >100)
03792 {
03793 cout << "Subspace solution X = ";
03794 for (int i = 1; i <= n; i++) cout << x[i] << " ";
03795 cout << endl;
03796 }
03797 }
03798
03799 if (alpha < one)
03800 iword = 1;
03801 else
03802 iword = 0;
03803
03804 if (iprint >= 99)
03805 cout << "----------------exit SUBSM --------------------" << endl;
03806 }
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
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
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902
03903
03904
03905
03906
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918
03919
03920
03921
03922
03923
03924
03925
03926
03927
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937
03938
03939
03940
03941
03942 void dcsrch(double& f, double& g, double& stp, const double& ftol,
03943 const double& gtol, const double& xtol, const double& stpmin,
03944 const double& stpmax, char* const & task, int* const & isave,
03945 double* const & dsave)
03946 {
03947 double zero=0.0,p5=0.5,p66=0.66;
03948 double xtrapl=1.1,xtrapu=4.0;
03949
03950 bool brackt;
03951 int stage;
03952 double finit,ftest,fm,fx,fxm,fy,fym,ginit,gtest,
03953 gm,gx,gxm,gy,gym,stx,sty,stmin,stmax,width,width1;
03954
03955
03956
03957 if (strncmp(task,"START",5)==0)
03958 {
03959
03960
03961 if (stp < stpmin) strcpy(task, "ERROR: STP < STPMIN");
03962 if (stp > stpmax) strcpy(task, "ERROR: STP > STPMAX");
03963 if (g >zero) strcpy(task, "ERROR: INITIAL G >ZERO");
03964 if (ftol < zero) strcpy(task, "ERROR: FTOL < ZERO");
03965 if (gtol < zero) strcpy(task, "ERROR: GTOL < ZERO");
03966 if (xtol < zero) strcpy(task, "ERROR: XTOL < ZERO");
03967 if (stpmin < zero) strcpy(task, "ERROR: STPMIN < ZERO");
03968 if (stpmax < stpmin) strcpy(task, "ERROR: STPMAX < STPMIN");
03969
03970
03971 if (strncmp(task,"ERROR",5)==0) return;
03972
03973
03974
03975 brackt = false;
03976 stage = 1;
03977 finit = f;
03978 ginit = g;
03979 gtest = ftol*ginit;
03980 width = stpmax - stpmin;
03981 width1 = width/p5;
03982
03983
03984
03985
03986
03987
03988
03989
03990 stx = zero;
03991 fx = finit;
03992 gx = ginit;
03993 sty = zero;
03994 fy = finit;
03995 gy = ginit;
03996 stmin = zero;
03997 stmax = stp + xtrapu*stp;
03998 strcpy(task, "FG");
03999
04000 goto goto1000;
04001 }
04002 else
04003 {
04004
04005
04006 if (isave[1] == 1)
04007 brackt = true;
04008 else
04009 brackt = false;
04010
04011 stage = isave[2];
04012 ginit = dsave[1];
04013 gtest = dsave[2];
04014 gx = dsave[3];
04015 gy = dsave[4];
04016 finit = dsave[5];
04017 fx = dsave[6];
04018 fy = dsave[7];
04019 stx = dsave[8];
04020 sty = dsave[9];
04021 stmin = dsave[10];
04022 stmax = dsave[11];
04023 width = dsave[12];
04024 width1 = dsave[13];
04025 }
04026
04027
04028
04029
04030 ftest = finit + stp*gtest;
04031 if (stage == 1 && f <= ftest && g >= zero) stage = 2;
04032
04033
04034
04035 if (brackt && (stp <= stmin || stp >= stmax))
04036 strcpy(task, "WARNING: ROUNDING ERRORS PREVENT PROGRESS");
04037 if (brackt && stmax - stmin <= xtol*stmax)
04038 strcpy(task, "WARNING: XTOL TEST SATISFIED");
04039 if (stp == stpmax && f <= ftest && g <= gtest)
04040 strcpy(task, "WARNING: STP = STPMAX");
04041 if (stp == stpmin && (f > ftest || g >= gtest))
04042 strcpy(task, "WARNING: STP = STPMIN");
04043
04044
04045
04046 if (f <= ftest && fabs(g) <= gtol*(-ginit))
04047 strcpy(task, "CONVERGENCE");
04048
04049
04050
04051 if (strncmp(task,"WARN",4)==0 || strncmp(task,"CONV",4)==0) goto goto1000;
04052
04053
04054
04055
04056
04057 if (stage == 1 && f <= fx && f > ftest)
04058 {
04059
04060
04061 fm = f - stp*gtest;
04062 fxm = fx - stx*gtest;
04063 fym = fy - sty*gtest;
04064 gm = g - gtest;
04065 gxm = gx - gtest;
04066 gym = gy - gtest;
04067
04068
04069
04070 dcstep(stx,fxm,gxm,sty,fym,gym,stp,fm,gm,
04071 brackt,stmin,stmax);
04072
04073
04074
04075 fx = fxm + stx*gtest;
04076 fy = fym + sty*gtest;
04077 gx = gxm + gtest;
04078 gy = gym + gtest;
04079 }
04080 else
04081 {
04082
04083
04084 dcstep(stx,fx,gx,sty,fy,gy,stp,f,g,
04085 brackt,stmin,stmax);
04086 }
04087
04088
04089
04090 if (brackt)
04091 {
04092 if (fabs(sty-stx) >= p66*width1) stp = stx + p5*(sty - stx);
04093 width1 = width;
04094 width = fabs(sty-stx);
04095 }
04096
04097
04098
04099 if (brackt)
04100 {
04101 stmin = min(stx,sty);
04102 stmax = max(stx,sty);
04103 }
04104 else
04105 {
04106 stmin = stp + xtrapl*(stp - stx);
04107 stmax = stp + xtrapu*(stp - stx);
04108 }
04109
04110
04111
04112 stp = max(stp,stpmin);
04113 stp = min(stp,stpmax);
04114
04115
04116
04117
04118 if (brackt && (stp <= stmin || stp >= stmax)
04119 || (brackt && stmax-stmin <= xtol*stmax)) stp = stx;
04120
04121
04122 strcpy(task,"FG");
04123
04124 goto1000:
04125
04126
04127
04128 if (brackt)
04129 isave[1] = 1;
04130 else
04131 isave[1] = 0;
04132
04133 isave[2] = stage;
04134 dsave[1] = ginit;
04135 dsave[2] = gtest;
04136 dsave[3] = gx;
04137 dsave[4] = gy;
04138 dsave[5] = finit;
04139 dsave[6] = fx;
04140 dsave[7] = fy;
04141 dsave[8] = stx;
04142 dsave[9] = sty;
04143 dsave[10] = stmin;
04144 dsave[11] = stmax;
04145 dsave[12] = width;
04146 dsave[13] = width1;
04147 }
04148
04149
04150
04151
04152
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165
04166
04167
04168
04169
04170
04171
04172
04173
04174
04175
04176
04177
04178
04179
04180
04181
04182
04183
04184
04185
04186
04187
04188
04189
04190
04191
04192
04193
04194
04195
04196
04197
04198
04199
04200
04201
04202
04203
04204
04205
04206
04207
04208
04209
04210
04211
04212
04213
04214
04215
04216
04217
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230
04231
04232
04233
04234
04235
04236
04237
04238
04239
04240
04241
04242
04243 void dcstep(double& stx, double& fx, double& dx, double& sty, double& fy,
04244 double& dy, double& stp, const double& fp, const double& dp,
04245 bool& brackt, const double& stpmin, const double& stpmax)
04246 {
04247 double zero=0.0,p66=0.66,two=2.0,three=3.0;
04248 double gamma,p,q,r,s,sgnd,stpc,stpf,stpq,theta;
04249
04250 sgnd = dp*(dx/fabs(dx));
04251
04252
04253
04254
04255
04256
04257 if (fp > fx)
04258 {
04259 theta = three*(fx - fp)/(stp - stx) + dx + dp;
04260 s = max(fabs(theta),fabs(dx),fabs(dp));
04261 gamma = s*sqrt( (theta/s)*(theta/s) - (dx/s)*(dp/s) );
04262 if (stp < stx) gamma = -gamma;
04263 p = (gamma - dx) + theta;
04264 q = ((gamma - dx) + gamma) + dp;
04265 r = p/q;
04266 stpc = stx + r*(stp - stx);
04267 stpq = stx + ((dx/((fx - fp)/(stp - stx) + dx))/two)*(stp - stx);
04268 if (fabs(stpc-stx) < fabs(stpq-stx))
04269 stpf = stpc;
04270 else
04271 stpf = stpc + (stpq - stpc)/two;
04272 brackt = true;
04273 }
04274
04275
04276
04277
04278
04279
04280 else
04281 if (sgnd < zero)
04282 {
04283 theta = three*(fx - fp)/(stp - stx) + dx + dp;
04284 s = max(fabs(theta),fabs(dx),fabs(dp));
04285 gamma = s*sqrt( (theta/s)*(theta/s) - (dx/s)*(dp/s) );
04286 if (stp > stx) gamma = -gamma;
04287 p = (gamma - dp) + theta;
04288 q = ((gamma - dp) + gamma) + dx;
04289 r = p/q;
04290 stpc = stp + r*(stx - stp);
04291 stpq = stp + (dp/(dp - dx))*(stx - stp);
04292 if (fabs(stpc-stp) > fabs(stpq-stp))
04293 stpf = stpc;
04294 else
04295 stpf = stpq;
04296 brackt = true;
04297 }
04298
04299
04300
04301
04302 else
04303 if (fabs(dp) < fabs(dx))
04304 {
04305
04306
04307
04308
04309
04310 theta = three*(fx - fp)/(stp - stx) + dx + dp;
04311 s = max(fabs(theta),fabs(dx),fabs(dp));
04312
04313
04314
04315
04316 gamma = s*sqrt(max(zero, (theta/s)*(theta/s)-(dx/s)*(dp/s)));
04317 if (stp > stx) gamma = -gamma;
04318 p = (gamma - dp) + theta;
04319 q = (gamma + (dx - dp)) + gamma;
04320 r = p/q;
04321 if (r < zero && gamma != zero)
04322 stpc = stp + r*(stx - stp);
04323 else
04324 if (stp > stx)
04325 stpc = stpmax;
04326 else
04327 stpc = stpmin;
04328
04329 stpq = stp + (dp/(dp - dx))*(stx - stp);
04330
04331 if (brackt)
04332 {
04333
04334
04335
04336
04337
04338 if (fabs(stpc-stp) < fabs(stpq-stp))
04339 stpf = stpc;
04340 else
04341 stpf = stpq;
04342
04343 if (stp > stx)
04344 stpf = min(stp+p66*(sty-stp),stpf);
04345 else
04346 stpf = max(stp+p66*(sty-stp),stpf);
04347 }
04348 else
04349 {
04350
04351
04352
04353
04354 if (fabs(stpc-stp) > fabs(stpq-stp))
04355 stpf = stpc;
04356 else
04357 stpf = stpq;
04358
04359 stpf = min(stpmax,stpf);
04360 stpf = max(stpmin,stpf);
04361 }
04362 }
04363
04364
04365
04366
04367 else
04368 {
04369 if (brackt)
04370 {
04371 theta = three*(fp - fy)/(sty - stp) + dy + dp;
04372 s = max(fabs(theta),fabs(dy),fabs(dp));
04373 gamma = s*sqrt((theta/s)*(theta/s) - (dy/s)*(dp/s));
04374 if (stp > sty) gamma = -gamma;
04375 p = (gamma - dp) + theta;
04376 q = ((gamma - dp) + gamma) + dy;
04377 r = p/q;
04378 stpc = stp + r*(sty - stp);
04379 stpf = stpc;
04380 }
04381 else
04382 if (stp > stx)
04383 stpf = stpmax;
04384 else
04385 stpf = stpmin;
04386 }
04387
04388
04389
04390 if (fp > fx)
04391 {
04392 sty = stp;
04393 fy = fp;
04394 dy = dp;
04395 }
04396 else
04397 {
04398 if (sgnd < zero)
04399 {
04400 sty = stx;
04401 fy = fx;
04402 dy = dx;
04403 }
04404 stx = stp;
04405 fx = fp;
04406 dx = dp;
04407 }
04408
04409
04410
04411 stp = stpf;
04412 }
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423
04424
04425
04426
04427
04428
04429
04430
04431
04432
04433
04434
04435
04436
04437
04438
04439
04440
04441
04442
04443
04444
04445 double dnrm2(int& n,double* const & x, int& incx)
04446 {
04447
04448 double scale = 0.0;
04449 double ddnrm2 = 0.0;
04450
04451 for (int i = 1; i <= n; i+=incx)
04452 scale = max(scale, fabs(x[i]));
04453
04454 if (scale == 0.0) return ddnrm2;
04455
04456 for (int i = 1; i <= n; i+=incx)
04457 ddnrm2 += (x[i]/scale)*(x[i]/scale);
04458
04459 ddnrm2 = scale*sqrt(ddnrm2);
04460 return ddnrm2;
04461 }
04462
04463
04464
04465
04466
04467
04468
04469
04470
04471
04472
04473
04474
04475
04476
04477
04478
04479
04480
04481
04482
04483
04484
04485
04486
04487
04488
04489
04490
04491
04492
04493
04494 double dpmeps()
04495 {
04496
04497 long int ibeta,irnd,it,itemp,negep;
04498 long double a,b,beta,betain,betah,temp,tempa,temp1,
04499 zero=0.0,one=1.0,two=2.0;
04500 long double ddpmeps;
04501
04502
04503
04504 a = one;
04505 b = one;
04506 goto10:
04507 a = a + a;
04508 temp = a + one;
04509 temp1 = temp - a;
04510 if (temp1 - one == zero) goto goto10;
04511
04512 goto20:
04513 b = b + b;
04514 temp = a + b;
04515 itemp = int(temp - a);
04516 if (itemp == 0) goto goto20;
04517 ibeta = itemp;
04518 beta = double(ibeta);
04519
04520
04521
04522 it = 0;
04523 b = one;
04524 goto30:
04525 it += 1;
04526 b *= beta;
04527 temp = b + one;
04528 temp1 = temp - b;
04529 if (temp1 - one == zero) goto goto30;
04530 irnd = 0;
04531 betah = beta/two;
04532 temp = a + betah;
04533 if (temp - a != zero) irnd = 1;
04534 tempa = a + beta;
04535 temp = tempa + betah;
04536 if ((irnd == 0) && (temp - tempa != zero)) irnd = 2;
04537
04538
04539
04540 negep = it + 3;
04541 betain = one/beta;
04542 a = one;
04543 for (int i = 1; i <= negep; i++)
04544 a *= betain;
04545
04546 goto50:
04547 temp = one + a;
04548 if (temp - one != zero) goto goto60;
04549 a *= beta;
04550 goto goto50;
04551
04552 goto60:
04553 ddpmeps = a;
04554 if ((ibeta == 2) || (irnd == 0)) goto goto70;
04555 a = (a*(one + a))/two;
04556 temp = one + a;
04557 if (temp - one != zero) ddpmeps = a;
04558
04559 goto70:
04560 return ddpmeps;
04561 }
04562
04563
04564
04565
04566
04567
04568 void daxpy(const int& n, const double& da, const double* const & dx,
04569 const int& incx, double* const & dy, const int& incy)
04570 {
04571
04572 int ix,iy,m,mp1;
04573 if (n <= 0) return;
04574 if (da == 0.0) return;
04575 if(incx==1 && incy==1) goto goto20;
04576
04577
04578
04579
04580 ix = 1;
04581 iy = 1;
04582 if(incx < 0) ix = (-n+1)*incx + 1;
04583 if(incy < 0) iy = (-n+1)*incy + 1;
04584
04585 for (int i = 1; i <= n; i++)
04586 {
04587 dy[iy] += da*dx[ix];
04588 ix += incx;
04589 iy += incy;
04590 }
04591 return;
04592
04593
04594
04595
04596 goto20:
04597 m = n%4;
04598 if (m == 0) goto goto40;
04599
04600 for (int i = 1; i <= m; i++)
04601 dy[i] += da*dx[i];
04602
04603 if (n < 4) return;
04604
04605 goto40:
04606 mp1 = m + 1;
04607
04608 for (int i = mp1; i <= n; i+=4)
04609 {
04610 dy[i] += da*dx[i];
04611 dy[i + 1] += da*dx[i + 1];
04612 dy[i + 2] += da*dx[i + 2];
04613 dy[i + 3] += da*dx[i + 3];
04614 }
04615 }
04616
04617
04618
04619
04620
04621
04622 void dcopy(const int& n, const double* const & dx, const int& incx,
04623 double* const & dy,const int& incy)
04624 {
04625
04626 int ix,iy,m,mp1;
04627
04628 if (n <= 0) return;
04629 if(incx==1 && incy==1) goto goto20;
04630
04631
04632
04633
04634 ix = 1;
04635 iy = 1;
04636 if (incx < 0) ix = (-n+1)*incx + 1;
04637 if (incy < 0) iy = (-n+1)*incy + 1;
04638 for (int i = 1; i <= n; i++)
04639 {
04640 dy[iy] = dx[ix];
04641 ix += incx;
04642 iy += incy;
04643 }
04644 return;
04645
04646
04647
04648
04649
04650 goto20:
04651 m = n%7;
04652 if (m == 0) goto goto40;
04653 for (int i = 1; i <= m; i++)
04654 dy[i] = dx[i];
04655
04656 if (n < 7) return;
04657
04658 goto40:
04659 mp1 = m + 1;
04660 for (int i = mp1; i <= n; i+=7)
04661 {
04662 dy[i] = dx[i];
04663 dy[i + 1] = dx[i + 1];
04664 dy[i + 2] = dx[i + 2];
04665 dy[i + 3] = dx[i + 3];
04666 dy[i + 4] = dx[i + 4];
04667 dy[i + 5] = dx[i + 5];
04668 dy[i + 6] = dx[i + 6];
04669 }
04670 }
04671
04672
04673
04674
04675
04676
04677 double ddot(const int& n, const double* const & dx, const int& incx,
04678 const double* const & dy, const int& incy)
04679 {
04680 double dtemp;
04681
04682 int ix,iy,m,mp1;
04683
04684 double dddot = 0.0;
04685 dtemp = 0.0;
04686 if (n <= 0) return dddot;
04687 if (incx==1 && incy==1) goto goto20;
04688
04689
04690
04691
04692 ix = 1;
04693 iy = 1;
04694 if (incx < 0) ix = (-n+1)*incx + 1;
04695 if (incy < 0) iy = (-n+1)*incy + 1;
04696
04697 for (int i = 1; i <= n; i++)
04698 {
04699 dtemp += dx[ix]*dy[iy];
04700 ix += incx;
04701 iy += incy;
04702 }
04703 dddot = dtemp;
04704 return dddot;
04705
04706
04707
04708
04709
04710 goto20:
04711 m = n%5;
04712 if (m == 0) goto goto40;
04713
04714 for (int i = 1; i <= m; i++)
04715 dtemp += dx[i]*dy[i];
04716
04717 if( n < 5 ) goto goto60;
04718
04719 goto40:
04720 mp1 = m + 1;
04721
04722
04723 for (int i = mp1; i <= n; i+=5)
04724 {
04725 dtemp += dx[i]*dy[i] + dx[i + 1]*dy[i + 1] +
04726 dx[i + 2]*dy[i + 2] + dx[i + 3]*dy[i + 3] + dx[i + 4]*dy[i + 4];
04727 }
04728
04729 goto60:
04730 dddot = dtemp;
04731 return dddot;
04732 }
04733
04734
04735
04736
04737
04738
04739
04740
04741
04742
04743
04744
04745
04746
04747
04748
04749
04750
04751
04752
04753
04754
04755
04756
04757
04758
04759
04760
04761
04762
04763
04764
04765
04766
04767
04768
04769
04770
04771
04772
04773
04774
04775
04776
04777 void dpofa(double* const & a, const int& lda, const int& n, int& info,
04778 bool smallerMatrix=false)
04779 {
04780 double t;
04781 double s;
04782
04783 int jm1;
04784 int idx;
04785
04786
04787 for (int j = 1; j <= n; j++)
04788 {
04789 info = j;
04790 s = 0.0;
04791 jm1 = j - 1;
04792 if (jm1 < 1) goto goto20;
04793 for (int k = 1; k <= jm1; k++)
04794 {
04795 idx = getIdx(k,j,lda);
04796 t = a[idx] - ddot(k-1,&(a[getIdx(1,k,lda)-1]),1,
04797 &(a[getIdx(1,j,lda)-1]),1);
04798 t = t/a[getIdx(k,k,lda)];
04799 a[idx] = t;
04800 s += t*t;
04801 }
04802
04803 goto20:
04804 idx = getIdx(j,j,lda);
04805 s = a[idx] - s;
04806
04807
04808 if (s <= 0.0) goto goto40;
04809 a[idx] = sqrt(s);
04810 }
04811 info = 0;
04812 goto40:
04813 t = 0;
04814 }
04815
04816
04817
04818
04819
04820
04821
04822 void dscal(const int& n, const double& da, double* const & dx,
04823 const int& incx)
04824 {
04825
04826 int m,mp1,nincx;
04827
04828 if (n <= 0 || incx <= 0) return;
04829 if (incx == 1) goto goto20;
04830
04831
04832
04833 nincx = n*incx;
04834
04835 for (int i = 1; i <= nincx; i+=incx)
04836 dx[i] = da*dx[i];
04837 return;
04838
04839
04840
04841
04842
04843 goto20:
04844 m = n%5;
04845 if (m == 0) goto goto40;
04846
04847 for (int i = 1; i <= m; i++)
04848 dx[i] = da*dx[i];
04849
04850 if (n < 5) return;
04851
04852 goto40:
04853 mp1 = m + 1;
04854 for (int i = mp1; i <= n; i+=5)
04855 {
04856 dx[i] = da*dx[i];
04857 dx[i + 1] = da*dx[i + 1];
04858 dx[i + 2] = da*dx[i + 2];
04859 dx[i + 3] = da*dx[i + 3];
04860 dx[i + 4] = da*dx[i + 4];
04861 }
04862 }
04863
04864
04865
04866
04867
04868
04869
04870
04871
04872
04873
04874
04875
04876
04877
04878
04879
04880
04881
04882
04883
04884
04885
04886
04887
04888
04889
04890
04891
04892
04893
04894
04895
04896
04897
04898
04899
04900
04901
04902
04903
04904
04905
04906
04907
04908
04909
04910
04911
04912
04913
04914
04915
04916
04917
04918
04919 void dtrsl(double* const & t, const int& ldt, const int& n,
04920 double* const &b, const int& job, int& info)
04921 {
04922 double temp;
04923 int ccase,j;
04924
04925
04926
04927
04928
04929
04930 for (info = 1; info <= n; info++)
04931 {
04932
04933 if (t[getIdx(info,info,ldt)] == 0.0) goto goto150;
04934 }
04935 info = 0;
04936
04937
04938
04939 ccase = 1;
04940 if (job%10 != 0) ccase = 2;
04941 if ((job%100)/10 != 0) ccase += 2;
04942 if (ccase==1) goto goto20;
04943 if (ccase==2) goto goto50;
04944 if (ccase==3) goto goto80;
04945 if (ccase==4) goto goto110;
04946
04947
04948
04949 goto20:
04950 b[1] /= t[getIdx(1,1,ldt)];
04951 if (n < 2) goto goto40;
04952 for (int j = 2; j <= n; j++)
04953 {
04954 temp = -b[j-1];
04955 daxpy(n-j+1,temp,&(t[getIdx(j,j-1,ldt)-1]),1,&(b[j-1]),1);
04956 b[j] /= t[getIdx(j,j,ldt)];
04957 }
04958 goto40:
04959 goto goto140;
04960
04961
04962
04963 goto50:
04964 b[n] /= t[getIdx(n,n,ldt)];
04965 if (n < 2) goto goto70;
04966 for (int jj = 2; jj <= n; jj++)
04967 {
04968 j = n - jj + 1;
04969 temp = -b[j+1];
04970 daxpy(j,temp,&(t[getIdx(1,j+1,ldt)-1]),1,&(b[1-1]),1);
04971 b[j] /= t[getIdx(j,j,ldt)];
04972 }
04973
04974 goto70:
04975 goto goto140;
04976
04977
04978
04979 goto80:
04980 b[n] /= t[getIdx(n,n,ldt)];
04981 if (n < 2) goto goto100;
04982 for (int jj = 2; jj <= n; jj++)
04983 {
04984 j = n - jj + 1;
04985 b[j] = b[j] - ddot(jj-1,&(t[getIdx(j+1,j,ldt)-1]),1,&(b[j+1-1]),1);
04986 b[j] /= t[getIdx(j,j,ldt)];
04987 }
04988 goto100:
04989 goto goto140;
04990
04991
04992
04993 goto110:
04994 b[1] /= t[getIdx(1,1,ldt)];
04995 if (n < 2) goto goto130;
04996 for (int j = 2; j <= n; j++)
04997 {
04998 b[j] = b[j] - ddot(j-1,&(t[getIdx(1,j,ldt)-1]),1,&(b[1-1]),1);
04999 b[j] /= t[getIdx(j,j,ldt)];
05000 }
05001
05002 goto130:
05003
05004 if (false);
05005
05006 goto140:
05007
05008 if (false);
05009
05010 goto150:
05011
05012 if (false);
05013
05014 }
05015
05016 private:
05017 Timer timer_;
05018
05019 };
05020 #endif