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