00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00049 for (int i=0; i < nargs; i++) {
00050
00051 expression
00052 *arg = al [i],
00053 *simpl = arg -> simplify ();
00054
00055 if (simpl)
00056 al [i] = arg = simpl;
00057
00058 if (jnlst_ -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE)) {
00059 printf (" flatten arg %d ---> ", arg -> code ());
00060 arg -> print ();
00061 printf ("\n");
00062 }
00063
00064 switch (arg -> code ()) {
00065
00066 case COU_EXPRCONST:
00067
00068 coe *= arg -> Value ();
00069 break;
00070
00071 case COU_EXPRMUL:
00072
00073 flattenMul (arg, coe, indices);
00074 break;
00075
00076 case COU_EXPRVAR: {
00077
00078 std::map <int, CouNumber>::iterator
00079 where = indices.find (arg -> Index ());
00080
00081 if (where == indices.end ())
00082 indices.insert (std::pair <int, CouNumber> (arg -> Index (), 1));
00083 else ++ (where -> second);
00084 } break;
00085
00086 case COU_EXPROPP:
00087
00088 coe = -coe;
00089
00090 if (arg -> Argument () -> Type () == N_ARY) {
00091 flattenMul (arg -> Argument (), coe, indices);
00092 break;
00093 } else arg = arg -> Argument ();
00094
00095 case COU_EXPRPOW:
00096
00097 if (arg -> code () == COU_EXPRPOW) {
00098
00099 expression
00100 *base = arg -> ArgList () [0],
00101 *exponent = arg -> ArgList () [1];
00102
00103 if (exponent -> Type () == CONST) {
00104
00105 double expnum = exponent -> Value ();
00106
00107 expression *aux = base -> standardize (this);
00108
00109 if (!aux)
00110 aux = base;
00111
00112 std::map <int, CouNumber>::iterator
00113 where = indices.find (aux -> Index ());
00114
00115 if (where == indices.end ())
00116 indices.insert (std::pair <int, CouNumber> (aux -> Index (), expnum));
00117 else (where -> second += expnum);
00118
00119 break;
00120 }
00121 }
00122
00123 case COU_EXPRSUM:
00124
00125 if ((arg -> code () == COU_EXPRSUM) &&
00126 (arg -> nArgs () == 1)) {
00127
00128 flattenMul (arg, coe, indices);
00129 break;
00130
00131 }
00132
00133 default: {
00134
00135 exprAux *aux = arg -> standardize (this);
00136
00137 int ind = (aux) ? aux -> Index () : arg -> Index ();
00138
00139 std::map <int, CouNumber>::iterator
00140 where = indices.find (ind);
00141
00142 if (where == indices.end ())
00143 indices.insert (std::pair <int, CouNumber> (ind, 1));
00144 else ++ (where -> second);
00145 }
00146 }
00147 }
00148 }