matrix_helper_test.cxx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. //
  2. // matrix_helper_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_helpers.hpp"
  9. #include "math/matrix/macro.h"
  10. template <std::size_t N> using vec = math::vector::vector<double, N>;
  11. namespace math { namespace matrix {
  12. template <typename T, std::size_t R, std::size_t C>
  13. void PrintTo(matrix<T, R, C> const & matr, std::ostream * out) {
  14. (*out) << "[\n";
  15. VECTOR_FOR_EACH_RANGE(i, R) {
  16. (*out) << " [ ";
  17. VECTOR_FOR_EACH_RANGE(j, C) {
  18. if (j != 0) (*out) << ", ";
  19. (*out) << matr(i, j);
  20. }
  21. (*out) << " ]\n";
  22. }
  23. (*out) << "]";
  24. }
  25. }}
  26. TEST(MatrixHelper, IdentityFunctionProducesOnes) {
  27. auto iden = math::matrix::identity<double, 4>();
  28. VECTOR_FOR_EACH_RANGE(i, 4) { EXPECT_THAT(iden.at(i, i), 1.0); }
  29. MATRIX_FOR_EACH_RANGE(i, 4, j, 4) {
  30. EXPECT_TRUE(i == j || iden.at(i, j) == 0);
  31. }
  32. }
  33. TEST(MatrixHelper, DiagonalWillFillWithAllZeros) {
  34. vec<4> const vector{1.5, 0.5, -1.0, 2.2};
  35. auto diag = math::matrix::diagonal(vector);
  36. VECTOR_FOR_EACH_RANGE(i, 4) { EXPECT_THAT(diag.at(i, i), vector.at(i)); }
  37. MATRIX_FOR_EACH_RANGE(i, 4, j, 4) {
  38. EXPECT_TRUE(i == j || diag.at(i, j) == 0);
  39. }
  40. }
  41. TEST(MatrixHelper, ScalarMatrixPiecewiseStretchesVector) {
  42. vec<3> const vector{1.5, 0.5, -1.0};
  43. vec<3> const x{2.0, 3.8, 11.0};
  44. auto const A = math::matrix::scalar(vector);
  45. EXPECT_THAT(A * x, vector * x);
  46. }
  47. TEST(MatrixHelper, TranslationMatrixAddsToEachElement) {
  48. vec<3> const vector{1.5, 0.5, -1.0};
  49. vec<3> const x{2.0, 3.8, 11.0};
  50. auto const A = math::matrix::translation(vector);
  51. EXPECT_THAT(A * x, vector + x);
  52. }
  53. using matr3 = math::matrix::matrix<double, 3, 3>;
  54. using math::matrix::rotation;
  55. using math::matrix::rotation_t;
  56. namespace rotate = math::matrix::rotate;
  57. class RotationTest
  58. : public ::testing::TestWithParam<std::tuple<rotation_t<3>, matr3>> {};
  59. TEST(MatrixHelper, RotateByHalfPi) {
  60. auto const theta = M_PI / 2;
  61. auto const iden = math::matrix::identity<double, 2>();
  62. auto const expected = math::matrix::matrix<int, 2, 2>{{0, -1}, {1, 0}};
  63. auto result = iden * rotation(theta, rotate::ROT_2D);
  64. MATRIX_FOR_EACH_RANGE(i, 2, j, 2) {
  65. EXPECT_THAT(result(i, j),
  66. ::testing::DoubleNear(expected(i, j),
  67. std::numeric_limits<double>::epsilon()));
  68. }
  69. }
  70. TEST_P(RotationTest, RotateByHalfPi) {
  71. auto const theta = M_PI / 2;
  72. auto const iden = math::matrix::identity<double, 3>();
  73. auto const expected = std::get<1>(GetParam());
  74. auto result = iden * rotation(theta, std::get<0>(GetParam()));
  75. MATRIX_FOR_EACH_RANGE(i, 3, j, 3) {
  76. EXPECT_THAT(result(i, j),
  77. ::testing::DoubleNear(expected(i, j),
  78. std::numeric_limits<double>::epsilon()));
  79. }
  80. }
  81. TEST(MatrixHelper, RotateIntoLargerMatrixArea) {
  82. auto const theta = M_PI / 2;
  83. auto const iden = math::matrix::identity<double, 4>();
  84. auto const expected = math::matrix::matrix<double, 4, 4>{
  85. {0, -1, 0, 0}, {1, 0, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
  86. auto result = iden * rotation<4>(theta, rotate::Z_AXIS);
  87. MATRIX_FOR_EACH_RANGE(i, 4, j, 4) {
  88. EXPECT_THAT(result(i, j),
  89. ::testing::DoubleNear(expected(i, j),
  90. std::numeric_limits<double>::epsilon()));
  91. }
  92. }
  93. std::vector<std::tuple<rotation_t<3>, matr3>> values{
  94. {rotate::X_AXIS, matr3{{1, 0, 0}, {0, 0, -1}, {0, 1, 0}}},
  95. {rotate::Y_AXIS, matr3{{0, 0, 1}, {0, 1, 0}, {-1, 0, 0}}},
  96. {rotate::Z_AXIS, matr3{{0, -1, 0}, {1, 0, 0}, {0, 0, 1}}}};
  97. INSTANTIATE_TEST_SUITE_P(MatrixHelper, RotationTest,
  98. ::testing::ValuesIn(values));