exprMul.cpp
Go to the documentation of this file.
1 /* $Id: exprMul.cpp 1147 2015-05-04 14:01:51Z stefan $
2  *
3  * Name: exprMul.cpp
4  * Author: Pietro Belotti
5  * Purpose: definition of multiplications
6  *
7  * (C) Carnegie-Mellon University, 2006.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include <stdlib.h>
12 #include <assert.h>
13 
14 #include "CouenneExprMul.hpp"
15 #include "CouenneExprSum.hpp"
16 #include "CouenneExprPow.hpp"
17 #include "CouenneExprConst.hpp"
18 #include "CouenneExprClone.hpp"
19 #include "CouennePrecisions.hpp"
20 
21 #include "CouenneConfig.h"
22 #include "CoinHelperFunctions.hpp"
23 #include "CoinFinite.hpp"
24 
25 using namespace Couenne;
26 
29  exprOp (al, n) { //< non-leaf expression, with argument list
30 
31  // commutative operator, sort elements
32  qsort (arglist_, nargs_, sizeof (expression*), compareExpr);
33 }
34 
37  exprOp (arg0, arg1) {
38 
39  if (compareExpr (arglist_, arglist_ + 1) > 0) {
40 
41  register expression
42  *swap = arglist_ [0];
43  arglist_ [0] = arglist_ [1];
44  arglist_ [1] = swap;
45  }
46 }
47 
48 
50 
52 
54 
55  if (nargs_ == 1) {
56 
57  expression *ret = arglist_ [0];
58  arglist_ [0] = NULL;
59  return ret;
60  }
61 
62  CouNumber prod = 1.;
63 
64  bool found_one = false;
65 
68 
69  for (int i=0; i < nargs_ - 1; i++) {
70 
71  if ((arglist_ [i]) &&
72  (arglist_ [i+1]) &&
73  (compareExpr (arglist_ + i, arglist_ + i + 1) == 0)) {
74 
75  int
76  j = i+2,
77  exponent = 2;
78 
79  delete arglist_ [i+1];
80  arglist_ [i+1] = NULL;
81 
82  found_one = true;
83 
84  for (; j < nargs_; ++j) {
85 
86  if ((arglist_ [j]) &&
87  (compareExpr (arglist_ + i, arglist_ + j) == 0))
88  ++exponent;
89  else break;
90 
91  delete arglist_ [j];
92  arglist_ [j] = NULL;
93  }
94 
95  arglist_ [i] = new exprPow (arglist_ [i], new exprConst ((CouNumber) exponent));
96 
97  i=j;
98  }
99 
100  // TODO
101  }
102 
103  for (register int i=0; i<nargs_; i++) {
104 
105  // check for null operands in multiplications
106 
107  if (arglist_ [i] &&
108  (arglist_ [i] -> Type () == CONST)) {
109 
110  found_one = true;
111 
112  CouNumber c = arglist_ [i] -> Value ();
113  prod *= c;
114 
115  if (fabs (c) == 0.) {
116 
117  // for (int j=0; j<nargs_; j++)
118  // if (arglist_ [j]) {
119  // delete arglist_ [j];
120  // arglist_ [j] = NULL;
121  // }
122 
123  return new exprConst (0.);
124  }
125 
126  // check for nonzero constants in multiplications
127 
128  delete arglist_ [i];
129  arglist_ [i] = NULL;
130  }
131  }
132 
133  /*
134  if (found_one && shrink_arglist (prod, 1))
135  return new exprConst (arglist_ [0] -> Value ());
136  */
137  if (found_one && shrink_arglist (prod, 1.)) {
138  expression *ret = arglist_ [0];
139  arglist_ [0] = NULL;
140  return ret;
141  } else return NULL;
142 }
143 
144 
145 // differentiate product of expressions
146 
148 
149  expression **als = new expression * [nargs_];
150  int nonconst = 0;
151 
152  for (int i = 0; i < nargs_; i++)
153 
154  if (arglist_ [i] -> dependsOn (index)) {
155 
156  expression **alm = new expression * [nargs_];
157 
158  alm [i] = arglist_ [i] -> differentiate (index);
159 
160  for (int j = 0; j < nargs_; j++)
161  if (i!=j)
162  alm [j] = arglist_ [j] -> clone (); //new exprClone (arglist_ [j]);
163 
164  als [nonconst++] = new exprMul (alm, nargs_);
165  }
166 
167  if (nonconst)
168  return new exprSum (als, nonconst);
169  else {
170  delete [] als;
171  return new exprConst (0.);
172  }
173 }
174 
175 
176 // get a measure of "how linear" the expression is:
177 //
178 // ZERO = 0: constant 0
179 // CONSTANT = 1: a constant
180 // LINEAR = 2: linear
181 // QUADRATIC = 3: quadratic
182 // NONLINER = 4: nonlinear non-quadratic
183 
185 
186  int lin0 = arglist_ [0] -> Linearity ();
187 
188  if (lin0 >= NONLINEAR) return NONLINEAR;
189  if (lin0 == ZERO) return ZERO;
190 
191  for (register int i=1; i<nargs_; i++) {
192 
193  int lin = arglist_ [i] -> Linearity ();
194 
195  switch (lin) {
196  case NONLINEAR: return NONLINEAR;
197  case ZERO: return ZERO;
198  case LINEAR: lin0++; break;
199  case QUADRATIC: lin0 += 2; break;
200  default: break;
201  }
202 
203  if (lin0 >= NONLINEAR) return NONLINEAR;
204  }
205  return lin0;
206 }
207 
208 
211  expression *vardep,
212  CouNumber &left,
213  CouNumber &right) const {
214 
215  expression *varoth = arglist_ [0]; // suppose $w = cy$;
216 
217  if (varoth -> Index () == varind -> Index ())
218  varoth = arglist_ [1]; // actually no, it's $w = x*c$
219 
220  assert (varoth -> Index () >= 0);
221 
222  CouNumber
223  x = (*varind) (),
224  y = (*vardep) (),
225  c = (*varoth) ();
226 
227  if (c < 0.)
228  if (y < c*x) {assert (y/c >= right); right = y/c;}
229  else {assert (y/c <= left); left = y/c;}
230  else if (c > 0.)
231  if (y < c*x) {assert (y/c <= left); left = y/c;}
232  else {assert (y/c >= right); right = y/c;}
233  else left = - (right = COIN_DBL_MAX);
234 }
235 
236 
239 
240  int
241  ind0 = arglist_ [0] -> Index (),
242  ind1 = arglist_ [1] -> Index ();
243 
244  CouNumber
245  x0 = (ind0 < 0) ? arglist_ [0] -> Value () : x [ind0],
246  x1 = (ind1 < 0) ? arglist_ [1] -> Value () : x [ind1];
247 
248  if (ind0 < 0)
249  if (ind1 < 0) return 0.; // c*d
250  else return fabs (x0); // c*y
251  else
252  if (ind1 < 0) return fabs (x1); // x*d
253  else return sqrt (x0*x0 + x1*x1); // x*y
254 }
255 
virtual int dependsOn(int *ind, int n, enum dig_type type=STOP_AT_AUX)
dependence on variable set: return cardinality of subset of the set of indices in first argument whic...
Definition: expression.cpp:172
expression * differentiate(int index)
differentiation
Definition: exprMul.cpp:147
virtual void closestFeasible(expression *varind, expression *vardep, CouNumber &left, CouNumber &right) const
compute and for Violation Transfer algorithm
Definition: exprMul.cpp:210
int compareExpr(const void *e0, const void *e1)
independent comparison
int shrink_arglist(CouNumber, CouNumber)
compress argument list
Definition: exprOp.cpp:300
Power of an expression (binary operator), with constant.
virtual CouNumber gradientNorm(const double *x)
return l-2 norm of gradient at given point
Definition: exprMul.cpp:238
virtual expression * clone(Domain *d=NULL) const
Cloning method.
virtual int Linearity()
get a measure of &quot;how linear&quot; the expression is:
Definition: exprMul.cpp:184
constant-type operator
static char * j
Definition: OSdtoa.cpp:3622
ULong * x0
Definition: OSdtoa.cpp:1776
exprMul(expression **, int)
Constructor.
Definition: exprMul.cpp:28
virtual enum nodeType Type() const
Node type.
virtual int Index() const
Return index of variable (only valid for exprVar and exprAux)
ULong x1
Definition: OSdtoa.cpp:1776
expression * simplify()
simplification
Definition: exprMul.cpp:51
virtual expression * simplify()
simplification
Definition: exprOp.cpp:243
expression ** arglist_
argument list is an array of pointers to other expressions
double CouNumber
main number type in Couenne
int nargs_
number of arguments (cardinality of arglist)
general n-ary operator-type expression: requires argument list.
Expression base class.
void fint * n
virtual CouNumber Value() const
value (empty)
real c
void fint fint fint real fint real * x