Integrate the SchurEliminatorForOneFBlock for the case <2,3,6>
Also run clang-format on schur_complement_solver.cc.
A more elaborate integration is not done, because it will cause
binary bloat.
Change-Id: Idf4e9e1794f7401a39f05fb145ec06459209a1e1
diff --git a/internal/ceres/schur_complement_solver.cc b/internal/ceres/schur_complement_solver.cc
index a80bd23..27a44a7 100644
--- a/internal/ceres/schur_complement_solver.cc
+++ b/internal/ceres/schur_complement_solver.cc
@@ -67,8 +67,7 @@
public:
explicit BlockRandomAccessSparseMatrixAdapter(
const BlockRandomAccessSparseMatrix& m)
- : m_(m) {
- }
+ : m_(m) {}
virtual ~BlockRandomAccessSparseMatrixAdapter() {}
@@ -93,8 +92,7 @@
public:
explicit BlockRandomAccessDiagonalMatrixAdapter(
const BlockRandomAccessDiagonalMatrix& m)
- : m_(m) {
- }
+ : m_(m) {}
virtual ~BlockRandomAccessDiagonalMatrixAdapter() {}
@@ -115,7 +113,7 @@
const BlockRandomAccessDiagonalMatrix& m_;
};
-} // namespace
+} // namespace
LinearSolver::Summary SchurComplementSolver::SolveImpl(
BlockSparseMatrix* A,
@@ -124,19 +122,36 @@
double* x) {
EventLogger event_logger("SchurComplementSolver::Solve");
+ const CompressedRowBlockStructure* bs = A->block_structure();
if (eliminator_.get() == NULL) {
- InitStorage(A->block_structure());
- DetectStructure(*A->block_structure(),
- options_.elimination_groups[0],
+ const int num_eliminate_blocks = options_.elimination_groups[0];
+ const int num_f_blocks = bs->cols.size() - num_eliminate_blocks;
+
+ InitStorage(bs);
+ DetectStructure(*bs,
+ num_eliminate_blocks,
&options_.row_block_size,
&options_.e_block_size,
&options_.f_block_size);
- eliminator_.reset(SchurEliminatorBase::Create(options_));
- CHECK(eliminator_ != nullptr);
+
+ // For the special case of the static structure <2,3,6> with
+ // exactly one f block use the SchurEliminatorForOneFBlock.
+ //
+ // TODO(sameeragarwal): A more scalable template specialization
+ // mechanism that does not cause binary bloat.
+ if (options_.row_block_size == 2 &&
+ options_.e_block_size == 3 &&
+ options_.f_block_size == 6 &&
+ num_f_blocks == 1) {
+ eliminator_.reset(new SchurEliminatorForOneFBlock<2, 3, 6>);
+ } else {
+ eliminator_.reset(SchurEliminatorBase::Create(options_));
+ }
+
+ CHECK(eliminator_);
const bool kFullRankETE = true;
- eliminator_->Init(
- options_.elimination_groups[0], kFullRankETE, A->block_structure());
- };
+ eliminator_->Init(num_eliminate_blocks, kFullRankETE, bs);
+ }
std::fill(x, x + A->num_cols(), 0.0);
event_logger.AddEvent("Setup");
@@ -165,9 +180,7 @@
const int num_col_blocks = bs->cols.size();
vector<int> blocks(num_col_blocks - num_eliminate_blocks, 0);
- for (int i = num_eliminate_blocks, j = 0;
- i < num_col_blocks;
- ++i, ++j) {
+ for (int i = num_eliminate_blocks, j = 0; i < num_col_blocks; ++i, ++j) {
blocks[j] = bs->cols[i].size;
}
@@ -178,10 +191,8 @@
// Solve the system Sx = r, assuming that the matrix S is stored in a
// BlockRandomAccessDenseMatrix. The linear system is solved using
// Eigen's Cholesky factorization.
-LinearSolver::Summary
-DenseSchurComplementSolver::SolveReducedLinearSystem(
- const LinearSolver::PerSolveOptions& per_solve_options,
- double* solution) {
+LinearSolver::Summary DenseSchurComplementSolver::SolveReducedLinearSystem(
+ const LinearSolver::PerSolveOptions& per_solve_options, double* solution) {
LinearSolver::Summary summary;
summary.num_iterations = 0;
summary.termination_type = LINEAR_SOLVER_SUCCESS;
@@ -202,8 +213,8 @@
if (options().dense_linear_algebra_library_type == EIGEN) {
Eigen::LLT<Matrix, Eigen::Upper> llt =
ConstMatrixRef(m->values(), num_rows, num_rows)
- .selfadjointView<Eigen::Upper>()
- .llt();
+ .selfadjointView<Eigen::Upper>()
+ .llt();
if (llt.info() != Eigen::Success) {
summary.termination_type = LINEAR_SOLVER_FAILURE;
summary.message =
@@ -214,11 +225,8 @@
VectorRef(solution, num_rows) = llt.solve(ConstVectorRef(rhs(), num_rows));
} else {
VectorRef(solution, num_rows) = ConstVectorRef(rhs(), num_rows);
- summary.termination_type =
- LAPACK::SolveInPlaceUsingCholesky(num_rows,
- m->values(),
- solution,
- &summary.message);
+ summary.termination_type = LAPACK::SolveInPlaceUsingCholesky(
+ num_rows, m->values(), solution, &summary.message);
}
return summary;
@@ -232,8 +240,7 @@
}
}
-SparseSchurComplementSolver::~SparseSchurComplementSolver() {
-}
+SparseSchurComplementSolver::~SparseSchurComplementSolver() {}
// Determine the non-zero blocks in the Schur Complement matrix, and
// initialize a BlockRandomAccessSparseMatrix object.
@@ -347,8 +354,7 @@
LinearSolver::Summary
SparseSchurComplementSolver::SolveReducedLinearSystemUsingConjugateGradients(
- const LinearSolver::PerSolveOptions& per_solve_options,
- double* solution) {
+ const LinearSolver::PerSolveOptions& per_solve_options, double* solution) {
CHECK(options().use_explicit_schur_complement);
const int num_rows = lhs()->num_rows();
// The case where there are no f blocks, and the system is block
@@ -368,13 +374,12 @@
preconditioner_.reset(new BlockRandomAccessDiagonalMatrix(blocks_));
}
- BlockRandomAccessSparseMatrix* sc =
- down_cast<BlockRandomAccessSparseMatrix*>(
- const_cast<BlockRandomAccessMatrix*>(lhs()));
+ BlockRandomAccessSparseMatrix* sc = down_cast<BlockRandomAccessSparseMatrix*>(
+ const_cast<BlockRandomAccessMatrix*>(lhs()));
// Extract block diagonal from the Schur complement to construct the
// schur_jacobi preconditioner.
- for (int i = 0; i < blocks_.size(); ++i) {
+ for (int i = 0; i < blocks_.size(); ++i) {
const int block_size = blocks_[i];
int sc_r, sc_c, sc_row_stride, sc_col_stride;
@@ -401,7 +406,6 @@
std::unique_ptr<LinearOperator> preconditioner_adapter(
new BlockRandomAccessDiagonalMatrixAdapter(*preconditioner_));
-
LinearSolver::Options cg_options;
cg_options.min_num_iterations = options().min_num_iterations;
cg_options.max_num_iterations = options().max_num_iterations;
@@ -412,10 +416,8 @@
cg_per_solve_options.q_tolerance = per_solve_options.q_tolerance;
cg_per_solve_options.preconditioner = preconditioner_adapter.get();
- return cg_solver.Solve(lhs_adapter.get(),
- rhs(),
- cg_per_solve_options,
- solution);
+ return cg_solver.Solve(
+ lhs_adapter.get(), rhs(), cg_per_solve_options, solution);
}
} // namespace internal