blob: 4af586a4252c0d726a731dc6a2dc324ab55aceb2 [file] [log] [blame]
Keir Mierle8ebb0732012-04-30 23:09:08 -07001// Ceres Solver - A fast non-linear least squares minimizer
2// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
3// http://code.google.com/p/ceres-solver/
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// Abstract interface for objects solving linear systems of various
32// kinds.
33
34#ifndef CERES_INTERNAL_LINEAR_SOLVER_H_
35#define CERES_INTERNAL_LINEAR_SOLVER_H_
36
37#include <cstddef>
Sameer Agarwal509f68c2013-02-20 01:39:03 -080038#include <map>
Sameer Agarwala427c872013-06-24 17:50:56 -070039#include <string>
Sameer Agarwal0c52f1e2012-09-17 11:30:14 -070040#include <vector>
Keir Mierle8ebb0732012-04-30 23:09:08 -070041#include "ceres/block_sparse_matrix.h"
42#include "ceres/casts.h"
43#include "ceres/compressed_row_sparse_matrix.h"
44#include "ceres/dense_sparse_matrix.h"
Sameer Agarwalbdd87c02013-01-29 16:24:31 -080045#include "ceres/execution_summary.h"
Keir Mierle8ebb0732012-04-30 23:09:08 -070046#include "ceres/triplet_sparse_matrix.h"
47#include "ceres/types.h"
Sameer Agarwal509f68c2013-02-20 01:39:03 -080048#include "glog/logging.h"
Keir Mierle8ebb0732012-04-30 23:09:08 -070049
50namespace ceres {
51namespace internal {
52
Sameer Agarwal79bde352013-11-21 21:33:51 -080053enum LinearSolverTerminationType {
54 // Termination criterion was met. For factorization based solvers
55 // the tolerance is assumed to be zero. Any user provided values are
56 // ignored.
57 TOLERANCE,
58
59 // Solver ran for max_num_iterations and terminated before the
60 // termination tolerance could be satified.
61 MAX_ITERATIONS,
62
63 // Solver is stuck and further iterations will not result in any
64 // measurable progress.
65 STAGNATION,
66
67 // Solver failed. Solver was terminated due to numerical errors. The
68 // exact cause of failure depends on the particular solver being
69 // used.
70 FAILURE,
71
72 // Solver failed with a fatal error that cannot be recovered from.
73 FATAL_ERROR
74};
75
76
Keir Mierle8ebb0732012-04-30 23:09:08 -070077class LinearOperator;
78
79// Abstract base class for objects that implement algorithms for
80// solving linear systems
81//
82// Ax = b
83//
84// It is expected that a single instance of a LinearSolver object
Sameer Agarwala9d8ef82012-05-14 02:28:05 -070085// maybe used multiple times for solving multiple linear systems with
86// the same sparsity structure. This allows them to cache and reuse
87// information across solves. This means that calling Solve on the
88// same LinearSolver instance with two different linear systems will
89// result in undefined behaviour.
Keir Mierle8ebb0732012-04-30 23:09:08 -070090//
91// Subclasses of LinearSolver use two structs to configure themselves.
92// The Options struct configures the LinearSolver object for its
93// lifetime. The PerSolveOptions struct is used to specify options for
94// a particular Solve call.
95class LinearSolver {
96 public:
97 struct Options {
98 Options()
99 : type(SPARSE_NORMAL_CHOLESKY),
100 preconditioner_type(JACOBI),
Sameer Agarwalf06b9fa2013-10-27 21:38:13 -0700101 visibility_clustering_type(CANONICAL_VIEWS),
Sameer Agarwal367b65e2013-08-09 10:35:37 -0700102 dense_linear_algebra_library_type(EIGEN),
103 sparse_linear_algebra_library_type(SUITE_SPARSE),
Sameer Agarwal9189f4e2013-04-19 17:09:49 -0700104 use_postordering(false),
Keir Mierle8ebb0732012-04-30 23:09:08 -0700105 min_num_iterations(1),
106 max_num_iterations(1),
107 num_threads(1),
Keir Mierle8ebb0732012-04-30 23:09:08 -0700108 residual_reset_period(10),
Sameer Agarwal31730ef2013-02-28 11:20:28 -0800109 row_block_size(Eigen::Dynamic),
110 e_block_size(Eigen::Dynamic),
111 f_block_size(Eigen::Dynamic) {
Keir Mierle8ebb0732012-04-30 23:09:08 -0700112 }
113
114 LinearSolverType type;
115
116 PreconditionerType preconditioner_type;
Sameer Agarwalf06b9fa2013-10-27 21:38:13 -0700117 VisibilityClusteringType visibility_clustering_type;
Keir Mierle8ebb0732012-04-30 23:09:08 -0700118
Sameer Agarwal367b65e2013-08-09 10:35:37 -0700119 DenseLinearAlgebraLibraryType dense_linear_algebra_library_type;
120 SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type;
Sameer Agarwalb0518732012-05-29 00:27:57 -0700121
Sameer Agarwal9189f4e2013-04-19 17:09:49 -0700122 // See solver.h for information about this flag.
123 bool use_postordering;
Sameer Agarwal7a3c43b2012-06-05 23:10:59 -0700124
Keir Mierle8ebb0732012-04-30 23:09:08 -0700125 // Number of internal iterations that the solver uses. This
126 // parameter only makes sense for iterative solvers like CG.
127 int min_num_iterations;
128 int max_num_iterations;
129
130 // If possible, how many threads can the solver use.
131 int num_threads;
132
Sameer Agarwal0c52f1e2012-09-17 11:30:14 -0700133 // Hints about the order in which the parameter blocks should be
134 // eliminated by the linear solver.
135 //
136 // For example if elimination_groups is a vector of size k, then
137 // the linear solver is informed that it should eliminate the
Sameer Agarwal931c3092013-02-25 09:46:21 -0800138 // parameter blocks 0 ... elimination_groups[0] - 1 first, and
139 // then elimination_groups[0] ... elimination_groups[1] - 1 and so
140 // on. Within each elimination group, the linear solver is free to
141 // choose how the parameter blocks are ordered. Different linear
142 // solvers have differing requirements on elimination_groups.
Sameer Agarwal0c52f1e2012-09-17 11:30:14 -0700143 //
144 // The most common use is for Schur type solvers, where there
145 // should be at least two elimination groups and the first
146 // elimination group must form an independent set in the normal
147 // equations. The first elimination group corresponds to the
148 // num_eliminate_blocks in the Schur type solvers.
149 vector<int> elimination_groups;
Keir Mierle8ebb0732012-04-30 23:09:08 -0700150
151 // Iterative solvers, e.g. Preconditioned Conjugate Gradients
152 // maintain a cheap estimate of the residual which may become
153 // inaccurate over time. Thus for non-zero values of this
154 // parameter, the solver can be told to recalculate the value of
155 // the residual using a |b - Ax| evaluation.
156 int residual_reset_period;
157
158 // If the block sizes in a BlockSparseMatrix are fixed, then in
159 // some cases the Schur complement based solvers can detect and
160 // specialize on them.
161 //
162 // It is expected that these parameters are set programmatically
163 // rather than manually.
164 //
Sameer Agarwala9d8ef82012-05-14 02:28:05 -0700165 // Please see schur_complement_solver.h and schur_eliminator.h for
166 // more details.
Keir Mierle8ebb0732012-04-30 23:09:08 -0700167 int row_block_size;
168 int e_block_size;
169 int f_block_size;
170 };
171
172 // Options for the Solve method.
173 struct PerSolveOptions {
174 PerSolveOptions()
175 : D(NULL),
176 preconditioner(NULL),
177 r_tolerance(0.0),
178 q_tolerance(0.0) {
179 }
180
181 // This option only makes sense for unsymmetric linear solvers
182 // that can solve rectangular linear systems.
183 //
184 // Given a matrix A, an optional diagonal matrix D as a vector,
185 // and a vector b, the linear solver will solve for
186 //
187 // | A | x = | b |
188 // | D | | 0 |
189 //
190 // If D is null, then it is treated as zero, and the solver returns
191 // the solution to
192 //
193 // A x = b
194 //
195 // In either case, x is the vector that solves the following
196 // optimization problem.
197 //
Keir Mierlef7898fb2012-05-05 20:55:08 -0700198 // arg min_x ||Ax - b||^2 + ||Dx||^2
Keir Mierle8ebb0732012-04-30 23:09:08 -0700199 //
200 // Here A is a matrix of size m x n, with full column rank. If A
201 // does not have full column rank, the results returned by the
202 // solver cannot be relied on. D, if it is not null is an array of
203 // size n. b is an array of size m and x is an array of size n.
204 double * D;
205
206 // This option only makes sense for iterative solvers.
207 //
208 // In general the performance of an iterative linear solver
209 // depends on the condition number of the matrix A. For example
210 // the convergence rate of the conjugate gradients algorithm
211 // is proportional to the square root of the condition number.
212 //
213 // One particularly useful technique for improving the
214 // conditioning of a linear system is to precondition it. In its
215 // simplest form a preconditioner is a matrix M such that instead
216 // of solving Ax = b, we solve the linear system AM^{-1} y = b
217 // instead, where M is such that the condition number k(AM^{-1})
218 // is smaller than the conditioner k(A). Given the solution to
219 // this system, x = M^{-1} y. The iterative solver takes care of
220 // the mechanics of solving the preconditioned system and
221 // returning the corrected solution x. The user only needs to
222 // supply a linear operator.
223 //
224 // A null preconditioner is equivalent to an identity matrix being
225 // used a preconditioner.
226 LinearOperator* preconditioner;
227
228
229 // The following tolerance related options only makes sense for
230 // iterative solvers. Direct solvers ignore them.
231
232 // Solver terminates when
233 //
234 // |Ax - b| <= r_tolerance * |b|.
235 //
236 // This is the most commonly used termination criterion for
237 // iterative solvers.
238 double r_tolerance;
239
240 // For PSD matrices A, let
241 //
242 // Q(x) = x'Ax - 2b'x
243 //
244 // be the cost of the quadratic function defined by A and b. Then,
245 // the solver terminates at iteration i if
246 //
247 // i * (Q(x_i) - Q(x_i-1)) / Q(x_i) < q_tolerance.
248 //
249 // This termination criterion is more useful when using CG to
250 // solve the Newton step. This particular convergence test comes
251 // from Stephen Nash's work on truncated Newton
252 // methods. References:
253 //
254 // 1. Stephen G. Nash & Ariela Sofer, Assessing A Search
255 // Direction Within A Truncated Newton Method, Operation
256 // Research Letters 9(1990) 219-221.
257 //
258 // 2. Stephen G. Nash, A Survey of Truncated Newton Methods,
259 // Journal of Computational and Applied Mathematics,
260 // 124(1-2), 45-59, 2000.
261 //
262 double q_tolerance;
263 };
264
265 // Summary of a call to the Solve method. We should move away from
266 // the true/false method for determining solver success. We should
267 // let the summary object do the talking.
268 struct Summary {
269 Summary()
270 : residual_norm(0.0),
271 num_iterations(-1),
272 termination_type(FAILURE) {
273 }
274
275 double residual_norm;
276 int num_iterations;
277 LinearSolverTerminationType termination_type;
Sameer Agarwal79bde352013-11-21 21:33:51 -0800278 string status;
Keir Mierle8ebb0732012-04-30 23:09:08 -0700279 };
280
281 virtual ~LinearSolver();
282
283 // Solve Ax = b.
284 virtual Summary Solve(LinearOperator* A,
285 const double* b,
286 const PerSolveOptions& per_solve_options,
287 double* x) = 0;
288
Sameer Agarwal42a84b82013-02-01 12:22:53 -0800289 // The following two methods return copies instead of references so
290 // that the base class implementation does not have to worry about
291 // life time issues. Further, these calls are not expected to be
292 // frequent or performance sensitive.
293 virtual map<string, int> CallStatistics() const {
294 return map<string, int>();
295 }
296
297 virtual map<string, double> TimeStatistics() const {
298 return map<string, double>();
299 }
300
Sameer Agarwala9d8ef82012-05-14 02:28:05 -0700301 // Factory
Keir Mierle8ebb0732012-04-30 23:09:08 -0700302 static LinearSolver* Create(const Options& options);
303};
304
305// This templated subclass of LinearSolver serves as a base class for
306// other linear solvers that depend on the particular matrix layout of
307// the underlying linear operator. For example some linear solvers
308// need low level access to the TripletSparseMatrix implementing the
309// LinearOperator interface. This class hides those implementation
310// details behind a private virtual method, and has the Solve method
311// perform the necessary upcasting.
312template <typename MatrixType>
313class TypedLinearSolver : public LinearSolver {
314 public:
315 virtual ~TypedLinearSolver() {}
316 virtual LinearSolver::Summary Solve(
317 LinearOperator* A,
318 const double* b,
319 const LinearSolver::PerSolveOptions& per_solve_options,
320 double* x) {
Sameer Agarwal42a84b82013-02-01 12:22:53 -0800321 ScopedExecutionTimer total_time("LinearSolver::Solve", &execution_summary_);
Keir Mierle8ebb0732012-04-30 23:09:08 -0700322 CHECK_NOTNULL(A);
323 CHECK_NOTNULL(b);
324 CHECK_NOTNULL(x);
325 return SolveImpl(down_cast<MatrixType*>(A), b, per_solve_options, x);
326 }
327
Sameer Agarwal42a84b82013-02-01 12:22:53 -0800328 virtual map<string, int> CallStatistics() const {
329 return execution_summary_.calls();
330 }
331
332 virtual map<string, double> TimeStatistics() const {
333 return execution_summary_.times();
334 }
335
Keir Mierle8ebb0732012-04-30 23:09:08 -0700336 private:
337 virtual LinearSolver::Summary SolveImpl(
338 MatrixType* A,
339 const double* b,
340 const LinearSolver::PerSolveOptions& per_solve_options,
341 double* x) = 0;
Sameer Agarwal42a84b82013-02-01 12:22:53 -0800342
343 ExecutionSummary execution_summary_;
Keir Mierle8ebb0732012-04-30 23:09:08 -0700344};
345
346// Linear solvers that depend on acccess to the low level structure of
347// a SparseMatrix.
348typedef TypedLinearSolver<BlockSparseMatrix> BlockSparseMatrixSolver; // NOLINT
Keir Mierle8ebb0732012-04-30 23:09:08 -0700349typedef TypedLinearSolver<CompressedRowSparseMatrix> CompressedRowSparseMatrixSolver; // NOLINT
350typedef TypedLinearSolver<DenseSparseMatrix> DenseSparseMatrixSolver; // NOLINT
351typedef TypedLinearSolver<TripletSparseMatrix> TripletSparseMatrixSolver; // NOLINT
352
353} // namespace internal
354} // namespace ceres
355
356#endif // CERES_INTERNAL_LINEAR_SOLVER_H_