/home/coin/SVN-release/OS-2.1.1/Couenne/src/standardize/flattenMul.cpp

Go to the documentation of this file.
00001 /* $Id: flattenMul.cpp 268 2009-10-22 03:41:03Z pbelotti $
00002  *
00003  * Name:    flattenMul.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: flatten multiplication expression tree into monomial
00006  *          c*\Prod_{k\in K} x_{i_k}^{p_k}
00007  *
00008  * (C) Carnegie-Mellon University, 2007. 
00009  * This file is licensed under the Common Public License (CPL)
00010  */
00011 
00012 #include "CouenneProblem.hpp"
00013 
00014 //#define DEBUG
00015 
00018 void CouenneProblem::flattenMul (expression *mul, CouNumber &coe, 
00019                                  std::map <int, CouNumber> &indices) {
00020 
00021 #ifdef DEBUG
00022   printf ("flatten %d ---> ", mul -> code ()); mul -> print ();
00023   printf ("\n");
00024 #endif
00025 
00026   if (mul -> code () != COU_EXPRMUL) {
00027 
00028     exprAux *aux = mul -> standardize (this);
00029 
00030     int ind = (aux) ? aux -> Index () : mul -> Index ();
00031 
00032     std::map <int, CouNumber>::iterator 
00033       where = indices.find (ind);
00034 
00035     if (where == indices.end ()) 
00036       indices.insert (std::pair <int, CouNumber> (ind, 1));
00037     else ++ (where -> second);
00038 
00039     return;
00040   }
00041 
00042   int nargs = mul -> nArgs ();
00043   expression **al = mul -> ArgList ();
00044 
00045   // for each factor (variable, function, or constant) of the product
00046   for (int i=0; i < nargs; i++) { 
00047 
00048     expression *arg = al [i];
00049 
00050 #ifdef DEBUG
00051     printf ("  flatten arg %d ---> ", arg -> code ()); arg -> print ();
00052     printf ("\n");
00053 #endif
00054 
00055     switch (arg -> code ()) {
00056 
00057     case COU_EXPRCONST: // change scalar multiplier
00058 
00059       coe *= arg -> Value ();
00060       break;
00061 
00062     case COU_EXPRMUL:  // apply recursively
00063 
00064       flattenMul (arg, coe, indices);
00065       break;
00066 
00067     case COU_EXPRVAR: { // insert index or increment 
00068 
00069       std::map <int, CouNumber>::iterator 
00070         where = indices.find (arg -> Index ());
00071 
00072       if (where == indices.end ()) 
00073         indices.insert (std::pair <int, CouNumber> (arg -> Index (), 1));
00074       else ++ (where -> second);
00075     } break;
00076 
00077     case COU_EXPROPP: // equivalent to multiplying by -1
00078 
00079       coe = -coe;
00080 
00081       if (arg -> Argument () -> Type () == N_ARY) {
00082         flattenMul (arg -> Argument (), coe, indices);
00083         break;
00084       } else arg = arg -> Argument ();
00085 
00086     case COU_EXPRPOW: 
00087 
00088       if (arg -> code () == COU_EXPRPOW) { // re-check as it could come from above
00089 
00090       expression *base     = arg -> ArgList () [0],
00091                  *exponent = arg -> ArgList () [1];
00092 
00093       if (exponent -> Type () == CONST) { // could be of the form k x^2
00094 
00095         double expnum = exponent -> Value ();
00096 
00097         expression *aux = base -> standardize (this);
00098 
00099         if (!aux)
00100           aux = base;
00101 
00102         std::map <int, CouNumber>::iterator 
00103           where = indices.find (aux -> Index ());
00104 
00105         if (where == indices.end ())
00106           indices.insert (std::pair <int, CouNumber> (aux -> Index (), expnum));
00107         else (where -> second += expnum);
00108 
00109         break;
00110       }  // otherwise, revert to default
00111     }
00112 
00113     case COU_EXPRSUM: // well, only if there is one element
00114 
00115       if ((arg -> code  () == COU_EXPRSUM) && // re-check as it could come from above
00116           (arg -> nArgs () == 1)) {
00117 
00118         flattenMul (arg, coe, indices);
00119         break;
00120 
00121       } // otherwise, continue into default case
00122 
00123     default: { // for all other expression, add associated new auxiliary
00124 
00125       exprAux *aux = arg -> standardize (this);
00126 
00127       int ind = (aux) ? aux -> Index () : arg -> Index ();
00128 
00129       std::map <int, CouNumber>::iterator 
00130         where = indices.find (ind);
00131 
00132       if (where == indices.end ()) 
00133         indices.insert (std::pair <int, CouNumber> (ind, 1));
00134       else ++ (where -> second);
00135 
00136     } break;
00137     }
00138   }
00139 }

Generated on Mon May 3 03:05:22 2010 by  doxygen 1.4.7