00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "exprQuad.hpp"
00012 #include "CoinHelperFunctions.hpp"
00013
00014
00015 void updateInf (CouNumber coe, CouNumber lb, CouNumber ub, int &indInf1, int &indInf2, int i) {
00016
00017 if (coe > 0) {
00018 if (lb < 0) indInf1 = (indInf1 == -1) ? i : -2;
00019 if (ub > 0) indInf2 = (indInf2 == -1) ? i : -2;
00020 } else {
00021 if (lb < 0) indInf2 = (indInf2 == -1) ? i : -2;
00022 if (ub > 0) indInf1 = (indInf1 == -1) ? i : -2;
00023 }
00024 }
00025
00026
00027
00028
00029 void exprQuad::computeQuadFiniteBound (CouNumber &qMin,
00030 CouNumber &qMax,
00031 CouNumber *l,
00032 CouNumber *u,
00033 int &indInfLo,
00034 int &indInfUp) {
00035
00036
00037
00038 for (lincoeff::iterator el = lcoeff_.begin (); el != lcoeff_.end (); ++el) {
00039
00040 int ind = el -> first -> Index ();
00041
00042 CouNumber
00043 coe = el -> second,
00044 li = l [ind],
00045 ui = u [ind];
00046
00047 if (coe < 0) {
00048
00049 if (indInfLo > -2) {
00050 if (ui > COUENNE_INFINITY) indInfLo = (indInfLo == -1) ? ind : -2;
00051 else qMin += coe * ui;
00052 }
00053
00054 if (indInfUp > -2) {
00055 if (li < -COUENNE_INFINITY) indInfUp = (indInfUp == -1) ? ind : -2;
00056 else qMax += coe * li;
00057 }
00058 } else {
00059
00060 if (indInfLo > -2) {
00061 if (li < -COUENNE_INFINITY) indInfLo = (indInfLo == -1) ? ind : -2;
00062 else qMin += coe * li;
00063 }
00064
00065 if (indInfUp > -2) {
00066 if (ui > COUENNE_INFINITY) indInfUp = (indInfUp == -1) ? ind : -2;
00067 else qMax += coe * ui;
00068 }
00069 }
00070 }
00071
00072
00073
00074 for (sparseQ::iterator row = matrix_.begin (); row != matrix_.end (); ++row) {
00075
00076 int i = row -> first -> Index ();
00077
00078 for (sparseQcol::iterator col = row -> second.begin (); col != row -> second.end (); ++col) {
00079
00080 int j = col -> first -> Index ();
00081
00082 CouNumber
00083 coe = col -> second,
00084 lbi = l [i],
00085 ubi = u [i];
00086
00087 if (i==j) {
00088
00089 CouNumber
00090 tmin = (ubi <= 0) ? (ubi * ubi) : (lbi >= 0) ? (lbi * lbi) : 0,
00091 tmax = CoinMax (lbi*lbi, ubi*ubi);
00092
00093 if (coe < 0) {
00094 qMax += coe * tmin;
00095 if (indInfLo > -2) {
00096 if (tmax > COUENNE_INFINITY) indInfLo = (indInfLo == -1) ? i : -2;
00097 else qMin += coe * tmax;
00098 }
00099 } else {
00100 qMin += coe * tmin;
00101 if (indInfUp > -2) {
00102 if (tmax > COUENNE_INFINITY) indInfUp = (indInfUp == -1) ? i : -2;
00103 else qMax += coe * tmax;
00104 }
00105 }
00106 } else {
00107
00108 CouNumber
00109 lbj = l [j],
00110 ubj = u [j];
00111
00112 coe *= 2;
00113
00114
00115
00116 if (lbi < -COUENNE_INFINITY) updateInf (coe, lbj, ubj, indInfUp, indInfLo, i);
00117 if (lbj < -COUENNE_INFINITY) updateInf (coe, lbi, ubi, indInfUp, indInfLo, j);
00118
00119 if (ubi > COUENNE_INFINITY) updateInf (coe, lbj, ubj, indInfLo, indInfUp, i);
00120 if (ubj > COUENNE_INFINITY) updateInf (coe, lbi, ubi, indInfLo, indInfUp, j);
00121
00122 CouNumber term,
00123 b1 = coe * lbi * lbj,
00124 b2 = coe * lbi * ubj,
00125 b3 = coe * ubi * lbj,
00126 b4 = coe * ubi * ubj;
00127
00128 if ((term = CoinMin (CoinMin (b1, b2), CoinMin (b3, b4))) > -COUENNE_INFINITY) qMin += term;
00129 if ((term = CoinMax (CoinMax (b1, b2), CoinMax (b3, b4))) < COUENNE_INFINITY) qMax += term;
00130 }
00131 }
00132 }
00133 }