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