00001 /* $Id: simplifiers.cpp 490 2011-01-14 16:07:12Z pbelotti $ */ 00002 /* 00003 * Name: simplifiers.cpp 00004 * Author: Pietro Belotti 00005 * Purpose: simplifiers for main operators (+,*,-) 00006 * 00007 * (C) Carnegie-Mellon University, 2006. 00008 * This file is licensed under the Eclipse Public License (EPL) 00009 */ 00010 00011 #include "CouenneExprOp.hpp" 00012 #include "CouenneExprConst.hpp" 00013 #include "CouennePrecisions.hpp" 00014 00015 using namespace Couenne; 00016 00017 // 00018 // shrink argument list 00019 // 00020 // used by + and * (for now), accepts a constant resulting from 00021 // applying an operator to the constants in the list of (pointers to) 00022 // function arguments contained in el. The constant is inserted in the 00023 // list if the result is not equal to null_element or if there are 00024 // other non-constant terms in the arglist. 00025 // 00026 // Example: f(x) + 3 + g(x) + 2 + 4 00027 // 00028 // el = {pf, NULL, pg, NULL, NULL} 00029 // nargs = 5 00030 // c = 3 + 2 + 4 = 9 00031 // null_element = 0 (for sums) 00032 // 00033 // where pf and pg are pointers to expression containing f and g, 00034 // resp. 00035 // 00036 // Result: el and nargs are changed to 00037 // 00038 // el = {pf, p9, pg} 00039 // nargs = 3 00040 // 00041 // Another example: f(x) + 2 + g(x) + (-4) + 2 00042 // Result: 00043 // el = {pf, pg} 00044 // nargs = 2 00045 // 00046 // Another example: f(x) * 3 * g(x) * 2 00047 // 00048 // el = {pf, NULL, pg, NULL} 00049 // nargs = 4 00050 // c = 3 * 2 = 6 != null_element = 1 (for multiplications) 00051 // Result: 00052 // el = {pf, p6, pg} 00053 // nargs = 3 00054 // 00055 00056 int exprOp::shrink_arglist (CouNumber c, CouNumber null_element) { 00057 00058 register int i=0, j=0; 00059 00060 bool one_fun = false; 00061 00062 // find first NULL spot (left by some constant) 00063 while ((i < nargs_) && (arglist_ [i])) 00064 i++; 00065 00066 // no spots, leave 00067 if (i==nargs_) 00068 return 0; 00069 00070 // check if there is at least one non-constant expression 00071 for (register int k=nargs_; k--;) 00072 if (arglist_ [k]) { 00073 one_fun = true; 00074 break; 00075 } 00076 00077 // add constant term if c is not null w.r.t. the operation or if it 00078 // would be an empty operand list otherwise 00079 if ((fabs (c - null_element) > COUENNE_EPS) || !one_fun) 00080 arglist_ [i++] = new exprConst (c); 00081 00082 j = i; 00083 00084 // now shift back all operands to compress argument list 00085 while (i < nargs_) { 00086 00087 while ((i < nargs_) && !(arglist_ [i])) 00088 i++; 00089 00090 if (i < nargs_) 00091 one_fun = true; 00092 00093 while ((i < nargs_) && (arglist_ [i])) 00094 arglist_ [j++] = arglist_ [i++]; 00095 } 00096 00097 nargs_ = j; 00098 00099 // only say shrinking simplified arg list if there is just the 00100 // constant 00101 return (nargs_ == 1);// && ((fabs (c - null_element) > COUENNE_EPS) || !one_fun)); 00102 }