elementBreak.cpp
Go to the documentation of this file.
1 /* $Id: elementBreak.cpp 490 2011-01-14 16:07:12Z pbelotti $ */
2 /*
3  * Name: elementBreak.cpp
4  * Author: Pietro Belotti
5  * Purpose: decompose element of sum if it is of the form cx or x
6  *
7  * (C) Carnegie-Mellon University, 2007.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include "CouenneExpression.hpp"
12 
13 using namespace Couenne;
14 
18 
19 void elementBreak (expression *arg, int &index, CouNumber &coeff) {
20 
21  CouNumber oppMulCoe = 1.;
22  bool isMul = false;
23  index = -1;
24 
25  if (arg -> Linearity () <= LINEAR) {
26 
27  // check if it's w, c*w, or w/c. If more complicated (sum or
28  // subtraction) nevermind
29 
30  switch (arg -> code ()) { // check element of sum
31 
32  case COU_EXPRCONST: // it is a constant, nevermind
33  break;
34 
35  case COU_EXPRVAR: // it is a simple variable, w
36  index = arg -> Index ();
37  coeff = 1.;
38  break;
39 
40  case COU_EXPROPP: { // it is the opposite of a simple variable or of
41  // another linear term
42 
43  index = arg -> Argument () -> Index ();
44  coeff = -1.;
45 
46  oppMulCoe = -1; // to be used below
47  arg = arg -> Argument (); // transfer analysis to argument of exprOpp
48 
49  int argcode = arg -> code ();
50 
51  if (argcode == COU_EXPRMUL) isMul = true;
52  else if (argcode != COU_EXPRDIV) break;
53  }
54  // no break. Bail out of switch only if this was a -w rather
55  // than a -c*w or a -w/c
56 
57  case COU_EXPRMUL:
58  if (isMul) {
59 
60  // it is c*w or w*c. Forget the case with more than two
61  // non-constant arguments.
62 
63  expression **factors = arg -> ArgList ();
64 
65  int pos = 0;
66 
67  index = (*factors) -> Index ();
68 
69  if (index < 0)
70  index = factors [pos = 1] -> Index ();
71 
72  if ((index >= 0) &&
73  (fabs (coeff = oppMulCoe * factors [1 - pos] -> Value ()) < COUENNE_EPS))
74  index = -1;
75 
76  break;
77  }
78  // no break outside, there could be some residue from case
79  // COU_EXPROPP
80 
81  case COU_EXPRDIV: { // if linear, it must be of the form w/c
82 
83  expression **factors = arg -> ArgList ();
84 
85  coeff = factors [1] -> Value ();
86  index = (*factors) -> Index ();
87 
88  if (fabs (coeff) < COUENNE_EPS)
89  index = -1;
90  else coeff = 1. / coeff;
91 
92  } break;
93 
94  default: break;
95  }
96  }
97 }
pos
position where the operator should be printed when printing the expression
void elementBreak(expression *arg, int &index, CouNumber &coeff)
given an element of a sum, check if it is a variable (possibly with a coefficient) and return its ind...
#define COUENNE_EPS
double CouNumber
main number type in Couenne
Expression base class.