FLOPC++
MP_set.hpp
Go to the documentation of this file.
1 // ******************** FlopCpp **********************************************
2 // File: MP_set.hpp
3 // $Id$
4 // Author: Tim Helge Hultberg (thh@mat.ua.pt)
5 // Copyright (C) 2003 Tim Helge Hultberg
6 // All Rights Reserved.
7 // ****************************************************************************
8 
9 #ifndef _MP_set_hpp_
10 #define _MP_set_hpp_
11 
12 #include <iostream>
13 #include <sstream>
14 using std::cout;
15 using std::endl;
16 
17 #include <string>
18 using std::string;
19 
20 #include "MP_domain.hpp"
21 #include "MP_index.hpp"
22 #include "MP_utilities.hpp"
23 
24 namespace flopc {
25 
30  class MP_set_base : public MP_index , public Named {
31  public:
32  MP_set_base() : Cyclic(false) {}
33 
34  virtual int size() const = 0;
35  virtual operator MP_domain() const = 0;
36  virtual MP_domain operator()(const MP_index_exp& i) const = 0;
37 
38  int check(int i) const {
39  if ((i>=0) && (i<size())) {
40  return i;
41  } else {
42  if (Cyclic == true) {
43  return mod(i,size());
44  } else {
45  return outOfBound;
46  }
47  }
48  }
49  int checkStage(int i) const {
50  if ((i>=0) && (i<size())) {
51  return i*isStage();
52  } else {
53  if (Cyclic == true) {
54  return mod(i,size())*isStage();
55  } else {
56  return outOfBound;
57  }
58  }
59  }
61  virtual int isStage() const {
62  return 0;
63  }
64 
65  bool Cyclic;
66  };
67 
68 
79  class MP_set : public MP_set_base {
80  public:
82  MP_set(int i = 0): cardinality(i) {}
87  MP_domain operator()(const MP_index_exp& i) const {
88  return i->getDomain(const_cast<MP_set*>(this));
89  }
91  operator MP_domain() const {
92  return new MP_domain_set(this,const_cast<MP_set*>(this));
93  }
98  return (MP_domain(new MP_domain_set(this,this))).such_that(b);
99  }
103  void cyclic() {
104  Cyclic = true;
105  }
107  virtual int size() const {
108  return cardinality;
109  }
110  int last() {
111  return cardinality-1;
112  }
114  static MP_set &getEmpty();
115  private:
116  static MP_set Empty;
118  };
119 
120  class MP_stage : public MP_set {
121  public:
122  MP_stage(int i = 0): MP_set(i) {}
123  virtual int isStage() const {
124  return 1;
125  }
126  };
127 
128  template <int nbr> class MP_subset;
129 
135  template<int nbr> class InsertFunctor : public Functor {
136  public:
137  InsertFunctor( MP_subset<nbr>* s, vector<MP_index_exp> i)
138  : S(s), I(i) {}
139  void operator()() const {
140  vector<int> elm(nbr);
141  for (int i=0; i<nbr; i++) {
142  elm[i] = I[i]->evaluate();
143  }
144  S->insert(elm);
145  }
146  private:
148  vector<MP_index_exp> I;
149  };
150 
151  template <int nbr> class SubsetRef;
152 
161  template <int nbr>
162  class MP_subset : public MP_set {
163  friend class MP_domain_subset<nbr>;
164  friend class SubsetRef<nbr>;
165  public:
166  MP_subset(const MP_set& s1,
167  const MP_set& s2=MP_set::getEmpty(),
168  const MP_set& s3=MP_set::getEmpty(),
169  const MP_set& s4=MP_set::getEmpty(),
170  const MP_set& s5=MP_set::getEmpty()) {
171  S = makeVector<nbr,const MP_set*>(&s1,&s2,&s3,&s4,&s5);
172  }
173 
174  void display(const std::string& s = "") const {
175  std::map<std::vector<int>, int>::const_iterator i;
176  cout<<s<<endl;
177  for (i = elements.begin(); i != elements.end(); i++) {
178  for (int j=0; j<nbr; j++) {
179  cout<<(*i).first[j]<<" ";
180  }
181  cout<<endl;
182  }
183  }
184 
185  MP_subset(vector<const MP_set*> s) : S(s) {}
186 
188 
189  int operator()(int i1, int i2=0, int i3=0, int i4=0, int i5=0) {
190  std::map<vector<int>, int>::const_iterator pos;
191  pos = elements.find(makeVector<nbr>(i1, i2, i3, i4, i5));
192  if (pos==elements.end()) {
193  return outOfBound;
194  } else {
195  return pos->second;
196  }
197  }
198 
200  const MP_index_exp& i2=MP_index::getEmpty(),
201  const MP_index_exp& i3=MP_index::getEmpty(),
202  const MP_index_exp& i4=MP_index::getEmpty(),
203  const MP_index_exp& i5=MP_index::getEmpty()) {
204  return *new SubsetRef<nbr>(this,i1,i2,i3,i4,i5);
205  }
206 
208  return MP_domain(s);
209  }
210 
211  int evaluate(const vector<MP_index*>& I) const {
212  vector<int> vi;
213  for (int k=0; k<nbr; k++) {
214  int temp = I[k]->evaluate();
215  vi.push_back(temp);
216  }
217  std::map<vector<int>, int>::const_iterator pos;
218  pos = elements.find(vi);
219  if (pos==elements.end()) {
220  return outOfBound;
221  } else {
222  return pos->second;
223  }
224  }
225 
226  void insert(const vector<int> &args) {
227  bool isOk = true;
228  for (int i=0; i<nbr; i++) {
229  if ( S[i]->check(args[i]) == outOfBound ) {
230  isOk = false;
231  }
232  }
233  if (isOk == true) {
234  std::map<vector<int>, int>::const_iterator pos;
235  pos = elements.find(args);
236  if (pos==elements.end()) { // insert if not existent
237  const int v = elements.size();
238  elements[args] = v;
239  }
240  }
241  }
242  void insert(int i1, int i2=0, int i3=0, int i4=0, int i5=0) {
243  insert(makeVector<nbr>(i1, i2, i3, i4, i5));
244  }
250  return *new InsertFunctor<nbr>(this,makeVector<nbr>(i1, i2, i3, i4, i5));
251  }
252  virtual int size() const {
253  return elements.size();
254  }
255 
256  private:
257  vector<const MP_set*> S;
258  std::map<std::vector<int>, int> elements;
259  };
260 
269  class SUBSETREF : public MP_index_base {
270  public:
271  virtual MP_index* getIndex() const {
272  return 0;
273  }
274  virtual MP_domain getDomain(MP_set* s) const {
275  return MP_domain::getEmpty();
276  }
277  int evaluate() const {
278  return 0;
279  }
280  };
281 
289  template <int nbr>
290  class SubsetRef : public SUBSETREF {
291  public:
293  const MP_index_exp& i1,
294  const MP_index_exp& i2,
295  const MP_index_exp& i3,
296  const MP_index_exp& i4,
297  const MP_index_exp& i5) :
298  S(s),I1(i1),I2(i2),I3(i3),I4(i4),I5(i5) {}
299 
300  operator MP_domain() const {
301 // MP_domain_base* base;
302 // base = new MP_domain_subset<nbr>(S,
303 // makeVector<nbr>(I1->getIndex(), I2->getIndex(),
304 // I3->getIndex(), I4->getIndex(),
305 // I5->getIndex()) );
306 // base->such_that(B);
307 // return base;
308  return new MP_domain_subset<nbr>(S,
309  makeVector<nbr>(I1->getIndex(), I2->getIndex(),
310  I3->getIndex(), I4->getIndex(),
311  I5->getIndex()) );
312  }
313 
314  virtual MP_domain getDomain(MP_set* s) const {
315  return new MP_domain_subset<nbr>(S,
316  makeVector<nbr>(I1->getIndex(), I2->getIndex(),
317  I3->getIndex(), I4->getIndex(),
318  I5->getIndex()) );
319  }
320 
321 // const MP_domain& such_that(const MP_boolean& b) {
322 // return MP_domain().such_that(b);
323 // }
324 
326  B = b;
327  return *this;
328  }
329 
330  int evaluate() const {
331  vector<MP_index_exp> I = makeVector<nbr>(I1,I2,I3,I4,I5);
332  vector<int> vi;
333  for (int k=0; k<nbr; k++) {
334  int temp = I[k]->evaluate();
335  vi.push_back(temp);
336  }
337  std::map<vector<int>, int>::const_iterator pos;
338  pos = S->elements.find(vi);
339  if (pos==S->elements.end()) {
340  return outOfBound;
341  } else {
342  return pos->second;
343  }
344 
345  }
346  MP_index* getIndex() const {
347  return S;
348  }
352  };
353 
354 } // End of namespace flopc
355 #endif