LocARNA-1.9.2
|
00001 #ifndef LOCARNA_MATRICES_HH 00002 #define LOCARNA_MATRICES_HH 00003 00004 #ifdef HAVE_CONFIG_H 00005 #include <config.h> 00006 #endif 00007 00008 /* @file Define various generic matrix classes (with templated element 00009 type): simple matrix, matrix with range restriction, matrix with 00010 offset, rotatable matrix. 00011 */ 00012 00013 #include <iostream> 00014 #include <vector> 00015 #include <assert.h> 00016 00017 #include <algorithm> 00018 00019 #include "matrix.hh" 00020 00021 namespace LocARNA { 00022 00023 // ---------------------------------------- 00036 template <class elem_t> 00037 class RMatrix : public Matrix<elem_t> { 00038 typedef typename Matrix<elem_t>::size_type size_type; 00039 protected: 00040 size_type xl_; 00041 size_type xr_; 00042 size_type yl_; 00043 size_type yr_; 00044 00045 size_type xfactor_; 00046 size_type offset_; 00047 00057 size_type 00058 addr(size_type i, size_type j) const { 00059 assert(xl_ <= i && i <= xr_); 00060 assert(yl_ <= j && j <= yr_); 00061 00062 return i * xfactor_ + j - offset_; 00063 } 00064 00065 public: 00070 RMatrix() : Matrix<elem_t>() {} 00071 00081 void 00082 resize(size_type xdim, size_type ydim) { 00083 this->xdim_ = xdim; 00084 this->ydim_ = ydim; 00085 this->mat_.resize(xdim * ydim); 00086 00087 restrict(0, xdim - 1, 0, ydim - 1); 00088 } 00089 00098 void 00099 restrict(size_type xl, size_type xr, size_type yl, size_type yr) { 00100 assert(xl >= 0); 00101 assert(yl >= 0); 00102 assert(xr < this->xdim_); 00103 assert(yr < this->ydim_); 00104 assert(xl <= xr); 00105 assert(yl <= yr); 00106 00107 this->xl_ = xl; 00108 this->xr_ = xr; 00109 this->yl_ = yl; 00110 this->yr_ = yr; 00111 00112 this->xfactor_ = (yr - yl) + 1; 00113 this->offset_ = 0; 00114 this->offset_ = addr(xl, yl); 00115 } 00116 00126 const elem_t & 00127 operator()(size_type i, size_type j) const { 00128 return this->mat_[addr(i, j)]; 00129 } 00130 00140 elem_t & 00141 operator()(size_type i, size_type j) { 00142 return this->mat_[addr(i, j)]; 00143 } 00144 00154 const elem_t 00155 get(size_type i, size_type j) const { 00156 return this->mat_[addr(i, j)]; 00157 } 00158 00167 void 00168 set(size_type i, size_type j, const elem_t &x) { 00169 this->mat_[addr(i, j)] = x; 00170 } 00171 00178 void 00179 fill(const elem_t &val) { 00180 for (size_type i = xl_; i < xr_; ++i) 00181 for (size_type j = yl_; j < yr_; ++j) 00182 this->mat_(i, j) = val; 00183 } 00184 }; 00185 00186 // ---------------------------------------- 00188 template <class elem_t> 00189 class OMatrix : public Matrix<elem_t> { 00190 protected: 00191 size_t off_; 00192 size_t xoff_; 00193 size_t yoff_; 00194 00206 size_t 00207 addr(size_t i, size_t j) const { 00208 assert(xoff_ <= i && i < xoff_ + this->xdim_); 00209 assert(yoff_ <= j && j < yoff_ + this->ydim_); 00210 return i * this->ydim_ + j - off_; 00211 } 00212 00213 public: 00219 OMatrix() : Matrix<elem_t>(), off_(0), xoff_(0), yoff_(0) {} 00220 00229 void 00230 resize(size_t xdim, size_t ydim, size_t xoff = 0, size_t yoff = 0) { 00231 xoff_ = xoff; 00232 yoff_ = yoff; 00233 off_ = xoff * ydim + yoff; 00234 this->xdim_ = xdim; 00235 this->ydim_ = ydim; 00236 this->mat_.resize(xdim * ydim); 00237 } 00238 00248 const elem_t & 00249 operator()(size_t i, size_t j) const { 00250 return this->mat_[addr(i, j)]; 00251 } 00252 00262 elem_t & 00263 operator()(size_t i, size_t j) { 00264 return this->mat_[addr(i, j)]; 00265 } 00266 00276 const elem_t 00277 get(size_t i, size_t j) const { 00278 return this->mat_[addr(i, j)]; 00279 } 00280 00289 void 00290 set(size_t i, size_t j, const elem_t &x) { 00291 this->mat_[addr(i, j)] = x; 00292 } 00293 }; 00294 00295 // ---------------------------------------- 00298 template <class elem_t> 00299 class RotMatrix : public Matrix<elem_t> { 00300 protected: 00301 size_t xrot_; 00302 size_t yrot_; 00303 00313 size_t 00314 rot(size_t x, size_t r, size_t d) { 00315 assert(r < d); 00316 return (x + d - r) % d; 00317 } 00318 00330 size_t 00331 addr(size_t i, size_t j) const { 00332 assert(xrot_ <= i && i < xrot_ + this->xdim_); 00333 assert(yrot_ <= j && j < yrot_ + this->ydim_); 00334 return rot(i, xrot_, this->xdim_) * this->xdim_ + 00335 rot(j, yrot_, this->ydim_); 00336 } 00337 00338 public: 00344 RotMatrix() : Matrix<elem_t>(0), xrot_(0), yrot_(0) {} 00345 00354 void 00355 resize(size_t xdim, size_t ydim, size_t xrot = 0, size_t yrot = 0) { 00356 xrot_ = xrot; 00357 yrot_ = yrot; 00358 this->xdim_ = xdim; 00359 this->ydim_ = ydim; 00360 this->mat_.resize(xdim * ydim); 00361 } 00362 00370 void 00371 move(size_t xrot, size_t yrot) { 00372 xrot_ = xrot; 00373 yrot_ = yrot; 00374 } 00375 00385 const elem_t & 00386 operator()(size_t i, size_t j) const { 00387 return this->mat_[addr(i, j)]; 00388 } 00389 00399 elem_t & 00400 operator()(size_t i, size_t j) { 00401 return this->mat_[addr(i, j)]; 00402 } 00403 00413 const elem_t 00414 get(size_t i, size_t j) const { 00415 return this->mat_[addr(i, j)]; 00416 } 00417 00427 void 00428 set(size_t i, size_t j, const elem_t &x) { 00429 this->mat_[addr(i, j)] = x; 00430 } 00431 }; 00432 00433 } // end namespace LocARNA 00434 00435 #endif // LOCARNA_MATRICES_HH