00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef COUENNE_EXPRBDIV_H
00012 #define COUENNE_EXPRBDIV_H
00013
00014 #include "CouenneExprOp.hpp"
00015
00016 namespace Couenne {
00017
00019 static inline CouNumber safeDiv (register CouNumber a, register CouNumber b, int sign) {
00020
00021 if (fabs (a) < COUENNE_EPS) return 0;
00022
00023
00024
00025 if (fabs (b) < COUENNE_EPS) return ((sign < 0) ? -COUENNE_INFINITY : COUENNE_INFINITY);
00026
00027 if (a > COUENNE_INFINITY) return ((sign < 0) ? -COUENNE_INFINITY : COUENNE_INFINITY);
00028 if (a < -COUENNE_INFINITY) return ((sign < 0) ? -COUENNE_INFINITY : COUENNE_INFINITY);
00029
00030 return a/b;
00031 }
00032
00033
00036
00037 class exprLBDiv: public exprOp {
00038
00039 public:
00040
00042 exprLBDiv (expression **al, int n):
00043 exprOp (al, n) {}
00044
00046 expression *clone (Domain *d = NULL) const
00047 {return new exprLBDiv (clonearglist (d), nargs_);}
00048
00050 CouNumber operator () ();
00051
00053 enum pos printPos () const
00054 {return PRE;}
00055
00057 std::string printOp () const
00058 {return "LB_Div";}
00059 };
00060
00061
00063
00064 inline CouNumber exprLBDiv::operator () () {
00065
00066 register CouNumber n = (*(arglist_ [0])) ();
00067 register CouNumber N = (*(arglist_ [1])) ();
00068 register CouNumber d = (*(arglist_ [2])) ();
00069 register CouNumber D = (*(arglist_ [3])) ();
00070
00071 if (d > 0)
00072 if (n > 0) return safeDiv (n,D,-1);
00073 else return safeDiv (n,d,-1);
00074 else {
00075 if (D > 0) return - COUENNE_INFINITY;
00076 else if (N > 0) return safeDiv (N,D,-1);
00077 else return safeDiv (N,d,-1);
00078 }
00079 }
00080
00081
00084
00085 class exprUBDiv: public exprOp {
00086
00087 public:
00088
00090 exprUBDiv (expression **al, int n):
00091 exprOp (al, n) {}
00092
00094 expression *clone (Domain *d = NULL) const
00095 {return new exprUBDiv (clonearglist (d), nargs_);}
00096
00098 CouNumber operator () ();
00099
00101 enum pos printPos () const
00102 {return PRE;}
00103
00105 std::string printOp () const
00106 {return "UB_Div";}
00107 };
00108
00109
00111
00112 inline CouNumber exprUBDiv::operator () () {
00113
00114 register CouNumber n = (*(arglist_ [0])) ();
00115 register CouNumber N = (*(arglist_ [1])) ();
00116 register CouNumber d = (*(arglist_ [2])) ();
00117 register CouNumber D = (*(arglist_ [3])) ();
00118
00119 if (d > 0)
00120 if (N < 0) return safeDiv (N,D,1);
00121 else return safeDiv (N,d,1);
00122 else {
00123 if (D > 0) return + COUENNE_INFINITY;
00124 else if (n < 0) return safeDiv (n,D,1);
00125 else return safeDiv (n,d,1);
00126 }
00127 }
00128
00129 }
00130
00131 #endif