00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CouenneProblem.hpp"
00012 #include "exprSum.hpp"
00013 #include "exprSub.hpp"
00014 #include "exprOpp.hpp"
00015 #include "exprMul.hpp"
00016 #include "exprPow.hpp"
00017 #include "exprGroup.hpp"
00018 #include "exprQuad.hpp"
00019 #include "lqelems.hpp"
00020
00021
00022
00024 exprAux *CouenneProblem::linStandardize (bool addAux,
00025 CouNumber c0,
00026 LinMap &lmap,
00027 QuadMap &qmap) {
00028
00029
00030
00031 analyzeSparsity (c0, lmap, qmap);
00032
00034
00035 int nq = qmap.Map().size (),
00036 *qi = new int [nq+1],
00037 *qj = new int [nq+1];
00038
00039 CouNumber *qc = new CouNumber [nq];
00040
00041 int
00042 nl = lmap.Map().size(),
00043 *li = new int [nl+1];
00044
00045 CouNumber *lc = new CouNumber [nl];
00046
00047
00048 qi [nq] = li [nl] = -1;
00049
00050 std::map <int, CouNumber>::iterator lit = lmap.Map().begin ();
00051
00052
00053 for (int i=0; i<nl; i++, lit++) {
00054
00055 li [i] = lit -> first;
00056 lc [i] = lit -> second;
00057 }
00058
00059 std::map <std::pair <int, int>, CouNumber>::iterator qit = qmap.Map().begin ();
00060
00061
00062 for (int i=0; i < nq; i++, qit++) {
00063 qi [i] = qit -> first. first;
00064 qj [i] = qit -> first. second;
00065 qc [i] = qit -> second;
00066 }
00067
00068 nl = lmap.Map().size ();
00069 nq = qmap.Map().size ();
00070
00071
00072
00073 expression *ret;
00074
00075
00076 if ((nq==0) && (nl==0))
00077
00078 ret = new exprConst (c0);
00079
00080 else if ((nq==0) && (fabs (c0) < COUENNE_EPS) && (nl==1)) {
00081
00082 if (fabs (*lc - 1.) < COUENNE_EPS) ret = new exprClone (Var (*li));
00083 else if (fabs (*lc + 1.) < COUENNE_EPS) ret = new exprOpp (new exprClone (Var (*li)));
00084 else ret = new exprMul (new exprConst (*lc),
00085 new exprClone (Var (*li)));
00086
00087 } else if ((nl==0) && (fabs (c0) < COUENNE_EPS) && (nq==1)) {
00088
00089
00090
00091 expression *quad;
00092
00093 if (*qi == *qj) quad = new exprPow (new exprClone (Var (*qi)), new exprConst (2.));
00094 else quad = new exprMul (new exprClone (Var (*qi)),
00095 new exprClone (Var (*qj)));
00096
00097 if (fabs (*qc - 1) < COUENNE_EPS)
00098 ret = quad;
00099 else {
00100 quad = addAuxiliary (quad);
00101 ret = new exprMul (new exprConst (*qc), new exprClone (quad));
00102 }
00103
00104 } else {
00105
00106
00107
00108 std::vector <std::pair <exprVar *, CouNumber> > lcoeff;
00109 indcoe2vector (li, lc, lcoeff);
00110
00111 std::vector <quadElem> qcoeff;
00112 indcoe2vector (qi, qj, qc, qcoeff);
00113
00114 if (!nq) ret = new exprGroup (c0, lcoeff);
00115 else ret = new exprQuad (c0, lcoeff, qcoeff);
00116 }
00117
00118 delete [] li;
00119 delete [] lc;
00120 delete [] qi;
00121 delete [] qj;
00122 delete [] qc;
00123
00124 #ifdef DEBUG
00125 printf ("\nlinstand ==> ");
00126 ret -> print (); printf ("\n");
00127
00128 #endif
00129
00130
00131
00132
00133 return (addAux ? addAuxiliary (ret) : new exprAux (ret, &domain_));
00134 }