Ocean
Loading...
Searching...
No Matches
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
14namespace Ocean
15{
16
17// Forward declaration.
18template <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 */
46typedef 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 */
61template <typename T>
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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
691template <typename T>
692inline size_t MatrixT<T>::rows() const
693{
694 return rows_;
695}
696
697template <typename T>
698inline size_t MatrixT<T>::columns() const
699{
700 return columns_;
701}
702
703template <typename T>
704inline size_t MatrixT<T>::elements() const
705{
706 return rows_ * columns_;
707}
708
709template <typename T>
710inline 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
719template <typename T>
720template <typename MatrixT<T>::MatrixProperty tMatrixProperty>
721inline 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
730template <typename T>
731inline 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
744template <typename T>
745inline size_t MatrixT<T>::rank() const
746{
747 return rank(data(), rows(), columns());
748}
749
750template <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
765template <typename T>
767{
768 *this = transposed();
769}
770
771template <typename T>
772inline 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
784template <typename T>
785inline 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
797template <typename T>
798inline const T* MatrixT<T>::data() const
799{
800 return values_;
801}
802
803template <typename T>
805{
806 return values_;
807}
808
809template <typename T>
810inline bool MatrixT<T>::operator==(const MatrixT<T>& right) const
811{
812 return isEqual(right, NumericT<T>::eps());
813}
814
815template <typename T>
816inline bool MatrixT<T>::operator!=(const MatrixT<T>& right) const
817{
818 return !(*this == right);
819}
820
821template <typename T>
823{
824 *this = *this * right;
825 return *this;
826}
827
828template <typename T>
829inline const T* MatrixT<T>::operator[](const size_t row) const
830{
831 ocean_assert(row < rows());
832 return values_ + row * columns_;
833}
834
835template <typename T>
836inline T* MatrixT<T>::operator[](const size_t row)
837{
838 ocean_assert(row < rows());
839 return values_ + row * columns_;
840}
841
842template <typename T>
843inline 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
850template <typename T>
851inline 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
858template <typename T>
859inline T MatrixT<T>::operator()(const size_t index) const
860{
861 ocean_assert(index < elements());
862 return values_[index];
863}
864
865template <typename T>
866inline T& MatrixT<T>::operator()(const size_t index)
867{
868 ocean_assert(index < elements());
869 return values_[index];
870}
871
872template <typename T>
873inline MatrixT<T>::operator bool() const
874{
875 return values_ != nullptr;
876}
877
878}
879
880#endif // META_OCEAN_MATH_MATRIX_H
This class implements a matrix with arbitrary size.
Definition Matrix.h:63
MatrixT< T > operator-(const MatrixT< T > &right) const
Subtracts two matrices.
MatrixT(const size_t rows, const size_t columns, const T value)
Creates a new matrix with defined rows and columns.
MatrixT< T > selfSquareMatrix() const
Returns the matrix product of this matrix and the transposed matrix of this matrix.
~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 > transposedMultiply(const MatrixT< T > &right) const
Multiplies this transposed matrix with a second matrix.
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
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.
MatrixT< T > pseudoInverted(const T epsilon=NumericT< T >::eps()) const
Returns the pseudo inverse of this matrix by application of the singular value decomposition.
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
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.
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
MatrixT< T > vector(const size_t column) const
Returns a column vector of the matrix.
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 MatrixT< T > &right)
Subtracts and assigns two matrices.
MatrixT< T > & operator*=(const T scalar)
Multiplies this matrix by a scalar.
size_t rows_
Number of rows.
Definition Matrix.h:682
void transpose()
Transposes this matrix.
Definition Matrix.h:766
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.
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.
void addRows(const size_t targetRow, const size_t sourceRow, const T scalar)
Adds a multiple of a row to another one.
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
MatrixT< T > operator+(const MatrixT< T > &right) const
Adds two matrices.
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 > row(const size_t index) const
Returns a row of the matrix.
MatrixT< T > selfTransposedSquareMatrix() const
Returns the matrix product of transposed matrix of this matrix and 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.
MatrixT< T > diagonal() const
Returns a vector containing the values of the diagonal.
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.
MatrixT< T > operator*(const MatrixT< T > &right) const
Multiplies two matrices.
T norm() const
Determines the L1 norm (sum of absolute elements) of this matrix.
Definition Matrix.h:772
MatrixT< T > operator*(const T scalar) const
Multiplies the matrix with a scalar.
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
MatrixT< T > & operator+=(const MatrixT< T > &right)
Adds and assigns two matrices.
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...
bool solve(const T *b, T *x) const
Solves the given linear system.
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.
MatrixT< T > transposed() const
Returns the transposed of this matrix.
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
MatrixT< T > & operator=(MatrixT< T > &&matrix) noexcept
Move assign operator.
bool solve(const MatrixT< T > &b, MatrixT< T > &x, const MatrixProperty matrixProperty=MP_UNKNOWN) const
Solves the given linear system.
Definition Matrix.h:710
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:25
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