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

Go to the documentation of this file.
00001 /* $Id: linStandardize.cpp 490 2011-01-14 16:07:12Z 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-10.
00008  * This file is licensed under the Eclipse Public License (EPL)
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   // check if quadratic forms are dense enough ///////////////////////////////////////////
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   // terminate arrays with negative index
00052   qi [nq] = li [nl] = -1; 
00053 
00054   std::map <int, CouNumber>::iterator lit = lmap.Map().begin (); 
00055 
00056   // fill in arrays for linear part
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   // fill in arrays for quadratic part
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   // particular cases ///////////////////////////////////////////////////////////
00076 
00077   expression *ret;
00078 
00079   // a constant
00080   if ((nq==0) && (nl==0)) 
00081 
00082     ret = new exprConst (c0); // a constant auxiliary? 
00083 
00084   else if ((nq==0) && (fabs (c0) < COUENNE_EPS) && (nl==1)) { // a linear monomial, cx
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     // a bilinear/quadratic monomial, cx^2 or cxy
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     // general case ///////////////////////////////////////////////////////////////
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); // create exprGroup
00119     else     ret = new exprQuad  (c0, lcoeff, qcoeff); // create exprQuad
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     //printf (": "); fflush (stdout); 
00132     //ret -> Image () -> print ();     
00133   }
00134 
00135   //if (ret -> Type () == AUX)
00136   //return ret;
00137 
00138   return (addAux ? addAuxiliary (ret) : new exprAux (ret, &domain_));
00139 }

Generated on Wed Nov 30 03:04:09 2011 by  doxygen 1.4.7