FLOPC++
MP_expression.cpp
Go to the documentation of this file.
00001 // ******************** FlopCpp **********************************************
00002 // File: MP_expression.cpp
00003 // $Id$
00004 // Author: Tim Helge Hultberg (thh@mat.ua.pt)
00005 // Copyright (C) 2003 Tim Helge Hultberg
00006 // All Rights Reserved.
00007 //****************************************************************************
00008 
00009 #include <sstream>
00010 #include "MP_expression.hpp"
00011 #include "MP_constant.hpp"
00012 #include "MP_boolean.hpp"
00013 #include "MP_constraint.hpp"
00014 #include "MP_set.hpp"
00015 #include "MP_variable.hpp"
00016 #include "MP_model.hpp"
00017 #include <OsiSolverInterface.hpp>
00018 
00019 namespace flopc {
00020 
00021   VariableRef::VariableRef(MP_variable* v, 
00022                            const MP_index_exp& i1,
00023                            const MP_index_exp& i2,
00024                            const MP_index_exp& i3,
00025                            const MP_index_exp& i4,
00026                            const MP_index_exp& i5) :
00027     V(v),I1(i1),I2(i2),I3(i3),I4(i4),I5(i5) { 
00028     offset = v->offset; 
00029   }
00030   
00031   double VariableRef::level() const {
00032     return  V->M->Solver->getColSolution()[V->offset +
00033                                            V->f(V->S1->evaluate(),
00034                                                 V->S2->evaluate(),
00035                                                 V->S3->evaluate(),
00036                                                 V->S4->evaluate(),
00037                                                 V->S5->evaluate())];
00038   }
00039 
00040   int VariableRef::getColumn() const { 
00041     int i1 = V->S1->check(I1->evaluate());
00042     int i2 = V->S2->check(I2->evaluate());
00043     int i3 = V->S3->check(I3->evaluate());
00044     int i4 = V->S4->check(I4->evaluate());
00045     int i5 = V->S5->check(I5->evaluate());
00046     
00047     if (i1==outOfBound || i2==outOfBound || i3==outOfBound ||
00048         i4==outOfBound || i5==outOfBound) {
00049       return outOfBound;
00050     } else {
00051       return V->offset +  V->f(i1,i2,i3,i4,i5);
00052     }
00053   }
00054 
00055   void VariableRef::generate(const MP_domain& domain,
00056                              vector<Constant > multiplicators,
00057                              MP::GenerateFunctor& f,
00058                              double m)  const {
00059     f.setMultiplicator(multiplicators,m);
00060     f.setTerminalExpression(this);
00061     domain.forall(&f);
00062   }
00063 
00064   class Expression_constant : public TerminalExpression, public MP {
00065     friend class MP_expression;
00066   private:
00067     Expression_constant(const Constant& c) : C(c) {}
00068     double level() const { 
00069       return C->evaluate(); 
00070     }
00071     double getValue() const {
00072       return C->evaluate();
00073     }
00074     int getColumn() const {
00075       return -1;
00076     }
00077     int getStage() const {
00078       return C->getStage(); //NB to be changed
00079     }
00080     void generate(const MP_domain& domain,
00081                   vector<Constant> multiplicators,
00082                   MP::GenerateFunctor& f,
00083                   double m) const {
00084       f.setMultiplicator(multiplicators,m);
00085       f.setTerminalExpression(this);
00086       domain.forall(&f);
00087     }
00088     void insertVariables(set<MP_variable*>& v) const {}
00089 
00090     Constant C;
00091   };
00092 
00093 
00094   class Expression_operator : public MP_expression_base, public MP  {
00095   protected:
00096     Expression_operator(const MP_expression& e1, const MP_expression& e2) : 
00097       left(e1),right(e2) {}
00098 
00099     void insertVariables(set<MP_variable*>& v) const {
00100       left->insertVariables(v);
00101       right->insertVariables(v);
00102     }
00103  
00104     MP_expression left,right;
00105   };
00106 
00107   class Expression_plus : public Expression_operator {
00108     friend MP_expression operator+(const MP_expression& e1, const MP_expression& e2);
00109     friend MP_expression operator+(const MP_expression& e1, const Constant& e2);
00110     friend MP_expression operator+(const Constant& e1, const MP_expression& e2);        
00111   private:
00112     Expression_plus(const MP_expression& e1, const MP_expression& e2) : 
00113       Expression_operator(e1,e2) {}
00114     double level() const { 
00115       return left->level()+right->level(); 
00116     }
00117     void generate(const MP_domain& domain,
00118                   vector<Constant> multiplicators,
00119                   MP::GenerateFunctor& f,
00120                   double m) const { 
00121       left->generate(domain, multiplicators, f, m);
00122       right->generate(domain, multiplicators, f, m);
00123     }
00124   };
00125 
00126   class Expression_minus : public Expression_operator {
00127     friend MP_expression operator-(const MP_expression& e1, const MP_expression& e2);
00128     friend MP_expression operator-(const MP_expression& e1, const Constant& e2); 
00129     friend MP_expression operator-(const Constant& e1, const MP_expression& e2);
00130   private:
00131     Expression_minus(const MP_expression& e1, const MP_expression& e2) : 
00132       Expression_operator(e1,e2) {}
00133     double level() const { 
00134       return left->level()-right->level(); 
00135     }
00136     void generate(const MP_domain& domain,
00137                   vector<Constant> multiplicators,
00138                   MP::GenerateFunctor& f,
00139                   double m) const {
00140       left->generate(domain, multiplicators, f, m);
00141       right->generate(domain, multiplicators, f, -m);
00142     }
00143   };
00144 
00145   class Expression_mult : public MP_expression_base,  MP  {
00146     friend MP_expression operator*(const Constant& e1, const MP_expression& e2); 
00147     friend MP_expression operator*(const MP_expression& e1, const Constant& e2);
00148 
00149   private:
00150     Expression_mult(const Constant& e1, const MP_expression& e2) : 
00151       left(e1), right(e2) {}
00152     double level() const { 
00153       return left->evaluate()*right->level(); 
00154     }
00155     void generate(const MP_domain& domain,
00156                   vector<Constant> multiplicators,
00157                   MP::GenerateFunctor& f,
00158                   double m) const {
00159       multiplicators.push_back(left);
00160       right->generate(domain, multiplicators, f, m);
00161     }
00162     void insertVariables(set<MP_variable*>& v) const {
00163       right->insertVariables(v);
00164     }
00165     Constant left;
00166     MP_expression right;
00167   };
00168 
00169   class Expression_div : public MP_expression_base, MP  {
00170     friend MP_expression operator/(const MP_expression& e1, const Constant& e2);
00171   private:
00172     Expression_div(const MP_expression& e, const Constant& c) : 
00173       left(e), right(c) {}
00174     double level() const { 
00175       return left->level()/right->evaluate(); 
00176     }
00177     void generate(const MP_domain& domain,
00178                   vector<Constant> multiplicators,
00179                   MP::GenerateFunctor& f,
00180                   double m) const {
00181       multiplicators.push_back(1/right);
00182       left->generate(domain, multiplicators, f, m);
00183     }
00184     void insertVariables(set<MP_variable*>& v) const {
00185       left->insertVariables(v);
00186     }
00187     MP_expression left;
00188     Constant right;
00189   };
00190     
00191   class Expression_sum : public MP_expression_base, public MP  {
00192     friend MP_expression sum(const MP_domain& d, const MP_expression& e);
00193   private:
00194     Expression_sum(const MP_domain& d, const MP_expression& e) : D(d), exp(e) {}
00195 
00196     double level() const {
00197       SumFunctor SF(exp);
00198       D.forall(SF);
00199       return SF.the_sum;
00200     } 
00201     void generate(const MP_domain& domain,
00202                   vector<Constant> multiplicators,
00203                   MP::GenerateFunctor& f,
00204                   double m) const {
00205       // The order, D*domain (NOT domain*D), is important for efficiency! 
00206       exp->generate(D*domain, multiplicators, f, m); 
00207     }
00208     void insertVariables(set<MP_variable*>& v) const {
00209       exp->insertVariables(v);
00210     }
00211     
00212     class SumFunctor : public Functor {
00213     public:
00214       SumFunctor(MP_expression exp) : E(exp), the_sum(0) {}
00215       void operator()() const {
00216         the_sum += E->level();
00217       }
00218       MP_expression E;      
00219       mutable double the_sum;
00220     };
00221 
00222     MP_domain D;
00223     MP_expression exp;
00224   };
00225 
00226 
00227   MP_expression operator+(const MP_expression& e1, const MP_expression& e2) {
00228     return new Expression_plus(e1, e2);
00229   }
00230   MP_expression operator+(const MP_expression& e1, const Constant& e2) {
00231     return new Expression_plus(e1, e2);
00232   }
00233   MP_expression operator+(const Constant& e1, const MP_expression& e2) {
00234     return new Expression_plus(e1, e2);
00235   }
00236 
00237   MP_expression operator-(const MP_expression& e1, const MP_expression& e2) {  
00238     return new Expression_minus(e1, e2);
00239   }
00240   MP_expression operator-(const MP_expression& e1, const Constant& e2) {
00241     return new Expression_minus(e1, e2);
00242   }
00243   MP_expression operator-(const Constant& e1, const MP_expression& e2) {
00244     return new Expression_minus(e1, e2);
00245   }
00246 
00247   MP_expression operator*(const Constant& e1, const MP_expression& e2) {
00248     return new Expression_mult(e1, e2);
00249   }
00250   MP_expression operator*(const MP_expression& e1, const Constant& e2) {
00251     return new Expression_mult(e2, e1);
00252   }
00253 
00254   MP_expression operator/(const MP_expression& e1, const Constant& e2) {
00255     return new Expression_div(e1, e2);
00256   }
00257 
00258   MP_expression sum(const MP_domain& d, const MP_expression& e) {
00259     return new Expression_sum(d, e);  
00260   }
00261     
00262 } // End of namespace flopc
00263 
00264 using namespace flopc;
00265 
00266 
00267 MP_expression::MP_expression(const Constant &c) :
00268   Handle<MP_expression_base*>(new Expression_constant(c)) {} 
00269 
00270 MP_expression::MP_expression(const VariableRef &v) : 
00271   Handle<MP_expression_base*>(const_cast<VariableRef*>(&v)) {} 
00272 
00273 
00274 bool MP::CoefLess::operator() (const MP::Coef& a, const MP::Coef& b) const {
00275   if (a.col < b.col) {
00276     return true;
00277   } else if (a.col == b.col && a.row < b.row) {
00278     return true;
00279   } else {
00280     return false;
00281   }
00282 }
00283 
00284 void MP::GenerateFunctor::operator()() const {
00285   double multiplicator = M;
00286   int stage = 0;
00287   for (unsigned int i=0; i<multiplicators.size(); i++) {
00288     multiplicator *= multiplicators[i]->evaluate();
00289     if (multiplicators[i]->getStage() > stage) {
00290       stage = multiplicators[i]->getStage();
00291     }
00292   }
00293   int rowNumber = -1;
00294   if (R != 0) {
00295     rowNumber = R->row_number();
00296   }
00297   if (rowNumber != outOfBound) {
00298     int colNumber = C->getColumn();
00299     if ( colNumber != outOfBound  ) {
00300       double val = multiplicator*C->getValue();
00301       int tstage = C->getStage();
00302       if (tstage > stage) {
00303         stage = tstage;
00304       }
00305       // if (val != 0) {
00306       Coefs.push_back(MP::Coef(colNumber, rowNumber, val, stage));
00307       //}
00308     }
00309   }
00310 }