blob: 2b08c6723e877367e5cd58b77c5e581c6c1ade52 [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// keir@google.com (Keir Mierle)
31//
32// The Problem object is used to build and hold least squares problems.
33
34#ifndef CERES_PUBLIC_PROBLEM_H_
35#define CERES_PUBLIC_PROBLEM_H_
36
37#include <cstddef>
38#include <map>
39#include <set>
40#include <vector>
41
42#include <glog/logging.h>
43#include "ceres/internal/macros.h"
44#include "ceres/internal/port.h"
45#include "ceres/internal/scoped_ptr.h"
46#include "ceres/types.h"
47
48namespace ceres {
49
50class CostFunction;
51class LossFunction;
52class LocalParameterization;
Keir Mierle6196cba2012-06-18 11:03:40 -070053class Solver;
Keir Mierle8ebb0732012-04-30 23:09:08 -070054
55namespace internal {
56class Preprocessor;
57class ProblemImpl;
58class ParameterBlock;
59class ResidualBlock;
Keir Mierle8ebb0732012-04-30 23:09:08 -070060} // namespace internal
61
62// A ResidualBlockId is a handle clients can use to delete residual
63// blocks after creating them. They are opaque for any purposes other
64// than that.
65typedef const internal::ResidualBlock* ResidualBlockId;
66
67// A class to represent non-linear least squares problems. Such
68// problems have a cost function that is a sum of error terms (known
69// as "residuals"), where each residual is a function of some subset
70// of the parameters. The cost function takes the form
71//
72// N 1
73// SUM --- loss( || r_i1, r_i2,..., r_ik ||^2 ),
74// i=1 2
75//
76// where
77//
78// r_ij is residual number i, component j; the residual is a
79// function of some subset of the parameters x1...xk. For
80// example, in a structure from motion problem a residual
81// might be the difference between a measured point in an
82// image and the reprojected position for the matching
83// camera, point pair. The residual would have two
84// components, error in x and error in y.
85//
86// loss(y) is the loss function; for example, squared error or
87// Huber L1 loss. If loss(y) = y, then the cost function is
88// non-robustified least squares.
89//
90// This class is specifically designed to address the important subset
91// of "sparse" least squares problems, where each component of the
92// residual depends only on a small number number of parameters, even
93// though the total number of residuals and parameters may be very
94// large. This property affords tremendous gains in scale, allowing
95// efficient solving of large problems that are otherwise
96// inaccessible.
97//
98// The canonical example of a sparse least squares problem is
99// "structure-from-motion" (SFM), where the parameters are points and
100// cameras, and residuals are reprojection errors. Typically a single
101// residual will depend only on 9 parameters (3 for the point, 6 for
102// the camera).
103//
104// To create a least squares problem, use the AddResidualBlock() and
105// AddParameterBlock() methods, documented below. Here is an example least
106// squares problem containing 3 parameter blocks of sizes 3, 4 and 5
107// respectively and two residual terms of size 2 and 6:
108//
109// double x1[] = { 1.0, 2.0, 3.0 };
110// double x2[] = { 1.0, 2.0, 3.0, 5.0 };
111// double x3[] = { 1.0, 2.0, 3.0, 6.0, 7.0 };
112//
113// Problem problem;
114//
115// problem.AddResidualBlock(new MyUnaryCostFunction(...), x1);
116// problem.AddResidualBlock(new MyBinaryCostFunction(...), x2, x3);
117//
118// Please see cost_function.h for details of the CostFunction object.
119class Problem {
120 public:
121 struct Options {
122 Options()
123 : cost_function_ownership(TAKE_OWNERSHIP),
124 loss_function_ownership(TAKE_OWNERSHIP),
125 local_parameterization_ownership(TAKE_OWNERSHIP) {}
126
127 // These flags control whether the Problem object owns the cost
128 // functions, loss functions, and parameterizations passed into
129 // the Problem. If set to TAKE_OWNERSHIP, then the problem object
130 // will delete the corresponding cost or loss functions on
131 // destruction. The destructor is careful to delete the pointers
132 // only once, since sharing cost/loss/parameterizations is
133 // allowed.
134 Ownership cost_function_ownership;
135 Ownership loss_function_ownership;
136 Ownership local_parameterization_ownership;
137 };
138
139 // The default constructor is equivalent to the
140 // invocation Problem(Problem::Options()).
141 Problem();
142 explicit Problem(const Options& options);
143
144 ~Problem();
145
146 // Add a residual block to the overall cost function. The cost
147 // function carries with it information about the sizes of the
148 // parameter blocks it expects. The function checks that these match
149 // the sizes of the parameter blocks listed in parameter_blocks. The
150 // program aborts if a mismatch is detected. loss_function can be
151 // NULL, in which case the cost of the term is just the squared norm
152 // of the residuals.
153 //
154 // The user has the option of explicitly adding the parameter blocks
155 // using AddParameterBlock. This causes additional correctness
156 // checking; however, AddResidualBlock implicitly adds the parameter
157 // blocks if they are not present, so calling AddParameterBlock
158 // explicitly is not required.
159 //
160 // The Problem object by default takes ownership of the
161 // cost_function and loss_function pointers. These objects remain
162 // live for the life of the Problem object. If the user wishes to
163 // keep control over the destruction of these objects, then they can
164 // do this by setting the corresponding enums in the Options struct.
165 //
166 // Note: Even though the Problem takes ownership of cost_function
167 // and loss_function, it does not preclude the user from re-using
168 // them in another residual block. The destructor takes care to call
169 // delete on each cost_function or loss_function pointer only once,
170 // regardless of how many residual blocks refer to them.
171 //
172 // Example usage:
173 //
174 // double x1[] = {1.0, 2.0, 3.0};
175 // double x2[] = {1.0, 2.0, 5.0, 6.0};
176 // double x3[] = {3.0, 6.0, 2.0, 5.0, 1.0};
177 //
178 // Problem problem;
179 //
180 // problem.AddResidualBlock(new MyUnaryCostFunction(...), NULL, x1);
181 // problem.AddResidualBlock(new MyBinaryCostFunction(...), NULL, x2, x1);
182 //
183 ResidualBlockId AddResidualBlock(CostFunction* cost_function,
184 LossFunction* loss_function,
185 const vector<double*>& parameter_blocks);
186
187 // Convenience methods for adding residuals with a small number of
188 // parameters. This is the common case. Instead of specifying the
189 // parameter block arguments as a vector, list them as pointers.
190 ResidualBlockId AddResidualBlock(CostFunction* cost_function,
191 LossFunction* loss_function,
192 double* x0);
193 ResidualBlockId AddResidualBlock(CostFunction* cost_function,
194 LossFunction* loss_function,
195 double* x0, double* x1);
196 ResidualBlockId AddResidualBlock(CostFunction* cost_function,
197 LossFunction* loss_function,
198 double* x0, double* x1, double* x2);
199 ResidualBlockId AddResidualBlock(CostFunction* cost_function,
200 LossFunction* loss_function,
201 double* x0, double* x1, double* x2,
202 double* x3);
203 ResidualBlockId AddResidualBlock(CostFunction* cost_function,
204 LossFunction* loss_function,
205 double* x0, double* x1, double* x2,
206 double* x3, double* x4);
207 ResidualBlockId AddResidualBlock(CostFunction* cost_function,
208 LossFunction* loss_function,
209 double* x0, double* x1, double* x2,
210 double* x3, double* x4, double* x5);
211
212 // Add a parameter block with appropriate size to the problem.
213 // Repeated calls with the same arguments are ignored. Repeated
214 // calls with the same double pointer but a different size results
215 // in undefined behaviour.
216 void AddParameterBlock(double* values, int size);
217
218 // Add a parameter block with appropriate size and parameterization
219 // to the problem. Repeated calls with the same arguments are
220 // ignored. Repeated calls with the same double pointer but a
221 // different size results in undefined behaviour.
222 void AddParameterBlock(double* values,
223 int size,
224 LocalParameterization* local_parameterization);
225
226 // Hold the indicated parameter block constant during optimization.
227 void SetParameterBlockConstant(double* values);
228
229 // Allow the indicated parameter to vary during optimization.
230 void SetParameterBlockVariable(double* values);
231
232 // Set the local parameterization for one of the parameter blocks.
233 // The local_parameterization is owned by the Problem by default. It
234 // is acceptable to set the same parameterization for multiple
235 // parameters; the destructor is careful to delete local
236 // parameterizations only once. The local parameterization can only
237 // be set once per parameter, and cannot be changed once set.
238 void SetParameterization(double* values,
239 LocalParameterization* local_parameterization);
240
241 // Number of parameter blocks in the problem. Always equals
242 // parameter_blocks().size() and parameter_block_sizes().size().
243 int NumParameterBlocks() const;
244
245 // The size of the parameter vector obtained by summing over the
246 // sizes of all the parameter blocks.
247 int NumParameters() const;
248
249 // Number of residual blocks in the problem. Always equals
250 // residual_blocks().size().
251 int NumResidualBlocks() const;
252
253 // The size of the residual vector obtained by summing over the
254 // sizes of all of the residual blocks.
255 int NumResiduals() const;
256
257 private:
Keir Mierle6196cba2012-06-18 11:03:40 -0700258 friend class Solver;
Keir Mierle8ebb0732012-04-30 23:09:08 -0700259 internal::scoped_ptr<internal::ProblemImpl> problem_impl_;
Sameer Agarwal237d6592012-05-30 20:34:49 -0700260 CERES_DISALLOW_COPY_AND_ASSIGN(Problem);
Keir Mierle8ebb0732012-04-30 23:09:08 -0700261};
262
263} // namespace ceres
264
265#endif // CERES_PUBLIC_PROBLEM_H_