Expose line search parameters in Solver::Options.
Change-Id: Ifc52980976e7bac73c8164d80518a5a19db1b79d
diff --git a/internal/ceres/line_search.cc b/internal/ceres/line_search.cc
index bc47814..06c823f 100644
--- a/internal/ceres/line_search.cc
+++ b/internal/ceres/line_search.cc
@@ -125,7 +125,7 @@
step_size_is_valid =
function->Evaluate(step_size,
&cost,
- options.interpolation_degree < 2 ? NULL : &gradient);
+ options.interpolation_type != CUBIC ? NULL : &gradient);
while (!step_size_is_valid || cost > (initial_cost
+ options.sufficient_decrease
* initial_gradient
@@ -137,26 +137,22 @@
const double current_step_size = step_size;
// Backtracking search. Each iteration of this loop finds a new point
- if ((options.interpolation_degree == 0) || !step_size_is_valid) {
- // Backtrack by halving the step_size;
+ if ((options.interpolation_type == BISECTION) || !step_size_is_valid) {
step_size *= 0.5;
} else {
// Backtrack by interpolating the function and gradient values
// and minimizing the corresponding polynomial.
-
vector<FunctionSample> samples;
samples.push_back(ValueAndGradientSample(0.0,
initial_cost,
initial_gradient));
- if (options.interpolation_degree == 1) {
+ if (options.interpolation_type == QUADRATIC) {
// Two point interpolation using function values and the
// initial gradient.
samples.push_back(ValueSample(step_size, cost));
- if (options.use_higher_degree_interpolation_when_possible &&
- summary->num_evaluations > 1 &&
- previous_step_size_is_valid) {
+ if (summary->num_evaluations > 1 && previous_step_size_is_valid) {
// Three point interpolation, using function values and the
// initial gradient.
samples.push_back(ValueSample(previous_step_size, previous_cost));
@@ -167,9 +163,7 @@
cost,
gradient));
- if (options.use_higher_degree_interpolation_when_possible &&
- summary->num_evaluations > 1 &&
- previous_step_size_is_valid) {
+ if (summary->num_evaluations > 1 && previous_step_size_is_valid) {
// Three point interpolation using the function values and
// the gradients.
samples.push_back(ValueAndGradientSample(previous_step_size,
@@ -191,7 +185,7 @@
previous_cost = cost;
previous_gradient = gradient;
- if (fabs(initial_gradient) * step_size < options.step_size_threshold) {
+ if (fabs(initial_gradient) * step_size < options.min_step_size) {
LOG(WARNING) << "Line search failed: step_size too small: " << step_size;
return;
}
@@ -200,7 +194,7 @@
step_size_is_valid =
function->Evaluate(step_size,
&cost,
- options.interpolation_degree < 2 ? NULL : &gradient);
+ options.interpolation_type != CUBIC ? NULL : &gradient);
}
summary->optimal_step_size = step_size;
diff --git a/internal/ceres/line_search.h b/internal/ceres/line_search.h
index a2b59b1..5792652 100644
--- a/internal/ceres/line_search.h
+++ b/internal/ceres/line_search.h
@@ -38,6 +38,7 @@
#include <vector>
#include "ceres/internal/eigen.h"
#include "ceres/internal/port.h"
+#include "ceres/types.h"
namespace ceres {
namespace internal {
@@ -60,30 +61,16 @@
struct Options {
Options()
- : interpolation_degree(1),
- use_higher_degree_interpolation_when_possible(false),
+ : interpolation_type(CUBIC),
sufficient_decrease(1e-4),
min_relative_step_size_change(1e-3),
- max_relative_step_size_change(0.6),
- step_size_threshold(1e-9),
+ max_relative_step_size_change(0.9),
+ min_step_size(1e-9),
function(NULL) {}
- // TODO(sameeragarwal): Replace this with enums which are common
- // across various line searches.
- //
// Degree of the polynomial used to approximate the objective
- // function. Valid values are {0, 1, 2}.
- //
- // For Armijo line search
- //
- // 0: Bisection based backtracking search.
- // 1: Quadratic interpolation.
- // 2: Cubic interpolation.
- int interpolation_degree;
-
- // Usually its possible to increase the degree of the
- // interpolation polynomial by storing and using an extra point.
- bool use_higher_degree_interpolation_when_possible;
+ // function.
+ LineSearchInterpolationType interpolation_type;
// Armijo line search parameters.
@@ -110,7 +97,7 @@
// If during the line search, the step_size falls below this
// value, it is truncated to zero.
- double step_size_threshold;
+ double min_step_size;
// The one dimensional function that the line search algorithm
// minimizes.
diff --git a/internal/ceres/line_search_minimizer.cc b/internal/ceres/line_search_minimizer.cc
index 92b7965..24aada3 100644
--- a/internal/ceres/line_search_minimizer.cc
+++ b/internal/ceres/line_search_minimizer.cc
@@ -164,11 +164,19 @@
LineSearchDirection::Create(line_search_direction_options));
LineSearchFunction line_search_function(evaluator);
+
LineSearch::Options line_search_options;
+ line_search_options.interpolation_type =
+ options.line_search_interpolation_type;
+ line_search_options.min_step_size = options.min_line_search_step_size;
+ line_search_options.sufficient_decrease =
+ options.armijo_sufficient_decrease;
+ line_search_options.min_relative_step_size_change =
+ options.min_armijo_relative_step_size_change;
+ line_search_options.max_relative_step_size_change =
+ options.max_armijo_relative_step_size_change;
line_search_options.function = &line_search_function;
- // TODO(sameeragarwal): Make this parameterizable over different
- // line searches.
ArmijoLineSearch line_search;
LineSearch::Summary line_search_summary;
diff --git a/internal/ceres/minimizer.h b/internal/ceres/minimizer.h
index f8f8a96..300d2df 100644
--- a/internal/ceres/minimizer.h
+++ b/internal/ceres/minimizer.h
@@ -88,6 +88,14 @@
nonlinear_conjugate_gradient_type =
options.nonlinear_conjugate_gradient_type;
max_lbfgs_rank = options.max_lbfgs_rank;
+ line_search_interpolation_type =
+ options.line_search_interpolation_type;
+ min_line_search_step_size = options.min_line_search_step_size;
+ armijo_sufficient_decrease = options.armijo_sufficient_decrease;
+ min_armijo_relative_step_size_change =
+ options.min_armijo_relative_step_size_change;
+ max_armijo_relative_step_size_change =
+ options.max_armijo_relative_step_size_change;
evaluator = NULL;
trust_region_strategy = NULL;
jacobian = NULL;
@@ -123,6 +131,12 @@
LineSearchType line_search_type;
NonlinearConjugateGradientType nonlinear_conjugate_gradient_type;
int max_lbfgs_rank;
+ LineSearchInterpolationType line_search_interpolation_type;
+ double min_line_search_step_size;
+ double armijo_sufficient_decrease;
+ double min_armijo_relative_step_size_change;
+ double max_armijo_relative_step_size_change;
+
// List of callbacks that are executed by the Minimizer at the end
// of each iteration.
diff --git a/internal/ceres/types.cc b/internal/ceres/types.cc
index 2e19322..e88cdd6 100644
--- a/internal/ceres/types.cc
+++ b/internal/ceres/types.cc
@@ -193,6 +193,27 @@
return false;
}
+const char* LineSearchInterpolationTypeToString(
+ LineSearchInterpolationType type) {
+ switch (type) {
+ CASESTR(BISECTION);
+ CASESTR(QUADRATIC);
+ CASESTR(CUBIC);
+ default:
+ return "UNKNOWN";
+ }
+}
+
+bool StringToLineSearchInterpolationType(
+ string value,
+ LineSearchInterpolationType* type) {
+ UpperCase(&value);
+ STRENUM(BISECTION);
+ STRENUM(QUADRATIC);
+ STRENUM(CUBIC);
+ return false;
+}
+
const char* NonlinearConjugateGradientTypeToString(
NonlinearConjugateGradientType type) {
switch (type) {