Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)

toolbox/multiArray.hh
Go to the documentation of this file.
00001 /* multidimensional arrays based on std::map
00002  */
00003 
00004 #ifndef multiarray_hh
00005 #define multiarray_hh
00006 
00007 #include <map>
00008 #include "basics/outputOperator.hh"
00009 #include "basics/exceptions.hh"
00010 #include "basics/typedefs.hh"
00011 #include "basics/vectorsMatrices.hh"
00012 #include "toolbox/stiffArray.hh"
00013 #include "toolbox/scannerConnectors.hh"
00014 #include "basics/debug.hh"
00015 
00016 // debugging
00017 #define MultiIndexDestr_D 0
00018 #define MultiArrayCommute_D 0
00019 #define MultiArrayErase_D 0
00020 #define MultiArrayScanner_D 0
00021 #define MultiArrayIndex_D 0
00022 #define MultiArrayIndexShort_D 0
00023 // simple info
00024 #define MultiArrayInfo 1
00025 
00026 namespace concepts {
00027 
00028   // Forward Declaration
00029   template <uint dim, typename T>
00030   class MultiArray;
00031 
00032   // ******************************************************* MultiIndex<dim> **
00033 
00034   /* Class for a multidimensional index
00035 
00036      @author Kersten Schmidt, 2005
00037   */
00038 
00039   template<uint dim>
00040   class MultiIndex : public StiffArray<dim, uint> {
00041   public:
00043     MultiIndex() : StiffArray<dim, uint>() {}
00049     MultiIndex(const uint& dft) : StiffArray<dim, uint>(dft) {}
00056     MultiIndex(const uint dft[]); 
00057 
00059     MultiIndex(const MultiIndex<dim>& a) : StiffArray<dim, uint>(a) {}
00060     virtual ~MultiIndex() {
00061       DEBUGL(MultiIndexDestr_D, "done.");
00062     }
00063 
00065 //     bool operator<(const MultiIndex<dim>& a) const;
00067     bool operator==(const MultiIndex<dim>& a) const;
00069     bool operator!=(const MultiIndex<dim>& a) const;
00070   protected:
00071     virtual std::ostream& info(std::ostream& os) const;
00072   };
00073 
00074   template<uint dim>
00075   MultiIndex<dim>::MultiIndex(const uint dft[]) :
00076     StiffArray<dim, uint>() {
00077     memorycpy((uint*)(*this), dft, dim);
00078   }
00079 
00080 //   template<uint dim>
00081 //   bool MultiIndex<dim>::operator<(const MultiIndex<dim>& a) const {
00082 //     uint i = 0;
00083 //     while(i < dim && (*this)[i] == a[i]) ++i;
00084 //     return (i < dim && (*this)[i] < a[i]);
00085 //   }
00086 
00087   template<uint dim>
00088   bool MultiIndex<dim>::operator==(const MultiIndex<dim>& a) const {
00089     uint i = 0;
00090     while(i < dim && (*this)[i] == a[i]) ++i;
00091     return (i == dim);
00092   }
00093 
00094   template<uint dim>
00095   bool MultiIndex<dim>::operator!=(const MultiIndex<dim>& a) const {
00096     return !(*this == a);
00097   }
00098 
00099   template<uint dim>
00100   std::ostream& MultiIndex<dim>::info(std::ostream& os) const {
00101     os << "MultiIndex<" << dim << ">([";
00102     for (uint i = 0; i < dim; ++i)
00103       os << (*this)[i] << ((i == dim-1) ? "" : ", ");
00104     return os << "])";
00105   }
00106 
00107   // ************************************************** MultiEntrance<dim,T> **
00108 
00109   /* Class for Entrance of multidimensional Array
00110 
00111      @author Kersten Schmidt, 2004
00112    */
00113 
00114   template <uint dim, typename T>
00115   class MultiEntrance : public OutputOperator {
00116   public:
00117     MultiEntrance(const uint i, const MultiEntrance<dim-1,T> ent) : 
00118       i_(i), ent_(ent) {}
00119     inline uint operator()(const uint j) const {
00120       conceptsAssert(j < dim, Assertion());
00121       if (j==0) return i_;
00122       return ent_(j-1);
00123     }
00124     inline const T& value() const { return ent_.value(); }
00125   protected:
00126     virtual std::ostream& info(std::ostream& os) const {
00127       os << "(" << i_;
00128       for(uint j=0;j < dim-1;++j)
00129   os << ", " << ent_(j);
00130       return os << ", " << ent_.value() << ")";
00131     }
00132   private:
00133     const uint i_;
00134     MultiEntrance<dim-1,T> ent_;
00135   };
00136 
00137   // **************************************************** MultiEntrance<1,T> **
00138 
00139   template <typename T>
00140   class MultiEntrance<1,T> : public OutputOperator {
00141   public:
00142     MultiEntrance(const uint i, const T& value) : i_(i), value_(value) {}
00143     inline uint operator()(const uint j = 0) const {
00144       conceptsAssert(j < 1, Assertion());
00145       return i_;
00146     }
00147     inline const T& value() const { return value_; }
00148   protected:
00149     virtual std::ostream& info(std::ostream& os) const {
00150       return os << "(" << i_ << ", " << value_ << ")";
00151     }
00152   private:
00153     const uint i_;
00154     const T value_;
00155   };
00156   
00157   // ***************************************************** MultiArray<dim,T> **
00158 
00165   template <uint dim, typename T>
00166   class MultiArray : public OutputOperator {
00167   public:
00170     class Scanner {
00171     public:
00172       Scanner(const MultiArray<dim,T> array) : 
00173         i_(array.data_.begin()), end_(array.data_.end()), j_(0) {
00174         DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
00175         if (!eos()) 
00176           //    j_.reset(i_->second.scan());
00177           j_ = i_->second.scan();
00178         DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
00179       }
00180       Scanner(const Scanner& scan) 
00181         : i_(scan.i_), end_(scan.end_), j_(scan.j_) {}
00183       virtual ~Scanner() { if (j_!=0) delete j_; }
00185       bool eos() const {
00186         DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
00187         return i_ == end_; 
00188       }
00189       const MultiEntrance<dim,T> operator()() const {
00190         DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
00191         return MultiEntrance<dim,T>(i_->first, (*j_)());
00192       }
00193       const MultiEntrance<dim,T> operator++(int) {
00194         DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second);
00195         // avoid taking the next entrance if you are at the end
00196         conceptsAssert(!eos(), Assertion());
00197   // take first the current entrance
00198 //  const MultiEntrance<dim,T> tmp(i_->first, (*j_)++);
00199 //  // if the scanner of the next dimension came to the end,
00200 //  // take next in this dimension
00201 //  if (j_->eos()) {
00202 //    i_++;
00203 //    j_.reset(i_->second.scan());
00204 //    delete j_;
00205 //    j_ = new typename MultiArray<dim-1,T>::Scanner(i_->second);
00206 //    typename MultiArray<dim-1, T>::Scanner* j2= i_->second.scan();
00207 //    DEBUGL(MultiArrayScanner_D, i_->first << ", " << (*j2)() << ", " << j2 << ", " << j2->eos());
00208 //    j_ = j2;
00209 //    DEBUGL(MultiArrayScanner_D, i_->first << ", " << (*j_)() << ", " << j_ << ", " << j_->eos());
00210 //  }
00211         const MultiEntrance<dim,T> tmp(i_++->first, (*j_)());
00212         DEBUGL(MultiArrayScanner_D, i_->first << ", " << i_->second << ", " << j_ << ", " << j_->eos());  
00213         return tmp;
00214       }
00215       Scanner* clone() const { return new Scanner(*this); }
00216     private:
00220       typename std::map<uint, MultiArray<dim-1, T> >::const_iterator i_;
00222       typename std::map<uint, MultiArray<dim-1, T> >::const_iterator end_;
00224       typename MultiArray<dim-1, T>::Scanner* j_;
00225 //       std::auto_ptr<typename MultiArray<dim-1, T>::Scanner> j_;
00226     };
00231     MultiArray(bool commutable = false) : commutable_(commutable) {}
00232     ~MultiArray() { clear(); }
00240     T& operator [](const uint i[dim]);
00241     T& operator [](uint i[dim]);
00242 
00247     const T& operator [](const uint i[dim]) const;
00248     const T& operator [](uint i[dim]) const;
00249     Scanner* scan() const { return new Scanner(*this); }
00252     bool isElm(const uint i[dim]) const;
00253     bool isElm(uint i[dim]) const;
00255     void commute(uint i[dim]) const;
00258     void erase(const uint i[dim]);
00259     void erase(uint i[dim]);
00261     uint size() const;
00263     void clear();
00264   protected:
00265     virtual std::ostream& info(std::ostream& os) const;
00266   private:
00268     std::map<uint, MultiArray<dim-1, T> > data_;
00270     const bool commutable_;
00271   };
00272 
00273   template <uint dim, typename T>
00274   T& MultiArray<dim, T>::operator[](const uint i[dim]) {
00275     DEBUGL(MultiArrayIndex_D, *this << ", i = " << MultiIndex<dim>(i));
00276     DEBUGL(!MultiArrayIndex_D && MultiArrayIndexShort_D,
00277      "i = " << MultiIndex<dim>(i));
00278     uint I[dim];
00279     memorycpy(I, i, dim);
00280     return (*this)[I];
00281   }
00282 
00283   template <uint dim, typename T>
00284   T& MultiArray<dim, T>::operator[](uint i[dim]) {
00285     DEBUGL(MultiArrayIndex_D, *this << ", i = " << MultiIndex<dim>(i));
00286     DEBUGL(!MultiArrayIndex_D && MultiArrayIndexShort_D,
00287      "i = " << MultiIndex<dim>(i));
00288     commute(i);
00289     typename std::map<uint, MultiArray<dim-1, T> >::iterator j = 
00290       data_.find(i[0]);
00291     if (j == data_.end()) {
00292       // creating of new entrance, but no data
00293       std::pair
00294   <typename std::map<uint, MultiArray<dim-1, T> >::iterator, bool> k =
00295   data_.insert(std::pair<uint, MultiArray<dim-1, T> >
00296          (i[0], MultiArray<dim-1, T>(commutable_)));
00297       j = k.first;
00298     }
00299     DEBUGL(MultiArrayIndex_D, *this);
00300     // if new entrance was created, here the data is created
00301     return j->second[i+1];
00302   }
00303 
00304   template <uint dim, typename T>
00305   const T& MultiArray<dim, T>::operator[](const uint i[dim]) const {
00306     DEBUGL(MultiArrayIndex_D, *this << ", i = " << MultiIndex<dim>(i));
00307     DEBUGL(!MultiArrayIndex_D && MultiArrayIndexShort_D,
00308      "i = " << MultiIndex<dim>(i));
00309     uint I[dim];
00310     memorycpy(I, i, dim);
00311     return (*this)[I];
00312   }
00313 
00314   template <uint dim, typename T>
00315   const T& MultiArray<dim, T>::operator[](uint i[dim]) const {
00316     DEBUGL(MultiArrayIndex_D, *this << ", i = " << MultiIndex<dim>(i));
00317     DEBUGL(!MultiArrayIndex_D && MultiArrayIndexShort_D,
00318      "i = " << MultiIndex<dim>(i));
00319     commute(i);
00320     typename std::map<uint, MultiArray<dim-1, T> >::const_iterator j =
00321       data_.find(i[0]);
00322     if (j == data_.end()) {
00323       DEBUGL(MultiArrayIndex_D || MultiArrayIndexShort_D,
00324        "i = " << MultiIndex<dim>(i));
00325       throw conceptsException(IndexNotExisting());
00326     }
00327     return j->second[i+1];
00328   }
00329 
00330   template <uint dim, typename T>
00331   bool MultiArray<dim, T>::isElm(const uint i[dim]) const {
00332     uint I[dim];
00333     memorycpy(I, i, dim);
00334     return isElm(I);
00335   }
00336 
00337   template <uint dim, typename T>
00338   bool MultiArray<dim, T>::isElm(uint i[dim]) const {
00339     commute(i);
00340     typename std::map<uint, MultiArray<dim-1, T> >::const_iterator j = 
00341       data_.find(i[0]);
00342     if (j == data_.end())
00343       return false;
00344     else return j->second.isElm(i+1);
00345   }
00346 
00347   template <uint dim, typename T>
00348   void MultiArray<dim, T>::commute(uint i[dim]) const {
00349     if (commutable_) {
00350       for(uint j=1; j < dim; ++j) {
00351   if (i[j] < i[0]) std::swap(i[0],i[j]);
00352       }
00353       DEBUGL(MultiArrayCommute_D, MultiIndex<dim>(i));
00354     }
00355   }
00356 
00357   template <uint dim, typename T>
00358   void MultiArray<dim, T>::erase(const uint i[dim]) {
00359     uint I[dim];
00360     memorycpy(I, i, dim);
00361     erase(I);
00362   }
00363 
00364   template <uint dim, typename T>
00365   void MultiArray<dim, T>::erase(uint i[dim]) {
00366     commute(i);
00367     DEBUGL(MultiArrayErase_D, "Erase (" << Array<uint>(i,dim) << ")");
00368     typename std::map<uint, MultiArray<dim-1, T> >::iterator j = 
00369       data_.find(i[0]);
00370     if (j == data_.end())
00371       throw conceptsException(IndexNotExisting());
00372     DEBUGL(MultiArrayErase_D, j->second);    
00373     j->second.erase(i+1);
00374     DEBUGL(MultiArrayErase_D, j->second);
00375     if (j->second.size()==0)
00376       data_.erase(i[0]);
00377   }
00378 
00379   template <uint dim, typename T>
00380   uint MultiArray<dim, T>::size() const {
00381     uint size = 0;
00382     typename std::map<uint, MultiArray<dim-1, T> >::const_iterator j = 
00383       data_.begin();
00384     for(;j != data_.end();++j)
00385       size += j->second.size();
00386     return size;
00387   }
00388 
00389   template <uint dim, typename T>
00390   void MultiArray<dim, T>::clear() {
00391     typename std::map<uint, MultiArray<dim-1, T> >::iterator j = data_.begin();
00392     for(;j != data_.end();++j)
00393       j->second.clear();
00394     data_.clear();
00395   }
00396 
00397   template <uint dim, typename T>
00398   std::ostream& MultiArray<dim, T>::info(std::ostream& os) const {
00399     uint size = this->size();
00400     os << "MultiArray<" << dim << ",T>(" << size << ", ";
00401     if (commutable_) os << "yes";
00402     else os << "no";
00403     if (size > 0) {
00404       os << ",[";
00405       typename std::map<uint, MultiArray<dim-1, T> >::const_iterator j0 = data_.begin();
00406       for(;j0 != data_.end();) {
00407 #if MultiArrayInfo
00408   DEBUGL(MultiArrayScanner_D,j0->first << ", " << j0->second);
00409   os << "(" << j0->first << ", " << j0->second << ")";
00410 #else
00411   // does not function, ++-Operator doesn't work
00412   std::auto_ptr<Scanner> sc(scan());
00413   while (!sc->eos()) {
00414     os << (*sc)++;
00415     if (!sc->eos()) os << ", ";
00416   }
00417 #endif
00418   if (++j0 != data_.end()) os << ", ";
00419       }
00420       os << "]";
00421     }
00422     return os << ")";
00423   }
00424 
00425   // ******************************************************* MultiArray<1,T> **
00426 
00431   template <typename T>
00432   class MultiArray<1,T> : public OutputOperator {
00433   public:
00436     class Scanner  {
00437     public:
00438       Scanner(const MultiArray<1,T> array) : i_(array.data_.begin()), 
00439                end_(array.data_.end()) {}
00440       Scanner(const Scanner& scan) : i_(scan.i_), end_(scan.end_) {}
00441       bool eos() const { return i_ == end_; }
00442       const MultiEntrance<1,T> operator()() const {
00443   return MultiEntrance<1,T>(i_->first, i_->second);
00444       }
00445       const MultiEntrance<1,T> operator++(int) {
00446   // avoid taking the next entrance if you are at the end
00447   conceptsAssert(!eos(), Assertion());
00448   // take the current entrance
00449   const MultiEntrance<1,T> tmp(i_->first, i_->second);
00450   i_++;
00451   return tmp;
00452       }
00453       Scanner* clone() const { return new Scanner(*this); }
00454     private:
00458       typename std::map<uint, T>::const_iterator i_;
00459       typename std::map<uint, T>::const_iterator end_;
00460     };
00461     
00467     MultiArray(bool commutable = false) {}
00468     ~MultiArray() { clear(); }
00476     T& operator [](const uint i[1]) { return data_[i[0]]; }
00481     const T& operator [](const uint i[1]) const { return (*this)[i[0]];}
00489     T& operator [](const uint i) { return data_[i]; }
00494     const T& operator [](const uint i) const;
00496     Scanner* scan() const { return new Scanner(*this); }
00499     bool isElm(const uint i[1]) const { return isElm(i[0]); }
00500     bool isElm(const uint i) const;
00503     inline void erase(const uint i[1]) { erase(i[0]); }
00504     inline void erase(uint i) { 
00505       DEBUGL(MultiArrayErase_D, "Erase (" << i << ")");
00506       data_.erase(i);
00507     }
00509     uint size() const { return data_.size(); }
00510 
00512     inline void clear() { data_.clear(); }
00513   protected:
00514     virtual std::ostream& info(std::ostream& os) const;
00515   private:
00517     std::map<uint, T> data_;
00518   };
00519 
00520   template <typename T>
00521   const T& MultiArray<1, T>::operator[](const uint i) const {
00522     typename std::map<uint, T>::const_iterator j = data_.find(i);
00523     if (j == data_.end())
00524       throw conceptsException(IndexNotExisting());
00525     return j->second;
00526   }
00527 
00528   template <typename T>
00529   bool MultiArray<1, T>::isElm(const uint i) const {
00530     typename std::map<uint, T>::const_iterator j = data_.find(i);
00531     return (j != data_.end());
00532   }
00533 
00534   template <typename T>
00535   std::ostream& MultiArray<1,T>::info(std::ostream& os) const {
00536     uint size = this->size();
00537     os << "MultiArray<1,T>(" << size;
00538     if (size > 0) {
00539       os << ",[";
00540       std::auto_ptr<Scanner> sc(scan());
00541       while (!sc->eos()) {
00542         os << (*sc)++;
00543         if (!sc->eos()) os << ", ";
00544       }
00545       os << "]";
00546     }
00547     return os << ")";
00548   }
00549 
00550 } // namespace concepts
00551 
00552 #endif // multiarray_hh

Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)