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