analyzeSparsity.cpp
Go to the documentation of this file.
1 /* $Id: analyzeSparsity.cpp 732 2011-07-03 20:06:50Z pbelotti $
2  *
3  * Name: analyzeSparsity.cpp
4  * Author: Pietro Belotti
5  * Purpose: return one or more exprGroup/exprQuad based on sparsity of
6  * original one
7  *
8  * (C) Carnegie-Mellon University, 2007-10.
9  * This file is licensed under the Eclipse Public License (EPL)
10  */
11 
12 #include <stdio.h>
13 #include <map>
14 #include <set>
15 
16 #include "CouenneExprQuad.hpp"
17 #include "CouenneTypes.hpp"
18 #include "CouenneProblem.hpp"
19 #include "CouenneExprAux.hpp"
20 #include "CouenneExprMul.hpp"
21 #include "CouenneExprPow.hpp"
22 #include "CouenneLQelems.hpp"
23 
24 using namespace Couenne;
25 
26 #define MIN_DENSITY 0.5
27 
32  LinMap &lmap,
33  QuadMap &qmap) {
34 
35  if (qmap.Map().size () == 0) return;
36 
37  // simple technique: if number of elements in quadratic map is more
38  // than a given fraction of n^2, then turn it into an exprQuad,
39  // otherwise break it down.
40 
41  std::set <int> occur;
42  unsigned int nsquares = 0;
43 
44  for (std::map <std::pair <int,int>, CouNumber>::iterator i = qmap.Map().begin ();
45  i != qmap.Map().end (); ++i) {
46 
47  int
48  first = i -> first.first,
49  second = i -> first.second;
50 
51  if (occur.find (first) == occur.end ())
52  occur.insert (first);
53 
54  if (first != second) {
55  if (occur.find (second) == occur.end ())
56  occur.insert (second);
57  } else nsquares++;
58  }
59 
60  if (jnlst_ -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE)) {
61  printf ("qmap has %d element, occur has %d, md*s*(s+1)/2 = %g\n",
62  qmap.Map().size (),
63  occur.size (),
64  MIN_DENSITY * (double) (occur.size ()) * ((double) (occur.size ()) + 1.) / 2);
65  }
66 
67  int nterms = occur.size ();
68 
69  if (useQuadratic_ &&
70  (((qmap.Map().size () >= MIN_DENSITY * nterms * (nterms+1) / 2) &&
71  (nterms >= 2))
72  //|| (nsquares > nterms/2)
73  || (nsquares >= occur.size ()))
74  )
75  return; // keep current exprQuad structure
76 
77  // flatten exprQuad to a sum of terms (disaggregate). This is while
78  // we are testing exprQuad's
79 
80  for (std::map <std::pair <int,int>, CouNumber>::iterator i = qmap.Map().begin ();
81  i != qmap.Map().end (); ++i) {
82 
83  int indI = i -> first.first,
84  indJ = i -> first.second;
85 
86  exprAux *aux = (indI != indJ) ?
88  (new exprMul (new exprClone (Var (indI)),
89  new exprClone (Var (indJ)))) :
91  (new exprPow (new exprClone (Var (indI)),
92  new exprConst (2.)));
93 
94  // aux -> print (); printf (" := "); aux -> Image () -> print (); printf ("\n");
95 
96  lmap.insert (aux -> Index (), i -> second);
97  }
98 
99  if (qmap.Map().size () == 1) {
100 
101  // very simple case: we have a linear term plus a single bilinear
102  // x*y (or square x^2) term.
103  }
104 
105  qmap.Map().erase (qmap.Map().begin (), qmap.Map().end ());
106 
107  // in general, decompose qmap+lmap into several (qmap+lmap)s so that
108  // each corresponds to an exprQuad to be transformed into a single
109  // auxiliary variable
110 
111  // build graph and look for components -- TODO
112 }
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) ...
#define MIN_DENSITY
void insert(int index, CouNumber coe)
insert a pair &lt;int,CouNumber&gt; into a map for linear terms
expression clone (points to another expression)
const Ipopt::EJournalCategory J_REFORMULATE(Ipopt::J_USER7)
exprVar * Var(int i) const
Return pointer to i-th variable.
double CouNumber
main number type in Couenne
bool useQuadratic_
Use quadratic expressions?
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...
class for multiplications,