blob: 9fab62e6d94a6d9b9929fab8ce10764dc043e319 [file] [log] [blame]
Austin Schuh70cc9552019-01-21 19:46:48 -08001// Ceres Solver - A fast non-linear least squares minimizer
Austin Schuh1d1e6ea2020-12-23 21:56:30 -08002// Copyright 2019 Google Inc. All rights reserved.
Austin Schuh70cc9552019-01-21 19:46:48 -08003// http://ceres-solver.org/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7//
8// * Redistributions of source code must retain the above copyright notice,
9// this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13// * Neither the name of Google Inc. nor the names of its contributors may be
14// used to endorse or promote products derived from this software without
15// specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27// POSSIBILITY OF SUCH DAMAGE.
28//
29// Author: sameeragarwal@google.com (Sameer Agarwal)
30
31#ifndef CERES_PUBLIC_GRADIENT_PROBLEM_SOLVER_H_
32#define CERES_PUBLIC_GRADIENT_PROBLEM_SOLVER_H_
33
34#include <cmath>
35#include <string>
36#include <vector>
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080037
38#include "ceres/internal/disable_warnings.h"
Austin Schuh70cc9552019-01-21 19:46:48 -080039#include "ceres/internal/port.h"
40#include "ceres/iteration_callback.h"
41#include "ceres/types.h"
Austin Schuh70cc9552019-01-21 19:46:48 -080042
43namespace ceres {
44
45class GradientProblem;
46
47class CERES_EXPORT GradientProblemSolver {
48 public:
49 virtual ~GradientProblemSolver();
50
51 // The options structure contains, not surprisingly, options that control how
52 // the solver operates. The defaults should be suitable for a wide range of
53 // problems; however, better performance is often obtainable with tweaking.
54 //
55 // The constants are defined inside types.h
56 struct CERES_EXPORT Options {
57 // Returns true if the options struct has a valid
58 // configuration. Returns false otherwise, and fills in *error
59 // with a message describing the problem.
60 bool IsValid(std::string* error) const;
61
62 // Minimizer options ----------------------------------------
63 LineSearchDirectionType line_search_direction_type = LBFGS;
64 LineSearchType line_search_type = WOLFE;
65 NonlinearConjugateGradientType nonlinear_conjugate_gradient_type =
66 FLETCHER_REEVES;
67
68 // The LBFGS hessian approximation is a low rank approximation to
69 // the inverse of the Hessian matrix. The rank of the
70 // approximation determines (linearly) the space and time
71 // complexity of using the approximation. Higher the rank, the
72 // better is the quality of the approximation. The increase in
73 // quality is however is bounded for a number of reasons.
74 //
75 // 1. The method only uses secant information and not actual
76 // derivatives.
77 //
78 // 2. The Hessian approximation is constrained to be positive
79 // definite.
80 //
81 // So increasing this rank to a large number will cost time and
82 // space complexity without the corresponding increase in solution
83 // quality. There are no hard and fast rules for choosing the
84 // maximum rank. The best choice usually requires some problem
85 // specific experimentation.
86 //
87 // For more theoretical and implementation details of the LBFGS
88 // method, please see:
89 //
90 // Nocedal, J. (1980). "Updating Quasi-Newton Matrices with
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080091 // Limited Storage". Mathematics of Computation 35 (151): 773-782.
Austin Schuh70cc9552019-01-21 19:46:48 -080092 int max_lbfgs_rank = 20;
93
94 // As part of the (L)BFGS update step (BFGS) / right-multiply step (L-BFGS),
95 // the initial inverse Hessian approximation is taken to be the Identity.
96 // However, Oren showed that using instead I * \gamma, where \gamma is
97 // chosen to approximate an eigenvalue of the true inverse Hessian can
98 // result in improved convergence in a wide variety of cases. Setting
99 // use_approximate_eigenvalue_bfgs_scaling to true enables this scaling.
100 //
101 // It is important to note that approximate eigenvalue scaling does not
102 // always improve convergence, and that it can in fact significantly degrade
103 // performance for certain classes of problem, which is why it is disabled
104 // by default. In particular it can degrade performance when the
105 // sensitivity of the problem to different parameters varies significantly,
106 // as in this case a single scalar factor fails to capture this variation
107 // and detrimentally downscales parts of the jacobian approximation which
108 // correspond to low-sensitivity parameters. It can also reduce the
109 // robustness of the solution to errors in the jacobians.
110 //
111 // Oren S.S., Self-scaling variable metric (SSVM) algorithms
112 // Part II: Implementation and experiments, Management Science,
113 // 20(5), 863-874, 1974.
114 bool use_approximate_eigenvalue_bfgs_scaling = false;
115
116 // Degree of the polynomial used to approximate the objective
117 // function. Valid values are BISECTION, QUADRATIC and CUBIC.
118 //
119 // BISECTION corresponds to pure backtracking search with no
120 // interpolation.
121 LineSearchInterpolationType line_search_interpolation_type = CUBIC;
122
123 // If during the line search, the step_size falls below this
124 // value, it is truncated to zero.
125 double min_line_search_step_size = 1e-9;
126
127 // Line search parameters.
128
129 // Solving the line search problem exactly is computationally
130 // prohibitive. Fortunately, line search based optimization
131 // algorithms can still guarantee convergence if instead of an
132 // exact solution, the line search algorithm returns a solution
133 // which decreases the value of the objective function
134 // sufficiently. More precisely, we are looking for a step_size
135 // s.t.
136 //
137 // f(step_size) <= f(0) + sufficient_decrease * f'(0) * step_size
138 //
139 double line_search_sufficient_function_decrease = 1e-4;
140
141 // In each iteration of the line search,
142 //
143 // new_step_size >= max_line_search_step_contraction * step_size
144 //
145 // Note that by definition, for contraction:
146 //
147 // 0 < max_step_contraction < min_step_contraction < 1
148 //
149 double max_line_search_step_contraction = 1e-3;
150
151 // In each iteration of the line search,
152 //
153 // new_step_size <= min_line_search_step_contraction * step_size
154 //
155 // Note that by definition, for contraction:
156 //
157 // 0 < max_step_contraction < min_step_contraction < 1
158 //
159 double min_line_search_step_contraction = 0.6;
160
161 // Maximum number of trial step size iterations during each line search,
162 // if a step size satisfying the search conditions cannot be found within
163 // this number of trials, the line search will terminate.
164 int max_num_line_search_step_size_iterations = 20;
165
166 // Maximum number of restarts of the line search direction algorithm before
167 // terminating the optimization. Restarts of the line search direction
168 // algorithm occur when the current algorithm fails to produce a new descent
169 // direction. This typically indicates a numerical failure, or a breakdown
170 // in the validity of the approximations used.
171 int max_num_line_search_direction_restarts = 5;
172
173 // The strong Wolfe conditions consist of the Armijo sufficient
174 // decrease condition, and an additional requirement that the
175 // step-size be chosen s.t. the _magnitude_ ('strong' Wolfe
176 // conditions) of the gradient along the search direction
177 // decreases sufficiently. Precisely, this second condition
178 // is that we seek a step_size s.t.
179 //
180 // |f'(step_size)| <= sufficient_curvature_decrease * |f'(0)|
181 //
182 // Where f() is the line search objective and f'() is the derivative
183 // of f w.r.t step_size (d f / d step_size).
184 double line_search_sufficient_curvature_decrease = 0.9;
185
186 // During the bracketing phase of the Wolfe search, the step size is
187 // increased until either a point satisfying the Wolfe conditions is
188 // found, or an upper bound for a bracket containing a point satisfying
189 // the conditions is found. Precisely, at each iteration of the
190 // expansion:
191 //
192 // new_step_size <= max_step_expansion * step_size.
193 //
194 // By definition for expansion, max_step_expansion > 1.0.
195 double max_line_search_step_expansion = 10.0;
196
197 // Maximum number of iterations for the minimizer to run for.
198 int max_num_iterations = 50;
199
200 // Maximum time for which the minimizer should run for.
201 double max_solver_time_in_seconds = 1e9;
202
203 // Minimizer terminates when
204 //
205 // (new_cost - old_cost) < function_tolerance * old_cost;
206 //
207 double function_tolerance = 1e-6;
208
209 // Minimizer terminates when
210 //
211 // max_i |x - Project(Plus(x, -g(x))| < gradient_tolerance
212 //
213 // This value should typically be 1e-4 * function_tolerance.
214 double gradient_tolerance = 1e-10;
215
216 // Minimizer terminates when
217 //
218 // |step|_2 <= parameter_tolerance * ( |x|_2 + parameter_tolerance)
219 //
220 double parameter_tolerance = 1e-8;
221
222 // Logging options ---------------------------------------------------------
223
224 LoggingType logging_type = PER_MINIMIZER_ITERATION;
225
226 // By default the Minimizer progress is logged to VLOG(1), which
227 // is sent to STDERR depending on the vlog level. If this flag is
228 // set to true, and logging_type is not SILENT, the logging output
229 // is sent to STDOUT.
230 bool minimizer_progress_to_stdout = false;
231
232 // If true, the user's parameter blocks are updated at the end of
233 // every Minimizer iteration, otherwise they are updated when the
234 // Minimizer terminates. This is useful if, for example, the user
235 // wishes to visualize the state of the optimization every
236 // iteration.
237 bool update_state_every_iteration = false;
238
239 // Callbacks that are executed at the end of each iteration of the
240 // Minimizer. An iteration may terminate midway, either due to
241 // numerical failures or because one of the convergence tests has
242 // been satisfied. In this case none of the callbacks are
243 // executed.
244
245 // Callbacks are executed in the order that they are specified in
246 // this vector. By default, parameter blocks are updated only at
247 // the end of the optimization, i.e when the Minimizer
248 // terminates. This behaviour is controlled by
249 // update_state_every_variable. If the user wishes to have access
250 // to the update parameter blocks when his/her callbacks are
251 // executed, then set update_state_every_iteration to true.
252 //
253 // The solver does NOT take ownership of these pointers.
254 std::vector<IterationCallback*> callbacks;
255 };
256
257 struct CERES_EXPORT Summary {
258 // A brief one line description of the state of the solver after
259 // termination.
260 std::string BriefReport() const;
261
262 // A full multiline description of the state of the solver after
263 // termination.
264 std::string FullReport() const;
265
266 bool IsSolutionUsable() const;
267
268 // Minimizer summary -------------------------------------------------
269 TerminationType termination_type = FAILURE;
270
271 // Reason why the solver terminated.
272 std::string message = "ceres::GradientProblemSolve was not called.";
273
274 // Cost of the problem (value of the objective function) before
275 // the optimization.
276 double initial_cost = -1.0;
277
278 // Cost of the problem (value of the objective function) after the
279 // optimization.
280 double final_cost = -1.0;
281
282 // IterationSummary for each minimizer iteration in order.
283 std::vector<IterationSummary> iterations;
284
285 // Number of times the cost (and not the gradient) was evaluated.
286 int num_cost_evaluations = -1;
287
288 // Number of times the gradient (and the cost) were evaluated.
289 int num_gradient_evaluations = -1;
290
291 // Sum total of all time spent inside Ceres when Solve is called.
292 double total_time_in_seconds = -1.0;
293
294 // Time (in seconds) spent evaluating the cost.
295 double cost_evaluation_time_in_seconds = -1.0;
296
297 // Time (in seconds) spent evaluating the gradient.
298 double gradient_evaluation_time_in_seconds = -1.0;
299
300 // Time (in seconds) spent minimizing the interpolating polynomial
301 // to compute the next candidate step size as part of a line search.
302 double line_search_polynomial_minimization_time_in_seconds = -1.0;
303
304 // Number of parameters in the problem.
305 int num_parameters = -1;
306
307 // Dimension of the tangent space of the problem.
308 int num_local_parameters = -1;
309
310 // Type of line search direction used.
311 LineSearchDirectionType line_search_direction_type = LBFGS;
312
313 // Type of the line search algorithm used.
314 LineSearchType line_search_type = WOLFE;
315
316 // When performing line search, the degree of the polynomial used
317 // to approximate the objective function.
318 LineSearchInterpolationType line_search_interpolation_type = CUBIC;
319
320 // If the line search direction is NONLINEAR_CONJUGATE_GRADIENT,
321 // then this indicates the particular variant of non-linear
322 // conjugate gradient used.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800323 NonlinearConjugateGradientType nonlinear_conjugate_gradient_type =
324 FLETCHER_REEVES;
Austin Schuh70cc9552019-01-21 19:46:48 -0800325
326 // If the type of the line search direction is LBFGS, then this
327 // indicates the rank of the Hessian approximation.
328 int max_lbfgs_rank = -1;
329 };
330
331 // Once a least squares problem has been built, this function takes
332 // the problem and optimizes it based on the values of the options
333 // parameters. Upon return, a detailed summary of the work performed
334 // by the preprocessor, the non-linear minimizer and the linear
335 // solver are reported in the summary object.
336 virtual void Solve(const GradientProblemSolver::Options& options,
337 const GradientProblem& problem,
338 double* parameters,
339 GradientProblemSolver::Summary* summary);
340};
341
342// Helper function which avoids going through the interface.
343CERES_EXPORT void Solve(const GradientProblemSolver::Options& options,
344 const GradientProblem& problem,
345 double* parameters,
346 GradientProblemSolver::Summary* summary);
347
348} // namespace ceres
349
350#include "ceres/internal/reenable_warnings.h"
351
352#endif // CERES_PUBLIC_GRADIENT_PROBLEM_SOLVER_H_