Add more documentation. Add documentation to the TrustRegionMinimizer and TrustRegionStepEvaluator. Change-Id: I3651e41ff37955a0b7044910403630af1a855071
diff --git a/internal/ceres/trust_region_minimizer.cc b/internal/ceres/trust_region_minimizer.cc index 8d4407b..35c7c41 100644 --- a/internal/ceres/trust_region_minimizer.cc +++ b/internal/ceres/trust_region_minimizer.cc
@@ -66,8 +66,8 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options, double* parameters, Solver::Summary* solver_summary) { - start_time_ = WallTimeInSeconds(); - iteration_start_time_ = start_time_; + start_time_in_secs_ = WallTimeInSeconds(); + iteration_start_time_in_secs_ = start_time_in_secs_; Init(options, parameters, solver_summary); RETURN_IF_ERROR_AND_LOG(IterationZero()); @@ -81,7 +81,7 @@ : 0)); while (FinalizeIterationAndCheckIfMinimizerCanContinue()) { - iteration_start_time_ = WallTimeInSeconds(); + iteration_start_time_in_secs_ = WallTimeInSeconds(); iteration_summary_ = IterationSummary(); iteration_summary_.iteration = solver_summary->iterations.back().iteration + 1; @@ -304,9 +304,9 @@ iteration_summary_.trust_region_radius = strategy_->Radius(); iteration_summary_.iteration_time_in_seconds = - WallTimeInSeconds() - iteration_start_time_; + WallTimeInSeconds() - iteration_start_time_in_secs_; iteration_summary_.cumulative_time_in_seconds = - WallTimeInSeconds() - start_time_ + + WallTimeInSeconds() - start_time_in_secs_ + solver_summary_->preprocessor_time_in_seconds; solver_summary_->iterations.push_back(iteration_summary_); @@ -590,9 +590,12 @@ } } +// Check if the maximum amount of time allowed by the user for the +// solver has been exceeded, and if so return false after updating +// Solver::Summary::message. bool TrustRegionMinimizer::MaxSolverTimeReached() { const double total_solver_time = - WallTimeInSeconds() - start_time_ + + WallTimeInSeconds() - start_time_in_secs_ + solver_summary_->preprocessor_time_in_seconds; if (total_solver_time < options_.max_solver_time_in_seconds) { return false; @@ -607,6 +610,9 @@ return true; } +// Check if the maximum number of iterations allowed by the user for +// the solver has been exceeded, and if so return false after updating +// Solver::Summary::message. bool TrustRegionMinimizer::MaxSolverIterationsReached() { if (iteration_summary_.iteration < options_.max_num_iterations) { return false; @@ -622,6 +628,8 @@ return true; } +// Check convergence based on the max norm of the gradient (only for +// iterations where the step was declared successful). bool TrustRegionMinimizer::GradientToleranceReached() { if (!iteration_summary_.step_is_successful || iteration_summary_.gradient_max_norm > options_.gradient_tolerance) { @@ -638,6 +646,7 @@ return true; } +// Check convergence based the size of the trust region radius. bool TrustRegionMinimizer::MinTrustRegionRadiusReached() { if (iteration_summary_.trust_region_radius > options_.min_trust_region_radius) { @@ -751,6 +760,9 @@ options_.min_relative_decrease); } +// Declare the step successful, move to candidate_x, update the +// derivatives and let the trust region strategy and the step +// evaluator know that the step has been accepted. bool TrustRegionMinimizer::HandleSuccessfulStep() { x_ = candidate_x_; x_norm_ = x_.norm(); @@ -765,6 +777,7 @@ return true; } +// Declare the step unsuccessful and inform the trust region strategy. void TrustRegionMinimizer::HandleUnsuccessfulStep() { iteration_summary_.step_is_successful = false; strategy_->StepRejected(iteration_summary_.relative_decrease);
diff --git a/internal/ceres/trust_region_minimizer.h b/internal/ceres/trust_region_minimizer.h index ac4a6ed..43141da 100644 --- a/internal/ceres/trust_region_minimizer.h +++ b/internal/ceres/trust_region_minimizer.h
@@ -103,30 +103,60 @@ // Summary of the current iteration. IterationSummary iteration_summary_; + // Dimensionality of the problem in the ambient space. int num_parameters_; + // Dimensionality of the problem in the tangent space. This is the + // number of columns in the Jacobian. int num_effective_parameters_; + // Length of the residual vector, also the number of rows in the Jacobian. int num_residuals_; - Vector delta_; + // Current point. + Vector x_; + // Residuals at x_; + Vector residuals_; + // Gradient at x_. Vector gradient_; + // Solution computed by the inner iterations. Vector inner_iteration_x_; + // model_residuals = J * trust_region_step Vector model_residuals_; Vector negative_gradient_; + // projected_gradient_step = Plus(x, -gradient), an intermediate + // quantity used to compute the projected gradient norm. Vector projected_gradient_step_; - Vector residuals_; + // The step computed by the trust region strategy. If Jacobi scaling + // is enabled, this is a vector in the scaled space. Vector trust_region_step_; - Vector x_; + // The current proposal for how far the trust region algorithm + // thinks we should move. In the most basic case, it is just the + // trust_region_step_ with the Jacobi scaling undone. If bounds + // constraints are present, then it is the result of the projected + // line search. + Vector delta_; + // candidate_x = Plus(x, delta) Vector candidate_x_; + // Scaling vector to scale the columns of the Jacobian. Vector jacobian_scaling_; + // Euclidean norm of x_. double x_norm_; + // Cost at x_. double x_cost_; + // Minimum cost encountered up till now. double minimum_cost_; + // How much did the trust region strategy reduce the cost of the + // linearized Gauss-Newton model. double model_cost_change_; + // Cost at candidate_x_. double candidate_cost_; - double start_time_; - double iteration_start_time_; + // Time at which the minimizer was started. + double start_time_in_secs_; + // Time at which the current iteration was started. + double iteration_start_time_in_secs_; + // Number of consecutive steps where the minimizer loop computed a + // numerically invalid step. int num_consecutive_invalid_steps_; };
diff --git a/internal/ceres/trust_region_step_evaluator.h b/internal/ceres/trust_region_step_evaluator.h index 1f14954..06df102 100644 --- a/internal/ceres/trust_region_step_evaluator.h +++ b/internal/ceres/trust_region_step_evaluator.h
@@ -49,7 +49,7 @@ // increase in the value of the objective function. // // This is because allowing for non-decreasing objective function -// values in a principaled manner allows the algorithm to "jump over +// values in a principled manner allows the algorithm to "jump over // boulders" as the method is not restricted to move into narrow // valleys while preserving its convergence properties. // @@ -76,19 +76,43 @@ // } class TrustRegionStepEvaluator { public: + // initial_cost is as the name implies the cost of the starting + // state of the trust region minimizer. + // + // max_consecutive_nonmonotonic_steps controls the window size used + // by the step selection algorithm to accept non-monotonic + // steps. Setting this parameter to zero, recovers the classic + // montonic descent algorithm. TrustRegionStepEvaluator(double initial_cost, int max_consecutive_nonmonotonic_steps); + + // Return the quality of the step given its cost and the decrease in + // the cost of the model. model_cost_change has to be positive. double StepQuality(double cost, double model_cost_change) const; + + // Inform the step evaluator that a step with the given cost and + // model_cost_change has been accepted by the trust region + // minimizer. void StepAccepted(double cost, double model_cost_change); private: const int max_consecutive_nonmonotonic_steps_; + // The minimum cost encountered up till now. double minimum_cost_; + // The current cost of the trust region minimizer as informed by the + // last call to StepAccepted. double current_cost_; double reference_cost_; double candidate_cost_; + // Accumulated model cost since the last time the reference model + // cost was updated, i.e., when a step with cost less than the + // current known minimum cost is accepted. double accumulated_reference_model_cost_change_; + // Accumulated model cost since the last time the candidate model + // cost was updated, i.e., a non-monotonic step was taken with a + // cost that was greater than the current candidate cost. double accumulated_candidate_model_cost_change_; + // Number of steps taken since the last time minimum_cost was updated. int num_consecutive_nonmonotonic_steps_; };