00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef COUENNE_EXPRBMUL_H
00012 #define COUENNE_EXPRBMUL_H
00013
00014 #include "exprOp.hpp"
00015 #include "CoinHelperFunctions.hpp"
00016
00017 #define MUL_ZERO 1e-20
00018 #define MUL_INF sqrt (COIN_DBL_MAX)
00019
00021 inline CouNumber safeProd (register CouNumber a, register CouNumber b) {
00022
00023 if (a > MUL_INF) return (b < -MUL_ZERO) ? -COIN_DBL_MAX : (b > MUL_ZERO) ? COIN_DBL_MAX : 0.;
00024 if (a < -MUL_INF) return (b < -MUL_ZERO) ? COIN_DBL_MAX : (b > MUL_ZERO) ? -COIN_DBL_MAX : 0.;
00025
00026 if (b > MUL_INF) return (a < -MUL_ZERO) ? -COIN_DBL_MAX : (a > MUL_ZERO) ? COIN_DBL_MAX : 0.;
00027 if (b < -MUL_INF) return (a < -MUL_ZERO) ? COIN_DBL_MAX : (a > MUL_ZERO) ? -COIN_DBL_MAX : 0.;
00028
00029 return a*b;
00030 }
00031
00032
00035
00036 class exprLBMul: public exprOp {
00037
00038 public:
00039
00041 exprLBMul (expression **al, int n):
00042 exprOp (al, n) {}
00043
00045 expression *clone (Domain *d = NULL) const
00046 {return new exprLBMul (clonearglist (d), nargs_);}
00047
00049 CouNumber operator () ();
00050
00052 enum pos printPos () const
00053 {return PRE;}
00054
00056 std::string printOp () const
00057 {return "LB_Mul";}
00058 };
00059
00060
00062
00063 inline CouNumber exprLBMul::operator () () {
00064
00065 register CouNumber n = (*(arglist_ [0])) ();
00066 register CouNumber N = (*(arglist_ [1])) ();
00067 register CouNumber d = (*(arglist_ [2])) ();
00068 register CouNumber D = (*(arglist_ [3])) ();
00069
00070 if (d>=0)
00071 if (n>=0) return safeProd (n,d);
00072 else return safeProd (n,D);
00073 else
00074 if (N>0) {
00075 CouNumber Nd = safeProd (N,d), nD;
00076 if (n<0 && D>0 &&
00077 (Nd > (nD = safeProd (n,D)))) return nD;
00078 else return Nd;
00079 }
00080 else
00081 if (D>0) return safeProd (n,D);
00082 else return safeProd (N,D);
00083 }
00084
00085
00088
00089 class exprUBMul: public exprOp {
00090
00091 public:
00092
00094 exprUBMul (expression **al, int n):
00095 exprOp (al, n) {}
00096
00098 expression *clone (Domain *d = NULL) const
00099 {return new exprUBMul (clonearglist (d), nargs_);}
00100
00102 CouNumber operator () ();
00103
00105 enum pos printPos () const
00106 {return PRE;}
00107
00109 std::string printOp () const
00110 {return "UB_Mul";}
00111 };
00112
00113
00115
00116 inline CouNumber exprUBMul::operator () () {
00117
00118
00119
00120 register CouNumber n = (*(arglist_ [0])) ();
00121 register CouNumber N = (*(arglist_ [1])) ();
00122 register CouNumber d = (*(arglist_ [2])) ();
00123 register CouNumber D = (*(arglist_ [3])) ();
00124
00125 if (d>0)
00126 if (N<0) return safeProd (N,d);
00127 else return safeProd (N,D);
00128 else
00129 if (n<0) {
00130 CouNumber nd = safeProd (n,d), ND;
00131 if (N>0 && D>0 &&
00132 ((ND = safeProd (N,D)) > nd)) return ND;
00133 else return nd;
00134 }
00135 else
00136 if (D>0) return safeProd (N,D);
00137 else return safeProd (n,D);
00138 }
00139
00140 #endif