CouenneAmplInterface.cpp
Go to the documentation of this file.
1 // $Id: CouenneAmplInterface.cpp 1147 2015-05-04 14:01:51Z stefan $
2 //
3 // (C) Copyright XXX 2009
4 // All Rights Reserved.
5 // This code is published under the Eclipse Public License (EPL).
6 //
7 // Authors :
8 // Pietro Belotti, Lehigh University
9 // Stefan Vigerske, Humboldt University
10 //
11 // Date : 07/18/2009
12 
13 #include "CouenneConfig.h"
14 #include "CouenneAmplInterface.hpp"
15 #include "CoinPragma.hpp"
16 
17 #include <cstdlib>
18 
19 #if defined HAVE_CSTDINT
20 #include <cstdint>
21 #elif defined HAVE_STDINT_H
22 #include <stdint.h>
23 #endif
24 
25 #include <string>
26 
27 #include "BonAmplTMINLP.hpp"
28 #include "BonCbc.hpp"
29 
30 #include "CouenneProblem.hpp"
31 #include "CouenneTypes.hpp"
32 
33 #include "CouenneExprClone.hpp"
34 #include "CouenneExprGroup.hpp"
35 #include "CouenneExprAbs.hpp"
36 #include "CouenneExprSum.hpp"
37 #include "CouenneExprSub.hpp"
38 #include "CouenneExprMul.hpp"
39 #include "CouenneExprDiv.hpp"
40 #include "CouenneExprInv.hpp"
41 #include "CouenneExprSin.hpp"
42 #include "CouenneExprPow.hpp"
43 #include "CouenneExprLog.hpp"
44 #include "CouenneExprOpp.hpp"
45 #include "CouenneExprCos.hpp"
46 #include "CouenneExprExp.hpp"
47 
48 #include "asl.h"
49 #include "nlp.h"
50 #include "getstub.h"
51 #include "opcode.hd"
52 
53 // get ASL op. code relative to function pointer passed as parameter
54 int getOperator (efunc *);
55 
56 #define OBJ_DE ((const ASL_fg *) asl) -> I.obj_de_
57 #define VAR_E ((const ASL_fg *) asl) -> I.var_e_
58 #define CON_DE ((const ASL_fg *) asl) -> I.con_de_
59 #define OBJ_sense ((const ASL_fg *) asl) -> i.objtype_
60 
61 #include "r_opn.hd" /* for N_OPS */
62 
63 static fint timing = 0;
64 
65 static
66 keyword keywds[] = { // must be alphabetical
67  KW(const_cast<char*>("timing"), L_val, &timing, const_cast<char*>("display timings for the run")),
68 };
69 
70 static
71 Option_Info Oinfo = { const_cast<char*>("testampl"), const_cast<char*>("ANALYSIS TEST"),
72  const_cast<char*>("concert_options"), keywds, nkeywds, 0, const_cast<char*>("ANALYSIS TEST") };
73 
74 
75 // (C++) code starts here ///////////////////////////////////////////////////////////////////////////
76 
77 using namespace Couenne;
78 
80  roptions->AddStringOption1("nlfile", "name of an ampl .nl file to get the problem from", "", "*", "name of .nl file");
81 }
82 
84  delete problem;
85 
86  if (asl) {
87  delete[] X0;
88  delete[] havex0;
89  delete[] pi0;
90  delete[] havepi0;
91  ASL_free(&asl);
92  }
93 }
94 
95 // create an AMPL problem by using ASL interface to the .nl file
97  if (problem)
98  return problem;
99 
100  if (!readASLfg())
101  return NULL;
102 
103  problem = new CouenneProblem;
104 
105  if (!readnl()) {
106  delete problem;
107  problem = NULL;
108  return NULL;
109  }
110 
111  return problem;
112 }
113 
115  if (IsValid(tminlp))
116  return tminlp;
117 
118  if (IsNull(roptions)) {
119  jnlst->Printf(Ipopt::J_ERROR, Ipopt::J_INITIALIZATION, "Error: Need registered options to create AmplTMINLP object!\n");
120  return NULL;
121  }
122 
123  std::string nlfile;
124  options->GetStringValue("nlfile", nlfile, "");
125  char** argv = new char*[3];
126  argv[0] = const_cast<char*>("dummy");
127  argv[1] = strdup(nlfile.c_str());
128  argv[2] = NULL;
130 
131  free(argv[1]);
132  delete[] argv;
133 
134  return tminlp;
135 }
136 
138  const char* message;
139 
140  //TODO setup a nicer message
141  if (bab.bestSolution()) {
142  message = "Couenne found a solution.\n";
143  } else {
144  message = "Couenne could not found a solution.\n";
145  }
146 
147  write_sol(const_cast<char*>(message), const_cast<double*>(bab.bestSolution()), NULL, NULL);
148 
149  return true;
150 }
151 
153  assert(asl == NULL);
154 
155  std::string nlfile;
156  options->GetStringValue("nlfile", nlfile, "");
157 
158  if (nlfile == "")
159  return false;
160 
161  char** argv = new char*[3];
162  argv[0] = const_cast<char*>("dummy");
163  argv[1] = strdup(nlfile.c_str());
164  argv[2] = NULL;
165 
166  // Create the ASL structure
167  asl = (ASL*) ASL_alloc (ASL_read_fg);
168 
169  char* stub = getstub (&argv, &Oinfo);
170 
171  // Although very intuitive, we shall explain why the second argument
172  // is passed with a minus sign: it is to tell the ASL to retrieve
173  // the nonlinear information too.
174  FILE* nl = jac0dim (stub, - (fint) strlen (stub));
175 
176  // Set options in the asl structure
177  want_xpi0 = 1 | 2; // allocate initial values for primal and dual if available
178  obj_no = 0; // always want to work with the first (and only?) objective
179 
180  // allocate space for initial values
181  X0 = new real [n_var];
182  havex0 = new char [n_var];
183  pi0 = new real [n_con];
184  havepi0 = new char [n_con];
185 
186  // read the rest of the nl file
187  fg_read (nl, ASL_return_read_err | ASL_findgroups);
188 
189  //FIXME freeing argv and argv[1] gives segfault !!!
190 // free(argv[1]);
191 // delete[] argv;
192 
193  return true;
194 }
195 
196 // check if an expression is a null pointer or equals zero
197 //static inline bool is_expr_zero (expr* e) {
198 // return ((e==NULL) || ((((Intcast (e->op)) == OPNUM) &&
199 // (fabs (((expr_n *)e) -> v) < COUENNE_EPS)
200 // // && (fabs (e -> dL) < COUENNE_EPS)
201 // // *** CHECK THIS! dL is the derivative
202 // )));
203 //}
204 
205 
206 // Reads a MINLP from an AMPL .nl file through the ASL methods
208 
209  std::string nlfile;
210  options->GetStringValue("nlfile", nlfile, "");
211  problem -> setProblemName (nlfile);
212 
213  // number of defined variables (aka common expressions)
214  problem -> setNDefVars(como + comc + comb + como1 + comc1);
215 
216  // see "hooking your solver to AMPL", by David M. Gay, tables 3, 4, and 5
217 
218  // nonlinear in both objectives and constraints
219  if (nlvb >= 0) {
220  for (int i = 0; i < nlvb - nlvbi; i++) problem -> addVariable (false, problem -> domain ());
221  for (int i = 0; i < nlvbi; i++) problem -> addVariable (true, problem -> domain ());
222  }
223 
224  // nonlinear in either objectives or constraints
225  if (nlvo > nlvc) {
226  for (int i = 0; i < nlvc - (nlvb + nlvci); i++) problem -> addVariable (false, problem -> domain ());
227  for (int i = 0; i < nlvci; i++) problem -> addVariable (true, problem -> domain ());
228  for (int i = 0; i < nlvo - (nlvc + nlvoi); i++) problem -> addVariable (false, problem -> domain ());
229  for (int i = 0; i < nlvoi; i++) problem -> addVariable (true, problem -> domain ());
230  } else {
231  for (int i = 0; i < nlvo - (nlvb + nlvoi); i++) problem -> addVariable (false, problem -> domain ());
232  for (int i = 0; i < nlvoi; i++) problem -> addVariable (true, problem -> domain ());
233  for (int i = 0; i < nlvc - (nlvo + nlvci); i++) problem -> addVariable (false, problem -> domain ());
234  for (int i = 0; i < nlvci; i++) problem -> addVariable (true, problem -> domain ());
235  }
236 
237  for (int i = 0; i < nwv; i++) problem -> addVariable(false, problem -> domain ());//arc
238  for (int i = n_var - (CoinMax (nlvc,nlvo) +niv+nbv+nwv); i--;) problem -> addVariable(false, problem -> domain ());//other
239  for (int i = 0; i < nbv; i++) problem -> addVariable(true, problem -> domain ());//binary
240  for (int i = 0; i < niv; i++) problem -> addVariable(true, problem -> domain ());//int.
241 
242  // add space for common expressions
243  for (int i = problem->nDefVars(); i--;) problem -> addVariable(false, problem -> domain ());
244 
245  // common expressions (or defined variables) ///////////////////////////////////////
246 
247 #ifdef DEBUG
248  printf ("tot var = %d\n", variables_ . size ());
249  printf ("c_vars_ = %d\n", ((const ASL_fg *) asl) -> i.c_vars_ );
250  printf ("comb_ = %d\n", ((const ASL_fg *) asl) -> i.comb_ );
251  printf ("combc_ = %d\n", ((const ASL_fg *) asl) -> i.combc_ );
252  printf ("comc1_ = %d\n", ((const ASL_fg *) asl) -> i.comc1_ );
253  printf ("comc_ = %d\n", ((const ASL_fg *) asl) -> i.comc_ );
254  printf ("como1_ = %d\n", ((const ASL_fg *) asl) -> i.como1_ );
255  printf ("como_ = %d\n", ((const ASL_fg *) asl) -> i.como_ );
256 #endif
257 
258  // Each has a linear and a nonlinear part (thanks to Dominique
259  // Orban: http://www.gerad.ca/~orban/drampl/def-vars.html)
260 
261  try {
262  for (int i = 0; i < como + comc + comb; i++) {
263 
264  struct cexp *common = ((const ASL_fg *) asl) -> I.cexps_ + i;
265  expression *nle = nl2e (common -> e);
266 
267 #ifdef DEBUG
268  printf ("cexp %d [%d]: ", i, problem -> nVars()); nle -> print (); printf (" ||| ");
269 #endif
270 
271  int nlin = common -> nlin; // Number of linear terms
272 
273  if (nlin > 0) {
274 
275  int *indexL = new int [nlin+1];
276  CouNumber *coeff = new CouNumber [nlin];
277 
278  linpart *L = common -> L;
279 
280  for (int j = 0; j < nlin; j++) {
281  //vp = (expr_v *)((char *)L->v.rp - ((char *)&ev.v - (char *)&ev));
282  //Printf( " %-g x[%-d]", L->fac, (int)(vp - VAR_E) );
283  coeff [j] = L [j]. fac;
284  indexL [j] = ((uintptr_t) (L [j].v.rp) - (uintptr_t) VAR_E) / sizeof (expr_v);
285 #ifdef DEBUG
286  Printf( " %+g x_%-3d", L [j]. fac,
287  (expr_v *) (L [j].v.rp) - VAR_E //((const ASL_fg *) asl) -> I.cexps_
288  //L [j]. v.i
289  );
290 #endif
291  }
292 
293  indexL [nlin] = -1;
294 
295  expression **al = new expression * [1];
296  *al = nle;
297 
298  std::vector <std::pair <exprVar *, CouNumber> > lcoeff;
299  problem -> indcoe2vector (indexL, coeff, lcoeff);
300 
301  expression *eg = exprGroup::genExprGroup (0, lcoeff, al, 1);
302  problem -> commonExprs (). push_back (eg);
303  }
304  else problem -> commonExprs () . push_back (nle);
305 #ifdef DEBUG
306  printf ("\n");
307 #endif
308  }
309 
310  for (int i = 0; i < como1 + comc1; i++) {
311 
312  struct cexp1 *common = ((const ASL_fg *) asl) -> I.cexps1_ + i;
313  expression *nle = nl2e (common -> e);
314 
315 #ifdef DEBUG
316  printf ("cexp1 %d [%d]: ", i, variables_ . size ()); nle -> print (); printf (" ||| ");
317 #endif
318 
319  int nlin = common -> nlin; // Number of linear terms
320 
321  if (nlin > 0) {
322 
323  int *indexL = new int [nlin+1];
324  CouNumber *coeff = new CouNumber [nlin];
325 
326  linpart *L = common -> L;
327 
328  for (int j = 0; j < nlin; j++) {
329  //vp = (expr_v *)((char *)L->v.rp - ((char *)&ev.v - (char *)&ev));
330  coeff [j] = L [j]. fac;
331  indexL [j] = ((uintptr_t) (L [j].v.rp) - (uintptr_t) VAR_E) / sizeof (expr_v);
332 #ifdef DEBUG
333  Printf( " %+g x_%-3d", L [j]. fac,
334  (expr_v *) (L [j].v.rp) - VAR_E //((const ASL_fg *) asl) -> I.cexps_
335  //L [j]. v.i
336  );
337 #endif
338  }
339 
340  indexL [nlin] = -1;
341 
342  expression **al = new expression * [1];
343  *al = nle;
344 
345  std::vector <std::pair <exprVar *, CouNumber> > lcoeff;
346  problem -> indcoe2vector (indexL, coeff, lcoeff);
347 
348  expression *eg = exprGroup::genExprGroup (0, lcoeff, al, 1);
349  problem -> commonExprs () . push_back (eg);
350  }
351  else problem -> commonExprs () . push_back (nle);
352 #ifdef DEBUG
353  printf ("\n");
354 #endif
355  // addAuxiliary (nl2e (((const ASL_fg *) asl) -> I.cexps1_ [i] . e));
356  }
357 
358  // objective functions /////////////////////////////////////////////////////////////
359 
360  for (int i = 0; i < n_obj; i++) {
361 
363  int nterms = 0;
364 
365  // count nonzero terms in linear part
366 
367  for (ograd *objgrad = Ograd [i];
368  objgrad;
369  objgrad = objgrad -> next)
370  if (fabs (objgrad -> coef) > COUENNE_EPS)
371  nterms++;
372 
373  expression
374  *body,
375  *nl = nl2e (OBJ_DE [i] . e);
376 
377  if (nterms) { // have linear terms
378 
379  int *indexL = new int [nterms+1];
380  CouNumber *coeff = new CouNumber [nterms];
381 
382  for (ograd *objgrad = Ograd [i]; objgrad; objgrad = objgrad -> next)
383  if (fabs (objgrad -> coef) > COUENNE_EPS) {
384 
385  *indexL++ = objgrad -> varno;
386  *coeff++ = objgrad -> coef;
387  }
388 
389  *indexL = -1;
390 
391  indexL -= nterms;
392  coeff -= nterms;
393 
394  std::vector <std::pair <exprVar *, CouNumber> > lcoeff;
395  problem -> indcoe2vector (indexL, coeff, lcoeff);
396 
397  if (nl -> code () == COU_EXPRSUM) {
398  body = exprGroup::genExprGroup (0., lcoeff, nl -> ArgList (), nl -> nArgs ());
399  // delete node without deleting children (they are now in body)
400  nl -> ArgList (NULL);
401  delete nl;
402  }
403  else {
404 
405  expression **nll = new expression * [1];
406 
407  *nll = nl;
408 
409  // apparently, objconst (i) is included in the obj expression
410  body = exprGroup::genExprGroup (0., lcoeff, nll, 1);
411  //body = new exprGroup (objconst (i), indexL, coeff, nll, 1);
412  }
413 
414  delete [] indexL;
415  delete [] coeff;
416 
417  } else
418  // apparently, objconst (i) is included in the obj expression
419  body = nl;
420  //if (fabs (objconst (i) > COUENNE_EPS))
421  //body = new exprSum (nl, new exprConst (objconst (i)));
422  //else
423 
425 
426  expression *subst = Simplified (body);// -> simplify ();
427 
428  // if (subst) {
429  // delete body; // VALGRIND
430  // body = subst;
431  // }
432 
433  // ThirdParty/ASL/solvers/asl.h, line 336: 0 is minimization, 1 is maximization
434  problem -> addObjective (body, (OBJ_sense [i] == 0) ? "min" : "max");
435  }
436 
437  // constraints ///////////////////////////////////////////////////////////////////
438 
439  int *nterms = new int [n_con];
440 
441  // allocate space for argument list of all constraints' summations
442  // of linear and nonlinear terms
443 
444  // init array with # terms of each constraint
445  for (int i = n_con; i--;)
446  *nterms++ = 0;
447  nterms -= n_con;
448 
449  cgrad *congrad;
450 
451  // count all linear terms
452  if (A_colstarts && A_vals) // Constraints' linear info is stored in A_vals
453  for (register int j = A_colstarts [n_var]; j--;) {
454 
455  real coeff = A_vals [j];
456 
457  if (fabs (coeff) > COUENNE_EPS)
458  nterms [A_rownos [j]] ++;
459  }
460  else { // Constraints' linear info is stored in Cgrad
461  for (register int i = 0; i < n_con; i++)
462  for (congrad = Cgrad [i];
463  congrad;
464  congrad = congrad -> next)
465  if (fabs (congrad -> coef) > COUENNE_EPS)
466  nterms [i] ++;
467  }
468 
469 
470  // vectors of the linear part
471  CouNumber **coeff = new CouNumber * [n_con];
472  int **indexL = new int * [n_con];
473 
474  for (register int i = n_con; i--;)
475  *indexL++ = NULL;
476 
477  indexL -= n_con;
478 
479 
480  // set linear terms
481 
482  if (A_colstarts && A_vals) // Constraints' linear info is stored in A_vals
483  for (int j = 0; j < n_var; j++)
484  for (register int i = A_colstarts [j], k = A_colstarts [j+1] - i; k--; i++) {
485 
486  int rowno = A_rownos [i],
487  nt = nterms [rowno] --;
488 
489  CouNumber **cline = coeff + rowno;
490  int **iline = indexL + rowno;
491 
492  if (*iline==NULL) {
493  *cline = new CouNumber [nt];
494  *iline = new int [nt+1];
495  (*iline) [nt] = -1;
496  }
497 
498  (*cline) [--nt] = A_vals [i];
499  (*iline) [nt] = j;
500 
501  }
502  else { // Constraints' linear info is stored in Cgrad
503  for (int i=0; i < n_con; i++) {
504 
505  int nt = nterms [i];
506 
507  CouNumber **cline = coeff + i;
508  int **iline = indexL + i;
509 
510  *cline = new CouNumber [nt];
511  *iline = new int [nt+1];
512  (*iline) [nt] = -1;
513 
514  for (congrad = Cgrad [i]; congrad; congrad = congrad -> next)
515  if (fabs (congrad -> coef) > COUENNE_EPS) {
516  (*cline) [--nt] = congrad -> coef;
517  (*iline) [nt] = congrad -> varno;
518  }
519  }
520  }
521 
522  // set constraints' bound and sign and store nonlinear part ///////////////////////////////
523 
524  for (int i = 0; i < n_con; i++) {
525 
526  enum con_sign sign;
527  double lb, ub;
528 
529  if (Urhsx) {
530  lb = LUrhs [i];
531  ub = Urhsx [i];
532  } else {
533  int j = 2*i;
534  lb = LUrhs [j];
535  ub = LUrhs [j+1];
536  }
537 
538  // set constraint sign
539  if (lb > negInfinity)
540  if (ub < Infinity) sign = COUENNE_RNG;
541  else sign = COUENNE_GE;
542  else sign = COUENNE_LE;
543 
544  // this is an equality constraint
545  if (fabs (lb - ub) < COUENNE_EPS)
546  sign = COUENNE_EQ;
547 
548  expression *body;
549 
550  expression **nll = new expression * [1];
551  *nll = nl2e (CON_DE [i] . e);
552 
553  if (indexL [i] && (*(indexL [i]) >= 0)) {
554 
555  int code = (*nll) -> code ();
556 
557  std::vector <std::pair <exprVar *, CouNumber> > lcoeff;
558  problem -> indcoe2vector (indexL [i], coeff [i], lcoeff);
559 
560  /*std::vector <std::pair <exprVar *, CouNumber> > lcoeff;
561  for (int i=0, *ind = indexL; *ind >= 0; *ind++, i++)
562  lcoeff.push_back (std::pair <exprVar *, CouNumber> (Var (*ind), coeff [i]));*/
563 
564  if ((code == COU_EXPRSUM) ||
565  (code == COU_EXPRGROUP)) {
566 
567  body = exprGroup::genExprGroup (0., lcoeff, (*nll) -> ArgList (), (*nll) -> nArgs ());
568  // delete node without deleting children (they are now in body)
569  (*nll) -> ArgList (NULL);
570  delete *nll;
571  delete [] nll;
572  }
573  else body = exprGroup::genExprGroup (0., lcoeff, nll, 1);
574  }
575  else {
576  body = *nll;
577  delete [] nll;
578  }
579 
580  expression *subst = Simplified (body);
581 
582  // -> simplify ();
583  // if (subst) {
584  // delete body; // VALGRIND
585  // body = subst;
586  // }
587 
588  // add them (and set lower-upper bound)
589  switch (sign) {
590 
591  case COUENNE_EQ: problem -> addEQConstraint (body, new exprConst (ub)); break;
592  case COUENNE_LE: problem -> addLEConstraint (body, new exprConst (ub)); break;
593  case COUENNE_GE: problem -> addGEConstraint (body, new exprConst (lb)); break;
594  case COUENNE_RNG: problem -> addRNGConstraint (body, new exprConst (lb),
595  new exprConst (ub)); break;
596  default: jnlst->Printf(Ipopt::J_ERROR, Ipopt::J_INITIALIZATION, "Error: could not recognize constraint\n"); return false;
597  }
598 
599  delete [] indexL [i];
600  delete [] coeff [i];
601  }
602 
603  delete [] indexL;
604  delete [] coeff;
605  delete [] nterms;
606 
607  } catch (...) {
608  return false;
609  }
610 
611  // create room for problem's variables and bounds
612  CouNumber
613  *x = (CouNumber *) malloc ((n_var + problem -> nDefVars() ) * sizeof (CouNumber)),
614  *lb = (CouNumber *) malloc ((n_var + problem -> nDefVars() ) * sizeof (CouNumber)),
615  *ub = (CouNumber *) malloc ((n_var + problem -> nDefVars() ) * sizeof (CouNumber));
616 
617  for (int i = n_var + problem -> nDefVars(); i--;) {
618  x [i] = 0.;
619  lb [i] = -COUENNE_INFINITY;
620  ub [i] = COUENNE_INFINITY;
621  }
622 
623  problem -> domain () -> push (n_var + problem -> nDefVars(), x, lb, ub);
624  free (x); free (lb); free (ub);
625 
626  // suggested:
627  // problem -> domain () -> push (n_var + problem -> nDefVars(), x, lb, ub, false);
628  // //free (x); free (lb); free (ub);
629  // saves three allocations (default last parameter is true, which copies x,l,b)
630 
631  // lower and upper bounds ///////////////////////////////////////////////////////////////
632 
633  if (LUv) {
634 
635  real *Uvx_copy = Uvx;
636 
637  if (!Uvx_copy)
638  for (register int i=0; i<n_var; i++) {
639 
640  register int j = 2*i;
641 
642  problem -> Lb (i) = LUv[j] <= -COUENNE_INFINITY ? -COUENNE_INFINITY : LUv[j] ;
643  problem -> Ub (i) = LUv[j+1] >= COUENNE_INFINITY ? COUENNE_INFINITY : LUv[j+1];
644  }
645  else
646  for (register int i=n_var; i--;) {
647  problem -> Lb (i) = LUv [i] <= -COUENNE_INFINITY ? -COUENNE_INFINITY : LUv[i];
648  problem -> Ub (i) = Uvx_copy [i] >= COUENNE_INFINITY ? COUENNE_INFINITY : Uvx_copy[i];
649  }
650 
651  } else
652  for (register int i=n_var; i--;) {
653  problem -> Lb (i) = - COUENNE_INFINITY;
654  problem -> Ub (i) = COUENNE_INFINITY;
655  }
656 
657  // initial x ////////////////////////////////////////////////////////////////////
658 
659  for (register int i=n_var; i--;)
660 
661  if (X0 && havex0 [i]) problem -> X (i) = X0 [i];
662 
663  else {
664 
665  CouNumber x, l = problem -> Lb (i), u = problem -> Ub (i);
666 
667  if (l < - COUENNE_INFINITY)
668  if (u > COUENNE_INFINITY) x = 0.;
669  else x = u;
670  else if (u > COUENNE_INFINITY) x = l;
671  else x = 0.5 * (l+u);
672 
673  problem -> X (i) = x;
674  }
675 
676  for (register int i=n_var; i < problem -> nDefVars() ; i++) { //FIXME: shouldn't this loop go until n_var + problem -> nDefVars() ?
677 
678  problem -> X (i) = 0.;
679  problem -> Lb (i) = -COUENNE_INFINITY;
680  problem -> Ub (i) = COUENNE_INFINITY;
681  }
682 
683  return true;
684 }
685 
686 
687 // warning for non-implemented functions -- return 0 constant expression
688 //expression *notimpl (const std::string &fname) {
689 //static void notimpl (const std::string &fname) {
690 // std::cerr << "*** Error: " << fname << " not implemented" << std::endl;
691 // exit (-1);
692 //}
693 
694 // converts an AMPL expression (sub)tree into an expression* (sub)tree
696 
697  switch (getOperator (e -> op)) {
698 
699  case OPPLUS: return new exprSum (nl2e (e -> L.e), nl2e (e -> R.e));
700  case OPMINUS: return new exprSub (nl2e (e -> L.e), nl2e (e -> R.e));
701  case OPMULT: return new exprMul (nl2e (e -> L.e), nl2e (e -> R.e));
702  case OPDIV: return new exprDiv (nl2e (e -> L.e), nl2e (e -> R.e));
703  //case OPREM: notimpl ("remainder");
704  case OPPOW: return new exprPow (nl2e (e -> L.e), nl2e (e -> R.e));
705  //case OPLESS: notimpl ("less");
706  //case MINLIST: notimpl ("min");
707  //case MAXLIST: notimpl ("max");
708  //case FLOOR: notimpl ("floor");
709  //case CEIL: notimpl ("ceil");
710  case ABS: return new exprAbs (nl2e (e -> L.e));
711  case OPUMINUS:return new exprOpp (nl2e (e -> L.e));
712  // return new exprOpp (nl2e (e -> L.e -> L.e));
713  //case OPIFnl: { notimpl ("ifnl");
714 
715  // see ASL/solvers/rops.c, IfNL
716  //}
717 
718  case OP_tanh: return new exprDiv
719  (new exprSub (new exprExp (nl2e (e -> L.e)),
720  new exprExp (new exprOpp (nl2e (e->L.e)))),
721  new exprSum (new exprExp (nl2e (e -> L.e)),
722  new exprExp (new exprOpp (nl2e (e->L.e)))));
723 
724  case OP_tan: {
725  expression *arg;
726  arg = nl2e (e -> L.e);
727  return new exprDiv (new exprSin (arg), new exprCos (new exprClone (arg)));
728  }
729  case OP_sqrt: return new exprPow (nl2e (e -> L.e), new exprConst (0.5));
730  case OP_sinh: return new exprMul (new exprConst (0.5),
731  new exprSub (new exprExp (nl2e (e -> L.e)),
732  new exprExp (new exprOpp (nl2e (e->L.e)))));
733  case OP_sin: return new exprSin (nl2e (e -> L.e));
734  case OP_log10: return new exprMul (new exprConst (1.0 / log (10.0)),
735  new exprLog (nl2e (e -> L.e)));
736  case OP_log: return new exprLog (nl2e (e -> L.e));
737  case OP_exp: return new exprExp (nl2e (e -> L.e));
738  case OP_cosh: return new exprMul (new exprConst (0.5),
739  new exprSum (new exprExp (nl2e (e -> L.e)),
740  new exprExp (new exprOpp (nl2e (e->L.e)))));
741 
742  case OP_cos: return new exprCos (nl2e (e -> L.e));
743  //case OP_atanh: notimpl ("atanh");
744  //case OP_atan2: notimpl ("atan2");
745  //case OP_atan: notimpl ("atan");
746  //case OP_asinh: notimpl ("asinh");
747  //case OP_asin: notimpl ("asin");
748  //case OP_acosh: notimpl ("acosh");
749  //case OP_acos: notimpl ("acos");
750 
751  case OPSUMLIST: {
752  int i=0;
753  expression **al = new expression * [(e->R.ep - e->L.ep)];
754  for (expr **ep = e->L.ep; ep < e->R.ep; ep++)
755  al [i++] = nl2e (*ep);
756  return new exprSum (al, i);
757  }
758  //case OPintDIV: notimpl ("intdiv");
759  //case OPprecision: notimpl ("precision");
760  //case OPround: notimpl ("round");
761  //case OPtrunc: notimpl ("trunc");
762 
763  case OP1POW: return new exprPow (nl2e (e -> L.e),
764  new exprConst (((expr_n *)e->R.e)->v));
765  case OP2POW: return new exprPow (nl2e (e -> L.e),
766  new exprConst (2.));
767  case OPCPOW: return new exprPow (new exprConst (((expr_n *)e->L.e)->v),
768  nl2e (e -> R.e));
769  //case OPFUNCALL: notimpl ("function call");
770  case OPNUM: return new exprConst (((expr_n *)e)->v);
771  //case OPPLTERM: notimpl ("plterm");
772  //case OPIFSYM: notimpl ("ifsym");
773  //case OPHOL: notimpl ("hol");
774  case OPVARVAL: {
775 
776  int j = ((expr_v *) e) -> a;
777 
778  if (j >= problem -> nOrigVars()) // common expression
779  // use base pointer otherwise the .a field returns an awkward, out-of-bound index
780  j = ((expr_v *) e) - ((const ASL_fg *) asl) -> I.var_e_;
781 
782  if (j >= problem -> nOrigVars() + problem -> nDefVars()) {
783  jnlst -> Printf (Ipopt::J_ERROR, Ipopt::J_INITIALIZATION, "Error: unknown variable x_%d\n", j);
784  throw -1;
785  }
786 
787  return new exprClone (problem -> Variables() [j]);
788  }
789 
790  default:
791  jnlst -> Printf (Ipopt::J_ERROR, Ipopt::J_INITIALIZATION, "ERROR: unknown operator (address %p), aborting.\n", Intcast (e -> op));
792  throw -2;
793  }
794 
795  return new exprConst (0.);
796 }
Ipopt::SmartPtr< Ipopt::OptionsList > options
CouenneProblem * getCouenneProblem()
Should return the problem to solve in algebraic form.
#define CON_DE
ULong L
Definition: OSdtoa.cpp:1816
class cosine,
class for subtraction,
CouExpr & log(CouExpr &e)
class opposite,
bool writeSolution(Bonmin::Bab &bab)
Called after B&amp;B finished.
Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions
void fint fint fint real * a
Power of an expression (binary operator), with constant.
Ipopt::SmartPtr< Ipopt::Journalist > jnlst
bool IsValid(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:465
if(!yyg->yy_init)
Ipopt::SmartPtr< Bonmin::TMINLP > tminlp
Bonmin::BqpdSolver::fint fint
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
#define VAR_E
constant-type operator
static char * j
Definition: OSdtoa.cpp:3622
Option_Info Oinfo
Definition: readASLfg.cpp:24
class for divisions,
static expression * genExprGroup(CouNumber, lincoeff &, expression **=NULL, int=0)
Generalized (static) constructor: check parameters and return a constant, a single variable...
Definition: exprGroup.cpp:50
void fint fint fint real fint real real real real real real real real real * e
Bonmin::BqpdSolver::real real
bool IsNull(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:471
int nDefVars() const
Number of def&#39;d variables.
int getOperator(efunc *)
Definition: invmap.cpp:51
Class for MINLP problems with symbolic information.
void fint fint * k
expression clone (points to another expression)
#define COUENNE_EPS
#define Intcast
Definition: OSdtoa.cpp:38
Ipopt::SmartPtr< Bonmin::TMINLP > getTMINLP()
Should return the problem to solve as TMINLP.
U * GetRawPtr(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:452
static fint timing
double CouNumber
main number type in Couenne
expression * Simplified(expression *complicated)
Macro to return already simplified expression without having to do the if part every time simplify ()...
#define COUENNE_INFINITY
class logarithm,
con_sign
sign of constraint
Ampl MINLP Interface.
const double * bestSolution() const
get the best solution known to the problem (is optimal if MipStatus is FeasibleOptimal).
Definition: BonCbc.hpp:47
#define OBJ_sense
fint nt
Expression base class.
class for the exponential,
The in-memory representation of the variables element.
Definition: OSInstance.h:83
static keyword keywds[]
Definition: CouTight.cpp:47
#define OBJ_DE
void fint fint fint real fint real * x
class for multiplications,