diff --git a/Matrix.cpp b/Matrix.cpp index d6864bc..11954b7 100644 --- a/Matrix.cpp +++ b/Matrix.cpp @@ -24,19 +24,18 @@ Matrix::Matrix(Args... args) { static_cast(columns)}; std::initializer_list initList{static_cast(args)...}; - std::array data{}; // choose whichever buffer size is smaller for the copy length uint32_t minSize = std::min(arraySize, static_cast(initList.size())); - memcpy(data.begin(), initList.begin(), minSize * sizeof(float)); - this->setMatrixToArray(data); + memcpy(this->matrix.begin(), initList.begin(), minSize * sizeof(float)); } template Matrix::Matrix(const Matrix &other) { for (uint8_t row_idx{0}; row_idx < rows; row_idx++) { for (uint8_t column_idx{0}; column_idx < columns; column_idx++) { - this->matrix[row_idx][column_idx] = other.Get(row_idx, column_idx); + this->matrix[row_idx * columns + column_idx] = + other.Get(row_idx, column_idx); } } } @@ -50,9 +49,9 @@ void Matrix::setMatrixToArray( static_cast(row_idx) * static_cast(columns) + static_cast(column_idx); if (array_idx < array.size()) { - this->matrix[row_idx][column_idx] = array[array_idx]; + this->matrix[row_idx * columns + column_idx] = array[array_idx]; } else { - this->matrix[row_idx][column_idx] = 0; + this->matrix[row_idx * columns + column_idx] = 0; } } } @@ -175,10 +174,9 @@ Matrix::Transpose(Matrix &result) const { // explicitly define the determinant for a 2x2 matrix because it is definitely // the fastest way to calculate a 2x2 matrix determinant template <> float Matrix<0, 0>::Det() const { return 1e+6; } -template <> float Matrix<1, 1>::Det() const { return this->matrix[0][0]; } +template <> float Matrix<1, 1>::Det() const { return this->matrix[0]; } template <> float Matrix<2, 2>::Det() const { - return this->matrix[0][0] * this->matrix[1][1] - - this->matrix[0][1] * this->matrix[1][0]; + return this->matrix[0] * this->matrix[3] - this->matrix[1] * this->matrix[2]; } template @@ -191,7 +189,7 @@ float Matrix::Det() const { for (uint8_t column_idx{0}; column_idx < columns; column_idx++) { // for odd indices the sign is negative float sign = (column_idx % 2 == 0) ? 1 : -1; - determinant += sign * this->matrix[0][column_idx] * + determinant += sign * this->matrix[column_idx] * this->MinorMatrix(MinorMatrix, 0, column_idx).Det(); } @@ -233,14 +231,15 @@ float Matrix::Get(uint8_t row_index, return 1e+10; // TODO: We should throw something here instead of failing // quietly } - return this->matrix[row_index][column_index]; + return this->matrix[row_index * columns + column_index]; } template Matrix<1, columns> & Matrix::GetRow(uint8_t row_index, Matrix<1, columns> &row) const { - row = Matrix<1, columns>(this->matrix[row_index]); + memcpy(&(row[0]), this->matrix.begin() + row_index * columns, + columns * sizeof(float)); return row; } @@ -261,7 +260,8 @@ void Matrix::ToString(std::string &stringBuffer) const { for (uint8_t row_idx{0}; row_idx < rows; row_idx++) { stringBuffer += "|"; for (uint8_t column_idx{0}; column_idx < columns; column_idx++) { - stringBuffer += std::to_string(this->matrix[row_idx][column_idx]); + stringBuffer += + std::to_string(this->matrix[row_idx * columns + column_idx]); if (column_idx != columns - 1) { stringBuffer += "\t"; } @@ -274,10 +274,13 @@ template std::array &Matrix:: operator[](uint8_t row_index) { if (row_index > rows - 1) { - return this->matrix[0]; // TODO: We should throw something here instead of - // failing quietly. + // TODO: We should throw something here instead of failing quietly. + row_index = 0; } - return this->matrix[row_index]; + // cursed reinterpret_cast that will help us fake having a nested array when + // we really don't + return *reinterpret_cast *>( + &(this->matrix[row_index * columns])); } template @@ -285,7 +288,8 @@ Matrix &Matrix:: operator=(const Matrix &other) { for (uint8_t row_idx{0}; row_idx < rows; row_idx++) { for (uint8_t column_idx{0}; column_idx < columns; column_idx++) { - this->matrix[row_idx][column_idx] = other.Get(row_idx, column_idx); + this->matrix[row_idx * columns + column_idx] = + other.Get(row_idx, column_idx); } } // return a reference to ourselves so you can chain together these functions @@ -351,7 +355,7 @@ template void Matrix::Fill(float value) { for (uint8_t row_idx{0}; row_idx < rows; row_idx++) { for (uint8_t column_idx{0}; column_idx < columns; column_idx++) { - this->matrix[row_idx][column_idx] = value; + this->matrix[row_idx * columns + column_idx] = value; } } } diff --git a/Matrix.hpp b/Matrix.hpp index a2e9299..4b5479b 100644 --- a/Matrix.hpp +++ b/Matrix.hpp @@ -198,7 +198,7 @@ private: void setMatrixToArray(const std::array &array); - std::array, rows> matrix; + std::array matrix; }; #include "Matrix.cpp" diff --git a/unit-tests/matrix-test-timings.txt b/unit-tests/matrix-test-timings.txt index 57b54b0..1e2dff2 100644 --- a/unit-tests/matrix-test-timings.txt +++ b/unit-tests/matrix-test-timings.txt @@ -1,14 +1,14 @@ -Addition: 0.55 s -Subtraction: 0.548 s -Multiplication: 3.404 s -Scalar Multiplication: 0.453 s -Element Multiply: 0.347 s -Element Divide: 0.347 s -Minor Matrix: 0.44 s -Determinant: 0.251 s -Matrix of Minors: 1.044 s -Invert: 0.262 s -Transpose: 0.26 s -Normalize: 0.333 s -GET ROW: 0.683 s -GET COLUMN: 0.427 s +Addition: 0.419 s +Subtraction: 0.421 s +Multiplication: 3.297 s +Scalar Multiplication: 0.329 s +Element Multiply: 0.306 s +Element Divide: 0.302 s +Minor Matrix: 0.331 s +Determinant: 0.177 s +Matrix of Minors: 0.766 s +Invert: 0.183 s +Transpose: 0.215 s +Normalize: 0.315 s +GET ROW: 0.008 s +GET COLUMN: 0.43 s diff --git a/unit-tests/test-timing-post-process.py b/unit-tests/test-timing-post-process.py index ba45a54..3b56360 100644 --- a/unit-tests/test-timing-post-process.py +++ b/unit-tests/test-timing-post-process.py @@ -83,7 +83,7 @@ for new_timing in new_timings: for old_timing in old_timings: if new_timing == old_timing: new_timing.difference = new_timing - old_timing - if new_timing.difference >= 0.03: + if abs(new_timing.difference) >= 0.03: difference_increased += f"{new_timing.test_name}, " def save_option(): @@ -102,7 +102,7 @@ for timing in new_timings: print(timing.to_string_w_diff()) if len(difference_increased) > 0: - print("You increased the time it takes to run for:" + difference_increased) + print("You've made major timing changes for:" + difference_increased) save_option() else: print("No times have changed outside the margin of error.")