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