detect_structure_test.cc 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. // Ceres Solver - A fast non-linear least squares minimizer
  2. // Copyright 2023 Google Inc. All rights reserved.
  3. // http://ceres-solver.org/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are met:
  7. //
  8. // * Redistributions of source code must retain the above copyright notice,
  9. // this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above copyright notice,
  11. // this list of conditions and the following disclaimer in the documentation
  12. // and/or other materials provided with the distribution.
  13. // * Neither the name of Google Inc. nor the names of its contributors may be
  14. // used to endorse or promote products derived from this software without
  15. // specific prior written permission.
  16. //
  17. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  18. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  21. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  22. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  23. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  24. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  25. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  26. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  27. // POSSIBILITY OF SUCH DAMAGE.
  28. //
  29. // Author: sameeragarwal@google.com (Sameer Agarwal)
  30. #include "ceres/detect_structure.h"
  31. #include "Eigen/Core"
  32. #include "ceres/block_structure.h"
  33. #include "glog/logging.h"
  34. #include "gtest/gtest.h"
  35. namespace ceres {
  36. namespace internal {
  37. TEST(DetectStructure, EverythingStatic) {
  38. const int expected_row_block_size = 2;
  39. const int expected_e_block_size = 3;
  40. const int expected_f_block_size = 4;
  41. CompressedRowBlockStructure bs;
  42. bs.cols.emplace_back();
  43. bs.cols.back().size = 3;
  44. bs.cols.back().position = 0;
  45. bs.cols.emplace_back();
  46. bs.cols.back().size = 4;
  47. bs.cols.back().position = 3;
  48. bs.cols.emplace_back();
  49. bs.cols.back().size = 4;
  50. bs.cols.back().position = 7;
  51. {
  52. bs.rows.emplace_back();
  53. CompressedRow& row = bs.rows.back();
  54. row.block.size = 2;
  55. row.block.position = 0;
  56. row.cells.emplace_back(0, 0);
  57. row.cells.emplace_back(1, 0);
  58. }
  59. {
  60. bs.rows.emplace_back();
  61. CompressedRow& row = bs.rows.back();
  62. row.block.size = 2;
  63. row.block.position = 2;
  64. row.cells.emplace_back(0, 0);
  65. row.cells.emplace_back(2, 0);
  66. }
  67. int row_block_size = 0;
  68. int e_block_size = 0;
  69. int f_block_size = 0;
  70. const int num_eliminate_blocks = 1;
  71. DetectStructure(
  72. bs, num_eliminate_blocks, &row_block_size, &e_block_size, &f_block_size);
  73. EXPECT_EQ(row_block_size, expected_row_block_size);
  74. EXPECT_EQ(e_block_size, expected_e_block_size);
  75. EXPECT_EQ(f_block_size, expected_f_block_size);
  76. }
  77. TEST(DetectStructure, DynamicRow) {
  78. const int expected_row_block_size = Eigen::Dynamic;
  79. const int expected_e_block_size = 3;
  80. const int expected_f_block_size = 4;
  81. CompressedRowBlockStructure bs;
  82. bs.cols.emplace_back();
  83. bs.cols.back().size = 3;
  84. bs.cols.back().position = 0;
  85. bs.cols.emplace_back();
  86. bs.cols.back().size = 4;
  87. bs.cols.back().position = 3;
  88. bs.cols.emplace_back();
  89. bs.cols.back().size = 4;
  90. bs.cols.back().position = 7;
  91. {
  92. bs.rows.emplace_back();
  93. CompressedRow& row = bs.rows.back();
  94. row.block.size = 2;
  95. row.block.position = 0;
  96. row.cells.emplace_back(0, 0);
  97. row.cells.emplace_back(1, 0);
  98. }
  99. {
  100. bs.rows.emplace_back();
  101. CompressedRow& row = bs.rows.back();
  102. row.block.size = 1;
  103. row.block.position = 2;
  104. row.cells.emplace_back(0, 0);
  105. row.cells.emplace_back(2, 0);
  106. }
  107. int row_block_size = 0;
  108. int e_block_size = 0;
  109. int f_block_size = 0;
  110. const int num_eliminate_blocks = 1;
  111. DetectStructure(
  112. bs, num_eliminate_blocks, &row_block_size, &e_block_size, &f_block_size);
  113. EXPECT_EQ(row_block_size, expected_row_block_size);
  114. EXPECT_EQ(e_block_size, expected_e_block_size);
  115. EXPECT_EQ(f_block_size, expected_f_block_size);
  116. }
  117. TEST(DetectStructure, DynamicFBlockDifferentRows) {
  118. const int expected_row_block_size = 2;
  119. const int expected_e_block_size = 3;
  120. const int expected_f_block_size = Eigen::Dynamic;
  121. CompressedRowBlockStructure bs;
  122. bs.cols.emplace_back();
  123. bs.cols.back().size = 3;
  124. bs.cols.back().position = 0;
  125. bs.cols.emplace_back();
  126. bs.cols.back().size = 4;
  127. bs.cols.back().position = 3;
  128. bs.cols.emplace_back();
  129. bs.cols.back().size = 3;
  130. bs.cols.back().position = 7;
  131. {
  132. bs.rows.emplace_back();
  133. CompressedRow& row = bs.rows.back();
  134. row.block.size = 2;
  135. row.block.position = 0;
  136. row.cells.emplace_back(0, 0);
  137. row.cells.emplace_back(1, 0);
  138. }
  139. {
  140. bs.rows.emplace_back();
  141. CompressedRow& row = bs.rows.back();
  142. row.block.size = 2;
  143. row.block.position = 2;
  144. row.cells.emplace_back(0, 0);
  145. row.cells.emplace_back(2, 0);
  146. }
  147. int row_block_size = 0;
  148. int e_block_size = 0;
  149. int f_block_size = 0;
  150. const int num_eliminate_blocks = 1;
  151. DetectStructure(
  152. bs, num_eliminate_blocks, &row_block_size, &e_block_size, &f_block_size);
  153. EXPECT_EQ(row_block_size, expected_row_block_size);
  154. EXPECT_EQ(e_block_size, expected_e_block_size);
  155. EXPECT_EQ(f_block_size, expected_f_block_size);
  156. }
  157. TEST(DetectStructure, DynamicEBlock) {
  158. const int expected_row_block_size = 2;
  159. const int expected_e_block_size = Eigen::Dynamic;
  160. const int expected_f_block_size = 3;
  161. CompressedRowBlockStructure bs;
  162. bs.cols.emplace_back();
  163. bs.cols.back().size = 3;
  164. bs.cols.back().position = 0;
  165. bs.cols.emplace_back();
  166. bs.cols.back().size = 4;
  167. bs.cols.back().position = 3;
  168. bs.cols.emplace_back();
  169. bs.cols.back().size = 3;
  170. bs.cols.back().position = 7;
  171. {
  172. bs.rows.emplace_back();
  173. CompressedRow& row = bs.rows.back();
  174. row.block.size = 2;
  175. row.block.position = 0;
  176. row.cells.emplace_back(0, 0);
  177. row.cells.emplace_back(2, 0);
  178. }
  179. {
  180. bs.rows.emplace_back();
  181. CompressedRow& row = bs.rows.back();
  182. row.block.size = 2;
  183. row.block.position = 2;
  184. row.cells.emplace_back(1, 0);
  185. row.cells.emplace_back(2, 0);
  186. }
  187. int row_block_size = 0;
  188. int e_block_size = 0;
  189. int f_block_size = 0;
  190. const int num_eliminate_blocks = 2;
  191. DetectStructure(
  192. bs, num_eliminate_blocks, &row_block_size, &e_block_size, &f_block_size);
  193. EXPECT_EQ(row_block_size, expected_row_block_size);
  194. EXPECT_EQ(e_block_size, expected_e_block_size);
  195. EXPECT_EQ(f_block_size, expected_f_block_size);
  196. }
  197. TEST(DetectStructure, DynamicFBlockSameRow) {
  198. const int expected_row_block_size = 2;
  199. const int expected_e_block_size = 3;
  200. const int expected_f_block_size = Eigen::Dynamic;
  201. CompressedRowBlockStructure bs;
  202. bs.cols.emplace_back();
  203. bs.cols.back().size = 3;
  204. bs.cols.back().position = 0;
  205. bs.cols.emplace_back();
  206. bs.cols.back().size = 4;
  207. bs.cols.back().position = 3;
  208. bs.cols.emplace_back();
  209. bs.cols.back().size = 3;
  210. bs.cols.back().position = 7;
  211. {
  212. bs.rows.emplace_back();
  213. CompressedRow& row = bs.rows.back();
  214. row.block.size = 2;
  215. row.block.position = 0;
  216. row.cells.emplace_back(0, 0);
  217. row.cells.emplace_back(1, 0);
  218. row.cells.emplace_back(2, 0);
  219. }
  220. int row_block_size = 0;
  221. int e_block_size = 0;
  222. int f_block_size = 0;
  223. const int num_eliminate_blocks = 1;
  224. DetectStructure(
  225. bs, num_eliminate_blocks, &row_block_size, &e_block_size, &f_block_size);
  226. EXPECT_EQ(row_block_size, expected_row_block_size);
  227. EXPECT_EQ(e_block_size, expected_e_block_size);
  228. EXPECT_EQ(f_block_size, expected_f_block_size);
  229. }
  230. } // namespace internal
  231. } // namespace ceres