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 
00017 namespace flopc {
00018 
00019   class Expression_constant : public TerminalExpression {
00020     friend class MP_expression;
00021 
00022   private:
00023     Expression_constant(const Constant& c) : C(c) {}
00024     double level() const { 
00025       return C->evaluate(); 
00026     }
00027     double getValue() const {
00028       return C->evaluate();
00029     }
00030     int getColumn() const {
00031       return -1;
00032     }
00033     int getStage() const {
00034       return C->getStage(); //NB to be changed
00035     }
00036     void generate(const MP_domain& domain,
00037                   vector<Constant> multiplicators,
00038                   GenerateFunctor& f,
00039                   double m) const {
00040       f.setMultiplicator(multiplicators,m);
00041       f.setTerminalExpression(this);
00042       domain.Forall(&f);
00043     }
00044     void insertVariables(set<MP_variable*>& v) const {}
00045 
00046     Constant C;
00047   };
00048 
00049   class Expression_plus : public Expression_operator {
00050     friend MP_expression operator+(const MP_expression& e1, const MP_expression& e2);
00051     friend MP_expression operator+(const MP_expression& e1, const Constant& e2);
00052     friend MP_expression operator+(const Constant& e1, const MP_expression& e2);        
00053   private:
00054     Expression_plus(const MP_expression& e1, const MP_expression& e2) : 
00055       Expression_operator(e1,e2) {}
00056     double level() const { 
00057       return left->level()+right->level(); 
00058     }
00059     void generate(const MP_domain& domain,
00060                   vector<Constant> multiplicators,
00061                   GenerateFunctor& f,
00062                   double m) const { 
00063       left->generate(domain, multiplicators,f,m);
00064       right->generate(domain, multiplicators,f,m);
00065     }
00066   };
00067 
00068   class Expression_minus : public Expression_operator {
00069     friend MP_expression operator-(const MP_expression& e1, const MP_expression& e2);
00070     friend MP_expression operator-(const MP_expression& e1, const Constant& e2); 
00071     friend MP_expression operator-(const Constant& e1, const MP_expression& e2);
00072   private:
00073     Expression_minus(const MP_expression& e1, const MP_expression& e2) : 
00074       Expression_operator(e1,e2) {}
00075     double level() const { 
00076       return left->level()-right->level(); 
00077     }
00078     void generate(const MP_domain& domain,
00079                   vector<Constant> multiplicators,
00080                   GenerateFunctor& f,
00081                   double m) const {
00082       left->generate(domain, multiplicators,f,m);
00083       right->generate(domain, multiplicators,f,-m);
00084     }
00085   };
00086 
00087   class Expression_mult : public MP_expression_base {
00088     friend MP_expression operator*(const Constant& e1, const MP_expression& e2); 
00089     friend MP_expression operator*(const MP_expression& e1, const Constant& e2);
00090 
00091   private:
00092     Expression_mult(const Constant& e1, const MP_expression& e2) : 
00093       left(e1), right(e2) {}
00094     double level() const { 
00095       return left->evaluate()*right->level(); 
00096     }
00097     void generate(const MP_domain& domain,
00098                   vector<Constant> multiplicators,
00099                   GenerateFunctor& f,
00100                   double m) const {
00101       multiplicators.push_back(left);
00102       right->generate(domain, multiplicators, f, m);
00103     }
00104     void insertVariables(set<MP_variable*>& v) const {
00105       right->insertVariables(v);
00106     }
00107     Constant left;
00108     MP_expression right;
00109   };
00110 
00111   class Expression_div : public MP_expression_base {
00112     friend MP_expression operator/(const MP_expression& e1, const Constant& e2);
00113   private:
00114     Expression_div(const MP_expression& e, const Constant& c) : 
00115       left(e), right(c) {}
00116     double level() const { 
00117       return left->level()/right->evaluate(); 
00118     }
00119     void generate(const MP_domain& domain,
00120                   vector<Constant> multiplicators,
00121                   GenerateFunctor& f,
00122                   double m) const {
00123       multiplicators.push_back(1/right);
00124       left->generate(domain, multiplicators, f, m);
00125     }
00126     void insertVariables(set<MP_variable*>& v) const {
00127       left->insertVariables(v);
00128     }
00129     MP_expression left;
00130     Constant right;
00131   };
00132     
00133   class Expression_sum : public MP_expression_base, public Functor {
00134     friend MP_expression sum(const MP_domain& d, const MP_expression& e);
00135   private:
00136     Expression_sum(const MP_domain& d, const MP_expression& e) : 
00137       D(d), exp(e) {}
00138     void operator()() const {
00139       the_sum += exp->level();
00140     }
00141     double level() const {
00142       the_sum = 0;
00143       D.Forall(this);
00144       return the_sum;
00145     } 
00146     void generate(const MP_domain& domain,
00147                   vector<Constant> multiplicators,
00148                   GenerateFunctor& f,
00149                   double m) const {
00150       // The order, D*domain (NOT domain*D), is important for efficiency! 
00151       exp->generate(D*domain, multiplicators, f, m); 
00152     }
00153     void insertVariables(set<MP_variable*>& v) const {
00154       exp->insertVariables(v);
00155     }
00156 
00157     mutable double the_sum;
00158     MP_domain D;
00159     MP_expression exp;
00160   };
00161 
00162 
00163   MP_expression operator+(const MP_expression& e1, const MP_expression& e2) {
00164     return new Expression_plus(e1, e2);
00165   }
00166   MP_expression operator+(const MP_expression& e1, const Constant& e2) {
00167     return new Expression_plus(e1, e2);
00168   }
00169   MP_expression operator+(const Constant& e1, const MP_expression& e2) {
00170     return new Expression_plus(e1, e2);
00171   }
00172 
00173   MP_expression operator-(const MP_expression& e1, 
00174                           const MP_expression& e2) {
00175     return new Expression_minus(e1, e2);
00176   }
00177   MP_expression operator-(const MP_expression& e1, 
00178                           const Constant& e2) {
00179     return new Expression_minus(e1, e2);
00180   }
00181   MP_expression operator-(const Constant& e1, 
00182                           const MP_expression& e2) {
00183     return new Expression_minus(e1, e2);
00184   }
00185 
00186   MP_expression operator*(const Constant& e1, const MP_expression& e2) {
00187     return new Expression_mult(e1, e2);
00188   }
00189   MP_expression operator*(const MP_expression& e1, const Constant& e2) {
00190     return new Expression_mult(e2, e1);
00191   }
00192   MP_expression operator/(const MP_expression& e1, const Constant& e2) {
00193     return new Expression_div(e1, e2);
00194   }
00195 
00196   MP_expression sum(const MP_domain& d, const MP_expression& e) {
00197     return new Expression_sum(d, e);  
00198   }
00199     
00200 } // End of namespace flopc
00201 
00202 using namespace flopc;
00203 
00204 
00205 MP_expression::MP_expression(const Constant &c) :
00206   Handle<MP_expression_base*>(new Expression_constant(c)) {} 
00207 
00208 MP_expression::MP_expression(const VariableRef &v) : 
00209   Handle<MP_expression_base*>(const_cast<VariableRef*>(&v)) {} 
00210 
00211 int GenerateFunctor::row_number() const {
00212   return R->row_number();
00213 }
00214 
00215 void GenerateFunctor::operator()() const {
00216   double multiplicator = m_;
00217   int stage = 0;
00218   for (unsigned int i=0; i<multiplicators.size(); i++) {
00219     multiplicator *= multiplicators[i]->evaluate();
00220     if (multiplicators[i]->getStage() > stage) {
00221       stage = multiplicators[i]->getStage();
00222     }
00223   }
00224   int rowNumber = row_number();
00225   if (rowNumber != outOfBound) {
00226     int colNumber = C->getColumn();
00227     if ( colNumber != outOfBound  ) {
00228       double val = multiplicator*C->getValue();
00229       int tstage = C->getStage();
00230       if (tstage > stage) {
00231         stage = tstage;
00232       }
00233       // For the SP core it might be usefull to generate zero coefs
00234       // if (val != 0) {
00235       Coefs.push_back(Coef(colNumber, rowNumber, val, stage));
00236       //}
00237     }
00238   }
00239 }

Generated on Fri May 16 00:25:12 2008 for FLOPC++ by  doxygen 1.4.7