ivl 679
|
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>. 00002 A C++ template library extending syntax towards mathematical notation. 00003 00004 Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr> 00005 Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr> 00006 00007 ivl is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU Lesser General Public License 00009 version 3 as published by the Free Software Foundation. 00010 00011 Alternatively, you can redistribute it and/or modify it under the terms 00012 of the GNU General Public License version 2 as published by the Free 00013 Software Foundation. 00014 00015 ivl is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00018 See the GNU General Public License for more details. 00019 00020 You should have received a copy of the GNU General Public License 00021 and a copy of the GNU Lesser General Public License along 00022 with ivl. If not, see <http://www.gnu.org/licenses/>. */ 00023 00024 #ifndef IVL_ARRAY_ND_DETAILS_GSLICE_ARRAY_HPP 00025 #define IVL_ARRAY_ND_DETAILS_GSLICE_ARRAY_HPP 00026 00027 #if 0 00028 namespace ivl { 00029 00030 //-------------------------------------------------------------- 00031 // CLASS gslice 00032 00034 class gslice 00035 { 00036 protected: 00037 template<class T, class S> friend class array; 00038 size_t start; 00039 size_array sizes; 00040 size_array strides; 00041 00042 template<class T, class S> friend class array_nd; 00043 00044 public: 00046 inline gslice() : start(0) { } 00047 00049 inline gslice(size_t off, const size_array& length_array, const size_array& stride_array) 00050 : start(off), sizes(length_array), strides(stride_array) { } 00051 00053 inline gslice(const array<slice>& as, size_array sz); // defined below 00054 00056 inline size_t offset(size_array& index_array) const; 00057 // return total length of generalized slice 00058 inline size_t length() const; 00059 00060 }; 00061 00062 00063 //-------------------------------------------------------------- 00064 // TEMPLATE CLASS gslice_array 00065 00067 template<class T> class gslice_array : public gslice 00068 { 00069 00070 private: 00071 template<class X,class Y> friend class array_nd; 00072 00074 gslice_array(const gslice& gsl, T *ptr) : gslice(gsl), base_ptr(ptr) { } 00075 00077 template <class S> 00078 gslice_array(const array<slice>& as, array_nd<T,S>& a) : gslice(as, a.sizes), base_ptr(a.base_ptr) { } 00079 00081 T *base_ptr; 00082 00083 public: 00084 gslice_array(); // not defined 00085 gslice_array(const gslice_array&); // not defined 00086 gslice_array& operator=(const gslice_array&); // not defined 00087 00088 void operator=(const array<T>& a) const; 00089 void operator=(const T& s) const; 00090 00091 void operator+=(const T& s) const; 00092 void operator-=(const T& s) const; 00093 void operator*=(const T& s) const; 00094 void operator/=(const T& s) const; 00095 void operator%=(const T& s) const; 00096 void operator^=(const T& s) const; 00097 void operator&=(const T& s) const; 00098 void operator|=(const T& s) const; 00099 void operator<<=(const T& s) const; 00100 void operator>>=(const T& s) const; 00101 00102 void operator+=(const array_nd<T>& a) const; 00103 void operator-=(const array_nd<T>& a) const; 00104 void operator*=(const array_nd<T>& a) const; 00105 void operator/=(const array_nd<T>& a) const; 00106 void operator%=(const array_nd<T>& a) const; 00107 void operator^=(const array_nd<T>& a) const; 00108 void operator&=(const array_nd<T>& a) const; 00109 void operator|=(const array_nd<T>& a) const; 00110 void operator<<=(const array_nd<T>& a) const; 00111 void operator>>=(const array_nd<T>& a) const; 00112 }; 00113 00114 00115 //-------------------------------------------------------------- 00116 // array_nd/glice_array MEMBER FUNCTIONS 00117 00118 00120 template<class T, class D> 00121 inline 00122 typename array_nd<T, D>::NewDerived array_nd<T, D>::operator()(const gslice& gsl) const 00123 { 00124 return array_nd<T, D>::NewDerived(gslice_array<T>(gsl, this->c_ptr())); 00125 } 00126 00128 template<class T, class D> 00129 inline 00130 gslice_array<T> array_nd<T, D>::operator()(const gslice& gsl) 00131 { 00132 return gslice_array<T>(gsl, this->c_ptr()); 00133 } 00134 00136 template<class T, class D> 00137 inline 00138 typename array_nd<T, D>::Derived& array_nd<T, D>::operator=(const gslice_array<T>& ga) 00139 { 00140 this->tidy(true); 00141 grow(ga.length()); 00142 ndim = ga.strides.size(); 00143 sizes = ga.sizes; 00144 strides = cumprod(shift(sizes, 1, size_t(1))); 00145 size_array index_array(ga.sizes.size(), (size_t)0); // to index_array einai to voh8htiko array (000,001,010,011 klp.) 00146 00147 for (size_t i = 0; i < this->length(); ++i) 00148 (*this)[i] = ga.base_ptr[ga.offset(index_array)]; 00149 00150 return derived(); 00151 } 00152 00153 00154 //-------------------------------------------------------------- 00155 // array_nd/array<slice> MEMBER FUNCTIONS 00156 00158 template<class T, class D> 00159 inline 00160 typename array_nd<T, D>::NewDerived array_nd<T, D>::operator()(const array<slice>& a) const 00161 { 00162 return typename array_nd<T, D>::NewDerived(gslice_array<T>(a, 00163 *const_cast<array_nd<T, D>* >(this))); 00164 } 00165 00167 template<class T, class D> 00168 inline 00169 gslice_array<T> array_nd<T, D>::operator()(const array<slice>& a) 00170 { 00171 return gslice_array<T>(a, *this); 00172 } 00173 00174 00175 // -------------------------------------------------------------- 00176 // GSLICE MEMBER FUNCTIONS 00177 00178 gslice::gslice(const array<slice>& as, size_array sz) 00179 { 00180 size_t a_len = as.length(); 00181 00182 size_array offsets(a_len); 00183 sizes = size_array(a_len); 00184 strides = size_array(a_len); 00185 00186 for (size_t i = 0; i < a_len; i++) { 00187 offsets[i] = as[i].start; 00188 sizes[i] = as[i].length; 00189 strides[i] = as[i].stride; 00190 } 00191 00192 size_array strd(cumprod(shift(sz,1, size_t(1)))); 00193 00194 size_array tmp = offsets * strd; 00195 00196 start = sum(tmp); 00197 } 00198 00200 size_t gslice::offset(size_array& index_array) const 00201 { 00202 size_t i, offs = start; 00203 00204 for (i = 0; i < index_array.size(); ++i) 00205 offs += index_array[i] * strides[i]; // compute offset 00206 00207 i = 0; 00208 while (i < index_array.size()) 00209 if (++index_array[i] < sizes[i]) break; // increment done, quit 00210 else index_array[i++] = 0; // carry to more-significant index 00211 return (offs); 00212 } 00213 00215 size_t gslice::length() const 00216 { 00217 if (sizes.size() == 0) 00218 return 0; 00219 00220 return prod(sizes); 00221 } 00222 00223 // -------------------------------------------------------------- 00224 // GSLICE_ARRAY MEMBER FUNCTIONS & OPERATORS 00225 00227 template <class T> 00228 void gslice_array<T>::operator=(const array<T>& a) const 00229 { 00230 size_array index_array(sizes.size(), (size_t)0); 00231 00232 for (size_t i = 0; i < (size_t) length(); ++i ) 00233 base_ptr[offset(index_array)] = a[i]; 00234 } 00235 00237 template <class T> 00238 void gslice_array<T>::operator=(const T& s) const 00239 { 00240 size_array index_array(sizes.size(), (size_t)0); 00241 00242 for (size_t i = 0; i < (size_t) length(); ++i ) 00243 base_ptr[offset(index_array)] = s; 00244 } 00245 00247 template <class T> 00248 void gslice_array<T>::operator+=(const T& s) const 00249 { 00250 size_array index_array(sizes.size(), (size_t)0); 00251 00252 for (size_t i = 0; i < (size_t) length(); ++i ) 00253 base_ptr[offset(index_array)] += s; 00254 } 00255 00257 template <class T> 00258 void gslice_array<T>::operator-=(const T& s) const 00259 { 00260 size_array index_array(sizes.size(), (size_t)0); 00261 00262 for (size_t i = 0; i < (size_t) length(); ++i ) 00263 base_ptr[offset(index_array)] -= s; 00264 } 00265 00267 template <class T> 00268 void gslice_array<T>::operator*=(const T& s) const 00269 { 00270 size_array index_array(sizes.size(), (size_t)0); 00271 for (size_t i = 0; i < (size_t) length(); ++i ) 00272 base_ptr[offset(index_array)] *= s; 00273 } 00274 00276 template <class T> 00277 void gslice_array<T>::operator/=(const T& s) const 00278 { 00279 size_array index_array(sizes.size(), (size_t)0); 00280 00281 for (size_t i = 0; i < (size_t) length(); ++i ) 00282 base_ptr[offset(index_array)] /= s; 00283 } 00284 00286 template <class T> 00287 void gslice_array<T>::operator%=(const T& s) const 00288 { 00289 size_array index_array(sizes.size(), (size_t)0); 00290 00291 for (size_t i = 0; i < (size_t) length(); ++i ) 00292 base_ptr[offset(index_array)] %= s; 00293 } 00294 00296 template <class T> 00297 void gslice_array<T>::operator^=(const T& s) const 00298 { 00299 size_array index_array(sizes.size(), (size_t)0); 00300 00301 for (size_t i = 0; i < (size_t) length(); ++i ) 00302 base_ptr[offset(index_array)] ^= s; 00303 } 00304 00306 template <class T> 00307 void gslice_array<T>::operator&=(const T& s) const 00308 { 00309 size_array index_array(sizes.size(), (size_t)0); 00310 00311 for (size_t i = 0; i < (size_t) length(); ++i ) 00312 base_ptr[offset(index_array)] &= s; 00313 } 00314 00316 template <class T> 00317 void gslice_array<T>::operator|=(const T& s) const 00318 { 00319 size_array index_array(sizes.size(), (size_t)0); 00320 00321 for (size_t i = 0; i < (size_t) length(); ++i ) 00322 base_ptr[offset(index_array)] |= s; 00323 } 00324 00326 template <class T> 00327 void gslice_array<T>::operator<<=(const T& s) const 00328 { 00329 size_array index_array(sizes.size(), (size_t)0); 00330 for (size_t i = 0; i < (size_t) length(); ++i ) 00331 base_ptr[offset(index_array)] <<= s; 00332 } 00333 00335 template <class T> 00336 void gslice_array<T>::operator>>=(const T& s) const 00337 { 00338 size_array index_array(sizes.size(), (size_t)0); 00339 for (size_t i = 0; i < (size_t) length(); ++i ) 00340 base_ptr[offset(index_array)] >>= s; 00341 } 00342 00344 template <class T> 00345 void gslice_array<T>::operator*=(const array_nd<T>& a) const 00346 { 00347 size_array index_array(sizes.size(), (size_t)0); 00348 00349 for (size_t i = 0; i < (size_t) length(); ++i ) 00350 base_ptr[offset(index_array)] *= a[i]; 00351 } 00352 00354 template <class T> 00355 void gslice_array<T>::operator/=(const array_nd<T>& a) const 00356 { 00357 size_array index_array(sizes.size(), (size_t)0); 00358 00359 for (size_t i = 0; i < (size_t) length(); ++i ) 00360 base_ptr[offset(index_array)] /= a[i]; 00361 } 00362 00364 template <class T> 00365 void gslice_array<T>::operator%=(const array_nd<T>& a) const 00366 { 00367 size_array index_array(sizes.size(), (size_t)0); 00368 00369 for (size_t i = 0; i < (size_t) length(); ++i ) 00370 base_ptr[offset(index_array)] %= a[i]; 00371 } 00372 00374 template <class T> 00375 void gslice_array<T>::operator+=(const array_nd<T>& a) const 00376 { 00377 size_array index_array(sizes.size(), (size_t)0); 00378 00379 for (size_t i = 0; i < (size_t) length(); ++i ) 00380 base_ptr[offset(index_array)] += a[i]; 00381 } 00382 00384 template <class T> 00385 void gslice_array<T>::operator-=(const array_nd<T>& a) const 00386 { 00387 size_array index_array(sizes.size(), (size_t)0); 00388 00389 for (size_t i = 0; i < (size_t) length(); ++i ) 00390 base_ptr[offset(index_array)] -= a[i]; 00391 } 00392 00394 template <class T> 00395 void gslice_array<T>::operator^=(const array_nd<T>& a) const 00396 { 00397 size_array index_array(sizes.size(), (size_t)0); 00398 00399 for (size_t i = 0; i < (size_t) length(); ++i ) 00400 base_ptr[offset(index_array)] ^= a[i]; 00401 } 00402 00404 template <class T> 00405 void gslice_array<T>::operator&=(const array_nd<T>& a) const 00406 { 00407 size_array index_array(sizes.size(), (size_t)0); 00408 00409 for (size_t i = 0; i < (size_t) length(); ++i ) 00410 base_ptr[offset(index_array)] &= a[i]; 00411 } 00412 00414 template <class T> 00415 void gslice_array<T>::operator|=(const array_nd<T>& a) const 00416 { 00417 size_array index_array(sizes.size(), (size_t)0); 00418 00419 for (size_t i = 0; i < (size_t) length(); ++i ) 00420 base_ptr[offset(index_array)] |= a[i]; 00421 } 00422 00424 template <class T> 00425 void gslice_array<T>::operator<<=(const array_nd<T>& a) const 00426 { 00427 size_array index_array(sizes.size(), (size_t)0); 00428 00429 for (size_t i = 0; i < (size_t) length(); ++i ) 00430 base_ptr[offset(index_array)] <<= a[i]; 00431 } 00432 00434 template <class T> 00435 void gslice_array<T>::operator>>=(const array_nd<T>& a) const 00436 { 00437 size_array index_array(sizes.size(), (size_t)0); 00438 00439 for (size_t i = 0; i < (size_t) length(); ++i ) 00440 base_ptr[offset(index_array)] >>= a[i]; 00441 } 00442 00443 } // namespace ivl 00444 #endif 00445 00446 #endif // IVL_ARRAY_ND_DETAILS_GSLICE_ARRAY_HPP 00447