tesseract++ 0.0.1
N-dimensional tensor library for embedded systems
Loading...
Searching...
No Matches
matrix.h
Go to the documentation of this file.
1#ifndef MATRIX_H
2#define MATRIX_H
3
4#include "tensor.h"
6#include "matrix_traits.h"
7
8// Derived class: Matrix
9template <typename T, my_size_t Rows, my_size_t Cols>
10class Matrix : public TensorND<T, Rows, Cols>
11{
12public:
13 // TODO: add Transfomation funtions like FusedMatrix
14 DEFINE_TYPE_ALIAS(T, value_type);
15
16 // Default constructor initializes a 2D matrix with default values
18 : TensorND<T, Rows, Cols>() {}
19
20 // Constructor to initialize all elements to a specific value
21 Matrix(T initValue)
22 : TensorND<T, Rows, Cols>(initValue) {}
23
24 // Copy constructor from another Matrix
25 Matrix(const Matrix &other)
26 : TensorND<T, Rows, Cols>(other) {}
27
28 // Copy constructor from base class
30 : TensorND<T, Rows, Cols>(baseTensor) {}
31
32 // Move constructor from another FusedMatrix
33 Matrix(Matrix &&other) noexcept
34 : TensorND<T, Rows, Cols>(std::move(other)) {}
35
36 // Move constructor from base class
37 Matrix(TensorND<T, Rows, Cols> &&baseTensor) noexcept
38 : TensorND<T, Rows, Cols>(std::move(baseTensor)) {}
39
40 static constexpr Matrix fromTensor(TensorND<T, Rows, Cols> &&tensor)
41 {
42 return Matrix(std::move(tensor));
43 }
44
45 Matrix(T (&initList)[Rows][Cols]) : TensorND<T, Rows, Cols>()
46 {
47 // loop trough the input and use (i,j) to store them
48 for (my_size_t i = 0; i < Rows; ++i)
49 {
50 for (my_size_t j = 0; j < Cols; ++j)
51 {
52 (*this)(i, j) = initList[i][j];
53 }
54 }
55 }
56
57 // method to return this as a TensorND
59 {
60 // Cast to base class to ensure correct type
61 return static_cast<const TensorND<T, Rows, Cols> &>(*this);
62 }
63
64 // Override operator= to assign a matrix to another matrix
65 Matrix &operator=(const Matrix &other)
66 {
67 // Call the base class operator= to assign the tensor
69
70 // Return the derived type
71 return *this;
72 }
73
74 // Override operator= to assign a 2D array to the matrix
75 Matrix &operator=(T (&initList)[Rows][Cols])
76 {
77 // loop trough the input and use (i,j) to store them
78 for (my_size_t i = 0; i < Rows; ++i)
79 {
80 for (my_size_t j = 0; j < Cols; ++j)
81 {
82 (*this)(i, j) = initList[i][j];
83 }
84 }
85
86 // Return the derived type
87 return *this;
88 }
89
90 // Override operator+ to return a Matrix
91 template <my_size_t Rows1, my_size_t Cols1>
93 {
94 // Call the base class operator+ to get a TensorND result
95 auto resultTensor = TensorND<T, Rows, Cols>::operator+(other);
96
97 // Use fromTensor to convert the resultTensor to a Matrix
98 return Matrix::fromTensor(std::move(resultTensor));
99 }
100
101 // Override operator+ to add a scalar to the matrix
102 Matrix operator+(const T scalar) const
103 {
104 // Call the base class operator+ to get a TensorND result
105 auto resultTensor = TensorND<T, Rows, Cols>::operator+(scalar);
106
107 // Cast the result to Matrix and return
108 return Matrix::fromTensor(std::move(resultTensor));
109 }
110
111 // overide operator+ to add a matrix to a scalar
112 friend Matrix operator+(const T scalar, const Matrix &matrix)
113 {
114 return matrix + scalar;
115 }
116
117 // Override operator- to return a Matrix
118 template <my_size_t Rows1, my_size_t Cols1>
120 {
121 // Call the base class operator- to get a TensorND result
122 auto resultTensor = TensorND<T, Rows, Cols>::operator-(other);
123
124 // Use fromTensor to convert the resultTensor to a Matrix
125 return Matrix::fromTensor(std::move(resultTensor));
126 }
127
128 // Override operator- to subtract a scalar from the matrix
129 Matrix operator-(const T scalar) const
130 {
131 // Call the base class operator- to get a TensorND result
132 auto resultTensor = TensorND<T, Rows, Cols>::operator-(scalar);
133
134 // Use fromTensor to convert the resultTensor to a Matrix
135 return Matrix::fromTensor(std::move(resultTensor));
136 }
137
138 // overide operator- to subtract a matrix from a scalar
139 friend Matrix operator-(const T scalar, const Matrix &matrix)
140 {
141 return -matrix + scalar; // scalar - matrix = -matrix + scalar
142 }
143
144 // Override operator- to get the negative of the matrix
145 Matrix operator-(void) const
146 {
147 // Call the base class operator- to get a TensorND result
148 auto resultTensor = TensorND<T, Rows, Cols>::operator-();
149
150 // Use fromTensor to convert the resultTensor to a Matrix
151 return Matrix::fromTensor(std::move(resultTensor));
152 }
153
154 // Override operator* to return a Matrix
155 template <my_size_t Rows1, my_size_t Cols1>
157 {
158 // Call the base class operator* to get a TensorND result
159 auto resultTensor = TensorND<T, Rows, Cols>::operator*(other);
160
161 // Use fromTensor to convert the resultTensor to a Matrix
162 return Matrix::fromTensor(std::move(resultTensor));
163 }
164
165 // Override operator* to multiply a scalar with the matrix
166 Matrix operator*(const T scalar) const
167 {
168 // Call the base class operator* to get a TensorND result
169 auto resultTensor = TensorND<T, Rows, Cols>::operator*(scalar);
170
171 // Use fromTensor to convert the resultTensor to a Matrix
172 return Matrix::fromTensor(std::move(resultTensor));
173 }
174
175 // overide operator* to multiply a matrix with a scalar
176 friend Matrix operator*(const T scalar, const Matrix &matrix)
177 {
178 return matrix * scalar;
179 }
180
181 // Override operator/ to return a Matrix
182 template <my_size_t Rows1, my_size_t Cols1>
184 {
185 // Call the base class operator/ to get a TensorND result
186 auto resultTensor = TensorND<T, Rows, Cols>::operator/(other);
187
188 // Use fromTensor to convert the resultTensor to a Matrix
189 return Matrix::fromTensor(std::move(resultTensor));
190 }
191
192 // Override operator/ to divide the matrix by a scalar
193 Matrix operator/(const T scalar) const
194 {
195 // Call the base class operator/ to get a TensorND result
196 auto resultTensor = TensorND<T, Rows, Cols>::operator/(scalar);
197
198 // Use fromTensor to convert the resultTensor to a Matrix
199 return Matrix::fromTensor(std::move(resultTensor));
200 }
201
202 // overide operator/ to divide a scalar by the matrix
203 friend Matrix operator/(const T scalar, const Matrix &matrix)
204 {
205 auto resultTensor = scalar / static_cast<const TensorND<T, Rows, Cols> &>(matrix);
206
207 // Use fromTensor to convert the resultTensor to a Matrix
208 return Matrix::fromTensor(std::move(resultTensor));
209 }
210
211 Matrix transposed(void) const
212 {
213 // Call base class transposed(), which returns a TensorND
215
216 // Convert the transposed tensor into a Matrix
217 return Matrix(transposedTensor);
218 }
219
224
225 // Override setToZero to return a Matrix
227 {
228 // Call the base class setToZero to set all elements to zero
230
231 // Cast the base class (TensorND) to Matrix to return the derived type
232 return *this;
233 }
234
235 // Override setHomogen to return a Matrix
237 {
238 // Call the base class setHomogen to set all elements to a specific value
240
241 // Cast the base class (TensorND) to Matrix to return the derived type
242 return *this;
243 }
244
245 // Override setRandom to return a Matrix
246 Matrix &setRandom(my_size_t _maxRand, my_size_t _minRand)
247 {
248 // Call the base class setRandom to set all elements to random values
249 TensorND<T, Rows, Cols>::setRandom(_maxRand, _minRand);
250
251 // Cast the base class (TensorND) to Matrix to return the derived type
252 return *this;
253 }
254
255 // Override setDiagonal to return a Matrix
257 {
258 // Call the base class setDiagonal
260
261 // Cast the base class (TensorND) to Matrix to return the derived type
262 return *this;
263 }
264
265 // Override setIdentity to return a Matrix
267 {
268 // Call the base class setIdentity
270
271 // Cast the base class (TensorND) to Matrix to return the derived type
272 return *this;
273 }
274
275 // Override setSequencial to return a Matrix
277 {
278 // Call the base class setSequencial
280
281 // Cast the base class (TensorND) to Matrix to return the derived type
282 return *this;
283 }
284
285 // matmul using einsum of parent class
286 template <my_size_t Common, my_size_t mat1_rows, my_size_t mat2_cols>
288 {
289 auto resultTensor = TensorND<T, Rows, Cols>::einsum(mat1, mat2, 1, 0);
290 return Matrix::fromTensor(std::move(resultTensor));
291 }
292
293 bool isIdentity(void) const
294 {
295 // Check if the matrix is square
296 if (!this->areDimsEqual())
297 {
298 return false;
299 }
300
301 // Check if the diagonal elements are 1 and the rest are 0
302 for (my_size_t i = 0; i < this->getDim(0); i++)
303 {
304 for (my_size_t j = 0; j < this->getDim(1); j++)
305 {
306 if (i == j)
307 {
308 if (std::abs((*this)(i, j) - T(1)) > T(PRECISION_TOLERANCE))
309 {
310 return false;
311 }
312 }
313 else
314 {
315 if (std::abs((*this)(i, j)) > T(PRECISION_TOLERANCE))
316 {
317 return false;
318 }
319 }
320 }
321 }
322 return true;
323 }
324
325 bool isSymmetric(void) const
326 {
327 // Check if the matrix is square
328 if (!this->areDimsEqual())
329 {
330 MyErrorHandler::error("Matrix is not square");
331 }
332
333 // use the fact that A = A^T for symmetric matrices
334 // use transpose() to get the transpose of the matrix
335 // and see if it's equal to the original matrix
336
337 Matrix transposed = this->transposed();
338
339 return (*this == transposed);
340 }
341
342 bool isUpperTriangular(void) const
343 {
344 // Check if the matrix is square
345 if (!this->areDimsEqual())
346 {
347 MyErrorHandler::error("Matrix is not square");
348 }
349
350 // Check if the matrix is upper triangular
351 for (my_size_t i = 1; i < this->getDim(0); i++)
352 {
353 for (my_size_t j = 0; j < i; j++)
354 {
355 if (std::abs((*this)(i, j)) > T(PRECISION_TOLERANCE))
356 {
357 return false;
358 }
359 }
360 }
361 return true;
362 }
363
364 bool isLowerTriangular(void) const
365 {
366 // Check if the matrix is square
367 if (!this->areDimsEqual())
368 {
369 MyErrorHandler::error("Matrix is not square");
370 }
371
372 // Check if the matrix is lower triangular
373 for (my_size_t i = 0; i < this->getDim(0); i++)
374 {
375 for (my_size_t j = i + 1; j < this->getDim(1); j++)
376 {
377 if (std::abs((*this)(i, j)) > T(PRECISION_TOLERANCE))
378 {
379 return false;
380 }
381 }
382 }
383 return true;
384 }
385
386 Matrix upperTriangular(bool inplace = false)
387 {
388 // Check if the matrix is square
389 if (!this->areDimsEqual())
390 {
391 MyErrorHandler::error("Matrix is not square");
392 }
393
394 my_size_t matrix_size = this->getDim(0); // Assuming the matrix is square the number of rows and columns are equal
395
396 if (!inplace)
397 {
398 // Create a copy and modify it
399 // std::cout << "Setting matrix to upper triangular" << std::endl;
400 Matrix result = *this;
401 for (my_size_t i = 1; i < matrix_size; i++)
402 {
403 for (my_size_t j = 0; j < i; j++)
404 {
405 result(i, j) = T(0);
406 }
407 }
408 return result;
409 }
410 else
411 {
412 // std::cout << "Setting matrix to upper triangular in place" << std::endl;
413 // Modify the matrix in-place
414 for (my_size_t i = 1; i < matrix_size; i++)
415 {
416 for (my_size_t j = 0; j < i; j++)
417 {
418 (*this)(i, j) = T(0);
419 }
420 }
421 return *this; // Returning the modified matrix itself
422 }
423 }
424
425 Matrix lowerTriangular(bool inplace = false)
426 {
427 // Check if the matrix is square
428 if (!this->areDimsEqual())
429 {
430 MyErrorHandler::error("Matrix is not square");
431 }
432
433 my_size_t matrix_size = this->getDim(0); // Assuming the matrix is square the number of rows and columns are equal
434
435 if (!inplace)
436 {
437 // Create a copy and modify it
438 // std::cout << "Setting matrix to lower triangular" << std::endl;
439 Matrix result = *this;
440 for (my_size_t i = 0; i < matrix_size; i++)
441 {
442 for (my_size_t j = i + 1; j < matrix_size; j++)
443 {
444 result(i, j) = T(0);
445 }
446 }
447 return result;
448 }
449 else
450 {
451 // std::cout << "Setting matrix to lower triangular in place" << std::endl;
452 // Modify the matrix in-place
453 for (my_size_t i = 0; i < matrix_size; i++)
454 {
455 for (my_size_t j = i + 1; j < matrix_size; j++)
456 {
457 (*this)(i, j) = T(0);
458 }
459 }
460 return *this; // Returning the modified matrix itself
461 }
462 }
463
464 /* Invers operation using Gauss-Jordan algorithm */
465 Matrix inverse(void) const
466 {
467 if (!this->areDimsEqual())
468 {
469 MyErrorHandler::error("Matrix is non-invertible cause: not square");
470 }
471
472 // check if is identity
473 if (this->isIdentity())
474 {
475 return *this;
476 }
477
478 Matrix _outp = *this;
479 Matrix _temp = *this;
480
481 my_size_t rows = _temp.getDim(0);
482 my_size_t cols = _temp.getDim(1);
483 _outp.setIdentity();
484
485 /* Gauss Elimination... */
486 for (my_size_t j = 0; j < rows - 1; j++)
487 {
488 for (my_size_t i = j + 1; i < rows; i++)
489 {
490 if (std::abs(_temp(j, j)) < T(PRECISION_TOLERANCE))
491 {
492 /* Matrix is non-invertible */
493 MyErrorHandler::error("Matrix is non-invertible cause: diagonal element is zero (Gauss Elimination)");
494 }
495
496 T tmp = _temp(i, j) / _temp(j, j);
497
498 for (my_size_t k = 0; k < cols; k++)
499 {
500 _temp(i, k) -= (_temp(j, k) * tmp);
501 _outp(i, k) -= (_outp(j, k) * tmp);
502
503 // round _temp(i, k) to zero if it's too small
504 // round _outp(i, k) to zero if it's too small
505 }
506 }
507 }
508
509 /* At this point, the _temp matrix should be an upper triangular matrix.
510 * But because of rounding error, it might not.
511 * Make it upper triangular by setting the lower triangular to zero.
512 */
513 _temp.upperTriangular(true);
514
515 /* Jordan... */
516 for (my_size_t j = rows - 1; j > 0; j--)
517 {
518 for (int i = j - 1; i >= 0; i--)
519 {
520 if (std::abs(_temp(j, j)) < T(PRECISION_TOLERANCE))
521 {
522 /* Matrix is non-invertible */
523 MyErrorHandler::error("Matrix is non-invertible cause: diagonal element is zero (Jordan)");
524 }
525
526 T tmp = _temp(i, j) / _temp(j, j);
527 _temp(i, j) -= (_temp(j, j) * tmp);
528
529 // round _temp(i, j) to zero if it's too small
530
531 for (int k = rows - 1; k >= 0; k--)
532 {
533 _outp(i, k) -= (_outp(j, k) * tmp);
534
535 // round _outp(i, k) to zero if it's too small
536 }
537 }
538 }
539
540 /* Normalize the matrix */
541 for (my_size_t i = 0; i < rows; i++)
542 {
543 if (std::abs(_temp(i, i)) < T(PRECISION_TOLERANCE))
544 {
545 /* Matrix is non-invertible */
546 MyErrorHandler::error("Matrix is non-invertible cause: diagonal element is zero (Normalization)");
547 }
548
549 T tmp = _temp(i, i);
550 _temp(i, i) = T(1.0);
551
552 for (my_size_t j = 0; j < cols; j++)
553 {
554 _outp(i, j) /= tmp;
555 }
556 }
557 return _outp;
558 }
559
560 Matrix inverse_c(void) const
561 {
562 if (!this->areDimsEqual())
563 {
564 MyErrorHandler::error("Matrix is non-invertible cause: not square");
565 }
566
567 Matrix _outp = *this; // The identity matrix, which will store the inverse
568 my_size_t rows = _outp.getDim(0);
569 my_size_t cols = _outp.getDim(1);
570
571 _outp.setIdentity();
572
573 // Function to swap rows
574 auto swapRows = [&_outp, cols](my_size_t i, my_size_t j)
575 {
576 for (my_size_t k = 0; k < cols; k++)
577 {
578 std::swap(_outp(i, k), _outp(j, k));
579 }
580 };
581
582 for (my_size_t j = 0; j < rows; j++)
583 {
584 // Check if the pivot element is too small, if so perform row swapping
585 if (std::abs(_outp(j, j)) < T(PRECISION_TOLERANCE))
586 {
587 bool swapped = false;
588 for (my_size_t i = j + 1; i < rows; i++)
589 {
590 if (std::abs(_outp(i, j)) > std::abs(_outp(j, j)))
591 {
592 swapRows(i, j); // Swap rows to ensure numerical stability
593 swapped = true;
594 break;
595 }
596 }
597
598 if (!swapped)
599 {
600 MyErrorHandler::error("Matrix is non-invertible: no valid pivot found.");
601 }
602 }
603
604 T pivot = _outp(j, j);
605 if (std::abs(pivot) < T(PRECISION_TOLERANCE))
606 {
607 MyErrorHandler::error("Matrix is non-invertible: pivot is zero.");
608 }
609
610 // Normalize the pivot row (making the diagonal element 1)
611 for (my_size_t k = 0; k < cols; k++)
612 {
613 _outp(j, k) /= pivot; // Normalize the pivot row
614 }
615
616 // Eliminate all other elements in the column
617 for (my_size_t i = 0; i < rows; i++)
618 {
619 if (i != j)
620 {
621 T factor = _outp(i, j);
622 for (my_size_t k = 0; k < cols; k++)
623 {
624 _outp(i, k) -= factor * _outp(j, k); // Eliminate column elements
625 }
626 }
627 }
628 }
629
630 return _outp;
631 }
632
633 bool isOrthogonal(void)
634 {
636
637 // Check if the matrix is square
638 if (!this->areDimsEqual())
639 {
640 MyErrorHandler::error("Matrix is not square");
641 }
642
643 // Check if the matrix is orthogonal
644 Matrix transposed = this->transposed();
645
647 if (!ident.isIdentity())
648 {
649 return false;
650 }
651
653 if (!ident.isIdentity())
654 {
655 return false;
656 }
657 return true;
658 }
659
661 {
662 // Strict: rejects near-zero diagonals
663 auto strict = matrix_algorithms::cholesky(*this);
664 if (strict.has_value())
665 {
667 }
668
669 // Relaxed: allows zero diagonals (semi-definite)
670 // Negative tolerance lets exact-zero diagonals pass while
671 // still rejecting truly negative ones.
672 auto relaxed = matrix_algorithms::cholesky(*this, T(-PRECISION_TOLERANCE));
673 if (relaxed.has_value())
674 {
676 }
677
679 }
680};
681
682#endif // MATRIX_H
Cholesky decomposition for symmetric positive-definite matrices.
static void error(const T &msg)
Definition error_handler.h:30
Definition matrix.h:11
TensorND< T, Rows, Cols > toTensor(void) const
Definition matrix.h:58
Matrix & operator=(const Matrix &other)
Definition matrix.h:65
friend Matrix operator/(const T scalar, const Matrix &matrix)
Definition matrix.h:203
matrix_traits::Definiteness isPositiveDefinite() const
Definition matrix.h:660
Matrix(const TensorND< T, Rows, Cols > &baseTensor)
Definition matrix.h:29
Matrix operator-(const T scalar) const
Definition matrix.h:129
Matrix upperTriangular(bool inplace=false)
Definition matrix.h:386
friend Matrix operator+(const T scalar, const Matrix &matrix)
Definition matrix.h:112
Matrix operator/(const Matrix< T, Rows1, Cols1 > &other) const
Definition matrix.h:183
Matrix inverse_c(void) const
Definition matrix.h:560
Matrix(const Matrix &other)
Definition matrix.h:25
Matrix & setHomogen(T _val)
Definition matrix.h:236
Matrix operator*(const Matrix< T, Rows1, Cols1 > &other) const
Definition matrix.h:156
Matrix & setSequencial(void)
Definition matrix.h:276
Matrix operator+(const T scalar) const
Definition matrix.h:102
Matrix operator+(const Matrix< T, Rows1, Cols1 > &other) const
Definition matrix.h:92
bool isOrthogonal(void)
Definition matrix.h:633
Matrix operator/(const T scalar) const
Definition matrix.h:193
DEFINE_TYPE_ALIAS(T, value_type)
Matrix(T(&initList)[Rows][Cols])
Definition matrix.h:45
bool isIdentity(void) const
Definition matrix.h:293
bool isSymmetric(void) const
Definition matrix.h:325
Matrix()
Definition matrix.h:17
Matrix & setDiagonal(T _val)
Definition matrix.h:256
friend Matrix operator*(const T scalar, const Matrix &matrix)
Definition matrix.h:176
Matrix(TensorND< T, Rows, Cols > &&baseTensor) noexcept
Definition matrix.h:37
Matrix & setToZero(void)
Definition matrix.h:226
friend Matrix operator-(const T scalar, const Matrix &matrix)
Definition matrix.h:139
static constexpr Matrix fromTensor(TensorND< T, Rows, Cols > &&tensor)
Definition matrix.h:40
Matrix(T initValue)
Definition matrix.h:21
Matrix lowerTriangular(bool inplace=false)
Definition matrix.h:425
Matrix operator-(void) const
Definition matrix.h:145
Matrix inverse(void) const
Definition matrix.h:465
bool isLowerTriangular(void) const
Definition matrix.h:364
Matrix & operator=(T(&initList)[Rows][Cols])
Definition matrix.h:75
Matrix operator-(const Matrix< T, Rows1, Cols1 > &other) const
Definition matrix.h:119
void inplace_transpose(void)
Definition matrix.h:220
Matrix(Matrix &&other) noexcept
Definition matrix.h:33
static Matrix< T, Rows, Cols > matmul(const Matrix< T, mat1_rows, Common > &mat1, const Matrix< T, Common, mat2_cols > &mat2)
Definition matrix.h:287
Matrix transposed(void) const
Definition matrix.h:211
Matrix & setRandom(my_size_t _maxRand, my_size_t _minRand)
Definition matrix.h:246
Matrix operator*(const T scalar) const
Definition matrix.h:166
Matrix & setIdentity(void)
Definition matrix.h:266
bool isUpperTriangular(void) const
Definition matrix.h:342
Definition tensor.h:15
TensorND & setSequencial(void)
Definition tensor.h:589
friend TensorND operator-(const T scalar, const TensorND &tensor)
Definition tensor.h:213
friend TensorND operator+(const T scalar, const TensorND &tensor)
Definition tensor.h:165
void inplace_transpose(void)
Definition tensor.h:481
friend TensorND operator*(const T scalar, const TensorND &tensor)
Definition tensor.h:278
TensorND & operator=(const TensorND &other)
Definition tensor.h:136
TensorND & setRandom(my_size_t _maxRand, my_size_t _minRand)
Definition tensor.h:535
TensorND & setDiagonal(T _val)
Definition tensor.h:546
my_size_t getDim(my_size_t i) const
Definition tensor.h:830
TensorND & setToZero(void)
Definition tensor.h:523
TensorND & setIdentity(void)
Definition tensor.h:570
friend TensorND operator/(const T scalar, const TensorND &tensor)
Definition tensor.h:326
constexpr bool areDimsEqual() const
Definition tensor.h:376
static TensorND einsum(const TensorND< T, Dims1... > &_tensor1, const TensorND< T, Dims2... > &_tensor2, my_size_t a, my_size_t b)
Definition tensor.h:620
TensorND transposed(void) const
Definition tensor.h:460
TensorND & setHomogen(T _val)
Definition tensor.h:529
#define my_size_t
Size/index type used throughout the library.
Definition config.h:126
#define PRECISION_TOLERANCE
Tolerance for floating-point comparisons (e.g. symmetry checks, Cholesky).
Definition config.h:117
Runtime property descriptors and error codes for matrices.
Expected< MatrixType, MatrixStatus > cholesky(const MatrixType &A, typename MatrixType::value_type tol=typename MatrixType::value_type(PRECISION_TOLERANCE))
Compute the Cholesky decomposition of a symmetric positive-definite matrix.
Definition cholesky.h:87
Definiteness
Describes the definiteness of a symmetric matrix.
Definition matrix_traits.h:20
@ PositiveSemiDefinite
All eigenvalues ≥ 0.
@ PositiveDefinite
All eigenvalues > 0.
@ NotPositiveDefinite
Neither positive definite nor semi-definite.