ViennaCL - The Vienna Computing Library  1.2.0
adapter.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_TOOLS_ADAPTER_HPP_
2 #define VIENNACL_TOOLS_ADAPTER_HPP_
3 
4 /* =========================================================================
5  Copyright (c) 2010-2011, Institute for Microelectronics,
6  Institute for Analysis and Scientific Computing,
7  TU Wien.
8 
9  -----------------
10  ViennaCL - The Vienna Computing Library
11  -----------------
12 
13  Project Head: Karl Rupp rupp@iue.tuwien.ac.at
14 
15  (A list of authors and contributors can be found in the PDF manual)
16 
17  License: MIT (X11), see file LICENSE in the base directory
18 ============================================================================= */
19 
24 #include <string>
25 #include <fstream>
26 #include <sstream>
27 #include <assert.h>
28 #include "viennacl/forwards.h"
29 
30 #include <vector>
31 #include <map>
32 
33 namespace viennacl
34 {
35  namespace tools
36  {
37 
46  template <typename SCALARTYPE, bool is_iterator1, bool is_forward>
48  {
50 
51  public:
54  typedef std::size_t size_type;
55 
56  const_sparse_matrix_adapted_iterator(std::vector<std::map<unsigned int, SCALARTYPE> > const & mat, int i, int j)
57  : _mat(mat), _i(i), _j(j)
58  {
59  if (i < 0) //reverse iterator end
60  {
61  //iter2 = _mat[0].rend(); //reverse iterator end
62  }
63  else //_i is valid
64  {
65  if (j < 0)
66  {
67  //iter2 = _mat[i].rend();
68  }
69  else //_j is valid
70  {
71  if (_i < _mat.size() && _mat[i].size() > 0 )
72  {
73  //TODO: Start at entry j, not at the beginning
74  if (static_cast<int>(_mat[i].rbegin()->first) < j)
75  iter2 = _mat[i].end();
76  else
77  iter2 = _mat[i].begin();
78  }
79  else if (_i < _mat.size() && _mat[i].size() == 0)
80  iter2 = _mat[i].end();
81  else //i is out of range -> end iterator requested
82  iter2 = _mat.back().end(); //forward iterator end
83  }
84  }
85  }
86 
87  SCALARTYPE operator*(void) const
88  {
89  if (is_iterator1)
90  {
91  typedef typename std::map<unsigned int, SCALARTYPE>::const_iterator col_iterator;
92 
93  col_iterator colit = _mat[_i].find(_j);
94 
95  if (colit != _mat[_i].end())
96  return colit->second;
97  return 0.0;
98  }
99  else
100  return iter2->second;
101  }
102 
104  {
105  if (is_iterator1)
106  {
107  if (is_forward)
108  ++_i;
109  else
110  --_i;
111  }
112  else
113  ++iter2;
114  return *this;
115  }
116  self_type & operator++(int) { self_type tmp = *this; ++(*this); return tmp; }
117 
118  self_type operator+=(unsigned int offset)
119  {
120  if (is_iterator1)
121  {
122  if (is_forward)
123  _i += offset;
124  else
125  _i -= offset;
126  }
127  else
128  {
129  for (unsigned int k=0; k<offset; ++k)
130  ++iter2; //Note: User must ensure that this is always valid...
131  }
132  return *this;
133  }
134 
135  bool operator==(self_type const & other) const
136  {
137  if (is_iterator1)
138  return (_i == other._i);
139  return (iter2 == other.iter2);
140  }
141 
142  bool operator!=(self_type const & other) const { return !(*this == other); }
143 
144  int index1() const { return _i; }
145  int index2() const
146  {
147  if (is_iterator1)
148  return 0;
149  else
150  return iter2->first;
151  }
152 
154  {
156  }
158  {
159  int end_ = static_cast<int>(_mat[_i].size());
160  if (end_ > 0)
161  end_ = _mat[_i].rbegin()->first;
163  }
164 
165  private:
166  std::vector<std::map<unsigned int, SCALARTYPE> > const & _mat;
167  typename std::map<unsigned int, SCALARTYPE>::const_iterator iter2;
168  size_type _i;
169  size_type _j;
170  };
171 
176  template <typename SCALARTYPE>
178  {
179  public:
182 
184  typedef SCALARTYPE value_type;
185  typedef std::size_t size_type;
186 
187  const_sparse_matrix_adapter(std::vector<std::map<unsigned int, SCALARTYPE> > const & mat)
188  : _mat(mat) {};
189 
190  size_type size1() const { return _mat.size(); }
191  size_type size2() const { return _mat.size(); }
192  //size_type size2() const { return (_mat.size() > 0) ? _mat.back().size() : 0; }
193 
194  const_iterator1 begin1() const { return const_iterator1(_mat, 0, 0); }
195  const_iterator1 end1() const { return const_iterator1(_mat, size1(), size2()); }
196 
197  const_reverse_iterator1 rbegin1() const { return const_reverse_iterator1(_mat, size1() - 1, 0); }
199 
200  const_iterator2 begin2() const { return const_iterator2(_mat, 0, 0); }
201  const_iterator2 end2() const { return const_iterator2(_mat, size1(), size2()); }
202 
203  SCALARTYPE operator()(unsigned int i, unsigned int j) const
204  {
205  typedef typename std::map<unsigned int, SCALARTYPE>::const_iterator col_iterator;
206 
207  col_iterator colit = _mat[i].find(j);
208 
209  if (colit != _mat[i].end())
210  return colit->second;
211  return 0.0;
212  }
213 
214  private:
215  std::vector<std::map<unsigned int, SCALARTYPE> > const & _mat;
216  };
217 
218 
226  template <typename SCALARTYPE, bool is_iterator1>
228  {
230 
231  public:
234 
235  sparse_matrix_adapted_iterator(std::vector<std::map<unsigned int, SCALARTYPE> > & mat, int i, int j)
236  : _mat(mat), _i(i), _j(j)
237  {
238  if (i < 0) //reverse iterator end
239  {
240  //iter2 = _mat[0].rend(); //reverse iterator end
241  }
242  else //_i is valid
243  {
244  if (j < 0)
245  {
246  //iter2 = _mat[i].rend();
247  }
248  else //_j is valid
249  {
250  if (_i < _mat.size() && _mat[i].size() > 0 )
251  {
252  //TODO: Start at entry j, not at the beginning
253  if (static_cast<int>(_mat[i].rbegin()->first) < j)
254  iter2 = _mat[i].end();
255  else
256  iter2 = _mat[i].begin();
257  }
258  else if (_i < _mat.size() && _mat[i].size() == 0)
259  iter2 = _mat[i].end();
260  else //i is out of range -> end iterator requested
261  iter2 = _mat.back().end(); //forward iterator end
262  }
263  }
264  }
265 
266  SCALARTYPE & operator*(void)
267  {
268  if (is_iterator1)
269  {
270  return _mat[_i][_j];
271  }
272  else
273  return iter2->second;
274  }
275 
277  {
278  if (is_iterator1)
279  ++_i;
280  else
281  ++iter2;
282  return *this;
283  }
284  self_type & operator++(int) { self_type tmp = *this; ++(*this); return tmp; }
285 
286  self_type operator+=(unsigned int offset)
287  {
288  if (is_iterator1)
289  _i += offset;
290  else
291  {
292  for (unsigned int k=0; k<offset; ++k)
293  ++iter2; //Note: User must ensure that this is always valid...
294  }
295  return *this;
296  }
297 
298  bool operator==(self_type const & other) const
299  {
300  if (is_iterator1)
301  return (_i == other._i);
302  return (iter2 == other.iter2);
303  }
304  bool operator!=(self_type const & other) const { return !(*this == other); }
305 
306  unsigned int index1() const { return _i; }
307  unsigned int index2() const
308  {
309  if (is_iterator1)
310  return 0;
311  else
312  return iter2->first;
313  }
314 
316  {
318  }
320  {
321  int end_ = static_cast<int>(_mat[_i].size());
322  if (end_ > 0)
323  end_ = _mat[_i].rbegin()->first;
325  }
326 
327  private:
328  std::vector<std::map<unsigned int, SCALARTYPE> > & _mat;
329  typename std::map<unsigned int, SCALARTYPE>::iterator iter2;
330  unsigned int _i;
331  unsigned int _j;
332  };
333 
334 
335 
340  template <typename SCALARTYPE>
342  {
344  public:
347 
348  sparse_matrix_adapter(std::vector<std::map<unsigned int, SCALARTYPE> > & mat)
349  : BaseType(mat), _mat(mat) { };
350 
351  iterator1 begin1() { return iterator1(_mat, 0, 0); }
352  iterator1 end1() { return iterator1(_mat, _mat.size(), _mat.back().size()); }
353 
354  iterator2 begin2() { return iterator2(_mat, 0, 0); }
355  iterator2 end2() { return iterator2(_mat, _mat.size(), _mat.back().size()); }
356 
357  SCALARTYPE & operator()(unsigned int i, unsigned int j) { return _mat[i][j]; }
358 
359  void resize(unsigned int i, unsigned int j, bool preserve = true)
360  {
361  if (i>0)
362  _mat.resize(i);
363  if (!preserve)
364  clear();
365  }
366 
367  void clear()
368  {
369  for (unsigned int i=0; i<_mat.size(); ++i)
370  _mat[i].clear();
371  }
372 
373  size_t size1() { return _mat.size(); }
374  size_t size1() const { return _mat.size(); } //Note: Due to name hiding it is not sufficient to have it in the base class
375 
376  //assume a square matrix
377  size_t size2() { return (_mat.size() > 0) ? (_mat.back().size() > 0 ? _mat.back().size() : _mat.size()) : 0; }
378  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
379 
380  private:
381  std::vector<std::map<unsigned int, SCALARTYPE> > & _mat;
382  };
383 
384 
385  }
386 }
387 #endif