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

Go to the documentation of this file.
00001 /* $Id: flattenMul.cpp 563 2011-04-24 13:40:46Z 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-10.
00009  * This file is licensed under the Eclipse Public License (EPL)
00010  */
00011 
00012 #include <stdio.h>
00013 
00014 #include "CouenneProblem.hpp"
00015 #include "CouenneExprAux.hpp"
00016 
00017 using namespace Couenne;
00018 
00021 void CouenneProblem::flattenMul (expression *mul, CouNumber &coe, 
00022                                  std::map <int, CouNumber> &indices) {
00023 
00024   if (jnlst_ -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE)) {
00025     printf ("flatten %d ---> ", mul -> code ()); mul -> print ();
00026     printf ("\n");
00027   }
00028 
00029   if (mul -> code () != COU_EXPRMUL) {
00030 
00031     exprAux *aux = mul -> standardize (this);
00032 
00033     int ind = (aux) ? aux -> Index () : mul -> Index ();
00034 
00035     std::map <int, CouNumber>::iterator 
00036       where = indices.find (ind);
00037 
00038     if (where == indices.end ()) 
00039       indices.insert (std::pair <int, CouNumber> (ind, 1));
00040     else ++ (where -> second);
00041 
00042     return;
00043   }
00044 
00045   int nargs = mul -> nArgs ();
00046   expression **al = mul -> ArgList ();
00047 
00048   // for each factor (variable, function, or constant) of the product
00049   for (int i=0; i < nargs; i++) { 
00050 
00051     expression *arg = al [i];
00052 
00053     if (jnlst_ -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE)) {
00054       printf ("  flatten arg %d ---> ", arg -> code ()); 
00055       arg -> print ();
00056       printf ("\n");
00057     }
00058 
00059     switch (arg -> code ()) {
00060 
00061     case COU_EXPRCONST: // change scalar multiplier
00062 
00063       coe *= arg -> Value ();
00064       break;
00065 
00066     case COU_EXPRMUL:  // apply recursively
00067 
00068       flattenMul (arg, coe, indices);
00069       break;
00070 
00071     case COU_EXPRVAR: { // insert index or increment 
00072 
00073       std::map <int, CouNumber>::iterator 
00074         where = indices.find (arg -> Index ());
00075 
00076       if (where == indices.end ()) 
00077         indices.insert (std::pair <int, CouNumber> (arg -> Index (), 1));
00078       else ++ (where -> second);
00079     } break;
00080 
00081     case COU_EXPROPP: // equivalent to multiplying by -1
00082 
00083       coe = -coe;
00084 
00085       if (arg -> Argument () -> Type () == N_ARY) {
00086         flattenMul (arg -> Argument (), coe, indices);
00087         break;
00088       } else arg = arg -> Argument ();
00089 
00090     case COU_EXPRPOW: 
00091 
00092       if (arg -> code () == COU_EXPRPOW) { // re-check as it could come from above
00093 
00094         expression 
00095           *base     = arg -> ArgList () [0],
00096           *exponent = arg -> ArgList () [1];
00097 
00098         if (exponent -> Type () == CONST) { // could be of the form k x^2
00099 
00100           double expnum = exponent -> Value ();
00101 
00102           expression *aux = base -> standardize (this);
00103 
00104           if (!aux)
00105             aux = base;
00106 
00107           std::map <int, CouNumber>::iterator 
00108             where = indices.find (aux -> Index ());
00109 
00110           if (where == indices.end ())
00111             indices.insert (std::pair <int, CouNumber> (aux -> Index (), expnum));
00112           else (where -> second += expnum);
00113 
00114           break;
00115         }  // otherwise, revert to default
00116       }
00117 
00118     case COU_EXPRSUM: // well, only if there is one element
00119 
00120       if ((arg -> code  () == COU_EXPRSUM) && // re-check as it could come from above
00121           (arg -> nArgs () == 1)) {
00122 
00123         flattenMul (arg, coe, indices);
00124         break;
00125 
00126       } // otherwise, continue into default case
00127 
00128     default: { // for all other expression, add associated new auxiliary
00129 
00130       exprAux *aux = arg -> standardize (this);
00131 
00132       int ind = (aux) ? aux -> Index () : arg -> Index ();
00133 
00134       std::map <int, CouNumber>::iterator 
00135         where = indices.find (ind);
00136 
00137       if (where == indices.end ()) 
00138         indices.insert (std::pair <int, CouNumber> (ind, 1));
00139       else ++ (where -> second);
00140     }
00141     }
00142   }
00143 }

Generated on Thu Nov 10 03:05:46 2011 by  doxygen 1.4.7