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