1 /* $Id$
2  *
3  * Name:    exprSum.hpp
4  * Author:  Pietro Belotti
5  * Purpose: definition of sum expressions
6  *
7  * (C) Carnegie-Mellon University, 2006-10.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #ifndef COUENNE_EXPRSUM_H
12 #define COUENNE_EXPRSUM_H
13 
14 #include <vector>
15 
16 #include "CouenneExprOp.hpp"
17 
18 namespace Couenne {
19 
20 /// class sum, \f$ \sum_{i=1}^n f_i(x) \f$
21 
22 class exprSum: public exprOp {
23 
24  public:
25 
26   /// Constructors, destructor
27   exprSum  (expression ** = NULL, int = 0);
28 
29   /// Constructor with two elements
30   exprSum (expression *, expression *);
31 
32   /// Empty destructor
~exprSum()33   virtual ~exprSum () {}
34 
35   /// Cloning method
clone(Domain * d=NULL) const36   virtual expression *clone (Domain *d = NULL) const
37     {return new exprSum (clonearglist (d), nargs_);}
38 
39   /// Print operator
printOp() const40   std::string printOp () const
41     {return "+";}
42 
43   /// Function for the evaluation of the expression
44   virtual CouNumber operator () ();
45 
46   /// Differentiation
47   virtual expression *differentiate (int index);
48 
49   /// Simplification
50   virtual expression *simplify ();
51 
52   /// Get a measure of "how linear" the expression is:
53   virtual int Linearity ();
54 
55   /// Get lower and upper bound of an expression (if any)
56   virtual void getBounds (expression *&, expression *&);
57 
58   /// Get lower and upper bound of an expression (if any)
59   virtual void getBounds (CouNumber &, CouNumber &);
60 
61   /// Reduce expression in standard form, creating additional aux
62   /// variables (and constraints)
63   virtual exprAux *standardize (CouenneProblem *p, bool addAux = true);
64 
65   /// Special version for linear constraints
66   virtual void generateCuts (expression *, //const OsiSolverInterface &,
67 			     OsiCuts &, const CouenneCutGenerator *,
68 			     t_chg_bounds * = NULL, int = -1,
69 			     CouNumber = -COUENNE_INFINITY,
70 			     CouNumber =  COUENNE_INFINITY);
71 
72   /// Code for comparison
code()73   virtual enum expr_type code ()
74     {return COU_EXPRSUM;}
75 
76   /** Implied bound.
77    *  An expression
78    *
79    *  \f$w = a0 + \sum_{i\in I1} a_i x_i + \sum_{i\in I2} a_i x_i\f$
80    *
81    *  is given such that all \f$a_i\f$ are positive for \f$i \in I1\f$ and
82    *  negative for \f$i \in I2\f$. If the bounds on \f$w \in [l,u]\f$, implied
83    *  bounds on all \f$x_i, i\in I1 \cup I2\f$ are as follows:
84    *
85    *  \f$\forall i\in I1\f$
86    *    \f$x_i \ge (l - a0 - \sum_{j\in I1 | j\neq i} a_j u_j - \sum_{j\in I2}        a_j l_j) / a_i\f$
87    *    \f$x_i \le (u - a0 - \sum_{j\in I1 | j\neq i} a_j l_j - \sum_{j\in I2}        a_j u_j) / a_i\f$
88    *
89    *  \f$\forall i\in I2\f$
90    *    \f$x_i \ge (u - a0 - \sum_{j\in I1} a_j u_j       - \sum_{j\in I2 | j\neq i} a_j l_j) / a_i\f$
91    *    \f$x_i \le (l - a0 - \sum_{j\in I1} a_j l_j       - \sum_{j\in I2 | j\neq i} a_j u_j) / a_i\f$,
92    *
93    *  where \f$l_i\f$ and \f$u_i\f$ are lower and upper bound,
94    *  respectively, of \f$x_i\f$. We also have to check if some of
95    *  these bounds are infinite.
96    */
97   virtual bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::AUX_EQ);
98 
99   /// Checks for quadratic terms in the expression and returns an
100   /// exprQuad if there are enough to create something that can be
101   /// convexified
102   exprAux *createQuadratic (CouenneProblem *);
103 
104 protected:
105 
106   /// inferring bounds on factors of a product
107   int impliedBoundSum (CouNumber wl,
108 		       CouNumber wu,
109 		       std::vector <CouNumber> &xl,
110 		       std::vector <CouNumber> &xu,
111 		       std::vector <std::pair <int, CouNumber> > &nl,
112 		       std::vector <std::pair <int, CouNumber> > &nu);
113 };
114 
115 
116 /// compute sum
117 
operator ()()118 inline CouNumber exprSum::operator () () {
119 
120   CouNumber ret = 0;
121 
122   expression **al = arglist_;
123 
124   for (int n = nargs_; n--;)
125     ret += (**al++) ();
126 
127   return ret;
128 }
129 
130 }
131 
132 #endif
133