SparseMatrix.h
Go to the documentation of this file.
1 #ifndef _utl_SparseMatrix_h_
2 #define _utl_SparseMatrix_h_
3 
4 #include <map>
5 #include <numeric>
6 
7 #include <boost/lambda/lambda.hpp>
8 
9 
10 namespace utl {
11 
35  template<typename T = double>
36  class SparseMatrix {
37  public:
38  typedef int IndexType;
39 
41  class Row {
42  public:
43  Row(const SparseMatrix& m, const IndexType row)
44  : fSparseMatrix(m), fRow(row) { }
45 
46  const T&
47  operator[](const IndexType column)
48  const
49  { return fSparseMatrix(fRow, column); }
50 
51  private:
53  const IndexType fRow;
54  };
55 
57  class Index {
58  public:
59  Index(const IndexType row, const IndexType column)
60  : fRow(row), fColumn(column) { }
61 
62  IndexType GetRow() const { return fRow; }
63 
64  IndexType GetColumn() const { return fColumn; }
65 
66  bool operator<(const Index& i) const
67  { return fRow < i.fRow || (fRow == i.fRow && fColumn < i.fColumn); }
68 
69  bool operator==(const Index& i) const
70  { return fRow == i.fRow && fColumn == i.fColumn; }
71 
72  private:
73  const IndexType fRow;
75  };
76 
77  private:
79  typedef std::map<IndexKeyType, T> MapType;
80  typedef typename MapType::value_type MapValueType;
81  typedef typename MapType::iterator MapIterator;
82  typedef typename MapType::const_iterator MapConstIterator;
83 
84  public:
86  template<class IteratorType, typename ValueType>
88  public:
89  IteratorTransformer(const IteratorType& it)
90  : fIterator(it) { }
91 
92  IndexType GetRow() const { return fIterator->first.GetRow(); }
93 
94  IndexType GetColumn() const { return fIterator->first.GetColumn(); }
95 
96  ValueType& operator()() const { return fIterator->second; }
97 
98  ValueType& operator*() const { return (*this)(); }
99 
100  IteratorTransformer& operator++() { ++fIterator; return *this; }
101 
102  bool operator==(const IteratorTransformer& it) const { return fIterator == it.fIterator; }
103 
104  bool operator!=(const IteratorTransformer& it) const { return fIterator != it.fIterator; }
105 
106  private:
107  IteratorType fIterator;
108  };
109 
110  SparseMatrix(const T& init = T())
111  : fInitializer(init) { }
112 
113  template<typename U>
114  explicit
117  {
119  it != m.SparseEnd(); ++it)
120  (*this)(it.GetRow(), it.GetColumn()) = it();
121  }
122 
123  unsigned int GetNonEmptySize() const { return fMatrix.size(); }
124 
125  const T& GetInitializer() const { return fInitializer; }
126 
127  void Clear() { fMatrix.clear(); }
128 
130  typename SparseMatrix::Row
132  const
133  { return typename SparseMatrix::Row(*this, row); }
134 
136  T&
137  operator()(const IndexType row, const IndexType column)
138  {
139  return
140  fMatrix.insert(MapValueType(IndexKeyType(row, column), fInitializer)).first->second;
141  }
142 
144  const T&
145  operator()(const IndexType row, const IndexType column)
146  const
147  {
148  const MapConstIterator it = fMatrix.find(IndexKeyType(row, column));
149  return (it == fMatrix.end()) ? fInitializer : it->second;
150  }
151 
152  bool IsEmpty() const { return fMatrix.empty(); }
153 
154  bool
155  IsEmpty(const IndexType row, const IndexType column)
156  const
157  {
158  const MapConstIterator it = fMatrix.find(IndexKeyType(row, column));
159  return it == fMatrix.end();
160  }
161 
162  unsigned int
164  {
165  unsigned int erased = 0;
166  for (MapIterator it = fMatrix.begin();
167  it != fMatrix.end(); )
168  if (it->second != fInitializer)
169  ++it;
170  else {
171  Erase(it++);
172  ++erased;
173  }
174  return erased;
175  }
176 
178  bool operator==(const SparseMatrix& m) const
179  { return fMatrix == m.fMatrix && fInitializer == m.fInitializer; }
180 
182  bool operator!=(const SparseMatrix& m) const { return !operator==(m); }
183 
184  template<typename U>
185  bool
187  const
188  {
189  if (fInitializer != m.GetInitializer())
190  return false;
191 
192  ConstIterator it1 = SparseBegin();
193  typename SparseMatrix<U>::ConstIterator it2 = m.SparseBegin();
194  while (it1 != SparseEnd() && it2 != m.SparseEnd()) {
195  if (it1.GetRow() != it2.GetRow() ||
196  it1.GetColumn() != it2.GetColumn() ||
197  it1() != it2())
198  return false;
199  ++it1;
200  ++it2;
201  }
202 
203  if (it1 != SparseEnd() || it2 != m.SparseEnd())
204  return false;
205 
206  return true;
207  }
208 
209  template<typename U>
210  bool operator!=(const SparseMatrix<U>& m) const { return !operator==(m); }
211 
214 
215  Iterator SparseBegin() { return Iterator(fMatrix.begin()); }
216 
217  ConstIterator SparseBegin() const { return ConstIterator(fMatrix.begin()); }
218 
219  Iterator SparseEnd() { return Iterator(fMatrix.end()); }
220 
221  ConstIterator SparseEnd() const { return ConstIterator(fMatrix.end()); }
222 
223  Iterator Find(const IndexType row, const IndexType column)
224  { return Iterator(fMatrix.find(Index(row, column))); }
225 
226  ConstIterator Find(const IndexType row, const IndexType column) const
227  { return ConstIterator(fMatrix.find(Index(row, column))); }
228 
230  template<typename U>
231  SparseMatrix&
232  operator*=(const U& value)
233  {
234  for (MapIterator it = fMatrix.begin(); it != fMatrix.end(); ++it)
235  it->second *= value;
236  return *this;
237  }
238 
240  template<typename U>
241  SparseMatrix&
243  {
244  for (typename SparseMatrix<U>::ConstIterator it = m.SparseBegin();
245  it != m.SparseEnd(); ++it)
246  (*this)(it.GetRow(), it.GetColumn()) += it();
247  return *this;
248  }
249 
251  template<typename U>
252  SparseMatrix&
254  {
255  for (typename SparseMatrix<U>::ConstIterator it = m.SparseBegin();
256  it != m.SparseEnd(); ++it)
257  (*this)(it.GetRow(), it.GetColumn()) -= it();
258  return *this;
259  }
260 
262  void
264  {
265  MapType t;
266  for (MapConstIterator it = fMatrix.begin(); it != fMatrix.end(); ++it) {
267  const IndexKeyType& i = it->first;
268  t.insert(t.begin(), std::make_pair(IndexKeyType(i.GetColumn(), i.GetRow()), it->second));
269  }
270  fMatrix.swap(t);
271  }
272 
273  private:
274  void Erase(const MapIterator it) { fMatrix.erase(it); }
275 
277  const T fInitializer;
278 
279  template<typename U> friend class SparseMatrix;
280  };
281 
282 
289  template<typename T, typename U>
290  typename boost::lambda::return_type_2<
291  boost::lambda::arithmetic_action<boost::lambda::multiply_action>,
294  >::type
296  {
297  typedef typename boost::lambda::return_type_2<
298  boost::lambda::arithmetic_action<boost::lambda::multiply_action>,
301  >::type ResultMatrix;
302 
303  ResultMatrix c;
304 
305  for (typename SparseMatrix<U>::ConstIterator bIt = b.SparseBegin();
306  bIt != b.SparseEnd(); ++bIt) {
307  const typename SparseMatrix<U>::IndexType k = bIt.GetRow();
308  for (typename SparseMatrix<T>::ConstIterator aIt = a.SparseBegin();
309  aIt != a.SparseEnd(); ++aIt) {
310  const typename SparseMatrix<T>::IndexType kk = aIt.GetColumn();
311  if (kk == k) {
312  const typename SparseMatrix<T>::IndexType i = aIt.GetRow();
313  const typename SparseMatrix<U>::IndexType j = bIt.GetColumn();
314  c(i, j) += aIt() * bIt();
315  }
316  }
317  }
318 
319  return c;
320  }
321 
322 
323  // output stuff
324 
325  template<class Stream, typename T>
326  Stream&
327  operator<<(Stream& s, const SparseMatrix<T>& m)
328  {
329  s << '(';
331  if (it != m.SparseEnd()) {
332  s << '{' << it.GetRow() << ',' << it.GetColumn() << ", " << it() << '}';
333  ++it;
334  while (it != m.SparseEnd())
335  s << " {" << it.GetRow() << ',' << it.GetColumn() << ", " << it() << '}';
336  }
337  return s << ')';
338  }
339 
340 
341  // output functions assume the lowest index starts with 0, which is not
342  // necessarily true
343 
344  template<class Stream, typename T, typename SparseType>
345  Stream&
346  OutputSparse(Stream& s,
347  const SparseMatrix<T>& m,
348  const typename SparseMatrix<T>::IndexType rows,
349  const typename SparseMatrix<T>::IndexType columns,
350  const char separator, const SparseType& sparse)
351  {
352  typedef typename SparseMatrix<T>::IndexType Index;
353  for (Index i = 0; i < rows; ++i) {
354  if (m.IsEmpty(i, 0))
355  s << sparse;
356  else
357  s << m[i][0];
358  for (Index j = 1; j < columns; ++j) {
359  s << separator;
360  if (m.IsEmpty(i, j))
361  s << sparse;
362  else
363  s << m[i][j];
364  }
365  s << '\n';
366  }
367  return s;
368  }
369 
370 
371  template<class Stream, typename T>
372  inline
373  Stream&
374  OutputSparse(Stream& s,
375  const SparseMatrix<T>& m,
376  const typename SparseMatrix<T>::IndexType rows,
377  const typename SparseMatrix<T>::IndexType columns)
378  {
379  return OutputSparse(s, m, rows, columns, ' ', '.');
380  }
381 
382 
383  template<class Stream, typename T>
384  inline
385  Stream&
386  Output(Stream& s,
387  const SparseMatrix<T>& m,
388  const typename SparseMatrix<T>::IndexType rows,
389  const typename SparseMatrix<T>::IndexType columns,
390  const char separator = ' ')
391  {
392  return OutputSparse(s, m, rows, columns, separator, m.GetInitializer());
393  }
394 
395 
396 }
397 
398 
399 namespace boost {
400 
401  namespace lambda {
402 
404  template<typename T, typename U>
405  class plain_return_type_2<
406  arithmetic_action<multiply_action>,
407  utl::SparseMatrix<T>,
409  > {
410  private:
411  // find type of T * U
412  typedef typename
413  return_type_2<
414  arithmetic_action<multiply_action>,
415  T,
416  U
418 
419  public:
421  };
422 
423  }
424 
425 }
426 
427 
428 #include <utl/SparseMatrixVectorOp.h>
429 
430 
431 #endif
const IndexType fRow
Definition: SparseMatrix.h:73
Stream & OutputSparse(Stream &s, const SparseMatrix< T > &m, const typename SparseMatrix< T >::IndexType rows, const typename SparseMatrix< T >::IndexType columns, const char separator, const SparseType &sparse)
Definition: SparseMatrix.h:346
bool operator==(const SparseMatrix &m) const
be sure to call Reclaim() first
Definition: SparseMatrix.h:178
const IndexType fColumn
Definition: SparseMatrix.h:74
ConstIterator SparseEnd() const
Definition: SparseMatrix.h:221
IteratorTransformer< MapConstIterator, const T > ConstIterator
Definition: SparseMatrix.h:213
SparseMatrix & operator-=(const SparseMatrix< U > &m)
matrix subtraction
Definition: SparseMatrix.h:253
bool operator==(const Index &i) const
Definition: SparseMatrix.h:69
unsigned int GetNonEmptySize() const
Definition: SparseMatrix.h:123
friend class SparseMatrix
Definition: SparseMatrix.h:279
const T & operator[](const IndexType column) const
Definition: SparseMatrix.h:47
void Transpose()
in-situ transpose
Definition: SparseMatrix.h:263
bool operator!=(const IteratorTransformer &it) const
Definition: SparseMatrix.h:104
MapType::value_type MapValueType
Definition: SparseMatrix.h:80
IteratorTransformer & operator++()
Definition: SparseMatrix.h:100
IteratorTransformer< MapIterator, T > Iterator
Definition: SparseMatrix.h:212
Sparse container class for matrix data.
Definition: SparseMatrix.h:36
IndexType GetColumn() const
Definition: SparseMatrix.h:64
IteratorTransformer(const IteratorType &it)
Definition: SparseMatrix.h:89
Iterator SparseEnd()
Definition: SparseMatrix.h:219
Row(const SparseMatrix &m, const IndexType row)
Definition: SparseMatrix.h:43
#define U
const T & operator()(const IndexType row, const IndexType column) const
noncreational () access for const
Definition: SparseMatrix.h:145
bool operator==(const IteratorTransformer &it) const
Definition: SparseMatrix.h:102
constexpr double s
Definition: AugerUnits.h:163
SparseMatrix & operator*=(const U &value)
multiplication with scalar
Definition: SparseMatrix.h:232
MapType::const_iterator MapConstIterator
Definition: SparseMatrix.h:82
bool IsEmpty() const
Definition: SparseMatrix.h:152
SparseMatrix::Row operator[](const IndexType row) const
noncreational [] access trough proxy
Definition: SparseMatrix.h:131
T & operator()(const IndexType row, const IndexType column)
creational () access
Definition: SparseMatrix.h:137
ConstIterator Find(const IndexType row, const IndexType column) const
Definition: SparseMatrix.h:226
Vector operator*(const double d, const Vector &v)
Definition: OperationsVV.h:38
Index(const IndexType row, const IndexType column)
Definition: SparseMatrix.h:59
void Erase(const MapIterator it)
Definition: SparseMatrix.h:274
const IndexType fRow
Definition: SparseMatrix.h:53
bool operator!=(const SparseMatrix< U > &m) const
Definition: SparseMatrix.h:210
MapType::iterator MapIterator
Definition: SparseMatrix.h:81
std::map< IndexKeyType, T > MapType
Definition: SparseMatrix.h:79
SparseMatrix< T >::Index IndexKeyType
Definition: SparseMatrix.h:78
bool operator!=(const SparseMatrix &m) const
be sure to call Reclaim() first
Definition: SparseMatrix.h:182
const SparseMatrix & fSparseMatrix
Definition: SparseMatrix.h:52
IndexType GetRow() const
Definition: SparseMatrix.h:62
Iterator Find(const IndexType row, const IndexType column)
Definition: SparseMatrix.h:223
SparseMatrix & operator+=(const SparseMatrix< U > &m)
matrix addition
Definition: SparseMatrix.h:242
ConstIterator SparseBegin() const
Definition: SparseMatrix.h:217
Stream & Output(Stream &s, const SparseMatrix< T > &m, const typename SparseMatrix< T >::IndexType rows, const typename SparseMatrix< T >::IndexType columns, const char separator= ' ')
Definition: SparseMatrix.h:386
bool operator<(const Index &i) const
Definition: SparseMatrix.h:66
constexpr double m
Definition: AugerUnits.h:121
const T & GetInitializer() const
Definition: SparseMatrix.h:125
bool operator==(const SparseMatrix< U > &m) const
Definition: SparseMatrix.h:186
Iterator SparseBegin()
Definition: SparseMatrix.h:215
unsigned int Reclaim()
Definition: SparseMatrix.h:163

, generated on Tue Sep 26 2023.