00001 #ifndef VIENNACL_TOOLS_ADAPTER_HPP_
00002 #define VIENNACL_TOOLS_ADAPTER_HPP_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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)
00060 {
00061
00062 }
00063 else
00064 {
00065 if (j < 0)
00066 {
00067
00068 }
00069 else
00070 {
00071 if (_i < _mat.size() && _mat[i].size() > 0 )
00072 {
00073
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
00082 iter2 = _mat.back().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;
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
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)
00239 {
00240
00241 }
00242 else
00243 {
00244 if (j < 0)
00245 {
00246
00247 }
00248 else
00249 {
00250 if (_i < _mat.size() && _mat[i].size() > 0 )
00251 {
00252
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
00261 iter2 = _mat.back().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;
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(); }
00375
00376
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; }
00379
00380 private:
00381 std::vector<std::map<unsigned int, SCALARTYPE> > & _mat;
00382 };
00383
00384
00385 }
00386 }
00387 #endif