Ocean
SparseMatrix.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_MATH_SPARSE_MATRIX_H
9 #define META_OCEAN_MATH_SPARSE_MATRIX_H
10 
11 #include "ocean/math/Math.h"
12 #include "ocean/math/Matrix.h"
13 
14 #include <vector>
15 
16 namespace Ocean
17 {
18 
19 // Forward declaration.
20 template <typename T> class MatrixT;
21 
22 // Forward declaration.
23 template <typename T> class SparseMatrixT;
24 
25 /**
26  * Definition of the SparseMatrix object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with single or double precision float data type.
27  * @see SparseMatrixT
28  * @ingroup math
29  */
31 
32 /**
33  * Instantiation of the SparseMatrixT template class using a double precision float data type.
34  * @see SparseMatrixT
35  * @ingroup math
36  */
38 
39 /**
40  * Instantiation of the SparseMatrixT template class using a single precision float data type.
41  * @see SparseMatrixT
42  * @ingroup math
43  */
45 
46 /**
47  * Definition of a vector holding sparse matrix objects.
48  * @see SparseMatrix
49  * @ingroup math
50  */
51 typedef std::vector<SparseMatrix> SparseMatrices;
52 
53 /**
54  * This class implements a sparse matrix using a float type for its elements that is specified by T.
55  * @tparam T Data type of matrix elements
56  * @see SparseMatrix, SparseMatrixF, SparseMatrixD, Matrix.
57  * @ingroup math
58  */
59 template <typename T>
61 {
62  public:
63 
64  // Forward declaration.
65  class Entry;
66 
67  /**
68  * Definition of a vector holding entries.
69  */
70  typedef std::vector<Entry> Entries;
71 
72  /**
73  * This class implements a triple object for matrix entries.
74  */
75  class OCEAN_MATH_EXPORT Entry
76  {
77  public:
78 
79  /**
80  * Creates an invalid entry object.
81  */
82  inline Entry();
83 
84  /**
85  * Creates a new entry object.
86  * @param row The row of the entry
87  * @param column The column of the entry
88  * @param value The value of the entry
89  */
90  inline Entry(const size_t row, const size_t column, const T value);
91 
92  /**
93  * Returns the row of this entry
94  * @return The row
95  */
96  inline size_t row() const;
97 
98  /**
99  * Returns the column of this entry
100  * @return The column
101  */
102  inline size_t column() const;
103 
104  /**
105  * Returns the value of this entry
106  * @return The value
107  */
108  inline T value() const;
109 
110  /**
111  * Returns whether this entry is valid.
112  * @return True, if so
113  */
114  inline bool isValid() const;
115 
116  /**
117  * Compares two entries and returns whether this entry is 'lesser' than the second entry.
118  * Beware: The result is composed only on the coordinate of this entry, not on the value (thus, two entries with same coordinate but different value count as identical).
119  * @param second The second entry to compare
120  * @return True, if so
121  */
122  inline bool operator<(const Entry& second) const;
123 
124  /**
125  * Checks whether a set of given entries have at least one entry in each row and in each column of a matrix with defined dimension.
126  * @param rows The number of rows of the matrix, with range [1, infinity)
127  * @param columns The number of columns of the matrix, with range [1, infinity)
128  * @param entries The entries to check
129  * @return True, if so
130  */
131  static bool hasOneEntry(const size_t rows, const size_t columns, const Entries& entries);
132 
133  protected:
134 
135  /// The row of this entry.
136  size_t entryRow;
137 
138  /// The column of this entry.
139  size_t entryColumn;
140 
141  /// The value of this entry.
143  };
144 
145  public:
146 
147  /**
148  * Creates an empty sparse matrix object.
149  */
151 
152  /**
153  * Copy constructor.
154  * @param matrix Sparse matrix to be copied
155  */
157 
158  /**
159  * Move constructor.
160  * @param matrix Sparse matrix to be movied
161  */
162  SparseMatrixT(SparseMatrixT<T>&& matrix) noexcept;
163 
164  /**
165  * Creates a new spare matrix with given dimensions.
166  * @param rows Number of rows to create a sparse matrix for
167  * @param columns Number of columns to create a sparse matrix for
168  */
169  SparseMatrixT(const size_t rows, const size_t columns);
170 
171  /**
172  * Creates a new spare matrix with given dimensions.
173  * @param rows Number of rows to create a sparse matrix for
174  * @param columns Number of columns to create a sparse matrix for
175  * @param nonZeroElements Number of expected non zero elements to reserve memory for
176  */
177  SparseMatrixT(const size_t rows, const size_t columns, const size_t nonZeroElements);
178 
179  /**
180  * Creates a new spare matrix with given dimensions.
181  * @param rows Number of rows to create a sparse matrix for
182  * @param columns Number of columns to create a sparse matrix for
183  * @param entries All non-zero entries of the new matrix
184  */
185  SparseMatrixT(const size_t rows, const size_t columns, const Entries& entries);
186 
187  /**
188  * Creates a new sparse matrix with defined rows and columns and initializes the diagonal with small sub matrices.
189  * The number of columns of the given diagonal vector matrix defines the size of the small sub matrices.<br>
190  * The number of rows of the diagonal vector matrix must be a multiple of the number of rows.<br>
191  * @param rows Rows of the new matrix
192  * @param columns Columns of the new matrix
193  * @param diagonal Diagonal vector matrix holding the new diagonal sub matrices
194  * @param forceNonZeros True, to force all diagonal elements to be an epsilon larger than zero (if the given element is zero)
195  */
196  SparseMatrixT(const size_t rows, const size_t columns, const MatrixT<T>& diagonal, const bool forceNonZeros = false);
197 
198  /**
199  * Creates a new sparse matrix with defined rows and columns and copies all non-zero values from a dense matrix.
200  * @param denseMatrix Dense matrix from that the non-zero values are copied
201  */
203 
204  /**
205  * Destructs a sparse matrix object.
206  */
208 
209  /**
210  * Returns the number of rows this matrix has
211  * @return Number of rows
212  */
213  size_t rows() const;
214 
215  /**
216  * Returns the number of columns this matrix has.
217  * @return Number of columns
218  */
219  size_t columns() const;
220 
221  /**
222  * Returns the number of non zero elements stored in this matrix.
223  * @return Number of non zero elements
224  */
225  size_t nonZeroElements() const;
226 
227  /**
228  * Returns a vector containing the values of the diagonal.
229  * @return Vector with diagonal values with dimension n x 1
230  */
232 
233  /**
234  * Reserves memory for a specified number of non zero elements.
235  * @param elements Number of non zero elements.
236  */
237  void reserve(const size_t elements);
238 
239  /**
240  * Returns whether a specified elements is zero.
241  * @param row The row of the element to be checked
242  * @param column The column of the element to be checked
243  * @return True, if so
244  */
245  bool isZero(const size_t row, const size_t column) const;
246 
247  /**
248  * Returns whether two matrices are almost identical up to a specified epsilon.
249  * @param matrix Second matrix that will be checked
250  * @param eps Epsilon to be used
251  * @return True, if so
252  */
253  bool isEqual(const SparseMatrixT<T>& matrix, const T eps) const;
254 
255  /**
256  * Returns whether two matrices are almost identical up to a specified epsilon.
257  * @param matrix Second matrix that will be checked
258  * @param eps Epsilon to be used
259  * @return True, if so
260  */
261  bool isEqual(const MatrixT<T>& matrix, const T eps) const;
262 
263  /**
264  * (Re-)sets the non-zero entries of this sparse matrix.
265  * All previous non-zero entries will be removed.<br>
266  * If the given set of entries contains zero-values these zero values will be skipped.
267  * @param entries The entries to set
268  */
269  void setEntries(const Entries& entries);
270 
271  /**
272  * Returns a submatrix of this matrix.
273  * @param row The index of the row which will be the first row of the new submatrix, with range [0, rows())
274  * @param column The index of the column which will be the first column of the new sub-matrix, with range [0, colums())
275  * @param rows The number of rows of the new sub-matrix, with range [1, rows() - row]
276  * @param columns The number of columns of the new sub-matrix, with range [1, columns() - column]
277  * @return The specified submatrix of this matrix
278  */
279  SparseMatrixT<T> submatrix(const size_t row, const size_t column, const size_t rows, const size_t columns) const;
280 
281  /**
282  * Returns the transposes matrix of this matrix.
283  * @return Transposes matrix of this matrix
284  */
286 
287  /**
288  * Transposes this matrix.
289  */
290  void transpose();
291 
292  /**
293  * Solves the given linear system.
294  * M * x = b, with M and b known.<br>
295  * This matrix is M, the given vector is b and the result will be x.<br>
296  * @param b Vector defining the linear system
297  * @param x Solution vector receiving the solution if existing
298  * @return True, if succeeded
299  */
300  bool solve(const MatrixT<T>& b, MatrixT<T>& x) const;
301 
302  /**
303  * Computes the rank of this matrix.
304  * The matrix must be valid.
305  * @return The matrix's rank with range [0, min(rows(), columns())]
306  */
307  size_t rank() const;
308 
309  /**
310  * Determines the sum of all elements of this matrix.
311  * @return Matrix sum
312  */
313  inline T sum() const;
314 
315  /**
316  * Inverts this square diagonal matrix.
317  * @return True, if succeeded
318  */
320 
321  /**
322  * Inverts this square block diagonal matrix with 3x3 block size.
323  * The size of the matrix must be a multiple of three.<br>
324  * Each of the 3x3 block is inverted individually.<br>
325  * @return True, if succeeded
326  */
328 
329  /**
330  * Inverts this square block diagonal matrix with size x size block size.
331  * The size of the matrix must be a multiple of size.<br>
332  * Each of the size x size block is inverted individually.<br>
333  * @param size The size of the block (size x size) with range (2, infinity)
334  * @return True, if succeeded
335  */
336  bool invertBlockDiagonal(const size_t size);
337 
338  /**
339  * Returns the dense matrix of this matrix.
340  * @return Dense matrix
341  */
343 
344  /**
345  * Performs a non-negative matrix factorization with multiplicative update rules
346  * V = W * H, V is a matrix containing non-negative values<br>
347  * This matrix is V, and will be factorized into two matrices W (weights) and H (subcomponents).
348  * @param subcomponents Solution matrix containing base component vectors
349  * @param weights Solution matrix containing weights to the component vectors
350  * @param components Number of base component vectors (Number of components is usally much smaller than its rank). If set to 0, the rank of matrix is used [0, rank]
351  * @param iterations Number of iterations maximal performed [1, infinity)
352  * @param convergenceThreshold Differential threshold as convergence criterion (0, infinity)
353  * @return True, if succeeded
354  */
355  bool nonNegativeMatrixFactorization(MatrixT<T>& subcomponents, MatrixT<T>& weights, const unsigned int components = 0u, const unsigned int iterations = 100u, const T convergenceThreshold = T(0.0001)) const;
356 
357  /**
358  * Assign operator.
359  * @param matrix Sparse matrix to be assigned to this matrix
360  * @return Reference to this matrix
361  */
363 
364  /**
365  * Move operator.
366  * @param matrix Sparse matrix to be move to this matrix
367  * @return Reference to this matrix
368  */
370 
371  /**
372  * Multiplies two sparse matrix objects and returns the matrix result.
373  * @param matrix Right sparse matrix to multiply
374  * @return Matrix product result
375  */
377 
378  /**
379  * Multiplies a second sparse matrix object to this matrix object.
380  * @param matrix Right sparse matrix to multiply
381  * @return Reference to this (modified) sparse matrix
382  */
383  inline SparseMatrixT<T>& operator*=(const SparseMatrixT<T>& matrix);
384 
385  /**
386  * Adds two sparse matrix objects and returns the matrix result.
387  * @param matrix Right sparse matrix to add
388  * @return Matrix result
389  */
391 
392  /**
393  * Adds a second sparse matrix object to this matrix.
394  * @param matrix Right sparse matrix to add
395  * @return Reference to this (modified) matrix
396  */
398 
399  /**
400  * Subtracts two sparse matrix objects and returns the matrix result.
401  * @param matrix Right sparse matrix to subtract
402  * @return Matrix result
403  */
405 
406  /**
407  * Subtracts a second sparse matrix object from this matrix.
408  * @param matrix Right sparse matrix to subtract
409  * @return Reference to this (modified) matrix
410  */
412 
413  /**
414  * Multiplies a dense matrix object on this sparse matrix object and returns the dense matrix result.
415  * @param matrix Right matrix to multiply
416  * @return Matrix product result
417  */
418  MatrixT<T> operator*(const MatrixT<T>& matrix) const;
419 
420  /**
421  * Returns whether this matrix is equal to an other one up to an epsilon value.
422  * @param matrix Second matrix to compare
423  * @return True, if succeeded
424  */
425  bool operator==(const SparseMatrixT<T>& matrix) const;
426 
427  /**
428  * Returns whether this matrix is equal to an other one up to an epsilon value.
429  * @param matrix Second matrix to compare
430  * @return True, if succeeded
431  */
432  bool operator==(const MatrixT<T>& matrix) const;
433 
434  /**
435  * Returns a specific element of the sparse matrix.
436  * @param row Element row to be returned
437  * @param column Element column to be returned
438  * @return Matrix element
439  */
440  T operator()(const size_t row, const size_t column) const;
441 
442  /**
443  * Returns the reference to a specific element of the sparse matrix.
444  * Beware: The element must be non zero, thus the element must have been inserted before!
445  * @param row Element row to be returned
446  * @param column Element column to be returned
447  * @return Matrix element
448  * @see insert().
449  */
450  T& operator()(const size_t row, const size_t column);
451 
452  private:
453 
454  /**
455  * Creates a new sparse matrix object by the internal matrix object data directly.
456  * @param matrix Internal matrix object
457  */
458  explicit SparseMatrixT<T>(void* matrix);
459 
460  private:
461 
462  /// Abstract pointer to the internal matrix object.
464 };
465 
466 template <typename T>
468  entryRow(size_t(-1)),
469  entryColumn(size_t(-1)),
470  entryValue(T(0))
471 {
472  // nothing to do here
473 }
474 
475 template <typename T>
476 inline SparseMatrixT<T>::Entry::Entry(const size_t row, const size_t column, const T value) :
477  entryRow(row),
478  entryColumn(column),
479  entryValue(value)
480 {
481  // nothing to do here
482 }
483 
484 template <typename T>
485 inline size_t SparseMatrixT<T>::Entry::row() const
486 {
487  return entryRow;
488 }
489 
490 template <typename T>
491 inline size_t SparseMatrixT<T>::Entry::column() const
492 {
493  return entryColumn;
494 }
495 
496 template <typename T>
498 {
499  return entryValue;
500 }
501 
502 template <typename T>
504 {
505  return entryRow != size_t(-1) && entryColumn != size_t(-1);
506 }
507 
508 template <typename T>
509 inline bool SparseMatrixT<T>::Entry::operator<(const Entry& second) const
510 {
511  return entryRow < second.entryRow || (entryRow == second.entryRow && entryColumn < second.entryColumn);
512 }
513 
514 template <typename T>
516 {
517  *this = (*this) * matrix;
518  return *this;
519 }
520 
521 template <typename T>
522 inline bool SparseMatrixT<T>::operator==(const SparseMatrixT<T>& matrix) const
523 {
524  return isEqual(matrix, NumericT<T>::eps());
525 }
526 
527 template <typename T>
528 inline bool SparseMatrixT<T>::operator==(const MatrixT<T>& matrix) const
529 {
530  return isEqual(matrix, NumericT<T>::eps());
531 }
532 
533 }
534 
535 #endif // META_OCEAN_MATH_SPARSE_MATRIX_H
This class implements a matrix with arbitrary size.
Definition: Matrix.h:63
This class provides basic numeric functionalities.
Definition: Numeric.h:57
This class implements a triple object for matrix entries.
Definition: SparseMatrix.h:76
bool isValid() const
Returns whether this entry is valid.
Definition: SparseMatrix.h:503
size_t column() const
Returns the column of this entry.
Definition: SparseMatrix.h:491
T value() const
Returns the value of this entry.
Definition: SparseMatrix.h:497
size_t entryRow
The row of this entry.
Definition: SparseMatrix.h:136
size_t entryColumn
The column of this entry.
Definition: SparseMatrix.h:139
static bool hasOneEntry(const size_t rows, const size_t columns, const Entries &entries)
Checks whether a set of given entries have at least one entry in each row and in each column of a mat...
bool operator<(const Entry &second) const
Compares two entries and returns whether this entry is 'lesser' than the second entry.
Definition: SparseMatrix.h:509
Entry()
Creates an invalid entry object.
Definition: SparseMatrix.h:467
size_t row() const
Returns the row of this entry.
Definition: SparseMatrix.h:485
T entryValue
The value of this entry.
Definition: SparseMatrix.h:142
This class implements a sparse matrix using a float type for its elements that is specified by T.
Definition: SparseMatrix.h:61
void reserve(const size_t elements)
Reserves memory for a specified number of non zero elements.
bool invertBlockDiagonal3()
Inverts this square block diagonal matrix with 3x3 block size.
T sum() const
Determines the sum of all elements of this matrix.
SparseMatrixT< T > operator*(const SparseMatrixT< T > &matrix) const
Multiplies two sparse matrix objects and returns the matrix result.
SparseMatrixT(const size_t rows, const size_t columns, const Entries &entries)
Creates a new spare matrix with given dimensions.
bool isZero(const size_t row, const size_t column) const
Returns whether a specified elements is zero.
SparseMatrixT< T > submatrix(const size_t row, const size_t column, const size_t rows, const size_t columns) const
Returns a submatrix of this matrix.
bool isEqual(const SparseMatrixT< T > &matrix, const T eps) const
Returns whether two matrices are almost identical up to a specified epsilon.
SparseMatrixT(const size_t rows, const size_t columns)
Creates a new spare matrix with given dimensions.
SparseMatrixT< T > & operator=(SparseMatrixT< T > &&matrix) noexcept
Move operator.
MatrixT< T > operator*(const MatrixT< T > &matrix) const
Multiplies a dense matrix object on this sparse matrix object and returns the dense matrix result.
size_t rows() const
Returns the number of rows this matrix has.
SparseMatrixT(const MatrixT< T > &denseMatrix)
Creates a new sparse matrix with defined rows and columns and copies all non-zero values from a dense...
bool isEqual(const MatrixT< T > &matrix, const T eps) const
Returns whether two matrices are almost identical up to a specified epsilon.
size_t nonZeroElements() const
Returns the number of non zero elements stored in this matrix.
~SparseMatrixT()
Destructs a sparse matrix object.
SparseMatrixT(const SparseMatrixT< T > &matrix)
Copy constructor.
std::vector< Entry > Entries
Definition of a vector holding entries.
Definition: SparseMatrix.h:65
void * internalMatrix
Abstract pointer to the internal matrix object.
Definition: SparseMatrix.h:463
SparseMatrixT< T > & operator=(const SparseMatrixT< T > &matrix)
Assign operator.
SparseMatrixT()
Creates an empty sparse matrix object.
size_t columns() const
Returns the number of columns this matrix has.
void setEntries(const Entries &entries)
(Re-)sets the non-zero entries of this sparse matrix.
bool solve(const MatrixT< T > &b, MatrixT< T > &x) const
Solves the given linear system.
bool operator==(const SparseMatrixT< T > &matrix) const
Returns whether this matrix is equal to an other one up to an epsilon value.
Definition: SparseMatrix.h:522
void transpose()
Transposes this matrix.
bool invertDiagonal()
Inverts this square diagonal matrix.
bool invertBlockDiagonal(const size_t size)
Inverts this square block diagonal matrix with size x size block size.
size_t rank() const
Computes the rank of this matrix.
SparseMatrixT(const size_t rows, const size_t columns, const size_t nonZeroElements)
Creates a new spare matrix with given dimensions.
SparseMatrixT< T > operator+(const SparseMatrixT< T > &matrix) const
Adds two sparse matrix objects and returns the matrix result.
SparseMatrixT< T > & operator*=(const SparseMatrixT< T > &matrix)
Multiplies a second sparse matrix object to this matrix object.
Definition: SparseMatrix.h:515
MatrixT< T > denseMatrix() const
Returns the dense matrix of this matrix.
SparseMatrixT< T > operator-(const SparseMatrixT< T > &matrix) const
Subtracts two sparse matrix objects and returns the matrix result.
MatrixT< T > diagonal() const
Returns a vector containing the values of the diagonal.
bool nonNegativeMatrixFactorization(MatrixT< T > &subcomponents, MatrixT< T > &weights, const unsigned int components=0u, const unsigned int iterations=100u, const T convergenceThreshold=T(0.0001)) const
Performs a non-negative matrix factorization with multiplicative update rules V = W * H,...
T & operator()(const size_t row, const size_t column)
Returns the reference to a specific element of the sparse matrix.
SparseMatrixT(const size_t rows, const size_t columns, const MatrixT< T > &diagonal, const bool forceNonZeros=false)
Creates a new sparse matrix with defined rows and columns and initializes the diagonal with small sub...
SparseMatrixT(SparseMatrixT< T > &&matrix) noexcept
Move constructor.
SparseMatrixT< T > transposed() const
Returns the transposes matrix of this matrix.
SparseMatrixT< T > & operator-=(const SparseMatrixT< T > &matrix)
Subtracts a second sparse matrix object from this matrix.
T operator()(const size_t row, const size_t column) const
Returns a specific element of the sparse matrix.
SparseMatrixT< T > & operator+=(const SparseMatrixT< T > &matrix)
Adds a second sparse matrix object to this matrix.
std::vector< SparseMatrix > SparseMatrices
Definition of a vector holding sparse matrix objects.
Definition: SparseMatrix.h:51
SparseMatrixT< Scalar > SparseMatrix
Definition of the SparseMatrix object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with s...
Definition: SparseMatrix.h:23
SparseMatrixT< double > SparseMatrixD
Instantiation of the SparseMatrixT template class using a double precision float data type.
Definition: SparseMatrix.h:37
SparseMatrixT< float > SparseMatrixF
Instantiation of the SparseMatrixT template class using a single precision float data type.
Definition: SparseMatrix.h:44
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15