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 */
46using Matrices = std::vector<Matrix>;
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 using Type = T;
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 [[nodiscard]] 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, with range [1, infinity)
468 * @param columns Number of columns of the resized matrix, with range [1, infinity)
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 * Releases the matrix and removes all elements.
490 */
491 inline void release();
492
493 /**
494 * Returns whether this matrix holds at least one element.
495 * @return True, if so
496 */
497 inline bool isValid() const;
498
499 /**
500 * Returns a pointer to the internal values.
501 * @return Pointer to the internal values
502 */
503 inline const T* data() const;
504
505 /**
506 * Returns a pointer to the internal values.
507 * @return Pointer to the internal values
508 */
509 inline T* data();
510
511 /**
512 * Assigns a matrix to this one.
513 * @param matrix The matrix to assign
514 * @return Reference to this matrix
515 */
517
518 /**
519 * Move assign operator.
520 * @param matrix The matrix to moved
521 * @return Reference to this matrix
522 */
523 MatrixT<T>& operator=(MatrixT<T>&& matrix) noexcept;
524
525 /**
526 * Returns whether two matrices are identical up to a small epsilon.
527 * @param right The right matrix
528 * @return True, if so
529 */
530 inline bool operator==(const MatrixT<T>& right) const;
531
532 /**
533 * Returns whether two matrices are not identical up to a small epsilon.
534 * @param right The right matrix
535 * @return True, if so
536 */
537 inline bool operator!=(const MatrixT<T>& right) const;
538
539 /**
540 * Adds two matrices.
541 * @param right The right matrix
542 * @return Sum matrix
543 */
544 MatrixT<T> operator+(const MatrixT<T>& right) const;
545
546 /**
547 * Adds and assigns two matrices.
548 * @param right The right matrix
549 * @return Reference to this matrix
550 */
552
553 /**
554 * Subtracts two matrices.
555 * @param right The right matrix
556 * @return Subtracted matrix
557 */
558 MatrixT<T> operator-(const MatrixT<T>& right) const;
559
560 /**
561 * Subtracts and assigns two matrices.
562 * @param right The right matrix
563 * @return Reference to this matrix
564 */
566
567 /**
568 * Multiplies two matrices.
569 * @param right The right matrix
570 * @return Resulting matrix
571 */
572 MatrixT<T> operator*(const MatrixT<T>& right) const;
573
574 /**
575 * Multiplies the matrix with a scalar.
576 * @param scalar The scalar to multiply
577 * @return Resulting matrix
578 */
579 MatrixT<T> operator*(const T scalar) const;
580
581 /**
582 * Multiplies and assigns two matrices.
583 * @param right The right matrix
584 * @return Reference to this matrix
585 */
586 inline MatrixT<T>& operator*=(const MatrixT<T>& right);
587
588 /**
589 * Multiplies this matrix by a scalar.
590 * @param scalar The scalar to multiply
591 * @return Reference to this matrix
592 */
593 MatrixT<T>& operator*=(const T scalar);
594
595 /**
596 * Returns the pointer to the elements of a specified row.
597 * @param row Index of the row to return, with range [0, rows())
598 * @return Specified row
599 */
600 inline const T* operator[](const size_t row) const;
601
602 /**
603 * Element operator for the row aligned elements.
604 * @param row Index of the element to return, with range [0, rows())
605 * @return Specified element
606 */
607 inline T* operator[](const size_t row);
608
609 /**
610 * Element operator allowing to access a specific elements of this matrix.
611 * @param row The row of the element to return, with range [0, rows())
612 * @param column The column of the element to return, with range [0, columns())
613 * @return Specified element
614 */
615 inline T operator()(const size_t row, const size_t column) const;
616
617 /**
618 * Element operator allowing to access a specific elements of this matrix.
619 * @param row The row of the element to return, with range [0, rows())
620 * @param column The column of the element to return, with range [0, columns())
621 * @return Specified element
622 */
623 inline T& operator()(const size_t row, const size_t column);
624
625 /**
626 * Element operator for the row aligned elements.
627 * @param index The index of the element to return, with range [0, elements())
628 * @return Specified element
629 */
630 inline T operator()(const size_t index) const;
631
632 /**
633 * Element operator for the row aligned elements.
634 * @param index The index of the element to return, with range [0, elements())
635 * @return Specified element
636 */
637 inline T& operator()(const size_t index);
638
639 /**
640 * Returns whether the matrix holds at least one element.
641 * @return True, if so
642 */
643 explicit inline operator bool() const;
644
645 /**
646 * Computes the rank of given matrix data.
647 * @param data The elements of the matrix for which the rank will be calculated, provided in a row aligned order, must be valid
648 * @param rows The number of rows of the provided matrix, with range [1, infinity)
649 * @param columns The number of columns of the provided matrix, with range [1, infinity)
650 * @return The matrix's rank with range [0, min(rows, columns)]
651 */
652 static size_t rank(const T* data, const size_t rows, const size_t columns);
653
654 protected:
655
656 /**
657 * Swaps two rows.
658 * @param row0 The index of the first row to be swapped, with range [0, rows())
659 * @param row1 The index of the second row to be swapped, with range [0, rows())
660 */
661 void swapRows(const size_t row0, const size_t row1);
662
663 /**
664 * Swaps two columns.
665 * @param column0 The index of the first column to be swapped, with range [0, columns())
666 * @param column1 The index of the second column to be swapped, with range [0, columns())
667 */
668 void swapColumns(const size_t column0, const size_t column1);
669
670 /**
671 * Adds a multiple of a row to another one.
672 * @param targetRow The index of the target row to which the multiple of the source row will be added, with range [0, rows())
673 * @param sourceRow The index of the source row, with range [0, rows())
674 * @param scalar The scalar to multiply the source elements with
675 */
676 void addRows(const size_t targetRow, const size_t sourceRow, const T scalar);
677
678 /**
679 * Performs an element-wise matrix multiplication meaning that each element of this matrix will be multiplied by a corresponding element from 'multiplier'.
680 * @param multiplier The matrix providing the multiplication elements, with same size as this matrix, all elements must not be zero
681 */
683
684 /**
685 * Performs an element-wise matrix division meaning that each element of this matrix will be divided by a corresponding element from 'denominator'.
686 * @param denominator The matrix providing the denominator elements, with same size as this matrix
687 */
689
690 protected:
691
692 /// Number of rows.
693 size_t rows_ = 0;
694
695 /// Number of columns.
696 size_t columns_ = 0;
697
698 /// Elements of the matrix.
699 T* values_ = nullptr;
700};
701
702template <typename T>
703inline size_t MatrixT<T>::rows() const
704{
705 return rows_;
706}
707
708template <typename T>
709inline size_t MatrixT<T>::columns() const
710{
711 return columns_;
712}
713
714template <typename T>
715inline size_t MatrixT<T>::elements() const
716{
717 return rows_ * columns_;
718}
719
720template <typename T>
721inline bool MatrixT<T>::solve(const MatrixT<T>& b, MatrixT<T>& x, const MatrixProperty matrixProperty) const
722{
723 ocean_assert(columns() == b.rows());
724 ocean_assert(b.columns() == 1);
725
726 x.resize(columns(), 1);
727 return solve(b.data(), x.data(), matrixProperty);
728}
729
730template <typename T>
731template <typename MatrixT<T>::MatrixProperty tMatrixProperty>
732inline bool MatrixT<T>::solve(const MatrixT<T>& b, MatrixT<T>& x) const
733{
734 ocean_assert(columns() == b.rows());
735 ocean_assert(b.columns() == 1);
736
737 x.resize(columns(), 1);
738 return solve<tMatrixProperty>(b.data(), x.data());
739}
740
741template <typename T>
742inline bool MatrixT<T>::solve(const T* b, T* x, const MatrixProperty matrixProperty) const
743{
744 switch (matrixProperty)
745 {
746 case MP_SYMMETRIC:
747 return solve<MP_SYMMETRIC>(b, x);
748
749 case MP_UNKNOWN:
750 default:
751 ocean_assert(matrixProperty == MP_UNKNOWN);
752 return solve<MP_UNKNOWN>(b, x);
753 }
754}
755
756template <typename T>
757inline size_t MatrixT<T>::rank() const
758{
759 return rank(data(), rows(), columns());
760}
761
762template <typename T>
764{
765 ocean_assert(rows_ == columns_);
766
767 MatrixT<T> result(*this);
768
769 if (!result.invert())
770 {
771 ocean_assert(false && "The matrix is a singular matrix.");
772 }
773
774 return result;
775}
776
777template <typename T>
779{
780 *this = transposed();
781}
782
783template <typename T>
784inline T MatrixT<T>::norm() const
785{
786 T result = T(0.0);
787
788 for (size_t n = 0u; n < elements(); ++n)
789 {
790 result += NumericT<T>::abs(values_[n]);
791 }
792
793 return result;
794}
795
796template <typename T>
797inline T MatrixT<T>::sum() const
798{
799 T result = T(0.0);
800
801 for (size_t n = 0u; n < elements(); ++n)
802 {
803 result += values_[n];
804 }
805
806 return result;
807}
808
809template <typename T>
811{
812 rows_ = 0;
813 columns_ = 0;
814
815 free(values_);
816 values_ = nullptr;
817}
818
819template <typename T>
820inline bool MatrixT<T>::isValid() const
821{
822 ocean_assert((values_ == nullptr && rows_ == 0 && columns_ == 0) || (values_ != nullptr && rows_ != 0 && columns_ != 0));
823
824 return values_ != nullptr;
825}
826
827template <typename T>
828inline const T* MatrixT<T>::data() const
829{
830 return values_;
831}
832
833template <typename T>
835{
836 return values_;
837}
838
839template <typename T>
840inline bool MatrixT<T>::operator==(const MatrixT<T>& right) const
841{
842 return isEqual(right, NumericT<T>::eps());
843}
844
845template <typename T>
846inline bool MatrixT<T>::operator!=(const MatrixT<T>& right) const
847{
848 return !(*this == right);
849}
850
851template <typename T>
853{
854 *this = *this * right;
855 return *this;
856}
857
858template <typename T>
859inline const T* MatrixT<T>::operator[](const size_t row) const
860{
861 ocean_assert(row < rows());
862 return values_ + row * columns_;
863}
864
865template <typename T>
866inline T* MatrixT<T>::operator[](const size_t row)
867{
868 ocean_assert(row < rows());
869 return values_ + row * columns_;
870}
871
872template <typename T>
873inline T MatrixT<T>::operator()(const size_t row, const size_t column) const
874{
875 ocean_assert(row < rows_ && column < columns_);
876
877 return *(values_ + row * columns_ + column);
878}
879
880template <typename T>
881inline T& MatrixT<T>::operator()(const size_t row, const size_t column)
882{
883 ocean_assert(row < rows_ && column < columns_);
884
885 return *(values_ + row * columns_ + column);
886}
887
888template <typename T>
889inline T MatrixT<T>::operator()(const size_t index) const
890{
891 ocean_assert(index < elements());
892 return values_[index];
893}
894
895template <typename T>
896inline T& MatrixT<T>::operator()(const size_t index)
897{
898 ocean_assert(index < elements());
899 return values_[index];
900}
901
902template <typename T>
903inline MatrixT<T>::operator bool() const
904{
905 return isValid();
906}
907
908}
909
910#endif // META_OCEAN_MATH_MATRIX_H
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:797
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:763
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:873
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:866
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:889
size_t columns() const
Returns the count of columns.
Definition Matrix.h:709
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:732
T & operator()(const size_t row, const size_t column)
Element operator allowing to access a specific elements of this matrix.
Definition Matrix.h:881
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:859
bool operator!=(const MatrixT< T > &right) const
Returns whether two matrices are not identical up to a small epsilon.
Definition Matrix.h:846
void elementwiseMultiplication(const MatrixT< T > &multiplier)
Performs an element-wise matrix multiplication meaning that each element of this matrix will be multi...
bool isValid() const
Returns whether this matrix holds at least one element.
Definition Matrix.h:820
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:693
void transpose()
Transposes this matrix.
Definition Matrix.h:778
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:828
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:757
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.
T Type
Definition of the used data type.
Definition Matrix.h:69
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:715
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:784
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:742
T & operator()(const size_t index)
Element operator for the row aligned elements.
Definition Matrix.h:896
MatrixT< T > & operator+=(const MatrixT< T > &right)
Adds and assigns two matrices.
size_t columns_
Number of columns.
Definition Matrix.h:696
T * values_
Elements of the matrix.
Definition Matrix.h:699
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:840
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.
void release()
Releases the matrix and removes all elements.
Definition Matrix.h:810
size_t rows() const
Returns the count of rows.
Definition Matrix.h:703
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:852
T * data()
Returns a pointer to the internal values.
Definition Matrix.h:834
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:721
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
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