slice.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include <test_common.h>
  2. #include <igl/LinSpaced.h>
  3. #include <igl/placeholders.h>
  4. #include <igl/randperm.h>
  5. // We don't want to include dense slices in the static library so include them
  6. // via header only mode for these tests (which themselves will eventually be
  7. // deprecated, too).
  8. #ifdef IGL_STATIC_LIBRARY
  9. # undef IGL_STATIC_LIBRARY
  10. # include <igl/slice.h>
  11. # define IGL_STATIC_LIBRARY
  12. #else
  13. # include <igl/slice.h>
  14. #endif
  15. TEST_CASE("slice: eigen-simple", "[igl]")
  16. {
  17. Eigen::MatrixXd X = Eigen::MatrixXd::Random(10,3);
  18. Eigen::VectorXi I(2); I<<1,0;
  19. {
  20. Eigen::MatrixXd Yigl;
  21. igl::slice(X,I,1,Yigl);
  22. Eigen::MatrixXd Yeigen = X(I,igl::placeholders::all);
  23. test_common::assert_eq(Yigl,Yeigen);
  24. }
  25. {
  26. Eigen::MatrixXd Yigl;
  27. igl::slice(X,I,2,Yigl);
  28. Eigen::MatrixXd Yeigen = X(igl::placeholders::all,I);
  29. test_common::assert_eq(Yigl,Yeigen);
  30. }
  31. }
  32. TEST_CASE("slice: eigen-random", "[igl]")
  33. {
  34. const int m = 100;
  35. const int n = 100;
  36. Eigen::MatrixXd X = Eigen::MatrixXd::Random(m,n);
  37. Eigen::VectorXi I;
  38. igl::randperm(m,I);
  39. Eigen::VectorXi J;
  40. igl::randperm(n,J);
  41. {
  42. Eigen::MatrixXd Yigl;
  43. igl::slice(X,I,J,Yigl);
  44. Eigen::MatrixXd Yeigen = X(I,J);
  45. test_common::assert_eq(Yigl,Yeigen);
  46. }
  47. {
  48. Eigen::MatrixXd Yigl;
  49. igl::slice(X,I,1,Yigl);
  50. Eigen::MatrixXd Yeigen = X(I,igl::placeholders::all);
  51. test_common::assert_eq(Yigl,Yeigen);
  52. }
  53. {
  54. Eigen::MatrixXd Yigl;
  55. igl::slice(X,J,2,Yigl);
  56. Eigen::MatrixXd Yeigen = X(igl::placeholders::all,J);
  57. test_common::assert_eq(Yigl,Yeigen);
  58. }
  59. }
  60. TEST_CASE("slice: dense_identity", "[igl]")
  61. {
  62. // https://en.wikipedia.org/wiki/Monkey_testing
  63. Eigen::MatrixXd A = Eigen::MatrixXd::Random(10,9);
  64. Eigen::VectorXi I = igl::LinSpaced<Eigen::VectorXi >(A.rows(),0,A.rows()-1);
  65. Eigen::VectorXi J = igl::LinSpaced<Eigen::VectorXi >(A.cols(),0,A.cols()-1);
  66. {
  67. Eigen::MatrixXd B;
  68. igl::slice(A,I,J,B);
  69. test_common::assert_eq(A,B);
  70. }
  71. {
  72. Eigen::MatrixXd B;
  73. igl::slice(A,I,1,B);
  74. test_common::assert_eq(A,B);
  75. }
  76. {
  77. Eigen::MatrixXd B;
  78. igl::slice(A,J,2,B);
  79. test_common::assert_eq(A,B);
  80. }
  81. }
  82. TEST_CASE("slice: sparse_identity", "[igl]")
  83. {
  84. Eigen::SparseMatrix<double> A = Eigen::MatrixXd::Random(10,9).sparseView();
  85. Eigen::VectorXi I = igl::LinSpaced<Eigen::VectorXi >(A.rows(),0,A.rows()-1);
  86. Eigen::VectorXi J = igl::LinSpaced<Eigen::VectorXi >(A.cols(),0,A.cols()-1);
  87. {
  88. Eigen::SparseMatrix<double> B;
  89. igl::slice(A,I,J,B);
  90. test_common::assert_eq(A,B);
  91. }
  92. {
  93. Eigen::SparseMatrix<double> B;
  94. igl::slice(A,I,1,B);
  95. test_common::assert_eq(A,B);
  96. }
  97. {
  98. Eigen::SparseMatrix<double> B;
  99. igl::slice(A,J,2,B);
  100. test_common::assert_eq(A,B);
  101. }
  102. }
  103. TEST_CASE("slice: density_reverse", "[igl]")
  104. {
  105. {
  106. Eigen::MatrixXd A = Eigen::MatrixXd::Random(10,9);
  107. Eigen::VectorXi I = igl::LinSpaced<Eigen::VectorXi >(A.rows(),A.rows()-1,0);
  108. Eigen::VectorXi J = igl::LinSpaced<Eigen::VectorXi >(A.cols(),0,A.cols()-1);
  109. Eigen::MatrixXd B;
  110. igl::slice(A,I,J,B);
  111. // reverse rows (i.e., reverse each column vector)
  112. Eigen::MatrixXd C = A.colwise().reverse().eval();
  113. test_common::assert_eq(B,C);
  114. }
  115. {
  116. Eigen::MatrixXd A = Eigen::MatrixXd::Random(10,9);
  117. Eigen::VectorXi I = igl::LinSpaced<Eigen::VectorXi >(A.rows(),0,A.rows()-1);
  118. Eigen::VectorXi J = igl::LinSpaced<Eigen::VectorXi >(A.cols(),A.cols()-1,0);
  119. Eigen::MatrixXd B;
  120. igl::slice(A,I,J,B);
  121. // reverse cols (i.e., reverse each row vector)
  122. Eigen::MatrixXd C = A.rowwise().reverse().eval();
  123. test_common::assert_eq(B,C);
  124. }
  125. }
  126. TEST_CASE("slice: random", "[igl]")
  127. {
  128. // Test whether unsorted indices are handled correctly by Randomly grow and
  129. // shrink a matrix by slicing out rows and columns: note that growing will
  130. // test whether repeated indices are correctly handled
  131. std::vector<std::pair<int,int> > sizes = {{30,27},{3,4}};
  132. for(const auto & size : sizes)
  133. {
  134. Eigen::MatrixXd A(10,9);
  135. for(int i = 0;i<A.rows();i++)
  136. {
  137. for(int j = 0;j<A.cols();j++)
  138. {
  139. A(i,j) = A.rows()*j + i;
  140. }
  141. }
  142. Eigen::VectorXi I =
  143. ((Eigen::VectorXd::Random(size.first,1).array()*0.5+0.5)*A.rows()
  144. ).cast<int>();
  145. Eigen::VectorXi J =
  146. ((Eigen::VectorXd::Random(size.second,1).array()*0.5+0.5)*A.cols()
  147. ).cast<int>();
  148. Eigen::MatrixXd B;
  149. igl::slice(A,I,J,B);
  150. Eigen::MatrixXd C(I.size(),J.size());
  151. for(int i = 0;i<I.size();i++)
  152. {
  153. for(int j = 0;j<J.size();j++)
  154. {
  155. C(i,j) = A.rows()*J(j) + I(i);
  156. }
  157. }
  158. test_common::assert_eq(B,C);
  159. }
  160. }