1 /* $Id$
2 *
3 * Name: exprDiv.hpp
4 * Author: Pietro Belotti
5 * Purpose: definition of divisions
6 *
7 * (C) Carnegie-Mellon University, 2006-10.
8 * This file is licensed under the Eclipse Public License (EPL)
9 */
10
11 #ifndef COUENNE_EXPRDIV_HPP
12 #define COUENNE_EXPRDIV_HPP
13
14 #include "CouenneExprOp.hpp"
15 #include "CouennePrecisions.hpp"
16
17 namespace Couenne {
18
19 #define BR_NEXT_ZERO 1e-3
20 #define BR_MULT 1e-3
21
22 /// class for divisions, \f$ \frac{f(x)}{g(x)} \f$
23
24 class exprDiv: public exprOp {
25
26 public:
27
28 /// Constructor
exprDiv(expression ** al,int n=2)29 exprDiv (expression **al, int n = 2):
30 exprOp (al, n) {} //< non-leaf expression, with argument list
31
32 /// Constructor with two arguments given explicitly
exprDiv(expression * arg0,expression * arg1)33 exprDiv (expression *arg0, expression *arg1):
34 exprOp (arg0, arg1) {}
35
36 /// Cloning method
clone(Domain * d=NULL) const37 expression *clone (Domain *d = NULL) const
38 {return new exprDiv (clonearglist (d), nargs_);}
39
40 /// Print operator
printOp() const41 std::string printOp () const
42 {return "/";}
43
44 /// Function for the evaluation of the expression
45 inline CouNumber operator () ();
46
47 /// return l-2 norm of gradient at given point
48 CouNumber gradientNorm (const double *x);
49
50 /// Differentiation
51 expression *differentiate (int index);
52
53 /// Simplification
54 expression *simplify ();
55
56 /// Get a measure of "how linear" the expression is (see CouenneTypes.h)
Linearity()57 inline int Linearity () {
58
59 if (arglist_ [1] -> Type () == CONST)
60 return arglist_ [0] -> Linearity ();
61 else return NONLINEAR;
62 }
63
64 /// Get lower and upper bound of an expression (if any)
65 void getBounds (expression *&lb, expression *&ub);
66
67 /// Get value of lower and upper bound of an expression (if any)
68 void getBounds (CouNumber &lb, CouNumber &ub);
69
70 /// Reduce expression in standard form, creating additional aux
71 /// variables (and constraints)
72 exprAux *standardize (CouenneProblem *p, bool addAux = true);
73
74 /// Generate equality between *this and *w
75 void generateCuts (expression *w, //const OsiSolverInterface &si,
76 OsiCuts &cs, const CouenneCutGenerator *cg,
77 t_chg_bounds * = NULL, int = -1,
78 CouNumber = -COUENNE_INFINITY,
79 CouNumber = COUENNE_INFINITY);
80
81 /// Code for comparisons
code()82 virtual enum expr_type code () {return COU_EXPRDIV;}
83
84 /// is this expression integer?
85 bool isInteger ();
86
87 /// Implied bound processing
88 bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::AUX_EQ);
89
90 /// Set up branching object by evaluating many branching points for
91 /// each expression's arguments
92 virtual CouNumber selectBranch (const CouenneObject *obj,
93 const OsiBranchingInformation *info,
94 expression * &var,
95 double * &brpts,
96 double * &brDist, // distance of current LP
97 // point to new convexifications
98 int &way);
99
100 /// compute $y^{lv}$ and $y^{uv}$ for Violation Transfer algorithm
101 virtual void closestFeasible (expression *varind,
102 expression *vardep,
103 CouNumber &left,
104 CouNumber &right) const;
105
106 /// can this expression be further linearized or are we on its
107 /// concave ("bad") side
isCuttable(CouenneProblem * problem,int index) const108 virtual bool isCuttable (CouenneProblem *problem, int index) const
109 {return false;} // concave on both sides, as for products
110 };
111
112
113 /// Compute division
114
operator ()()115 inline CouNumber exprDiv::operator () ()
116 {return ((*(*arglist_)) () / (*(arglist_ [1])) ());}
117
118
119 #define SAFE_COEFFICIENT 1e9
120
121 /// check if bounding box is suitable for a multiplication/division
122 /// convexification constraint
123
is_boundbox_regular(register CouNumber b1,register CouNumber b2)124 inline bool is_boundbox_regular (register CouNumber b1, register CouNumber b2) {
125
126 // Why SAFE_COEFFICIENT and not COUENNE_INFINITY? Because
127 // OsiRowCut::set[LU]b do not work for values more than
128 // SAFE_COEFFICIENT and apparently makes the convexification
129 // infeasible.
130 return
131 (fabs (b1) < SAFE_COEFFICIENT) &&
132 (fabs (b2) < SAFE_COEFFICIENT) &&
133 (fabs (b1*b2) < SAFE_COEFFICIENT);
134 // && ((fabs (b1) > COUENNE_EPS) || (fabs (b2) > COUENNE_EPS));
135 }
136
137 }
138
139 #endif
140