ViennaCL - The Vienna Computing Library  1.7.0
Free open-source GPU-accelerated linear algebra and solver library.
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-2015, Institute for Microelectronics,
6  Institute for Analysis and Scientific Computing,
7  TU Wien.
8  Portions of this software are copyright by UChicago Argonne, LLC.
9 
10  -----------------
11  ViennaCL - The Vienna Computing Library
12  -----------------
13 
14  Project Head: Karl Rupp rupp@iue.tuwien.ac.at
15 
16  (A list of authors and contributors can be found in the manual)
17 
18  License: MIT (X11), see file LICENSE in the base directory
19 ============================================================================= */
20 
25 #include <string>
26 #include <fstream>
27 #include <sstream>
28 #include <assert.h>
29 #include "viennacl/forwards.h"
30 
31 #include <vector>
32 #include <map>
33 
34 namespace viennacl
35 {
36 namespace tools
37 {
38 
47 template<typename NumericT, typename SizeT, bool is_iterator1, bool is_forward>
49 {
51 
52 public:
53  typedef self_type iterator1;
54  typedef self_type iterator2;
56 
57  const_sparse_matrix_adapted_iterator(std::vector<std::map<SizeT, NumericT> > const & mat, int i, int j)
58  : mat_(mat), i_(static_cast<size_type>(i)), j_(static_cast<size_type>(j))
59  {
60  if (i < 0) //reverse iterator end
61  {
62  //iter2 = mat_[0].rend(); //reverse iterator end
63  }
64  else //i_ is valid
65  {
66  if (j < 0)
67  {
68  //iter2 = mat_[i].rend();
69  }
70  else //j_ is valid
71  {
72  if (i_ < mat_.size() && mat_[static_cast<vcl_size_t>(i)].size() > 0 )
73  {
74  //TODO: Start at entry j, not at the beginning
75  if (static_cast<int>(mat_[static_cast<vcl_size_t>(i)].rbegin()->first) < j)
76  iter2 = mat_[static_cast<vcl_size_t>(i)].end();
77  else
78  iter2 = mat_[static_cast<vcl_size_t>(i)].begin();
79  }
80  else if (i_ < mat_.size() && mat_[static_cast<vcl_size_t>(i)].size() == 0)
81  iter2 = mat_[static_cast<vcl_size_t>(i)].end();
82  else //i is out of range -> end iterator requested
83  iter2 = mat_.back().end(); //forward iterator end
84  }
85  }
86  }
87 
88  NumericT operator*(void) const
89  {
90  bool flag_iterator1 = is_iterator1; // avoid unreachable code warnings without specializing template
91  if (flag_iterator1)
92  {
93  typedef typename std::map<SizeT, NumericT>::const_iterator col_iterator;
94 
95  col_iterator colit = mat_[i_].find(static_cast<unsigned int>(j_));
96 
97  if (colit != mat_[i_].end())
98  return colit->second;
99  return 0.0;
100  }
101  else
102  return iter2->second;
103  }
104 
105  self_type & operator++(void)
106  {
107  bool flag_iterator1 = is_iterator1; // avoid unreachable code warnings without specializing template
108  bool flag_forward = is_forward;
109  if (flag_iterator1)
110  {
111  if (flag_forward)
112  ++i_;
113  else
114  --i_;
115  }
116  else
117  ++iter2;
118  return *this;
119  }
120  self_type operator++(int) { self_type tmp = *this; ++(*this); return tmp; }
121 
122  self_type operator+=(SizeT offset)
123  {
124  bool flag_iterator1 = is_iterator1; // avoid unreachable code warnings without specializing template
125  bool flag_forward = is_forward;
126  if (flag_iterator1)
127  {
128  if (flag_forward)
129  i_ += offset;
130  else
131  i_ -= offset;
132  }
133  else
134  {
135  for (SizeT k=0; k<offset; ++k)
136  ++iter2; //Note: User must ensure that this is always valid...
137  }
138  return *this;
139  }
140 
141  bool operator==(self_type const & other) const
142  {
143  bool flag_iterator1 = is_iterator1; // avoid unreachable code warnings without specializing template
144  return flag_iterator1 ? (i_ == other.i_) : (iter2 == other.iter2);
145  }
146 
147  bool operator!=(self_type const & other) const { return !(*this == other); }
148 
149  size_type index1() const { return i_; }
150  size_type index2() const
151  {
152  bool flag_iterator1 = is_iterator1; // avoid unreachable code warnings without specializing template
153  if (flag_iterator1)
154  return 0;
155  else
156  return iter2->first;
157  }
158 
160  {
162  }
164  {
165  int end_ = static_cast<int>(mat_[i_].size());
166  if (end_ > 0)
167  end_ = static_cast<int>(mat_[i_].rbegin()->first);
168  return const_sparse_matrix_adapted_iterator<NumericT, SizeT, !is_iterator1, true>(mat_, static_cast<int>(i_), end_ + 1);
169  }
170 
171 private:
172  std::vector<std::map<SizeT, NumericT> > const & mat_;
173  typename std::map<SizeT, NumericT>::const_iterator iter2;
174  size_type i_;
175  size_type j_;
176 };
177 
182 template<typename NumericT, typename SizeT = unsigned int>
184 {
185 public:
188 
192 
193  const_sparse_matrix_adapter(std::vector<std::map<SizeT, NumericT> > const & mat)
194  : mat_(mat), size1_(mat_.size()), size2_(mat_.size()) {}
195 
196  const_sparse_matrix_adapter(std::vector<std::map<SizeT, NumericT> > const & mat, size_type num_rows, size_type num_cols)
197  : mat_(mat), size1_(num_rows), size2_(num_cols) {}
198 
199  size_type size1() const { return size1_; }
200  size_type size2() const { return size2_; }
201 
202  const_iterator1 begin1() const { return const_iterator1(mat_, 0, 0); }
203  const_iterator1 end1() const { return const_iterator1(mat_, static_cast<int>(size1()), static_cast<int>(size2())); }
204 
205  const_reverse_iterator1 rbegin1() const { return const_reverse_iterator1(mat_, static_cast<int>(size1() - 1), 0); }
206  const_reverse_iterator1 rend1() const { return const_reverse_iterator1(mat_, -1, static_cast<int>(size2())); }
207 
208  const_iterator2 begin2() const { return const_iterator2(mat_, 0, 0); }
209  const_iterator2 end2() const { return const_iterator2(mat_, size1(), size2()); }
210 
211  NumericT operator()(SizeT i, SizeT j) const
212  {
213  typedef typename std::map<SizeT, NumericT>::const_iterator col_iterator;
214 
215  col_iterator colit = mat_[i].find(j);
216 
217  if (colit != mat_[i].end())
218  return colit->second;
219  return 0.0;
220  }
221 
222 private:
223  std::vector<std::map<SizeT, NumericT> > const & mat_;
224  size_type size1_;
225  size_type size2_;
226 };
227 
228 
236 template<typename NumericT, typename SizeT, bool is_iterator1>
238 {
240 
241 public:
242  typedef self_type iterator1;
243  typedef self_type iterator2;
245 
246  sparse_matrix_adapted_iterator(std::vector<std::map<SizeT, NumericT> > & mat, int i, int j)
247  : mat_(mat), i_(static_cast<size_type>(i)), j_(static_cast<size_type>(j))
248  {
249  if (i < 0) //reverse iterator end
250  {
251  //iter2 = mat_[0].rend(); //reverse iterator end
252  }
253  else //_i is valid
254  {
255  if (j < 0)
256  {
257  //iter2 = mat[i]_.rend();
258  }
259  else //_j is valid
260  {
261  if (i_ < mat_.size() && mat_[i_].size() > 0 )
262  {
263  //TODO: Start at entry j, not at the beginning
264  if (static_cast<int>(mat_[i_].rbegin()->first) < j)
265  iter2 = mat_[i_].end();
266  else
267  iter2 = mat_[i_].begin();
268  }
269  else if (i_ < mat_.size() && mat_[i_].size() == 0)
270  iter2 = mat_[i_].end();
271  else //i is out of range -> end iterator requested
272  iter2 = mat_.back().end(); //forward iterator end
273  }
274  }
275  }
276 
278  {
279  bool flag_iterator1 = is_iterator1; // avoid unreachable code warnings without specializing template
280  if (flag_iterator1)
281  {
282  return mat_[i_][static_cast<SizeT>(j_)];
283  }
284  else
285  return iter2->second;
286  }
287 
288  self_type & operator++(void)
289  {
290  bool flag_iterator1 = is_iterator1; // avoid unreachable code warnings without specializing template
291  if (flag_iterator1)
292  ++i_;
293  else
294  ++iter2;
295  return *this;
296  }
297  self_type operator++(int) { self_type tmp = *this; ++(*this); return tmp; }
298 
299  self_type operator+=(size_type offset)
300  {
301  bool flag_iterator1 = is_iterator1; // avoid unreachable code warnings without specializing template
302  if (flag_iterator1)
303  i_ += offset;
304  else
305  {
306  for (size_type k=0; k<offset; ++k)
307  ++iter2; //Note: User must ensure that this is always valid...
308  }
309  return *this;
310  }
311 
312  bool operator==(self_type const & other) const
313  {
314  bool flag_iterator1 = is_iterator1; // avoid unreachable code warnings without specializing template
315  if (flag_iterator1)
316  return (i_ == other.i_);
317  return (iter2 == other.iter2);
318  }
319  bool operator!=(self_type const & other) const { return !(*this == other); }
320 
321  size_type index1() const { return i_; }
322  size_type index2() const
323  {
324  bool flag_iterator1 = is_iterator1; // avoid unreachable code warnings without specializing template
325  if (flag_iterator1)
326  return 0;
327  else
328  return iter2->first;
329  }
330 
332  {
333  return sparse_matrix_adapted_iterator<NumericT, SizeT, !is_iterator1>(mat_, static_cast<int>(i_), 0);
334  }
336  {
337  int end_ = static_cast<int>(mat_[i_].size());
338  if (end_ > 0)
339  end_ = static_cast<int>(mat_[i_].rbegin()->first);
340  return sparse_matrix_adapted_iterator<NumericT, SizeT, !is_iterator1>(mat_, static_cast<int>(i_), end_ + 1);
341  }
342 
343 private:
344  std::vector<std::map<SizeT, NumericT> > & mat_;
345  typename std::map<SizeT, NumericT>::iterator iter2;
346  size_type i_;
347  size_type j_;
348 };
349 
350 
351 
356 template<typename NumericT, typename SizeT = unsigned int>
357 class sparse_matrix_adapter : public const_sparse_matrix_adapter<NumericT, SizeT>
358 {
360 public:
365  typedef SizeT size_type;
366 
367  sparse_matrix_adapter(std::vector<std::map<SizeT, NumericT> > & mat)
368  : BaseType(mat), mat_(mat), size1_(static_cast<SizeT>(mat_.size())), size2_(static_cast<SizeT>(mat_.size())) {}
369 
370  sparse_matrix_adapter(std::vector<std::map<SizeT, NumericT> > & mat,
371  vcl_size_t num_rows,
372  vcl_size_t num_cols)
373  : BaseType(mat, num_rows, num_cols), mat_(mat), size1_(static_cast<size_type>(num_rows)), size2_(static_cast<size_type>(num_cols)) {}
374 
375  iterator1 begin1() { return iterator1(mat_, 0, 0); }
376  iterator1 end1() { return iterator1(mat_, static_cast<int>(mat_.size()), static_cast<int>(mat_.back().size())); }
377 
378  const_iterator1 begin1() const { return const_iterator1(mat_, 0, 0); }
379  const_iterator1 end1() const { return const_iterator1(mat_, static_cast<int>(size1()), static_cast<int>(size2())); }
380 
381  iterator2 begin2() { return iterator2(mat_, 0, 0); }
382  iterator2 end2() { return iterator2(mat_, mat_.size(), mat_.back().size()); }
383 
384  const_iterator2 begin2() const { return const_iterator2(mat_, 0, 0); }
385  const_iterator2 end2() const { return const_iterator2(mat_, size1(), size2()); }
386 
387  NumericT & operator()(vcl_size_t i, vcl_size_t j) { return mat_[i][static_cast<size_type>(j)]; }
388 
389  void resize(vcl_size_t i, vcl_size_t j, bool preserve = true)
390  {
391  if (i>0)
392  mat_.resize(i);
393  if (!preserve)
394  clear();
395 
396  size1_ = static_cast<size_type>(i);
397  size2_ = static_cast<size_type>(j);
398  }
399 
400  void clear()
401  {
402  for (size_type i=0; i<mat_.size(); ++i)
403  mat_[i].clear();
404  }
405 
406  size_type size1() { return size1_; }
407  size_type size1() const { return size1_; } //Note: Due to name hiding it is not sufficient to have it in the base class
408 
409  //assume a square matrix
410  size_type size2() { return size2_; }
411  size_type size2() const { return size2_; } //Note: Due to name hiding it is not sufficient to have it in the base class
412 
413 private:
414  std::vector<std::map<SizeT, NumericT> > & mat_;
415  size_type size1_;
416  size_type size2_;
417 };
418 
419 }
420 }
421 #endif
NumericT & operator()(vcl_size_t i, vcl_size_t j)
Definition: adapter.hpp:387
const_iterator1 end1() const
Definition: adapter.hpp:379
sparse_matrix_adapted_iterator< NumericT, SizeT,!is_iterator1 > end() const
Definition: adapter.hpp:335
const_sparse_matrix_adapted_iterator< NumericT, SizeT, false, true > const_iterator2
Definition: adapter.hpp:187
sparse_matrix_adapted_iterator< NumericT, SizeT, true > iterator1
Definition: adapter.hpp:361
void resize(vcl_size_t i, vcl_size_t j, bool preserve=true)
Definition: adapter.hpp:389
bool operator==(self_type const &other) const
Definition: adapter.hpp:141
self_type operator+=(size_type offset)
Definition: adapter.hpp:299
const_reverse_iterator1 rbegin1() const
Definition: adapter.hpp:205
This file provides the forward declarations for the main types used within ViennaCL.
const_sparse_matrix_adapted_iterator< NumericT, SizeT, true, true > const_iterator1
Definition: adapter.hpp:363
sparse_matrix_adapted_iterator(std::vector< std::map< SizeT, NumericT > > &mat, int i, int j)
Definition: adapter.hpp:246
bool operator!=(self_type const &other) const
Definition: adapter.hpp:147
const_iterator2 begin2() const
Definition: adapter.hpp:384
float NumericT
Definition: bisect.cpp:40
A const iterator for sparse matrices of type std::vector > ...
Definition: adapter.hpp:48
Main namespace in ViennaCL. Holds all the basic types such as vector, matrix, etc. and defines operations upon them.
Definition: cpu_ram.hpp:34
const_sparse_matrix_adapter(std::vector< std::map< SizeT, NumericT > > const &mat)
Definition: adapter.hpp:193
const_sparse_matrix_adapted_iterator< NumericT, SizeT,!is_iterator1, true > end() const
Definition: adapter.hpp:163
sparse_matrix_adapter(std::vector< std::map< SizeT, NumericT > > &mat, vcl_size_t num_rows, vcl_size_t num_cols)
Definition: adapter.hpp:370
NumericT operator()(SizeT i, SizeT j) const
Definition: adapter.hpp:211
const_iterator1 begin1() const
Definition: adapter.hpp:378
vcl_size_t size(VectorType const &vec)
Generic routine for obtaining the size of a vector (ViennaCL, uBLAS, etc.)
Definition: size.hpp:235
sparse_matrix_adapter(std::vector< std::map< SizeT, NumericT > > &mat)
Definition: adapter.hpp:367
const_sparse_matrix_adapted_iterator(std::vector< std::map< SizeT, NumericT > > const &mat, int i, int j)
Definition: adapter.hpp:57
const_reverse_iterator1 rend1() const
Definition: adapter.hpp:206
Adapts a constant sparse matrix type made up from std::vector > to basic ub...
Definition: adapter.hpp:183
A non-const iterator for sparse matrices of type std::vector > ...
Definition: adapter.hpp:237
std::size_t vcl_size_t
Definition: forwards.h:75
const_sparse_matrix_adapter(std::vector< std::map< SizeT, NumericT > > const &mat, size_type num_rows, size_type num_cols)
Definition: adapter.hpp:196
const_iterator2 end2() const
Definition: adapter.hpp:385
sparse_matrix_adapted_iterator< NumericT, SizeT, false > iterator2
Definition: adapter.hpp:362
const_sparse_matrix_adapted_iterator< NumericT, SizeT,!is_iterator1, true > begin() const
Definition: adapter.hpp:159
sparse_matrix_adapted_iterator< NumericT, SizeT,!is_iterator1 > begin() const
Definition: adapter.hpp:331
Adapts a non-const sparse matrix type made up from std::vector > to basic u...
Definition: adapter.hpp:357
const_sparse_matrix_adapted_iterator< NumericT, SizeT, false, true > const_iterator2
Definition: adapter.hpp:364
const_sparse_matrix_adapted_iterator< NumericT, SizeT, true, false > const_reverse_iterator1
Definition: adapter.hpp:189
bool operator!=(self_type const &other) const
Definition: adapter.hpp:319
const_sparse_matrix_adapted_iterator< NumericT, SizeT, true, true > const_iterator1
Definition: adapter.hpp:186
bool operator==(self_type const &other) const
Definition: adapter.hpp:312