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 {
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
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
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
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
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
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
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
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
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 }
00564
00565 #endif