BALL  1.4.1
diagonalIterator.h
Go to the documentation of this file.
00001 #ifndef BALL_LINALG_DIAGONALITERATOR_H
00002 #define BALL_LINALG_DIAGONALITERATOR_H
00003 
00004 #ifndef BALL_LINALG_MATRIX_IH
00005 # include <BALL/MATHS/LINALG/matrix.ih>
00006 #endif
00007 
00008 #ifndef BALL_LINALG_VECTOR_IH
00009 # include <BALL/MATHS/vector.ih>
00010 #endif
00011 
00012 #ifndef BALL_CONCEPT_RANDOMACCESSITERATOR_H
00013 #include <BALL/CONCEPT/randomAccessIterator.h>
00014 #endif
00015 
00016 namespace BALL {
00017 
00018   // forward declaration
00019   template <class valuetype, class mtraits>
00020   class Matrix;
00021 
00022   
00023   template <class valuetype, class mtraits=StandardTraits>
00024   class DiagonalIteratorTraits
00025   {
00028     typedef valuetype ValueType;
00029 
00032     typedef valuetype* PointerType;
00033 
00036     typedef int IteratorPosition;
00037 
00040     typedef int Distance;
00041 
00044     typedef int Index;
00045 
00046       friend class Matrix<valuetype, mtraits>;
00047     public:
00048 
00049       virtual ~DiagonalIteratorTraits()
00050       {
00051       }
00052 
00053       DiagonalIteratorTraits()
00054         : bound_(0),
00055           position_(0),
00056           vector_(0)
00057       {
00058       }
00059       
00060       DiagonalIteratorTraits(const Matrix<valuetype, mtraits>& matrix)
00061         : bound_(const_cast<Matrix<valuetype, mtraits>*>(&matrix)),
00062           position_(0),
00063           vector_(bound_->m_)
00064       {
00065       }
00066       
00067       DiagonalIteratorTraits(const DiagonalIteratorTraits& traits)
00068         : bound_(traits.bound_),
00069           position_(traits.position_),
00070           vector_(bound_->m_)
00071       {
00072       }
00073       
00074       DiagonalIteratorTraits& operator = (const DiagonalIteratorTraits& traits)
00075       {
00076         bound_ = traits.bound_;
00077         position_ = traits.position_;
00078         vector_ = traits.vector_;
00079     
00080         return *this;
00081       }
00082 
00083       Matrix<valuetype, mtraits>* getContainer()
00084       {
00085         return bound_;
00086       }
00087       
00088       const Matrix<valuetype, mtraits>* getContainer() const
00089       {
00090         return bound_;
00091       }
00092       
00093       bool isSingular() const
00094       {
00095         return (bound_ == 0);
00096       }
00097       
00098       IteratorPosition& getPosition()
00099       {
00100         return position_;
00101       }
00102 
00103       const IteratorPosition& getPosition() const
00104       {
00105         return position_;
00106       }
00107 
00108       bool operator == (const DiagonalIteratorTraits& traits) const
00109       {
00110         return (position_ == traits.position_);
00111       }
00112 
00113       bool operator != (const DiagonalIteratorTraits& traits) const
00114       {
00115         return (position_ != traits.position_);
00116       }
00117         
00118       bool operator < (const DiagonalIteratorTraits& traits) const
00119       {
00120         if (bound_->row_major_)
00121         {
00122           return (((position_ / bound_->m_) > (traits.position_ / traits.bound_->m_)) &&
00123             ((position_ % bound_->m_) < (traits.position_ % traits.bound_->m_)));
00124         }
00125         else
00126         {
00127           return (((position_ % bound_->n_) > (traits.position_ % traits.bound_->n_)) &&
00128             ((position_ / bound_->n_) < (traits.position_ / traits.bound_->n_)));
00129         }
00130       }
00131 
00132       Distance getDistance(const DiagonalIteratorTraits& traits) const
00133       {
00134         return (Distance)(position_ - traits.position_);
00135       }
00136       
00137       bool isValid() const
00138       {
00139         return ((bound_ != 0) && (position_ >= 0) && (position_ < (int)bound_->data_.size()));
00140       }
00141 
00142       void invalidate()
00143       {
00144         bound_ = 0;
00145         position_ = -1;
00146       }
00147       
00148       void toBegin()
00149       {
00150         if (bound_->row_major_)
00151         {
00152           position_ = bound_->data_.size() - bound_->m_;
00153         }
00154         else
00155         {
00156           position_ = (bound_->n_ - 1);
00157         }
00158       }
00159 
00160       bool isBegin() const
00161       {
00162         if (bound_->row_major_)
00163         {
00164           return (position_ == (int)(bound_->data_.size() - bound_->m_));
00165         }
00166         else
00167         {
00168           return (position_ == (int)(bound_->n_ - 1));
00169         }
00170       }
00171 
00172       void toEnd()
00173       {
00174         if (bound_->row_major_)
00175         {
00176           position_ = bound_->m_;
00177         }
00178         else
00179         {
00180           position_ = bound_->data_.size();
00181         }
00182       }
00183       
00184       bool isEnd() const
00185       {
00186         if (bound_->row_major_)
00187         {
00188           return (position_ == (int)bound_->m_);
00189         }
00190         else
00191         {
00192           return (position_ == (int)bound_->data_.size());
00193         }
00194       }
00195       
00196       Vector<valuetype>& getData()
00197       {
00198 
00199         if (bound_->row_major_)
00200         {
00201           // calculate the size of the current diagonalvector
00202           uint vector_size = std::min(bound_->n_-(position_ / bound_->m_), bound_->m_-(position_ % bound_->m_));
00203           vector_.resize(vector_size);
00204           uint i = 0;
00205           for (uint j = 0; j < vector_size; j++)
00206           {
00207             vector_[j]=(*bound_)[position_+i];
00208             i+=bound_->m_+1;
00209           }
00210         }
00211         else
00212         {
00213           // calculate the size of the current diagonalvector
00214           uint vector_size = std::min(bound_->n_-(position_ % bound_->n_), bound_->m_-(position_ / bound_->n_));
00215           vector_.resize(vector_size);
00216           uint j = 0;
00217           for (uint i = 0; position_+i < bound_->data_.size(); i+=bound_->n_)
00218           {
00219             vector_[j++]=(*bound_)[position_+i];
00220             i++;
00221           }
00222         }
00223 
00224         return vector_;
00225       }
00226 
00227       const Vector<valuetype>& getData() const
00228       {
00229         if (bound_->row_major_)
00230         {
00231 
00232           // calculate the size of the current diagonalvector
00233           uint vector_size = std::min(bound_->n_-(position_ / bound_->m_), bound_->m_-(position_ % bound_->m_));
00234           vector_.resize(vector_size);
00235           uint i = 0;
00236           for (uint j = 0; j < vector_size; j++)
00237           {
00238             vector_[j]=(*bound_)[position_+i];
00239             i+=bound_->m_+1;
00240           }
00241         }
00242         else
00243         {
00244           // calculate the size of the current diagonalvector
00245           uint vector_size = std::min(bound_->n_-(position_ % bound_->n_), bound_->m_-(position_ / bound_->n_));
00246           vector_.resize(vector_size);
00247           uint j = 0;
00248           for (uint i = 0; position_+i < bound_->data_.size(); i+=bound_->n_)
00249           {
00250             vector_[j++]=(*bound_)[position_+i];
00251             i++;
00252           }
00253         }
00254 
00255         return vector_;
00256 
00257       }
00258 
00259       void forward()
00260       {
00261         int i,j;
00262         if (bound_->row_major_)
00263         {
00264           i = position_ / bound_->m_;
00265           j = position_ % bound_->m_;
00266         }
00267         else
00268         {
00269           i = position_ % bound_->n_;
00270           j = position_ / bound_->n_;
00271         }
00272 
00273         if (i != 0)
00274         {
00275           i--;
00276         } else
00277         {
00278           j++;
00279         }
00280         if (bound_->row_major_)
00281         {
00282           position_ = j + bound_->m_*i;
00283         }
00284         else
00285         {
00286           position_ = i + bound_->n_*j;
00287         }
00288       }
00289 
00290       friend std::ostream& operator << (std::ostream& s, const DiagonalIteratorTraits& traits)
00291       {
00292         return (s << traits.position_ << ' ');
00293       }
00294       
00295       void dump(std::ostream& s) const
00296       {
00297         s << position_ << std::endl;
00298       }
00299       
00300       void toRBegin()
00301       {
00302         if (bound_->row_major_)
00303         {
00304           position_ = (bound_->m_ - 1);
00305         }
00306         else
00307         {
00308           position_ = bound_->data_.size() - bound_->n_;
00309         }
00310       }
00311       
00312       bool isRBegin() const
00313       {
00314         if (bound_->row_major_)
00315         {
00316           return (position_ == (int)(bound_->m_ - 1));
00317         }
00318         else
00319         {
00320           return (position_ == (int)(bound_->data_.size() - bound_->n_));
00321         }
00322       }
00323       
00324       void toREnd()
00325       {
00326         if (bound_->row_major_)
00327         {
00328           position_ = bound_->data_.size();
00329         }
00330         else
00331         {
00332           position_ = bound_->n_;
00333         }
00334       }
00335 
00336       bool isREnd() const
00337       {
00338         if (bound_->row_major_)
00339         {
00340           return (position_ == (int)bound_->data_.size());
00341         }
00342         else
00343         {
00344           return  (position_ == (int)bound_->n_);
00345         }
00346       }
00347       
00348       void backward()
00349       {
00350 
00351         int i,j;
00352         if (bound_->row_major_)
00353         {
00354           if (position_ == (int)bound_->m_)
00355           {
00356             position_--;
00357             return;
00358           }
00359           i = position_ / bound_->m_;
00360           j = position_ % bound_->m_;
00361         }
00362         else
00363         {
00364           i = position_ % bound_->n_;
00365           j = position_ / bound_->n_;
00366         }
00367         if (j != 0)
00368         {
00369           j--;
00370         } else
00371         {
00372           i++;
00373         }
00374         if (bound_->row_major_)
00375         {
00376           position_ = j + bound_->m_*i;
00377         }
00378         else
00379         {
00380           position_ = i + bound_->n_*j;
00381         }
00382 
00383       }
00384 
00385       void backward(Distance distance)
00386       {
00387         int i,j;
00388         if (bound_->row_major_)
00389         {
00390           if (position_ == (int)bound_->m_)
00391           {
00392             position_--;
00393             distance--;
00394           }
00395           i = position_ / bound_->m_;
00396           j = position_ % bound_->m_;
00397         }
00398         else
00399         {
00400           i = position_ % bound_->n_;
00401           j = position_ / bound_->n_;
00402         }
00403 
00404         if (j-distance >= 0)
00405         {
00406           j-=distance;
00407         } else
00408         {
00409           j = 0;
00410           i += (distance - j);
00411         }
00412         if (bound_->row_major_)
00413         {
00414           position_ = j + bound_->m_*i;
00415         }
00416         else
00417         {
00418           position_ = i + bound_->n_*j;
00419         }
00420       }
00421 
00422       void forward(Distance distance)
00423       {
00424         
00425         int i,j;
00426         if (bound_->row_major_)
00427         {
00428           i = position_ / bound_->m_;
00429           j = position_ % bound_->m_;
00430         }
00431         else
00432         {
00433           i = position_ % bound_->n_;
00434           j = position_ / bound_->n_;
00435         }
00436 
00437         if (i-distance >= 0)
00438         {
00439           i-=distance;
00440         } else
00441         {
00442           i = 0;
00443           j += (distance - i);
00444         }
00445         if (bound_->row_major_)
00446         {
00447           position_ = j + bound_->m_*i;
00448         }
00449         else
00450         {
00451           position_ = i + bound_->n_*j;
00452         }
00453       }
00454       
00455       Vector<valuetype>& getData(Index index)
00456       {
00457         int i = bound_->n_ - 1;
00458         int j = 0;
00459         int position;
00460 
00461         if (i-index >= 0)
00462         {
00463           i-=index;
00464         } else
00465         {
00466           i = 0;
00467           j += (index - i);
00468         }
00469         if (bound_->row_major_)
00470         {
00471           position = j + bound_->m_*i;
00472         }
00473         else
00474         {
00475           position = i + bound_->n_*j;
00476         }
00477         if (bound_->row_major_)
00478         {
00479           // calculate the size of the current diagonalvector
00480           uint vector_size = std::min(bound_->n_-(position / bound_->m_), bound_->m_-(position % bound_->m_));
00481           vector_.resize(vector_size);
00482           uint i = 0;
00483           for (uint j = 0; j < vector_size; j++)
00484           {
00485             vector_[j]=(*bound_)[position+i];
00486             i+=bound_->m_+1;
00487           }
00488         }
00489         else
00490         {
00491           // calculate the size of the current diagonalvector
00492           uint vector_size = std::min(bound_->n_-(position % bound_->n_), bound_->m_-(position / bound_->n_));
00493           vector_.resize(vector_size);
00494           uint j = 0;
00495           for (uint i = 0; i < bound_->data_.size(); i+=bound_->n_)
00496           {
00497             vector_[j++]=(*bound_)[position+i];
00498             i++;
00499           }
00500         }
00501         
00502         return vector_;
00503       }
00504       
00505       const Vector<valuetype>& getData(Index index) const
00506       {
00507         int i = bound_->n_ - 1;
00508         int j = 0;
00509         int position;
00510 
00511         if (i-index >= 0)
00512         {
00513           i-=index;
00514         } else
00515         {
00516           i = 0;
00517           j += (index - i);
00518         }
00519         if (bound_->row_major_)
00520         {
00521           position = j + bound_->m_*i;
00522         }
00523         else
00524         {
00525           position = i + bound_->n_*j;
00526         }
00527         if (bound_->row_major_)
00528         {
00529           // calculate the size of the current diagonalvector
00530           uint vector_size = std::min(bound_->n_-(position / bound_->m_), bound_->m_-(position % bound_->m_));
00531           vector_.resize(vector_size);
00532           uint i = 0;
00533           for (uint j = 0; j < vector_size; j++)
00534           {
00535             vector_[j]=(*bound_)[position+i];
00536             i+=bound_->m_+1;
00537           }
00538         }
00539         else
00540         {
00541           // calculate the size of the current diagonalvector
00542           uint vector_size = std::min(bound_->n_-(position % bound_->n_), bound_->m_-(position / bound_->n_));
00543           vector_.resize(vector_size);
00544           uint j = 0;
00545           for (uint i = 0; i < bound_->data_.size(); i+=bound_->n_)
00546           {
00547             vector_[j++]=(*bound_)[position+i];
00548             i++;
00549           }
00550         }
00551         return vector_;
00552       }
00553       
00554 
00555       protected:
00556 
00557       Matrix<valuetype, mtraits>*   bound_;
00558       IteratorPosition    position_;
00559       mutable Vector<valuetype>           vector_;
00560     };
00561 
00562 
00563 } // namespace BALL
00564 
00565 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines