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 #include <stdio.h>
00017
00018 #include "CouenneExprOp.hpp"
00019 #include "CouenneExprMul.hpp"
00020 #include "CouenneExprClone.hpp"
00021 #include "CouenneExprConst.hpp"
00022
00023 namespace Couenne {
00024
00025 class funtriplet;
00026
00027
00029
00030 class exprPow: public exprOp {
00031
00032 private:
00033
00035 bool issignpower_;
00036
00037 public:
00038
00040 exprPow (expression **al, int n = 2, bool signpower = false):
00041 exprOp (al, n), issignpower_ (signpower) {}
00042
00044 exprPow (expression *arg0, expression *arg1, bool signpower = false):
00045 exprOp (arg0, arg1), issignpower_ (signpower) {}
00046
00048 expression *clone (Domain *d = NULL) const
00049 {return new exprPow (clonearglist (d), nargs_, issignpower_);}
00050
00052 virtual std::string printOp () const
00053 {return "^";}
00054
00056 virtual CouNumber operator () ();
00057
00059 virtual CouNumber gradientNorm (const double *x);
00060
00062 virtual expression *differentiate (int index);
00063
00065 virtual expression *simplify ();
00066
00068 virtual int Linearity ();
00069
00071 virtual bool isInteger ();
00072
00074 virtual void getBounds (expression *&, expression *&);
00075
00077 virtual void getBounds (CouNumber &lb, CouNumber &ub);
00078
00081 virtual exprAux *standardize (CouenneProblem *p, bool addAux = true);
00082
00084 virtual void generateCuts (expression *w,
00085 OsiCuts &cs, const CouenneCutGenerator *cg,
00086 t_chg_bounds * = NULL, int = -1,
00087 CouNumber = -COUENNE_INFINITY,
00088 CouNumber = COUENNE_INFINITY);
00089
00092 virtual expression *getFixVar ()
00093 {return arglist_ [0];}
00094
00096 virtual enum expr_type code ()
00097 {return (issignpower_ ? COU_EXPRSIGNPOW : COU_EXPRPOW);}
00098
00100 virtual bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::AUX_EQ);
00101
00104 virtual CouNumber selectBranch (const CouenneObject *obj,
00105 const OsiBranchingInformation *info,
00106 expression * &var,
00107 double * &brpts,
00108 double * &brDist,
00109
00110 int &way);
00111
00113 virtual void closestFeasible (expression *varind,
00114 expression *vardep,
00115 CouNumber &left,
00116 CouNumber &right) const;
00117
00120 virtual bool isCuttable (CouenneProblem *problem, int index) const;
00121
00123 virtual bool isSignpower () const { return issignpower_; }
00124 };
00125
00126
00128
00129 inline CouNumber safe_pow (CouNumber base,
00130 CouNumber exponent, bool signpower = false) {
00131
00132 double
00133 lbase = base,
00134 lexponent = exponent,
00135 retval = 0.;
00136
00137 if (lbase < 0.) {
00138
00139 register int rndexp = COUENNE_round (lexponent);
00140
00141 if (((fabs (lexponent - rndexp) < COUENNE_EPS) ||
00142 ((fabs (lexponent) > COUENNE_EPS) &&
00143 (fabs (1. / lexponent - (rndexp = COUENNE_round (1. / lexponent))) < COUENNE_EPS)))) {
00144 if ((rndexp % 2) || signpower)
00145 retval = (- pow (- lbase, lexponent));
00146 else retval = pow (- lbase, lexponent);
00147 }
00148 else retval = 0.;
00149 }
00150 else if (fabs (lbase) >= COUENNE_INFINITY) {
00151
00152 if (lbase <= -COUENNE_INFINITY) {
00153
00154 register int intk = COUENNE_round (lexponent);
00155
00156 if ((fabs (lexponent - intk) < COUENNE_EPS) && (intk % 2 || signpower))
00157 retval = (lexponent < 0.) ? 0. : -COUENNE_INFINITY;
00158 }
00159 else retval = (lexponent < 0.) ? 0. : COUENNE_INFINITY;
00160 }
00161 else
00162 retval = (pow (lbase, lexponent));
00163
00164 return (CouNumber) (retval);
00165 }
00166
00167
00169 inline CouNumber exprPow::operator () () {
00170
00171 return safe_pow ((**arglist_) (), (*(arglist_ [1])) (), issignpower_);
00172 }
00173
00174
00176 void addPowEnvelope (const CouenneCutGenerator *, OsiCuts &, int, int,
00177 CouNumber, CouNumber, CouNumber, CouNumber, CouNumber, int, bool = false);
00178
00180 CouNumber powNewton (CouNumber, CouNumber, unary_function, unary_function, unary_function);
00181
00183 CouNumber powNewton (CouNumber, CouNumber, funtriplet *);
00184
00185 }
00186
00187 #endif