00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "BonminConfig.h"
00012
00013 #include "BonBqpdSolver.hpp"
00014 #include "BonBqpdWarmStart.hpp"
00015
00016 #include "CoinTime.hpp"
00017 #include <algorithm>
00018
00019 #define InitializeAll
00020
00021 typedef Bonmin::BqpdSolver::fint fint;
00022 typedef Bonmin::BqpdSolver::real real;
00023 int Bonmin::BqpdSolver::reinit_freq_ = 0;
00024 int Bonmin::BqpdSolver::m0de_ = 6;
00025 extern "C"
00026 {
00027 void F77_FUNC(bqpd,BQPD)(fint* n, fint* m, fint* k, fint* kmax,
00028 real* a, fint* la, real* x, real* bl, real* bu,
00029 real* f, real* fmin, real* g, real* r, real* w,
00030 real* e, fint* ls, real* alp, fint* lp, fint* mlp,
00031 fint* peq, real* ws, fint* lws, fint* m0de,
00032 fint* ifail, fint* info, fint* iprint, fint* nout);
00033
00034
00035 extern struct {
00036 fint kk,ll,kkk,lll,mxws,mxlws;
00037 }
00038 F77_FUNC(wsc,WSC);
00039
00040 extern struct {
00041 real eps,tol,emin;
00042 }
00043 F77_FUNC(epsc,EPSC);
00044
00045 extern struct {
00046 real sgnf;
00047 fint nrep,npiv,nres;
00048 }
00049 F77_FUNC(repc,REPC);
00050
00051 extern struct {
00052 fint nup,nfreq;
00053 }
00054 F77_FUNC(refactorc,REFACTORC);
00055
00056 extern struct {
00057 real vstep;
00058 }
00059 F77_FUNC(vstepc,VSTEPC);
00060
00061 extern struct {
00062 fint phl, phr, phc;
00063 }
00064 F77_FUNC(hessc,HESSC);
00065
00066 extern struct {
00067 fint scale_mode, phe;
00068 }
00069 F77_FUNC(scalec,SCALEC);
00070
00071 extern struct {
00072 fint irh1,na,na1,nb,nb1,ka1,kb1,kc1,irg1,lu1,lv,lv1,ll1;
00073 }
00074 F77_FUNC(bqpdc,BQPDC);
00075
00076 extern struct {
00077 real alpha;
00078 }
00079 F77_FUNC(alphac,ALPHAC);
00080
00081 extern struct {
00082 fint ns,ns1,nt,nt1,nu,nu1,nx,nx1,np,np1,nprof,lc;
00083 fint lc1,li,li1,lm,lm1,lp_,lp1,lq,lq1,lr,lr1,ls_,ls1,lt,lt1;
00084 }
00085 F77_FUNC(sparsec,SPARSEC);
00086
00087 extern struct {
00088 fint m1,m2,mp,mq,lastr,irow;
00089 }
00090 F77_FUNC(factorc,FACTORC);
00091
00092 extern struct {
00093 fint mxm1;
00094 }
00095 F77_FUNC(mxm1c,MXM1C);
00096
00097 extern struct {
00098 real c;
00099 }
00100 F77_FUNC(minorc,MINORS);
00101 }
00102
00103 namespace Bonmin
00104 {
00105
00106 std::string BqpdSolver::solverName_ = "Bqpd QP";
00107
00108 void BqpdSolver::
00109 registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions)
00110 {
00111 roptions->SetRegisteringCategory("Bqpd options",RegisteredOptions::BqpdCategory);
00112 roptions->AddLowerBoundedNumberOption("qp_fillin_factor", "Factor for estimating fill-in for factorization method in Bqpd", 0., true, 4.);
00113 roptions->AddBoundedIntegerOption("hot_start_m0de", "Choice of the hot start option", 0, 6, 6);
00114 roptions->AddLowerBoundedIntegerOption("reinit_freq", "Number of pivots before recopy hot start", 0, 0);
00115 }
00116
00117 BqpdSolver::BqpdSolver(bool createEmpty )
00118 :
00119 TNLPSolver(),
00120 cached_(NULL)
00121 {
00122 if (createEmpty) return;
00123 }
00124
00125 BqpdSolver::BqpdSolver(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions,
00126 Ipopt::SmartPtr<Ipopt::OptionsList> options,
00127 Ipopt::SmartPtr<Ipopt::Journalist> journalist,
00128 const std::string & prefix)
00129 :
00130 TNLPSolver(roptions, options, journalist, prefix),
00131 cached_(NULL)
00132 {
00133 options->GetNumericValue("qp_fillin_factor", fillin_factor_, "bqpd.");
00134 options->GetIntegerValue("kmax", kmax_ipt_, "bqpd.");
00135 options->GetIntegerValue("mlp", mlp_ipt_,"bqpd.");
00136 options->GetIntegerValue("hot_start_m0de", m0de_,"bqpd.");
00137 options->GetIntegerValue("reinit_freq", reinit_freq_,"bqpd.");
00138 if(!options_->GetIntegerValue("print_level",default_log_level_,""))
00139 default_log_level_ = 1;
00140
00141 }
00142
00143 Ipopt::SmartPtr <TNLPSolver>
00144 BqpdSolver::clone()
00145 {
00146 #ifdef TIME_BQPD
00147 times().create -= CoinCpuTime();
00148 #endif
00149 Ipopt::SmartPtr<BqpdSolver> retval = new BqpdSolver(true);
00150 *retval->options_ = *options_;
00151 retval->roptions_ = roptions_;
00152 retval->journalist_ = journalist_;
00153 retval->prefix_ = prefix_;
00154 retval->fillin_factor_ = fillin_factor_;
00155 retval->kmax_ipt_ = kmax_ipt_;
00156 retval->mlp_ipt_ = mlp_ipt_;
00157 retval->default_log_level_ = default_log_level_;
00158 retval->reinit_freq_ = reinit_freq_;
00159 retval->m0de_ = m0de_;
00160 #ifdef TIME_BQPD
00161 times().create += CoinCpuTime();
00162 #endif
00163 return GetRawPtr(retval);
00164 }
00165
00166 BqpdSolver::~BqpdSolver()
00167 {}
00168
00169 bool
00170 BqpdSolver::Initialize(std::string optFile)
00171 {
00172 std::ifstream is;
00173 if (optFile != "") {
00174 try {
00175 is.open(optFile.c_str());
00176 }
00177 catch (std::bad_alloc) {
00178 journalist_->Printf(Ipopt::J_SUMMARY, Ipopt::J_MAIN, "\nEXIT: Not enough memory.\n");
00179 return false;
00180 }
00181 catch (...) {
00182 Ipopt::IpoptException E("Unknown Exception caught in ipopt", "Unknown File", -1);
00183 E.ReportException(*journalist_);
00184 return false;
00185 }
00186 }
00187 bool retval = Initialize(is);
00188 if (is) {
00189 is.close();
00190 }
00191 if(!options_->GetIntegerValue("print_level",default_log_level_,""))
00192 default_log_level_ = 1;
00193 return retval;
00194 }
00195
00196 bool
00197 BqpdSolver::Initialize(std::istream &is)
00198 {
00199 if (is.good()) {
00200 options_->ReadFromStream(*journalist_, is);
00201 }
00202 return true;
00203 }
00204
00206 TNLPSolver::ReturnStatus
00207 BqpdSolver::OptimizeTNLP(const Ipopt::SmartPtr<Ipopt::TNLP>& tnlp)
00208 {
00209 BranchingTQP* tqp = dynamic_cast<BranchingTQP*>(GetRawPtr(tnlp));
00210 if (!tqp) {
00211 Ipopt::IpoptException E("BqpdSolver called with object other than a BranchingTQP",
00212 "BonBqpdSolver.cpp",-1);
00213 throw E;
00214 }
00215 if (IsNull(cached_) || !cached_->use_warm_start_in_cache_) {
00216 cached_ = new cachedInfo(tqp, options_, kmax_ipt_, mlp_ipt_,
00217 &fillin_factor_);
00218 }
00219 #ifdef TIME_BQPD
00220 times().solve -= CoinCpuTime();
00221 #endif
00222 TNLPSolver::ReturnStatus r_val = callOptimizer();
00223 #ifdef TIME_BQPD
00224 times().solve += CoinCpuTime();
00225 #endif
00226 return r_val;
00227 }
00228
00230 TNLPSolver::ReturnStatus
00231 BqpdSolver::ReOptimizeTNLP(const Ipopt::SmartPtr<Ipopt::TNLP> & tnlp)
00232 {
00233 #ifndef NDEBUG
00234 BranchingTQP* tqp = dynamic_cast<BranchingTQP*>(GetRawPtr(tnlp));
00235 assert(tqp == GetRawPtr(cached_->tqp_));
00236 #endif
00237 int n = cached_->n;
00238 int m = cached_->m;
00239 tnlp->get_bounds_info(n, cached_->bl, cached_->bu,
00240 m, cached_->bl+n, cached_->bu+n);
00241
00242 for (int i=0; i<n+m; i++) {
00243 cached_->bl[i] = std::max(cached_->bl[i], -1e50);
00244 cached_->bu[i] = std::min(cached_->bu[i], 1e50);
00245 }
00246
00247 #if 1
00248 cached_->use_warm_start_in_cache_ = true;
00249 cached_->m0de = m0de_;
00250 #else
00251 cached_->re_initialize();
00252 cached_->use_warm_start_in_cache_ = true;
00253 #endif
00254
00255 #ifdef TIME_BQPD
00256 times().resolve -= CoinCpuTime();
00257 #endif
00258 TNLPSolver::ReturnStatus r_val = callOptimizer();
00259 #ifdef TIME_BQPD
00260 times().resolve += CoinCpuTime();
00261 #endif
00262 return r_val;
00263 }
00264
00265 void
00266 BqpdSolver::cachedInfo::initialize(const Ipopt::SmartPtr<BranchingTQP> & tqp,
00267 Ipopt::SmartPtr<Ipopt::OptionsList>& options,
00268 int kmax_ipt,
00269 int mlp_ipt,
00270 double* fillin_factor)
00271 {
00272
00273 fillin_factor_ = fillin_factor;
00274
00275
00276
00277 F77_FUNC(epsc,EPSC).eps = 1111e-19;
00278 F77_FUNC(epsc,EPSC).tol = 1e-12;
00279 F77_FUNC(epsc,EPSC).emin = 1.;
00280 F77_FUNC(repc,REPC).sgnf = 1e-4;
00281 F77_FUNC(repc,REPC).nrep = 2;
00282 F77_FUNC(repc,REPC).npiv = 3;
00283 F77_FUNC(repc,REPC).nres = 2;
00284 F77_FUNC(refactorc,REFACTORC).nfreq = 500;
00285
00286 Ipopt::TNLP::IndexStyleEnum index_style;
00287 Ipopt::Index nv, nc, nnz_jac_g, nnz_hess;
00288 tqp->get_nlp_info(nv, nc, nnz_jac_g, nnz_hess, index_style);
00289 n = nv;
00290 m = nc;
00291
00292 if (kmax_ipt == -1) {
00293 kmax = n;
00294 }
00295 else {
00296 kmax = kmax_ipt;
00297 kmax = std::min(kmax,n);
00298 }
00299 mlp = mlp_ipt;
00300
00301 use_warm_start_in_cache_ = false;
00302
00303
00304 x = new real[n];
00305 bl = new real[n+m];
00306 bu = new real[n+m];
00307 g = new real[n];
00308 r = new real[n+m];
00309 w = new real[n+m];
00310 e = new real[n+m];
00311 ls = new fint[n+m];
00312 alp = new real[mlp];
00313 lp = new fint[mlp];
00314
00315
00316 tqp->get_bounds_info(n, bl, bu, m, bl+n, bu+n);
00317
00318
00319 for (int i=0; i<n+m; i++) {
00320 bl[i] = std::max(bl[i], -1e50);
00321 bu[i] = std::min(bu[i], 1e50);
00322 }
00323
00324
00325
00326 const Ipopt::Number* obj_grad = tqp->ObjGrad();
00327 amax_ = nnz_jac_g;
00328 for (int i = 0; i<n; i++) {
00329 if (obj_grad[i]!=0.) {
00330 amax_++;
00331 }
00332 }
00333 int lamax = amax_+m+2;
00334 a = new real[amax_];
00335 la = new fint [1+lamax];
00336
00337
00338 int nnz_grad = 0;
00339 for (int i = 0; i < n ; i++) {
00340 if (obj_grad[i]!=0.) {
00341 a[nnz_grad] = obj_grad[i];
00342 la[++nnz_grad] = i+1;
00343 }
00344 }
00345 la[amax_+1] = 1;
00346
00347
00348 const Ipopt::Number* JacVals = tqp->ConstrJacVals();
00349 const Ipopt::Index* RowJac = tqp->ConstrJacIRow();
00350 const Ipopt::Index* ColJac = tqp->ConstrJacJCol();
00351
00352 int* permutationJac = new int [nnz_jac_g];
00353 FilterSolver::TMat2RowPMat(false, n, m, nnz_jac_g, RowJac, ColJac, permutationJac,
00354 la, nnz_grad, 1, Ipopt::TNLP::C_STYLE);
00355 for (int i=0; i<nnz_jac_g; i++) {
00356 const int& indice = permutationJac[i];
00357 a[nnz_grad+i] = JacVals[indice];
00358 }
00359 delete [] permutationJac;
00360 #if 0
00361
00362 printf("nnz_grad = %d nnz_jac = %d\n", nnz_grad, nnz_jac_g);
00363 for (int i=0; i<1+lamax; i++) printf("la[%2d] = %d\n", i,la[i]);
00364 for (int i=0; i<amax_; i++) printf("a[%3d] = %e\n",i,a[i]);
00365 #endif
00366
00367
00368 mxws = nnz_hess + ((kmax*(kmax+9))/2 + 2*n + m) + (5*n + (int)(*fillin_factor_*(double)amax_));
00369 mxlws = (nnz_hess + n + 2) + kmax + (9*n + m);
00370
00371 ws = new real[mxws];
00372 lws = new fint[mxlws];
00373
00374 #ifdef InitializeAll
00375 for (int i=0; i<mxws; i++) {
00376 ws[i] = 42.;
00377 }
00378 for (int i=0; i<mxlws; i++) {
00379 lws[i] = 55;
00380 }
00381 #endif
00382
00383
00384 const Ipopt::Number* HessVals = tqp->ObjHessVals();
00385 const Ipopt::Index* RowHess = tqp->ObjHessIRow();
00386 const Ipopt::Index* ColHess = tqp->ObjHessJCol();
00387
00388 kk = nnz_hess;
00389 ll = nnz_hess + n + 2;
00390 int* permutationHess = new int[nnz_hess];
00391
00392 FilterSolver::TMat2RowPMat(true, n, n, nnz_hess, RowHess, ColHess,
00393 permutationHess, lws, 0, 0, Ipopt::TNLP::C_STYLE);
00394 for (int i=0; i<nnz_hess; i++) {
00395 ws[i] = HessVals[permutationHess[i]];
00396 }
00397 delete [] permutationHess;
00398 #if 0
00399
00400 printf("nnz_hess = %d\n", nnz_hess);
00401 for (int i=0; i<ll; i++) printf("hess lws[%2d] = %d\n", i,lws[i]);
00402 for (int i=0; i<kk; i++) printf("hess ws[%3d] = %e\n",i,ws[i]);
00403 #endif
00404
00405 Ipopt::Index bufy;
00406 options->GetIntegerValue("iprint",bufy, "bqpd.");
00407 iprint = bufy;
00408 nout = 6;
00409
00410 tqp_ = tqp;
00411 }
00412
00413 void
00414 BqpdSolver::cachedInfo::re_initialize()
00415 {
00416 use_warm_start_in_cache_ = false;
00417
00418
00419 for (int i=0; i<mxws; i++) {
00420 ws[i] = 42.;
00421 }
00422 for (int i=0; i<mxlws; i++) {
00423 lws[i] = 55;
00424 }
00425 }
00426
00428 TNLPSolver::ReturnStatus BqpdSolver::callOptimizer() {
00429 #ifdef TIME_BQPD
00430 times().numsolve++;
00431 #endif
00432 cached_->optimize();
00433
00434 TNLPSolver::ReturnStatus optimizationStatus = TNLPSolver::exception;
00435 Ipopt::SolverReturn status = Ipopt::INTERNAL_ERROR;
00436 fint ifail = cached_->ifail;
00437 switch (ifail) {
00438 case 0:
00439 optimizationStatus = TNLPSolver::solvedOptimal;
00440 status = Ipopt::SUCCESS;
00441 break;
00442 case 1:
00443 optimizationStatus = TNLPSolver::unbounded;
00444 status = Ipopt::DIVERGING_ITERATES;
00445 case 2:
00446 case 3:
00447 optimizationStatus = TNLPSolver::provenInfeasible;
00448 status = Ipopt::LOCAL_INFEASIBILITY;
00449 break;
00450 }
00451
00452 Ipopt::Index dummy_len = std::max(cached_->n,cached_->m);
00453 Ipopt::Number* dummy = new Ipopt::Number[dummy_len];
00454 for (int i=0; i<dummy_len; i++) {
00455 dummy[i] = 0.;
00456 }
00457
00458 cached_->tqp_->finalize_solution(status, cached_->n,
00459 cached_->x, dummy, dummy,
00460 cached_->m, dummy, dummy,
00461 cached_->f, NULL, NULL);
00462 delete [] dummy;
00463 return optimizationStatus;
00464 }
00465
00466 BqpdSolver::cachedInfo::~cachedInfo()
00467 {
00468 if (haveHotStart_) {
00469 unmarkHotStart();
00470 }
00471 delete [] a;
00472 delete [] la;
00473 delete [] x;
00474 delete [] bl;
00475 delete [] bu;
00476 delete [] g;
00477 delete [] r;
00478 delete [] w;
00479 delete [] e;
00480 delete [] ls;
00481 delete [] alp;
00482 delete [] lp;
00483 delete [] ws;
00484 delete [] lws;
00485 }
00486
00487 bool
00488 BqpdSolver::cachedInfo::markHotStart()
00489 {
00490 next_reinit_ = BqpdSolver::reinit_freq_;
00491 #ifdef DISABLE_COPYING
00492 return 1;
00493 #endif
00494 #ifdef TIME_BQPD
00495 times_.warm_start -= CoinCpuTime();
00496 #endif
00497 haveHotStart_ = true;
00498 irh1 = F77_FUNC(bqpdc,BQPDC).irh1;
00499 na = F77_FUNC(bqpdc,BQPDC).na;
00500 na1 = F77_FUNC(bqpdc,BQPDC).na1;
00501 nb = F77_FUNC(bqpdc,BQPDC).nb;
00502 nb1 = F77_FUNC(bqpdc,BQPDC).nb1;
00503 ka1 = F77_FUNC(bqpdc,BQPDC).ka1;
00504 kb1 = F77_FUNC(bqpdc,BQPDC).kb1;
00505 kc1 = F77_FUNC(bqpdc,BQPDC).kc1;
00506 irg1 = F77_FUNC(bqpdc,BQPDC).irg1;
00507 lu1 = F77_FUNC(bqpdc,BQPDC).lu1;
00508 lv = F77_FUNC(bqpdc,BQPDC).lv;
00509 lv1 = F77_FUNC(bqpdc,BQPDC).lv1;
00510 ll1 = F77_FUNC(bqpdc,BQPDC).ll1;
00511 eps = F77_FUNC(epsc,EPSC).eps;
00512 tol = F77_FUNC(epsc,EPSC).tol;
00513 emin = F77_FUNC(epsc,EPSC).emin;
00514 vstep = F77_FUNC(vstepc,VSTEPC).vstep;
00515 sgnf = F77_FUNC(repc,REPC).sgnf;
00516 nrep = F77_FUNC(repc,REPC).nrep;
00517 npiv = F77_FUNC(repc,REPC).npiv;
00518 nres = F77_FUNC(repc,REPC).nres;
00519 nup = F77_FUNC(refactorc,REFACTORC).nup;
00520 nfreq = F77_FUNC(refactorc,REFACTORC).nfreq;
00521 alpha = F77_FUNC(alphac,ALPHAC).alpha;
00522
00523 ns = F77_FUNC(sparsec,SPARSEC).ns;
00524 ns1 = F77_FUNC(sparsec,SPARSEC).ns1;
00525 nt = F77_FUNC(sparsec,SPARSEC).nt;
00526 nt1 = F77_FUNC(sparsec,SPARSEC).nt1;
00527 nu = F77_FUNC(sparsec,SPARSEC).nu;
00528 nu1 = F77_FUNC(sparsec,SPARSEC).nu1;
00529 nx = F77_FUNC(sparsec,SPARSEC).nx;
00530 nx1 = F77_FUNC(sparsec,SPARSEC).nx1;
00531 np = F77_FUNC(sparsec,SPARSEC).np;
00532 np1 = F77_FUNC(sparsec,SPARSEC).np1;
00533 nprof = F77_FUNC(sparsec,SPARSEC).nprof;
00534 lc = F77_FUNC(sparsec,SPARSEC).lc;
00535 lc1 = F77_FUNC(sparsec,SPARSEC).lc1;
00536 li = F77_FUNC(sparsec,SPARSEC).li;
00537 li1 = F77_FUNC(sparsec,SPARSEC).li1;
00538 lm = F77_FUNC(sparsec,SPARSEC).lm;
00539 lm1 = F77_FUNC(sparsec,SPARSEC).lm1;
00540 lp_ = F77_FUNC(sparsec,SPARSEC).lp_;
00541 lp1 = F77_FUNC(sparsec,SPARSEC).lp1;
00542 lq = F77_FUNC(sparsec,SPARSEC).lq;
00543 lq1 = F77_FUNC(sparsec,SPARSEC).lq1;
00544 lr = F77_FUNC(sparsec,SPARSEC).lr;
00545 lr1 = F77_FUNC(sparsec,SPARSEC).lr1;
00546 ls_ = F77_FUNC(sparsec,SPARSEC).ls_;
00547 ls1 = F77_FUNC(sparsec,SPARSEC).ls1;
00548 lt = F77_FUNC(sparsec,SPARSEC).lt;
00549 lt1 = F77_FUNC(sparsec,SPARSEC).lt1;
00550
00551 m1 = F77_FUNC(factorc,FACTORC).m1;
00552 m2 = F77_FUNC(factorc,FACTORC).m2;
00553 mp = F77_FUNC(factorc,FACTORC).mp;
00554 mq = F77_FUNC(factorc,FACTORC).mq;
00555 lastr = F77_FUNC(factorc,FACTORC).lastr;
00556 irow = F77_FUNC(factorc,FACTORC).irow;
00557
00558 mxm1 = F77_FUNC(mxm1c,MXM1c).mxm1;
00559 c = F77_FUNC(minorc,MINORC).c;
00560
00561 kkHot = F77_FUNC(wsc,WSC).kk;
00562 kkkHot = F77_FUNC(wsc,WSC).kkk;
00563 llHot = F77_FUNC(wsc,WSC).ll;
00564 lllHot = F77_FUNC(wsc,WSC).lll;
00565
00566 kHot = k;
00567 xHot = CoinCopyOfArray(x,n);
00568 fHot = f;
00569 gHot = CoinCopyOfArray(g,n);
00570 rHot = CoinCopyOfArray(r,n+m);
00571 wHot = CoinCopyOfArray(w,n+m);
00572 eHot = CoinCopyOfArray(e,n+m);
00573 lsHot = CoinCopyOfArray(ls,n+m);
00574 alpHot = CoinCopyOfArray(alp,mlp);
00575 lpHot = CoinCopyOfArray(lp,mlp);
00576 peqHot = peq;
00577 wsHot = CoinCopyOfArray(ws,mxws);
00578 lwsHot = CoinCopyOfArray(lws,mxlws);
00579 infoHot[0] = info[0];
00580 #ifdef TIME_BQPD
00581 times_.warm_start += CoinCpuTime();
00582 #endif
00583
00584 return true;
00585 }
00586
00587 void
00588 BqpdSolver::cachedInfo::copyFromHotStart()
00589 {
00590 #ifdef DISABLE_COPYING
00591 return;
00592 #endif
00593 #ifdef TIME_BQPD
00594 times_.warm_start -= CoinCpuTime();
00595 #endif
00596 F77_FUNC(bqpdc,BQPDC).irh1 = irh1;
00597 F77_FUNC(bqpdc,BQPDC).na = na;
00598 F77_FUNC(bqpdc,BQPDC).na1 = na1;
00599 F77_FUNC(bqpdc,BQPDC).nb = nb;
00600 F77_FUNC(bqpdc,BQPDC).nb1 = nb1;
00601 F77_FUNC(bqpdc,BQPDC).ka1 = ka1;
00602 F77_FUNC(bqpdc,BQPDC).kb1 = kb1;
00603 F77_FUNC(bqpdc,BQPDC).kc1 = kc1;
00604 F77_FUNC(bqpdc,BQPDC).irg1 = irg1;
00605 F77_FUNC(bqpdc,BQPDC).lu1 = lu1;
00606 F77_FUNC(bqpdc,BQPDC).lv = lv;
00607 F77_FUNC(bqpdc,BQPDC).lv1 = lv1;
00608 F77_FUNC(bqpdc,BQPDC).ll1 = ll1;
00609 F77_FUNC(epsc,EPSC).eps = eps;
00610 F77_FUNC(epsc,EPSC).tol = tol;
00611 F77_FUNC(epsc,EPSC).emin = emin;
00612 F77_FUNC(vstepc,VSTEPC).vstep = vstep;
00613 F77_FUNC(repc,REPC).sgnf = sgnf;
00614 F77_FUNC(repc,REPC).nrep = nrep;
00615 F77_FUNC(repc,REPC).npiv = npiv;
00616 F77_FUNC(repc,REPC).nres = nres;
00617 F77_FUNC(refactorc,REFACTORC).nup = nup;
00618 F77_FUNC(refactorc,REFACTORC).nfreq = nfreq;
00619 F77_FUNC(alphac,ALPHAC).alpha = alpha;
00620
00621 F77_FUNC(sparsec,SPARSEC).ns = ns;
00622 F77_FUNC(sparsec,SPARSEC).ns1 = ns1;
00623 F77_FUNC(sparsec,SPARSEC).nt = nt;
00624 F77_FUNC(sparsec,SPARSEC).nt1 = nt1;
00625 F77_FUNC(sparsec,SPARSEC).nu = nu;
00626 F77_FUNC(sparsec,SPARSEC).nu1 = nu1;
00627 F77_FUNC(sparsec,SPARSEC).nx = nx;
00628 F77_FUNC(sparsec,SPARSEC).nx1 = nx1;
00629 F77_FUNC(sparsec,SPARSEC).np = np;
00630 F77_FUNC(sparsec,SPARSEC).np1 = np1;
00631 F77_FUNC(sparsec,SPARSEC).nprof = nprof;
00632 F77_FUNC(sparsec,SPARSEC).lc = lc;
00633 F77_FUNC(sparsec,SPARSEC).lc1 = lc1;
00634 F77_FUNC(sparsec,SPARSEC).li = li;
00635 F77_FUNC(sparsec,SPARSEC).li1 = li1;
00636 F77_FUNC(sparsec,SPARSEC).lm = lm;
00637 F77_FUNC(sparsec,SPARSEC).lm1 = lm1;
00638 F77_FUNC(sparsec,SPARSEC).lp_ = lp_;
00639 F77_FUNC(sparsec,SPARSEC).lp1 = lp1;
00640 F77_FUNC(sparsec,SPARSEC).lq = lq;
00641 F77_FUNC(sparsec,SPARSEC).lq1 = lq1;
00642 F77_FUNC(sparsec,SPARSEC).lr = lr;
00643 F77_FUNC(sparsec,SPARSEC).lr1 = lr1;
00644 F77_FUNC(sparsec,SPARSEC).ls_ = ls_;
00645 F77_FUNC(sparsec,SPARSEC).ls1 = ls1;
00646 F77_FUNC(sparsec,SPARSEC).lt = lt;
00647 F77_FUNC(sparsec,SPARSEC).lt1 = lt1;
00648
00649 F77_FUNC(factorc,FACTORC).m1 = m1;
00650 F77_FUNC(factorc,FACTORC).m2 = m2;
00651 F77_FUNC(factorc,FACTORC).mp = mp;
00652 F77_FUNC(factorc,FACTORC).mq = mq;
00653 F77_FUNC(factorc,FACTORC).lastr = lastr;
00654 F77_FUNC(factorc,FACTORC).irow = irow;
00655
00656 F77_FUNC(mxm1c,MXM1c).mxm1 = mxm1;
00657 F77_FUNC(minorc,MINORC).c = c;
00658
00659 F77_FUNC(wsc,WSC).kk = kkHot;
00660 F77_FUNC(wsc,WSC).kkk = kkkHot;
00661 F77_FUNC(wsc,WSC).ll = llHot;
00662 F77_FUNC(wsc,WSC).lll = lllHot;
00663
00664 k = kHot;
00665 CoinCopyN(xHot,n,x);
00666 f = fHot;
00667 CoinCopyN(gHot,n,g);
00668 CoinCopyN(rHot,n+m,r);
00669 CoinCopyN(wHot,n+m,w);
00670 CoinCopyN(eHot,n+m,e);
00671 CoinCopyN(lsHot,n+m,ls);
00672 CoinCopyN(alpHot,mlp,alp);
00673 CoinCopyN(lpHot,mlp,lp);
00674 CoinCopyN(wsHot,mxws,ws);
00675 CoinCopyN(lwsHot,mxlws,lws);
00676 info[0] = infoHot[0];
00677 peq = peqHot;
00678 #ifdef TIME_BQPD
00679 times_.warm_start += CoinCpuTime();
00680 #endif
00681
00682 }
00683
00684 void
00685 BqpdSolver::cachedInfo::unmarkHotStart()
00686 {
00687 delete [] xHot;
00688 delete [] gHot;
00689 delete [] rHot;
00690 delete [] wHot;
00691 delete [] eHot;
00692 delete [] lsHot;
00693 delete [] alpHot;
00694 delete [] lpHot;
00695 delete [] wsHot;
00696 delete [] lwsHot;
00697 haveHotStart_ = false;
00698 }
00699
00701 void
00702 BqpdSolver::cachedInfo::optimize()
00703 {
00704
00705 F77_FUNC(scalec,SCALEC).scale_mode = 0;
00706 F77_FUNC(scalec,SCALEC).phe = 0;
00707 F77_FUNC(hessc,HESSC).phl = 1;
00708 F77_FUNC(wsc,WSC).kk = kk;
00709 F77_FUNC(wsc,WSC).ll = ll;
00710 F77_FUNC(wsc,WSC).mxws = mxws;
00711 F77_FUNC(wsc,WSC).mxlws = mxlws;
00712
00713 if (use_warm_start_in_cache_ && !bad_warm_start_info_) {
00714 ifail = 0;
00715 use_warm_start_in_cache_ = false;
00716 if (haveHotStart_ && pivots_ > next_reinit_) {
00717
00718 copyFromHotStart();
00719 while (BqpdSolver::reinit_freq_ > 0&& next_reinit_ < pivots_)
00720 next_reinit_ += BqpdSolver::reinit_freq_;
00721 }
00722 }
00723 else {
00724 m0de = 0;
00725 tqp_->get_starting_point(n, 1, x, 0, NULL, NULL, m, 0, NULL);
00726 ifail = 0;
00727 bad_warm_start_info_ = false;
00728 }
00729
00730 #if 0
00731 printf("========= 222222222222 =============\n");
00732 printf("kk = %d ll = %d mxws = %d mxlws = %d\n", kk, ll, mxws, mxlws);
00733 for (int i=0; i<n; i++) {
00734 printf("xL[%3d] = %15.8e xU[%3d] = %15.8e\n", i, bl[i], i, bu[i]);
00735 }
00736 for (int i=0; i<m; i++) {
00737 printf("gL[%3d] = %15.8e gU[%3d] = %15.8e\n", i, bl[n+i], i, bu[n+i]);
00738 }
00739 #endif
00740 cpuTime_ = - CoinCpuTime();
00741 real fmin = -1e100;
00742 #if 0
00743 for (int i=0; i<n; i++) {
00744 printf("qxstart[%2d] = %23.16e\n", i, x[i]);
00745 }
00746 #endif
00747
00748 #ifdef WRITE_QPS
00749 if (m0de==0) {
00750 FILE* fp = fopen("QPinit.dat", "w");
00751 fprintf(fp, "n = %d\n", n);
00752 fprintf(fp, "m = %d\n", m);
00753 fprintf(fp, "kmax = %d\n", kmax);
00754 fprintf(fp, "amax = %d\n" ,amax_);
00755 for (int i=1; i<=amax_; i++) {
00756 fprintf(fp, "a = %23.16e\n", a[i-1]);
00757 }
00758 int lamax = amax_ + m + 2;
00759 fprintf(fp, "lamax = %d\n" ,lamax);
00760 for (int i=1; i<=lamax+1; i++) {
00761 fprintf(fp, "la = %6d\n", la[i-1]);
00762 }
00763 for (int i=1; i<=n; i++) {
00764 fprintf(fp, "x = %23.16e\n", x[i-1]);
00765 }
00766 for (int i=1; i<=n+m; i++) {
00767 fprintf(fp, "bl = %23.16e\n", bl[i-1]);
00768 }
00769 for (int i=1; i<=n+m; i++) {
00770 fprintf(fp, "bu = %23.16e\n", bu[i-1]);
00771 }
00772 fprintf(fp, "fmin = %23.16e\n", fmin);
00773 fprintf(fp, "mlp = %6d\n", mlp);
00774 fprintf(fp, "mxws = %d\n", mxws);
00775 fprintf(fp, "mxlws = %d\n", mxlws);
00776 fclose(fp);
00777 }
00778 else {
00779 FILE* fp = fopen("QPbounds.dat", "w");
00780 fprintf(fp, "m0de = %d\n", m0de);
00781 for (int i=1; i<=n+m; i++) {
00782 fprintf(fp, "bl = %23.16e\n", bl[i-1]);
00783 }
00784 for (int i=1; i<=n+m; i++) {
00785 fprintf(fp, "bu = %23.16e\n", bu[i-1]);
00786 }
00787 fclose(fp);
00788 }
00789 #endif
00790 F77_FUNC(bqpd,BQPD)(&n, &m, &k, &kmax, a, la, x, bl, bu, &f, &fmin,
00791 g, r, w, e, ls, alp, lp, &mlp, &peq, ws, lws,
00792 &m0de, &ifail, info, &iprint, &nout);
00793 #ifdef TIME_BQPD
00794 times_.pivots += info[0];
00795 #endif
00796 pivots_ += info[0];
00797 if(BqpdSolver::reinit_freq_ > 0 && haveHotStart_ && (ifail == 7 || ifail == 8) && m0de == 6){
00798 fprintf(stdout, "Reinitialize hot start...\n");
00799 copyFromHotStart();
00800 ifail = 0;
00801 F77_FUNC(bqpd,BQPD)(&n, &m, &k, &kmax, a, la, x, bl, bu, &f, &fmin,
00802 g, r, w, e, ls, alp, lp, &mlp, &peq, ws, lws,
00803 &m0de, &ifail, info, &iprint, &nout);
00804 printf("new ifail = %d\n", ifail);
00805 }
00806 if (ifail == 8 && BqpdSolver::m0de_ == 6) {
00807 fprintf(stdout, "Restarting Bqpd...");
00808 m0de = 0;
00809 tqp_->get_starting_point(n, 1, x, 0, NULL, NULL, m, 0, NULL);
00810 ifail = 0;
00811 F77_FUNC(bqpd,BQPD)(&n, &m, &k, &kmax, a, la, x, bl, bu, &f, &fmin,
00812 g, r, w, e, ls, alp, lp, &mlp, &peq, ws, lws,
00813 &m0de, &ifail, info, &iprint, &nout);
00814 printf("new ifail = %d\n", ifail);
00815 }
00816 while (ifail == 7) {
00817
00818 if (haveHotStart_) unmarkHotStart();
00819
00820 printf("Increasing fillin_factor from %e ", *fillin_factor_);
00821 *fillin_factor_ *= 2.;
00822 printf("to %e\n", *fillin_factor_);
00823 int mxws_new = kk + F77_FUNC(wsc,WSC).kkk + (5*n + (int)(*fillin_factor_*(double)amax_));
00824 real* ws_new = new real[mxws_new];
00825 #ifdef InitializeAll
00826 for (int i=0; i<mxws_new; i++) {
00827 ws_new[i] = 42.;
00828 }
00829 #endif
00830 CoinCopyN(ws, kk, ws_new);
00831 delete [] ws;
00832 ws = ws_new;
00833 mxws = mxws_new;
00834 F77_FUNC(wsc,WSC).mxws = mxws;
00835
00836 m0de = 0;
00837 tqp_->get_starting_point(n, 1, x, 0, NULL, NULL, m, 0, NULL);
00838 ifail = 0;
00839 F77_FUNC(bqpd,BQPD)(&n, &m, &k, &kmax, a, la, x, bl, bu, &f, &fmin,
00840 g, r, w, e, ls, alp, lp, &mlp, &peq, ws, lws,
00841 &m0de, &ifail, info, &iprint, &nout);
00842 }
00843 if (ifail == 8) bad_warm_start_info_ = true;
00844 #if 0
00845 for (int i=0; i<n; i++) {
00846 printf("qxsol[%2d] = %23.16e\n", i, x[i]);
00847 }
00848 #endif
00849 #if 0
00850 printf("ifail = %d\n", ifail);
00851 printf("final f = %e\n", f);
00852 printf("final f + obj_val = %e\n", f+tqp_->ObjVal());
00853 #endif
00854 #if 0
00855 int kkk = F77_FUNC(wsc,WSC).kkk;
00856 int lll = F77_FUNC(wsc,WSC).lll;
00857 printf("========= 3333333333 =============\n");
00858 printf("kk = %d ll = %d kkk = %d lll = %d mxws = %d mxlws = %d\n", kk, ll, kkk, lll, mxws, mxlws);
00859 for (int i=0; i<kk+kkk; i++) {
00860 printf("ws[%3d] = %15.8e\n ", i, ws[i]);
00861 }
00862 printf("--------\n");
00863 for (int i=kk+kkk; i<mxws; i++) {
00864 printf("ws[%3d] = %15.8e\n ", i, ws[i]);
00865 }
00866 for (int i=0; i<ll+lll; i++) {
00867 printf("lws[%5d] = %8d\n", i, lws[i]);
00868 }
00869 printf("------\n");
00870 for (int i=ll+lll; i<mxlws; i++) {
00871 printf("lws[%5d] = %8d\n", i, lws[i]);
00872 }
00873 #endif
00874 cpuTime_ += CoinCpuTime();
00875 }
00876
00877 std::string
00878 BqpdSolver::UnsolvedBqpdError::errorNames_[1] =
00879 {"Internal error in Filter SQP."};
00880
00881 std::string
00882 BqpdSolver::UnsolvedBqpdError::solverName_ =
00883 "filterSqp";
00884
00885 const std::string&
00886 BqpdSolver::UnsolvedBqpdError::errorName() const
00887 {
00888 return errorNames_[0];
00889 }
00890
00891 const std::string&
00892 BqpdSolver::UnsolvedBqpdError::solverName() const
00893 {
00894 return solverName_;
00895 }
00896
00897 bool
00898 BqpdSolver::setWarmStart(const CoinWarmStart * warm,
00899 Ipopt::SmartPtr<TMINLP2TNLP> tnlp)
00900 {
00901 #if 0
00902 if (IsNull(cached_)) {
00903 cached_ = new cachedInfo(GetRawPtr(tnlp), options_);
00904 }
00905
00906 const FilterWarmStart * warmF = dynamic_cast<const FilterWarmStart *> (warm);
00907
00908 const fint xsize = warmF->xSize();
00909 real* x = cached_->x;
00910 const real* xarray = warmF->xArray();
00911 for (int i = 0; i<xsize; i++) {
00912 x[i] = xarray[i];
00913 }
00914 CoinCopyN(warmF->lamArray(), warmF->lamSize(), cached_->lam);
00915 CoinCopyN(warmF->lwsArray(), warmF->lwsSize(), cached_->lws);
00916 for (int i = 0 ; i < 14 ; i ++) {
00917 cached_->istat[i] = warmF->istat()[i];
00918 }
00919 cached_->use_warm_start_in_cache_ = true;
00920 #endif
00921 printf("BqpdSolver::setWarmStart called!\n");
00922 return true;
00923 }
00924
00925 CoinWarmStart *
00926 BqpdSolver::getWarmStart(Ipopt::SmartPtr<TMINLP2TNLP> tnlp) const
00927 {
00928 #if 0
00929 return new FilterWarmStart(cached_->n, cached_->x,
00930 cached_->n+cached_->m, cached_->lam,
00931 cached_->maxiWk, cached_->lws, cached_->istat);
00932 #endif
00933 printf("BqpdSolver::getWarmStart called!\n");
00934 return NULL;
00935 }
00936
00937 CoinWarmStart *
00938 BqpdSolver::getEmptyWarmStart() const
00939 {
00940 #if 0
00941 return new FilterWarmStart;
00942 #endif
00943 printf("BqpdSolver::getEmptyWarmStart called \n");
00944 return NULL;
00945 }
00946
00948 bool
00949 BqpdSolver::warmStartIsValid(const CoinWarmStart * ws) const{
00950 const BqpdWarmStart* bws = dynamic_cast<const BqpdWarmStart*>(ws);
00951 if (bws && ! bws->empty()) {
00952 return true;
00953 }
00954 return false;
00955 }
00956
00957 }