/home/coin/SVN-release/OS-2.4.0/Bonmin/src/Interfaces/Filter/BonBqpdSolver.cpp

Go to the documentation of this file.
00001 // (C) Copyright International Business Machines Corporation 2007, 2008
00002 // All Rights Reserved.
00003 // This code is published under the Common Public License.
00004 //
00005 // Authors :
00006 // Andreas Waechter, International Business Machines Corporation
00007 //                    based on BonFilterSolver.cpp
00008 //
00009 // Date : 07/09/2007
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   //Access to filter common blocks
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 /* = false */)
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_; // Copy the options
00151     retval->roptions_ = roptions_; // only copy pointers of registered options
00152     retval->journalist_ = journalist_; // and 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     // Make sure bounds are not infinity
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;  // Trying...
00249     cached_->m0de = m0de_;
00250 #else
00251     cached_->re_initialize();
00252     cached_->use_warm_start_in_cache_ = true;  // Trying...
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     // Maybe a dirty trick?  We want to change fillin_factor in calling object
00273     fillin_factor_ = fillin_factor;
00274 
00275     // In case BQPD's BLOCK DATA doesn't work, we initialize the COMMON
00276     // BLOCKs explicitly here
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     // Get space for arrays
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     // Getting the bounds
00316     tqp->get_bounds_info(n, bl, bu, m, bl+n, bu+n);
00317 
00318     // Make sure bounds are not infinity
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     // Set up sparse matrix with objective gradient and constraint Jacobian
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     // Objective function gradient
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     // Constraint Jacobian
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 //deleteme
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     // Setup workspaces
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     // Now setup Hessian
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 //deleteme
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     // Setup workspaces
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     // Set up some common block stuff
00705     F77_FUNC(scalec,SCALEC).scale_mode = 0;  // No scaling
00706     F77_FUNC(scalec,SCALEC).phe = 0;  // No scaling
00707     F77_FUNC(hessc,HESSC).phl = 1; // This is to tell gdotx to do the right thing
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         //printf("Reinitialize hot start\n");
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 //#define WRITE_QPS
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       // FIXME: For now, we just disable hot starts in case they were active
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     //CoinCopyN(warmF->xArray(), warmF->xSize(), cached_->x);
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 }//end namespace Bonmin

Generated on Thu Sep 22 03:05:55 2011 by  doxygen 1.4.7