compQuadFinBounds.cpp
Go to the documentation of this file.
1 /* $Id: compQuadFinBounds.cpp 490 2011-01-14 16:07:12Z pbelotti $ */
2 /*
3  * Name: compQuadFinBounds.cpp
4  * Author: Pietro Belotti
5  * Purpose: compute bounds on quadratic form without the contribution of a single variable
6  *
7  * (C) Carnegie-Mellon University, 2006.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include "CouenneExprQuad.hpp"
12 #include "CoinHelperFunctions.hpp"
13 
14 using namespace Couenne;
15 
16 void updateInf (CouNumber coe, CouNumber lb, CouNumber ub, int &indInf1, int &indInf2, int i) {
17 
18  if (coe > 0) {
19  if (lb < 0) indInf1 = (indInf1 == -1) ? i : -2;
20  if (ub > 0) indInf2 = (indInf2 == -1) ? i : -2;
21  } else {
22  if (lb < 0) indInf2 = (indInf2 == -1) ? i : -2;
23  if (ub > 0) indInf1 = (indInf1 == -1) ? i : -2;
24  }
25 }
26 
27 // compute bound of a quadratic expression neglecting the infinite
28 // bounds of single variables
29 
31  CouNumber &qMax,
32  CouNumber *l,
33  CouNumber *u,
34  int &indInfLo,
35  int &indInfUp) {
36 
37  // linear terms ///////////////////////////////////////////////////
38 
39  for (lincoeff::iterator el = lcoeff_.begin (); el != lcoeff_.end (); ++el) {
40 
41  int ind = el -> first -> Index ();
42 
43  CouNumber
44  coe = el -> second,
45  li = l [ind],
46  ui = u [ind];
47 
48  if (coe < 0) { // negative coefficient
49 
50  if (indInfLo > -2) {
51  if (ui > COUENNE_INFINITY) indInfLo = (indInfLo == -1) ? ind : -2;
52  else qMin += coe * ui;
53  }
54 
55  if (indInfUp > -2) {
56  if (li < -COUENNE_INFINITY) indInfUp = (indInfUp == -1) ? ind : -2;
57  else qMax += coe * li;
58  }
59  } else { // positive coefficient
60 
61  if (indInfLo > -2) {
62  if (li < -COUENNE_INFINITY) indInfLo = (indInfLo == -1) ? ind : -2;
63  else qMin += coe * li;
64  }
65 
66  if (indInfUp > -2) {
67  if (ui > COUENNE_INFINITY) indInfUp = (indInfUp == -1) ? ind : -2;
68  else qMax += coe * ui;
69  }
70  }
71  }
72 
73  // quadratic terms ///////////////////////////////////////////////////
74 
75  for (sparseQ::iterator row = matrix_.begin (); row != matrix_.end (); ++row) {
76 
77  int i = row -> first -> Index ();
78 
79  for (sparseQcol::iterator col = row -> second.begin (); col != row -> second.end (); ++col) {
80 
81  int j = col -> first -> Index ();
82 
83  CouNumber
84  coe = col -> second,
85  lbi = l [i],
86  ubi = u [i];
87 
88  if (i==j) { // term of the form q_{ii} x_i^2
89 
90  CouNumber
91  tmin = (ubi <= 0) ? (ubi * ubi) : (lbi >= 0) ? (lbi * lbi) : 0,
92  tmax = CoinMax (lbi*lbi, ubi*ubi);
93 
94  if (coe < 0) { // negative coefficient, q_{ii} < 0
95  qMax += coe * tmin;
96  if (indInfLo > -2) {
97  if (tmax > COUENNE_INFINITY) indInfLo = (indInfLo == -1) ? i : -2;
98  else qMin += coe * tmax;
99  }
100  } else { // positive coefficient
101  qMin += coe * tmin;
102  if (indInfUp > -2) {
103  if (tmax > COUENNE_INFINITY) indInfUp = (indInfUp == -1) ? i : -2;
104  else qMax += coe * tmax;
105  }
106  }
107  } else { // term of the form q_{ij} x_i x_j, j\neq i
108 
109  CouNumber
110  lbj = l [j],
111  ubj = u [j];
112 
113  coe *= 2;
114 
115  // check if index i wrings unbounded value in both directions
116 
117  if (lbi < -COUENNE_INFINITY) updateInf (coe, lbj, ubj, indInfUp, indInfLo, i);
118  if (lbj < -COUENNE_INFINITY) updateInf (coe, lbi, ubi, indInfUp, indInfLo, j);
119 
120  if (ubi > COUENNE_INFINITY) updateInf (coe, lbj, ubj, indInfLo, indInfUp, i);
121  if (ubj > COUENNE_INFINITY) updateInf (coe, lbi, ubi, indInfLo, indInfUp, j);
122 
123  CouNumber term,
124  b1 = coe * lbi * lbj,
125  b2 = coe * lbi * ubj,
126  b3 = coe * ubi * lbj,
127  b4 = coe * ubi * ubj;
128 
129  if ((term = CoinMin (CoinMin (b1, b2), CoinMin (b3, b4))) > -COUENNE_INFINITY) qMin += term;
130  if ((term = CoinMax (CoinMax (b1, b2), CoinMax (b3, b4))) < COUENNE_INFINITY) qMax += term;
131  }
132  }
133  }
134 }
static char * j
Definition: OSdtoa.cpp:3622
virtual int Index() const
Return index of variable (only valid for exprVar and exprAux)
Bigint * b1
Definition: OSdtoa.cpp:1708
lincoeff lcoeff_
coefficients and indices of the linear term
fint li
double CouNumber
main number type in Couenne
void updateInf(CouNumber coe, CouNumber lb, CouNumber ub, int &indInf1, int &indInf2, int i)
#define COUENNE_INFINITY
void computeQuadFiniteBound(CouNumber &qMin, CouNumber &qMax, CouNumber *l, CouNumber *u, int &indInfLo, int &indInfUp)
return lower and upper bound of quadratic expression