ivl 679
ivl/details/array_nd/impl/gslice_array.hpp
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations