matrix_test.cxx 5.1 KB

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