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