Ocean
Matrix.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_MATRIX_H
9 #define META_OCEAN_MATH_MATRIX_H
10 
11 #include "ocean/math/Math.h"
12 #include "ocean/math/Numeric.h"
13 
14 namespace Ocean
15 {
16 
17 // Forward declaration.
18 template <typename T> class MatrixT;
19 
20 /**
21  * Definition of the Matrix object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with single or double precision float data type.
22  * @see MatrixT
23  * @ingroup math
24  */
26 
27 /**
28  * Definition of the MatrixT template class using a double precision float data type.
29  * @see MatrixT
30  * @ingroup math
31  */
33 
34 /**
35  * Definition of the MatrixT template class using a single precision float data type.
36  * @see MatrixT
37  * @ingroup math
38  */
40 
41 /**
42  * Definition of a vector holding matrix objects.
43  * @see Matrix
44  * @ingroup math
45  */
46 typedef std::vector<Matrix> Matrices;
47 
48 /**
49  * This class implements a matrix with arbitrary size.
50  * The elements of this matrix are stored in a row aligned order.<br>
51  * That means that elements are stored in the following pattern:
52  * <pre>
53  * | 0 1 2 3 4 ... c-1 |
54  * | c c+1 c+2 c+3 c+4 ... |
55  * | ... |
56  * </pre>
57  * @tparam T Data type of matrix elements
58  * @see Matrix, MatrixF, MatrixD, StaticMatrix, SparseMatrix, SquareMatrix2, SquareMatrix3, SquareMatrix4.
59  * @ingroup math
60  */
61 template <typename T>
62 class MatrixT
63 {
64  public:
65 
66  /**
67  * Definition of the used data type.
68  */
69  typedef T Type;
70 
71  /**
72  * Definition of specific properties of matrices.
73  */
75  {
76  /// No specific property known.
78  /// The matrix is symmetric.
80  };
81 
82  public:
83 
84  /**
85  * Creates a new matrix with no size.
86  */
87  MatrixT() = default;
88 
89  /**
90  * Creates a new matrix with defined rows and columns.
91  * @param rows The rows of the new matrix
92  * @param columns The columns of the new matrix
93  */
94  MatrixT(const size_t rows, const size_t columns);
95 
96  /**
97  * Creates a new matrix with defined rows and columns.
98  * @param rows The rows of the new matrix
99  * @param columns The columns of the new matrix
100  * @param toIdentity Determines whether the matrix will be initialized with as entity matrix or zero matrix.
101  */
102  MatrixT(const size_t rows, const size_t columns, bool toIdentity);
103 
104  /**
105  * Creates a new matrix with defined rows and columns.
106  * @param rows The rows of the new matrix
107  * @param columns The columns of the new matrix
108  * @param value The value that every matrix element will be set to
109  */
110  MatrixT(const size_t rows, const size_t columns, const T value);
111 
112  /**
113  * Creates a new matrix with defined rows and columns.
114  * @param rows The rows of the new matrix
115  * @param columns The columns of the new matrix
116  * @param source Elements to be copied into this matrix
117  */
118  MatrixT(const size_t rows, const size_t columns, const T* source);
119 
120  /**
121  * Creates a new matrix with defined rows and columns.
122  * @param rows The rows of the new matrix
123  * @param columns The columns of the new matrix
124  * @param source Elements to be copied into this matrix
125  * @param valuesRowAligned True, if the given values are stored in a row aligned order (which is the default case for this matrix); False, if the values are stored in a column aligned order
126  */
127  MatrixT(const size_t rows, const size_t columns, const T* source, const bool valuesRowAligned);
128 
129  /**
130  * Creates a new matrix with defined rows and columns and initializes the diagonal with small sub matrices.
131  * The number of columns of the given diagonal vector matrix defines the size of the small sub matrices.<br>
132  * The number of rows of the diagonal vector matrix must be a multiple of the number of rows.<br>
133  * @param rows The rows of the new matrix
134  * @param columns The columns of the new matrix
135  * @param diagonal The diagonal vector matrix holding the new diagonal sub matrices
136  */
137  MatrixT(const size_t rows, const size_t columns, const MatrixT<T>& diagonal);
138 
139  /**
140  * Creates a new matrix with defined rows and columns and a given sub-matrix.
141  * The given sub-matrix can be larger than the new matrix as elements not fitting into the new matrix will be skipped.<br>
142  * All remaining elements of the matrix will be set to the specified value.
143  * @param rows The number of rows the new matrix will have, with range [1, infinity)
144  * @param columns The number of columns the new matrix will have, with range [1, infinity)
145  * @param subMatrix The sub-matrix from which the elements will be copied into the new matrix
146  * @param row The row at which the sub-matrix will be placed in the new matrix, with range [0, rows - 1]
147  * @param column The column at which the sub-matrix will be placed in the new matrix, with range [0, columns - 1]
148  * @param value The value which will be used to fill the remaining matrix elements, with range (-infinity, infinity)
149  */
150  MatrixT(const size_t rows, const size_t columns, const MatrixT<T>& subMatrix, const size_t row, const size_t column, const T value = T(0.0));
151 
152  /**
153  * Copies a matrix.
154  * @param matrix The matrix to copy
155  */
156  MatrixT(const MatrixT<T>& matrix);
157 
158  /**
159  * Move constructor.
160  * @param matrix The matrix to be moved
161  */
162  MatrixT(MatrixT<T>&& matrix) noexcept;
163 
164  /**
165  * Destructs a matrix and releases the elements.
166  */
168 
169  /**
170  * Returns the count of rows.
171  * @return Rows of the matrix, with range [0, infinity)
172  */
173  inline size_t rows() const;
174 
175  /**
176  * Returns the count of columns.
177  * @return Columns of the matrix, with range [0, infinity)
178  */
179  inline size_t columns() const;
180 
181  /**
182  * Returns the number of entire elements, which is the product of rows and columns.
183  * @return Number of elements, with range [0, infinity)
184  */
185  inline size_t elements() const;
186 
187  /**
188  * Returns the inverted of this matrix.
189  * Beware: This function does not throw an exception if the matrix cannot be inverted.<br>
190  * Thus, ensure that the matrix is invertible before calling this function.<br>
191  * This matrix is invertible e.g., if the matrix is square and has full rank (rank() == rows() && rank() == columns()).<br>
192  * Even better: avoid the usage of this function and call invert() instead.<br>
193  * In case, this matrix is not invertible, this matrix will be returned instead.
194  * @return Inverted matrix
195  * @see invert(), rank().
196  */
197  inline MatrixT<T> inverted() const;
198 
199  /**
200  * Inverts this matrix.
201  * @return True, if the matrix is not singular.
202  * @see inverted().
203  */
204  bool invert();
205 
206  /**
207  * Returns the transposed of this matrix.
208  * @return Transposed matrix
209  */
211 
212  /**
213  * Transposes this matrix.
214  */
215  inline void transpose();
216 
217  /**
218  * Returns the matrix product of this matrix and the transposed matrix of this matrix.<br>
219  * The result will be a square matrix with size: rows() x rows().<br>
220  * Actually, the following matrix will be returned: (*this) * (*this).transposed().
221  * @return Resulting matrix
222  */
224 
225  /**
226  * Returns the matrix product of transposed matrix of this matrix and this matrix.<br>
227  * The result will be a square matrix with size: columns() x columns().<br>
228  * Actually, the following matrix will be returned: (*this).transposed() * (*this).
229  * @return Resulting matrix
230  */
232 
233  /**
234  * Returns the matrix product of transposed matrix of this matrix and this matrix.<br>
235  * The result will be a square matrix with size: columns() x columns().<br>
236  * Actually, the following matrix will be returned: (*this).transposed() * (*this).
237  * @param result Resulting matrix
238  */
240 
241  /**
242  * Returns the matrix product of transposed matrix of this matrix and this matrix and applies a further squared diagonal weighting matrix.<br>
243  * The result will be a square matrix with size: columns() x columns().<br>
244  * Actually, the following matrix will be returned: (*this).transposed() * diag(weightDiagonal) * (*this).
245  * @param weightDiagonal Weight vector defining the diagonal of the weighting matrix, with one column
246  * @param result Resulting matrix
247  */
248  void weightedSelfTransposedSquareMatrix(const MatrixT<T>& weightDiagonal, MatrixT<T>& result) const;
249 
250  /**
251  * Interprets this matrix as diagonal matrix and multiplies a second matrix on the right of the interpreted diagonal matrix.
252  * The square sub matrices size is defined by the number of columns of this matrix.<br>
253  * Thus the number of rows must be a multiple of the number of columns of this matrix.<br>
254  * Actually, the following matrix will be returned: result = diag(*this) * right.
255  * @param right The right matrix to be multiplied with the interpreted diagonal matrix
256  * @param result Resulting matrix
257  * @return True, if succeeded
258  */
259  bool selfSquareDiagonalMatrixMultiply(const MatrixT<T>& right, MatrixT<T>& result) const;
260 
261  /**
262  * Interprets this matrix as diagonal matrix and multiplies a second matrix on the right of the interpreted diagonal matrix.
263  * Further, a diagonal weighting vector is applied.<br>
264  * The square sub matrices size is defined by the number of columns of this matrix.<br>
265  * Thus the number of rows must be a multiple of the number of columns of this matrix.<br>
266  * Actually, the following matrix will be returned: result = diag(*this) * diag(weightDiagonal) * right.
267  * @param right The right matrix to be multiplied with the interpreted diagonal matrix
268  * @param weightDiagonal Weight vector defining the diagonal of the weighting matrix, with one column
269  * @param result Resulting matrix
270  * @return True, if succeeded
271  */
272  bool selfSquareDiagonalMatrixMultiply(const MatrixT<T>& weightDiagonal, const MatrixT<T>& right, MatrixT<T>& result) const;
273 
274  /**
275  * Multiplies this transposed matrix with a second matrix.
276  * Actually, the following matrix will be returned: (*this).transposed() * right.<br>
277  * The resulting matrix will have the size: columns() x right.columns().
278  * @param right Matrix to multiply
279  * @return Matrix product
280  */
282 
283  /**
284  * Multiplies this transposed matrix with a second matrix.
285  * Actually, the following matrix will be returned: (*this).transposed() * right.<br>
286  * The resulting matrix will have the size: columns() x right.columns().
287  * @param right Matrix to multiply
288  * @param result Resulting matrix product
289  */
290  void transposedMultiply(const MatrixT<T>& right, MatrixT<T>& result) const;
291 
292  /**
293  * Solves the given linear system.
294  * M * x = b, with M and b known and M is a square matrix<br>
295  * This matrix is M, the given vector is b and the result will be x.<br>
296  * Note: If a non-square matrix should be solved, use: (M.transposed() * M) * x = M.transposed() * b
297  * @param b Vector defining the linear system, with size columns() x 1
298  * @param x Solution vector receiving the solution if existing, with size columns() x 1
299  * @param matrixProperty The property of the matrix allowing to improve the solving performance and stability, MP_UNKNOWN to apply a standard solving
300  * @return True, if succeeded
301  */
302  inline bool solve(const MatrixT<T>& b, MatrixT<T>& x, const MatrixProperty matrixProperty = MP_UNKNOWN) const;
303 
304  /**
305  * Solves the given linear system.
306  * M * x = b, with M and b known and M is a square matrix<br>
307  * This matrix is M, the given vector is b and the result will be x.<br>
308  * Note: If a non-square matrix should be solved, use: (M.transposed() * M) * x = M.transposed() * b
309  * @param b Vector defining the linear system, with size columns() x 1
310  * @param x Solution vector receiving the solution if existing, with size columns() x 1
311  * @return True, if succeeded
312  * @tparam tMatrixProperty The property of the matrix allowing to improve the solving performance and stability, MP_UNKNOWN to apply a standard solving
313  */
314  template <MatrixProperty tMatrixProperty>
315  inline bool solve(const MatrixT<T>& b, MatrixT<T>& x) const;
316 
317  /**
318  * Solves the given linear system.
319  * M * x = b, with M and b known and M is a square matrix<br>
320  * This matrix is M, the given vector is b and the result will be x..<br>
321  * Note: If a non-square matrix should be solved, use: (M.transposed() * M) * x = M.transposed() * b
322  * @param b Pointer to the vector defining the linear system, ensure that the number of provided values is equal to columns()
323  * @param x Pointer to the solution vector receiving the solution if existing, ensure that the number of elements is equal to columns()
324  * @param matrixProperty The property of the matrix allowing to improve the solving performance and stability, MP_UNKNOWN to apply a standard solving
325  * @return True, if succeeded
326  */
327  inline bool solve(const T* b, T* x, const MatrixProperty matrixProperty = MP_UNKNOWN) const;
328 
329  /**
330  * Solves the given linear system.
331  * M * x = b, with M and b known and M is a square matrix<br>
332  * This matrix is M, the given vector is b and the result will be x..<br>
333  * Note: If a non-square matrix should be solved, use: (M.transposed() * M) * x = M.transposed() * b
334  * @param b Pointer to the vector defining the linear system, ensure that the number of provided values is equal to columns()
335  * @param x Pointer to the solution vector receiving the solution if existing, ensure that the number of elements is equal to columns()
336  * @return True, if succeeded
337  * @tparam tMatrixProperty The property of the matrix allowing to improve the solving performance and stability, MP_UNKNOWN to apply a standard solving
338  */
339  template <MatrixProperty tMatrixProperty>
340  bool solve(const T* b, T* x) const;
341 
342  /**
343  * Performs a non-negative matrix factorization with multiplicative update rules
344  * V = W * H, V is a matrix containing non-negative values<br>
345  * This matrix is V, and will be factorized into two matrices W (weights) and H (subcomponents).
346  * @param subcomponents Solution matrix containing base component vectors
347  * @param weights Solution matrix containing weights to the component vectors
348  * @param components Number of base component vectors (Number of components is usually much smaller than its rank). If set to 0, the rank of matrix is used [0, rank]
349  * @param iterations Number of iterations maximal performed [1, infinity)
350  * @param convergenceThreshold Differential threshold aborting the calculation (0, infinity)
351  * @return True, if succeeded
352  */
353  bool nonNegativeMatrixFactorization(MatrixT<T>& subcomponents, MatrixT<T>& weights, const size_t components = 0u, const unsigned int iterations = 100u, const T convergenceThreshold = T(0.0001)) const;
354 
355  /**
356  * Computes the eigen system of this matrix.
357  * The function determines values and vectors that: matrix * vectors = vectors * diagonal(values).<br>
358  * Beware: The eigen values are not ordered!
359  * @param values Vector with resulting eigen values
360  * @param vectors Matrix with resulting eigen vectors as columns
361  * @return True, if succeeded
362  */
363  bool eigenSystem(MatrixT<T>& values, MatrixT<T>& vectors) const;
364 
365  /**
366  * Computes the singular value decomposition for this matrix.
367  * This matrix is decomposed into three matrices as follows: u * w * v.transposed().<br>
368  * The diagonal values of w are ordered in descending order already.
369  * @param u Resulting u matrix
370  * @param w Resulting w vector holding the values of the diagonal matrix
371  * @param v Resulting v matrix
372  * @return True, if succeeded
373  */
375 
376  /**
377  * Computes the QR decomposition for this matrix [m x n] while m >= n must hold.
378  * This matrix is decomposed into two matrices as follows: q * r, where q is a orthogonal [m x m] matrix (m * m^T = I), and r is a upper triangular matrix [m x n].
379  * @param qMatrix Resulting q matrix, containing the null space in the last (m - rank) columns, the size of the matrix will be adjusted internally
380  * @param rMatrix Optional resulting r matrix, upper triangle matrix, the size of the matrix will be adjusted internally, nullptr if the matrix is not needed
381  * @return True, if succeeded
382  */
383  bool qrDecomposition(MatrixT<T>& qMatrix, MatrixT<T>* rMatrix = nullptr) const;
384 
385  /**
386  * Computes the Cholesky decomposition for this square matrix [m x m].
387  * This matrix is decomposed into M = L * L^T, where L is a lower triangular matrix [m x m].
388  * @param lMatrix Resulting L matrix, the lower triangle matrix
389  * @return True, if succeeded
390  */
391  bool choleskyDecomposition(MatrixT<T>& lMatrix) const;
392 
393  /**
394  * Returns the pseudo inverse of this matrix by application of the singular value decomposition.
395  * @param epsilon The tolerance value, with range [0, infinity)
396  * @return The resulting pseudo inverted matrix
397  */
398  MatrixT<T> pseudoInverted(const T epsilon = NumericT<T>::eps()) const;
399 
400  /**
401  * Computes the rank of this matrix.
402  * The matrix must be valid.
403  * @return The matrix's rank with range [0, min(rows(), columns())]
404  */
405  inline size_t rank() const;
406 
407  /**
408  * Returns a row of the matrix.
409  * @param index The index of the row to receive, with range [0, rows())
410  * @return Entire row
411  */
412  MatrixT<T> row(const size_t index) const;
413 
414  /**
415  * Returns a column vector of the matrix.
416  * @param column The column to receive the vector from, with range [0, columns())
417  * @return Column vector
418  */
419  MatrixT<T> vector(const size_t column) const;
420 
421  /**
422  * Returns a vector containing the values of the diagonal.
423  * @return Vector with diagonal values
424  */
426 
427  /**
428  * Determines the L1 norm (sum of absolute elements) of this matrix.
429  * @return Matrix norm
430  */
431  inline T norm() const;
432 
433  /**
434  * Determines the sum of all elements of this matrix.
435  * @return Matrix sum
436  */
437  inline T sum() const;
438 
439  /**
440  * Returns a sub matrix of this one
441  * @param row The start row at which the sub matrix will start, with range [0, row() - 1]
442  * @param column The start column at which the sub matrix will start, with range [0, columns() - 1]
443  * @param rows The number of rows in the sub matrix, with range [1, rows() - row]
444  * @param columns The number of columns in the sub matrix, with range [1, columns() - row]
445  * @return The resulting sub matrix
446  */
447  MatrixT<T> subMatrix(const size_t row, const size_t column, const size_t rows, const size_t columns);
448 
449  /**
450  * Multiplies a row with a scalar.
451  * Beware: No range check will be done!
452  * @param row The row to multiply, with range [0, rows() - 1]
453  * @param scalar The scalar to multiply, with range (-infinity, infinity)
454  */
455  void multiplyRow(const size_t row, const T scalar);
456 
457  /**
458  * Multiplies a column with a scalar.
459  * Beware: No range check will be done!
460  * @param column The column to multiply, with range [0, columns() - 1]
461  * @param scalar The scalar to multiply, with range (-infinity, infinity)
462  */
463  void multiplyColumn(const size_t column, const T scalar);
464 
465  /**
466  * Resizes this matrix.
467  * @param rows Number of rows of the resized matrix
468  * @param columns Number of columns of the resized matrix
469  */
470  void resize(const size_t rows, const size_t columns);
471 
472  /**
473  * Returns whether two matrices are almost identical up to a specified epsilon.
474  * @param matrix Second matrix that will be checked
475  * @param eps The epsilon threshold to be used, with range [0, infinity)
476  * @return True, if so
477  */
478  bool isEqual(const MatrixT<T>& matrix, const T eps = NumericT<T>::eps()) const;
479 
480  /**
481  * Returns whether this matrix is symmetric (and whether this matrix is a square matrix).
482  * Beware: An empty matrix (without any rows or columns) is symmetric.
483  * @param eps The epsilon threshold to be used, with range [0, infinity)
484  * @return True, if so
485  */
486  bool isSymmetric(const T eps = NumericT<T>::eps()) const;
487 
488  /**
489  * Returns a pointer to the internal values.
490  * @return Pointer to the internal values
491  */
492  inline const T* data() const;
493 
494  /**
495  * Returns a pointer to the internal values.
496  * @return Pointer to the internal values
497  */
498  inline T* data();
499 
500  /**
501  * Assigns a matrix to this one.
502  * @param matrix The matrix to assign
503  * @return Reference to this matrix
504  */
505  MatrixT<T>& operator=(const MatrixT<T>& matrix);
506 
507  /**
508  * Move assign operator.
509  * @param matrix The matrix to moved
510  * @return Reference to this matrix
511  */
512  MatrixT<T>& operator=(MatrixT<T>&& matrix) noexcept;
513 
514  /**
515  * Returns whether two matrices are identical up to a small epsilon.
516  * @param right The right matrix
517  * @return True, if so
518  */
519  inline bool operator==(const MatrixT<T>& right) const;
520 
521  /**
522  * Returns whether two matrices are not identical up to a small epsilon.
523  * @param right The right matrix
524  * @return True, if so
525  */
526  inline bool operator!=(const MatrixT<T>& right) const;
527 
528  /**
529  * Adds two matrices.
530  * @param right The right matrix
531  * @return Sum matrix
532  */
533  MatrixT<T> operator+(const MatrixT<T>& right) const;
534 
535  /**
536  * Adds and assigns two matrices.
537  * @param right The right matrix
538  * @return Reference to this matrix
539  */
541 
542  /**
543  * Subtracts two matrices.
544  * @param right The right matrix
545  * @return Subtracted matrix
546  */
547  MatrixT<T> operator-(const MatrixT<T>& right) const;
548 
549  /**
550  * Subtracts and assigns two matrices.
551  * @param right The right matrix
552  * @return Reference to this matrix
553  */
555 
556  /**
557  * Multiplies two matrices.
558  * @param right The right matrix
559  * @return Resulting matrix
560  */
561  MatrixT<T> operator*(const MatrixT<T>& right) const;
562 
563  /**
564  * Multiplies the matrix with a scalar.
565  * @param scalar The scalar to multiply
566  * @return Resulting matrix
567  */
568  MatrixT<T> operator*(const T scalar) const;
569 
570  /**
571  * Multiplies and assigns two matrices.
572  * @param right The right matrix
573  * @return Reference to this matrix
574  */
575  inline MatrixT<T>& operator*=(const MatrixT<T>& right);
576 
577  /**
578  * Multiplies this matrix by a scalar.
579  * @param scalar The scalar to multiply
580  * @return Reference to this matrix
581  */
582  MatrixT<T>& operator*=(const T scalar);
583 
584  /**
585  * Returns the pointer to the elements of a specified row.
586  * @param row Index of the row to return, with range [0, rows())
587  * @return Specified row
588  */
589  inline const T* operator[](const size_t row) const;
590 
591  /**
592  * Element operator for the row aligned elements.
593  * @param row Index of the element to return, with range [0, rows())
594  * @return Specified element
595  */
596  inline T* operator[](const size_t row);
597 
598  /**
599  * Element operator allowing to access a specific elements of this matrix.
600  * @param row The row of the element to return, with range [0, rows())
601  * @param column The column of the element to return, with range [0, columns())
602  * @return Specified element
603  */
604  inline T operator()(const size_t row, const size_t column) const;
605 
606  /**
607  * Element operator allowing to access a specific elements of this matrix.
608  * @param row The row of the element to return, with range [0, rows())
609  * @param column The column of the element to return, with range [0, columns())
610  * @return Specified element
611  */
612  inline T& operator()(const size_t row, const size_t column);
613 
614  /**
615  * Element operator for the row aligned elements.
616  * @param index The index of the element to return, with range [0, elements())
617  * @return Specified element
618  */
619  inline T operator()(const size_t index) const;
620 
621  /**
622  * Element operator for the row aligned elements.
623  * @param index The index of the element to return, with range [0, elements())
624  * @return Specified element
625  */
626  inline T& operator()(const size_t index);
627 
628  /**
629  * Returns whether the matrix holds at least one element.
630  * @return True, if so
631  */
632  explicit inline operator bool() const;
633 
634  /**
635  * Computes the rank of given matrix data.
636  * @param data The elements of the matrix for which the rank will be calculated, provided in a row aligned order, must be valid
637  * @param rows The number of rows of the provided matrix, with range [1, infinity)
638  * @param columns The number of columns of the provided matrix, with range [1, infinity)
639  * @return The matrix's rank with range [0, min(rows, columns)]
640  */
641  static size_t rank(const T* data, const size_t rows, const size_t columns);
642 
643  protected:
644 
645  /**
646  * Swaps two rows.
647  * @param row0 The index of the first row to be swapped, with range [0, rows())
648  * @param row1 The index of the second row to be swapped, with range [0, rows())
649  */
650  void swapRows(const size_t row0, const size_t row1);
651 
652  /**
653  * Swaps two columns.
654  * @param column0 The index of the first column to be swapped, with range [0, columns())
655  * @param column1 The index of the second column to be swapped, with range [0, columns())
656  */
657  void swapColumns(const size_t column0, const size_t column1);
658 
659  /**
660  * Adds a multiple of a row to another one.
661  * @param targetRow The index of the target row to which the multiple of the source row will be added, with range [0, rows())
662  * @param sourceRow The index of the source row, with range [0, rows())
663  * @param scalar The scalar to multiply the source elements with
664  */
665  void addRows(const size_t targetRow, const size_t sourceRow, const T scalar);
666 
667  /**
668  * Performs an element-wise matrix multiplication meaning that each element of this matrix will be multiplied by a corresponding element from 'multiplier'.
669  * @param multiplier The matrix providing the multiplication elements, with same size as this matrix, all elements must not be zero
670  */
671  void elementwiseMultiplication(const MatrixT<T>& multiplier);
672 
673  /**
674  * Performs an element-wise matrix division meaning that each element of this matrix will be divided by a corresponding element from 'denominator'.
675  * @param denominator The matrix providing the denominator elements, with same size as this matrix
676  */
677  void elementwiseDivision(const MatrixT<T>& denominator);
678 
679  protected:
680 
681  /// Number of rows.
682  size_t rows_ = 0;
683 
684  /// Number of columns.
685  size_t columns_ = 0;
686 
687  /// Elements of the matrix.
688  T* values_ = nullptr;
689 };
690 
691 template <typename T>
692 inline size_t MatrixT<T>::rows() const
693 {
694  return rows_;
695 }
696 
697 template <typename T>
698 inline size_t MatrixT<T>::columns() const
699 {
700  return columns_;
701 }
702 
703 template <typename T>
704 inline size_t MatrixT<T>::elements() const
705 {
706  return rows_ * columns_;
707 }
708 
709 template <typename T>
710 inline bool MatrixT<T>::solve(const MatrixT<T>& b, MatrixT<T>& x, const MatrixProperty matrixProperty) const
711 {
712  ocean_assert(columns() == b.rows());
713  ocean_assert(b.columns() == 1);
714 
715  x.resize(columns(), 1);
716  return solve(b.data(), x.data(), matrixProperty);
717 }
718 
719 template <typename T>
720 template <typename MatrixT<T>::MatrixProperty tMatrixProperty>
721 inline bool MatrixT<T>::solve(const MatrixT<T>& b, MatrixT<T>& x) const
722 {
723  ocean_assert(columns() == b.rows());
724  ocean_assert(b.columns() == 1);
725 
726  x.resize(columns(), 1);
727  return solve<tMatrixProperty>(b.data(), x.data());
728 }
729 
730 template <typename T>
731 inline bool MatrixT<T>::solve(const T* b, T* x, const MatrixProperty matrixProperty) const
732 {
733  switch (matrixProperty)
734  {
735  case MP_SYMMETRIC:
736  return solve<MP_SYMMETRIC>(b, x);
737 
738  default:
739  ocean_assert(matrixProperty == MP_UNKNOWN);
740  return solve<MP_UNKNOWN>(b, x);
741  }
742 }
743 
744 template <typename T>
745 inline size_t MatrixT<T>::rank() const
746 {
747  return rank(data(), rows(), columns());
748 }
749 
750 template <typename T>
752 {
753  ocean_assert(rows_ == columns_);
754 
755  MatrixT<T> result(*this);
756 
757  if (!result.invert())
758  {
759  ocean_assert(false && "The matrix is a singular matrix.");
760  }
761 
762  return result;
763 }
764 
765 template <typename T>
767 {
768  *this = transposed();
769 }
770 
771 template <typename T>
772 inline T MatrixT<T>::norm() const
773 {
774  T result = T(0.0);
775 
776  for (size_t n = 0u; n < elements(); ++n)
777  {
778  result += NumericT<T>::abs(values_[n]);
779  }
780 
781  return result;
782 }
783 
784 template <typename T>
785 inline T MatrixT<T>::sum() const
786 {
787  T result = T(0.0);
788 
789  for (size_t n = 0u; n < elements(); ++n)
790  {
791  result += values_[n];
792  }
793 
794  return result;
795 }
796 
797 template <typename T>
798 inline const T* MatrixT<T>::data() const
799 {
800  return values_;
801 }
802 
803 template <typename T>
804 inline T* MatrixT<T>::data()
805 {
806  return values_;
807 }
808 
809 template <typename T>
810 inline bool MatrixT<T>::operator==(const MatrixT<T>& right) const
811 {
812  return isEqual(right, NumericT<T>::eps());
813 }
814 
815 template <typename T>
816 inline bool MatrixT<T>::operator!=(const MatrixT<T>& right) const
817 {
818  return !(*this == right);
819 }
820 
821 template <typename T>
823 {
824  *this = *this * right;
825  return *this;
826 }
827 
828 template <typename T>
829 inline const T* MatrixT<T>::operator[](const size_t row) const
830 {
831  ocean_assert(row < rows());
832  return values_ + row * columns_;
833 }
834 
835 template <typename T>
836 inline T* MatrixT<T>::operator[](const size_t row)
837 {
838  ocean_assert(row < rows());
839  return values_ + row * columns_;
840 }
841 
842 template <typename T>
843 inline T MatrixT<T>::operator()(const size_t row, const size_t column) const
844 {
845  ocean_assert(row < rows_ && column < columns_);
846 
847  return *(values_ + row * columns_ + column);
848 }
849 
850 template <typename T>
851 inline T& MatrixT<T>::operator()(const size_t row, const size_t column)
852 {
853  ocean_assert(row < rows_ && column < columns_);
854 
855  return *(values_ + row * columns_ + column);
856 }
857 
858 template <typename T>
859 inline T MatrixT<T>::operator()(const size_t index) const
860 {
861  ocean_assert(index < elements());
862  return values_[index];
863 }
864 
865 template <typename T>
866 inline T& MatrixT<T>::operator()(const size_t index)
867 {
868  ocean_assert(index < elements());
869  return values_[index];
870 }
871 
872 template <typename T>
873 inline MatrixT<T>::operator bool() const
874 {
875  return values_ != nullptr;
876 }
877 
878 }
879 
880 #endif // META_OCEAN_MATH_MATRIX_H
MatrixT< T > subMatrix(const size_t row, const size_t column, const size_t rows, const size_t columns)
Returns a sub matrix of this one.
MatrixT(const size_t rows, const size_t columns, const T value)
Creates a new matrix with defined rows and columns.
~MatrixT()
Destructs a matrix and releases the elements.
T sum() const
Determines the sum of all elements of this matrix.
Definition: Matrix.h:785
MatrixT< T > & operator+=(const MatrixT< T > &right)
Adds and assigns two matrices.
void selfTransposedSquareMatrix(MatrixT< T > &result) const
Returns the matrix product of transposed matrix of this matrix and this matrix.
void weightedSelfTransposedSquareMatrix(const MatrixT< T > &weightDiagonal, MatrixT< T > &result) const
Returns the matrix product of transposed matrix of this matrix and this matrix and applies a further ...
MatrixT(const size_t rows, const size_t columns, const T *source)
Creates a new matrix with defined rows and columns.
MatrixT< T > inverted() const
Returns the inverted of this matrix.
Definition: Matrix.h:751
T operator()(const size_t row, const size_t column) const
Element operator allowing to access a specific elements of this matrix.
Definition: Matrix.h:843
MatrixT< T > diagonal() const
Returns a vector containing the values of the diagonal.
static size_t rank(const T *data, const size_t rows, const size_t columns)
Computes the rank of given matrix data.
T * operator[](const size_t row)
Element operator for the row aligned elements.
Definition: Matrix.h:836
T Type
Definition of the used data type.
Definition: Matrix.h:69
MatrixT()=default
Creates a new matrix with no size.
T operator()(const size_t index) const
Element operator for the row aligned elements.
Definition: Matrix.h:859
size_t columns() const
Returns the count of columns.
Definition: Matrix.h:698
void multiplyRow(const size_t row, const T scalar)
Multiplies a row with a scalar.
bool solve(const MatrixT< T > &b, MatrixT< T > &x) const
Solves the given linear system.
Definition: Matrix.h:721
T & operator()(const size_t row, const size_t column)
Element operator allowing to access a specific elements of this matrix.
Definition: Matrix.h:851
bool nonNegativeMatrixFactorization(MatrixT< T > &subcomponents, MatrixT< T > &weights, const size_t 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,...
const T * operator[](const size_t row) const
Returns the pointer to the elements of a specified row.
Definition: Matrix.h:829
bool operator!=(const MatrixT< T > &right) const
Returns whether two matrices are not identical up to a small epsilon.
Definition: Matrix.h:816
void elementwiseMultiplication(const MatrixT< T > &multiplier)
Performs an element-wise matrix multiplication meaning that each element of this matrix will be multi...
bool choleskyDecomposition(MatrixT< T > &lMatrix) const
Computes the Cholesky decomposition for this square matrix [m x m].
MatrixT< T > operator*(const T scalar) const
Multiplies the matrix with a scalar.
MatrixT< T > row(const size_t index) const
Returns a row of the matrix.
size_t rows_
Number of rows.
Definition: Matrix.h:682
void transpose()
Transposes this matrix.
Definition: Matrix.h:766
MatrixT< T > pseudoInverted(const T epsilon=NumericT< T >::eps()) const
Returns the pseudo inverse of this matrix by application of the singular value decomposition.
void multiplyColumn(const size_t column, const T scalar)
Multiplies a column with a scalar.
bool qrDecomposition(MatrixT< T > &qMatrix, MatrixT< T > *rMatrix=nullptr) const
Computes the QR decomposition for this matrix [m x n] while m >= n must hold.
void swapRows(const size_t row0, const size_t row1)
Swaps two rows.
MatrixT(const size_t rows, const size_t columns, const MatrixT< T > &subMatrix, const size_t row, const size_t column, const T value=T(0.0))
Creates a new matrix with defined rows and columns and a given sub-matrix.
MatrixT< T > selfSquareMatrix() const
Returns the matrix product of this matrix and the transposed matrix of this matrix.
const T * data() const
Returns a pointer to the internal values.
Definition: Matrix.h:798
bool selfSquareDiagonalMatrixMultiply(const MatrixT< T > &weightDiagonal, const MatrixT< T > &right, MatrixT< T > &result) const
Interprets this matrix as diagonal matrix and multiplies a second matrix on the right of the interpre...
MatrixT(const size_t rows, const size_t columns, const T *source, const bool valuesRowAligned)
Creates a new matrix with defined rows and columns.
MatrixT< T > & operator=(MatrixT< T > &&matrix) noexcept
Move assign operator.
void addRows(const size_t targetRow, const size_t sourceRow, const T scalar)
Adds a multiple of a row to another one.
MatrixT< T > selfTransposedSquareMatrix() const
Returns the matrix product of transposed matrix of this matrix and this matrix.
MatrixT< T > transposedMultiply(const MatrixT< T > &right) const
Multiplies this transposed matrix with a second matrix.
MatrixT(const size_t rows, const size_t columns)
Creates a new matrix with defined rows and columns.
size_t rank() const
Computes the rank of this matrix.
Definition: Matrix.h:745
void transposedMultiply(const MatrixT< T > &right, MatrixT< T > &result) const
Multiplies this transposed matrix with a second matrix.
MatrixT(const MatrixT< T > &matrix)
Copies a matrix.
MatrixT< T > transposed() const
Returns the transposed of this matrix.
size_t elements() const
Returns the number of entire elements, which is the product of rows and columns.
Definition: Matrix.h:704
bool isSymmetric(const T eps=NumericT< T >::eps()) const
Returns whether this matrix is symmetric (and whether this matrix is a square matrix).
bool isEqual(const MatrixT< T > &matrix, const T eps=NumericT< T >::eps()) const
Returns whether two matrices are almost identical up to a specified epsilon.
bool invert()
Inverts this matrix.
bool singularValueDecomposition(MatrixT< T > &u, MatrixT< T > &w, MatrixT< T > &v) const
Computes the singular value decomposition for this matrix.
bool eigenSystem(MatrixT< T > &values, MatrixT< T > &vectors) const
Computes the eigen system of this matrix.
void elementwiseDivision(const MatrixT< T > &denominator)
Performs an element-wise matrix division meaning that each element of this matrix will be divided by ...
MatrixT(MatrixT< T > &&matrix) noexcept
Move constructor.
T norm() const
Determines the L1 norm (sum of absolute elements) of this matrix.
Definition: Matrix.h:772
MatrixT< T > operator-(const MatrixT< T > &right) const
Subtracts two matrices.
MatrixT< T > operator*(const MatrixT< T > &right) const
Multiplies two matrices.
bool solve(const T *b, T *x, const MatrixProperty matrixProperty=MP_UNKNOWN) const
Solves the given linear system.
Definition: Matrix.h:731
T & operator()(const size_t index)
Element operator for the row aligned elements.
Definition: Matrix.h:866
size_t columns_
Number of columns.
Definition: Matrix.h:685
T * values_
Elements of the matrix.
Definition: Matrix.h:688
MatrixT(const size_t rows, const size_t columns, const MatrixT< T > &diagonal)
Creates a new matrix with defined rows and columns and initializes the diagonal with small sub matric...
MatrixT< T > & operator-=(const MatrixT< T > &right)
Subtracts and assigns two matrices.
bool solve(const T *b, T *x) const
Solves the given linear system.
MatrixT< T > operator+(const MatrixT< T > &right) const
Adds two matrices.
MatrixT< T > vector(const size_t column) const
Returns a column vector of the matrix.
MatrixProperty
Definition of specific properties of matrices.
Definition: Matrix.h:75
@ MP_UNKNOWN
No specific property known.
Definition: Matrix.h:77
@ MP_SYMMETRIC
The matrix is symmetric.
Definition: Matrix.h:79
void swapColumns(const size_t column0, const size_t column1)
Swaps two columns.
bool operator==(const MatrixT< T > &right) const
Returns whether two matrices are identical up to a small epsilon.
Definition: Matrix.h:810
MatrixT< T > & operator=(const MatrixT< T > &matrix)
Assigns a matrix to this one.
MatrixT(const size_t rows, const size_t columns, bool toIdentity)
Creates a new matrix with defined rows and columns.
size_t rows() const
Returns the count of rows.
Definition: Matrix.h:692
void resize(const size_t rows, const size_t columns)
Resizes this matrix.
bool selfSquareDiagonalMatrixMultiply(const MatrixT< T > &right, MatrixT< T > &result) const
Interprets this matrix as diagonal matrix and multiplies a second matrix on the right of the interpre...
MatrixT< T > & operator*=(const MatrixT< T > &right)
Multiplies and assigns two matrices.
Definition: Matrix.h:822
T * data()
Returns a pointer to the internal values.
Definition: Matrix.h:804
bool solve(const MatrixT< T > &b, MatrixT< T > &x, const MatrixProperty matrixProperty=MP_UNKNOWN) const
Solves the given linear system.
Definition: Matrix.h:710
MatrixT< T > & operator*=(const T scalar)
Multiplies this matrix by a scalar.
This class provides basic numeric functionalities.
Definition: Numeric.h:57
static T abs(const T value)
Returns the absolute value of a given value.
Definition: Numeric.h:1220
MatrixT< Scalar > Matrix
Definition of the Matrix object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with single ...
Definition: Matrix.h:18
MatrixT< float > MatrixF
Definition of the MatrixT template class using a single precision float data type.
Definition: Matrix.h:39
MatrixT< double > MatrixD
Definition of the MatrixT template class using a double precision float data type.
Definition: Matrix.h:32
std::vector< Matrix > Matrices
Definition of a vector holding matrix objects.
Definition: Matrix.h:46
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15