transpose and determinant matrix functions

This commit is contained in:
BlackMATov
2020-11-24 19:23:55 +07:00
parent b85cfb8e85
commit caf6ba65b4
2 changed files with 201 additions and 0 deletions

View File

@@ -258,3 +258,137 @@ namespace vmath_hpp
return false;
}
}
//
// Matrix Functions
//
namespace vmath_hpp
{
namespace impl
{
template < typename T >
constexpr mat<T, 2> transpose_2x2_impl(
T a, T c,
T b, T d)
{
return {
a, b,
c, d};
}
template < typename T >
constexpr mat<T, 3> transpose_3x3_impl(
T a, T d, T g,
T b, T e, T h,
T c, T f, T i)
{
return {
a, b, c,
d, e, f,
g, h, i};
}
template < typename T >
constexpr mat<T, 4> transpose_4x4_impl(
T a, T e, T i, T m,
T b, T f, T j, T n,
T c, T g, T k, T o,
T d, T h, T l, T p)
{
return {
a, b, c, d,
e, f, g, h,
i, j, k, l,
m, n, o, p};
}
}
template < typename T >
constexpr mat<T, 2> transpose(const mat<T, 2>& m) {
return impl::transpose_2x2_impl(
m[0][0], m[0][1],
m[1][0], m[1][1]);
}
template < typename T >
constexpr mat<T, 3> transpose(const mat<T, 3>& m) {
return impl::transpose_3x3_impl(
m[0][0], m[0][1], m[0][2],
m[1][0], m[1][1], m[1][2],
m[2][0], m[2][1], m[2][2]);
}
template < typename T >
constexpr mat<T, 4> transpose(const mat<T, 4>& m) {
return impl::transpose_4x4_impl(
m[0][0], m[0][1], m[0][2], m[0][3],
m[1][0], m[1][1], m[1][2], m[1][3],
m[2][0], m[2][1], m[2][2], m[2][3],
m[3][0], m[3][1], m[3][2], m[3][3]);
}
namespace impl
{
template < typename T >
constexpr T determinant_2x2_impl(
T a, T b,
T c, T d)
{
return
+ a * d
- b * c;
}
template < typename T >
constexpr T determinant_3x3_impl(
T a, T b, T c,
T d, T e, T f,
T g, T h, T i)
{
return
+ a * determinant_2x2_impl(e, f, h, i)
- b * determinant_2x2_impl(d, f, g, i)
+ c * determinant_2x2_impl(d, e, g, h);
}
template < typename T >
constexpr T determinant_4x4_impl(
T a, T b, T c, T d,
T e, T f, T g, T h,
T i, T j, T k, T l,
T m, T n, T o, T p)
{
return
+ a * determinant_3x3_impl(f, g, h, j, k, l, n, o, p)
- b * determinant_3x3_impl(e, g, h, i, k, l, m, o, p)
+ c * determinant_3x3_impl(e, f, h, i, j, l, m, n, p)
- d * determinant_3x3_impl(e, f, g, i, j, k, m, n, o);
}
}
template < typename T >
constexpr T determinant(const mat<T, 2>& m) {
return impl::determinant_2x2_impl(
m[0][0], m[0][1],
m[1][0], m[1][1]);
}
template < typename T >
constexpr T determinant(const mat<T, 3>& m) {
return impl::determinant_3x3_impl(
m[0][0], m[0][1], m[0][2],
m[1][0], m[1][1], m[1][2],
m[2][0], m[2][1], m[2][2]);
}
template < typename T >
constexpr T determinant(const mat<T, 4>& m) {
return impl::determinant_4x4_impl(
m[0][0], m[0][1], m[0][2], m[0][3],
m[1][0], m[1][1], m[1][2], m[1][3],
m[2][0], m[2][1], m[2][2], m[2][3],
m[3][0], m[3][1], m[3][2], m[3][3]);
}
}

View File

@@ -12,6 +12,23 @@
namespace
{
using namespace vmath_hpp;
template < typename T, int Size >
constexpr mat<T, Size> generate_frank_matrix() {
mat<T, Size> m;
for ( int i = 1; i <= Size; ++i ) {
for ( int j = 1; j <= Size; ++j ) {
if ( j < i - Size ) {
m[i - 1][j - 1] = 0;
} else if ( j == (i - 1) ) {
m[i - 1][j - 1] = Size + 1 - i;
} else {
m[i - 1][j - 1] = Size + 1 - j;
}
}
}
return m;
}
}
TEST_CASE("vmath/mat_fun") {
@@ -39,4 +56,54 @@ TEST_CASE("vmath/mat_fun") {
STATIC_REQUIRE(vec3i(1,2,3) * mat3i() == vec3i(1,2,3));
STATIC_REQUIRE(vec4i(1,2,3,4) * mat4i() == vec4i(1,2,3,4));
}
SECTION("Matrix Functions") {
{
STATIC_REQUIRE(transpose(mat2i(
1, 2,
3, 4
)) == mat2i(
1, 3,
2, 4
));
STATIC_REQUIRE(transpose(mat3i(
1, 2, 3,
4, 5, 6,
7, 8, 9
)) == mat3i(
1, 4, 7,
2, 5, 8,
3, 6, 9
));
STATIC_REQUIRE(transpose(mat4i(
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16
)) == mat4i(
1, 5, 9, 13,
2, 6, 10, 14,
3, 7, 11, 15,
4, 8, 12, 16
));
}
{
constexpr mat2i m2{1,2,3,4};
constexpr mat3i m3{1,2,3,4,5,6,7,8,9};
constexpr mat4i m4{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
STATIC_REQUIRE(determinant(m2) == determinant(transpose(m2)));
STATIC_REQUIRE(determinant(m3) == determinant(transpose(m3)));
STATIC_REQUIRE(determinant(m4) == determinant(transpose(m4)));
STATIC_REQUIRE(determinant(generate_frank_matrix<int, 2>()) == 1);
STATIC_REQUIRE(determinant(generate_frank_matrix<int, 3>()) == 1);
STATIC_REQUIRE(determinant(generate_frank_matrix<int, 4>()) == 1);
STATIC_REQUIRE(determinant(transpose(generate_frank_matrix<int, 2>())) == 1);
STATIC_REQUIRE(determinant(transpose(generate_frank_matrix<int, 3>())) == 1);
STATIC_REQUIRE(determinant(transpose(generate_frank_matrix<int, 4>())) == 1);
}
}
}