BonBqpdSolver.cpp
Go to the documentation of this file.
1 // (C) Copyright International Business Machines Corporation 2007, 2008
2 // All Rights Reserved.
3 // This code is published under the Eclipse Public License.
4 //
5 // Authors :
6 // Andreas Waechter, International Business Machines Corporation
7 // based on BonFilterSolver.cpp
8 //
9 // Date : 07/09/2007
10 
11 #include "BonminConfig.h"
12 
13 #include "BonBqpdSolver.hpp"
14 #include "BonBqpdWarmStart.hpp"
15 
16 #include "CoinTime.hpp"
17 #include <algorithm>
18 
19 #define InitializeAll
20 
25 extern "C"
26 {
27  void F77_FUNC(bqpd,BQPD)(fint* n, fint* m, fint* k, fint* kmax,
28  real* a, fint* la, real* x, real* bl, real* bu,
29  real* f, real* fmin, real* g, real* r, real* w,
30  real* e, fint* ls, real* alp, fint* lp, fint* mlp,
31  fint* peq, real* ws, fint* lws, fint* m0de,
33 
34  //Access to filter common blocks
35  extern struct {
37  }
38  F77_FUNC(wsc,WSC);
39 
40  extern struct {
42  }
43  F77_FUNC(epsc,EPSC);
44 
45  extern struct {
48  }
49  F77_FUNC(repc,REPC);
50 
51  extern struct {
53  }
54  F77_FUNC(refactorc,REFACTORC);
55 
56  extern struct {
58  }
59  F77_FUNC(vstepc,VSTEPC);
60 
61  extern struct {
63  }
64  F77_FUNC(hessc,HESSC);
65 
66  extern struct {
68  }
69  F77_FUNC(scalec,SCALEC);
70 
71  extern struct {
73  }
74  F77_FUNC(bqpdc,BQPDC);
75 
76  extern struct {
78  }
79  F77_FUNC(alphac,ALPHAC);
80 
81  extern struct {
84  }
85  F77_FUNC(sparsec,SPARSEC);
86 
87  extern struct {
89  }
90  F77_FUNC(factorc,FACTORC);
91 
92  extern struct {
94  }
95  F77_FUNC(mxm1c,MXM1C);
96 
97  extern struct {
99  }
100  F77_FUNC(minorc,MINORS);
101 }
102 
103 namespace Bonmin
104 {
105 
106  std::string BqpdSolver::solverName_ = "Bqpd QP";
107 
108  void BqpdSolver::
110  {
111  roptions->SetRegisteringCategory("Bqpd options",RegisteredOptions::BqpdCategory);
112  roptions->AddLowerBoundedNumberOption("qp_fillin_factor", "Factor for estimating fill-in for factorization method in Bqpd", 0., true, 4.);
113  roptions->AddBoundedIntegerOption("hot_start_m0de", "Choice of the hot start option", 0, 6, 6);
114  roptions->AddLowerBoundedIntegerOption("reinit_freq", "Number of pivots before recopy hot start", 0, 0);
115  }
116 
117  BqpdSolver::BqpdSolver(bool createEmpty /* = false */)
118  :
119  TNLPSolver(),
120  cached_(NULL)
121  {
122  if (createEmpty) return;
123  }
124 
128  const std::string & prefix)
129  :
130  TNLPSolver(roptions, options, journalist, prefix),
131  cached_(NULL)
132  {
133  options->GetNumericValue("qp_fillin_factor", fillin_factor_, "bqpd.");
134  options->GetIntegerValue("kmax", kmax_ipt_, "bqpd.");
135  options->GetIntegerValue("mlp", mlp_ipt_,"bqpd.");
136  options->GetIntegerValue("hot_start_m0de", m0de_,"bqpd.");
137  options->GetIntegerValue("reinit_freq", reinit_freq_,"bqpd.");
138  if(!options_->GetIntegerValue("print_level",default_log_level_,""))
139  default_log_level_ = 1;
140 
141  }
142 
145  {
146 #ifdef TIME_BQPD
147  times().create -= CoinCpuTime();
148 #endif
149  Ipopt::SmartPtr<BqpdSolver> retval = new BqpdSolver(true);
150  *retval->options_ = *options_; // Copy the options
151  retval->roptions_ = roptions_; // only copy pointers of registered options
152  retval->journalist_ = journalist_; // and journalist
153  retval->prefix_ = prefix_;
154  retval->fillin_factor_ = fillin_factor_;
155  retval->kmax_ipt_ = kmax_ipt_;
156  retval->mlp_ipt_ = mlp_ipt_;
157  retval->default_log_level_ = default_log_level_;
158  retval->reinit_freq_ = reinit_freq_;
159  retval->m0de_ = m0de_;
160 #ifdef TIME_BQPD
161  times().create += CoinCpuTime();
162 #endif
163  return GetRawPtr(retval);
164  }
165 
167  {}
168 
169  bool
170  BqpdSolver::Initialize(std::string optFile)
171  {
172  std::ifstream is;
173  if (optFile != "") {
174  try {
175  is.open(optFile.c_str());
176  }
177  catch (std::bad_alloc) {
178  journalist_->Printf(Ipopt::J_SUMMARY, Ipopt::J_MAIN, "\nEXIT: Not enough memory.\n");
179  return false;
180  }
181 #ifndef NO_CATCH_ALL
182  catch (...) {
183  Ipopt::IpoptException E("Unknown Exception caught in ipopt", "Unknown File", -1);
184  E.ReportException(*journalist_);
185  return false;
186  }
187 #endif
188  }
189  bool retval = Initialize(is);
190  if (is) {
191  is.close();
192  }
193  if(!options_->GetIntegerValue("print_level",default_log_level_,""))
194  default_log_level_ = 1;
195  return retval;
196  }
197 
198  bool
199  BqpdSolver::Initialize(std::istream &is)
200  {
201  if (is.good()) {
202  options_->ReadFromStream(*journalist_, is);
203  }
204  return true;
205  }
206 
210  {
211  BranchingTQP* tqp = dynamic_cast<BranchingTQP*>(GetRawPtr(tnlp));
212  if (!tqp) {
213  Ipopt::IpoptException E("BqpdSolver called with object other than a BranchingTQP",
214  "BonBqpdSolver.cpp",-1);
215  throw E;
216  }
217  if (IsNull(cached_) || !cached_->use_warm_start_in_cache_) {
219  &fillin_factor_);
220  }
221 #ifdef TIME_BQPD
222  times().solve -= CoinCpuTime();
223 #endif
225 #ifdef TIME_BQPD
226  times().solve += CoinCpuTime();
227 #endif
228  return r_val;
229  }
230 
234  {
235 #ifndef NDEBUG
236  BranchingTQP* tqp = dynamic_cast<BranchingTQP*>(GetRawPtr(tnlp));
237  assert(tqp == GetRawPtr(cached_->tqp_));
238 #endif
239  int n = cached_->n;
240  int m = cached_->m;
241  tnlp->get_bounds_info(n, cached_->bl, cached_->bu,
242  m, cached_->bl+n, cached_->bu+n);
243  // Make sure bounds are not infinity
244  for (int i=0; i<n+m; i++) {
245  cached_->bl[i] = std::max(cached_->bl[i], -1e50);
246  cached_->bu[i] = std::min(cached_->bu[i], 1e50);
247  }
248 
249 #if 1
250  cached_->use_warm_start_in_cache_ = true; // Trying...
251  cached_->m0de = m0de_;
252 #else
253  cached_->re_initialize();
254  cached_->use_warm_start_in_cache_ = true; // Trying...
255 #endif
256 
257 #ifdef TIME_BQPD
258  times().resolve -= CoinCpuTime();
259 #endif
261 #ifdef TIME_BQPD
262  times().resolve += CoinCpuTime();
263 #endif
264  return r_val;
265  }
266 
267  void
270  int kmax_ipt,
271  int mlp_ipt,
272  double* fillin_factor)
273  {
274  // Maybe a dirty trick? We want to change fillin_factor in calling object
275  fillin_factor_ = fillin_factor;
276 
277  // In case BQPD's BLOCK DATA doesn't work, we initialize the COMMON
278  // BLOCKs explicitly here
279  F77_FUNC(epsc,EPSC).eps = 1111e-19;
280  F77_FUNC(epsc,EPSC).tol = 1e-12;
281  F77_FUNC(epsc,EPSC).emin = 1.;
282  F77_FUNC(repc,REPC).sgnf = 1e-4;
283  F77_FUNC(repc,REPC).nrep = 2;
284  F77_FUNC(repc,REPC).npiv = 3;
285  F77_FUNC(repc,REPC).nres = 2;
286  F77_FUNC(refactorc,REFACTORC).nfreq = 500;
287 
288  Ipopt::TNLP::IndexStyleEnum index_style;
289  Ipopt::Index nv, nc, nnz_jac_g, nnz_hess;
290  tqp->get_nlp_info(nv, nc, nnz_jac_g, nnz_hess, index_style);
291  n = nv;
292  m = nc;
293 
294  if (kmax_ipt == -1) {
295  kmax = n;
296  }
297  else {
298  kmax = kmax_ipt;
299  kmax = std::min(kmax,n);
300  }
301  mlp = mlp_ipt;
302 
303  use_warm_start_in_cache_ = false;
304 
305  // Get space for arrays
306  x = new real[n];
307  bl = new real[n+m];
308  bu = new real[n+m];
309  g = new real[n];
310  r = new real[n+m];
311  w = new real[n+m];
312  e = new real[n+m];
313  ls = new fint[n+m];
314  alp = new real[mlp];
315  lp = new fint[mlp];
316 
317  // Getting the bounds
318  tqp->get_bounds_info(n, bl, bu, m, bl+n, bu+n);
319 
320  // Make sure bounds are not infinity
321  for (int i=0; i<n+m; i++) {
322  bl[i] = std::max(bl[i], -1e50);
323  bu[i] = std::min(bu[i], 1e50);
324  }
325 
326  // Set up sparse matrix with objective gradient and constraint Jacobian
327 
328  const Ipopt::Number* obj_grad = tqp->ObjGrad();
329  amax_ = nnz_jac_g;
330  for (int i = 0; i<n; i++) {
331  if (obj_grad[i]!=0.) {
332  amax_++;
333  }
334  }
335  int lamax = amax_+m+2;
336  a = new real[amax_];
337  la = new fint [1+lamax];
338 
339  // Objective function gradient
340  int nnz_grad = 0;
341  for (int i = 0; i < n ; i++) {
342  if (obj_grad[i]!=0.) {
343  a[nnz_grad] = obj_grad[i];
344  la[++nnz_grad] = i+1;
345  }
346  }
347  la[amax_+1] = 1;
348 
349  // Constraint Jacobian
350  const Ipopt::Number* JacVals = tqp->ConstrJacVals();
351  const Ipopt::Index* RowJac = tqp->ConstrJacIRow();
352  const Ipopt::Index* ColJac = tqp->ConstrJacJCol();
353 
354  int* permutationJac = new int [nnz_jac_g];
355  FilterSolver::TMat2RowPMat(false, n, m, nnz_jac_g, RowJac, ColJac, permutationJac,
356  la, nnz_grad, 1, Ipopt::TNLP::C_STYLE);
357  for (int i=0; i<nnz_jac_g; i++) {
358  const int& indice = permutationJac[i];
359  a[nnz_grad+i] = JacVals[indice];
360  }
361  delete [] permutationJac;
362 #if 0
363 //deleteme
364  printf("nnz_grad = %d nnz_jac = %d\n", nnz_grad, nnz_jac_g);
365  for (int i=0; i<1+lamax; i++) printf("la[%2d] = %d\n", i,la[i]);
366  for (int i=0; i<amax_; i++) printf("a[%3d] = %e\n",i,a[i]);
367 #endif
368 
369  // Setup workspaces
370  mxws = nnz_hess + ((kmax*(kmax+9))/2 + 2*n + m) + (5*n + (int)(*fillin_factor_*(double)amax_));
371  mxlws = (nnz_hess + n + 2) + kmax + (9*n + m);
372 
373  ws = new real[mxws];
374  lws = new fint[mxlws];
375 
376 #ifdef InitializeAll
377  for (int i=0; i<mxws; i++) {
378  ws[i] = 42.;
379  }
380  for (int i=0; i<mxlws; i++) {
381  lws[i] = 55;
382  }
383 #endif
384 
385  // Now setup Hessian
386  const Ipopt::Number* HessVals = tqp->ObjHessVals();
387  const Ipopt::Index* RowHess = tqp->ObjHessIRow();
388  const Ipopt::Index* ColHess = tqp->ObjHessJCol();
389 
390  kk = nnz_hess;
391  ll = nnz_hess + n + 2;
392  int* permutationHess = new int[nnz_hess];
393 
394  FilterSolver::TMat2RowPMat(true, n, n, nnz_hess, RowHess, ColHess,
395  permutationHess, lws, 0, 0, Ipopt::TNLP::C_STYLE);
396  for (int i=0; i<nnz_hess; i++) {
397  ws[i] = HessVals[permutationHess[i]];
398  }
399  delete [] permutationHess;
400 #if 0
401 //deleteme
402  printf("nnz_hess = %d\n", nnz_hess);
403  for (int i=0; i<ll; i++) printf("hess lws[%2d] = %d\n", i,lws[i]);
404  for (int i=0; i<kk; i++) printf("hess ws[%3d] = %e\n",i,ws[i]);
405 #endif
406 
407  Ipopt::Index bufy;
408  options->GetIntegerValue("iprint",bufy, "bqpd.");
409  iprint = bufy;
410  nout = 6;
411 
412  tqp_ = tqp;
413  }
414 
415  void
417  {
418  use_warm_start_in_cache_ = false;
419 
420  // Setup workspaces
421  for (int i=0; i<mxws; i++) {
422  ws[i] = 42.;
423  }
424  for (int i=0; i<mxlws; i++) {
425  lws[i] = 55;
426  }
427  }
428 
431 #ifdef TIME_BQPD
432  times().numsolve++;
433 #endif
434  cached_->optimize();
435 
436  TNLPSolver::ReturnStatus optimizationStatus = TNLPSolver::exception;
437  Ipopt::SolverReturn status = Ipopt::INTERNAL_ERROR;
438  fint ifail = cached_->ifail;
439  switch (ifail) {
440  case 0:
441  optimizationStatus = TNLPSolver::solvedOptimal;
442  status = Ipopt::SUCCESS;
443  break;
444  case 1:
445  optimizationStatus = TNLPSolver::unbounded;
446  status = Ipopt::DIVERGING_ITERATES;
447  case 2:
448  case 3:
449  optimizationStatus = TNLPSolver::provenInfeasible;
450  status = Ipopt::LOCAL_INFEASIBILITY;
451  break;
452  }
453 
454  Ipopt::Index dummy_len = std::max(cached_->n,cached_->m);
455  Ipopt::Number* dummy = new Ipopt::Number[dummy_len];
456  for (int i=0; i<dummy_len; i++) {
457  dummy[i] = 0.;
458  }
459 
460  cached_->tqp_->finalize_solution(status, cached_->n,
461  cached_->x, dummy, dummy,
462  cached_->m, dummy, dummy,
463  cached_->f, NULL, NULL);
464  delete [] dummy;
465  return optimizationStatus;
466  }
467 
469  {
470  if (haveHotStart_) {
471  unmarkHotStart();
472  }
473  delete [] a;
474  delete [] la;
475  delete [] x;
476  delete [] bl;
477  delete [] bu;
478  delete [] g;
479  delete [] r;
480  delete [] w;
481  delete [] e;
482  delete [] ls;
483  delete [] alp;
484  delete [] lp;
485  delete [] ws;
486  delete [] lws;
487  }
488 
489  bool
491  {
492  next_reinit_ = BqpdSolver::reinit_freq_;
493 #ifdef DISABLE_COPYING
494  return 1;
495 #endif
496 #ifdef TIME_BQPD
497  times_.warm_start -= CoinCpuTime();
498 #endif
499  haveHotStart_ = true;
500  irh1 = F77_FUNC(bqpdc,BQPDC).irh1;
501  na = F77_FUNC(bqpdc,BQPDC).na;
502  na1 = F77_FUNC(bqpdc,BQPDC).na1;
503  nb = F77_FUNC(bqpdc,BQPDC).nb;
504  nb1 = F77_FUNC(bqpdc,BQPDC).nb1;
505  ka1 = F77_FUNC(bqpdc,BQPDC).ka1;
506  kb1 = F77_FUNC(bqpdc,BQPDC).kb1;
507  kc1 = F77_FUNC(bqpdc,BQPDC).kc1;
508  irg1 = F77_FUNC(bqpdc,BQPDC).irg1;
509  lu1 = F77_FUNC(bqpdc,BQPDC).lu1;
510  lv = F77_FUNC(bqpdc,BQPDC).lv;
511  lv1 = F77_FUNC(bqpdc,BQPDC).lv1;
512  ll1 = F77_FUNC(bqpdc,BQPDC).ll1;
513  eps = F77_FUNC(epsc,EPSC).eps;
514  tol = F77_FUNC(epsc,EPSC).tol;
515  emin = F77_FUNC(epsc,EPSC).emin;
516  vstep = F77_FUNC(vstepc,VSTEPC).vstep;
517  sgnf = F77_FUNC(repc,REPC).sgnf;
518  nrep = F77_FUNC(repc,REPC).nrep;
519  npiv = F77_FUNC(repc,REPC).npiv;
520  nres = F77_FUNC(repc,REPC).nres;
521  nup = F77_FUNC(refactorc,REFACTORC).nup;
522  nfreq = F77_FUNC(refactorc,REFACTORC).nfreq;
523  alpha = F77_FUNC(alphac,ALPHAC).alpha;
524 
525  ns = F77_FUNC(sparsec,SPARSEC).ns;
526  ns1 = F77_FUNC(sparsec,SPARSEC).ns1;
527  nt = F77_FUNC(sparsec,SPARSEC).nt;
528  nt1 = F77_FUNC(sparsec,SPARSEC).nt1;
529  nu = F77_FUNC(sparsec,SPARSEC).nu;
530  nu1 = F77_FUNC(sparsec,SPARSEC).nu1;
531  nx = F77_FUNC(sparsec,SPARSEC).nx;
532  nx1 = F77_FUNC(sparsec,SPARSEC).nx1;
533  np = F77_FUNC(sparsec,SPARSEC).np;
534  np1 = F77_FUNC(sparsec,SPARSEC).np1;
535  nprof = F77_FUNC(sparsec,SPARSEC).nprof;
536  lc = F77_FUNC(sparsec,SPARSEC).lc;
537  lc1 = F77_FUNC(sparsec,SPARSEC).lc1;
538  li = F77_FUNC(sparsec,SPARSEC).li;
539  li1 = F77_FUNC(sparsec,SPARSEC).li1;
540  lm = F77_FUNC(sparsec,SPARSEC).lm;
541  lm1 = F77_FUNC(sparsec,SPARSEC).lm1;
542  lp_ = F77_FUNC(sparsec,SPARSEC).lp_;
543  lp1 = F77_FUNC(sparsec,SPARSEC).lp1;
544  lq = F77_FUNC(sparsec,SPARSEC).lq;
545  lq1 = F77_FUNC(sparsec,SPARSEC).lq1;
546  lr = F77_FUNC(sparsec,SPARSEC).lr;
547  lr1 = F77_FUNC(sparsec,SPARSEC).lr1;
548  ls_ = F77_FUNC(sparsec,SPARSEC).ls_;
549  ls1 = F77_FUNC(sparsec,SPARSEC).ls1;
550  lt = F77_FUNC(sparsec,SPARSEC).lt;
551  lt1 = F77_FUNC(sparsec,SPARSEC).lt1;
552 
553  m1 = F77_FUNC(factorc,FACTORC).m1;
554  m2 = F77_FUNC(factorc,FACTORC).m2;
555  mp = F77_FUNC(factorc,FACTORC).mp;
556  mq = F77_FUNC(factorc,FACTORC).mq;
557  lastr = F77_FUNC(factorc,FACTORC).lastr;
558  irow = F77_FUNC(factorc,FACTORC).irow;
559 
560  mxm1 = F77_FUNC(mxm1c,MXM1c).mxm1;
561  c = F77_FUNC(minorc,MINORC).c;
562 
563  kkHot = F77_FUNC(wsc,WSC).kk;
564  kkkHot = F77_FUNC(wsc,WSC).kkk;
565  llHot = F77_FUNC(wsc,WSC).ll;
566  lllHot = F77_FUNC(wsc,WSC).lll;
567 
568  kHot = k;
569  xHot = CoinCopyOfArray(x,n);
570  fHot = f;
571  gHot = CoinCopyOfArray(g,n);
572  rHot = CoinCopyOfArray(r,n+m);
573  wHot = CoinCopyOfArray(w,n+m);
574  eHot = CoinCopyOfArray(e,n+m);
575  lsHot = CoinCopyOfArray(ls,n+m);
576  alpHot = CoinCopyOfArray(alp,mlp);
577  lpHot = CoinCopyOfArray(lp,mlp);
578  peqHot = peq;
579  wsHot = CoinCopyOfArray(ws,mxws);
580  lwsHot = CoinCopyOfArray(lws,mxlws);
581  infoHot[0] = info[0];
582 #ifdef TIME_BQPD
583  times_.warm_start += CoinCpuTime();
584 #endif
585 
586  return true;
587  }
588 
589  void
591  {
592 #ifdef DISABLE_COPYING
593  return;
594 #endif
595 #ifdef TIME_BQPD
596  times_.warm_start -= CoinCpuTime();
597 #endif
598  F77_FUNC(bqpdc,BQPDC).irh1 = irh1;
599  F77_FUNC(bqpdc,BQPDC).na = na;
600  F77_FUNC(bqpdc,BQPDC).na1 = na1;
601  F77_FUNC(bqpdc,BQPDC).nb = nb;
602  F77_FUNC(bqpdc,BQPDC).nb1 = nb1;
603  F77_FUNC(bqpdc,BQPDC).ka1 = ka1;
604  F77_FUNC(bqpdc,BQPDC).kb1 = kb1;
605  F77_FUNC(bqpdc,BQPDC).kc1 = kc1;
606  F77_FUNC(bqpdc,BQPDC).irg1 = irg1;
607  F77_FUNC(bqpdc,BQPDC).lu1 = lu1;
608  F77_FUNC(bqpdc,BQPDC).lv = lv;
609  F77_FUNC(bqpdc,BQPDC).lv1 = lv1;
610  F77_FUNC(bqpdc,BQPDC).ll1 = ll1;
611  F77_FUNC(epsc,EPSC).eps = eps;
612  F77_FUNC(epsc,EPSC).tol = tol;
613  F77_FUNC(epsc,EPSC).emin = emin;
614  F77_FUNC(vstepc,VSTEPC).vstep = vstep;
615  F77_FUNC(repc,REPC).sgnf = sgnf;
616  F77_FUNC(repc,REPC).nrep = nrep;
617  F77_FUNC(repc,REPC).npiv = npiv;
618  F77_FUNC(repc,REPC).nres = nres;
619  F77_FUNC(refactorc,REFACTORC).nup = nup;
620  F77_FUNC(refactorc,REFACTORC).nfreq = nfreq;
621  F77_FUNC(alphac,ALPHAC).alpha = alpha;
622 
623  F77_FUNC(sparsec,SPARSEC).ns = ns;
624  F77_FUNC(sparsec,SPARSEC).ns1 = ns1;
625  F77_FUNC(sparsec,SPARSEC).nt = nt;
626  F77_FUNC(sparsec,SPARSEC).nt1 = nt1;
627  F77_FUNC(sparsec,SPARSEC).nu = nu;
628  F77_FUNC(sparsec,SPARSEC).nu1 = nu1;
629  F77_FUNC(sparsec,SPARSEC).nx = nx;
630  F77_FUNC(sparsec,SPARSEC).nx1 = nx1;
631  F77_FUNC(sparsec,SPARSEC).np = np;
632  F77_FUNC(sparsec,SPARSEC).np1 = np1;
633  F77_FUNC(sparsec,SPARSEC).nprof = nprof;
634  F77_FUNC(sparsec,SPARSEC).lc = lc;
635  F77_FUNC(sparsec,SPARSEC).lc1 = lc1;
636  F77_FUNC(sparsec,SPARSEC).li = li;
637  F77_FUNC(sparsec,SPARSEC).li1 = li1;
638  F77_FUNC(sparsec,SPARSEC).lm = lm;
639  F77_FUNC(sparsec,SPARSEC).lm1 = lm1;
640  F77_FUNC(sparsec,SPARSEC).lp_ = lp_;
641  F77_FUNC(sparsec,SPARSEC).lp1 = lp1;
642  F77_FUNC(sparsec,SPARSEC).lq = lq;
643  F77_FUNC(sparsec,SPARSEC).lq1 = lq1;
644  F77_FUNC(sparsec,SPARSEC).lr = lr;
645  F77_FUNC(sparsec,SPARSEC).lr1 = lr1;
646  F77_FUNC(sparsec,SPARSEC).ls_ = ls_;
647  F77_FUNC(sparsec,SPARSEC).ls1 = ls1;
648  F77_FUNC(sparsec,SPARSEC).lt = lt;
649  F77_FUNC(sparsec,SPARSEC).lt1 = lt1;
650 
651  F77_FUNC(factorc,FACTORC).m1 = m1;
652  F77_FUNC(factorc,FACTORC).m2 = m2;
653  F77_FUNC(factorc,FACTORC).mp = mp;
654  F77_FUNC(factorc,FACTORC).mq = mq;
655  F77_FUNC(factorc,FACTORC).lastr = lastr;
656  F77_FUNC(factorc,FACTORC).irow = irow;
657 
658  F77_FUNC(mxm1c,MXM1c).mxm1 = mxm1;
659  F77_FUNC(minorc,MINORC).c = c;
660 
661  F77_FUNC(wsc,WSC).kk = kkHot;
662  F77_FUNC(wsc,WSC).kkk = kkkHot;
663  F77_FUNC(wsc,WSC).ll = llHot;
664  F77_FUNC(wsc,WSC).lll = lllHot;
665 
666  k = kHot;
667  CoinCopyN(xHot,n,x);
668  f = fHot;
669  CoinCopyN(gHot,n,g);
670  CoinCopyN(rHot,n+m,r);
671  CoinCopyN(wHot,n+m,w);
672  CoinCopyN(eHot,n+m,e);
673  CoinCopyN(lsHot,n+m,ls);
674  CoinCopyN(alpHot,mlp,alp);
675  CoinCopyN(lpHot,mlp,lp);
676  CoinCopyN(wsHot,mxws,ws);
677  CoinCopyN(lwsHot,mxlws,lws);
678  info[0] = infoHot[0];
679  peq = peqHot;
680 #ifdef TIME_BQPD
681  times_.warm_start += CoinCpuTime();
682 #endif
683 
684  }
685 
686  void
688  {
689  delete [] xHot;
690  delete [] gHot;
691  delete [] rHot;
692  delete [] wHot;
693  delete [] eHot;
694  delete [] lsHot;
695  delete [] alpHot;
696  delete [] lpHot;
697  delete [] wsHot;
698  delete [] lwsHot;
699  haveHotStart_ = false;
700  }
701 
703  void
705  {
706  // Set up some common block stuff
707  F77_FUNC(scalec,SCALEC).scale_mode = 0; // No scaling
708  F77_FUNC(scalec,SCALEC).phe = 0; // No scaling
709  F77_FUNC(hessc,HESSC).phl = 1; // This is to tell gdotx to do the right thing
710  F77_FUNC(wsc,WSC).kk = kk;
711  F77_FUNC(wsc,WSC).ll = ll;
712  F77_FUNC(wsc,WSC).mxws = mxws;
713  F77_FUNC(wsc,WSC).mxlws = mxlws;
714 
715  if (use_warm_start_in_cache_ && !bad_warm_start_info_) {
716  ifail = 0;
717  use_warm_start_in_cache_ = false;
718  if (haveHotStart_ && pivots_ > next_reinit_) {
719  //printf("Reinitialize hot start\n");
720  copyFromHotStart();
721  while (BqpdSolver::reinit_freq_ > 0&& next_reinit_ < pivots_)
722  next_reinit_ += BqpdSolver::reinit_freq_;
723  }
724  }
725  else {
726  m0de = 0;
727  tqp_->get_starting_point(n, 1, x, 0, NULL, NULL, m, 0, NULL);
728  ifail = 0;
729  bad_warm_start_info_ = false;
730  }
731 
732 #if 0
733  printf("========= 222222222222 =============\n");
734  printf("kk = %d ll = %d mxws = %d mxlws = %d\n", kk, ll, mxws, mxlws);
735  for (int i=0; i<n; i++) {
736  printf("xL[%3d] = %15.8e xU[%3d] = %15.8e\n", i, bl[i], i, bu[i]);
737  }
738  for (int i=0; i<m; i++) {
739  printf("gL[%3d] = %15.8e gU[%3d] = %15.8e\n", i, bl[n+i], i, bu[n+i]);
740  }
741 #endif
742  cpuTime_ = - CoinCpuTime();
743  real fmin = -1e100;
744 #if 0
745  for (int i=0; i<n; i++) {
746  printf("qxstart[%2d] = %23.16e\n", i, x[i]);
747  }
748 #endif
749 //#define WRITE_QPS
750 #ifdef WRITE_QPS
751  if (m0de==0) {
752  FILE* fp = fopen("QPinit.dat", "w");
753  fprintf(fp, "n = %d\n", n);
754  fprintf(fp, "m = %d\n", m);
755  fprintf(fp, "kmax = %d\n", kmax);
756  fprintf(fp, "amax = %d\n" ,amax_);
757  for (int i=1; i<=amax_; i++) {
758  fprintf(fp, "a = %23.16e\n", a[i-1]);
759  }
760  int lamax = amax_ + m + 2;
761  fprintf(fp, "lamax = %d\n" ,lamax);
762  for (int i=1; i<=lamax+1; i++) {
763  fprintf(fp, "la = %6d\n", la[i-1]);
764  }
765  for (int i=1; i<=n; i++) {
766  fprintf(fp, "x = %23.16e\n", x[i-1]);
767  }
768  for (int i=1; i<=n+m; i++) {
769  fprintf(fp, "bl = %23.16e\n", bl[i-1]);
770  }
771  for (int i=1; i<=n+m; i++) {
772  fprintf(fp, "bu = %23.16e\n", bu[i-1]);
773  }
774  fprintf(fp, "fmin = %23.16e\n", fmin);
775  fprintf(fp, "mlp = %6d\n", mlp);
776  fprintf(fp, "mxws = %d\n", mxws);
777  fprintf(fp, "mxlws = %d\n", mxlws);
778  fclose(fp);
779  }
780  else {
781  FILE* fp = fopen("QPbounds.dat", "w");
782  fprintf(fp, "m0de = %d\n", m0de);
783  for (int i=1; i<=n+m; i++) {
784  fprintf(fp, "bl = %23.16e\n", bl[i-1]);
785  }
786  for (int i=1; i<=n+m; i++) {
787  fprintf(fp, "bu = %23.16e\n", bu[i-1]);
788  }
789  fclose(fp);
790  }
791 #endif
792  F77_FUNC(bqpd,BQPD)(&n, &m, &k, &kmax, a, la, x, bl, bu, &f, &fmin,
793  g, r, w, e, ls, alp, lp, &mlp, &peq, ws, lws,
794  &m0de, &ifail, info, &iprint, &nout);
795 #ifdef TIME_BQPD
796  times_.pivots += info[0];
797 #endif
798  pivots_ += info[0];
799  if(BqpdSolver::reinit_freq_ > 0 && haveHotStart_ && (ifail == 7 || ifail == 8) && m0de == 6){
800  fprintf(stdout, "Reinitialize hot start...\n");
801  copyFromHotStart();
802  ifail = 0;
803  F77_FUNC(bqpd,BQPD)(&n, &m, &k, &kmax, a, la, x, bl, bu, &f, &fmin,
804  g, r, w, e, ls, alp, lp, &mlp, &peq, ws, lws,
805  &m0de, &ifail, info, &iprint, &nout);
806  printf("new ifail = %d\n", ifail);
807  }
808  if (ifail == 8 && BqpdSolver::m0de_ == 6) {
809  fprintf(stdout, "Restarting Bqpd...");
810  m0de = 0;
811  tqp_->get_starting_point(n, 1, x, 0, NULL, NULL, m, 0, NULL);
812  ifail = 0;
813  F77_FUNC(bqpd,BQPD)(&n, &m, &k, &kmax, a, la, x, bl, bu, &f, &fmin,
814  g, r, w, e, ls, alp, lp, &mlp, &peq, ws, lws,
815  &m0de, &ifail, info, &iprint, &nout);
816  printf("new ifail = %d\n", ifail);
817  }
818  while (ifail == 7) {
819  // FIXME: For now, we just disable hot starts in case they were active
820  if (haveHotStart_) unmarkHotStart();
821 
822  printf("Increasing fillin_factor from %e ", *fillin_factor_);
823  *fillin_factor_ *= 2.;
824  printf("to %e\n", *fillin_factor_);
825  int mxws_new = kk + F77_FUNC(wsc,WSC).kkk + (5*n + (int)(*fillin_factor_*(double)amax_));
826  real* ws_new = new real[mxws_new];
827 #ifdef InitializeAll
828  for (int i=0; i<mxws_new; i++) {
829  ws_new[i] = 42.;
830  }
831 #endif
832  CoinCopyN(ws, kk, ws_new);
833  delete [] ws;
834  ws = ws_new;
835  mxws = mxws_new;
836  F77_FUNC(wsc,WSC).mxws = mxws;
837 
838  m0de = 0;
839  tqp_->get_starting_point(n, 1, x, 0, NULL, NULL, m, 0, NULL);
840  ifail = 0;
841  F77_FUNC(bqpd,BQPD)(&n, &m, &k, &kmax, a, la, x, bl, bu, &f, &fmin,
842  g, r, w, e, ls, alp, lp, &mlp, &peq, ws, lws,
843  &m0de, &ifail, info, &iprint, &nout);
844  }
845  if (ifail == 8) bad_warm_start_info_ = true;
846 #if 0
847  for (int i=0; i<n; i++) {
848  printf("qxsol[%2d] = %23.16e\n", i, x[i]);
849  }
850 #endif
851 #if 0
852  printf("ifail = %d\n", ifail);
853  printf("final f = %e\n", f);
854  printf("final f + obj_val = %e\n", f+tqp_->ObjVal());
855 #endif
856 #if 0
857  int kkk = F77_FUNC(wsc,WSC).kkk;
858  int lll = F77_FUNC(wsc,WSC).lll;
859  printf("========= 3333333333 =============\n");
860  printf("kk = %d ll = %d kkk = %d lll = %d mxws = %d mxlws = %d\n", kk, ll, kkk, lll, mxws, mxlws);
861  for (int i=0; i<kk+kkk; i++) {
862  printf("ws[%3d] = %15.8e\n ", i, ws[i]);
863  }
864  printf("--------\n");
865  for (int i=kk+kkk; i<mxws; i++) {
866  printf("ws[%3d] = %15.8e\n ", i, ws[i]);
867  }
868  for (int i=0; i<ll+lll; i++) {
869  printf("lws[%5d] = %8d\n", i, lws[i]);
870  }
871  printf("------\n");
872  for (int i=ll+lll; i<mxlws; i++) {
873  printf("lws[%5d] = %8d\n", i, lws[i]);
874  }
875 #endif
876  cpuTime_ += CoinCpuTime();
877  }
878 
879  std::string
881  {"Internal error in Filter SQP."};
882 
883  std::string
885  "filterSqp";
886 
887  const std::string&
889  {
890  return errorNames_[0];
891  }
892 
893  const std::string&
895  {
896  return solverName_;
897  }
898 
899  bool
900  BqpdSolver::setWarmStart(const CoinWarmStart * warm,
902  {
903 #if 0
904  if (IsNull(cached_)) {
905  cached_ = new cachedInfo(GetRawPtr(tnlp), options_);
906  }
907 
908  const FilterWarmStart * warmF = dynamic_cast<const FilterWarmStart *> (warm);
909  //CoinCopyN(warmF->xArray(), warmF->xSize(), cached_->x);
910  const fint xsize = warmF->xSize();
911  real* x = cached_->x;
912  const real* xarray = warmF->xArray();
913  for (int i = 0; i<xsize; i++) {
914  x[i] = xarray[i];
915  }
916  CoinCopyN(warmF->lamArray(), warmF->lamSize(), cached_->lam);
917  CoinCopyN(warmF->lwsArray(), warmF->lwsSize(), cached_->lws);
918  for (int i = 0 ; i < 14 ; i ++) {
919  cached_->istat[i] = warmF->istat()[i];
920  }
921  cached_->use_warm_start_in_cache_ = true;
922 #endif
923  printf("BqpdSolver::setWarmStart called!\n");
924  return true;
925  }
926 
927  CoinWarmStart *
929  {
930 #if 0
931  return new FilterWarmStart(cached_->n, cached_->x,
932  cached_->n+cached_->m, cached_->lam,
933  cached_->maxiWk, cached_->lws, cached_->istat);
934 #endif
935  printf("BqpdSolver::getWarmStart called!\n");
936  return NULL;
937  }
938 
939  CoinWarmStart *
941  {
942 #if 0
943  return new FilterWarmStart;
944 #endif
945  printf("BqpdSolver::getEmptyWarmStart called \n");
946  return NULL;
947  }
948 
950  bool
951  BqpdSolver::warmStartIsValid(const CoinWarmStart * ws) const{
952  const BqpdWarmStart* bws = dynamic_cast<const BqpdWarmStart*>(ws);
953  if (bws && ! bws->empty()) {
954  return true;
955  }
956  return false;
957  }
958 
959 }//end namespace Bonmin
fint irh1
fint nfreq
fint nup
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real fint * lws
TNLPSolver::ReturnStatus callOptimizer()
Perform optimization using data structure in cache.
fint mxlws
virtual ReturnStatus ReOptimizeTNLP(const Ipopt::SmartPtr< Ipopt::TNLP > &tnlp)
Resolves a problem expresses as a TNLP.
void fint fint fint * kmax
fint m2
virtual const std::string & errorName() const
Get the string corresponding to error.
fint kk
fint lm1
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real fint fint fint fint * info
Ipopt::SmartPtr< Ipopt::Journalist > journalist_
Storage of Journalist for output.
fint lu1
const fint * istat() const
void fint fint fint real fint * la
fint lll
fint lt1
fint nt1
Bonmin::BqpdSolver F77_FUNC
Ipopt::SmartPtr< BranchingTQP > tqp_
int mlp_ipt_
Fill-in factor for QP factorization.
std::string prefix_
Prefix to use for reading bonmin&#39;s options.
void unmarkHotStart()
Forget about the hot start info.
fint lwsSize() const
Access to lws size.
void fint fint fint real * a
real emin
fint lp1
fint ls_
static int reinit_freq_
Hot start reinitialization fequency.
void fint fint fint real fint real real * bl
fint phe
fint nx
bool use_warm_start_in_cache_
flag remembering if warm start information has been put into cache
fint nrep
fint lv
This is a generic class for calling an NLP solver to solve a TNLP.
Bonmin::BqpdSolver::fint fint
fint mq
fint lastr
Warm start for filter interface.
fint lc1
real eps
fint irow
fint nu1
fint ls1
fint ll1
void fint fint fint real fint real real real real real real real real real fint real fint fint * mlp
virtual bool Initialize(std::string params_file)
Initialize the TNLPSolver (read options from params_file)
fint lr1
ipfint fint
Fortran type for integer used in filter.
fint kkk
void fint fint fint real fint real real real real * f
real alpha
int default_log_level_
To record default log level.
fint lc
fint nres
fint mp
void fint fint fint real fint real real real real real real real real real * e
Bonmin::BqpdSolver::real real
fint lr
fint phl
fint npiv
bool IsNull(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:471
fint ns
void fint fint fint real fint real real real real real real real real real fint real fint * lp
fint np1
fint lt
void fint fint fint real fint real real real real real real real real real fint real fint fint fint * peq
fint lv1
virtual CoinWarmStart * getEmptyWarmStart() const
Solves a problem expresses as a TNLP.
bool markHotStart()
Store most recent solution as hot start.
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real fint fint * m0de
fint lq1
fint li1
Warm start for filter interface.
static int m0de_
Hot start m0de.
double fillin_factor_
Fill-in factor for QP factorization.
void registerOptions()
Register this solver options into passed roptions.
void fint fint * k
void fint fint fint real fint real real real real real * fmin
const fint * lwsArray() const
Access to lws array.
void fint fint fint real fint real real real real real real real real real fint real * alp
static void TMat2RowPMat(bool symmetric, fint n, fint m, int nnz, const Ipopt::Index *iRow, const Ipopt::Index *iCol, int *permutation2, fint *lws, int nnz_offset, int n_offset, Ipopt::TNLP::IndexStyleEnum index_style)
Converting TMatrices into row-ordered matrices.
void copyFromHotStart()
Copy current values from hot start info.
real tol
real sgnf
void fint fint fint real fint real real real real real real real * r
static int
Definition: OSdtoa.cpp:2173
fint irg1
virtual ReturnStatus OptimizeTNLP(const Ipopt::SmartPtr< Ipopt::TNLP > &tnlp)
Solves a problem expresses as a TNLP.
fint nprof
fint m1
U * GetRawPtr(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:452
Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions_
Registered Options.
fint ns1
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real * ws
fint lm
int kmax_ipt_
Fill-in factor for QP factorization.
fint li
fint phc
fint lp_
virtual bool setWarmStart(const CoinWarmStart *warm, Ipopt::SmartPtr< TMINLP2TNLP > tnlp)
Set the warm start in the solver.
fint na
ReturnStatus
Standard return statuses for a solver.
fint np
virtual Ipopt::SmartPtr< TNLPSolver > clone()
Virtual copy constructor.
double * fillin_factor_
Fill-in factor for QP factorization.
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real fint fint fint * ifail
fint ll
fint scale_mode
fint kb1
fint nb
Ipopt::SmartPtr< cachedInfo > cached_
Cached information on last problem optimized for reoptimization.
static int * permutationHess
void fint fint fint real fint real real real real real real real real real fint * ls
void initialize(const Ipopt::SmartPtr< BranchingTQP > &tqp, Ipopt::SmartPtr< Ipopt::OptionsList > &options, int kmax_ipt, int mlp_ipt, double *fillin_factor)
Fill data structures for filter with info from tnlp.
fint lq
fint nx1
This is an adapter class that converts a TMINLP2TNLP object into a TNLP, which is now just a QP...
void fint fint fint real fint real real real real real real * g
fint mxm1
BqpdSolver(bool createEmpty=false)
Default constructor.
fint nt
void optimize()
Optimize problem described by cache with filter.
static char prefix[100]
Definition: BM_lp.cpp:26
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real fint fint fint fint fint fint * nout
fint mxws
static int * permutationJac
void fint * m
fint kc1
virtual const std::string & solverName() const
Return the name of the solver.
int amax_
Number of nonzeros in Jacobian and gradient.
static std::string solverName_
To record default log level.
virtual bool warmStartIsValid(const CoinWarmStart *ws) const
Check that warm start object is valid.
fint nu
fint ka1
void fint fint fint real fint real real real real real real real real * w
real vstep
fint phr
Cached information for reoptimizing.
Ipopt::SmartPtr< Ipopt::OptionsList > options_
List of Options.
double real
Fortran type for double.used in filter.
void fint * n
virtual CoinWarmStart * getWarmStart(Ipopt::SmartPtr< TMINLP2TNLP > tnlp) const
Get the warm start form the solver.
real c
fint nb1
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real fint fint fint fint fint * iprint
bool empty() const
Is this an empty warm start?
void fint fint fint real fint real * x
fint na1
virtual ~BqpdSolver()
destructor
void fint fint fint real fint real real real * bu