Class documentation of Concepts

Loading...
Searching...
No Matches
multiArray.hh
Go to the documentation of this file.
1
6#ifndef multiarray_hh
7#define multiarray_hh
8
9#include <map>
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
29namespace 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>
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:
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:
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 }
183 Scanner(const Scanner& scan)
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 }
192 const MultiEntrance<dim,T> operator()() const {
193 DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
194 return MultiEntrance<dim,T>(i_->first, (*j_)());
195 }
196 const MultiEntrance<dim,T> operator++(int) {
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) {}
235 ~MultiArray() { clear(); }
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]);
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>
281 DEBUGL(MultiArrayIndex_D, *this << ", i = " << MultiIndex<dim>(i));
282 DEBUGL(!MultiArrayIndex_D && MultiArrayIndexShort_D,
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>
291 DEBUGL(MultiArrayIndex_D, *this << ", i = " << MultiIndex<dim>(i));
292 DEBUGL(!MultiArrayIndex_D && MultiArrayIndexShort_D,
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));
313 DEBUGL(!MultiArrayIndex_D && MultiArrayIndexShort_D,
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));
323 DEBUGL(!MultiArrayIndex_D && MultiArrayIndexShort_D,
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()) {
329 DEBUGL(MultiArrayIndex_D || MultiArrayIndexShort_D,
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>
355 if (commutable_) {
356 for(uint j=1; j < dim; ++j) {
357 if (i[j] < i[0]) std::swap(i[0],i[j]);
358 }
359 DEBUGL(MultiArrayCommute_D, MultiIndex<dim>(i));
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()) {}
453 Scanner(const Scanner& scan) : i_(scan.i_), end_(scan.end_) {}
454 bool eos() const {return i_ == end_; }
455 const MultiEntrance<1,T> operator()() const {
456 return MultiEntrance<1,T>(i_->first, i_->second);
457 }
458 const MultiEntrance<1,T> operator++(int) {
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 }
485 ~MultiArray() { clear(); }
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
#define conceptsException(exc)
virtual ~Scanner()
delete scanner, if there was one
bool eos() const
Returns true if the end of the scanned set is reached.
Scanner * scan() const
Scanner over the entrances.
void erase(const uint i[1])
uint size() const
Number of entrances.
MultiArray(bool commutable=false)
bool isElm(const uint i[1]) const
void clear()
Clears the array.
void erase(const uint i[dim])
uint size() const
Size.
MultiArray(bool commutable=false)
bool isElm(const uint i[dim]) const
void clear()
Clears the array.
T & operator[](const uint i[dim])
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
void commute(uint i[dim]) const
if commutable_ then order the smallest index to front
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
MultiIndex(const uint &dft)
Definition multiArray.hh:52
bool operator==(const MultiIndex< dim > &a) const
Comparison operator.
Definition multiArray.hh:91
MultiIndex()
Constructor.
Definition multiArray.hh:46
MultiIndex(const MultiIndex< dim > &a)
Copy constructor.
Definition multiArray.hh:62
bool operator!=(const MultiIndex< dim > &a) const
Comparison operator.
Definition multiArray.hh:98
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
#define conceptsAssert(cond, exc)
#define DEBUGL(doit, msg)
Definition debug.hh:40
std::string typeOf(const T &t)
Definition output.hh:43
void memorycpy(F *dest, const G *src, size_t n)
Copies n entries from src to dest (faster than std::memcpy)
Set< F > makeSet(uint n, const F &first,...)
Definition set.hh:320