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  catch (...) {
182  Ipopt::IpoptException E("Unknown Exception caught in ipopt", "Unknown File", -1);
183  E.ReportException(*journalist_);
184  return false;
185  }
186  }
187  bool retval = Initialize(is);
188  if (is) {
189  is.close();
190  }
191  if(!options_->GetIntegerValue("print_level",default_log_level_,""))
192  default_log_level_ = 1;
193  return retval;
194  }
195 
196  bool
197  BqpdSolver::Initialize(std::istream &is)
198  {
199  if (is.good()) {
200  options_->ReadFromStream(*journalist_, is);
201  }
202  return true;
203  }
204 
208  {
209  BranchingTQP* tqp = dynamic_cast<BranchingTQP*>(GetRawPtr(tnlp));
210  if (!tqp) {
211  Ipopt::IpoptException E("BqpdSolver called with object other than a BranchingTQP",
212  "BonBqpdSolver.cpp",-1);
213  throw E;
214  }
215  if (IsNull(cached_) || !cached_->use_warm_start_in_cache_) {
217  &fillin_factor_);
218  }
219 #ifdef TIME_BQPD
220  times().solve -= CoinCpuTime();
221 #endif
223 #ifdef TIME_BQPD
224  times().solve += CoinCpuTime();
225 #endif
226  return r_val;
227  }
228 
232  {
233 #ifndef NDEBUG
234  BranchingTQP* tqp = dynamic_cast<BranchingTQP*>(GetRawPtr(tnlp));
235  assert(tqp == GetRawPtr(cached_->tqp_));
236 #endif
237  int n = cached_->n;
238  int m = cached_->m;
239  tnlp->get_bounds_info(n, cached_->bl, cached_->bu,
240  m, cached_->bl+n, cached_->bu+n);
241  // Make sure bounds are not infinity
242  for (int i=0; i<n+m; i++) {
243  cached_->bl[i] = std::max(cached_->bl[i], -1e50);
244  cached_->bu[i] = std::min(cached_->bu[i], 1e50);
245  }
246 
247 #if 1
248  cached_->use_warm_start_in_cache_ = true; // Trying...
249  cached_->m0de = m0de_;
250 #else
251  cached_->re_initialize();
252  cached_->use_warm_start_in_cache_ = true; // Trying...
253 #endif
254 
255 #ifdef TIME_BQPD
256  times().resolve -= CoinCpuTime();
257 #endif
259 #ifdef TIME_BQPD
260  times().resolve += CoinCpuTime();
261 #endif
262  return r_val;
263  }
264 
265  void
268  int kmax_ipt,
269  int mlp_ipt,
270  double* fillin_factor)
271  {
272  // Maybe a dirty trick? We want to change fillin_factor in calling object
273  fillin_factor_ = fillin_factor;
274 
275  // In case BQPD's BLOCK DATA doesn't work, we initialize the COMMON
276  // BLOCKs explicitly here
277  F77_FUNC(epsc,EPSC).eps = 1111e-19;
278  F77_FUNC(epsc,EPSC).tol = 1e-12;
279  F77_FUNC(epsc,EPSC).emin = 1.;
280  F77_FUNC(repc,REPC).sgnf = 1e-4;
281  F77_FUNC(repc,REPC).nrep = 2;
282  F77_FUNC(repc,REPC).npiv = 3;
283  F77_FUNC(repc,REPC).nres = 2;
284  F77_FUNC(refactorc,REFACTORC).nfreq = 500;
285 
286  Ipopt::TNLP::IndexStyleEnum index_style;
287  Ipopt::Index nv, nc, nnz_jac_g, nnz_hess;
288  tqp->get_nlp_info(nv, nc, nnz_jac_g, nnz_hess, index_style);
289  n = nv;
290  m = nc;
291 
292  if (kmax_ipt == -1) {
293  kmax = n;
294  }
295  else {
296  kmax = kmax_ipt;
297  kmax = std::min(kmax,n);
298  }
299  mlp = mlp_ipt;
300 
301  use_warm_start_in_cache_ = false;
302 
303  // Get space for arrays
304  x = new real[n];
305  bl = new real[n+m];
306  bu = new real[n+m];
307  g = new real[n];
308  r = new real[n+m];
309  w = new real[n+m];
310  e = new real[n+m];
311  ls = new fint[n+m];
312  alp = new real[mlp];
313  lp = new fint[mlp];
314 
315  // Getting the bounds
316  tqp->get_bounds_info(n, bl, bu, m, bl+n, bu+n);
317 
318  // Make sure bounds are not infinity
319  for (int i=0; i<n+m; i++) {
320  bl[i] = std::max(bl[i], -1e50);
321  bu[i] = std::min(bu[i], 1e50);
322  }
323 
324  // Set up sparse matrix with objective gradient and constraint Jacobian
325 
326  const Ipopt::Number* obj_grad = tqp->ObjGrad();
327  amax_ = nnz_jac_g;
328  for (int i = 0; i<n; i++) {
329  if (obj_grad[i]!=0.) {
330  amax_++;
331  }
332  }
333  int lamax = amax_+m+2;
334  a = new real[amax_];
335  la = new fint [1+lamax];
336 
337  // Objective function gradient
338  int nnz_grad = 0;
339  for (int i = 0; i < n ; i++) {
340  if (obj_grad[i]!=0.) {
341  a[nnz_grad] = obj_grad[i];
342  la[++nnz_grad] = i+1;
343  }
344  }
345  la[amax_+1] = 1;
346 
347  // Constraint Jacobian
348  const Ipopt::Number* JacVals = tqp->ConstrJacVals();
349  const Ipopt::Index* RowJac = tqp->ConstrJacIRow();
350  const Ipopt::Index* ColJac = tqp->ConstrJacJCol();
351 
352  int* permutationJac = new int [nnz_jac_g];
353  FilterSolver::TMat2RowPMat(false, n, m, nnz_jac_g, RowJac, ColJac, permutationJac,
354  la, nnz_grad, 1, Ipopt::TNLP::C_STYLE);
355  for (int i=0; i<nnz_jac_g; i++) {
356  const int& indice = permutationJac[i];
357  a[nnz_grad+i] = JacVals[indice];
358  }
359  delete [] permutationJac;
360 #if 0
361 //deleteme
362  printf("nnz_grad = %d nnz_jac = %d\n", nnz_grad, nnz_jac_g);
363  for (int i=0; i<1+lamax; i++) printf("la[%2d] = %d\n", i,la[i]);
364  for (int i=0; i<amax_; i++) printf("a[%3d] = %e\n",i,a[i]);
365 #endif
366 
367  // Setup workspaces
368  mxws = nnz_hess + ((kmax*(kmax+9))/2 + 2*n + m) + (5*n + (int)(*fillin_factor_*(double)amax_));
369  mxlws = (nnz_hess + n + 2) + kmax + (9*n + m);
370 
371  ws = new real[mxws];
372  lws = new fint[mxlws];
373 
374 #ifdef InitializeAll
375  for (int i=0; i<mxws; i++) {
376  ws[i] = 42.;
377  }
378  for (int i=0; i<mxlws; i++) {
379  lws[i] = 55;
380  }
381 #endif
382 
383  // Now setup Hessian
384  const Ipopt::Number* HessVals = tqp->ObjHessVals();
385  const Ipopt::Index* RowHess = tqp->ObjHessIRow();
386  const Ipopt::Index* ColHess = tqp->ObjHessJCol();
387 
388  kk = nnz_hess;
389  ll = nnz_hess + n + 2;
390  int* permutationHess = new int[nnz_hess];
391 
392  FilterSolver::TMat2RowPMat(true, n, n, nnz_hess, RowHess, ColHess,
393  permutationHess, lws, 0, 0, Ipopt::TNLP::C_STYLE);
394  for (int i=0; i<nnz_hess; i++) {
395  ws[i] = HessVals[permutationHess[i]];
396  }
397  delete [] permutationHess;
398 #if 0
399 //deleteme
400  printf("nnz_hess = %d\n", nnz_hess);
401  for (int i=0; i<ll; i++) printf("hess lws[%2d] = %d\n", i,lws[i]);
402  for (int i=0; i<kk; i++) printf("hess ws[%3d] = %e\n",i,ws[i]);
403 #endif
404 
405  Ipopt::Index bufy;
406  options->GetIntegerValue("iprint",bufy, "bqpd.");
407  iprint = bufy;
408  nout = 6;
409 
410  tqp_ = tqp;
411  }
412 
413  void
415  {
416  use_warm_start_in_cache_ = false;
417 
418  // Setup workspaces
419  for (int i=0; i<mxws; i++) {
420  ws[i] = 42.;
421  }
422  for (int i=0; i<mxlws; i++) {
423  lws[i] = 55;
424  }
425  }
426 
429 #ifdef TIME_BQPD
430  times().numsolve++;
431 #endif
432  cached_->optimize();
433 
434  TNLPSolver::ReturnStatus optimizationStatus = TNLPSolver::exception;
435  Ipopt::SolverReturn status = Ipopt::INTERNAL_ERROR;
436  fint ifail = cached_->ifail;
437  switch (ifail) {
438  case 0:
439  optimizationStatus = TNLPSolver::solvedOptimal;
440  status = Ipopt::SUCCESS;
441  break;
442  case 1:
443  optimizationStatus = TNLPSolver::unbounded;
444  status = Ipopt::DIVERGING_ITERATES;
445  case 2:
446  case 3:
447  optimizationStatus = TNLPSolver::provenInfeasible;
448  status = Ipopt::LOCAL_INFEASIBILITY;
449  break;
450  }
451 
452  Ipopt::Index dummy_len = std::max(cached_->n,cached_->m);
453  Ipopt::Number* dummy = new Ipopt::Number[dummy_len];
454  for (int i=0; i<dummy_len; i++) {
455  dummy[i] = 0.;
456  }
457 
458  cached_->tqp_->finalize_solution(status, cached_->n,
459  cached_->x, dummy, dummy,
460  cached_->m, dummy, dummy,
461  cached_->f, NULL, NULL);
462  delete [] dummy;
463  return optimizationStatus;
464  }
465 
467  {
468  if (haveHotStart_) {
469  unmarkHotStart();
470  }
471  delete [] a;
472  delete [] la;
473  delete [] x;
474  delete [] bl;
475  delete [] bu;
476  delete [] g;
477  delete [] r;
478  delete [] w;
479  delete [] e;
480  delete [] ls;
481  delete [] alp;
482  delete [] lp;
483  delete [] ws;
484  delete [] lws;
485  }
486 
487  bool
489  {
490  next_reinit_ = BqpdSolver::reinit_freq_;
491 #ifdef DISABLE_COPYING
492  return 1;
493 #endif
494 #ifdef TIME_BQPD
495  times_.warm_start -= CoinCpuTime();
496 #endif
497  haveHotStart_ = true;
498  irh1 = F77_FUNC(bqpdc,BQPDC).irh1;
499  na = F77_FUNC(bqpdc,BQPDC).na;
500  na1 = F77_FUNC(bqpdc,BQPDC).na1;
501  nb = F77_FUNC(bqpdc,BQPDC).nb;
502  nb1 = F77_FUNC(bqpdc,BQPDC).nb1;
503  ka1 = F77_FUNC(bqpdc,BQPDC).ka1;
504  kb1 = F77_FUNC(bqpdc,BQPDC).kb1;
505  kc1 = F77_FUNC(bqpdc,BQPDC).kc1;
506  irg1 = F77_FUNC(bqpdc,BQPDC).irg1;
507  lu1 = F77_FUNC(bqpdc,BQPDC).lu1;
508  lv = F77_FUNC(bqpdc,BQPDC).lv;
509  lv1 = F77_FUNC(bqpdc,BQPDC).lv1;
510  ll1 = F77_FUNC(bqpdc,BQPDC).ll1;
511  eps = F77_FUNC(epsc,EPSC).eps;
512  tol = F77_FUNC(epsc,EPSC).tol;
513  emin = F77_FUNC(epsc,EPSC).emin;
514  vstep = F77_FUNC(vstepc,VSTEPC).vstep;
515  sgnf = F77_FUNC(repc,REPC).sgnf;
516  nrep = F77_FUNC(repc,REPC).nrep;
517  npiv = F77_FUNC(repc,REPC).npiv;
518  nres = F77_FUNC(repc,REPC).nres;
519  nup = F77_FUNC(refactorc,REFACTORC).nup;
520  nfreq = F77_FUNC(refactorc,REFACTORC).nfreq;
521  alpha = F77_FUNC(alphac,ALPHAC).alpha;
522 
523  ns = F77_FUNC(sparsec,SPARSEC).ns;
524  ns1 = F77_FUNC(sparsec,SPARSEC).ns1;
525  nt = F77_FUNC(sparsec,SPARSEC).nt;
526  nt1 = F77_FUNC(sparsec,SPARSEC).nt1;
527  nu = F77_FUNC(sparsec,SPARSEC).nu;
528  nu1 = F77_FUNC(sparsec,SPARSEC).nu1;
529  nx = F77_FUNC(sparsec,SPARSEC).nx;
530  nx1 = F77_FUNC(sparsec,SPARSEC).nx1;
531  np = F77_FUNC(sparsec,SPARSEC).np;
532  np1 = F77_FUNC(sparsec,SPARSEC).np1;
533  nprof = F77_FUNC(sparsec,SPARSEC).nprof;
534  lc = F77_FUNC(sparsec,SPARSEC).lc;
535  lc1 = F77_FUNC(sparsec,SPARSEC).lc1;
536  li = F77_FUNC(sparsec,SPARSEC).li;
537  li1 = F77_FUNC(sparsec,SPARSEC).li1;
538  lm = F77_FUNC(sparsec,SPARSEC).lm;
539  lm1 = F77_FUNC(sparsec,SPARSEC).lm1;
540  lp_ = F77_FUNC(sparsec,SPARSEC).lp_;
541  lp1 = F77_FUNC(sparsec,SPARSEC).lp1;
542  lq = F77_FUNC(sparsec,SPARSEC).lq;
543  lq1 = F77_FUNC(sparsec,SPARSEC).lq1;
544  lr = F77_FUNC(sparsec,SPARSEC).lr;
545  lr1 = F77_FUNC(sparsec,SPARSEC).lr1;
546  ls_ = F77_FUNC(sparsec,SPARSEC).ls_;
547  ls1 = F77_FUNC(sparsec,SPARSEC).ls1;
548  lt = F77_FUNC(sparsec,SPARSEC).lt;
549  lt1 = F77_FUNC(sparsec,SPARSEC).lt1;
550 
551  m1 = F77_FUNC(factorc,FACTORC).m1;
552  m2 = F77_FUNC(factorc,FACTORC).m2;
553  mp = F77_FUNC(factorc,FACTORC).mp;
554  mq = F77_FUNC(factorc,FACTORC).mq;
555  lastr = F77_FUNC(factorc,FACTORC).lastr;
556  irow = F77_FUNC(factorc,FACTORC).irow;
557 
558  mxm1 = F77_FUNC(mxm1c,MXM1c).mxm1;
559  c = F77_FUNC(minorc,MINORC).c;
560 
561  kkHot = F77_FUNC(wsc,WSC).kk;
562  kkkHot = F77_FUNC(wsc,WSC).kkk;
563  llHot = F77_FUNC(wsc,WSC).ll;
564  lllHot = F77_FUNC(wsc,WSC).lll;
565 
566  kHot = k;
567  xHot = CoinCopyOfArray(x,n);
568  fHot = f;
569  gHot = CoinCopyOfArray(g,n);
570  rHot = CoinCopyOfArray(r,n+m);
571  wHot = CoinCopyOfArray(w,n+m);
572  eHot = CoinCopyOfArray(e,n+m);
573  lsHot = CoinCopyOfArray(ls,n+m);
574  alpHot = CoinCopyOfArray(alp,mlp);
575  lpHot = CoinCopyOfArray(lp,mlp);
576  peqHot = peq;
577  wsHot = CoinCopyOfArray(ws,mxws);
578  lwsHot = CoinCopyOfArray(lws,mxlws);
579  infoHot[0] = info[0];
580 #ifdef TIME_BQPD
581  times_.warm_start += CoinCpuTime();
582 #endif
583 
584  return true;
585  }
586 
587  void
589  {
590 #ifdef DISABLE_COPYING
591  return;
592 #endif
593 #ifdef TIME_BQPD
594  times_.warm_start -= CoinCpuTime();
595 #endif
596  F77_FUNC(bqpdc,BQPDC).irh1 = irh1;
597  F77_FUNC(bqpdc,BQPDC).na = na;
598  F77_FUNC(bqpdc,BQPDC).na1 = na1;
599  F77_FUNC(bqpdc,BQPDC).nb = nb;
600  F77_FUNC(bqpdc,BQPDC).nb1 = nb1;
601  F77_FUNC(bqpdc,BQPDC).ka1 = ka1;
602  F77_FUNC(bqpdc,BQPDC).kb1 = kb1;
603  F77_FUNC(bqpdc,BQPDC).kc1 = kc1;
604  F77_FUNC(bqpdc,BQPDC).irg1 = irg1;
605  F77_FUNC(bqpdc,BQPDC).lu1 = lu1;
606  F77_FUNC(bqpdc,BQPDC).lv = lv;
607  F77_FUNC(bqpdc,BQPDC).lv1 = lv1;
608  F77_FUNC(bqpdc,BQPDC).ll1 = ll1;
609  F77_FUNC(epsc,EPSC).eps = eps;
610  F77_FUNC(epsc,EPSC).tol = tol;
611  F77_FUNC(epsc,EPSC).emin = emin;
612  F77_FUNC(vstepc,VSTEPC).vstep = vstep;
613  F77_FUNC(repc,REPC).sgnf = sgnf;
614  F77_FUNC(repc,REPC).nrep = nrep;
615  F77_FUNC(repc,REPC).npiv = npiv;
616  F77_FUNC(repc,REPC).nres = nres;
617  F77_FUNC(refactorc,REFACTORC).nup = nup;
618  F77_FUNC(refactorc,REFACTORC).nfreq = nfreq;
619  F77_FUNC(alphac,ALPHAC).alpha = alpha;
620 
621  F77_FUNC(sparsec,SPARSEC).ns = ns;
622  F77_FUNC(sparsec,SPARSEC).ns1 = ns1;
623  F77_FUNC(sparsec,SPARSEC).nt = nt;
624  F77_FUNC(sparsec,SPARSEC).nt1 = nt1;
625  F77_FUNC(sparsec,SPARSEC).nu = nu;
626  F77_FUNC(sparsec,SPARSEC).nu1 = nu1;
627  F77_FUNC(sparsec,SPARSEC).nx = nx;
628  F77_FUNC(sparsec,SPARSEC).nx1 = nx1;
629  F77_FUNC(sparsec,SPARSEC).np = np;
630  F77_FUNC(sparsec,SPARSEC).np1 = np1;
631  F77_FUNC(sparsec,SPARSEC).nprof = nprof;
632  F77_FUNC(sparsec,SPARSEC).lc = lc;
633  F77_FUNC(sparsec,SPARSEC).lc1 = lc1;
634  F77_FUNC(sparsec,SPARSEC).li = li;
635  F77_FUNC(sparsec,SPARSEC).li1 = li1;
636  F77_FUNC(sparsec,SPARSEC).lm = lm;
637  F77_FUNC(sparsec,SPARSEC).lm1 = lm1;
638  F77_FUNC(sparsec,SPARSEC).lp_ = lp_;
639  F77_FUNC(sparsec,SPARSEC).lp1 = lp1;
640  F77_FUNC(sparsec,SPARSEC).lq = lq;
641  F77_FUNC(sparsec,SPARSEC).lq1 = lq1;
642  F77_FUNC(sparsec,SPARSEC).lr = lr;
643  F77_FUNC(sparsec,SPARSEC).lr1 = lr1;
644  F77_FUNC(sparsec,SPARSEC).ls_ = ls_;
645  F77_FUNC(sparsec,SPARSEC).ls1 = ls1;
646  F77_FUNC(sparsec,SPARSEC).lt = lt;
647  F77_FUNC(sparsec,SPARSEC).lt1 = lt1;
648 
649  F77_FUNC(factorc,FACTORC).m1 = m1;
650  F77_FUNC(factorc,FACTORC).m2 = m2;
651  F77_FUNC(factorc,FACTORC).mp = mp;
652  F77_FUNC(factorc,FACTORC).mq = mq;
653  F77_FUNC(factorc,FACTORC).lastr = lastr;
654  F77_FUNC(factorc,FACTORC).irow = irow;
655 
656  F77_FUNC(mxm1c,MXM1c).mxm1 = mxm1;
657  F77_FUNC(minorc,MINORC).c = c;
658 
659  F77_FUNC(wsc,WSC).kk = kkHot;
660  F77_FUNC(wsc,WSC).kkk = kkkHot;
661  F77_FUNC(wsc,WSC).ll = llHot;
662  F77_FUNC(wsc,WSC).lll = lllHot;
663 
664  k = kHot;
665  CoinCopyN(xHot,n,x);
666  f = fHot;
667  CoinCopyN(gHot,n,g);
668  CoinCopyN(rHot,n+m,r);
669  CoinCopyN(wHot,n+m,w);
670  CoinCopyN(eHot,n+m,e);
671  CoinCopyN(lsHot,n+m,ls);
672  CoinCopyN(alpHot,mlp,alp);
673  CoinCopyN(lpHot,mlp,lp);
674  CoinCopyN(wsHot,mxws,ws);
675  CoinCopyN(lwsHot,mxlws,lws);
676  info[0] = infoHot[0];
677  peq = peqHot;
678 #ifdef TIME_BQPD
679  times_.warm_start += CoinCpuTime();
680 #endif
681 
682  }
683 
684  void
686  {
687  delete [] xHot;
688  delete [] gHot;
689  delete [] rHot;
690  delete [] wHot;
691  delete [] eHot;
692  delete [] lsHot;
693  delete [] alpHot;
694  delete [] lpHot;
695  delete [] wsHot;
696  delete [] lwsHot;
697  haveHotStart_ = false;
698  }
699 
701  void
703  {
704  // Set up some common block stuff
705  F77_FUNC(scalec,SCALEC).scale_mode = 0; // No scaling
706  F77_FUNC(scalec,SCALEC).phe = 0; // No scaling
707  F77_FUNC(hessc,HESSC).phl = 1; // This is to tell gdotx to do the right thing
708  F77_FUNC(wsc,WSC).kk = kk;
709  F77_FUNC(wsc,WSC).ll = ll;
710  F77_FUNC(wsc,WSC).mxws = mxws;
711  F77_FUNC(wsc,WSC).mxlws = mxlws;
712 
713  if (use_warm_start_in_cache_ && !bad_warm_start_info_) {
714  ifail = 0;
715  use_warm_start_in_cache_ = false;
716  if (haveHotStart_ && pivots_ > next_reinit_) {
717  //printf("Reinitialize hot start\n");
718  copyFromHotStart();
719  while (BqpdSolver::reinit_freq_ > 0&& next_reinit_ < pivots_)
720  next_reinit_ += BqpdSolver::reinit_freq_;
721  }
722  }
723  else {
724  m0de = 0;
725  tqp_->get_starting_point(n, 1, x, 0, NULL, NULL, m, 0, NULL);
726  ifail = 0;
727  bad_warm_start_info_ = false;
728  }
729 
730 #if 0
731  printf("========= 222222222222 =============\n");
732  printf("kk = %d ll = %d mxws = %d mxlws = %d\n", kk, ll, mxws, mxlws);
733  for (int i=0; i<n; i++) {
734  printf("xL[%3d] = %15.8e xU[%3d] = %15.8e\n", i, bl[i], i, bu[i]);
735  }
736  for (int i=0; i<m; i++) {
737  printf("gL[%3d] = %15.8e gU[%3d] = %15.8e\n", i, bl[n+i], i, bu[n+i]);
738  }
739 #endif
740  cpuTime_ = - CoinCpuTime();
741  real fmin = -1e100;
742 #if 0
743  for (int i=0; i<n; i++) {
744  printf("qxstart[%2d] = %23.16e\n", i, x[i]);
745  }
746 #endif
747 //#define WRITE_QPS
748 #ifdef WRITE_QPS
749  if (m0de==0) {
750  FILE* fp = fopen("QPinit.dat", "w");
751  fprintf(fp, "n = %d\n", n);
752  fprintf(fp, "m = %d\n", m);
753  fprintf(fp, "kmax = %d\n", kmax);
754  fprintf(fp, "amax = %d\n" ,amax_);
755  for (int i=1; i<=amax_; i++) {
756  fprintf(fp, "a = %23.16e\n", a[i-1]);
757  }
758  int lamax = amax_ + m + 2;
759  fprintf(fp, "lamax = %d\n" ,lamax);
760  for (int i=1; i<=lamax+1; i++) {
761  fprintf(fp, "la = %6d\n", la[i-1]);
762  }
763  for (int i=1; i<=n; i++) {
764  fprintf(fp, "x = %23.16e\n", x[i-1]);
765  }
766  for (int i=1; i<=n+m; i++) {
767  fprintf(fp, "bl = %23.16e\n", bl[i-1]);
768  }
769  for (int i=1; i<=n+m; i++) {
770  fprintf(fp, "bu = %23.16e\n", bu[i-1]);
771  }
772  fprintf(fp, "fmin = %23.16e\n", fmin);
773  fprintf(fp, "mlp = %6d\n", mlp);
774  fprintf(fp, "mxws = %d\n", mxws);
775  fprintf(fp, "mxlws = %d\n", mxlws);
776  fclose(fp);
777  }
778  else {
779  FILE* fp = fopen("QPbounds.dat", "w");
780  fprintf(fp, "m0de = %d\n", m0de);
781  for (int i=1; i<=n+m; i++) {
782  fprintf(fp, "bl = %23.16e\n", bl[i-1]);
783  }
784  for (int i=1; i<=n+m; i++) {
785  fprintf(fp, "bu = %23.16e\n", bu[i-1]);
786  }
787  fclose(fp);
788  }
789 #endif
790  F77_FUNC(bqpd,BQPD)(&n, &m, &k, &kmax, a, la, x, bl, bu, &f, &fmin,
791  g, r, w, e, ls, alp, lp, &mlp, &peq, ws, lws,
792  &m0de, &ifail, info, &iprint, &nout);
793 #ifdef TIME_BQPD
794  times_.pivots += info[0];
795 #endif
796  pivots_ += info[0];
797  if(BqpdSolver::reinit_freq_ > 0 && haveHotStart_ && (ifail == 7 || ifail == 8) && m0de == 6){
798  fprintf(stdout, "Reinitialize hot start...\n");
799  copyFromHotStart();
800  ifail = 0;
801  F77_FUNC(bqpd,BQPD)(&n, &m, &k, &kmax, a, la, x, bl, bu, &f, &fmin,
802  g, r, w, e, ls, alp, lp, &mlp, &peq, ws, lws,
803  &m0de, &ifail, info, &iprint, &nout);
804  printf("new ifail = %d\n", ifail);
805  }
806  if (ifail == 8 && BqpdSolver::m0de_ == 6) {
807  fprintf(stdout, "Restarting Bqpd...");
808  m0de = 0;
809  tqp_->get_starting_point(n, 1, x, 0, NULL, NULL, m, 0, NULL);
810  ifail = 0;
811  F77_FUNC(bqpd,BQPD)(&n, &m, &k, &kmax, a, la, x, bl, bu, &f, &fmin,
812  g, r, w, e, ls, alp, lp, &mlp, &peq, ws, lws,
813  &m0de, &ifail, info, &iprint, &nout);
814  printf("new ifail = %d\n", ifail);
815  }
816  while (ifail == 7) {
817  // FIXME: For now, we just disable hot starts in case they were active
818  if (haveHotStart_) unmarkHotStart();
819 
820  printf("Increasing fillin_factor from %e ", *fillin_factor_);
821  *fillin_factor_ *= 2.;
822  printf("to %e\n", *fillin_factor_);
823  int mxws_new = kk + F77_FUNC(wsc,WSC).kkk + (5*n + (int)(*fillin_factor_*(double)amax_));
824  real* ws_new = new real[mxws_new];
825 #ifdef InitializeAll
826  for (int i=0; i<mxws_new; i++) {
827  ws_new[i] = 42.;
828  }
829 #endif
830  CoinCopyN(ws, kk, ws_new);
831  delete [] ws;
832  ws = ws_new;
833  mxws = mxws_new;
834  F77_FUNC(wsc,WSC).mxws = mxws;
835 
836  m0de = 0;
837  tqp_->get_starting_point(n, 1, x, 0, NULL, NULL, m, 0, NULL);
838  ifail = 0;
839  F77_FUNC(bqpd,BQPD)(&n, &m, &k, &kmax, a, la, x, bl, bu, &f, &fmin,
840  g, r, w, e, ls, alp, lp, &mlp, &peq, ws, lws,
841  &m0de, &ifail, info, &iprint, &nout);
842  }
843  if (ifail == 8) bad_warm_start_info_ = true;
844 #if 0
845  for (int i=0; i<n; i++) {
846  printf("qxsol[%2d] = %23.16e\n", i, x[i]);
847  }
848 #endif
849 #if 0
850  printf("ifail = %d\n", ifail);
851  printf("final f = %e\n", f);
852  printf("final f + obj_val = %e\n", f+tqp_->ObjVal());
853 #endif
854 #if 0
855  int kkk = F77_FUNC(wsc,WSC).kkk;
856  int lll = F77_FUNC(wsc,WSC).lll;
857  printf("========= 3333333333 =============\n");
858  printf("kk = %d ll = %d kkk = %d lll = %d mxws = %d mxlws = %d\n", kk, ll, kkk, lll, mxws, mxlws);
859  for (int i=0; i<kk+kkk; i++) {
860  printf("ws[%3d] = %15.8e\n ", i, ws[i]);
861  }
862  printf("--------\n");
863  for (int i=kk+kkk; i<mxws; i++) {
864  printf("ws[%3d] = %15.8e\n ", i, ws[i]);
865  }
866  for (int i=0; i<ll+lll; i++) {
867  printf("lws[%5d] = %8d\n", i, lws[i]);
868  }
869  printf("------\n");
870  for (int i=ll+lll; i<mxlws; i++) {
871  printf("lws[%5d] = %8d\n", i, lws[i]);
872  }
873 #endif
874  cpuTime_ += CoinCpuTime();
875  }
876 
877  std::string
879  {"Internal error in Filter SQP."};
880 
881  std::string
883  "filterSqp";
884 
885  const std::string&
887  {
888  return errorNames_[0];
889  }
890 
891  const std::string&
893  {
894  return solverName_;
895  }
896 
897  bool
898  BqpdSolver::setWarmStart(const CoinWarmStart * warm,
900  {
901 #if 0
902  if (IsNull(cached_)) {
903  cached_ = new cachedInfo(GetRawPtr(tnlp), options_);
904  }
905 
906  const FilterWarmStart * warmF = dynamic_cast<const FilterWarmStart *> (warm);
907  //CoinCopyN(warmF->xArray(), warmF->xSize(), cached_->x);
908  const fint xsize = warmF->xSize();
909  real* x = cached_->x;
910  const real* xarray = warmF->xArray();
911  for (int i = 0; i<xsize; i++) {
912  x[i] = xarray[i];
913  }
914  CoinCopyN(warmF->lamArray(), warmF->lamSize(), cached_->lam);
915  CoinCopyN(warmF->lwsArray(), warmF->lwsSize(), cached_->lws);
916  for (int i = 0 ; i < 14 ; i ++) {
917  cached_->istat[i] = warmF->istat()[i];
918  }
919  cached_->use_warm_start_in_cache_ = true;
920 #endif
921  printf("BqpdSolver::setWarmStart called!\n");
922  return true;
923  }
924 
925  CoinWarmStart *
927  {
928 #if 0
929  return new FilterWarmStart(cached_->n, cached_->x,
930  cached_->n+cached_->m, cached_->lam,
931  cached_->maxiWk, cached_->lws, cached_->istat);
932 #endif
933  printf("BqpdSolver::getWarmStart called!\n");
934  return NULL;
935  }
936 
937  CoinWarmStart *
939  {
940 #if 0
941  return new FilterWarmStart;
942 #endif
943  printf("BqpdSolver::getEmptyWarmStart called \n");
944  return NULL;
945  }
946 
948  bool
949  BqpdSolver::warmStartIsValid(const CoinWarmStart * ws) const{
950  const BqpdWarmStart* bws = dynamic_cast<const BqpdWarmStart*>(ws);
951  if (bws && ! bws->empty()) {
952  return true;
953  }
954  return false;
955  }
956 
957 }//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