visibility_test.cc 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // Ceres Solver - A fast non-linear least squares minimizer
  2. // Copyright 2015 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: kushalav@google.com (Avanish Kushal)
  30. // sameeragarwal@google.com (Sameer Agarwal)
  31. #include "ceres/visibility.h"
  32. #include <memory>
  33. #include <set>
  34. #include <vector>
  35. #include "ceres/block_structure.h"
  36. #include "ceres/graph.h"
  37. #include "glog/logging.h"
  38. #include "gtest/gtest.h"
  39. namespace ceres::internal {
  40. class VisibilityTest : public ::testing::Test {};
  41. TEST(VisibilityTest, SimpleMatrix) {
  42. // A = [1 0 0 0 0 1
  43. // 1 0 0 1 0 0
  44. // 0 1 1 0 0 0
  45. // 0 1 0 0 1 0]
  46. int num_cols = 6;
  47. int num_eliminate_blocks = 2;
  48. CompressedRowBlockStructure bs;
  49. // Row 1
  50. {
  51. bs.rows.emplace_back();
  52. CompressedRow& row = bs.rows.back();
  53. row.block.size = 2;
  54. row.block.position = 0;
  55. row.cells.emplace_back(0, 0);
  56. row.cells.emplace_back(5, 0);
  57. }
  58. // Row 2
  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, 1);
  65. row.cells.emplace_back(3, 1);
  66. }
  67. // Row 3
  68. {
  69. bs.rows.emplace_back();
  70. CompressedRow& row = bs.rows.back();
  71. row.block.size = 2;
  72. row.block.position = 4;
  73. row.cells.emplace_back(1, 2);
  74. row.cells.emplace_back(2, 2);
  75. }
  76. // Row 4
  77. {
  78. bs.rows.emplace_back();
  79. CompressedRow& row = bs.rows.back();
  80. row.block.size = 2;
  81. row.block.position = 6;
  82. row.cells.emplace_back(1, 3);
  83. row.cells.emplace_back(4, 3);
  84. }
  85. bs.cols.resize(num_cols);
  86. std::vector<std::set<int>> visibility;
  87. ComputeVisibility(bs, num_eliminate_blocks, &visibility);
  88. ASSERT_EQ(visibility.size(), num_cols - num_eliminate_blocks);
  89. for (const auto& visible : visibility) {
  90. ASSERT_EQ(visible.size(), 1);
  91. }
  92. std::unique_ptr<WeightedGraph<int>> graph(
  93. CreateSchurComplementGraph(visibility));
  94. EXPECT_EQ(graph->vertices().size(), visibility.size());
  95. for (int i = 0; i < visibility.size(); ++i) {
  96. EXPECT_EQ(graph->VertexWeight(i), 1.0);
  97. }
  98. for (int i = 0; i < visibility.size(); ++i) {
  99. for (int j = i; j < visibility.size(); ++j) {
  100. double edge_weight = 0.0;
  101. if ((i == 1 && j == 3) || (i == 0 && j == 2) || (i == j)) {
  102. edge_weight = 1.0;
  103. }
  104. EXPECT_EQ(graph->EdgeWeight(i, j), edge_weight)
  105. << "Edge: " << i << " " << j << " weight: " << graph->EdgeWeight(i, j)
  106. << " expected weight: " << edge_weight;
  107. }
  108. }
  109. }
  110. TEST(VisibilityTest, NoEBlocks) {
  111. // A = [1 0 0 0 0 0
  112. // 1 0 0 0 0 0
  113. // 0 1 0 0 0 0
  114. // 0 1 0 0 0 0]
  115. int num_cols = 6;
  116. int num_eliminate_blocks = 2;
  117. CompressedRowBlockStructure bs;
  118. // Row 1
  119. {
  120. bs.rows.emplace_back();
  121. CompressedRow& row = bs.rows.back();
  122. row.block.size = 2;
  123. row.block.position = 0;
  124. row.cells.emplace_back(0, 0);
  125. }
  126. // Row 2
  127. {
  128. bs.rows.emplace_back();
  129. CompressedRow& row = bs.rows.back();
  130. row.block.size = 2;
  131. row.block.position = 2;
  132. row.cells.emplace_back(0, 1);
  133. }
  134. // Row 3
  135. {
  136. bs.rows.emplace_back();
  137. CompressedRow& row = bs.rows.back();
  138. row.block.size = 2;
  139. row.block.position = 4;
  140. row.cells.emplace_back(1, 2);
  141. }
  142. // Row 4
  143. {
  144. bs.rows.emplace_back();
  145. CompressedRow& row = bs.rows.back();
  146. row.block.size = 2;
  147. row.block.position = 6;
  148. row.cells.emplace_back(1, 3);
  149. }
  150. bs.cols.resize(num_cols);
  151. std::vector<std::set<int>> visibility;
  152. ComputeVisibility(bs, num_eliminate_blocks, &visibility);
  153. ASSERT_EQ(visibility.size(), num_cols - num_eliminate_blocks);
  154. for (const auto& visible : visibility) {
  155. ASSERT_EQ(visible.size(), 0);
  156. }
  157. std::unique_ptr<WeightedGraph<int>> graph(
  158. CreateSchurComplementGraph(visibility));
  159. EXPECT_EQ(graph->vertices().size(), visibility.size());
  160. for (int i = 0; i < visibility.size(); ++i) {
  161. EXPECT_EQ(graph->VertexWeight(i), 1.0);
  162. }
  163. for (int i = 0; i < visibility.size(); ++i) {
  164. for (int j = i; j < visibility.size(); ++j) {
  165. double edge_weight = 0.0;
  166. if (i == j) {
  167. edge_weight = 1.0;
  168. }
  169. EXPECT_EQ(graph->EdgeWeight(i, j), edge_weight)
  170. << "Edge: " << i << " " << j << " weight: " << graph->EdgeWeight(i, j)
  171. << " expected weight: " << edge_weight;
  172. }
  173. }
  174. }
  175. } // namespace ceres::internal