00001
00012 #ifndef COUENNE_EXPRQUAD_H
00013 #define COUENNE_EXPRQUAD_H
00014
00015 #include <map>
00016 #include <vector>
00017
00018 #include "CoinPackedVector.hpp"
00019 #include "exprGroup.hpp"
00020
00021 class quadElem;
00022 class CouenneProblem;
00023 class Domain;
00024
00042 class exprQuad: public exprGroup {
00043
00044 public:
00045
00047 typedef std::vector <std::pair <exprVar *, CouNumber> > sparseQcol;
00048 typedef std::vector <std::pair <exprVar *, sparseQcol> > sparseQ;
00049
00050 protected:
00051
00059 mutable sparseQ matrix_;
00060
00068
00069 mutable std::vector <std::pair <CouNumber,
00070 std::vector <std::pair <exprVar *,
00071 CouNumber> > > > eigen_;
00072
00074 std::map <exprVar *, std::pair <CouNumber, CouNumber> > bounds_;
00075
00077 int nqterms_;
00078
00079 public:
00080
00082 exprQuad (CouNumber c0,
00083 std::vector <std::pair <exprVar *, CouNumber> > &lcoeff,
00084 std::vector <quadElem> &qcoeff,
00085 expression **al = NULL,
00086 int n = 0);
00087
00089 exprQuad (const exprQuad &src, Domain *d = NULL);
00090
00091
00092 sparseQ &getQ () const
00093 {return matrix_;}
00094
00095 int getnQTerms ()
00096 {return nqterms_;}
00097
00099 virtual expression *clone (Domain *d = NULL) const
00100 {return new exprQuad (*this, d);}
00101
00103 virtual void print (std::ostream & = std::cout, bool = false) const;
00104
00106 virtual CouNumber operator () ();
00107
00109 CouNumber gradientNorm (const double *x);
00110
00113 virtual expression *differentiate (int index);
00114
00116 virtual expression *simplify ();
00117
00119 virtual int Linearity () {
00120 int
00121 lin = exprSum::Linearity (),
00122 lin2 = (matrix_ .size () > 0) ? QUADRATIC :
00123 (lcoeff_ .size () > 0) ? LINEAR :
00124 (fabs (c0_) > COUENNE_EPS) ? CONSTANT : ZERO;
00125
00126 return ((lin > lin2) ? lin : lin2);
00127 }
00128
00130 virtual void getBounds (expression *&, expression *&);
00131
00133 virtual void getBounds (CouNumber &, CouNumber &);
00134
00138 virtual void generateCuts (expression *w, const OsiSolverInterface &si,
00139 OsiCuts &cs, const CouenneCutGenerator *cg,
00140 t_chg_bounds * = NULL, int = -1,
00141 CouNumber = -COUENNE_INFINITY,
00142 CouNumber = COUENNE_INFINITY);
00143
00146 virtual bool alphaConvexify (const CouenneProblem *, const OsiSolverInterface &);
00147
00223 void quadCuts (expression *w, OsiCuts & cs, const CouenneCutGenerator * cg);
00224
00226 virtual int compare (exprQuad &);
00227
00229 virtual enum expr_type code ()
00230 {return COU_EXPRQUAD;}
00231
00233 virtual int rank ();
00234
00236 virtual bool isInteger ();
00237
00240 virtual int DepList (std::set <int> &deplist,
00241 enum dig_type type = ORIG_ONLY);
00242
00245 virtual CouNumber selectBranch (const CouenneObject *obj,
00246 const OsiBranchingInformation *info,
00247 expression * &var,
00248 double * &brpts,
00249 double * &brDist,
00250
00251 int &way);
00252
00255 virtual void fillDepSet (std::set <DepNode *, compNode> *dep, DepGraph *g);
00256
00258 virtual void replace (exprVar *x, exprVar *w);
00259
00261 virtual void realign (const CouenneProblem *p);
00262
00264 virtual bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *);
00265
00268 CouNumber computeQBound (int sign);
00269
00271 virtual void closestFeasible (expression *varind,
00272 expression *vardep,
00273 CouNumber &left,
00274 CouNumber &right) const;
00275 protected:
00276
00278 void computeQuadFiniteBound (CouNumber &qMin, CouNumber &qMax,
00279 CouNumber *l, CouNumber *u,
00280 int &indInfLo, int &indInfUp);
00281
00284 virtual bool isCuttable (CouenneProblem *problem, int index) const
00285 {return false;}
00286 };
00287
00288
00290
00291 inline CouNumber exprQuad::operator () () {
00292
00293
00294 CouNumber ret = exprGroup::operator () ();
00295
00296 for (sparseQ::iterator row = matrix_.begin (); row != matrix_.end (); ++row) {
00297
00298 int xind = row -> first -> Index ();
00299 CouNumber x = (*(row -> first)) ();
00300
00301 for (sparseQcol::iterator col = row -> second.begin (); col != row -> second.end (); ++col) {
00302
00303 CouNumber term = x * (*(col -> first)) () * col -> second;
00304 ret += (col -> first -> Index () == xind) ? term : 2. * term;
00305 }
00306 }
00307
00308 return (CouNumber) ret;
00309 }
00310
00311 #endif