• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

/data/development/ViennaCL/dev/viennacl/tools/adapter.hpp

Go to the documentation of this file.
00001 #ifndef VIENNACL_TOOLS_ADAPTER_HPP_
00002 #define VIENNACL_TOOLS_ADAPTER_HPP_
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2011, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008 
00009                             -----------------
00010                   ViennaCL - The Vienna Computing Library
00011                             -----------------
00012 
00013    Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at
00014                
00015    (A list of authors and contributors can be found in the PDF manual)
00016 
00017    License:         MIT (X11), see file LICENSE in the base directory
00018 ============================================================================= */
00019 
00024 #include <string>
00025 #include <fstream>
00026 #include <sstream>
00027 #include <assert.h>
00028 #include "viennacl/forwards.h"
00029 
00030 #include <vector>
00031 #include <map>
00032 
00033 namespace viennacl
00034 {
00035   namespace tools
00036   {
00037     
00046     template <typename SCALARTYPE, bool is_iterator1, bool is_forward>
00047     class const_sparse_matrix_adapted_iterator
00048     {
00049       typedef const_sparse_matrix_adapted_iterator<SCALARTYPE, is_iterator1, is_forward>    self_type;
00050       
00051       public:
00052         typedef self_type     iterator1;
00053         typedef self_type     iterator2;
00054         typedef std::size_t   size_type;
00055         
00056         const_sparse_matrix_adapted_iterator(std::vector<std::map<unsigned int, SCALARTYPE> > const & mat, int i, int j)
00057          : _mat(mat), _i(i), _j(j)
00058         {
00059           if (i < 0) //reverse iterator end
00060           {
00061             //iter2 = _mat[0].rend();  //reverse iterator end
00062           }
00063           else  //_i is valid
00064           {
00065             if (j < 0)
00066             {
00067               //iter2 = _mat[i].rend();
00068             }
00069             else //_j is valid
00070             {
00071               if (_i < _mat.size() && _mat[i].size() > 0 )
00072               {
00073                 //TODO: Start at entry j, not at the beginning
00074                 if (static_cast<int>(_mat[i].rbegin()->first) < j)
00075                   iter2 = _mat[i].end();
00076                 else
00077                   iter2 = _mat[i].begin();
00078               }
00079               else if (_i < _mat.size() && _mat[i].size() == 0)
00080                 iter2 = _mat[i].end();
00081               else //i is out of range -> end iterator requested
00082                 iter2 = _mat.back().end(); //forward iterator end
00083             }
00084           }
00085         }
00086          
00087         SCALARTYPE operator*(void) const
00088         {
00089           if (is_iterator1)
00090           {
00091             typedef typename std::map<unsigned int, SCALARTYPE>::const_iterator  col_iterator;
00092             
00093             col_iterator colit = _mat[_i].find(_j);
00094 
00095             if (colit != _mat[_i].end())
00096               return colit->second;
00097             return 0.0;
00098           }
00099           else
00100             return iter2->second;
00101         }
00102         
00103         self_type & operator++(void)
00104         {
00105           if (is_iterator1)
00106           {
00107             if (is_forward)
00108               ++_i;
00109             else
00110               --_i;
00111           }
00112           else
00113             ++iter2;
00114           return *this;
00115         }
00116         self_type & operator++(int) { self_type tmp = *this; ++(*this); return tmp; }
00117         
00118         self_type operator+=(unsigned int offset)
00119         {
00120           if (is_iterator1)
00121           {
00122             if (is_forward)
00123               _i += offset;
00124             else
00125               _i -= offset;
00126           }
00127           else
00128           {
00129             for (unsigned int k=0; k<offset; ++k)
00130               ++iter2;  //Note: User must ensure that this is always valid...
00131           }
00132           return *this;
00133         }
00134         
00135         bool operator==(self_type const & other) const
00136         {
00137           if (is_iterator1)
00138             return (_i == other._i);
00139           return (iter2 == other.iter2);
00140         }
00141         
00142         bool operator!=(self_type const & other) const { return !(*this == other); }
00143         
00144         int index1() const { return _i; }
00145         int index2() const
00146         { 
00147           if (is_iterator1)
00148             return 0;
00149           else
00150             return iter2->first;
00151         }
00152         
00153         const_sparse_matrix_adapted_iterator<SCALARTYPE, !is_iterator1, true> begin() const
00154         {
00155           return const_sparse_matrix_adapted_iterator<SCALARTYPE, !is_iterator1, true>(_mat, _i, 0);
00156         }
00157         const_sparse_matrix_adapted_iterator<SCALARTYPE, !is_iterator1, true> end() const
00158         {
00159           int end_ = static_cast<int>(_mat[_i].size());
00160           if (end_ > 0)
00161             end_ = _mat[_i].rbegin()->first;
00162           return const_sparse_matrix_adapted_iterator<SCALARTYPE, !is_iterator1, true>(_mat, _i, end_ + 1);
00163         }
00164         
00165       private:
00166         std::vector<std::map<unsigned int, SCALARTYPE> > const & _mat;
00167         typename std::map<unsigned int, SCALARTYPE>::const_iterator iter2;
00168         size_type _i;
00169         size_type _j;
00170     };
00171     
00176     template <typename SCALARTYPE>
00177     class const_sparse_matrix_adapter
00178     {
00179       public:
00180         typedef const_sparse_matrix_adapted_iterator<SCALARTYPE, true, true>      const_iterator1;
00181         typedef const_sparse_matrix_adapted_iterator<SCALARTYPE, false, true>     const_iterator2;
00182 
00183         typedef const_sparse_matrix_adapted_iterator<SCALARTYPE, true, false>   const_reverse_iterator1;
00184         typedef SCALARTYPE    value_type;
00185         typedef std::size_t   size_type;
00186         
00187         const_sparse_matrix_adapter(std::vector<std::map<unsigned int, SCALARTYPE> > const & mat) 
00188          : _mat(mat) {};
00189         
00190         size_type size1() const { return _mat.size(); }
00191         size_type size2() const { return _mat.size(); }
00192         //size_type size2() const { return (_mat.size() > 0) ? _mat.back().size() : 0; }
00193 
00194         const_iterator1 begin1() const { return const_iterator1(_mat, 0, 0); }
00195         const_iterator1 end1() const   { return const_iterator1(_mat, size1(), size2()); }
00196 
00197         const_reverse_iterator1 rbegin1() const { return const_reverse_iterator1(_mat, size1() - 1, 0); }
00198         const_reverse_iterator1 rend1() const   { return const_reverse_iterator1(_mat, -1, size2()); }
00199 
00200         const_iterator2 begin2() const { return const_iterator2(_mat, 0, 0); }
00201         const_iterator2 end2() const   { return const_iterator2(_mat, size1(), size2()); }
00202 
00203         SCALARTYPE operator()(unsigned int i, unsigned int j) const
00204         {
00205           typedef typename std::map<unsigned int, SCALARTYPE>::const_iterator  col_iterator;
00206           
00207           col_iterator colit = _mat[i].find(j);
00208 
00209           if (colit != _mat[i].end())
00210             return colit->second;
00211           return 0.0;
00212         }
00213 
00214       private:
00215         std::vector<std::map<unsigned int, SCALARTYPE> > const & _mat;
00216     };
00217     
00218     
00226     template <typename SCALARTYPE, bool is_iterator1>
00227     class sparse_matrix_adapted_iterator
00228     {
00229       typedef sparse_matrix_adapted_iterator<SCALARTYPE, is_iterator1>    self_type;
00230       
00231       public:
00232         typedef self_type     iterator1;
00233         typedef self_type     iterator2;
00234         
00235         sparse_matrix_adapted_iterator(std::vector<std::map<unsigned int, SCALARTYPE> > & mat, int i, int j)
00236          : _mat(mat), _i(i), _j(j)
00237         {
00238           if (i < 0) //reverse iterator end
00239           {
00240             //iter2 = _mat[0].rend();  //reverse iterator end
00241           }
00242           else  //_i is valid
00243           {
00244             if (j < 0)
00245             {
00246               //iter2 = _mat[i].rend();
00247             }
00248             else //_j is valid
00249             {
00250               if (_i < _mat.size() && _mat[i].size() > 0 )
00251               {
00252                 //TODO: Start at entry j, not at the beginning
00253                 if (static_cast<int>(_mat[i].rbegin()->first) < j)
00254                   iter2 = _mat[i].end();
00255                 else
00256                   iter2 = _mat[i].begin();
00257               }
00258               else if (_i < _mat.size() && _mat[i].size() == 0)
00259                 iter2 = _mat[i].end();
00260               else //i is out of range -> end iterator requested
00261                 iter2 = _mat.back().end(); //forward iterator end
00262             }
00263           }
00264         }
00265          
00266         SCALARTYPE & operator*(void)
00267         {
00268           if (is_iterator1)
00269           {
00270             return _mat[_i][_j];
00271           }
00272           else
00273             return iter2->second;
00274         }
00275         
00276         self_type & operator++(void)
00277         {
00278           if (is_iterator1)
00279             ++_i;
00280           else
00281             ++iter2;
00282           return *this;
00283         }
00284         self_type & operator++(int) { self_type tmp = *this; ++(*this); return tmp; }
00285         
00286         self_type operator+=(unsigned int offset)
00287         {
00288           if (is_iterator1)
00289             _i += offset;
00290           else
00291           {
00292             for (unsigned int k=0; k<offset; ++k)
00293               ++iter2;  //Note: User must ensure that this is always valid...
00294           }
00295           return *this;
00296         }
00297         
00298         bool operator==(self_type const & other) const
00299         {
00300           if (is_iterator1)
00301             return (_i == other._i);
00302           return (iter2 == other.iter2);
00303         }
00304         bool operator!=(self_type const & other) const { return !(*this == other); }
00305         
00306         unsigned int index1() const { return _i; }
00307         unsigned int index2() const
00308         { 
00309           if (is_iterator1)
00310             return 0;
00311           else
00312             return iter2->first;
00313         }
00314         
00315         sparse_matrix_adapted_iterator<SCALARTYPE, !is_iterator1> begin() const
00316         {
00317           return sparse_matrix_adapted_iterator<SCALARTYPE, !is_iterator1>(_mat, _i, 0);
00318         }
00319         sparse_matrix_adapted_iterator<SCALARTYPE, !is_iterator1> end() const
00320         {
00321           int end_ = static_cast<int>(_mat[_i].size());
00322           if (end_ > 0)
00323             end_ = _mat[_i].rbegin()->first;
00324           return sparse_matrix_adapted_iterator<SCALARTYPE, !is_iterator1>(_mat, _i, end_ + 1);
00325         }
00326         
00327       private:
00328         std::vector<std::map<unsigned int, SCALARTYPE> > & _mat;
00329         typename std::map<unsigned int, SCALARTYPE>::iterator iter2;
00330         unsigned int _i;
00331         unsigned int _j;
00332     };
00333     
00334     
00335     
00340     template <typename SCALARTYPE>
00341     class sparse_matrix_adapter : public const_sparse_matrix_adapter<SCALARTYPE>
00342     {
00343         typedef const_sparse_matrix_adapter<SCALARTYPE>   BaseType;
00344       public:
00345         typedef sparse_matrix_adapted_iterator<SCALARTYPE, true>      iterator1;
00346         typedef sparse_matrix_adapted_iterator<SCALARTYPE, false>     iterator2;
00347         
00348         sparse_matrix_adapter(std::vector<std::map<unsigned int, SCALARTYPE> > & mat) 
00349          : BaseType(mat), _mat(mat) { };
00350         
00351         iterator1 begin1() { return iterator1(_mat, 0, 0); }
00352         iterator1 end1() { return iterator1(_mat, _mat.size(), _mat.back().size()); }
00353 
00354         iterator2 begin2() { return iterator2(_mat, 0, 0); }
00355         iterator2 end2() { return iterator2(_mat, _mat.size(), _mat.back().size()); }
00356         
00357         SCALARTYPE & operator()(unsigned int i, unsigned int j) { return _mat[i][j]; }
00358         
00359         void resize(unsigned int i, unsigned int j, bool preserve = true)
00360         {
00361           if (i>0)
00362             _mat.resize(i);
00363           if (!preserve)
00364             clear();
00365         }
00366         
00367         void clear()
00368         {
00369           for (unsigned int i=0; i<_mat.size(); ++i)
00370             _mat[i].clear();
00371         }
00372         
00373         size_t size1() { return _mat.size(); }
00374         size_t size1() const { return _mat.size(); } //Note: Due to name hiding it is not sufficient to have it in the base class
00375         
00376         //assume a square matrix
00377         size_t size2() { return (_mat.size() > 0) ? (_mat.back().size() > 0 ? _mat.back().size() : _mat.size()) : 0; }
00378         size_t size2() const { return (_mat.size() > 0) ? (_mat.back().size() > 0 ? _mat.back().size() : _mat.size()) : 0; } //Note: Due to name hiding it is not sufficient to have it in the base class
00379         
00380       private:
00381         std::vector<std::map<unsigned int, SCALARTYPE> > & _mat;
00382     };
00383     
00384 
00385   }
00386 }
00387 #endif

Generated on Fri Dec 30 2011 23:20:43 for ViennaCL - The Vienna Computing Library by  doxygen 1.7.1