00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef COUENNE_EXPRSIN_HPP
00012 #define COUENNE_EXPRSIN_HPP
00013
00014 #include <math.h>
00015 #include <assert.h>
00016
00017 #include "CouenneExprUnary.hpp"
00018 #include "CouenneExprConst.hpp"
00019
00020 namespace Couenne {
00021
00023 enum cou_trig {COU_SINE, COU_COSINE};
00024
00025
00027 inline CouNumber modulo (register CouNumber a, register CouNumber b)
00028 {return a - b * floor (a/b);}
00029
00030
00032 CouNumber trigSelBranch (const CouenneObject *obj,
00033 const OsiBranchingInformation *info,
00034 expression * &var,
00035 double * &brpts,
00036 double * &brDist,
00037
00038 int &way,
00039 enum cou_trig type);
00040
00041
00043 bool trigImpliedBound (enum cou_trig, int, int, CouNumber *, CouNumber *, t_chg_bounds *);
00044
00045
00047 class exprSin: public exprUnary {
00048
00049 public:
00050
00052 exprSin (expression *al):
00053 exprUnary (al) {}
00054
00056 expression *clone (Domain *d = NULL) const
00057 {return new exprSin (argument_ -> clone (d));}
00058
00060 inline unary_function F ()
00061 {return sin;}
00062
00064 std::string printOp () const
00065 {return "sin";}
00066
00068 inline CouNumber gradientNorm (const double *x) {
00069 return (argument_ -> Index () < 0) ?
00070 0. : fabs (cos (x [argument_ -> Index ()]));
00071 }
00072
00074 expression *differentiate (int index);
00075
00077 void getBounds (expression *&, expression *&);
00078
00080 void getBounds (CouNumber &lb, CouNumber &ub);
00081
00083 void generateCuts (expression *w,
00084 OsiCuts &cs, const CouenneCutGenerator *cg,
00085 t_chg_bounds * = NULL, int = -1,
00086 CouNumber = -COUENNE_INFINITY,
00087 CouNumber = COUENNE_INFINITY);
00088
00090 virtual enum expr_type code ()
00091 {return COU_EXPRSIN;}
00092
00094 bool impliedBound (int index, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign = expression::AUX_EQ) {
00095
00096 bool impl = trigImpliedBound (COU_SINE, index, argument_ -> Index (), l, u, chg);
00097
00098 if (impl && argument_ -> isInteger ()) {
00099
00100 int ind = argument_ -> Index ();
00101 assert (ind >= 0);
00102 l [ind] = ceil (l [ind] - COUENNE_EPS);
00103 u [ind] = floor (u [ind] + COUENNE_EPS);
00104 }
00105
00106 return impl;
00107 }
00108
00111 virtual CouNumber selectBranch (const CouenneObject *obj,
00112 const OsiBranchingInformation *info,
00113 expression * &var,
00114 double * &brpts,
00115 double * &brDist,
00116
00117 int &way)
00118
00119 {return trigSelBranch (obj, info, var, brpts, brDist, way, COU_SINE);}
00120
00122 virtual void closestFeasible (expression *varind, expression *vardep,
00123 CouNumber& left, CouNumber& right) const;
00124
00127 virtual bool isCuttable (CouenneProblem *problem, int index) const
00128 {return false;}
00129 };
00130
00131 }
00132
00133 #endif