1 /* $Id$
2  *
3  * Name:    CouenneExprMultilin.hpp
4  * Author:  Pietro Belotti
5  * Purpose: Product of binary variables
6  *
7  * This file is licensed under the Eclipse Public License (EPL)
8  */
9 
10 #ifndef COUENNE_EXPRBINPROD_H
11 #define COUENNE_EXPRBINPROD_H
12 
13 #include <vector>
14 
15 #include "CouenneExprOp.hpp"
16 
17 namespace Couenne {
18 
19   /// class for \f$ \prod_{i=1}^n f_i(x) \f$ with \f$ f_i(x) \f$ all binary
20 
21   class exprBinProd: public exprMul {
22 
23   public:
24 
25     /// Constructor
26     exprBinProd (expression **, int);
27 
28     /// Constructor with two arguments
29     exprBinProd (expression *, expression *);
30 
31     /// return l-2 norm of gradient at given point
32     CouNumber gradientNorm (const double *x);
33 
34     /// differentiation
35     expression *differentiate (int index);
36 
37     /// simplification
38     expression *simplify ();
39 
40     /// get a measure of "how linear" the expression is:
41     virtual int Linearity ();
42 
43     /// Get lower and upper bound of an expression (if any)
44     virtual void getBounds (expression *&, expression *&);
45 
46     /// Get value of lower and upper bound of an expression (if any)
47     virtual void getBounds (CouNumber &lb, CouNumber &ub);
48 
49     /// reduce expression in standard form, creating additional aux
50     /// variables (and constraints)
51     virtual exprAux *standardize (CouenneProblem *p, bool addAux = true);
52 
53     /// generate equality between *this and *w
54     void generateCuts (expression *w, //const OsiSolverInterface &si,
55 		       OsiCuts &cs, const CouenneCutGenerator *cg,
56 		       t_chg_bounds * = NULL, int = -1,
57 		       CouNumber = -COUENNE_INFINITY,
58 		       CouNumber =  COUENNE_INFINITY);
59 
60     /// code for comparison
code()61     virtual enum expr_type code ()
62     {return COU_EXPRMUL;}
63 
64     /// implied bound processing
65     bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum Couenne::expression::auxSign = Couenne::expression::AUX_EQ);
66 
67     /// set up branching object by evaluating many branching points for
68     /// each expression's arguments
69     virtual CouNumber selectBranch (const CouenneObject *obj,
70 				    const OsiBranchingInformation *info,
71 				    expression * &var,
72 				    double * &brpts,
73 				    double * &brDist, // distance of current LP
74 				    // point to new convexifications
75 				    int &way);
76 
77     /// compute \f$y^{lv}\f$ and \f$y^{uv}\f$ for Violation Transfer algorithm
78     virtual void closestFeasible (expression *varind,
79 				  expression *vardep,
80 				  CouNumber &left,
81 				  CouNumber &right) const;
82   protected:
83 
84     /// balanced strategy for branching point selection in products
85     CouNumber balancedMul (const OsiBranchingInformation *info, int index, int wind);
86 
87     /// can this expression be further linearized or are we on its
88     /// concave ("bad") side
isCuttable(CouenneProblem * problem,int index) const89     virtual bool isCuttable (CouenneProblem *problem, int index) const
90     {return false;} // concave on both sides, as for products
91   };
92 }
93 
94 #endif
95