// // matrix_test.cpp // matrix // // Created by Sam Jaffe on 6/3/18. // #include #include "math/matrix/matrix.hpp" using matr2i = math::matrix::matrix; using matr2 = math::matrix::matrix; matr2i identity2i() { return matr2i({{{1, 0}, {0, 1}}}); } matr2 identity2() { return matr2({{{1, 0}, {0, 1}}}); } TEST(Matrix, Equality) { EXPECT_THAT(identity2i(), matr2i({{{1, 0}, {0, 1}}})); EXPECT_THAT(identity2i(), ::testing::Ne(matr2i({{{0, 1}, {0, 1}}}))); } TEST(Matrix, AtRowBeyondBoundaryThrowsException) { EXPECT_THROW(identity2i().at(2), std::out_of_range); } TEST(Matrix, ConstAtRowBeyondBoundaryThrowsException) { auto const iden = identity2i(); EXPECT_THROW(iden.at(2), std::out_of_range); } TEST(Matrix, AtCoordBeyondBoundaryThrowsException) { EXPECT_THROW(identity2i().at(2, 1), std::out_of_range); EXPECT_THROW(identity2i().at(1, 2), std::out_of_range); } TEST(Matrix, ConstAtCoordBeyondBoundaryThrowsException) { auto const iden = identity2i(); EXPECT_THROW(iden.at(2, 1), std::out_of_range); EXPECT_THROW(iden.at(1, 2), std::out_of_range); } TEST(Matrix, AtColumnBeyondBoundaryThrowsException) { auto iden = identity2i(); auto row = iden[1]; EXPECT_THROW(row.at(2), std::out_of_range); } TEST(Matrix, ConstAtColumnBeyondBoundaryThrowsException) { auto const iden = identity2i(); auto const row = iden[1]; EXPECT_THROW(row.at(2), std::out_of_range); } TEST(Matrix, TransposeOfSquareMatrixRotatesAroundDiagonal) { matr2i mat({{{1, 1}, {2, 2}}}); EXPECT_THAT(mat.transpose(), matr2i({{{1, 2}, {1, 2}}})); } TEST(Matrix, TransposeOfMatrixFlipsDimension) { using matr3x2i = math::matrix::matrix; using matr2x3i = math::matrix::matrix; matr3x2i mat({{{1, 1}, {2, 2}, {3, 3}}}); EXPECT_THAT(mat.transpose(), matr2x3i({{{1, 2, 3}, {1, 2, 3}}})); } TEST(Matrix, AdditionSumsAllElements) { auto iden = identity2i(); auto result = matr2i({{{2, 0}, {0, 2}}}); EXPECT_THAT(iden + iden, result); } TEST(Matrix, DefaultConstructorIsZeros) { auto zero = matr2i({{{0, 0}, {0, 0}}}); EXPECT_THAT(matr2i{}, zero); } TEST(Matrix, SubtractionDiffsAllElements) { auto iden = identity2i(); EXPECT_THAT(iden - iden, matr2i()); } TEST(Matrix, NegationAltersAllElements) { EXPECT_THAT(-identity2i(), matr2i({{{-1, 0}, {0, -1}}})); } TEST(Matrix, MultiplicationAltersAllElements) { EXPECT_THAT(2 * identity2(), matr2({{{2.0, 0.0}, {0.0, 2.0}}})); EXPECT_THAT(identity2() * 2, matr2({{{2.0, 0.0}, {0.0, 2.0}}})); } TEST(Matrix, DivisionAltersAllElements) { EXPECT_THAT(identity2() / 2.0, matr2({{{0.5, 0.0}, {0.0, 0.5}}})); } TEST(Matrix, MultiplyingSameSizeMatricesProducesSameSize) { auto A = matr2i({{{1, 2}, {2, 3}}}); auto B = matr2i({{{1, 0}, {1, 1}}}); EXPECT_THAT(A * B, matr2i({{{3, 2}, {5, 3}}})); EXPECT_THAT(B * A, matr2i({{{1, 2}, {3, 5}}})); } TEST(Matrix, MultiplyingDifferentSizeMatricesChangesSize) { using matr2x2i = math::matrix::matrix; using matr2x3i = math::matrix::matrix; using matr3x2i = math::matrix::matrix; using matr3x3i = math::matrix::matrix; auto A = matr3x2i({{{1, 0}, {0, 1}, {1, 1}}}); auto B = matr2x3i({{{0, 1, 0}, {1, 0, 1}}}); EXPECT_THAT(A * B, matr3x3i({{{0, 1, 0}, {1, 0, 1}, {1, 1, 1}}})); EXPECT_THAT(B * A, matr2x2i({{{0, 1}, {2, 1}}})); } TEST(Matrix, VectorMultiplicationProducesVector) { using vec2i = math::vector::vector; auto A = matr2i({{{1, 0}, {1, 2}}}); auto x = vec2i({1, 2}); EXPECT_THAT(A * x, vec2i({1, 5})); } TEST(Matrix, ConcatenationExtends) { using namespace math::matrix; auto A = matr2i({{{1, 2}, {2, 3}}}); auto B = matr2i({{{1, 0}, {1, 1}}}); EXPECT_THAT(A.concat(B, concat_strategy::horizontal), (matrix({{{1, 2, 1, 0}, {2, 3, 1, 1}}}))); EXPECT_THAT(A.concat(B, concat_strategy::vertical), (matrix({{{1, 2}, {2, 3}, {1, 0}, {1, 1}}}))); EXPECT_THAT(A.concat(B, concat_strategy::diagonal), (matrix( {{{1, 2, 0, 0}, {2, 3, 0, 0}, {0, 0, 1, 0}, {0, 0, 1, 1}}}))); } // TEST(Matrix, Composition) { // using namespace math::matrix; // using vec4 = math::vector::vector; // using vec3 = math::vector::vector; // auto rot = rotation<4>(math::degree{90}, rotate::X_AXIS); // auto mov = translation(vec3({2.0, 2.5, 1.5})); // auto scl = scalar(vec3(2.0, math::vector::fill)); // vec4 epsilon{0.00001, math::vector::fill}; // TS_ASSERT_DELTA((mov * scl * rot * vec4({1,2,3,1})), // (vec4({4.0,-1.5,-4.5,1.0})), // epsilon); //} TEST(Matrix, MatrixConstructableFromVector) { using vec3 = math::vector::vector; vec3 v = vec3({1, 2, 3}); math::matrix::matrix m{v}; EXPECT_THAT(m(0, 0), v[0]); EXPECT_THAT(m(1, 0), v[1]); EXPECT_THAT(m(2, 0), v[2]); } TEST(Matrix, RowAllowsMutation) { matr2i A = identity2i(); A[0][0] = 2; EXPECT_THAT(A, matr2i({{{2, 0}, {0, 1}}})); } TEST(Matrix, CanAlterEntireRowInOneExpression) { matr2i A = identity2i(); matr2i const B = 2 * A; A[0] = B[0]; EXPECT_THAT(A, matr2i({{{2, 0}, {0, 1}}})); }