Generalization of the inner iterations algorithm.

Add automatic recursive independent set decomposition.
Clean up the naming and the API for inner iterations.

Change-Id: I3d7d6babb9756842d7367e14b7279d2df98fb724
This commit is contained in:
Sameer Agarwal
2012-10-02 00:48:57 -07:00
parent 2c94eed50f
commit ba8d967f8c
19 changed files with 538 additions and 386 deletions
+27 -2
View File
@@ -34,7 +34,6 @@
#include <map>
#include <set>
#include "ceres/collections_port.h"
#include "glog/logging.h"
namespace ceres {
@@ -80,6 +79,11 @@ class OrderedGroups {
return true;
}
void Clear() {
group_to_elements_.clear();
element_to_group_.clear();
}
// Remove the element, no matter what group it is in. If the element
// is not a member of any group, calling this method will result in
// a crash.
@@ -102,6 +106,27 @@ class OrderedGroups {
return true;
}
// Reverse the order of the groups in place.
void Reverse() {
typename map<int, set<T> >::reverse_iterator it =
group_to_elements_.rbegin();
map<int, set<T> > new_group_to_elements;
new_group_to_elements[it->first] = it->second;
int new_group_id = it->first + 1;
for (++it; it != group_to_elements_.rend(); ++it) {
for (typename set<T>::const_iterator element_it = it->second.begin();
element_it != it->second.end();
++element_it) {
element_to_group_[*element_it] = new_group_id;
}
new_group_to_elements[new_group_id] = it->second;
new_group_id++;
}
group_to_elements_.swap(new_group_to_elements);
}
// Return the group id for the element. If the element is not a
// member of any group, return -1.
int GroupId(const T element) const {
@@ -134,7 +159,7 @@ class OrderedGroups {
return group_to_elements_.size();
}
const map<int, set<T> > group_to_elements() const {
const map<int, set<T> >& group_to_elements() const {
return group_to_elements_;
}
+33 -24
View File
@@ -98,6 +98,7 @@ class Solver {
#endif
ordering = NULL;
use_inner_iterations = false;
inner_iteration_ordering = NULL;
linear_solver_min_num_iterations = 1;
linear_solver_max_num_iterations = 500;
eta = 1e-1;
@@ -296,8 +297,25 @@ class Solver {
// the parameter blocks into two groups, one for the points and one
// for the cameras, where the group containing the points has an id
// smaller than the group containing cameras.
//
// Once assigned, Solver::Options owns this pointer and will
// deallocate the memory when destroyed.
ParameterBlockOrdering* ordering;
// By virtue of the modeling layer in Ceres being block oriented,
// all the matrices used by Ceres are also block oriented. When
// doing sparse direct factorization of these matrices (for
// SPARSE_NORMAL_CHOLESKY, SPARSE_SCHUR and ITERATIVE in
// conjunction with CLUSTER_TRIDIAGONAL AND CLUSTER_JACOBI
// preconditioners), the fill-reducing ordering algorithms can
// either be run on the block or the scalar form of these matrices.
// Running it on the block form exposes more of the super-nodal
// structure of the matrix to the factorization routines. Setting
// this parameter to true runs the ordering algorithms in block
// form. Currently this option only makes sense with
// sparse_linear_algebra_library = SUITE_SPARSE.
bool use_block_amd;
// Some non-linear least squares problems have additional
// structure in the way the parameter blocks interact that it is
// beneficial to modify the way the trust region step is computed.
@@ -345,38 +363,29 @@ class Solver {
// optimization problems will do. The only constraint on a_1 and
// a_2 is that they do not co-occur in any residual block.
//
// This idea can be further generalized, by not just optimizing
// (a_1, a_2), but decomposing the graph corresponding to the
// Hessian matrix's sparsity structure in a collection of
// non-overlapping independent sets and optimizing each of them.
//
// Setting "use_inner_iterations" to true enables the use of this
// non-linear generalization of Ruhe & Wedin's Algorithm II. This
// version of Ceres has a higher iteration complexity, but also
// displays better convergence behaviour per iteration.
// displays better convergence behaviour per iteration. Setting
// Solver::Options::num_threads to the maximum number possible is
// highly recommended.
bool use_inner_iterations;
// If inner_iterations is true, then the user has two choices.
//
// 1. Provide a list of parameter blocks, which should be subject
// to inner iterations. The only requirement on the set of
// parameter blocks is that they form an independent set in the
// Hessian matrix, much like the first elimination group in
// Solver::Options::ordering.
// 1. Let the solver heuristically decide which parameter blocks
// to optimize in each inner iteration. To do this leave
// Solver::Options::inner_iteration_ordering untouched.
//
// 2. The second is to leave it empty, in which case, Ceres will
// use a heuristic to automatically choose a set of parameter
// blocks.
vector<double*> parameter_blocks_for_inner_iterations;
// By virtue of the modeling layer in Ceres being block oriented,
// all the matrices used by Ceres are also block oriented. When
// doing sparse direct factorization of these matrices (for
// SPARSE_NORMAL_CHOLESKY, SPARSE_SCHUR and ITERATIVE in
// conjunction with CLUSTER_TRIDIAGONAL AND CLUSTER_JACOBI
// preconditioners), the fill-reducing ordering algorithms can
// either be run on the block or the scalar form of these matrices.
// Running it on the block form exposes more of the super-nodal
// structure of the matrix to the factorization routines. Setting
// this parameter to true runs the ordering algorithms in block
// form. Currently this option only makes sense with
// sparse_linear_algebra_library = SUITE_SPARSE.
bool use_block_amd;
// 2. Specify a collection of of ordered independent sets. Where
// the lower numbered groups are optimized before the higher
// number groups. Each group must be an independent set.
ParameterBlockOrdering* inner_iteration_ordering;
// Minimum number of iterations for which the linear solver should
// run, even if the convergence criterion is satisfied.