• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Ceres Solver - A fast non-linear least squares minimizer
2 // Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
3 // http://code.google.com/p/ceres-solver/
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 
32 #include "ceres/visibility.h"
33 
34 #include <set>
35 #include <vector>
36 #include "ceres/block_structure.h"
37 #include "ceres/graph.h"
38 #include "ceres/internal/scoped_ptr.h"
39 #include "glog/logging.h"
40 #include "gtest/gtest.h"
41 
42 namespace ceres {
43 namespace internal {
44 
45 class VisibilityTest : public ::testing::Test {
46 };
47 
TEST(VisibilityTest,SimpleMatrix)48 TEST(VisibilityTest, SimpleMatrix) {
49   //   A = [1 0 0 0 0 1
50   //        1 0 0 1 0 0
51   //        0 1 1 0 0 0
52   //        0 1 0 0 1 0]
53 
54   int num_cols = 6;
55   int num_eliminate_blocks = 2;
56   CompressedRowBlockStructure bs;
57 
58   // Row 1
59   {
60     bs.rows.push_back(CompressedRow());
61     CompressedRow& row = bs.rows.back();
62     row.block.size = 2;
63     row.block.position = 0;
64     row.cells.push_back(Cell(0, 0));
65     row.cells.push_back(Cell(5, 0));
66   }
67 
68   // Row 2
69   {
70     bs.rows.push_back(CompressedRow());
71     CompressedRow& row = bs.rows.back();
72     row.block.size = 2;
73     row.block.position = 2;
74     row.cells.push_back(Cell(0, 1));
75     row.cells.push_back(Cell(3, 1));
76   }
77 
78   // Row 3
79   {
80     bs.rows.push_back(CompressedRow());
81     CompressedRow& row = bs.rows.back();
82     row.block.size = 2;
83     row.block.position = 4;
84     row.cells.push_back(Cell(1, 2));
85     row.cells.push_back(Cell(2, 2));
86   }
87 
88   // Row 4
89   {
90     bs.rows.push_back(CompressedRow());
91     CompressedRow& row = bs.rows.back();
92     row.block.size = 2;
93     row.block.position = 6;
94     row.cells.push_back(Cell(1, 3));
95     row.cells.push_back(Cell(4, 3));
96   }
97   bs.cols.resize(num_cols);
98 
99   vector< set<int> > visibility;
100   ComputeVisibility(bs, num_eliminate_blocks, &visibility);
101   ASSERT_EQ(visibility.size(), num_cols - num_eliminate_blocks);
102   for (int i = 0; i < visibility.size(); ++i) {
103     ASSERT_EQ(visibility[i].size(), 1);
104   }
105 
106   scoped_ptr<Graph<int> > graph(CreateSchurComplementGraph(visibility));
107   EXPECT_EQ(graph->vertices().size(), visibility.size());
108   for (int i = 0; i < visibility.size(); ++i) {
109     EXPECT_EQ(graph->VertexWeight(i), 1.0);
110   }
111 
112   for (int i = 0; i < visibility.size(); ++i) {
113     for (int j = i; j < visibility.size(); ++j) {
114       double edge_weight = 0.0;
115       if ((i == 1 && j == 3) || (i == 0 && j == 2) || (i == j)) {
116         edge_weight = 1.0;
117       }
118 
119       EXPECT_EQ(graph->EdgeWeight(i, j), edge_weight)
120           << "Edge: " << i << " " << j
121           << " weight: " << graph->EdgeWeight(i, j)
122           << " expected weight: " << edge_weight;
123     }
124   }
125 }
126 
127 
TEST(VisibilityTest,NoEBlocks)128 TEST(VisibilityTest, NoEBlocks) {
129   //   A = [1 0 0 0 0 0
130   //        1 0 0 0 0 0
131   //        0 1 0 0 0 0
132   //        0 1 0 0 0 0]
133 
134   int num_cols = 6;
135   int num_eliminate_blocks = 2;
136   CompressedRowBlockStructure bs;
137 
138   // Row 1
139   {
140     bs.rows.push_back(CompressedRow());
141     CompressedRow& row = bs.rows.back();
142     row.block.size = 2;
143     row.block.position = 0;
144     row.cells.push_back(Cell(0, 0));
145   }
146 
147   // Row 2
148   {
149     bs.rows.push_back(CompressedRow());
150     CompressedRow& row = bs.rows.back();
151     row.block.size = 2;
152     row.block.position = 2;
153     row.cells.push_back(Cell(0, 1));
154   }
155 
156   // Row 3
157   {
158     bs.rows.push_back(CompressedRow());
159     CompressedRow& row = bs.rows.back();
160     row.block.size = 2;
161     row.block.position = 4;
162     row.cells.push_back(Cell(1, 2));
163   }
164 
165   // Row 4
166   {
167     bs.rows.push_back(CompressedRow());
168     CompressedRow& row = bs.rows.back();
169     row.block.size = 2;
170     row.block.position = 6;
171     row.cells.push_back(Cell(1, 3));
172   }
173   bs.cols.resize(num_cols);
174 
175   vector<set<int> > visibility;
176   ComputeVisibility(bs, num_eliminate_blocks, &visibility);
177   ASSERT_EQ(visibility.size(), num_cols - num_eliminate_blocks);
178   for (int i = 0; i < visibility.size(); ++i) {
179     ASSERT_EQ(visibility[i].size(), 0);
180   }
181 
182   scoped_ptr<Graph<int> > graph(CreateSchurComplementGraph(visibility));
183   EXPECT_EQ(graph->vertices().size(), visibility.size());
184   for (int i = 0; i < visibility.size(); ++i) {
185     EXPECT_EQ(graph->VertexWeight(i), 1.0);
186   }
187 
188   for (int i = 0; i < visibility.size(); ++i) {
189     for (int j = i; j < visibility.size(); ++j) {
190       double edge_weight = 0.0;
191       if (i == j) {
192         edge_weight = 1.0;
193       }
194       EXPECT_EQ(graph->EdgeWeight(i, j), edge_weight)
195           << "Edge: " << i << " " << j
196           << " weight: " << graph->EdgeWeight(i, j)
197           << " expected weight: " << edge_weight;
198     }
199   }
200 }
201 
202 }  // namespace internal
203 }  // namespace ceres
204