vnl_sparse_matrix.h
Go to the documentation of this file.
1 // This is core/vnl/vnl_sparse_matrix.h
2 #ifndef vnl_sparse_matrix_h_
3 #define vnl_sparse_matrix_h_
4 //:
5 // \file
6 // \brief Simple sparse matrix
7 //
8 // Only those values which
9 // are non-zero are stored. The sparse matrix currently supports
10 // only getting/putting elements, and multiply by vector or another
11 // sparse matrix.
12 //
13 // Each row is stored as a vector of std::pair<unsigned int,T>, where the first
14 // of the pair indicates the column index, and the second the
15 // value. All rows are stored, as std::vector< row >;
16 //
17 // \author Rupert W. Curwen, GE CR&D
18 // \date 20 Oct 98
19 //
20 // \verbatim
21 // Modifications
22 // Robin Flatland 5/31/99 Added pre_mult(lhs,result), where
23 // lhs is a vector.
24 //
25 // Robin Flatland 6/08/99 Added iterator that allows sequential
26 // access to non-zero values in matrix.
27 // Iterator is controlled using reset, next,
28 // getrow, getcolumn, and value.
29 //
30 // David Capel May 2000 Added set_row, scale_row, mult, vcat and const
31 // methods where appropriate.
32 // Peter Vanroose - Jan.2009 - Added several methods, modelled after vnl_matrix<T>:
33 // const version of operator()(unsigned int, unsigned int)
34 // T get(unsigned int, unsigned int)
35 // void put(unsigned int, unsigned int, T)
36 // void clear()
37 // vnl_sparse_matrix& normalize_rows()
38 // bool operator==()
39 // bool operator!=()
40 // unary minus of a matrix
41 // addition of two matrices
42 // subtraction of two matrices
43 // multiplication of two matrices
44 // in-place addition of two matrices
45 // in-place subtraction of two matrices
46 // in-place multiplication of two matrices
47 // scalar multiplication of a matrix
48 // in-place scalar multiplication of a matrix
49 // scalar division of a matrix
50 // in-place scalar division of a matrix
51 // Peter Vanroose - Oct.2010 - Added set_identity()
52 // Peter Vanroose - Mar.2011 - Added transpose() and conjugate_transpose()
53 // \endverbatim
54 
55 #include <vector>
56 #include <functional>
57 #ifdef _MSC_VER
58 # include <vcl_msvc_warnings.h>
59 #endif
60 #include <vnl/vnl_vector.h>
61 #include "vnl/vnl_export.h"
62 
63 //: Stores elements of sparse matrix
64 // Only those values which
65 // are non-zero are stored. The sparse matrix currently supports
66 // only getting/putting elements, and multiply by vector or another
67 // sparse matrix.
68 //
69 // Each row is stored as a vector of std::pair<unsigned int,T>, where the first
70 // of the pair indicates the column index, and the second the
71 // value. All rows are stored, as std::vector< row >;
72 //
73 template <class T>
74 class VNL_EXPORT vnl_sparse_matrix_pair
75 {
76  public:
77  unsigned int first;
78  T second;
79 
80  //: Constructs a pair with null values
81  vnl_sparse_matrix_pair() : first(0), second(T(0)) {}
82 
83  //: Constructs a pair with position a and value b
84  vnl_sparse_matrix_pair(unsigned int const& a, T const& b) : first(a), second(b) {}
85 
86  vnl_sparse_matrix_pair(const vnl_sparse_matrix_pair<T>& o) : first(o.first), second(o.second) {}
87 
89  if (&o != this) {
90  first = o.first;
91  second = o.second;
92  }
93  return *this;
94  }
95 
96  struct less
97  {
98  bool operator() (vnl_sparse_matrix_pair const& p1, vnl_sparse_matrix_pair const& p2) {
99  return p1.first < p2.first;
100  }
101  };
102 };
103 
104 
105 //: Simple sparse matrix
106 // Stores non-zero elements as a sparse_matrix_pair
107 template <class T>
108 class VNL_EXPORT vnl_sparse_matrix
109 {
110  public:
112  typedef std::vector < pair_t > row;
113  typedef std::vector < row > vnl_sparse_matrix_elements;
114 
115  //: Construct an empty matrix
117 
118  //: Construct an empty m*n matrix
119  vnl_sparse_matrix(unsigned int m, unsigned int n);
120 
121  //: Construct an m*n Matrix and copy rhs into it.
123 
124  //: Copy another vnl_sparse_matrix<T> into this.
125  vnl_sparse_matrix<T>& operator=(vnl_sparse_matrix<T> const& rhs);
126 
127  //: Multiply this*rhs, where rhs is a vector.
128  void mult(vnl_vector<T> const& rhs, vnl_vector<T>& result) const;
129 
130  //: Multiply this*p, a fortran order matrix.
131  void mult(unsigned int n, unsigned int m, T const* p, T* q) const;
132 
133  //: Multiplies lhs*this, where lhs is a vector
134  void pre_mult(const vnl_vector<T>& lhs, vnl_vector<T>& result) const;
135 
136  //: Get a reference to an entry in the matrix.
137  T& operator()(unsigned int row, unsigned int column);
138 
139  //: Get the value of an entry in the matrix.
140  T operator()(unsigned int row, unsigned int column) const;
141 
142  //: Get an entry in the matrix.
143  // This is the "const" version of operator().
144  T get(unsigned int row, unsigned int column) const;
145 
146  //: Put (i.e., add or overwrite) an entry into the matrix.
147  void put(unsigned int row, unsigned int column, T value);
148 
149  //: Get diag(A_transpose * A).
150  // Useful for forming Jacobi preconditioners for linear solvers.
151  void diag_AtA(vnl_vector<T>& result) const;
152 
153  //: Set a whole row at once. Much faster. Returns *this.
154  vnl_sparse_matrix& set_row(unsigned int r,
155  std::vector<int> const& cols,
156  std::vector<T> const& vals);
157 
158  //: Return row as vector of pairs
159  // Added to aid binary I/O
160  row& get_row(unsigned int r) {return elements[r];}
161 
162  //: Laminate matrix A onto the bottom of this one
164 
165  //: Get the number of rows in the matrix.
166  unsigned int rows() const { return rs_; }
167 
168  //: Get the number of columns in the matrix.
169  unsigned int columns() const { return cs_; }
170 
171  //: Get the number of columns in the matrix.
172  unsigned int cols() const { return cs_; }
173 
174  //: Return whether a given row is empty
175  bool empty_row(unsigned int r) const { return elements[r].empty(); }
176 
177  //: This is occasionally useful.
178  T sum_row(unsigned int r);
179 
180  //: Useful for normalizing row sums in convolution operators
181  vnl_sparse_matrix& scale_row(unsigned int r, T scale);
182 
183  //: Set all elements to null
184  void clear() { elements.clear(); }
185 
186  //: Resizes the array to have r rows and c cols -- sets elements to null
187  void set_size( int r, int c );
188 
189  //: Resizes the array to have r rows and c cols
190  void resize( int r, int c );
191 
192  //: Resets the internal iterator
193  void reset() const;
194 
195  //: Moves the internal iterator to next non-zero entry in matrix.
196  // Returns true if there is another value, false otherwise. Use
197  // in combination with methods reset, getrow, getcolumn, and value.
198  bool next() const;
199 
200  //: Returns the row of the entry pointed to by internal iterator.
201  int getrow() const;
202 
203  //: Returns the column of the entry pointed to by internal iterator.
204  int getcolumn() const;
205 
206  //: Returns the value pointed to by the internal iterator.
207  T value() const;
208 
209  //: Comparison
210  bool operator==(vnl_sparse_matrix<T> const& rhs) const;
211 
212  //: Inequality
213  bool operator!=(vnl_sparse_matrix<T> const& rhs) const
214  { return !operator==(rhs); }
215 
216  //: Unary minus
218 
219  //: addition
221 
222  //: subtraction
224 
225  //: multiplication
227 
228  //: in-place addition
229  vnl_sparse_matrix<T>& operator+=(vnl_sparse_matrix<T> const& rhs);
230 
231  //: in-place subtraction
232  vnl_sparse_matrix<T>& operator-=(vnl_sparse_matrix<T> const& rhs);
233 
234  //: in-place multiplication
235  vnl_sparse_matrix<T>& operator*=(vnl_sparse_matrix<T> const& rhs);
236 
237  //: scalar multiplication
238  vnl_sparse_matrix<T> operator*(T const& rhs) const;
239 
240  //: in-place scalar multiplication
241  vnl_sparse_matrix<T>& operator*=(T const& rhs);
242 
243  //: scalar division
244  vnl_sparse_matrix<T> operator/(T const& rhs) const;
245 
246  //: in-place scalar division
247  vnl_sparse_matrix<T>& operator/=(T const& rhs);
248 
249  //: returns a new sparse matrix, viz. the transpose of this
250  vnl_sparse_matrix<T> transpose() const;
251 
252  //: returns a new sparse matrix, viz. the conjugate (or Hermitian) transpose of this
253  vnl_sparse_matrix<T> conjugate_transpose() const;
254 
255  //: Sets this matrix to an identity matrix, then returns "*this".
256  // Returning "*this" allows e.g. passing an identity matrix as argument to
257  // a function f, without having to name the constructed matrix:
258  // \code
259  // f(vnl_sparse_matrix<double>(5000,5000).set_identity());
260  // \endcode
261  // Returning "*this" also allows "chaining" two or more operations:
262  // e.g., to set a matrix to identity, then add an other matrix to it:
263  // \code
264  // M.set_identity() += M2;
265  // \endcode
266  // If the matrix is not square, anyhow set main diagonal to 1, the rest to 0.
267  vnl_sparse_matrix& set_identity();
268 
269  //: Normalizes each row so it is a unit vector, and returns "*this".
270  // Zero rows are not modified
271  // Returning "*this" allows "chaining" two or more operations:
272  // \code
273  // M.normalize_rows() += M2;
274  // \endcode
275  // Note that there is no method normalize_columns() since its implementation
276  // would be much more inefficient than normalize_rows()!
277  vnl_sparse_matrix& normalize_rows();
278 
279  // These three methods are used to implement their operator() variants
280  // They should ideally be protected, but for backward compatibility reasons
281  // they continue to be public for a while ...
282 
283  //: Add rhs to this.
284  // Deprecated for direct use: please use operator "+" instead.
285  void add(const vnl_sparse_matrix<T>& rhs, vnl_sparse_matrix<T>& result) const;
286 
287  //: Subtract rhs from this.
288  // Deprecated for direct use: please use operator "-" instead.
289  void subtract(const vnl_sparse_matrix<T>& rhs, vnl_sparse_matrix<T>& result) const;
290 
291  //: Multiply this*rhs, another sparse matrix.
292  // Deprecated for direct use: please use operator "*" instead.
293  void mult(vnl_sparse_matrix<T> const& rhs, vnl_sparse_matrix<T>& result) const;
294 
295  protected:
297  unsigned int rs_, cs_;
298 
299  // internal iterator
300  mutable unsigned int itr_row;
301  mutable typename row::const_iterator itr_cur;
302  mutable bool itr_isreset;
303 };
304 
305 // non-member arithmetical operators.
306 
307 //:
308 // \relatesalso vnl_matrix
309 template<class T>
310 inline vnl_sparse_matrix<T> operator*(T const& value, vnl_sparse_matrix<T> const& m)
311 {
312  return m * value;
313 }
314 
315 
316 #endif // vnl_sparse_matrix_h_
std::vector< pair_t > row
unsigned int columns() const
Get the number of columns in the matrix.
Simple sparse matrix.
row::const_iterator itr_cur
vnl_sparse_matrix< T > operator *(T const &value, vnl_sparse_matrix< T > const &m)
#define m
Definition: vnl_vector.h:43
unsigned int cols() const
Get the number of columns in the matrix.
void add(const vnl_bignum &b1, const vnl_bignum &b2, vnl_bignum &sum)
add two non-infinite vnl_bignum values and save their sum.
Definition: vnl_bignum.cxx:887
vnl_sparse_matrix_pair< T > & operator=(vnl_sparse_matrix_pair const &o)
void clear()
Set all elements to null.
vnl_sparse_matrix_elements elements
bool empty_row(unsigned int r) const
Return whether a given row is empty.
void subtract(const vnl_bignum &bmax, const vnl_bignum &bmin, vnl_bignum &diff)
subtract bmin from bmax (unsigned, non-infinite), result in diff.
Definition: vnl_bignum.cxx:947
vnl_bignum operator-(vnl_bignum const &r1, vnl_bignum const &r2)
Returns the difference of two bignum numbers.
Definition: vnl_bignum.h:290
std::vector< row > vnl_sparse_matrix_elements
vnl_sparse_matrix_pair(const vnl_sparse_matrix_pair< T > &o)
unsigned int rows() const
Get the number of rows in the matrix.
vnl_sparse_matrix_pair()
Constructs a pair with null values.
vnl_sparse_matrix_pair(unsigned int const &a, T const &b)
Constructs a pair with position a and value b.
Mathematical vector class, templated by type of element.
Definition: vnl_fwd.h:16
vnl_bignum operator+(vnl_bignum const &r1, long r2)
Returns the sum of two bignum numbers.
Definition: vnl_bignum.h:279
row & get_row(unsigned int r)
Return row as vector of pairs.
bool operator==(const vnl_amoeba_SimplexCorner &a, const vnl_amoeba_SimplexCorner &b)
Definition: vnl_amoeba.cxx:143
Stores elements of sparse matrix.
vnl_bignum operator/(vnl_bignum const &r1, vnl_bignum const &r2)
Returns the division of two bignum numbers.
Definition: vnl_bignum.h:349
bool operator!=(vnl_sparse_matrix< T > const &rhs) const
Inequality.
vnl_bignum operator *(vnl_bignum const &r1, vnl_bignum const &r2)
Returns the product of two bignum numbers.
Definition: vnl_bignum.h:302
vnl_sparse_matrix_pair< T > pair_t