linStandardize.cpp
Go to the documentation of this file.
1 /* $Id: linStandardize.cpp 490 2011-01-14 16:07:12Z pbelotti $
2  *
3  * Name: linStandardize.cpp
4  * Author: Pietro Belotti
5  * Purpose: standardize sum expressions (expr{Sum,Sub,Quad,Group,Opp})
6  *
7  * (C) Carnegie-Mellon University, 2007-10.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include <stdio.h>
12 
13 #include "CouenneExprQuad.hpp"
14 
15 #include "CouenneProblem.hpp"
16 #include "CouenneExprAux.hpp"
17 #include "CouenneExprSum.hpp"
18 #include "CouenneExprSub.hpp"
19 #include "CouenneExprOpp.hpp"
20 #include "CouenneExprMul.hpp"
21 #include "CouenneExprPow.hpp"
22 #include "CouenneExprGroup.hpp"
23 #include "CouenneLQelems.hpp"
24 
25 using namespace Couenne;
26 
29  CouNumber c0,
30  LinMap &lmap,
31  QuadMap &qmap) {
32 
33  // check if quadratic forms are dense enough ///////////////////////////////////////////
34 
35  analyzeSparsity (c0, lmap, qmap);
36 
38 
39  int nq = qmap.Map().size (),
40  *qi = new int [nq+1],
41  *qj = new int [nq+1];
42 
43  CouNumber *qc = new CouNumber [nq];
44 
45  int
46  nl = lmap.Map().size(),
47  *li = new int [nl+1];
48 
49  CouNumber *lc = new CouNumber [nl];
50 
51  // terminate arrays with negative index
52  qi [nq] = li [nl] = -1;
53 
54  std::map <int, CouNumber>::iterator lit = lmap.Map().begin ();
55 
56  // fill in arrays for linear part
57  for (int i=0; i<nl; i++, lit++) {
58 
59  li [i] = lit -> first;
60  lc [i] = lit -> second;
61  }
62 
63  std::map <std::pair <int, int>, CouNumber>::iterator qit = qmap.Map().begin ();
64 
65  // fill in arrays for quadratic part
66  for (int i=0; i < nq; i++, qit++) {
67  qi [i] = qit -> first. first;
68  qj [i] = qit -> first. second;
69  qc [i] = qit -> second;
70  }
71 
72  nl = lmap.Map().size ();
73  nq = qmap.Map().size ();
74 
75  // particular cases ///////////////////////////////////////////////////////////
76 
77  expression *ret;
78 
79  // a constant
80  if ((nq==0) && (nl==0))
81 
82  ret = new exprConst (c0); // a constant auxiliary?
83 
84  else if ((nq==0) && (fabs (c0) < COUENNE_EPS) && (nl==1)) { // a linear monomial, cx
85 
86  if (fabs (*lc - 1.) < COUENNE_EPS) ret = new exprClone (Var (*li));
87  else if (fabs (*lc + 1.) < COUENNE_EPS) ret = new exprOpp (new exprClone (Var (*li)));
88  else ret = new exprMul (new exprConst (*lc),
89  new exprClone (Var (*li)));
90 
91  } else if ((nl==0) && (fabs (c0) < COUENNE_EPS) && (nq==1)) {
92 
93  // a bilinear/quadratic monomial, cx^2 or cxy
94 
95  expression *quad;
96 
97  if (*qi == *qj) quad = new exprPow (new exprClone (Var (*qi)), new exprConst (2.));
98  else quad = new exprMul (new exprClone (Var (*qi)),
99  new exprClone (Var (*qj)));
100 
101  if (fabs (*qc - 1) < COUENNE_EPS)
102  ret = quad;
103  else {
104  quad = addAuxiliary (quad);
105  ret = new exprMul (new exprConst (*qc), new exprClone (quad));
106  }
107 
108  } else {
109 
110  // general case ///////////////////////////////////////////////////////////////
111 
112  std::vector <std::pair <exprVar *, CouNumber> > lcoeff;
113  indcoe2vector (li, lc, lcoeff);
114 
115  std::vector <quadElem> qcoeff;
116  indcoe2vector (qi, qj, qc, qcoeff);
117 
118  if (!nq) ret = new exprGroup (c0, lcoeff); // create exprGroup
119  else ret = new exprQuad (c0, lcoeff, qcoeff); // create exprQuad
120  }
121 
122  delete [] li;
123  delete [] lc;
124  delete [] qi;
125  delete [] qj;
126  delete [] qc;
127 
128  if (jnlst_ -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE)) {
129  printf ("\nlinstand (addaux = %d) ==> ", addAux);
130  ret -> print (); printf ("\n");
131  //printf (": "); fflush (stdout);
132  //ret -> Image () -> print ();
133  }
134 
135  //if (ret -> Type () == AUX)
136  //return ret;
137 
138  return (addAux ? addAuxiliary (ret) : new exprAux (ret, &domain_));
139 }
class Group, with constant, linear and nonlinear terms:
class opposite,
exprAux * linStandardize(bool addAux, CouNumber c0, LinMap &lmap, QuadMap &qmap)
standardization of linear exprOp&#39;s
void print(std::ostream &=std::cout)
Display current representation of problem: objective, linear and nonlinear constraints, and auxiliary variables.
Definition: problemIO.cpp:24
Power of an expression (binary operator), with constant.
constant-type operator
exprAux * addAuxiliary(expression *)
Add auxiliary variable and associate it with expression given as argument (used in standardization) ...
fint lc
expression clone (points to another expression)
const Ipopt::EJournalCategory J_REFORMULATE(Ipopt::J_USER7)
#define COUENNE_EPS
exprVar * Var(int i) const
Return pointer to i-th variable.
Domain domain_
current point and bounds;
std::map< int, CouNumber > & Map()
public access
fint li
double CouNumber
main number type in Couenne
class exprQuad, with constant, linear and quadratic terms
std::map< std::pair< int, int >, CouNumber > & Map()
public access
Auxiliary variable.
JnlstPtr jnlst_
SmartPointer to the Journalist.
void analyzeSparsity(CouNumber, LinMap &, QuadMap &)
analyze sparsity of potential exprQuad/exprGroup and change linear/quadratic maps accordingly...
void indcoe2vector(int *indexL, CouNumber *coeff, std::vector< std::pair< exprVar *, CouNumber > > &lcoeff)
translates pair (indices, coefficients) into vector with pointers to variables
Expression base class.