WarpTwin
Documentation for WarpTwin models and classes.
Loading...
Searching...
No Matches
Matrix.hpp
Go to the documentation of this file.
1/******************************************************************************
2* Copyright (c) ATTX LLC 2024. All Rights Reserved.
3*
4* This software and associated documentation (the "Software") are the
5* proprietary and confidential information of ATTX, LLC. The Software is
6* furnished under a license agreement between ATTX and the user organization
7* and may be used or copied only in accordance with the terms of the agreement.
8* Refer to 'license/attx_license.adoc' for standard license terms.
9*
10* EXPORT CONTROL NOTICE: THIS SOFTWARE MAY INCLUDE CONTENT CONTROLLED UNDER THE
11* INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) OR THE EXPORT ADMINISTRATION
12* REGULATIONS (EAR99). No part of the Software may be used, reproduced, or
13* transmitted in any form or by any means, for any purpose, without the express
14* written permission of ATTX, LLC.
15******************************************************************************/
16/*
17Matrix math header file
18
19Author: Alex Reynolds
20*/
21#ifndef CORE_MATRIX_HPP
22#define CORE_MATRIX_HPP
23
24#include <cmath>
25#include <array>
26#include <cstring>
27
28#include "clockwerkerrors.h"
29#include "safemath.h"
30#include "utils/stringutils.hpp"
31
32namespace clockwerk {
33 const uint32 MAX_CHARS_PER_MATRIX_STRING = 1000;
34
54 template <uint32 R, uint32 C>
55 class Matrix {
56 public:
59
61 Matrix(floating_point elements);
62
65 Matrix(const floating_point(&initial)[R][C]);
66
69 Matrix(const Matrix<R, C> &initial);
70
72 Matrix(const std::array<std::array<floating_point, C>, R> &initial);
73
77
79#if CLOCKWERK_ALLOW_STD_STRING
80 std::string dump() const {
81 char retval[MAX_CHARS_PER_MATRIX_STRING];
83 return std::string(retval);
84 }
85#endif
86
88 int16 str(char* output, size_t size) const;
89
93 int16 fromStr(const char* val);
94
103 int16 set(uint32 row, uint32 col, const floating_point &value);
104
110 int16 get(uint32 row, uint32 col, floating_point &result) const;
111
118 void setFromArray(const floating_point* start_ptr, bool column_major = false);
119
126 void getAsArray(floating_point* start_ptr, bool column_major = false) const;
127
133 floating_point get(uint32 row, uint32 col) const;
134
137 void getCopy(Matrix<R, C> &result) const;
138
141
145 floating_point* operator [](uint32 idx);
146
150
152 std::pair<uint32, uint32> size() const {return std::pair<uint32, uint32>(R, C);}
153
156 void max(floating_point &result, std::pair<uint32, uint32> &index) const;
157
160 void min(floating_point &result, std::pair<uint32, uint32> &index) const;
161
165
169 int16 det(floating_point &result) const;
170
176 int16 chol(Matrix<R, C>& retval) const;
177 Matrix<R, C> chol() const {Matrix<R, C> tmp; chol(tmp); return tmp;}
178
182 int16 inverse(Matrix<R, C> &result) const;
183 Matrix<R, C> inverse() const {Matrix<R, C> tmp; inverse(tmp); return tmp;}
184
185 int16 pseudoinverse(Matrix<C, R> &result) const;
186 Matrix<C, R> pseudoinverse() const {Matrix<C, R> tmp; pseudoinverse(tmp); return tmp; }
187
191 void transpose(Matrix<C, R> &result) const;
193
197 int16 trace(floating_point &result) const;
198
201
204 int16 identity();
205 int16 eye() {return identity();}
206
213 std::array<std::array<floating_point, C>, R> values;
214
215 protected:
218 int16 _checkLookupBoundaries(uint32 start_r, uint32 end_r,
219 uint32 start_c, uint32 end_c) const;
220
228 int16 _LUPDecompose(floating_point *A[R], uint32 P[R+1]) const;
229
230 };
231
232 template <uint32 R, uint32 C>
234 uint32 i, j;
236 for(i = 0; i < R; i++) {
237 for(j = 0; j < C; j++) {
238 values[i][j] = 0.0;
239 }
240 }
241 }
242
243 template <uint32 R, uint32 C>
244 Matrix<R, C>::Matrix(floating_point elements) {
245 uint32 i, j;
247 for(i = 0; i < R; i++) {
248 for(j = 0; j < C; j++) {
249 values[i][j] = elements;
250 }
251 }
252 }
253
254 template <uint32 R, uint32 C>
255 Matrix<R, C>::Matrix(const floating_point(&initial)[R][C]) {
260
262 uint32 i, j;
263 for(i = 0; i < R; i++) {
264 for(j = 0; j < C; j++) {
265 values[i][j] = initial[i][j];
266 }
267 }
268 }
269
270 template <uint32 R, uint32 C>
272 uint32 i, j;
274 for(i = 0; i < R; i++) {
275 for(j = 0; j < C; j++) {
276 values[i][j] = initial.values[i][j];
277 }
278 }
279 }
280
281 template <uint32 R, uint32 C>
282 Matrix<R, C>::Matrix(const std::array<std::array<floating_point, C>, R> &initial) {
283 uint32 i, j;
285 for(i = 0; i < R; i++) {
286 for(j = 0; j < C; j++) {
287 values[i][j] = initial[i][j];
288 }
289 }
290 }
291
292 template <uint32 R, uint32 C>
293 floating_point* Matrix<R, C>::operator [](uint32 idx) {
294 // Return pointer to our array element
295 return &values[idx][0];
296 }
297
298 template <uint32 R, uint32 C>
299 int16 Matrix<R, C>::str(char* output, size_t size) const {
300 if (output == nullptr) return ERROR_NULLPTR;
301
302 if(size < 3) {
303 return ERROR_DIMENSIONS;
304 }
305 strcpy(output, "[[");
306
307 // Configure initial string
308 bool dimensions_error = false;
309 uint32 val_idx = 0;
310 int num_chars_filled = 2;
311 while (val_idx < R && !dimensions_error) {
312 // Call number to string conversion, starting at open space in our buffer
313 int16 err = numberToString(values[val_idx], output + num_chars_filled, size - num_chars_filled);
314 if(err) {dimensions_error = true;}
315
316 if(!dimensions_error) {
317 // Calculate updated parameters
318 num_chars_filled = strnlen(output, size);
319
320 // Add in comma to separate values
321 if(size - num_chars_filled > 2) {
322 if(val_idx < R - 1) {
323 strcpy(output + num_chars_filled, "][");
324 } else {
325 strcpy(output + num_chars_filled, "]]");
326 }
327 num_chars_filled += 2;
328 } else {
329 dimensions_error = true;
330 }
331 }
332
333 val_idx++;
334 }
335
336 if(dimensions_error) {return ERROR_DIMENSIONS;}
337 return NO_ERROR;
338 }
339
340 template <uint32 R, uint32 C>
341 int16 Matrix<R, C>::fromStr(const char* val) {
342 if (val == nullptr || val[0] != '[') {
343 return ERROR_DIMENSIONS;
344 }
345
346 const char* ptr = val + 1; // skip the initial '['
347 int16 err = NO_ERROR;
348
349 for (uint32 i = 0; i < R; ++i) {
350 // Find the start of the row
351 const char* row_start = strchr(ptr, '[');
352 if (!row_start) {
353 return ERROR_DIMENSIONS;
354 }
355 row_start++;
356
357 // Find the end of the row
358 const char* row_end = strchr(row_start, ']');
359 if (!row_end) return ERROR_DIMENSIONS;
360
361 // Copy row content into a buffer for parsing
362 size_t row_len = row_end - row_start;
363
364 char row_buf[row_len];
365 std::strncpy(row_buf, row_start, row_len);
366 row_buf[row_len] = '\0';
367
368 // Parse the row string into the matrix row
369 err = setArrayFromString(row_buf, values[i].data(), C);
370 if (err) {
371 return err;
372 }
373
374 ptr = row_end + 1; // move past ']'
375 }
376
377 return NO_ERROR;
378 }
379
380 template <uint32 R, uint32 C>
381 int16 Matrix<R, C>::set(uint32 row, uint32 col, const floating_point &value){
383 if(_checkLookupBoundaries(row, row, col, col)) {
385 return ERROR_DIMENSIONS;
386 }
387
389 values[row][col] = value;
390 return NO_ERROR;
391 }
392
393 template <uint32 R, uint32 C>
394 int16 Matrix<R, C>::get(uint32 row, uint32 col, floating_point &result) const{
396 if(_checkLookupBoundaries(row, row, col, col)) {
398 return ERROR_DIMENSIONS;
399 }
400
402 result = values[row][col];
403 return NO_ERROR;
404 }
405
406 template <uint32 R, uint32 C>
407 floating_point Matrix<R, C>::get(uint32 row, uint32 col) const{
408 return values[row][col];
409 }
410
411 template <uint32 R, uint32 C>
412 void Matrix<R, C>::setFromArray(const floating_point* start_ptr, bool column_major) {
413 const floating_point* ptr = start_ptr;
414 uint32 i, j;
415 if(column_major) {
416 for(i = 0; i < R; i++) {
417 for(j = 0; j < C; j++) {
418 values[j][i] = *ptr;
419 ptr++;
420 }
421 }
422 } else {
423 for(i = 0; i < R; i++) {
424 for(j = 0; j < C; j++) {
425 values[i][j] = *ptr;
426 ptr++;
427 }
428 }
429 }
430 }
431
432 template <uint32 R, uint32 C>
433 void Matrix<R, C>::getAsArray(floating_point* start_ptr, bool column_major) const {
434 floating_point* ptr = start_ptr;
435 uint32 i, j;
436 if(column_major) {
437 for(i = 0; i < R; i++) {
438 for(j = 0; j < C; j++) {
439 *ptr = values[j][i];
440 ptr++;
441 }
442 }
443 } else {
444 for(i = 0; i < R; i++) {
445 for(j = 0; j < C; j++) {
446 *ptr = values[i][j];
447 ptr++;
448 }
449 }
450 }
451 }
452
453 template <uint32 R, uint32 C>
457
458 uint32 i, j;
460 for(i = 0; i < R; i++) {
461 for(j = 0; j < C; j++) {
462 result.values[i][j] = values[i][j];
463 }
464 }
465 }
466
467 template <uint32 R, uint32 C>
469 {
471 uint32 i, j;
472 for(i = 0; i < R; i++) {
473 for(j = 0; j < C; j++) {
474 this->values[i][j] = other.values[i][j];
475 }
476 }
477 return *this;
478 }
479
480 template <uint32 R, uint32 C>
481 void Matrix<R, C>::max(floating_point &result, std::pair<uint32, uint32> &index) const {
482 uint32 i, j;
483 index.first = 0;
484 index.second = 0;
485 result = values[0][0];
487 for(i = 0; i < R; i++) {
488 for(j = 0; j < C; j++) {
489 if(values[i][j] > result) {
490 result = values[i][j];
491 index.first = i;
492 index.second = j;
493 }
494 }
495 }
496 }
497
498 template <uint32 R, uint32 C>
499 void Matrix<R, C>::min(floating_point &result, std::pair<uint32, uint32> &index) const {
500 uint32 i, j;
501 index.first = 0;
502 index.second = 0;
503 result = values[0][0];
505 for(i = 0; i < R; i++) {
506 for(j = 0; j < C; j++) {
507 if(values[i][j] < result) {
508 result = values[i][j];
509 index.first = i;
510 index.second = j;
511 }
512 }
513 }
514 }
515
516 template <uint32 R, uint32 C>
517 int16 Matrix<R, C>::det(floating_point &result) const {
521
523 uint32 i, j, err;
524
529 floating_point A[R][C];
530 floating_point *decomposed[R];
531 for(i = 0; i < R; i++) {
532 decomposed[i] = A[i];
533 for(j = 0; j < C; j++) {
534 A[i][j] = values[i][j];
535 }
536 }
537
542 uint32 P[R+1];
543
548 err = _LUPDecompose(decomposed, P);
549 if(err == ERROR_POORLY_CONDITIONED) {
550 result = 0;
551 return NO_ERROR;
552 } else if(err) {
553 return err;
554 }
555
557 result = decomposed[0][0];
558 for(i = 1; i < R; i++) {
559 result *= decomposed[i][i];
560 }
561 if((P[R] - R)%2) {
562 result = -result;
563 }
564
565 return NO_ERROR;
566 }
567
568 template <uint32 R, uint32 C>
569 int16 Matrix<R, C>::chol(Matrix<R, C>& retval) const{
570 // Only square matrices are choleskible
571 if (R != C) {
572 return ERROR_DIMENSIONS;
573 }
574
575 // Zero output.
576 for (uint32 i = 0; i < R; ++i) {
577 for (uint32 j = 0; j < C; ++j) {
578 retval.values[i][j] = 0.0;
579 }
580 }
581
582 // Compute MATLAB-style upper-triangular R such that R' * R = A.
583 for (uint32 j = 0; j < C; ++j)
584 {
585 floating_point sum = 0.0;
586 for (uint32 k = 0; k < j; ++k) {
587 sum += retval.values[k][j]*retval.values[k][j];
588 }
589
590 const floating_point diag = values[j][j] - sum;
591
592 // SPD check / conditioning
593 if (diag <= TOLERANCE_CONDITIONING) {
595 }
596 // Note no need for safe sqrt here becuase we just verified that diag isn't < 0
597 retval.values[j][j] = static_cast<floating_point>(std::sqrt(diag));
598
599 // Off-diagonal in row j (upper triangle): R(j,i) for i = j+1..C-1
600 floating_point rjj = retval.values[j][j];
601 for (uint32 i = j + 1; i < C; ++i) {
602 sum = 0.0;
603 for (uint32 k = 0; k < j; ++k) {
604 sum += retval.values[k][j]*retval.values[k][i];
605 }
606
607 // Note here we enforce symmetry in our matrix by taking the mean of the off diag terms
608 floating_point aji = (values[j][i] + values[i][j])*0.5;
609 retval.values[j][i] = (aji - sum)/rjj; // No need for safe divide because we verified rjj.
610 }
611 }
612
613 return NO_ERROR;
614 }
615
616 template <uint32 R, uint32 C>
617 int16 Matrix<R, C>::inverse(Matrix<R, C> &result) const {
618 // Only square matrices are invertible
619 if (R != C) {
620 result = 0.0; // deterministic output on error
621 return ERROR_DIMENSIONS;
622 }
623
624 // Trivial 1x1 case: inverse of a scalar
625 if (R == 1) {
626 result = 0.0;
627 int16 err = safeDivide(static_cast<floating_point>(1.0),
628 values[0][0],
629 result.values[0][0]);
630 if (err) {
631 result = 0.0;
632 return err; // e.g. divide-by-zero / poorly conditioned
633 }
634 return NO_ERROR;
635 }
636
637 // Ensure deterministic content even if we early-exit
638 result.setToZeros();
639
640 // Local copy of the matrix as a 2D array for in-place LU factorization
641 floating_point A[R][C];
642 floating_point* decomposed[R];
643
644 for (uint32 i = 0; i < R; ++i) {
645 decomposed[i] = A[i];
646 for (uint32 j = 0; j < C; ++j) {
647 A[i][j] = values[i][j];
648 }
649 }
650
651 // Permutation "matrix" P
652 // P[0..R-1] = permuted row indices, P[R] = pivot count
653 uint32 P[R + 1];
654
655 // LU decomposition with partial pivoting and conditioning check
656 int16 err = _LUPDecompose(decomposed, P);
657 if (err) {
658 // ERROR_POORLY_CONDITIONED, ERROR_DIMENSIONS, etc.
659 result = 0.0;
660 return err;
661 }
662
663 // Solve A * X = I using the LU factors in 'decomposed' and permutation P.
664 // We fill result column-by-column (each column is solution of A * x_j = e_j).
665 for (uint32 j = 0; j < R; ++j) {
666 // Forward substitution: L * y = P * e_j
667 // Start with y = P*e_j encoded into result.values[*][j]
668 for (uint32 i = 0; i < R; ++i) {
669 // P[i] tells which row of identity goes here
670 result.values[i][j] = (P[i] == j) ? static_cast<floating_point>(1.0)
671 : static_cast<floating_point>(0.0);
672 for (uint32 k = 0; k < i; ++k) {
673 result.values[i][j] -= decomposed[i][k] * result.values[k][j];
674 }
675 }
676
677 // Back substitution: U * x = y
678 for (uint32 idx = 1; idx <= R; ++idx) {
679 uint32 i = R - idx; // count backwards: R-1, R-2, ..., 0
680
681 for (uint32 k = i + 1; k < R; ++k) {
682 result.values[i][j] -= decomposed[i][k] * result.values[k][j];
683 }
684
685 // Divide by U(i,i)
686 floating_point tmp;
687 err = safeDivide(result.values[i][j], decomposed[i][i], tmp);
688 if (err) {
689 result = 0.0;
690 return err;
691 }
692 result.values[i][j] = tmp;
693 }
694 }
695
696 return NO_ERROR;
697 }
698
699 template <uint32 R, uint32 C>
701
702 //--- CASE 1: Tall matrix (R >= C) -----------------------------------------
703 if (R > C)
704 {
705 // Compute ATA = Aᵀ A (C×C)
706 Matrix<C, C> ATA;
707 for(uint32 i = 0; i < C; i++)
708 for(uint32 j = 0; j < C; j++) {
709 for(uint32 k = 0; k < R; k++) {
710 ATA.values[i][j] += values[k][i] * values[k][j];
711 }
712 }
713
714 // Invert ATA
715 Matrix<C, C> ATA_inv;
716 int16 err = ATA.inverse(ATA_inv);
717 if(err) {return err;} // Singular / bad conditioning
718
719 // Compute A⁺ = (AᵀA)⁻¹ Aᵀ
720 for(uint32 i = 0; i < C; i++)
721 for(uint32 j = 0; j < R; j++) {
722 result.values[i][j] = 0.0;
723 for(uint32 k = 0; k < C; k++) {
724 result.values[i][j] += ATA_inv.values[i][k] * values[j][k];
725 }
726 }
727
728 return NO_ERROR;
729 }
730
731 //--- CASE 2: Wide matrix (C > R) ------------------------------------------
732 else if (R < C)
733 {
734 // Compute AAT = A Aᵀ (R×R)
735 Matrix<R, R> AAT;
736 for(uint32 i = 0; i < R; i++)
737 for(uint32 j = 0; j < R; j++) {
738 for(uint32 k = 0; k < C; k++) {
739 AAT.values[i][j] += values[i][k] * values[j][k];
740 }
741 }
742
743 // Invert AAT
744 Matrix<R, R> AAT_inv;
745 int16 err = AAT.inverse(AAT_inv);
746 if(err) {return err;}
747
748 // Compute A⁺ = Aᵀ (A Aᵀ)⁻¹
749 for(uint32 i = 0; i < C; i++)
750 for(uint32 j = 0; j < R; j++) {
751 result.values[i][j] = 0.0;
752 for(uint32 k = 0; k < R; k++) {
753 result.values[i][j] += values[k][i] * AAT_inv.values[k][j];
754 }
755 }
756
757 return NO_ERROR;
758 }
759 //--- CASE 3: Square matrix (C = R) ------------------------------------------
760 else {
761 Matrix<R, C> inv;
762 int16 err = inverse(inv);
763 if(err) {return err;}
764
765 // Copy values element by element (safe when R==C)
766 for(uint32 i = 0; i < R; i++) {
767 for(uint32 j = 0; j < C; j++) {
768 result.values[i][j] = inv.values[i][j];
769 }
770 }
771
772 return NO_ERROR;
773 }
774 }
775
776 template <uint32 R, uint32 C>
781
782 uint32 i, j;
784 for(i = 0; i < R; i++) {
785 for(j = 0; j < C; j++) {
786 result.values[j][i] = values[i][j];
787 }
788 }
789 }
790 template <uint32 R, uint32 C>
795 Matrix<C, R> tmp;
796 transpose(tmp);
797 return tmp;
798 }
799
800 template <uint32 R, uint32 C>
801 int16 Matrix<R, C>::trace(floating_point &result) const {
804 if(R != C) {
805 return ERROR_DIMENSIONS;
806 }
807
808 result = 0.0;
809 uint32 i;
811 for(i = 0; i < R; i++) {
812 result += values[i][i];
813 }
814 return NO_ERROR;
815 }
816
817 template <uint32 R, uint32 C>
819 uint32 i, j;
820 for(i = 0; i < R; i++) {
821 for(j = 0; j < C; j++) {
822 values[j][i] = 0;
823 }
824 }
825 }
826
827 template <uint32 R, uint32 C>
829 if(C != R) {return ERROR_DIMENSIONS;}
830 uint32 i, j;
831 for(i = 0; i < R; i++) {
832 for(j = 0; j < C; j++) {
833 if(i == j) {
834 values[i][i] = 1.0;
835 } else {
836 values[i][j] = 0.0;
837 }
838 }
839 }
840
841 return NO_ERROR;
842 }
843
844 template <uint32 R, uint32 C>
845 int16 Matrix<R, C>::_checkLookupBoundaries(uint32 start_r, uint32 end_r,
846 uint32 start_c, uint32 end_c) const{
848 if(start_r > end_r || start_c > end_c) {
849 return ERROR_DIMENSIONS;
850 }
853 if(end_r >= R || end_c >= C) {
854 return ERROR_DIMENSIONS;
855 }
857 return NO_ERROR;
858 }
859
860 template<uint32 R, uint32 C>
861 int16 Matrix<R, C>::_LUPDecompose(floating_point *A[R], uint32 P[R+1]) const {
863 uint32 i, j, k, imax;
864 floating_point max_A, *ptr, abs_A;
865
867 for (k = 0; k <= R; k++) {
868 P[k] = k;
869 }
870
872 for (i = 0; i < R; i++) {
875 max_A = 0.0;
876 imax = i;
877
881 for (k = i; k < R; k++) {
882 abs_A = std::abs(A[k][i]);
884 if (abs_A > max_A) {
885 max_A = abs_A;
886 imax = k;
887 }
888 }
889
893 if (max_A < TOLERANCE_CONDITIONING)
894 return ERROR_POORLY_CONDITIONED; //failure, matrix is degenerate
895
899 if (imax != i) {
902 P[R]++;
903
905 j = P[i];
906 P[i] = P[imax];
907 P[imax] = j;
908
910 ptr = A[i];
911 A[i] = A[imax];
912 A[imax] = ptr;
913 }
914
916 for (j = i+1; j < R; j++) {
917 safeDivide(A[j][i], A[i][i], A[j][i]);
918 for (k = i+1; k < R; k++) {
919 A[j][k] -= A[j][i] * A[i][k];
920 }
921 }
922 }
923
925 return NO_ERROR;
926 }
927
928}
929
930#endif
floating_point get(uint32 row, uint32 col) const
Function to get a single value in the matrix.
Definition Matrix.hpp:407
int16 trace(floating_point &result) const
Function to return the trace of the matrix.
Definition Matrix.hpp:801
Matrix< C, R > transpose() const
Definition Matrix.hpp:791
Matrix(floating_point elements)
Constructor to initialize a matrix with all the same element.
Definition Matrix.hpp:244
Matrix< R, C > chol() const
Definition Matrix.hpp:177
void getAsArray(floating_point *start_ptr, bool column_major=false) const
Function to get the values of the matrix row-wise.
Definition Matrix.hpp:433
std::array< std::array< floating_point, C >, R > values
Definition Matrix.hpp:213
floating_point * operator[](uint32 idx)
Function to return a matrix row or vector value.
Definition Matrix.hpp:293
Matrix< R, C > inverse() const
Definition Matrix.hpp:183
void max(floating_point &result, std::pair< uint32, uint32 > &index) const
Function to return the maximum value in the matrix.
Definition Matrix.hpp:481
Matrix< C, R > pseudoinverse() const
Definition Matrix.hpp:186
int16 _LUPDecompose(floating_point *A[R], uint32 P[R+1]) const
Function to take a 2-d matrix represented by A and decompose it into LU form.
Definition Matrix.hpp:861
int16 get(uint32 row, uint32 col, floating_point &result) const
Function to get a single value in the matrix.
Definition Matrix.hpp:394
int16 identity()
Function to set matrix to identity, if it is a square matrix.
Definition Matrix.hpp:828
Matrix()
Default constructor to initialize a matrix to all zeroes for ease of use.
Definition Matrix.hpp:233
Matrix< R, C > & operator=(const Matrix< R, C > &other)
Equals operator overload for matrix.
Definition Matrix.hpp:468
~Matrix()
Definition Matrix.hpp:76
void min(floating_point &result, std::pair< uint32, uint32 > &index) const
Function to return the minimum value in the matrix.
Definition Matrix.hpp:499
int16 str(char *output, size_t size) const
Function to dump information on matrix.
Definition Matrix.hpp:299
int16 set(uint32 row, uint32 col, const floating_point &value)
Function to set a single value in the matrix.
Definition Matrix.hpp:381
int16 chol(Matrix< R, C > &retval) const
Take the cholesky decomposition of this matrix.
Definition Matrix.hpp:569
int16 eye()
Definition Matrix.hpp:205
Matrix(const Matrix< R, C > &initial)
Definition Matrix.hpp:271
void setToZeros()
Function to set all elements of the matrix to zero.
Definition Matrix.hpp:818
void getCopy(Matrix< R, C > &result) const
Function to get a copy of the matrix.
Definition Matrix.hpp:454
Matrix(const floating_point(&initial)[R][C])
Definition Matrix.hpp:255
int16 pseudoinverse(Matrix< C, R > &result) const
Definition Matrix.hpp:700
int16 det(floating_point &result) const
Function to return the determinant of the matrix.
Definition Matrix.hpp:517
int16 fromStr(const char *val)
Set value of matrix from string in same format as str().
Definition Matrix.hpp:341
void setFromArray(const floating_point *start_ptr, bool column_major=false)
Function to set the values of the matrix row-wise.
Definition Matrix.hpp:412
void transpose(Matrix< C, R > &result) const
Function to return the transpose of the matrix.
Definition Matrix.hpp:777
int16 inverse(Matrix< R, C > &result) const
Function to return the inverse of the matrix.
Definition Matrix.hpp:617
Matrix(const std::array< std::array< floating_point, C >, R > &initial)
Array constructor for the matrix class. Initializes from std::array.
Definition Matrix.hpp:282
std::pair< uint32, uint32 > size() const
Definition Matrix.hpp:152
int16 _checkLookupBoundaries(uint32 start_r, uint32 end_r, uint32 start_c, uint32 end_c) const
Definition Matrix.hpp:845
#define NO_ERROR
Error code in the case where matrix math executed successfully.
Definition clockwerkerrors.h:34
#define ERROR_NULLPTR
Error code in case of a null pointer.
Definition clockwerkerrors.h:60
#define TOLERANCE_CONDITIONING
Definition clockwerkerrors.h:46
#define ERROR_POORLY_CONDITIONED
Definition clockwerkerrors.h:45
#define ERROR_DIMENSIONS
Definition clockwerkerrors.h:41
Definition CircularBuffer.hpp:28
int16 numberToString(int64 num, char *out, size_t out_size)
Definition stringutils.cpp:156
const uint32 MAX_CHARS_PER_MATRIX_STRING
Definition Matrix.hpp:33
int16 safeDivide(float a, float b, float &result)
Overloaded functions to perform safe division.
Definition safemath.cpp:24
size_t strnlen(const char *s, size_t maxlen)
Function to calculate the string length with a length bound.
Definition stringutils.cpp:428
int16 setArrayFromString(const char *s, T *array, size_t array_size)
Converts a bracket-enclosed comma-separated string to a float array.
Definition stringutils.hpp:230