Refactor compressed_col_sparse_matrix_utils_test
Remove the dependence on SuiteSparse.
Update the CMakeLists.txt file
https://github.com/ceres-solver/ceres-solver/issues/276
Change-Id: Ifd480d465fb19ad6cd195e1025e0ad2dc4e4a2cc
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index b4d2e6f..8a56ca0 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -289,9 +289,9 @@
ceres_test(block_random_access_diagonal_matrix)
ceres_test(block_random_access_sparse_matrix)
ceres_test(block_sparse_matrix)
- ceres_test(bundle_adjustment)
ceres_test(c_api)
ceres_test(canonical_views_clustering)
+ ceres_test(compressed_col_sparse_matrix_utils)
ceres_test(compressed_row_sparse_matrix)
ceres_test(conditioned_cost_function)
ceres_test(conjugate_gradients_solver)
@@ -299,9 +299,10 @@
ceres_test(cost_function_to_functor)
ceres_test(covariance)
ceres_test(cubic_interpolation)
- ceres_test(detect_structure)
ceres_test(dense_linear_solver)
ceres_test(dense_sparse_matrix)
+ ceres_test(detect_structure)
+ ceres_test(dogleg_strategy)
ceres_test(dynamic_autodiff_cost_function)
ceres_test(dynamic_compressed_row_sparse_matrix)
ceres_test(dynamic_numeric_diff_cost_function)
@@ -314,13 +315,12 @@
ceres_test(graph)
ceres_test(graph_algorithms)
ceres_test(householder_vector)
- ceres_test(is_close)
- ceres_test(invert_psd_matrix)
ceres_test(implicit_schur_complement)
+ ceres_test(invert_psd_matrix)
+ ceres_test(is_close)
ceres_test(iterative_schur_complement_solver)
ceres_test(jet)
ceres_test(levenberg_marquardt_strategy)
- ceres_test(dogleg_strategy)
ceres_test(line_search_minimizer)
ceres_test(line_search_preprocessor)
ceres_test(local_parameterization)
@@ -346,15 +346,7 @@
ceres_test(solver)
ceres_test(sparse_cholesky)
ceres_test(sparse_normal_cholesky_solver)
-
- # TODO(sameeragarwal): This test should ultimately be made
- # independent of SuiteSparse.
- if (SUITESPARSE AND SUITESPARSE_FOUND)
- ceres_test(compressed_col_sparse_matrix_utils)
- target_link_libraries(compressed_col_sparse_matrix_utils_test
- ${SUITESPARSE_LIBRARIES})
- endif (SUITESPARSE AND SUITESPARSE_FOUND)
-
+ ceres_test(system)
ceres_test(triplet_sparse_matrix)
ceres_test(trust_region_minimizer)
ceres_test(trust_region_preprocessor)
@@ -362,5 +354,6 @@
ceres_test(visibility_based_preconditioner)
# Put the large end to end test last.
- ceres_test(system)
+ ceres_test(bundle_adjustment)
+
endif (BUILD_TESTING AND GFLAGS)
diff --git a/internal/ceres/compressed_col_sparse_matrix_utils_test.cc b/internal/ceres/compressed_col_sparse_matrix_utils_test.cc
index e19e6ba..47a98c2 100644
--- a/internal/ceres/compressed_col_sparse_matrix_utils_test.cc
+++ b/internal/ceres/compressed_col_sparse_matrix_utils_test.cc
@@ -28,13 +28,15 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
+
#include <algorithm>
+#include <numeric>
#include "ceres/compressed_col_sparse_matrix_utils.h"
#include "ceres/internal/port.h"
-#include "ceres/suitesparse.h"
#include "ceres/triplet_sparse_matrix.h"
#include "glog/logging.h"
#include "gtest/gtest.h"
+#include "Eigen/SparseCore"
namespace ceres {
namespace internal {
@@ -85,31 +87,18 @@
}
}
-// Helper function to fill the sparsity pattern of a TripletSparseMatrix.
-int FillBlock(const vector<int>& row_blocks,
- const vector<int>& col_blocks,
- const int row_block_id,
- const int col_block_id,
- int* rows,
- int* cols) {
- int row_pos = 0;
- for (int i = 0; i < row_block_id; ++i) {
- row_pos += row_blocks[i];
- }
-
- int col_pos = 0;
- for (int i = 0; i < col_block_id; ++i) {
- col_pos += col_blocks[i];
- }
-
- int offset = 0;
+void FillBlock(const vector<int>& row_blocks,
+ const vector<int>& col_blocks,
+ const int row_block_id,
+ const int col_block_id,
+ vector<Eigen::Triplet<double> >* triplets) {
+ const int row_offset = std::accumulate(&row_blocks[0], &row_blocks[row_block_id], 0);
+ const int col_offset = std::accumulate(&col_blocks[0], &col_blocks[col_block_id], 0);
for (int r = 0; r < row_blocks[row_block_id]; ++r) {
- for (int c = 0; c < col_blocks[col_block_id]; ++c, ++offset) {
- rows[offset] = row_pos + r;
- cols[offset] = col_pos + c;
+ for (int c = 0; c < col_blocks[col_block_id]; ++c) {
+ triplets->push_back(Eigen::Triplet<double>(row_offset + r, col_offset + c, 1.0));
}
}
- return offset;
}
TEST(_, ScalarMatrixToBlockMatrix) {
@@ -121,6 +110,7 @@
// [2] x x
// num_nonzeros = 1 + 3 + 4 + 4 + 1 + 2 = 15
+
vector<int> col_blocks;
col_blocks.push_back(1);
col_blocks.push_back(2);
@@ -132,67 +122,46 @@
row_blocks.push_back(2);
row_blocks.push_back(2);
- TripletSparseMatrix tsm(5, 8, 18);
- int* rows = tsm.mutable_rows();
- int* cols = tsm.mutable_cols();
- std::fill(tsm.mutable_values(), tsm.mutable_values() + 18, 1.0);
- int offset = 0;
+ const int num_rows = std::accumulate(row_blocks.begin(), row_blocks.end(), 0.0);
+ const int num_cols = std::accumulate(col_blocks.begin(), col_blocks.end(), 0.0);
-#define CERES_TEST_FILL_BLOCK(row_block_id, col_block_id) \
- offset += FillBlock(row_blocks, col_blocks, \
- row_block_id, col_block_id, \
- rows + offset, cols + offset);
+ vector<Eigen::Triplet<double> > triplets;
+ FillBlock(row_blocks, col_blocks, 0, 0, &triplets);
+ FillBlock(row_blocks, col_blocks, 2, 0, &triplets);
+ FillBlock(row_blocks, col_blocks, 1, 1, &triplets);
+ FillBlock(row_blocks, col_blocks, 2, 1, &triplets);
+ FillBlock(row_blocks, col_blocks, 0, 2, &triplets);
+ FillBlock(row_blocks, col_blocks, 1, 3, &triplets);
+ Eigen::SparseMatrix<double> sparse_matrix(num_rows, num_cols);
+ sparse_matrix.setFromTriplets(triplets.begin(), triplets.end());
- CERES_TEST_FILL_BLOCK(0, 0);
- CERES_TEST_FILL_BLOCK(2, 0);
- CERES_TEST_FILL_BLOCK(1, 1);
- CERES_TEST_FILL_BLOCK(2, 1);
- CERES_TEST_FILL_BLOCK(0, 2);
- CERES_TEST_FILL_BLOCK(1, 3);
-#undef CERES_TEST_FILL_BLOCK
+ vector<int> expected_compressed_block_rows;
+ expected_compressed_block_rows.push_back(0);
+ expected_compressed_block_rows.push_back(2);
+ expected_compressed_block_rows.push_back(1);
+ expected_compressed_block_rows.push_back(2);
+ expected_compressed_block_rows.push_back(0);
+ expected_compressed_block_rows.push_back(1);
- tsm.set_num_nonzeros(offset);
+ vector<int> expected_compressed_block_cols;
+ expected_compressed_block_cols.push_back(0);
+ expected_compressed_block_cols.push_back(2);
+ expected_compressed_block_cols.push_back(4);
+ expected_compressed_block_cols.push_back(5);
+ expected_compressed_block_cols.push_back(6);
- SuiteSparse ss;
- scoped_ptr<cholmod_sparse> ccsm(ss.CreateSparseMatrix(&tsm));
-
- vector<int> expected_block_rows;
- expected_block_rows.push_back(0);
- expected_block_rows.push_back(2);
- expected_block_rows.push_back(1);
- expected_block_rows.push_back(2);
- expected_block_rows.push_back(0);
- expected_block_rows.push_back(1);
-
- vector<int> expected_block_cols;
- expected_block_cols.push_back(0);
- expected_block_cols.push_back(2);
- expected_block_cols.push_back(4);
- expected_block_cols.push_back(5);
- expected_block_cols.push_back(6);
-
- vector<int> block_rows;
- vector<int> block_cols;
+ vector<int> compressed_block_rows;
+ vector<int> compressed_block_cols;
CompressedColumnScalarMatrixToBlockMatrix(
- reinterpret_cast<const int*>(ccsm->i),
- reinterpret_cast<const int*>(ccsm->p),
+ sparse_matrix.innerIndexPtr(),
+ sparse_matrix.outerIndexPtr(),
row_blocks,
col_blocks,
- &block_rows,
- &block_cols);
+ &compressed_block_rows,
+ &compressed_block_cols);
- EXPECT_EQ(block_cols.size(), expected_block_cols.size());
- EXPECT_EQ(block_rows.size(), expected_block_rows.size());
-
- for (int i = 0; i < expected_block_cols.size(); ++i) {
- EXPECT_EQ(block_cols[i], expected_block_cols[i]);
- }
-
- for (int i = 0; i < expected_block_rows.size(); ++i) {
- EXPECT_EQ(block_rows[i], expected_block_rows[i]);
- }
-
- ss.Free(ccsm.release());
+ EXPECT_EQ(compressed_block_rows, expected_compressed_block_rows);
+ EXPECT_EQ(compressed_block_cols, expected_compressed_block_cols);
}
class SolveUpperTriangularTest : public ::testing::Test {
@@ -266,8 +235,8 @@
double solution[4];
double expected[] = { 6.8420e+00, 1.0057e+00, -1.4907e-16, -1.9335e+00,
1.0057e+00, 2.2275e+00, -1.9493e+00, -6.5693e-01,
- -1.4907e-16, -1.9493e+00, 1.1111e+01, 9.7381e-17,
- -1.9335e+00, -6.5693e-01, 9.7381e-17, 1.2631e+00 };
+ -1.4907e-16, -1.9493e+00, 1.1111e+01, 9.7381e-17,
+ -1.9335e+00, -6.5693e-01, 9.7381e-17, 1.2631e+00 };
for (int i = 0; i < 4; ++i) {
SolveRTRWithSparseRHS<int>(cols.size() - 1,