21#ifndef CORE_MATRIX_HPP
22#define CORE_MATRIX_HPP
54 template <u
int32 R, u
int32 C>
65 Matrix(
const floating_point(&initial)[R][C]);
72 Matrix(
const std::array<std::array<floating_point, C>, R> &initial);
79#if CLOCKWERK_ALLOW_STD_STRING
80 std::string dump()
const {
83 return std::string(retval);
88 int16
str(
char* output,
size_t size)
const;
103 int16
set(uint32 row, uint32 col,
const floating_point &value);
110 int16
get(uint32 row, uint32 col, floating_point &result)
const;
118 void setFromArray(
const floating_point* start_ptr,
bool column_major =
false);
126 void getAsArray(floating_point* start_ptr,
bool column_major =
false)
const;
133 floating_point
get(uint32 row, uint32 col)
const;
152 std::pair<uint32, uint32>
size()
const {
return std::pair<uint32, uint32>(R, C);}
156 void max(floating_point &result, std::pair<uint32, uint32> &index)
const;
160 void min(floating_point &result, std::pair<uint32, uint32> &index)
const;
169 int16
det(floating_point &result)
const;
197 int16
trace(floating_point &result)
const;
213 std::array<std::array<floating_point, C>, R>
values;
219 uint32 start_c, uint32 end_c)
const;
232 template <u
int32 R, u
int32 C>
236 for(i = 0; i < R; i++) {
237 for(j = 0; j < C; j++) {
243 template <u
int32 R, u
int32 C>
247 for(i = 0; i < R; i++) {
248 for(j = 0; j < C; j++) {
254 template <u
int32 R, u
int32 C>
263 for(i = 0; i < R; i++) {
264 for(j = 0; j < C; j++) {
265 values[i][j] = initial[i][j];
270 template <u
int32 R, u
int32 C>
274 for(i = 0; i < R; i++) {
275 for(j = 0; j < C; j++) {
281 template <u
int32 R, u
int32 C>
285 for(i = 0; i < R; i++) {
286 for(j = 0; j < C; j++) {
287 values[i][j] = initial[i][j];
292 template <u
int32 R, u
int32 C>
298 template <u
int32 R, u
int32 C>
305 strcpy(output,
"[[");
308 bool dimensions_error =
false;
310 int num_chars_filled = 2;
311 while (val_idx < R && !dimensions_error) {
314 if(err) {dimensions_error =
true;}
316 if(!dimensions_error) {
321 if(
size - num_chars_filled > 2) {
322 if(val_idx < R - 1) {
323 strcpy(output + num_chars_filled,
"][");
325 strcpy(output + num_chars_filled,
"]]");
327 num_chars_filled += 2;
329 dimensions_error =
true;
340 template <u
int32 R, u
int32 C>
342 if (val ==
nullptr || val[0] !=
'[') {
346 const char* ptr = val + 1;
349 for (uint32 i = 0; i < R; ++i) {
351 const char* row_start = strchr(ptr,
'[');
358 const char* row_end = strchr(row_start,
']');
362 size_t row_len = row_end - row_start;
364 char row_buf[row_len];
365 std::strncpy(row_buf, row_start, row_len);
366 row_buf[row_len] =
'\0';
380 template <u
int32 R, u
int32 C>
393 template <u
int32 R, u
int32 C>
402 result =
values[row][col];
406 template <u
int32 R, u
int32 C>
411 template <u
int32 R, u
int32 C>
413 const floating_point* ptr = start_ptr;
416 for(i = 0; i < R; i++) {
417 for(j = 0; j < C; j++) {
423 for(i = 0; i < R; i++) {
424 for(j = 0; j < C; j++) {
432 template <u
int32 R, u
int32 C>
434 floating_point* ptr = start_ptr;
437 for(i = 0; i < R; i++) {
438 for(j = 0; j < C; j++) {
444 for(i = 0; i < R; i++) {
445 for(j = 0; j < C; j++) {
453 template <u
int32 R, u
int32 C>
460 for(i = 0; i < R; i++) {
461 for(j = 0; j < C; j++) {
467 template <u
int32 R, u
int32 C>
472 for(i = 0; i < R; i++) {
473 for(j = 0; j < C; j++) {
480 template <u
int32 R, u
int32 C>
487 for(i = 0; i < R; i++) {
488 for(j = 0; j < C; j++) {
489 if(
values[i][j] > result) {
498 template <u
int32 R, u
int32 C>
505 for(i = 0; i < R; i++) {
506 for(j = 0; j < C; j++) {
507 if(
values[i][j] < result) {
516 template <u
int32 R, u
int32 C>
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++) {
557 result = decomposed[0][0];
558 for(i = 1; i < R; i++) {
559 result *= decomposed[i][i];
568 template <u
int32 R, u
int32 C>
576 for (uint32 i = 0; i < R; ++i) {
577 for (uint32 j = 0; j < C; ++j) {
578 retval.
values[i][j] = 0.0;
583 for (uint32 j = 0; j < C; ++j)
585 floating_point sum = 0.0;
586 for (uint32 k = 0; k < j; ++k) {
590 const floating_point diag =
values[j][j] - sum;
597 retval.
values[j][j] =
static_cast<floating_point
>(std::sqrt(diag));
600 floating_point rjj = retval.
values[j][j];
601 for (uint32 i = j + 1; i < C; ++i) {
603 for (uint32 k = 0; k < j; ++k) {
609 retval.
values[j][i] = (aji - sum)/rjj;
616 template <u
int32 R, u
int32 C>
627 int16 err =
safeDivide(
static_cast<floating_point
>(1.0),
641 floating_point A[R][C];
642 floating_point* decomposed[R];
644 for (uint32 i = 0; i < R; ++i) {
645 decomposed[i] = A[i];
646 for (uint32 j = 0; j < C; ++j) {
665 for (uint32 j = 0; j < R; ++j) {
668 for (uint32 i = 0; i < R; ++i) {
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];
678 for (uint32 idx = 1; idx <= R; ++idx) {
681 for (uint32 k = i + 1; k < R; ++k) {
682 result.
values[i][j] -= decomposed[i][k] * result.
values[k][j];
692 result.
values[i][j] = tmp;
699 template <u
int32 R, u
int32 C>
707 for(uint32 i = 0; i < C; i++)
708 for(uint32 j = 0; j < C; j++) {
709 for(uint32 k = 0; k < R; k++) {
716 int16 err = ATA.
inverse(ATA_inv);
717 if(err) {
return err;}
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++) {
736 for(uint32 i = 0; i < R; i++)
737 for(uint32 j = 0; j < R; j++) {
738 for(uint32 k = 0; k < C; k++) {
745 int16 err = AAT.
inverse(AAT_inv);
746 if(err) {
return err;}
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++) {
763 if(err) {
return err;}
766 for(uint32 i = 0; i < R; i++) {
767 for(uint32 j = 0; j < C; j++) {
776 template <u
int32 R, u
int32 C>
784 for(i = 0; i < R; i++) {
785 for(j = 0; j < C; j++) {
790 template <u
int32 R, u
int32 C>
800 template <u
int32 R, u
int32 C>
811 for(i = 0; i < R; i++) {
817 template <u
int32 R, u
int32 C>
820 for(i = 0; i < R; i++) {
821 for(j = 0; j < C; j++) {
827 template <u
int32 R, u
int32 C>
831 for(i = 0; i < R; i++) {
832 for(j = 0; j < C; j++) {
844 template <u
int32 R, u
int32 C>
846 uint32 start_c, uint32 end_c)
const{
848 if(start_r > end_r || start_c > end_c) {
853 if(end_r >= R || end_c >= C) {
860 template<u
int32 R, u
int32 C>
863 uint32 i, j, k, imax;
864 floating_point max_A, *ptr, abs_A;
867 for (k = 0; k <= R; k++) {
872 for (i = 0; i < R; i++) {
881 for (k = i; k < R; k++) {
882 abs_A = std::abs(A[k][i]);
916 for (j = i+1; j < R; j++) {
918 for (k = i+1; k < R; k++) {
919 A[j][k] -= A[j][i] * A[i][k];
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