Select Git revision
TriangleTransformation.hpp
-
Stéphane Del Pino authored
There are no more template classes for affine and multilinear transformations. Now the classes refer directly to the reference element that is changed. This is also a preparation for surfaces and edges transformations (in superior dimensions).
Stéphane Del Pino authoredThere are no more template classes for affine and multilinear transformations. Now the classes refer directly to the reference element that is changed. This is also a preparation for surfaces and edges transformations (in superior dimensions).
test_TinyMatrix.cpp 7.60 KiB
#include <catch2/catch_approx.hpp>
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_all.hpp>
#include <Kokkos_Core.hpp>
#include <utils/PugsAssert.hpp>
#include <utils/Types.hpp>
#include <algebra/TinyMatrix.hpp>
// Instantiate to ensure full coverage is performed
template class TinyMatrix<1, int>;
template class TinyMatrix<2, int>;
template class TinyMatrix<3, int>;
template class TinyMatrix<4, double>;
// clazy:excludeall=non-pod-global-static
TEST_CASE("TinyMatrix", "[algebra]")
{
TinyMatrix<3, int> A(1, 2, 3, 4, 5, 6, 7, 8, 9);
REQUIRE(((A(0, 0) == 1) and (A(0, 1) == 2) and (A(0, 2) == 3) and (A(1, 0) == 4) and (A(1, 1) == 5) and
(A(1, 2) == 6) and (A(2, 0) == 7) and (A(2, 1) == 8) and (A(2, 2) == 9)));
TinyMatrix<3, int> B(6, 5, 3, 8, 34, 6, 35, 6, 7);
SECTION("checking for opposed matrix")
{
const TinyMatrix<3, int> minus_A = -A;
REQUIRE(((minus_A(0, 0) == -1) and (minus_A(0, 1) == -2) and (minus_A(0, 2) == -3) and (minus_A(1, 0) == -4) and
(minus_A(1, 1) == -5) and (minus_A(1, 2) == -6) and (minus_A(2, 0) == -7) and (minus_A(2, 1) == -8) and
(minus_A(2, 2) == -9)));
}
SECTION("checking for equality and difference tests")
{
const TinyMatrix<3, int> copy_A = A;
REQUIRE(((copy_A(0, 0) == 1) and (copy_A(0, 1) == 2) and (copy_A(0, 2) == 3) and (copy_A(1, 0) == 4) and
(copy_A(1, 1) == 5) and (copy_A(1, 2) == 6) and (copy_A(2, 0) == 7) and (copy_A(2, 1) == 8) and
(copy_A(2, 2) == 9)));
REQUIRE(copy_A == A);
REQUIRE_FALSE(copy_A != A);
TinyMatrix<3, int> affected_A;
affected_A = A;
REQUIRE(affected_A == A);
REQUIRE_FALSE(affected_A != A);
REQUIRE(A != B);
REQUIRE_FALSE(A == B);
}
SECTION("checking for scalar left product")
{
const int a = 2;
const TinyMatrix<3, int> aA = a * A;
REQUIRE(aA == TinyMatrix<3, int>(2, 4, 6, 8, 10, 12, 14, 16, 18));
}
SECTION("checking for scalar seft product")
{
const int a = 2;
TinyMatrix<3, int> copy_A = A;
REQUIRE((copy_A *= a) == TinyMatrix<3, int>(2, 4, 6, 8, 10, 12, 14, 16, 18));
}
SECTION("checking for null matrix management")
{
TinyMatrix<3, int> Z = zero;
REQUIRE(Z == TinyMatrix<3, int>(0, 0, 0, 0, 0, 0, 0, 0, 0));
TinyMatrix<3, int> affected_Z;
affected_Z = zero;
REQUIRE(affected_Z == Z);
}
SECTION("checking for identity management")
{
TinyMatrix<3, int> I = identity;
REQUIRE(I == TinyMatrix<3, int>(1, 0, 0, 0, 1, 0, 0, 0, 1));
TinyMatrix<3, int> affected_I;
affected_I = identity;
REQUIRE(affected_I == I);
}
SECTION("checking for matrices sum")
{
REQUIRE(A + B == TinyMatrix<3, int>(7, 7, 6, 12, 39, 12, 42, 14, 16));
TinyMatrix<3, int> ApB = A;
ApB += B;
REQUIRE(ApB == A + B);
TinyMatrix<3, int> Ap2B = A + 2 * B;
REQUIRE(Ap2B == ApB + B);
}
SECTION("checking for matrices difference ")
{
REQUIRE(A - B == TinyMatrix<3, int>(-5, -3, 0, -4, -29, 0, -28, 2, 2));
TinyMatrix<3, int> AmB = A;
AmB -= B;
REQUIRE(AmB == A - B);
TinyMatrix<3, int> Am2B = A - 2 * B;
REQUIRE(Am2B == AmB - B);
}
SECTION("checking for matrices product")
{
REQUIRE(A * B == TinyMatrix<3, int>(127, 91, 36, 274, 226, 84, 421, 361, 132));
}
SECTION("checking for matrix-vector product")
{
REQUIRE(A * TinyVector<3, int>(2, -3, 5) == TinyVector<3, int>(11, 23, 35));
}
SECTION("checking for tensor product")
{
const TinyVector<3, int> u(1, 3, 7);
const TinyVector<3, int> v(6, 2, -3);
REQUIRE(tensorProduct(u, v) == TinyMatrix<3, int>(6, 2, -3, 18, 6, -9, 42, 14, -21));
}
SECTION("checking for minor calculation")
{
TinyMatrix<3, int> A(1, 2, 3, 4, 5, 6, 7, 8, 9);
REQUIRE(getMinor(A, 0, 0) == TinyMatrix<2, int>(5, 6, 8, 9));
REQUIRE(getMinor(A, 1, 0) == TinyMatrix<2, int>(2, 3, 8, 9));
REQUIRE(getMinor(A, 2, 0) == TinyMatrix<2, int>(2, 3, 5, 6));
REQUIRE(getMinor(A, 0, 1) == TinyMatrix<2, int>(4, 6, 7, 9));
REQUIRE(getMinor(A, 1, 1) == TinyMatrix<2, int>(1, 3, 7, 9));
REQUIRE(getMinor(A, 2, 1) == TinyMatrix<2, int>(1, 3, 4, 6));
REQUIRE(getMinor(A, 0, 2) == TinyMatrix<2, int>(4, 5, 7, 8));
REQUIRE(getMinor(A, 1, 2) == TinyMatrix<2, int>(1, 2, 7, 8));
REQUIRE(getMinor(A, 2, 2) == TinyMatrix<2, int>(1, 2, 4, 5));
}
SECTION("checking for cofactors")
{
TinyMatrix<3, int> A(1, 2, 3, 4, 5, 6, 7, 8, 9);
REQUIRE(cofactor(A, 0, 0) == (5 * 9 - 8 * 6));
REQUIRE(cofactor(A, 1, 0) == -(2 * 9 - 8 * 3));
REQUIRE(cofactor(A, 2, 0) == (2 * 6 - 5 * 3));
REQUIRE(cofactor(A, 0, 1) == -(4 * 9 - 7 * 6));
REQUIRE(cofactor(A, 1, 1) == (1 * 9 - 7 * 3));
REQUIRE(cofactor(A, 2, 1) == -(1 * 6 - 4 * 3));
REQUIRE(cofactor(A, 0, 2) == (4 * 8 - 5 * 7));
REQUIRE(cofactor(A, 1, 2) == -(1 * 8 - 7 * 2));
REQUIRE(cofactor(A, 2, 2) == (1 * 5 - 4 * 2));
}
SECTION("checking for determinant calculations")
{
REQUIRE(det(TinyMatrix<1, int>(6)) == 6);
REQUIRE(det(TinyMatrix<2, int>(3, 1, -3, 6)) == 21);
REQUIRE(det(TinyMatrix<3, int>(1, 1, 1, 1, 2, 1, 2, 1, 3)) == 1);
REQUIRE(det(B) == -1444);
REQUIRE(det(TinyMatrix<4, double>(1, 2.3, 7, -6.2, 3, 4, 9, 1, 4.1, 5, 2, -3, 2, 27, 3, 17.5)) ==
Catch::Approx(6661.455).epsilon(1E-14));
REQUIRE(det(TinyMatrix<4, double>(1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 2, 0, 0, 2, 2)) == 0);
}
SECTION("checking for inverse calculations")
{
{
const TinyMatrix<1, double> A1(2);
REQUIRE(inverse(A1)(0, 0) == Catch::Approx(0.5).epsilon(1E-14));
}
{
const TinyMatrix<2, double> A2(2, 3, 4, 1);
const TinyMatrix<2, double> I = inverse(A2) * A2;
REQUIRE(I(0, 0) == Catch::Approx(1).epsilon(1E-14));
REQUIRE(I(0, 1) == Catch::Approx(0).margin(1E-14));
REQUIRE(I(1, 0) == Catch::Approx(0).margin(1E-14));
REQUIRE(I(1, 1) == Catch::Approx(1).epsilon(1E-14));
}
{
const TinyMatrix<3, double> A3(2, 3, 1, 4, -1, 5, -2, 3, 4);
const TinyMatrix<3, double> I = inverse(A3) * A3;
REQUIRE(I(0, 0) == Catch::Approx(1).epsilon(1E-14));
REQUIRE(I(0, 1) == Catch::Approx(0).margin(1E-14));
REQUIRE(I(0, 2) == Catch::Approx(0).margin(1E-14));
REQUIRE(I(1, 0) == Catch::Approx(0).margin(1E-14));
REQUIRE(I(1, 1) == Catch::Approx(1).epsilon(1E-14));
REQUIRE(I(1, 2) == Catch::Approx(0).margin(1E-14));
REQUIRE(I(2, 0) == Catch::Approx(0).margin(1E-14));
REQUIRE(I(2, 1) == Catch::Approx(0).margin(1E-14));
REQUIRE(I(2, 2) == Catch::Approx(1).epsilon(1E-14));
}
}
SECTION("checking for sizes")
{
REQUIRE(TinyMatrix<1>{}.nbRows() == 1);
REQUIRE(TinyMatrix<1>{}.nbColumns() == 1);
REQUIRE(TinyMatrix<1>{}.dimension() == 1);
REQUIRE(TinyMatrix<2>{}.nbRows() == 2);
REQUIRE(TinyMatrix<2>{}.nbColumns() == 2);
REQUIRE(TinyMatrix<2>{}.dimension() == 4);
REQUIRE(TinyMatrix<3>{}.nbRows() == 3);
REQUIRE(TinyMatrix<3>{}.nbColumns() == 3);
REQUIRE(TinyMatrix<3>{}.dimension() == 9);
}
SECTION("checking for matrices output")
{
REQUIRE(Catch::Detail::stringify(A) == "[(1,2,3)(4,5,6)(7,8,9)]");
REQUIRE(Catch::Detail::stringify(TinyMatrix<1, int>(7)) == "[(7)]");
}
#ifndef NDEBUG
SECTION("checking for bounds violation")
{
REQUIRE_THROWS_AS(A(3, 0), AssertError);
REQUIRE_THROWS_AS(A(0, 3), AssertError);
REQUIRE_THROWS_AS(getMinor(A, 3, 0), AssertError);
REQUIRE_THROWS_AS(getMinor(A, 0, 3), AssertError);
const TinyMatrix<3, int>& constA = A;
REQUIRE_THROWS_AS(constA(3, 0), AssertError);
REQUIRE_THROWS_AS(constA(0, 3), AssertError);
}
#endif // NDEBUG
}