mirror of
https://github.com/ceres-solver/ceres-solver.git
synced 2026-08-30 17:10:38 +08:00
LocalParameterization -> Manifold #1
Manifolds are now part of the public API and co-exist with LocalParameterizations. 1. Add Manifolds to the Problem API. a. AddParameterBlock(double*, int, Manifold*) b. SetParameterization(double*, Manifold*) b. GetManifold(const double*) c. HasManifold(const double*) 2. Internally Ceres now only uses Manifolds. When the user uses a LocalParameterization, it is wrapped in a ManifoldAdapter. 3. To preserve the API semantics while keeping the internals clean we need a new map in ProblemImpl which stores the association between parameter blocks and local parameterizations. This is temporary, it will go away once this transition is complete. 4. There are NO algorithmic changes, as in we are not using any of the expanded interface of the Manifold objects yet. That will come later. 5. All tests that use LocalParameterization have been duplicated to use Manifolds, and when this transition is complete the LocalParameterization based tests will be deleted. 6. Public documentation for the API has been updated. Deprecation notices to the documentation as well as C++ annotations will come later. 7. Similar changes have been made to GradientProblem. Change-Id: I8e03c8ced6e141876ef3eca5740c113afa788f0c
This commit is contained in:
@@ -62,15 +62,14 @@ namespace {
|
||||
|
||||
class GradientCheckingCostFunction : public CostFunction {
|
||||
public:
|
||||
GradientCheckingCostFunction(
|
||||
const CostFunction* function,
|
||||
const std::vector<const LocalParameterization*>* local_parameterizations,
|
||||
const NumericDiffOptions& options,
|
||||
double relative_precision,
|
||||
const string& extra_info,
|
||||
GradientCheckingIterationCallback* callback)
|
||||
GradientCheckingCostFunction(const CostFunction* function,
|
||||
const std::vector<const Manifold*>* manifolds,
|
||||
const NumericDiffOptions& options,
|
||||
double relative_precision,
|
||||
const string& extra_info,
|
||||
GradientCheckingIterationCallback* callback)
|
||||
: function_(function),
|
||||
gradient_checker_(function, local_parameterizations, options),
|
||||
gradient_checker_(function, manifolds, options),
|
||||
relative_precision_(relative_precision),
|
||||
extra_info_(extra_info),
|
||||
callback_(callback) {
|
||||
@@ -154,7 +153,7 @@ void GradientCheckingIterationCallback::SetGradientErrorDetected(
|
||||
|
||||
CostFunction* CreateGradientCheckingCostFunction(
|
||||
const CostFunction* cost_function,
|
||||
const std::vector<const LocalParameterization*>* local_parameterizations,
|
||||
const std::vector<const Manifold*>* manifolds,
|
||||
double relative_step_size,
|
||||
double relative_precision,
|
||||
const std::string& extra_info,
|
||||
@@ -163,7 +162,7 @@ CostFunction* CreateGradientCheckingCostFunction(
|
||||
numeric_diff_options.relative_step_size = relative_step_size;
|
||||
|
||||
return new GradientCheckingCostFunction(cost_function,
|
||||
local_parameterizations,
|
||||
manifolds,
|
||||
numeric_diff_options,
|
||||
relative_precision,
|
||||
extra_info,
|
||||
@@ -176,18 +175,16 @@ ProblemImpl* CreateGradientCheckingProblemImpl(
|
||||
double relative_precision,
|
||||
GradientCheckingIterationCallback* callback) {
|
||||
CHECK(callback != nullptr);
|
||||
// We create new CostFunctions by wrapping the original CostFunction
|
||||
// in a gradient checking CostFunction. So its okay for the
|
||||
// ProblemImpl to take ownership of it and destroy it. The
|
||||
// LossFunctions and LocalParameterizations are reused and since
|
||||
// they are owned by problem_impl, gradient_checking_problem_impl
|
||||
// We create new CostFunctions by wrapping the original CostFunction in a
|
||||
// gradient checking CostFunction. So its okay for the ProblemImpl to take
|
||||
// ownership of it and destroy it. The LossFunctions and Manifolds are reused
|
||||
// and since they are owned by problem_impl, gradient_checking_problem_impl
|
||||
// should not take ownership of it.
|
||||
Problem::Options gradient_checking_problem_options;
|
||||
gradient_checking_problem_options.cost_function_ownership = TAKE_OWNERSHIP;
|
||||
gradient_checking_problem_options.loss_function_ownership =
|
||||
DO_NOT_TAKE_OWNERSHIP;
|
||||
gradient_checking_problem_options.local_parameterization_ownership =
|
||||
DO_NOT_TAKE_OWNERSHIP;
|
||||
gradient_checking_problem_options.manifold_ownership = DO_NOT_TAKE_OWNERSHIP;
|
||||
gradient_checking_problem_options.context = problem_impl->context();
|
||||
|
||||
NumericDiffOptions numeric_diff_options;
|
||||
@@ -198,15 +195,15 @@ ProblemImpl* CreateGradientCheckingProblemImpl(
|
||||
|
||||
Program* program = problem_impl->mutable_program();
|
||||
|
||||
// For every ParameterBlock in problem_impl, create a new parameter
|
||||
// block with the same local parameterization and constancy.
|
||||
// For every ParameterBlock in problem_impl, create a new parameter block with
|
||||
// the same manifold and constancy.
|
||||
const vector<ParameterBlock*>& parameter_blocks = program->parameter_blocks();
|
||||
for (int i = 0; i < parameter_blocks.size(); ++i) {
|
||||
ParameterBlock* parameter_block = parameter_blocks[i];
|
||||
gradient_checking_problem_impl->AddParameterBlock(
|
||||
parameter_block->mutable_user_state(),
|
||||
parameter_block->Size(),
|
||||
parameter_block->mutable_local_parameterization());
|
||||
parameter_block->mutable_manifold());
|
||||
|
||||
if (parameter_block->IsConstant()) {
|
||||
gradient_checking_problem_impl->SetParameterBlockConstant(
|
||||
@@ -238,22 +235,22 @@ ProblemImpl* CreateGradientCheckingProblemImpl(
|
||||
string extra_info =
|
||||
StringPrintf("Residual block id %d; depends on parameters [", i);
|
||||
vector<double*> parameter_blocks;
|
||||
vector<const LocalParameterization*> local_parameterizations;
|
||||
vector<const Manifold*> manifolds;
|
||||
parameter_blocks.reserve(residual_block->NumParameterBlocks());
|
||||
local_parameterizations.reserve(residual_block->NumParameterBlocks());
|
||||
manifolds.reserve(residual_block->NumParameterBlocks());
|
||||
for (int j = 0; j < residual_block->NumParameterBlocks(); ++j) {
|
||||
ParameterBlock* parameter_block = residual_block->parameter_blocks()[j];
|
||||
parameter_blocks.push_back(parameter_block->mutable_user_state());
|
||||
StringAppendF(&extra_info, "%p", parameter_block->mutable_user_state());
|
||||
extra_info += (j < residual_block->NumParameterBlocks() - 1) ? ", " : "]";
|
||||
local_parameterizations.push_back(problem_impl->GetParameterization(
|
||||
parameter_block->mutable_user_state()));
|
||||
manifolds.push_back(
|
||||
problem_impl->GetManifold(parameter_block->mutable_user_state()));
|
||||
}
|
||||
|
||||
// Wrap the original CostFunction in a GradientCheckingCostFunction.
|
||||
CostFunction* gradient_checking_cost_function =
|
||||
new GradientCheckingCostFunction(residual_block->cost_function(),
|
||||
&local_parameterizations,
|
||||
&manifolds,
|
||||
numeric_diff_options,
|
||||
relative_precision,
|
||||
extra_info,
|
||||
|
||||
Reference in New Issue
Block a user