Darwin  1.10(beta)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
drwnSparseVector.h
1 /******************************************************************************
2 ** DARWIN: A FRAMEWORK FOR MACHINE LEARNING RESEARCH AND DEVELOPMENT
3 ** Distributed under the terms of the BSD license (see the LICENSE file)
4 ** Copyright (c) 2007-2015, Stephen Gould
5 ** All rights reserved.
6 **
7 ******************************************************************************
8 ** FILENAME: drwnSparseVector.h
9 ** AUTHOR(S): Stephen Gould <stephen.gould@anu.edu.au>
10 **
11 *****************************************************************************/
12 
13 #pragma once
14 
15 #include <cstdlib>
16 #include <vector>
17 #include <map>
18 
19 #include "drwnBase.h"
20 
21 using namespace std;
22 
23 // drwnSparseVec ------------------------------------------------------------
42 
43 template<typename T>
45  protected:
46  static const T _zero;
47  size_t _size;
48  map<size_t, T> _data;
49 
50  public:
51  typedef T value_type;
52  typedef T *pointer;
53  typedef const T *const_pointer;
54 
55  class iterator;
56 
57  class reference {
58  protected:
59  friend class drwnSparseVec;
60  friend class drwnSparseVec<T>::iterator;
61  drwnSparseVec<T> *_p;
62  size_t _indx;
63 
64  inline reference();
65  inline reference(drwnSparseVec<T>& v, size_t indx);
66 
67  public:
68  inline ~reference();
69 
70  inline operator T() const;
71  inline reference& operator=(const T& x);
72  inline reference& operator=(const reference& x);
73  inline reference& operator+=(const T& x);
74  inline reference& operator-=(const T& x);
75  inline reference& operator*=(const T& x);
76  inline reference& operator/=(const T& x);
77  };
78  friend class reference;
79 
80  typedef const T& const_reference;
81  typedef size_t size_type;
82  typedef ptrdiff_t difference_type;
83 
84  class iterator {
85  protected:
86  friend class drwnSparseVec;
87  drwnSparseVec<T> *_p;
88  size_t _indx;
89 
90  inline iterator(drwnSparseVec<T>& v, size_t indx);
91 
92  public:
93  typedef random_access_iterator_tag iterator_category;
94  typedef T value_type;
95  typedef size_t size_type;
96  typedef ptrdiff_t difference_type;
97  typedef T *pointer;
98  typedef const T *const_pointer;
99  typedef typename drwnSparseVec<T>::reference reference;
100  typedef const T& const_reference;
101 
102  public:
103  inline iterator();
104  inline ~iterator();
105 
106  inline iterator& operator=(const iterator& it);
107  inline bool operator==(const iterator& it) const;
108  inline bool operator!=(const iterator& it) const;
109  inline bool operator<(const iterator& it) const;
110  inline bool operator>(const iterator& it) const;
111  inline bool operator<=(const iterator& it) const;
112  inline bool operator>=(const iterator& it) const;
113  inline const_reference operator*() const;
114  inline reference operator*();
115  //inline pointer operator->();
116  inline iterator& operator++();
117  inline iterator& operator--();
118  inline iterator operator++(int);
119  inline iterator operator--(int);
120  inline iterator operator+(difference_type n);
121  inline iterator& operator+=(difference_type n);
122  inline iterator operator-(difference_type n);
123  inline iterator& operator-=(difference_type n);
124  inline const T& operator[](difference_type n) const;
125  inline reference operator[](difference_type n);
126 
127  inline difference_type operator-(const iterator& it) const {
128  return (_indx - it._indx);
129  }
130  inline difference_type operator+(const iterator& it) const {
131  return (_indx + it._indx);
132  }
133 
134  //operator size_t() const { return _indx; }
135  };
136  friend class iterator;
137 
138  /*
139  class const_iterator;
140  friend class const_iterator;
141  */
142 
143  public:
144  drwnSparseVec();
145  drwnSparseVec(size_t size);
147  drwnSparseVec(const vector<T>& v);
148  ~drwnSparseVec();
149 
150  bool empty() const { return (_size == 0); }
151  void clear() { _size = 0; _data.clear(); }
152  void resize(size_t n);
153  size_t size() const { return _size; }
154  size_t capacity() const { return _size; }
155  size_t max_size() const { return size_type(-1) / sizeof(value_type); }
156  void reserve(size_t size) { /* do nothing */ }
157  void swap(drwnSparseVec<T>& v);
158 
159  size_t nnz() const { return _data.size(); }
160 
161  iterator begin() { return iterator(*this, 0); }
162  iterator end() { return iterator(*this, _size); }
163 
164  // modification
165  void push_back(const T& x);
166  void pop_back();
167  void insert(size_t position, const T& x);
168  void insert(size_t position, typename vector<T>::const_iterator first,
169  typename vector<T>::const_iterator last);
170  void insert(iterator position, const T& x) {
171  assert(position._p == this);
172  return insert(position._indx, x);
173  }
174  void insert(iterator position, typename vector<T>::const_iterator first,
175  typename vector<T>::const_iterator last) {
176  assert(position._p == this);
177  return insert(position._indx, first, last);
178  }
179 
180  // operators
181  drwnSparseVec& operator=(const drwnSparseVec<T>& v);
182  drwnSparseVec& operator=(const vector<T>& v);
183  const T& operator[](size_t indx) const;
184  reference operator[](size_t indx);
185 
186  // typecasting
187  operator vector<T>() const { return decode(); }
188 
190  static T dot(const vector<T>& x, const drwnSparseVec<T>& y);
192  static T dot(const drwnSparseVec<T>& x, const vector<T>& y);
194  static T dot(const drwnSparseVec<T>& x, const drwnSparseVec<T>& y);
195 
196  protected:
197  // decode into an stl vector
198  vector<T> decode() const;
199 
200  // encode from an stl vector
201  void encode(const vector<T>& v);
202 };
203 
204 // drwnSparseVec implementation ---------------------------------------------
205 
206 template<typename T>
207 const T drwnSparseVec<T>::_zero(0);
208 
209 template<typename T>
211 {
212  // do nothing
213 }
214 
215 template<typename T>
216 drwnSparseVec<T>::drwnSparseVec(size_t size) : _size(size)
217 {
218  // do nothing
219 }
220 
221 template<typename T>
223  _size(v._size), _data(v._data)
224 {
225  // do nothing
226 }
227 
228 template<typename T>
229 drwnSparseVec<T>::drwnSparseVec(const vector<T>& v)
230 {
231  encode(v);
232 }
233 
234 template<typename T>
236 {
237  // do nothing
238 }
239 
240 
241 template<typename T>
242 void drwnSparseVec<T>::resize(size_t n)
243 {
244  _size = n;
245  for (typename map<size_t, T>::iterator it = _data.begin(); it != _data.end(); it++) {
246  if (it->first >= _size) {
247  it = _data.erase(it);
248  }
249  }
250 }
251 
252 template<typename T>
254 {
255  std::swap(_size, v._size);
256  _data.swap(v._data);
257 }
258 
259 template<typename T>
260 void drwnSparseVec<T>::push_back(const T& x)
261 {
262  if (x != T(0)) {
263  _data[_size] = x;
264  }
265  _size += 1;
266 }
267 
268 template<typename T>
270 {
271  DRWN_ASSERT(_size > 0);
272  typename map<size_t, T>::iterator it = _data.find(_size - 1);
273  if (it != _data.end()) {
274  _data.erase(it);
275  }
276  _size -= 1;
277 }
278 
279 template<typename T>
280 void drwnSparseVec<T>::insert(size_t position, const T& x)
281 {
282  // TODO: this is ugly; fix
283  DRWN_ASSERT((position >= this->begin()._indx) && (position <= this->end()._indx));
284 
285  if (position != this->end()._indx) {
286  map<size_t, T> oldVec(_data);
287  _data.clear();
288 
289  for (typename map<size_t, T>::const_iterator it = oldVec.begin(); it != oldVec.end(); it++) {
290  if (it->first >= position) {
291  _data[it->first + 1] = it->second;
292  } else {
293  _data[it->first] = it->second;
294  }
295  }
296  }
297 
298  if (x != T(0)) {
299  _data[position] = x;
300  }
301 
302  _size += 1;
303 }
304 
305 template<typename T>
306 void drwnSparseVec<T>::insert(size_t position, typename vector<T>::const_iterator first,
307  typename vector<T>::const_iterator last)
308 {
309  // TODO: this is ugly; fix
310  DRWN_ASSERT((position >= this->begin()._indx) && (position <= this->end()._indx));
311 
312  map<size_t, T> oldVec;
313  if (position != this->end()._indx) {
314  _data.swap(oldVec);
315  }
316 
317  size_t delta = 0;
318  for (typename vector<T>::const_iterator it = first; it != last; it++) {
319  if (*it != T(0)) {
320  _data[position + delta] = *it;
321  }
322  delta += 1;
323  }
324 
325  for (typename map<size_t, T>::const_iterator it = oldVec.begin(); it != oldVec.end(); it++) {
326  if (it->first >= position) {
327  _data[it->first + delta] = it->second;
328  } else {
329  _data[it->first] = it->second;
330  }
331  }
332 
333  _size += delta;
334 }
335 
336 // operators
337 template<typename T>
339 {
340  if (&v != this) {
341  _size = v._size;
342  _data = v._data;
343  }
344  return *this;
345 }
346 
347 template<typename T>
349 {
350  encode(v);
351  return *this;
352 }
353 
354 template<typename T>
355 const T& drwnSparseVec<T>::operator[](size_t indx) const
356 {
357  typename map<size_t, T>::const_iterator it = _data.find(indx);
358  if (it != _data.end()) {
359  return it->second;
360  }
361 
362  return _zero;
363 }
364 
365 template<typename T>
367 {
368  /*
369  typename map<size_t, T>::iterator it = _data.find(indx);
370  if (it == _data.end()) {
371  it = _data.insert(make_pair(indx, T(0))).first;
372  }
373 
374  return it->second;
375  */
376  return typename drwnSparseVec<T>::reference(*this, indx);
377 }
378 
379 template <typename T>
380 T drwnSparseVec<T>::dot(const vector<T>& x, const drwnSparseVec<T>& y)
381 {
382  T d(0);
383  for (typename map<size_t, T>::const_iterator it = y._data.begin(); it != y._data.end(); ++it) {
384  d += x[it->first] * it->second;
385  }
386 
387  return d;
388 }
389 
390 template <typename T>
391 T drwnSparseVec<T>::dot(const drwnSparseVec<T>& x, const vector<T>& y)
392 {
393  T d(0);
394  for (typename map<size_t, T>::const_iterator it = x._data.begin(); it != x._data.end(); ++it) {
395  d += y[it->first] * it->second;
396  }
397 
398  return d;
399 }
400 
401 template <typename T>
403 {
404  T d(0);
405 
406  if (x.nnz() < y.nnz()) {
407  for (typename map<size_t, T>::const_iterator it = x._data.begin(); it != x._data.end(); ++it) {
408  d += y[it->first] * it->second;
409  }
410  } else {
411  for (typename map<size_t, T>::const_iterator it = y._data.begin(); it != y._data.end(); ++it) {
412  d += x[it->first] * it->second;
413  }
414  }
415 
416  return d;
417 }
418 
419 // decode into an stl vector
420 template<typename T>
421 vector<T> drwnSparseVec<T>::decode() const
422 {
423  vector<T> v(_size, T(0));
424  for (typename map<size_t, T>::const_iterator it = _data.begin(); it != _data.end(); it++) {
425  v[it->first] = it->second;
426  }
427  return v;
428 }
429 
430 // encode from an stl vector
431 template<typename T>
432 void drwnSparseVec<T>::encode(const vector<T>& v)
433 {
434  _size = v.size();
435  for (size_t i = 0; i < v.size(); i++) {
436  if (v[i] != T(0)) {
437  _data[i] = v[i];
438  }
439  }
440 }
441 
442 // drwnSparseVec::reference implementation ----------------------------------
443 
444 template<typename T>
446  _p(&v), _indx(indx)
447 {
448  // do nothing
449 }
450 
451 template<typename T>
453 {
454  // do nothing
455 }
456 
457 template<typename T>
459 {
460  typename map<size_t, T>::iterator it = _p->_data.find(_indx);
461  if (it == _p->_data.end()) {
462  return T(0);
463  }
464 
465  return it->second;
466 }
467 
468 template<typename T>
470 {
471  typename map<size_t, T>::iterator it = _p->_data.find(_indx);
472  if (it == _p->_data.end()) {
473  if (x != T(0)) {
474  _p->_data.insert(make_pair(_indx, x));
475  }
476  } else {
477  if (x == T(0)) {
478  _p->_data.erase(it);
479  } else {
480  it->second = x;
481  }
482  }
483 
484  return *this;
485 }
486 
487 template<typename T>
489 {
490  this->operator=((T)x);
491  return *this;
492 }
493 
494 template<typename T>
496 {
497  typename map<size_t, T>::iterator it = _p->_data.find(_indx);
498  if (it != _p->_data.end()) {
499  return (*this = (it->second + x));
500  }
501 
502  return (*this = x);
503 }
504 
505 template<typename T>
507 {
508  typename map<size_t, T>::iterator it = _p->_data.find(_indx);
509  if (it != _p->_data.end()) {
510  return (*this = (it->second - x));
511  }
512 
513  return (*this = (T(0) - x));
514 }
515 
516 template<typename T>
518 {
519  typename map<size_t, T>::iterator it = _p->_data.find(_indx);
520  if (it != _p->_data.end()) {
521  return (*this = (it->second * x));
522  }
523 
524  return (*this = (T(0) * x));
525 }
526 
527 template<typename T>
529 {
530  typename map<size_t, T>::iterator it = _p->_data.find(_indx);
531  if (it != _p->_data.end()) {
532  return (*this = (it->second / x));
533  }
534 
535  return (*this = (T(0) / x));
536 }
537 
538 // drwnSparseVec::iterator implementation ------------------------------------
539 
540 template<typename T>
542  _p(&v), _indx(indx)
543 {
544  // do nothing
545 }
546 
547 template<typename T>
549  _p(NULL), _indx(0)
550 {
551  // do nothing
552 }
553 
554 template<typename T>
556 {
557  // do nothing
558 }
559 
560 template<typename T>
562 {
563  _p = it._p;
564  _indx = it._indx;
565  return *this;
566 }
567 
568 template<typename T>
569 bool drwnSparseVec<T>::iterator::operator==(const iterator& it) const
570 {
571  return ((_p == it._p) && (_indx == it._indx));
572 }
573 
574 template<typename T>
575 bool drwnSparseVec<T>::iterator::operator!=(const iterator& it) const
576 {
577  return ((_p != it._p) || (_indx != it._indx));
578 }
579 
580 template<typename T>
581 bool drwnSparseVec<T>::iterator::operator<(const iterator& it) const
582 {
583  return (_indx < it._indx);
584 }
585 
586 template<typename T>
587 bool drwnSparseVec<T>::iterator::operator>(const iterator& it) const
588 {
589  return (_indx > it._indx);
590 }
591 
592 template<typename T>
593 bool drwnSparseVec<T>::iterator::operator<=(const iterator& it) const
594 {
595  return (_indx <= it._indx);
596 }
597 
598 template<typename T>
599 bool drwnSparseVec<T>::iterator::operator>=(const iterator& it) const
600 {
601  return (_indx >= it._indx);
602 }
603 
604 template<typename T>
605 typename drwnSparseVec<T>::const_reference drwnSparseVec<T>::iterator::operator*() const
606 {
607  DRWN_ASSERT(_p != NULL);
608  return (*_p)[_indx];
609 }
610 
611 template<typename T>
613 {
614  return typename drwnSparseVec<T>::reference(*_p, _indx);
615 }
616 
617 template<typename T>
619 {
620  _indx = std::min(_indx + 1, _p->_size);
621  return *this;
622 }
623 
624 template<typename T>
626 {
627  if (_indx > 0) _indx -= 1;
628  return *this;
629 }
630 
631 template<typename T>
633 {
634  iterator copy(*this);
635  ++(*this);
636  return copy;
637 }
638 
639 template<typename T>
641 {
642  iterator copy(*this);
643  --(*this);
644  return copy;
645 }
646 
647 template<typename T>
649 {
650  iterator tmp(*this);
651  tmp._indx += n;
652  return tmp;
653 }
654 
655 template<typename T>
657 {
658  _indx += n;
659  *this;
660 }
661 
662 template<typename T>
664 {
665  iterator tmp(*this);
666  tmp._indx -= n;
667  return tmp;
668 }
669 
670 template<typename T>
672 {
673  _indx -= n;
674  *this;
675 }
676 
677 template<typename T>
678 const T& drwnSparseVec<T>::iterator::operator[](difference_type n) const
679 {
680  return (*_p)[_indx + n];
681 }
682 
683 template<typename T>
685 {
686  return drwnSparseVec<T>::reference(*_p, _indx + n);
687 }
Definition: drwnSparseVector.h:57
Definition: drwnSparseVector.h:84
Quick-and-dirty sparse vector class as a plugin replacement for std::vector.
Definition: drwnSparseVector.h:44
bool operator<(const CvSize &r, const CvSize &s)
inequality operator for CvSize objects (allows partial sorting)
Definition: drwnOpenCVUtils.cpp:88
static T dot(const vector< T > &x, const drwnSparseVec< T > &y)
efficient dot product between a vector and a sparse vector
Definition: drwnSparseVector.h:380
bool operator==(const CvRect &r, const CvRect &s)
equality operator for CvRect objects
Definition: drwnOpenCVUtils.cpp:83