multiArray.hh

Go to the documentation of this file.
1 
6 #ifndef multiarray_hh
7 #define multiarray_hh
8 
9 #include <map>
10 #include "basics/outputOperator.hh"
11 #include "basics/exceptions.hh"
12 #include "basics/typedefs.hh"
14 #include "toolbox/stiffArray.hh"
16 #include "basics/debug.hh"
17 
18 // debugging
19 #define MultiIndexDestr_D 0
20 #define MultiArrayConstr_D 0
21 #define MultiArrayCommute_D 0
22 #define MultiArrayErase_D 0
23 #define MultiArrayScanner_D 0
24 #define MultiArrayIndex_D 0
25 #define MultiArrayIndexShort_D 0
26 // simple info
27 #define MultiArrayInfo 1
28 
29 namespace concepts {
30 
31  // Forward Declaration
32  template <uint dim, typename T>
33  class MultiArray;
34 
35  // ******************************************************* MultiIndex<dim> **
36 
37  /* Class for a multidimensional index
38 
39  @author Kersten Schmidt, 2005
40  */
41 
42  template<uint dim>
43  class MultiIndex : public StiffArray<dim, uint> {
44  public:
46  MultiIndex() : StiffArray<dim, uint>() {}
52  MultiIndex(const uint& dft) : StiffArray<dim, uint>(dft) {}
59  MultiIndex(const uint dft[]);
60 
62  MultiIndex(const MultiIndex<dim>& a) : StiffArray<dim, uint>(a) {}
63  virtual ~MultiIndex() {
64  DEBUGL(MultiIndexDestr_D, "done.");
65  }
66 
68 // bool operator<(const MultiIndex<dim>& a) const;
70  bool operator==(const MultiIndex<dim>& a) const;
72  bool operator!=(const MultiIndex<dim>& a) const;
73  protected:
74  virtual std::ostream& info(std::ostream& os) const;
75  };
76 
77  template<uint dim>
78  MultiIndex<dim>::MultiIndex(const uint dft[]) :
79  StiffArray<dim, uint>() {
80  memorycpy((uint*)(*this), dft, dim);
81  }
82 
83 // template<uint dim>
84 // bool MultiIndex<dim>::operator<(const MultiIndex<dim>& a) const {
85 // uint i = 0;
86 // while(i < dim && (*this)[i] == a[i]) ++i;
87 // return (i < dim && (*this)[i] < a[i]);
88 // }
89 
90  template<uint dim>
92  uint i = 0;
93  while(i < dim && (*this)[i] == a[i]) ++i;
94  return (i == dim);
95  }
96 
97  template<uint dim>
99  return !(*this == a);
100  }
101 
102  template<uint dim>
103  std::ostream& MultiIndex<dim>::info(std::ostream& os) const {
104  os << concepts::typeOf(*this)<<"([";
105  for (uint i = 0; i < dim; ++i)
106  os << (*this)[i] << ((i == dim-1) ? "" : ", ");
107  return os << "])";
108  }
109 
110  // ************************************************** MultiEntrance<dim,T> **
111 
112  /* Class for Entrance of multidimensional Array
113 
114  @author Kersten Schmidt, 2004
115  */
116 
117  template <uint dim, typename T>
118  class MultiEntrance : public virtual OutputOperator {
119  public:
120  MultiEntrance(const uint i, const MultiEntrance<dim-1,T> ent) :
121  i_(i), ent_(ent) {}
122  inline uint operator()(const uint j) const {
123  conceptsAssert(j < dim, Assertion());
124  if (j==0) return i_;
125  return ent_(j-1);
126  }
127  inline const T& value() const { return ent_.value(); }
128  protected:
129  virtual std::ostream& info(std::ostream& os) const {
130  os << concepts::typeOf(*this) << "(" << i_;
131  for(uint j=0;j < dim-1;++j)
132  os << ", " << ent_(j);
133  return os << ", " << ent_.value() << ")";
134  }
135  private:
136  const uint i_;
137  MultiEntrance<dim-1,T> ent_;
138  };
139 
140  // **************************************************** MultiEntrance<1,T> **
141 
142  template <typename T>
143  class MultiEntrance<1,T> : public virtual OutputOperator {
144  public:
145  MultiEntrance(const uint i, const T& value) : i_(i), value_(value) {}
146  inline uint operator()(const uint j = 0) const {
147  conceptsAssert(j < 1, Assertion());
148  return i_;
149  }
150  inline const T& value() const { return value_; }
151  protected:
152  virtual std::ostream& info(std::ostream& os) const {
153  return os << concepts::typeOf(*this) << "(" << i_ << ", " << value_ << ")";
154  }
155  private:
156  const uint i_;
157  const T value_;
158  };
159 
160  // ***************************************************** MultiArray<dim,T> **
161 
168  template <uint dim, typename T>
169  class MultiArray : public virtual OutputOperator {
170  public:
173  class Scanner {
174  public:
175  Scanner(const MultiArray<dim,T> array) :
176  i_(array.data_.begin()), end_(array.data_.end()), j_(0) {
177  DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
178  if (!eos())
179  // j_.reset(i_->second.scan());
180  j_ = i_->second.scan();
181  DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
182  }
184  : i_(scan.i_), end_(scan.end_), j_(scan.j_) {}
186  virtual ~Scanner() { if (j_!=0) delete j_; }
188  bool eos() const {
189  DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
190  return i_ == end_;
191  }
193  DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
194  return MultiEntrance<dim,T>(i_->first, (*j_)());
195  }
197  DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
198  // avoid taking the next entrance if you are at the end
200  // take first the current entrance
201 // const MultiEntrance<dim,T> tmp(i_->first, (*j_)++);
202 // // if the scanner of the next dimension came to the end,
203 // // take next in this dimension
204 // if (j_->eos()) {
205 // i_++;
206 // j_.reset(i_->second.scan());
207 // delete j_;
208 // j_ = new typename MultiArray<dim-1,T>::Scanner(i_->second);
209 // typename MultiArray<dim-1, T>::Scanner* j2= i_->second.scan();
210 // DEBUGL(MultiArrayScanner_D, i_->first << ", " << (*j2)() << ", " << j2 << ", " << j2->eos());
211 // j_ = j2;
212 // DEBUGL(MultiArrayScanner_D, i_->first << ", " << (*j_)() << ", " << j_ << ", " << j_->eos());
213 // }
214  const MultiEntrance<dim,T> tmp(i_++->first, (*j_)());
215  DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second << ", " << j_ << ", " << j_->eos());
216  return tmp;
217  }
218  Scanner* clone() const { return new Scanner(*this); }
219  private:
223  typename std::map<uint, MultiArray<dim-1, T> >::const_iterator i_;
225  typename std::map<uint, MultiArray<dim-1, T> >::const_iterator end_;
227  typename MultiArray<dim-1, T>::Scanner* j_;
228 // std::unique_ptr<typename MultiArray<dim-1, T>::Scanner> j_;
229  };
234  MultiArray(bool commutable = false) : commutable_(commutable) {}
243  T& operator [](const uint i[dim]);
244  T& operator [](uint i[dim]);
245 
250  const T& operator [](const uint i[dim]) const;
251  const T& operator [](uint i[dim]) const;
252  Scanner* scan() const { return new Scanner(*this); }
255  bool isElm(const uint i[dim]) const;
256  bool isElm(uint i[dim]) const;
258  void commute(uint i[dim]) const;
261  void erase(const uint i[dim]);
262  void erase(uint i[dim]);
265  void erase_last();
267  uint size() const;
269  void clear();
270  protected:
271  virtual std::ostream& info(std::ostream& os) const;
272  private:
274  std::map<uint, MultiArray<dim-1, T> > data_;
276  const bool commutable_;
277  };
278 
279  template <uint dim, typename T>
280  T& MultiArray<dim, T>::operator[](const uint i[dim]) {
281  DEBUGL(MultiArrayIndex_D, *this << ", i = " << MultiIndex<dim>(i));
283  "i = " << MultiIndex<dim>(i));
284  uint I[dim];
285  memorycpy(I, i, dim);
286  return (*this)[I];
287  }
288 
289  template <uint dim, typename T>
290  T& MultiArray<dim, T>::operator[](uint i[dim]) {
291  DEBUGL(MultiArrayIndex_D, *this << ", i = " << MultiIndex<dim>(i));
293  "i = " << MultiIndex<dim>(i));
294  commute(i);
295  typename std::map<uint, MultiArray<dim-1, T> >::iterator j =
296  data_.find(i[0]);
297  if (j == data_.end()) {
298  // creating of new entrance, but no data
299  std::pair
300  <typename std::map<uint, MultiArray<dim-1, T> >::iterator, bool> k =
301  data_.insert(std::pair<uint, MultiArray<dim-1, T> >
302  (i[0], MultiArray<dim-1, T>(commutable_)));
303  j = k.first;
304  }
305  DEBUGL(MultiArrayIndex_D, *this);
306  // if new entrance was created, here the data is created
307  return j->second[i+1];
308  }
309 
310  template <uint dim, typename T>
311  const T& MultiArray<dim, T>::operator[](const uint i[dim]) const {
312  DEBUGL(MultiArrayIndex_D, *this << ", i = " << MultiIndex<dim>(i));
314  "i = " << MultiIndex<dim>(i));
315  uint I[dim];
316  memorycpy(I, i, dim);
317  return (*this)[I];
318  }
319 
320  template <uint dim, typename T>
321  const T& MultiArray<dim, T>::operator[](uint i[dim]) const {
322  DEBUGL(MultiArrayIndex_D, *this << ", i = " << MultiIndex<dim>(i));
324  "i = " << MultiIndex<dim>(i));
325  commute(i);
326  typename std::map<uint, MultiArray<dim-1, T> >::const_iterator j =
327  data_.find(i[0]);
328  if (j == data_.end()) {
330  "i = " << MultiIndex<dim>(i));
332  }
333  return j->second[i+1];
334  }
335 
336  template <uint dim, typename T>
337  bool MultiArray<dim, T>::isElm(const uint i[dim]) const {
338  uint I[dim];
339  memorycpy(I, i, dim);
340  return isElm(I);
341  }
342 
343  template <uint dim, typename T>
344  bool MultiArray<dim, T>::isElm(uint i[dim]) const {
345  commute(i);
346  typename std::map<uint, MultiArray<dim-1, T> >::const_iterator j =
347  data_.find(i[0]);
348  if (j == data_.end())
349  return false;
350  else return j->second.isElm(i+1);
351  }
352 
353  template <uint dim, typename T>
354  void MultiArray<dim, T>::commute(uint i[dim]) const {
355  if (commutable_) {
356  for(uint j=1; j < dim; ++j) {
357  if (i[j] < i[0]) std::swap(i[0],i[j]);
358  }
360  }
361  }
362 
363  template <uint dim, typename T>
364  void MultiArray<dim, T>::erase(const uint i[dim]) {
365  uint I[dim];
366  memorycpy(I, i, dim);
367  erase(I);
368  }
369 
370  template <uint dim, typename T>
371  void MultiArray<dim, T>::erase(uint i[dim]) {
372  commute(i);
373  DEBUGL(MultiArrayErase_D, "Erase (" << Array<uint>(i,dim) << ")");
374  typename std::map<uint, MultiArray<dim-1, T> >::iterator j =
375  data_.find(i[0]);
376  if (j == data_.end())
378  DEBUGL(MultiArrayErase_D, j->second);
379  j->second.erase(i+1);
380  DEBUGL(MultiArrayErase_D, j->second);
381  if (j->second.size()==0)
382  data_.erase(i[0]);
383  }
384 
385  template <uint dim, typename T>
387  typename std::map<uint, MultiArray<dim-1, T> >::iterator j =
388  data_.rbegin();
389  data_.erase(j->first);
390  }
391 
392  template <uint dim, typename T>
394  uint size = 0;
395  typename std::map<uint, MultiArray<dim-1, T> >::const_iterator j =
396  data_.begin();
397  for(;j != data_.end();++j)
398  size += j->second.size();
399  return size;
400  }
401 
402  template <uint dim, typename T>
404  typename std::map<uint, MultiArray<dim-1, T> >::iterator j = data_.begin();
405  for(;j != data_.end();++j)
406  j->second.clear();
407  data_.clear();
408  }
409 
410  template <uint dim, typename T>
411  std::ostream& MultiArray<dim, T>::info(std::ostream& os) const {
412  uint size = this->size();
413  os << concepts::typeOf(*this)<<"(" << size << ", ";
414  if (commutable_) os << "yes";
415  else os << "no";
416  if (size > 0) {
417  os << ",[";
418  typename std::map<uint, MultiArray<dim-1, T> >::const_iterator j0 = data_.begin();
419  for(;j0 != data_.end();) {
420 #if MultiArrayInfo
421  DEBUGL(MultiArrayScanner_D, j0->first << ", " << j0->second);
422  os << "(" << j0->first << ", " << j0->second << ")";
423 #else
424  // does not function, ++-Operator doesn't work
425  std::unique_ptr<Scanner> sc(scan());
426  while (!sc->eos()) {
427  os << (*sc)++;
428  if (!sc->eos()) os << ", ";
429  }
430 #endif
431  if (++j0 != data_.end()) os << ", ";
432  }
433  os << "]";
434  }
435  return os << ")";
436  }
437 
438  // ******************************************************* MultiArray<1,T> **
439 
444  template <typename T>
445  class MultiArray<1,T> : public virtual OutputOperator {
446  public:
449  class Scanner {
450  public:
451  Scanner(const MultiArray<1,T> array) : i_(array.data_.begin()),
452  end_(array.data_.end()) {}
454  bool eos() const {return i_ == end_; }
456  return MultiEntrance<1,T>(i_->first, i_->second);
457  }
459  // avoid taking the next entrance if you are at the end
461  // take the current entrance
462  const MultiEntrance<1,T> tmp(i_->first, i_->second);
463  DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
464  i_++;
465  return tmp;
466  }
467  Scanner* clone() const { return new Scanner(*this); }
468  private:
472  typename std::map<uint, T>::const_iterator i_;
473  typename std::map<uint, T>::const_iterator end_;
474  };
475 
481  MultiArray(bool commutable = false) {
482  clear();
483  DEBUGL(MultiArrayConstr_D,"Constructor called");
484  }
493  T& operator [](const uint i[1]) { return data_[i[0]]; }
498  const T& operator [](const uint i[1]) const { return (*this)[i[0]];}
506  T& operator [](const uint i) { return data_[i]; }
511  const T& operator [](const uint i) const;
513  Scanner* scan() const { return new Scanner(*this); }
516  bool isElm(const uint i[1]) const { return isElm(i[0]); }
517  bool isElm(const uint i) const;
520  inline void erase(const uint i[1]) { erase(i[0]); }
521  inline void erase(uint i) {
522  DEBUGL(MultiArrayErase_D, "Erase (" << i << ")");
523  data_.erase(i);
524  }
525  inline void erase_last() {
526  typename std::map<uint, T>::const_reverse_iterator j =
527  data_.rbegin();
528  data_.erase(j->first);
529  }
531  uint size() const { return data_.size(); }
532 
534  inline void clear() { data_.clear(); }
535  protected:
536  virtual std::ostream& info(std::ostream& os) const;
537  private:
539  std::map<uint, T> data_;
540  };
541 
542  template <typename T>
543  const T& MultiArray<1, T>::operator[](const uint i) const {
544  typename std::map<uint, T>::const_iterator j = data_.find(i);
545  if (j == data_.end())
547  return j->second;
548  }
549 
550  template <typename T>
551  bool MultiArray<1, T>::isElm(const uint i) const {
552  typename std::map<uint, T>::const_iterator j = data_.find(i);
553  return (j != data_.end());
554  }
555 
556  template <typename T>
557  std::ostream& MultiArray<1,T>::info(std::ostream& os) const {
558  uint size = this->size();
559  os << concepts::typeOf(*this)<<"(" << size;
560  if (size > 0) {
561  os << ",[";
562  typename std::map<uint, T>::const_iterator i_ = data_.begin();
563  typename std::map<uint, T>::const_iterator end_ = data_.end();
564  while (i_ != end_) {
565  os << "(" << i_->first << "," << i_->second << ")";
566  i_++;
567  if (i_ != end_) os << ", ";
568  }
569  os << "]";
570  }
571  return os << ")";
572  }
573 
574 } // namespace concepts
575 
576 #endif // multiarray_hh
bool operator==(const MultiIndex< dim > &a) const
Comparison operator.
Definition: multiArray.hh:91
bool isElm(const uint i[1]) const
Checks if the element exists.
Definition: multiArray.hh:516
const MultiEntrance< dim, T > operator()() const
Definition: multiArray.hh:192
virtual std::ostream & info(std::ostream &os) const
Definition: multiArray.hh:411
std::map< uint, MultiArray< dim-1, T > >::const_iterator i_
Iterator in current MultiArray, which holds the index and the array of smaller dimension.
Definition: multiArray.hh:223
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition: multiArray.hh:129
std::map< uint, MultiArray< dim-1, T > >::const_iterator end_
Iterator for the end of the mapping.
Definition: multiArray.hh:225
const MultiEntrance< 1, T > operator()() const
Definition: multiArray.hh:455
Class for scanning (iterating) over the array in all dimensions.
Definition: multiArray.hh:173
const bool commutable_
flag for commutability
Definition: multiArray.hh:276
void erase(const uint i[1])
Erase entry i.
Definition: multiArray.hh:520
#define MultiArrayIndex_D
Definition: multiArray.hh:24
MultiArray< dim-1, T >::Scanner * j_
Scanner of the entrances of smaller dimensions.
Definition: multiArray.hh:227
#define conceptsException(exc)
Prepares an exception for throwing.
Definition: exceptions.hh:344
#define MultiIndexDestr_D
Definition: multiArray.hh:19
#define MultiArrayConstr_D
Definition: multiArray.hh:20
void erase(uint i[dim])
bool isElm(uint i[dim]) const
uint operator()(const uint j) const
Definition: multiArray.hh:122
MultiIndex()
Constructor.
Definition: multiArray.hh:46
bool eos() const
Returns true if the end of the scanned set is reached.
Definition: multiArray.hh:188
Scanner(const Scanner &scan)
Definition: multiArray.hh:183
#define conceptsAssert(cond, exc)
Assert that a certain condition is fulfilled.
Definition: exceptions.hh:394
An array of objects of fix length, defined by template parameter dim.
Definition: stiffArray.hh:29
MultiArray(bool commutable=false)
Constructor.
Definition: multiArray.hh:481
void clear()
Clears the array.
Definition: multiArray.hh:534
#define DEBUGL(doit, msg)
virtual ~Scanner()
delete scanner, if there was one
Definition: multiArray.hh:186
virtual ~MultiIndex()
Definition: multiArray.hh:63
uint size() const
Number of entrances.
Definition: multiArray.hh:531
const T & value() const
Definition: multiArray.hh:127
MultiEntrance(const uint i, const T &value)
Definition: multiArray.hh:145
Scanner * scan() const
Scanner over the entrances.
Definition: multiArray.hh:513
Exception class for assertions.
Definition: exceptions.hh:258
uint operator()(const uint j=0) const
Definition: multiArray.hh:146
void erase(const uint i[dim])
Erase entry i.
Definition: multiArray.hh:364
T & operator[](const uint i[dim])
Index operator for the container.
Definition: multiArray.hh:280
Container typename for multidimensional Array which is based on std::map.
Definition: multiArray.hh:33
void clear()
Clears the array.
Definition: multiArray.hh:403
const MultiEntrance< dim, T > operator++(int)
Definition: multiArray.hh:196
std::map< uint, T >::const_iterator end_
Definition: multiArray.hh:473
#define MultiArrayErase_D
Definition: multiArray.hh:22
Scanner(const MultiArray< 1, T > array)
Definition: multiArray.hh:451
std::map< uint, MultiArray< dim-1, T > > data_
array of arrays of the dimension dim-1
Definition: multiArray.hh:274
void commute(uint i[dim]) const
if commutable_ then order the smallest index to front
Definition: multiArray.hh:354
#define MultiArrayCommute_D
Definition: multiArray.hh:21
std::map< uint, T >::const_iterator i_
Iterator in current MultiArray, which holds the index and the array of smaller dimension.
Definition: multiArray.hh:472
void memorycpy(F *dest, const G *src, size_t n)
Copies n entries from src to dest (faster than std::memcpy)
bool isElm(const uint i[dim]) const
Checks if the element exists.
Definition: multiArray.hh:337
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition: multiArray.hh:103
MultiEntrance< dim-1, T > ent_
Definition: multiArray.hh:137
Exception class to express that an index in a dynamic array does not exist.
Definition: exceptions.hh:191
MultiIndex(const MultiIndex< dim > &a)
Copy constructor.
Definition: multiArray.hh:62
uint size() const
Size.
Definition: multiArray.hh:393
MultiEntrance(const uint i, const MultiEntrance< dim-1, T > ent)
Definition: multiArray.hh:120
const MultiEntrance< 1, T > operator++(int)
Definition: multiArray.hh:458
#define MultiArrayIndexShort_D
Definition: multiArray.hh:25
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition: multiArray.hh:152
std::map< uint, T > data_
array of T
Definition: multiArray.hh:539
std::string typeOf(const T &t)
Return the typeid name of a class object.
Definition: output.hh:43
Container typename for multidimensional Array which is based on std::map.
Definition: multiArray.hh:445
Scanner * scan() const
Definition: multiArray.hh:252
Scanner(const MultiArray< dim, T > array)
Definition: multiArray.hh:175
MultiArray(bool commutable=false)
Constructor If commutable then the order of the indices is not important, e.g.
Definition: multiArray.hh:234
bool operator!=(const MultiIndex< dim > &a) const
Comparison operator.
Definition: multiArray.hh:98
Class providing an output operator.
void erase_last()
Erase last entry.
Definition: multiArray.hh:386
MultiIndex(const uint &dft)
Constructor.
Definition: multiArray.hh:52
#define MultiArrayScanner_D
Definition: multiArray.hh:23
Basic namespace for Concepts-2.
Definition: pml_formula.h:16
Page URL: http://wiki.math.ethz.ch/bin/view/Concepts/WebHome
21 August 2020
© 2020 Eidgenössische Technische Hochschule Zürich