00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef COUENNE_EXPRPOW_HPP
00013 #define COUENNE_EXPRPOW_HPP
00014
00015 #include <math.h>
00016
00017 #include "CouenneExprOp.hpp"
00018 #include "CouenneExprMul.hpp"
00019 #include "CouenneExprClone.hpp"
00020 #include "CouenneExprConst.hpp"
00021
00022 namespace Couenne {
00023
00024 class funtriplet;
00025
00026
00028
00029 class exprPow: public exprOp {
00030
00031 public:
00032
00034 exprPow (expression **al, int n = 2):
00035 exprOp (al, n) {}
00036
00038 exprPow (expression *arg0, expression *arg1):
00039 exprOp (arg0, arg1) {}
00040
00042 expression *clone (Domain *d = NULL) const
00043 {return new exprPow (clonearglist (d), nargs_);}
00044
00046 virtual std::string printOp () const
00047 {return "^";}
00048
00050 virtual CouNumber operator () ();
00051
00053 virtual CouNumber gradientNorm (const double *x);
00054
00056 virtual expression *differentiate (int index);
00057
00059 virtual expression *simplify ();
00060
00062 virtual int Linearity ();
00063
00065 virtual bool isInteger ();
00066
00068 virtual void getBounds (expression *&, expression *&);
00069
00071 virtual void getBounds (CouNumber &lb, CouNumber &ub);
00072
00075 virtual exprAux *standardize (CouenneProblem *p, bool addAux = true);
00076
00078 virtual void generateCuts (expression *w,
00079 OsiCuts &cs, const CouenneCutGenerator *cg,
00080 t_chg_bounds * = NULL, int = -1,
00081 CouNumber = -COUENNE_INFINITY,
00082 CouNumber = COUENNE_INFINITY);
00083
00086 virtual expression *getFixVar ()
00087 {return arglist_ [0];}
00088
00090 virtual enum expr_type code ()
00091 {return COU_EXPRPOW;}
00092
00094 virtual bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::AUX_EQ);
00095
00098 virtual CouNumber selectBranch (const CouenneObject *obj,
00099 const OsiBranchingInformation *info,
00100 expression * &var,
00101 double * &brpts,
00102 double * &brDist,
00103
00104 int &way);
00105
00107 virtual void closestFeasible (expression *varind,
00108 expression *vardep,
00109 CouNumber &left,
00110 CouNumber &right) const;
00111
00114 virtual bool isCuttable (CouenneProblem *problem, int index) const;
00115 };
00116
00117
00119
00120 inline CouNumber safe_pow (CouNumber base,
00121 CouNumber exponent) {
00122
00123 double
00124 lbase = base,
00125 lexponent = exponent,
00126 retval = 0.;
00127
00128 if (lbase < 0.) {
00129
00130 register int rndexp;
00131
00132 if (((fabs (lexponent - (rndexp = COUENNE_round (lexponent))) < COUENNE_EPS) ||
00133 ((fabs (lexponent) > COUENNE_EPS) &&
00134 (fabs (1. / lexponent - (rndexp = COUENNE_round (1. / lexponent))) < COUENNE_EPS)))) {
00135 if (rndexp % 2)
00136 retval = (- pow (- lbase, lexponent));
00137 else retval = pow (- lbase, lexponent);
00138 }
00139 else retval = 0.;
00140 }
00141 else if (fabs (lbase) >= COUENNE_INFINITY) {
00142
00143 if (lbase <= -COUENNE_INFINITY) {
00144
00145 register int intk = COUENNE_round (lexponent);
00146
00147 if ((fabs (lexponent - intk) < COUENNE_EPS) && (intk % 2))
00148 retval = (lexponent < 0.) ? 0. : -COUENNE_INFINITY;
00149 }
00150 else retval = (lexponent < 0.) ? 0. : COUENNE_INFINITY;
00151 }
00152 else
00153 retval = (pow (lbase, lexponent));
00154
00155 return (CouNumber) (retval);
00156 }
00157
00158
00160 inline CouNumber exprPow::operator () () {
00161
00162 return (safe_pow ((**arglist_) (), (*(arglist_ [1])) ()));
00163 }
00164
00165
00167 void addPowEnvelope (const CouenneCutGenerator *, OsiCuts &, int, int,
00168 CouNumber, CouNumber, CouNumber, CouNumber, CouNumber, int);
00169
00170
00172 CouNumber powNewton (CouNumber, CouNumber, unary_function, unary_function, unary_function);
00173
00175 CouNumber powNewton (CouNumber, CouNumber, funtriplet *);
00176
00177 }
00178
00179 #endif