MP_set.hpp

Go to the documentation of this file.
00001 // ******************** FlopCpp **********************************************
00002 // File: MP_set.hpp
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 #ifndef _MP_set_hpp_
00010 #define _MP_set_hpp_
00011 
00012 #include <iostream>
00013 #include <sstream>
00014 #include <string>
00015 #include <vector>
00016 #include <map>
00017 
00018 #include "MP_domain.hpp"
00019 #include "MP_index.hpp"
00020 #include "MP_utilities.hpp"
00021 
00022 namespace flopc {
00023 
00028 class MP_set_base : public MP_index , public Named {
00029 public:
00030     MP_set_base() : Cyclic(false) {}
00031 
00032     virtual int size() const = 0;
00033     virtual operator MP_domain() const = 0;
00034     virtual MP_domain operator()(const MP_index_exp& i) const = 0;
00035     void display()const;
00036 
00037     int check(int i) const {
00038         if ((i>=0) && (i<size())) {
00039             return i;
00040         } else {
00041             if (Cyclic == true) {
00042                 return mod(i,size());
00043             } else {
00044                 return outOfBound;
00045             }
00046         }
00047     }
00048     int checkStage(int i) const {
00049         if ((i>=0) && (i<size())) {
00050             return i*isStage();
00051         } else {
00052             if (Cyclic == true) {
00053                 return mod(i,size())*isStage();
00054             } else {
00055                 return outOfBound;
00056             }
00057         }
00058     }
00060     virtual int isStage() const {
00061         return 0;
00062     }
00063 
00064     bool Cyclic;
00065 };
00066 
00067     
00078 class MP_set : public MP_set_base {
00079 public:
00081     MP_set(int i = 0): cardinality(i) {}
00086     MP_domain operator()(const MP_index_exp& i) const {
00087         return i->getDomain(const_cast<MP_set*>(this));
00088     }
00090     operator MP_domain() const {
00091         return new MP_domain_set(this,const_cast<MP_set*>(this));
00092     }
00096     MP_domain such_that(const MP_boolean& b) {
00097         return (MP_domain(new MP_domain_set(this,this))).such_that(b);
00098     }
00102     void cyclic() {
00103         Cyclic = true;
00104     }
00106     virtual int size() const {
00107         return cardinality;
00108     }
00109     int last() {
00110         return cardinality-1;
00111     }
00113     static MP_set &getEmpty();
00114 private:
00115     static MP_set Empty;
00116     int cardinality;
00117 };
00118     
00119 class MP_stage : public MP_set {
00120 public:
00121     MP_stage(int i = 0): MP_set(i) {}
00122     virtual int isStage() const {
00123         return 1;
00124     }
00125 };
00126 
00127 template <int nbr> class MP_subset;
00128 
00134 template<int nbr> class InsertFunctor : public Functor {
00135 public:
00136     InsertFunctor( MP_subset<nbr>* s, std::vector<MP_index_exp> i) 
00137         : S(s), I(i) {}
00138     void operator()() const { 
00139         std::vector<int> elm(nbr);
00140         for (int i=0; i<nbr; i++) {
00141             elm[i] = I[i]->evaluate();
00142         }
00143         S->insert(elm);
00144     }
00145 private:
00146     MP_subset<nbr>* S;
00147     std::vector<MP_index_exp> I;
00148 };
00149 
00150 template <int nbr> class SubsetRef;
00151 
00160 template <int nbr>
00161 class MP_subset : public MP_set {
00162     friend class MP_domain_subset<nbr>;
00163     friend class SubsetRef<nbr>;
00164 public:
00165     MP_subset(const MP_set& s1, 
00166               const MP_set& s2=MP_set::getEmpty(), 
00167               const MP_set& s3=MP_set::getEmpty(), 
00168               const MP_set& s4=MP_set::getEmpty(), 
00169               const MP_set& s5=MP_set::getEmpty()) {
00170         S = makeVector<nbr,const MP_set*>(&s1,&s2,&s3,&s4,&s5);
00171     }
00172         void display(const std::string& s = "") const 
00173         {
00174 //              Messenger &msgr = *MP_model::getCurrentModel()->getMessenger();
00175 //              msgr.logMessage(5,s.c_str());
00176 //              std::map<std::vector<int>, int>::const_iterator i;
00177 //              for (i = elements.begin(); i != elements.end(); i++) 
00178 //              {
00179 //                      std::stringstream ss;
00180 //                      for (int j=0; j<nbr; j++) 
00181 //                      {
00182 //                              ss<<(*i).first[j]<<"  ";
00183 //                      }
00184 //                      ss<<(*i).second<<std::ends;
00185 //                      msgr.logMessage(5,ss.str().c_str());
00186 //              }
00187         }
00188 
00189     MP_subset(std::vector<const MP_set*> s) : S(s) {}
00190 
00191     ~MP_subset() {}
00192 
00193     int operator()(int i1, int i2=0, int i3=0, int i4=0, int i5=0) {
00194         std::map<std::vector<int>, int>::const_iterator pos;
00195         pos = elements.find(makeVector<nbr>(i1, i2, i3, i4, i5));
00196         if (pos==elements.end()) {
00197             return outOfBound;
00198         } else {
00199             return pos->second;
00200         }
00201     }
00202 
00203     SubsetRef<nbr>& operator()(const MP_index_exp& i1, 
00204                                const MP_index_exp& i2=MP_index::getEmpty(),  
00205                                const MP_index_exp& i3=MP_index::getEmpty(),
00206                                const MP_index_exp& i4=MP_index::getEmpty(),
00207                                const MP_index_exp& i5=MP_index::getEmpty()) {
00208         return *new SubsetRef<nbr>(this,i1,i2,i3,i4,i5);
00209     }
00210 
00211     MP_domain& operator()(const SUBSETREF& s) {
00212         return MP_domain(s);
00213     }
00214 
00215     int evaluate(const std::vector<MP_index*>& I) const {
00216         std::vector<int> vi;
00217         for (int k=0; k<nbr; k++) {
00218             int temp = I[k]->evaluate();
00219             vi.push_back(temp);
00220         }
00221         std::map<std::vector<int>, int>::const_iterator pos;
00222         pos = elements.find(vi);
00223         if (pos==elements.end()) {
00224             return outOfBound;
00225         } else {
00226             return pos->second;
00227         }
00228     }
00229     
00230     void insert(const std::vector<int> &args) {
00231         bool isOk = true;
00232         for (int i=0; i<nbr; i++) {
00233             if ( S[i]->check(args[i]) == outOfBound ) {
00234                 isOk = false;
00235             }
00236         }
00237         if (isOk == true) {
00238             std::map<std::vector<int>, int>::const_iterator pos;
00239             pos = elements.find(args);
00240             if (pos==elements.end()) {  // insert if not existent
00241                 const int v = static_cast<int>(elements.size());
00242                 elements[args] = v;
00243             }
00244         }
00245     }
00246     void insert(int i1, int i2=0, int i3=0, int i4=0, int i5=0) {
00247         insert(makeVector<nbr>(i1, i2, i3, i4, i5));
00248     }
00249     const InsertFunctor<nbr>& insert(MP_index_exp i1, 
00250                                      MP_index_exp i2=MP_index_exp::getEmpty(), 
00251                                      MP_index_exp i3=MP_index_exp::getEmpty(), 
00252                                      MP_index_exp i4=MP_index_exp::getEmpty(), 
00253                                      MP_index_exp i5=MP_index_exp::getEmpty()) {
00254         return *new InsertFunctor<nbr>(this,makeVector<nbr>(i1, i2, i3, i4, i5));
00255     }
00256     virtual int size() const {
00257         return static_cast<int>(elements.size());
00258     }
00259 
00260 private:
00261     std::vector<const MP_set*> S; 
00262         std::map<std::vector<int>, int> elements;
00263 };
00264 
00273     class SUBSETREF : public MP_index_base {
00274     public:
00275         virtual MP_index* getIndex() const {
00276             return 0;
00277         }
00278         virtual MP_domain getDomain(MP_set* s) const {
00279             return MP_domain::getEmpty();
00280         }
00281         int evaluate() const {
00282             return 0;
00283         }
00284     };
00285 
00293     template <int nbr>
00294     class SubsetRef : public SUBSETREF {
00295     public:
00296         SubsetRef(MP_subset<nbr>* s, 
00297                   const MP_index_exp& i1,
00298                   const MP_index_exp& i2,
00299                   const MP_index_exp& i3,
00300                   const MP_index_exp& i4,
00301                   const MP_index_exp& i5) : 
00302             S(s),I1(i1),I2(i2),I3(i3),I4(i4),I5(i5) {} 
00303         void display()const
00304         {
00305 //              Messenger &msgr=*MP_model::getCurrentModel()->getMessenger();
00306 //              msgr.logMessage(5,toString().c_str());
00307         }
00308     
00309         operator MP_domain() const {
00310 //          MP_domain_base* base;
00311 //          base = new MP_domain_subset<nbr>(S,
00312 //              makeVector<nbr>(I1->getIndex(), I2->getIndex(), 
00313 //                              I3->getIndex(), I4->getIndex(), 
00314 //                              I5->getIndex()) );
00315 //          base->such_that(B);
00316 //          return base; 
00317             return new MP_domain_subset<nbr>(S,
00318                           makeVector<nbr>(I1->getIndex(), I2->getIndex(), 
00319                                           I3->getIndex(), I4->getIndex(), 
00320                                           I5->getIndex()) );
00321         }
00322     
00323         virtual MP_domain getDomain(MP_set* s) const {
00324             return new MP_domain_subset<nbr>(S,
00325                 makeVector<nbr>(I1->getIndex(), I2->getIndex(), 
00326                                 I3->getIndex(), I4->getIndex(), 
00327                                 I5->getIndex()) );
00328         }
00329 
00330         SubsetRef& such_that(const MP_boolean& b) {
00331             B = b;
00332             return *this;
00333         }
00334 
00335         int evaluate() const {
00336             std::vector<MP_index_exp> I = makeVector<nbr>(I1,I2,I3,I4,I5);
00337             std::vector<int> vi;
00338             for (int k=0; k<nbr; k++) {
00339                 int temp = I[k]->evaluate();
00340                 vi.push_back(temp);
00341             }
00342             std::map<std::vector<int>, int>::const_iterator pos;
00343             pos = S->elements.find(vi);
00344             if (pos==S->elements.end()) {
00345                 return outOfBound;
00346             } else {
00347                 return pos->second;
00348             }
00349         }
00350         MP_index* getIndex() const {
00351             return S;
00352         }
00353         MP_boolean B;
00354         MP_subset<nbr>* S;
00355         MP_index_exp I1,I2,I3,I4,I5;
00356     };
00357 
00358 } // End of namespace flopc
00359 #endif

Generated on Sun Nov 6 03:14:50 2011 for FLOPC++ by  doxygen 1.4.7