BALL
1.4.1
|
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