/home/coin/SVN-release/OS-2.0.1/Couenne/src/standardize/linStandardize.cpp

Go to the documentation of this file.
00001 /* $Id: linStandardize.cpp 154 2009-06-16 18:52:53Z pbelotti $ */
00002 /*
00003  * Name:    linStandardize.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: standardize sum expressions (expr{Sum,Sub,Quad,Group,Opp})
00006  *
00007  * (C) Carnegie-Mellon University, 2007. 
00008  * This file is licensed under the Common Public License (CPL)
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 //#define DEBUG
00022 
00024 exprAux *CouenneProblem::linStandardize (bool addAux, 
00025                                          CouNumber c0, 
00026                                          LinMap  &lmap,
00027                                          QuadMap &qmap) {
00028 
00029   // check if quadratic forms are dense enough ///////////////////////////////////////////
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   // terminate arrays with negative index
00048   qi [nq] = li [nl] = -1; 
00049 
00050   std::map <int, CouNumber>::iterator lit = lmap.Map().begin (); 
00051 
00052   // fill in arrays for linear part
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   // fill in arrays for quadratic part
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   // particular cases ///////////////////////////////////////////////////////////
00072 
00073   expression *ret;
00074 
00075   // a constant
00076   if ((nq==0) && (nl==0)) 
00077 
00078     ret = new exprConst (c0); // a constant auxiliary? 
00079 
00080   else if ((nq==0) && (fabs (c0) < COUENNE_EPS) && (nl==1)) { // a linear monomial, cx
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     // a bilinear/quadratic monomial, cx^2 or cxy
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     // general case ///////////////////////////////////////////////////////////////
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); // create exprGroup
00115     else     ret = new exprQuad  (c0, lcoeff, qcoeff); // create exprQuad
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   //  ret -> Image () -> print (); printf ("\n");
00128 #endif
00129 
00130   //if (ret -> Type () == AUX)
00131   //return ret;
00132 
00133   return (addAux ? addAuxiliary (ret) : new exprAux (ret, &domain_));
00134 }

Generated on Thu Oct 8 03:02:57 2009 by  doxygen 1.4.7