Select Git revision
test_TinyMatrix.cpp
-
Stéphane Del Pino authored
Now subdirectory must be specified. The main reason for this change, is that this explicitely sets where the file is. Moreover, it "simplifies" `CMakeLists.txt` files.
Stéphane Del Pino authoredNow subdirectory must be specified. The main reason for this change, is that this explicitely sets where the file is. Moreover, it "simplifies" `CMakeLists.txt` files.
test_TinyMatrix.cpp 6.75 KiB
#include <catch2/catch.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>;
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(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)) ==
Approx(6661.455).epsilon(1E-14));
}
SECTION("checking for inverse calculations")
{
{
const TinyMatrix<1, double> A1(2);
REQUIRE(inverse(A1)(0, 0) == 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) == Approx(1).epsilon(1E-14));
REQUIRE(I(0, 1) == Approx(0).margin(1E-14));
REQUIRE(I(1, 0) == Approx(0).margin(1E-14));
REQUIRE(I(1, 1) == 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) == Approx(1).epsilon(1E-14));
REQUIRE(I(0, 1) == Approx(0).margin(1E-14));
REQUIRE(I(0, 2) == Approx(0).margin(1E-14));
REQUIRE(I(1, 0) == Approx(0).margin(1E-14));
REQUIRE(I(1, 1) == Approx(1).epsilon(1E-14));
REQUIRE(I(1, 2) == Approx(0).margin(1E-14));
REQUIRE(I(2, 0) == Approx(0).margin(1E-14));
REQUIRE(I(2, 1) == Approx(0).margin(1E-14));
REQUIRE(I(2, 2) == Approx(1).epsilon(1E-14));
}
}
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
}