From 992ae55e84901508e352bee102e0de86d4e4cf2f Mon Sep 17 00:00:00 2001 From: Sameer Agarwal Date: Tue, 1 Dec 2015 07:25:06 -0800 Subject: [PATCH] Report the number of line search steps in FullReport. Accumulate the number of steps of the line search algorithm and report it as part of Summary::FullReport. Change-Id: I1de12784009a3e08f2a2c2aff5085d57a3c73828 --- docs/source/nnls_solving.rst | 8 ++++++++ include/ceres/solver.h | 7 +++++++ include/ceres/version.h | 2 +- internal/ceres/line_search_minimizer.cc | 7 +++++++ internal/ceres/solver.cc | 19 +++++++++++++------ internal/ceres/trust_region_minimizer.cc | 7 +++++++ 6 files changed, 43 insertions(+), 7 deletions(-) diff --git a/docs/source/nnls_solving.rst b/docs/source/nnls_solving.rst index ab15f98cb..4eb1fad4f 100644 --- a/docs/source/nnls_solving.rst +++ b/docs/source/nnls_solving.rst @@ -2012,6 +2012,14 @@ The three arrays will be: Number of times inner iterations were performed. + .. member:: int Solver::Summary::num_line_search_steps + + Total number of iterations inside the line search algorithm across + all invocations. We call these iterations "steps" to distinguish + them from the outer iterations of the line search and trust region + minimizer algorithms which call the line search algorithm as a + subroutine. + .. member:: double Solver::Summary::preprocessor_time_in_seconds Time (in seconds) spent in the preprocessor. diff --git a/include/ceres/solver.h b/include/ceres/solver.h index f53760e6c..76f3ca742 100644 --- a/include/ceres/solver.h +++ b/include/ceres/solver.h @@ -811,6 +811,13 @@ class CERES_EXPORT Solver { // Number of times inner iterations were performed. int num_inner_iteration_steps; + // Total number of iterations inside the line search algorithm + // across all invocations. We call these iterations "steps" to + // distinguish them from the outer iterations of the line search + // and trust region minimizer algorithms which call the line + // search algorithm as a subroutine. + int num_line_search_steps; + // All times reported below are wall times. // When the user calls Solve, before the actual optimization diff --git a/include/ceres/version.h b/include/ceres/version.h index 66505a515..2f1cc297a 100644 --- a/include/ceres/version.h +++ b/include/ceres/version.h @@ -32,7 +32,7 @@ #define CERES_PUBLIC_VERSION_H_ #define CERES_VERSION_MAJOR 1 -#define CERES_VERSION_MINOR 11 +#define CERES_VERSION_MINOR 12 #define CERES_VERSION_REVISION 0 // Classic CPP stringifcation; the extra level of indirection allows the diff --git a/internal/ceres/line_search_minimizer.cc b/internal/ceres/line_search_minimizer.cc index 62264fb0b..f424dd840 100644 --- a/internal/ceres/line_search_minimizer.cc +++ b/internal/ceres/line_search_minimizer.cc @@ -376,6 +376,13 @@ void LineSearchMinimizer::Minimize(const Minimizer::Options& options, WallTimeInSeconds() - start_time + summary->preprocessor_time_in_seconds; + // Iterations inside the line search algorithm are considered + // 'steps' in the broader context, to distinguish these inner + // iterations from from the outer iterations of the line search + // minimizer. The number of line search steps is the total number + // of inner line search iterations (or steps) across the entire + // minimization. + summary->num_line_search_steps += line_search_summary.num_iterations; summary->line_search_cost_evaluation_time_in_seconds += line_search_summary.cost_evaluation_time_in_seconds; summary->line_search_gradient_evaluation_time_in_seconds += diff --git a/internal/ceres/solver.cc b/internal/ceres/solver.cc index 9f3228bb0..5c784f81d 100644 --- a/internal/ceres/solver.cc +++ b/internal/ceres/solver.cc @@ -351,6 +351,7 @@ void PreSolveSummarize(const Solver::Options& options, summary->dense_linear_algebra_library_type = options.dense_linear_algebra_library_type; // NOLINT summary->dogleg_type = options.dogleg_type; summary->inner_iteration_time_in_seconds = 0.0; + summary->num_line_search_steps = 0; summary->line_search_cost_evaluation_time_in_seconds = 0.0; summary->line_search_gradient_evaluation_time_in_seconds = 0.0; summary->line_search_polynomial_minimization_time_in_seconds = 0.0; @@ -556,6 +557,7 @@ Solver::Summary::Summary() num_successful_steps(-1), num_unsuccessful_steps(-1), num_inner_iteration_steps(-1), + num_line_search_steps(-1), preprocessor_time_in_seconds(-1.0), minimizer_time_in_seconds(-1.0), postprocessor_time_in_seconds(-1.0), @@ -784,9 +786,14 @@ string Solver::Summary::FullReport() const { num_inner_iteration_steps); } - const bool print_line_search_timing_information = - minimizer_type == LINE_SEARCH || - (minimizer_type == TRUST_REGION && is_constrained); + const bool line_search_used = + (minimizer_type == LINE_SEARCH || + (minimizer_type == TRUST_REGION && is_constrained)); + + if (line_search_used) { + StringAppendF(&report, "Line search steps % 14d\n", + num_line_search_steps); + } StringAppendF(&report, "\nTime (in seconds):\n"); StringAppendF(&report, "Preprocessor %25.4f\n", @@ -794,13 +801,13 @@ string Solver::Summary::FullReport() const { StringAppendF(&report, "\n Residual evaluation %23.4f\n", residual_evaluation_time_in_seconds); - if (print_line_search_timing_information) { + if (line_search_used) { StringAppendF(&report, " Line search cost evaluation %10.4f\n", line_search_cost_evaluation_time_in_seconds); } StringAppendF(&report, " Jacobian evaluation %23.4f\n", jacobian_evaluation_time_in_seconds); - if (print_line_search_timing_information) { + if (line_search_used) { StringAppendF(&report, " Line search gradient evaluation %6.4f\n", line_search_gradient_evaluation_time_in_seconds); } @@ -815,7 +822,7 @@ string Solver::Summary::FullReport() const { inner_iteration_time_in_seconds); } - if (print_line_search_timing_information) { + if (line_search_used) { StringAppendF(&report, " Line search polynomial minimization %.4f\n", line_search_polynomial_minimization_time_in_seconds); } diff --git a/internal/ceres/trust_region_minimizer.cc b/internal/ceres/trust_region_minimizer.cc index d654d0867..627430c26 100644 --- a/internal/ceres/trust_region_minimizer.cc +++ b/internal/ceres/trust_region_minimizer.cc @@ -393,6 +393,13 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options, const LineSearch::Summary line_search_summary = DoLineSearch(options, x, gradient, cost, delta, evaluator); + // Iterations inside the line search algorithm are considered + // 'steps' in the broader context, to distinguish these inner + // iterations from from the outer iterations of the trust + // region minimizer The number of line search steps is the + // total number of inner line search iterations (or steps) + // across the entire minimization. + summary->num_line_search_steps += line_search_summary.num_iterations; summary->line_search_cost_evaluation_time_in_seconds += line_search_summary.cost_evaluation_time_in_seconds; summary->line_search_gradient_evaluation_time_in_seconds +=