matrix_test.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. //
  2. // matrix_test.cpp
  3. // matrix
  4. //
  5. // Created by Sam Jaffe on 6/3/18.
  6. //
  7. #include <gmock/gmock.h>
  8. #include "matrix.hpp"
  9. using matr2i = math::matrix::matrix<int, 2, 2>;
  10. using matr2 = math::matrix::matrix<double, 2, 2>;
  11. matr2i identity2i() { return matr2i({{{1,0},{0,1}}}); }
  12. matr2 identity2() { return matr2({{{1,0},{0,1}}}); }
  13. TEST(Matrix, Equality) {
  14. EXPECT_THAT(identity2i(),
  15. matr2i({{{1,0},{0,1}}}));
  16. EXPECT_THAT(identity2i(),
  17. ::testing::Not(matr2i({{{0,1},{0,1}}})));
  18. }
  19. TEST(Matrix, AtRowBeyondBoundaryThrowsException) {
  20. EXPECT_THROW(identity2i().at(2), std::out_of_range);
  21. }
  22. TEST(Matrix, ConstAtRowBeyondBoundaryThrowsException) {
  23. auto const iden = identity2i();
  24. EXPECT_THROW(iden.at(2), std::out_of_range);
  25. }
  26. TEST(Matrix, AtCoordBeyondBoundaryThrowsException) {
  27. EXPECT_THROW(identity2i().at(2, 1), std::out_of_range);
  28. EXPECT_THROW(identity2i().at(1, 2), std::out_of_range);
  29. }
  30. TEST(Matrix, ConstAtCoordBeyondBoundaryThrowsException) {
  31. auto const iden = identity2i();
  32. EXPECT_THROW(iden.at(2, 1), std::out_of_range);
  33. EXPECT_THROW(iden.at(1, 2), std::out_of_range);
  34. }
  35. TEST(Matrix, AtColumnBeyondBoundaryThrowsException) {
  36. auto iden = identity2i();
  37. auto row = iden[1];
  38. EXPECT_THROW(row.at(2), std::out_of_range);
  39. }
  40. TEST(Matrix, ConstAtColumnBeyondBoundaryThrowsException) {
  41. auto const iden = identity2i();
  42. auto const row = iden[1];
  43. EXPECT_THROW(row.at(2), std::out_of_range);
  44. }
  45. TEST(Matrix, TransposeOfSquareMatrixRotatesAroundDiagonal) {
  46. matr2i mat({{{1, 1}, {2, 2}}});
  47. EXPECT_THAT(mat.transpose(),
  48. matr2i({{{1, 2}, {1, 2}}}));
  49. }
  50. TEST(Matrix, TransposeOfMatrixFlipsDimension) {
  51. using matr3x2i = math::matrix::matrix<int, 3, 2>;
  52. using matr2x3i = math::matrix::matrix<int, 2, 3>;
  53. matr3x2i mat({{{1, 1}, {2, 2}, {3, 3}}});
  54. EXPECT_THAT(mat.transpose(),
  55. matr2x3i({{{1, 2, 3}, {1, 2, 3}}}));
  56. }
  57. TEST(Matrix, AdditionSumsAllElements) {
  58. auto iden = identity2i();
  59. auto result = matr2i({{{2,0},{0,2}}});
  60. EXPECT_THAT(iden + iden, result);
  61. }
  62. TEST(Matrix, DefaultConstructorIsZeros) {
  63. auto zero = matr2i({{{0,0},{0,0}}});
  64. EXPECT_THAT(matr2i{}, zero);
  65. }
  66. TEST(Matrix, SubtractionDiffsAllElements) {
  67. auto iden = identity2i();
  68. EXPECT_THAT(iden-iden, matr2i());
  69. }
  70. TEST(Matrix, NegationAltersAllElements) {
  71. EXPECT_THAT(-identity2i(), matr2i({{{-1,0},{0,-1}}}));
  72. }
  73. TEST(Matrix, MultiplicationAltersAllElements) {
  74. EXPECT_THAT(2*identity2(), matr2({{{2.0,0.0},{0.0,2.0}}}));
  75. EXPECT_THAT(identity2()*2, matr2({{{2.0,0.0},{0.0,2.0}}}));
  76. }
  77. TEST(Matrix, DivisionAltersAllElements) {
  78. EXPECT_THAT(identity2()/2.0, matr2({{{0.5,0.0},{0.0,0.5}}}));
  79. }
  80. TEST(Matrix, MultiplyingSameSizeMatricesProducesSameSize) {
  81. auto A = matr2i({{{1,2},{2,3}}});
  82. auto B = matr2i({{{1,0},{1,1}}});
  83. EXPECT_THAT(A*B, matr2i({{{3,2},{5,3}}}));
  84. EXPECT_THAT(B*A, matr2i({{{1,2},{3,5}}}));
  85. }
  86. TEST(Matrix, MultiplyingDifferentSizeMatricesChangesSize) {
  87. using matr2x2i = math::matrix::matrix<int, 2, 2>;
  88. using matr2x3i = math::matrix::matrix<int, 2, 3>;
  89. using matr3x2i = math::matrix::matrix<int, 3, 2>;
  90. using matr3x3i = math::matrix::matrix<int, 3, 3>;
  91. auto A = matr3x2i({{{1,0},{0,1},{1,1}}});
  92. auto B = matr2x3i({{{0,1,0},{1,0,1}}});
  93. EXPECT_THAT(A*B, matr3x3i({{{0,1,0},{1,0,1},{1,1,1}}}));
  94. EXPECT_THAT(B*A, matr2x2i({{{0,1},{2,1}}}));
  95. }
  96. TEST(Matrix, VectorMultiplicationProducesVector) {
  97. using vec2i = math::vector::vector<int, 2>;
  98. auto A = matr2i({{{1,0},{1,2}}});
  99. auto x = vec2i({1,2});
  100. EXPECT_THAT(A*x, vec2i({1,5}));
  101. }
  102. //TEST(Matrix, Composition) {
  103. // using namespace math::matrix;
  104. // using vec4 = math::vector::vector<double, 4>;
  105. // using vec3 = math::vector::vector<double, 3>;
  106. // auto rot = rotation<4>(math::degree{90}, rotate::X_AXIS);
  107. // auto mov = translation(vec3({2.0, 2.5, 1.5}));
  108. // auto scl = scalar(vec3(2.0, math::vector::fill));
  109. // vec4 epsilon{0.00001, math::vector::fill};
  110. // TS_ASSERT_DELTA((mov * scl * rot * vec4({1,2,3,1})),
  111. // (vec4({4.0,-1.5,-4.5,1.0})),
  112. // epsilon);
  113. //}
  114. TEST(Matrix, MatrixConstructableFromVector) {
  115. using vec3 = math::vector::vector<double, 3>;
  116. vec3 v = vec3({1,2,3});
  117. math::matrix::matrix<double, 3, 1> m{v};
  118. EXPECT_THAT(m(0,0), v[0]);
  119. EXPECT_THAT(m(1,0), v[1]);
  120. EXPECT_THAT(m(2,0), v[2]);
  121. }
  122. TEST(Matrix, CanAlterEntireRowInOneExpression) {
  123. matr2i A = identity2i();
  124. matr2i const B = 2 * A;
  125. A[0] = B[0];
  126. EXPECT_THAT(A, matr2i({{{2,0},{0,1}}}));
  127. }