diff --git a/include/omath/mat.hpp b/include/omath/mat.hpp index 47773c6..c418702 100644 --- a/include/omath/mat.hpp +++ b/include/omath/mat.hpp @@ -253,21 +253,24 @@ namespace omath if constexpr (Rows == 2) return At(0, 0) * At(1, 1) - At(0, 1) * At(1, 0); - else + + if constexpr (Rows > 2) { Type det = 0; - for (size_t i = 0; i < Columns; ++i) + for (size_t column = 0; column < Columns; ++column) { - const Type cofactor = (i % 2 == 0 ? 1 : -1) * At(0, i) * Minor(0, i).Determinant(); + const Type cofactor = At(0, column) * AlgComplement(0, column); det += cofactor; } return det; } + std::unreachable(); } [[nodiscard]] - constexpr Mat Minor(const size_t row, const size_t column) const + constexpr Mat Strip(const size_t row, const size_t column) const { + static_assert(Rows-1 > 0 && Columns-1 > 0); Mat result; for (size_t i = 0, m = 0; i < Rows; ++i) { @@ -285,6 +288,19 @@ namespace omath return result; } + [[nodiscard]] + constexpr Type Minor(const size_t row, const size_t column) const + { + return Strip(row, column).Determinant(); + } + + [[nodiscard]] + constexpr Type AlgComplement(const size_t row, const size_t column) const + { + const auto minor = Minor(row, column); + return (row + column + 2) % 2 == 0 ? minor: -minor; + } + [[nodiscard]] constexpr const std::array& RawArray() const { @@ -343,6 +359,25 @@ namespace omath }; } + [[nodiscard]] + constexpr std::optional Inverted() const + { + const auto det = Determinant(); + + if (det == 0) + return std::nullopt; + + const auto transposed = Transposed(); + Mat result; + + for (std::size_t row = 0; row < Rows; row++) + for (std::size_t column = 0; column < Rows; column++) + result.At(row, column) = transposed.AlgComplement(row, column); + + result /= det; + + return {result}; + } private: std::array m_data; }; diff --git a/tests/general/unit_test_mat.cpp b/tests/general/unit_test_mat.cpp index 43b25c1..7fc25f6 100644 --- a/tests/general/unit_test_mat.cpp +++ b/tests/general/unit_test_mat.cpp @@ -180,10 +180,10 @@ TEST(UnitTestMatStandalone, Determinant_3x3) } // Test Minor for 3x3 matrix -TEST(UnitTestMatStandalone, Minor_3x3) +TEST(UnitTestMatStandalone, Strip_3x3) { constexpr Mat<3, 3> m{{3, 0, 2}, {2, 0, -2}, {0, 1, 1}}; - auto minor = m.Minor(0, 0); + auto minor = m.Strip(0, 0); EXPECT_EQ(minor.RowCount(), 2); EXPECT_EQ(minor.ColumnsCount(), 2); EXPECT_FLOAT_EQ(minor.At(0, 0), 0.0f); @@ -206,3 +206,11 @@ TEST(UnitTestMatStandalone, Transpose_NonSquare) EXPECT_FLOAT_EQ(transposed.At(1, 1), 5.0f); EXPECT_FLOAT_EQ(transposed.At(2, 1), 6.0f); } + +TEST(UnitTestMatStandalone, Enverse) +{ + constexpr Mat<2, 2> m{{1.0f, 3.0f}, {2.0f, 5.0f}}; + constexpr Mat<2,2> mv{{-5.0f, 3.0f}, {2.0f, -1.0f}}; + + EXPECT_EQ(mv, m.Inverted()); +}