Skip to content

Commit 40a3011

Browse files
authored
Merge pull request #40 from orange-cpp/u/orange/inverted-matrix
U/orange/inverted matrix
2 parents 69b9049 + a41526c commit 40a3011

File tree

2 files changed

+49
-6
lines changed

2 files changed

+49
-6
lines changed

include/omath/mat.hpp

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,21 +253,24 @@ namespace omath
253253

254254
if constexpr (Rows == 2)
255255
return At(0, 0) * At(1, 1) - At(0, 1) * At(1, 0);
256-
else
256+
257+
if constexpr (Rows > 2)
257258
{
258259
Type det = 0;
259-
for (size_t i = 0; i < Columns; ++i)
260+
for (size_t column = 0; column < Columns; ++column)
260261
{
261-
const Type cofactor = (i % 2 == 0 ? 1 : -1) * At(0, i) * Minor(0, i).Determinant();
262+
const Type cofactor = At(0, column) * AlgComplement(0, column);
262263
det += cofactor;
263264
}
264265
return det;
265266
}
267+
std::unreachable();
266268
}
267269

268270
[[nodiscard]]
269-
constexpr Mat<Rows - 1, Columns - 1, Type, StoreType> Minor(const size_t row, const size_t column) const
271+
constexpr Mat<Rows - 1, Columns - 1, Type, StoreType> Strip(const size_t row, const size_t column) const
270272
{
273+
static_assert(Rows-1 > 0 && Columns-1 > 0);
271274
Mat<Rows - 1, Columns - 1, Type, StoreType> result;
272275
for (size_t i = 0, m = 0; i < Rows; ++i)
273276
{
@@ -285,6 +288,19 @@ namespace omath
285288
return result;
286289
}
287290

291+
[[nodiscard]]
292+
constexpr Type Minor(const size_t row, const size_t column) const
293+
{
294+
return Strip(row, column).Determinant();
295+
}
296+
297+
[[nodiscard]]
298+
constexpr Type AlgComplement(const size_t row, const size_t column) const
299+
{
300+
const auto minor = Minor(row, column);
301+
return (row + column + 2) % 2 == 0 ? minor: -minor;
302+
}
303+
288304
[[nodiscard]]
289305
constexpr const std::array<Type, Rows * Columns>& RawArray() const
290306
{
@@ -343,6 +359,25 @@ namespace omath
343359
};
344360
}
345361

362+
[[nodiscard]]
363+
constexpr std::optional<Mat> Inverted() const
364+
{
365+
const auto det = Determinant();
366+
367+
if (det == 0)
368+
return std::nullopt;
369+
370+
const auto transposed = Transposed();
371+
Mat result;
372+
373+
for (std::size_t row = 0; row < Rows; row++)
374+
for (std::size_t column = 0; column < Rows; column++)
375+
result.At(row, column) = transposed.AlgComplement(row, column);
376+
377+
result /= det;
378+
379+
return {result};
380+
}
346381
private:
347382
std::array<Type, Rows * Columns> m_data;
348383
};

tests/general/unit_test_mat.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,10 @@ TEST(UnitTestMatStandalone, Determinant_3x3)
180180
}
181181

182182
// Test Minor for 3x3 matrix
183-
TEST(UnitTestMatStandalone, Minor_3x3)
183+
TEST(UnitTestMatStandalone, Strip_3x3)
184184
{
185185
constexpr Mat<3, 3> m{{3, 0, 2}, {2, 0, -2}, {0, 1, 1}};
186-
auto minor = m.Minor(0, 0);
186+
auto minor = m.Strip(0, 0);
187187
EXPECT_EQ(minor.RowCount(), 2);
188188
EXPECT_EQ(minor.ColumnsCount(), 2);
189189
EXPECT_FLOAT_EQ(minor.At(0, 0), 0.0f);
@@ -206,3 +206,11 @@ TEST(UnitTestMatStandalone, Transpose_NonSquare)
206206
EXPECT_FLOAT_EQ(transposed.At(1, 1), 5.0f);
207207
EXPECT_FLOAT_EQ(transposed.At(2, 1), 6.0f);
208208
}
209+
210+
TEST(UnitTestMatStandalone, Enverse)
211+
{
212+
constexpr Mat<2, 2> m{{1.0f, 3.0f}, {2.0f, 5.0f}};
213+
constexpr Mat<2,2> mv{{-5.0f, 3.0f}, {2.0f, -1.0f}};
214+
215+
EXPECT_EQ(mv, m.Inverted());
216+
}

0 commit comments

Comments
 (0)