blob: 4c6fd1beed9210b0cfe655e227814b7d06e41c17 [file] [log] [blame]
Austin Schuh70cc9552019-01-21 19:46:48 -08001// Ceres Solver - A fast non-linear least squares minimizer
Austin Schuh3de38b02024-06-25 18:25:10 -07002// Copyright 2023 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// 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 <array>
38#include <cstddef>
39#include <map>
40#include <memory>
41#include <set>
42#include <vector>
43
44#include "ceres/context.h"
45#include "ceres/internal/disable_warnings.h"
Austin Schuh3de38b02024-06-25 18:25:10 -070046#include "ceres/internal/export.h"
Austin Schuh70cc9552019-01-21 19:46:48 -080047#include "ceres/internal/port.h"
48#include "ceres/types.h"
49#include "glog/logging.h"
50
51namespace ceres {
52
53class CostFunction;
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080054class EvaluationCallback;
Austin Schuh70cc9552019-01-21 19:46:48 -080055class LossFunction;
Austin Schuh3de38b02024-06-25 18:25:10 -070056class Manifold;
Austin Schuh70cc9552019-01-21 19:46:48 -080057class Solver;
58struct CRSMatrix;
59
60namespace internal {
61class Preprocessor;
62class ProblemImpl;
63class ParameterBlock;
64class ResidualBlock;
65} // namespace internal
66
67// A ResidualBlockId is an opaque handle clients can use to remove residual
68// blocks from a Problem after adding them.
Austin Schuh3de38b02024-06-25 18:25:10 -070069using ResidualBlockId = internal::ResidualBlock*;
Austin Schuh70cc9552019-01-21 19:46:48 -080070
71// A class to represent non-linear least squares problems. Such
72// problems have a cost function that is a sum of error terms (known
73// as "residuals"), where each residual is a function of some subset
74// of the parameters. The cost function takes the form
75//
76// N 1
77// SUM --- loss( || r_i1, r_i2,..., r_ik ||^2 ),
78// i=1 2
79//
80// where
81//
Austin Schuh3de38b02024-06-25 18:25:10 -070082// r_ij is residual number i, component j; the residual is a function of some
83// subset of the parameters x1...xk. For example, in a structure from
84// motion problem a residual might be the difference between a measured
85// point in an image and the reprojected position for the matching
86// camera, point pair. The residual would have two components, error in x
87// and error in y.
Austin Schuh70cc9552019-01-21 19:46:48 -080088//
Austin Schuh3de38b02024-06-25 18:25:10 -070089// loss(y) is the loss function; for example, squared error or Huber L1
90// loss. If loss(y) = y, then the cost function is non-robustified
91// least squares.
Austin Schuh70cc9552019-01-21 19:46:48 -080092//
Austin Schuh3de38b02024-06-25 18:25:10 -070093// This class is specifically designed to address the important subset of
94// "sparse" least squares problems, where each component of the residual depends
95// only on a small number number of parameters, even though the total number of
96// residuals and parameters may be very large. This property affords tremendous
97// gains in scale, allowing efficient solving of large problems that are
98// otherwise inaccessible.
Austin Schuh70cc9552019-01-21 19:46:48 -080099//
100// The canonical example of a sparse least squares problem is
Austin Schuh3de38b02024-06-25 18:25:10 -0700101// "structure-from-motion" (SFM), where the parameters are points and cameras,
102// and residuals are reprojection errors. Typically a single residual will
103// depend only on 9 parameters (3 for the point, 6 for the camera).
Austin Schuh70cc9552019-01-21 19:46:48 -0800104//
105// To create a least squares problem, use the AddResidualBlock() and
106// AddParameterBlock() methods, documented below. Here is an example least
107// squares problem containing 3 parameter blocks of sizes 3, 4 and 5
108// respectively and two residual terms of size 2 and 6:
109//
110// double x1[] = { 1.0, 2.0, 3.0 };
111// double x2[] = { 1.0, 2.0, 3.0, 5.0 };
112// double x3[] = { 1.0, 2.0, 3.0, 6.0, 7.0 };
113//
114// Problem problem;
115//
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800116// problem.AddResidualBlock(new MyUnaryCostFunction(...), nullptr, x1);
117// problem.AddResidualBlock(new MyBinaryCostFunction(...), nullptr, x2, x3);
Austin Schuh70cc9552019-01-21 19:46:48 -0800118//
119// Please see cost_function.h for details of the CostFunction object.
120class CERES_EXPORT Problem {
121 public:
122 struct CERES_EXPORT Options {
Austin Schuh3de38b02024-06-25 18:25:10 -0700123 // These flags control whether the Problem object owns the CostFunctions,
124 // LossFunctions, and Manifolds passed into the Problem.
125 //
126 // If set to TAKE_OWNERSHIP, then the problem object will delete the
127 // corresponding object on destruction. The destructor is careful to delete
128 // the pointers only once, since sharing objects is allowed.
Austin Schuh70cc9552019-01-21 19:46:48 -0800129 Ownership cost_function_ownership = TAKE_OWNERSHIP;
130 Ownership loss_function_ownership = TAKE_OWNERSHIP;
Austin Schuh3de38b02024-06-25 18:25:10 -0700131 Ownership manifold_ownership = TAKE_OWNERSHIP;
Austin Schuh70cc9552019-01-21 19:46:48 -0800132
133 // If true, trades memory for faster RemoveResidualBlock() and
134 // RemoveParameterBlock() operations.
135 //
136 // By default, RemoveParameterBlock() and RemoveResidualBlock() take time
Austin Schuh3de38b02024-06-25 18:25:10 -0700137 // proportional to the size of the entire problem. If you only ever remove
Austin Schuh70cc9552019-01-21 19:46:48 -0800138 // parameters or residuals from the problem occasionally, this might be
Austin Schuh3de38b02024-06-25 18:25:10 -0700139 // acceptable. However, if you have memory to spare, enable this option to
Austin Schuh70cc9552019-01-21 19:46:48 -0800140 // make RemoveParameterBlock() take time proportional to the number of
141 // residual blocks that depend on it, and RemoveResidualBlock() take (on
142 // average) constant time.
143 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700144 // The increase in memory usage is two-fold: an additional hash set per
Austin Schuh70cc9552019-01-21 19:46:48 -0800145 // parameter block containing all the residuals that depend on the parameter
146 // block; and a hash set in the problem containing all residuals.
147 bool enable_fast_removal = false;
148
149 // By default, Ceres performs a variety of safety checks when constructing
Austin Schuh3de38b02024-06-25 18:25:10 -0700150 // the problem. There is a small but measurable performance penalty to these
151 // checks, typically around 5% of construction time. If you are sure your
152 // problem construction is correct, and 5% of the problem construction time
153 // is truly an overhead you want to avoid, then you can set
Austin Schuh70cc9552019-01-21 19:46:48 -0800154 // disable_all_safety_checks to true.
155 //
156 // WARNING: Do not set this to true, unless you are absolutely sure of what
157 // you are doing.
158 bool disable_all_safety_checks = false;
159
160 // A Ceres global context to use for solving this problem. This may help to
161 // reduce computation time as Ceres can reuse expensive objects to create.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800162 // The context object can be nullptr, in which case Ceres may create one.
Austin Schuh70cc9552019-01-21 19:46:48 -0800163 //
164 // Ceres does NOT take ownership of the pointer.
165 Context* context = nullptr;
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800166
Austin Schuh3de38b02024-06-25 18:25:10 -0700167 // Using this callback interface, Ceres can notify you when it is about to
168 // evaluate the residuals or jacobians. With the callback, you can share
169 // computation between residual blocks by doing the shared computation in
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800170 // EvaluationCallback::PrepareForEvaluation() before Ceres calls
Austin Schuh3de38b02024-06-25 18:25:10 -0700171 // CostFunction::Evaluate(). It also enables caching results between a pure
172 // residual evaluation and a residual & jacobian evaluation.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800173 //
174 // Problem DOES NOT take ownership of the callback.
175 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700176 // NOTE: Evaluation callbacks are incompatible with inner iterations. So
177 // calling Solve with Solver::Options::use_inner_iterations = true on a
178 // Problem with a non-null evaluation callback is an error.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800179 EvaluationCallback* evaluation_callback = nullptr;
Austin Schuh70cc9552019-01-21 19:46:48 -0800180 };
181
Austin Schuh3de38b02024-06-25 18:25:10 -0700182 // The default constructor is equivalent to the invocation
183 // Problem(Problem::Options()).
Austin Schuh70cc9552019-01-21 19:46:48 -0800184 Problem();
185 explicit Problem(const Options& options);
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800186 Problem(Problem&&);
187 Problem& operator=(Problem&&);
188
Austin Schuh70cc9552019-01-21 19:46:48 -0800189 Problem(const Problem&) = delete;
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800190 Problem& operator=(const Problem&) = delete;
Austin Schuh70cc9552019-01-21 19:46:48 -0800191
192 ~Problem();
193
Austin Schuh3de38b02024-06-25 18:25:10 -0700194 // Add a residual block to the overall cost function. The cost function
195 // carries with its information about the sizes of the parameter blocks it
196 // expects. The function checks that these match the sizes of the parameter
197 // blocks listed in parameter_blocks. The program aborts if a mismatch is
198 // detected. loss_function can be nullptr, in which case the cost of the term
199 // is just the squared norm of the residuals.
Austin Schuh70cc9552019-01-21 19:46:48 -0800200 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700201 // The user has the option of explicitly adding the parameter blocks using
202 // AddParameterBlock. This causes additional correctness checking; however,
203 // AddResidualBlock implicitly adds the parameter blocks if they are not
204 // present, so calling AddParameterBlock explicitly is not required.
Austin Schuh70cc9552019-01-21 19:46:48 -0800205 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700206 // The Problem object by default takes ownership of the cost_function and
207 // loss_function pointers (See Problem::Options to override this behaviour).
208 // These objects remain live for the life of the Problem object. If the user
209 // wishes to keep control over the destruction of these objects, then they can
Austin Schuh70cc9552019-01-21 19:46:48 -0800210 // do this by setting the corresponding enums in the Options struct.
211 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700212 // Note: Even though the Problem takes ownership of cost_function and
213 // loss_function, it does not preclude the user from re-using them in another
214 // residual block. The destructor takes care to call delete on each
215 // cost_function or loss_function pointer only once, regardless of how many
216 // residual blocks refer to them.
Austin Schuh70cc9552019-01-21 19:46:48 -0800217 //
218 // Example usage:
219 //
220 // double x1[] = {1.0, 2.0, 3.0};
221 // double x2[] = {1.0, 2.0, 5.0, 6.0};
222 // double x3[] = {3.0, 6.0, 2.0, 5.0, 1.0};
223 //
224 // Problem problem;
225 //
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800226 // problem.AddResidualBlock(new MyUnaryCostFunction(...), nullptr, x1);
227 // problem.AddResidualBlock(new MyBinaryCostFunction(...), nullptr, x2, x1);
Austin Schuh70cc9552019-01-21 19:46:48 -0800228 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700229 // Add a residual block by listing the parameter block pointers directly
230 // instead of wapping them in a container.
Austin Schuh70cc9552019-01-21 19:46:48 -0800231 template <typename... Ts>
232 ResidualBlockId AddResidualBlock(CostFunction* cost_function,
233 LossFunction* loss_function,
234 double* x0,
235 Ts*... xs) {
236 const std::array<double*, sizeof...(Ts) + 1> parameter_blocks{{x0, xs...}};
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800237 return AddResidualBlock(cost_function,
238 loss_function,
Austin Schuh70cc9552019-01-21 19:46:48 -0800239 parameter_blocks.data(),
240 static_cast<int>(parameter_blocks.size()));
241 }
242
243 // Add a residual block by providing a vector of parameter blocks.
244 ResidualBlockId AddResidualBlock(
245 CostFunction* cost_function,
246 LossFunction* loss_function,
247 const std::vector<double*>& parameter_blocks);
248
249 // Add a residual block by providing a pointer to the parameter block array
250 // and the number of parameter blocks.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800251 ResidualBlockId AddResidualBlock(CostFunction* cost_function,
252 LossFunction* loss_function,
253 double* const* const parameter_blocks,
254 int num_parameter_blocks);
Austin Schuh70cc9552019-01-21 19:46:48 -0800255
Austin Schuh3de38b02024-06-25 18:25:10 -0700256 // Add a parameter block with appropriate size to the problem. Repeated calls
257 // with the same arguments are ignored. Repeated calls with the same double
258 // pointer but a different size will result in a crash.
Austin Schuh70cc9552019-01-21 19:46:48 -0800259 void AddParameterBlock(double* values, int size);
260
Austin Schuh3de38b02024-06-25 18:25:10 -0700261 // Add a parameter block with appropriate size and Manifold to the
262 // problem. It is okay for manifold to be nullptr.
Austin Schuh70cc9552019-01-21 19:46:48 -0800263 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700264 // Repeated calls with the same arguments are ignored. Repeated calls
265 // with the same double pointer but a different size results in a crash
266 // (unless Solver::Options::disable_all_safety_checks is set to true).
267 //
268 // Repeated calls with the same double pointer and size but different Manifold
269 // is equivalent to calling SetManifold(manifold), i.e., any previously
270 // associated Manifold object will be replaced with the manifold.
271 void AddParameterBlock(double* values, int size, Manifold* manifold);
272
273 // Remove a parameter block from the problem. The Manifold of the parameter
274 // block, if it exists, will persist until the deletion of the problem
275 // (similar to cost/loss functions in residual block removal). Any residual
276 // blocks that depend on the parameter are also removed, as described above
277 // in RemoveResidualBlock().
278 //
279 // If Problem::Options::enable_fast_removal is true, then the removal is fast
280 // (almost constant time). Otherwise, removing a parameter block will incur a
281 // scan of the entire Problem object.
Austin Schuh70cc9552019-01-21 19:46:48 -0800282 //
283 // WARNING: Removing a residual or parameter block will destroy the implicit
284 // ordering, rendering the jacobian or residuals returned from the solver
285 // uninterpretable. If you depend on the evaluated jacobian, do not use
286 // remove! This may change in a future release.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800287 void RemoveParameterBlock(const double* values);
Austin Schuh70cc9552019-01-21 19:46:48 -0800288
289 // Remove a residual block from the problem. Any parameters that the residual
290 // block depends on are not removed. The cost and loss functions for the
291 // residual block will not get deleted immediately; won't happen until the
292 // problem itself is deleted.
293 //
294 // WARNING: Removing a residual or parameter block will destroy the implicit
295 // ordering, rendering the jacobian or residuals returned from the solver
296 // uninterpretable. If you depend on the evaluated jacobian, do not use
297 // remove! This may change in a future release.
298 void RemoveResidualBlock(ResidualBlockId residual_block);
299
300 // Hold the indicated parameter block constant during optimization.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800301 void SetParameterBlockConstant(const double* values);
Austin Schuh70cc9552019-01-21 19:46:48 -0800302
303 // Allow the indicated parameter block to vary during optimization.
304 void SetParameterBlockVariable(double* values);
305
Austin Schuh3de38b02024-06-25 18:25:10 -0700306 // Returns true if a parameter block is set constant, and false otherwise. A
307 // parameter block may be set constant in two ways: either by calling
308 // SetParameterBlockConstant or by associating a Manifold with a zero
309 // dimensional tangent space with it.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800310 bool IsParameterBlockConstant(const double* values) const;
Austin Schuh70cc9552019-01-21 19:46:48 -0800311
Austin Schuh3de38b02024-06-25 18:25:10 -0700312 // Set the Manifold for the parameter block. Calling SetManifold with nullptr
313 // will clear any previously set Manifold for the parameter block.
314 //
315 // Repeated calls will result in any previously associated Manifold object to
316 // be replaced with the manifold.
317 //
318 // The manifold is owned by the Problem by default (See Problem::Options to
319 // override this behaviour).
320 //
321 // It is acceptable to set the same Manifold for multiple parameter blocks.
322 void SetManifold(double* values, Manifold* manifold);
Austin Schuh70cc9552019-01-21 19:46:48 -0800323
Austin Schuh3de38b02024-06-25 18:25:10 -0700324 // Get the Manifold object associated with this parameter block.
325 //
326 // If there is no Manifold object associated then nullptr is returned.
327 const Manifold* GetManifold(const double* values) const;
328
329 // Returns true if a Manifold is associated with this parameter block, false
330 // otherwise.
331 bool HasManifold(const double* values) const;
Austin Schuh70cc9552019-01-21 19:46:48 -0800332
333 // Set the lower/upper bound for the parameter at position "index".
334 void SetParameterLowerBound(double* values, int index, double lower_bound);
335 void SetParameterUpperBound(double* values, int index, double upper_bound);
336
Austin Schuh3de38b02024-06-25 18:25:10 -0700337 // Get the lower/upper bound for the parameter at position "index". If the
338 // parameter is not bounded by the user, then its lower bound is
339 // -std::numeric_limits<double>::max() and upper bound is
340 // std::numeric_limits<double>::max().
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800341 double GetParameterLowerBound(const double* values, int index) const;
342 double GetParameterUpperBound(const double* values, int index) const;
Austin Schuh70cc9552019-01-21 19:46:48 -0800343
344 // Number of parameter blocks in the problem. Always equals
345 // parameter_blocks().size() and parameter_block_sizes().size().
346 int NumParameterBlocks() const;
347
Austin Schuh3de38b02024-06-25 18:25:10 -0700348 // The size of the parameter vector obtained by summing over the sizes of all
349 // the parameter blocks.
Austin Schuh70cc9552019-01-21 19:46:48 -0800350 int NumParameters() const;
351
352 // Number of residual blocks in the problem. Always equals
353 // residual_blocks().size().
354 int NumResidualBlocks() const;
355
Austin Schuh3de38b02024-06-25 18:25:10 -0700356 // The size of the residual vector obtained by summing over the sizes of all
357 // of the residual blocks.
Austin Schuh70cc9552019-01-21 19:46:48 -0800358 int NumResiduals() const;
359
360 // The size of the parameter block.
361 int ParameterBlockSize(const double* values) const;
362
Austin Schuh3de38b02024-06-25 18:25:10 -0700363 // The dimension of the tangent space of the Manifold for the parameter block.
364 // If there is no Manifold associated with this parameter block, then
365 // ParameterBlockTangentSize = ParameterBlockSize.
366 int ParameterBlockTangentSize(const double* values) const;
Austin Schuh70cc9552019-01-21 19:46:48 -0800367
368 // Is the given parameter block present in this problem or not?
369 bool HasParameterBlock(const double* values) const;
370
Austin Schuh3de38b02024-06-25 18:25:10 -0700371 // Fills the passed parameter_blocks vector with pointers to the parameter
372 // blocks currently in the problem. After this call, parameter_block.size() ==
373 // NumParameterBlocks.
Austin Schuh70cc9552019-01-21 19:46:48 -0800374 void GetParameterBlocks(std::vector<double*>* parameter_blocks) const;
375
Austin Schuh3de38b02024-06-25 18:25:10 -0700376 // Fills the passed residual_blocks vector with pointers to the residual
377 // blocks currently in the problem. After this call, residual_blocks.size() ==
378 // NumResidualBlocks.
Austin Schuh70cc9552019-01-21 19:46:48 -0800379 void GetResidualBlocks(std::vector<ResidualBlockId>* residual_blocks) const;
380
381 // Get all the parameter blocks that depend on the given residual block.
382 void GetParameterBlocksForResidualBlock(
383 const ResidualBlockId residual_block,
384 std::vector<double*>* parameter_blocks) const;
385
386 // Get the CostFunction for the given residual block.
387 const CostFunction* GetCostFunctionForResidualBlock(
388 const ResidualBlockId residual_block) const;
389
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800390 // Get the LossFunction for the given residual block. Returns nullptr
Austin Schuh70cc9552019-01-21 19:46:48 -0800391 // if no loss function is associated with this residual block.
392 const LossFunction* GetLossFunctionForResidualBlock(
393 const ResidualBlockId residual_block) const;
394
395 // Get all the residual blocks that depend on the given parameter block.
396 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700397 // If Problem::Options::enable_fast_removal is true, then getting the residual
398 // blocks is fast and depends only on the number of residual
399 // blocks. Otherwise, getting the residual blocks for a parameter block will
400 // incur a scan of the entire Problem object.
Austin Schuh70cc9552019-01-21 19:46:48 -0800401 void GetResidualBlocksForParameterBlock(
402 const double* values,
403 std::vector<ResidualBlockId>* residual_blocks) const;
404
405 // Options struct to control Problem::Evaluate.
406 struct EvaluateOptions {
407 // The set of parameter blocks for which evaluation should be
Austin Schuh3de38b02024-06-25 18:25:10 -0700408 // performed. This vector determines the order that parameter blocks occur
409 // in the gradient vector and in the columns of the jacobian matrix. If
410 // parameter_blocks is empty, then it is assumed to be equal to vector
411 // containing ALL the parameter blocks. Generally speaking the parameter
412 // blocks will occur in the order in which they were added to the
413 // problem. But, this may change if the user removes any parameter blocks
414 // from the problem.
Austin Schuh70cc9552019-01-21 19:46:48 -0800415 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700416 // NOTE: This vector should contain the same pointers as the ones used to
417 // add parameter blocks to the Problem. These parameter block should NOT
418 // point to new memory locations. Bad things will happen otherwise.
Austin Schuh70cc9552019-01-21 19:46:48 -0800419 std::vector<double*> parameter_blocks;
420
Austin Schuh3de38b02024-06-25 18:25:10 -0700421 // The set of residual blocks to evaluate. This vector determines the order
422 // in which the residuals occur, and how the rows of the jacobian are
423 // ordered. If residual_blocks is empty, then it is assumed to be equal to
424 // the vector containing ALL the residual blocks. Generally speaking the
425 // residual blocks will occur in the order in which they were added to the
426 // problem. But, this may change if the user removes any residual blocks
427 // from the problem.
Austin Schuh70cc9552019-01-21 19:46:48 -0800428 std::vector<ResidualBlockId> residual_blocks;
429
430 // Even though the residual blocks in the problem may contain loss
Austin Schuh3de38b02024-06-25 18:25:10 -0700431 // functions, setting apply_loss_function to false will turn off the
432 // application of the loss function to the output of the cost function. This
433 // is of use for example if the user wishes to analyse the solution quality
434 // by studying the distribution of residuals before and after the solve.
Austin Schuh70cc9552019-01-21 19:46:48 -0800435 bool apply_loss_function = true;
436
437 int num_threads = 1;
438 };
439
Austin Schuh3de38b02024-06-25 18:25:10 -0700440 // Evaluate Problem. Any of the output pointers can be nullptr. Which residual
441 // blocks and parameter blocks are used is controlled by the EvaluateOptions
442 // struct above.
Austin Schuh70cc9552019-01-21 19:46:48 -0800443 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700444 // Note 1: The evaluation will use the values stored in the memory locations
445 // pointed to by the parameter block pointers used at the time of the
446 // construction of the problem. i.e.,
Austin Schuh70cc9552019-01-21 19:46:48 -0800447 //
448 // Problem problem;
449 // double x = 1;
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800450 // problem.AddResidualBlock(new MyCostFunction, nullptr, &x);
Austin Schuh70cc9552019-01-21 19:46:48 -0800451 //
452 // double cost = 0.0;
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800453 // problem.Evaluate(Problem::EvaluateOptions(), &cost,
454 // nullptr, nullptr, nullptr);
Austin Schuh70cc9552019-01-21 19:46:48 -0800455 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700456 // The cost is evaluated at x = 1. If you wish to evaluate the problem at x =
457 // 2, then
Austin Schuh70cc9552019-01-21 19:46:48 -0800458 //
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800459 // x = 2;
460 // problem.Evaluate(Problem::EvaluateOptions(), &cost,
461 // nullptr, nullptr, nullptr);
Austin Schuh70cc9552019-01-21 19:46:48 -0800462 //
463 // is the way to do so.
464 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700465 // Note 2: If no Manifolds are used, then the size of the gradient vector (and
466 // the number of columns in the jacobian) is the sum of the sizes of all the
467 // parameter blocks. If a parameter block has a Manifold, then it contributes
468 // "TangentSize" entries to the gradient vector (and the number of columns in
469 // the jacobian).
Austin Schuh70cc9552019-01-21 19:46:48 -0800470 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700471 // Note 3: This function cannot be called while the problem is being solved,
472 // for example it cannot be called from an IterationCallback at the end of an
473 // iteration during a solve.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800474 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700475 // Note 4: If an EvaluationCallback is associated with the problem, then its
476 // PrepareForEvaluation method will be called every time this method is called
477 // with new_point = true.
Austin Schuh70cc9552019-01-21 19:46:48 -0800478 bool Evaluate(const EvaluateOptions& options,
479 double* cost,
480 std::vector<double>* residuals,
481 std::vector<double>* gradient,
482 CRSMatrix* jacobian);
483
Austin Schuh3de38b02024-06-25 18:25:10 -0700484 // Evaluates the residual block, storing the scalar cost in *cost, the
485 // residual components in *residuals, and the jacobians between the parameters
486 // and residuals in jacobians[i], in row-major order.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800487 //
488 // If residuals is nullptr, the residuals are not computed.
489 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700490 // If jacobians is nullptr, no Jacobians are computed. If jacobians[i] is
491 // nullptr, then the Jacobian for that parameter block is not computed.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800492 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700493 // It is not okay to request the Jacobian w.r.t a parameter block that is
494 // constant.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800495 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700496 // The return value indicates the success or failure. Even if the function
497 // returns false, the caller should expect the output memory locations to have
498 // been modified.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800499 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700500 // The returned cost and jacobians have had robustification and Manifold
501 // applied already; for example, the jacobian for a 4-dimensional quaternion
502 // parameter using the "QuaternionParameterization" is num_residuals by 3
503 // instead of num_residuals by 4.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800504 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700505 // apply_loss_function as the name implies allows the user to switch the
506 // application of the loss function on and off.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800507 //
508 // If an EvaluationCallback is associated with the problem, then its
Austin Schuh3de38b02024-06-25 18:25:10 -0700509 // PrepareForEvaluation method will be called every time this method is called
510 // with new_point = true. This conservatively assumes that the user may have
511 // changed the parameter values since the previous call to evaluate / solve.
512 // For improved efficiency, and only if you know that the parameter values
513 // have not changed between calls, see
514 // EvaluateResidualBlockAssumingParametersUnchanged().
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800515 bool EvaluateResidualBlock(ResidualBlockId residual_block_id,
516 bool apply_loss_function,
517 double* cost,
518 double* residuals,
519 double** jacobians) const;
520
Austin Schuh3de38b02024-06-25 18:25:10 -0700521 // Same as EvaluateResidualBlock except that if an EvaluationCallback is
522 // associated with the problem, then its PrepareForEvaluation method will be
523 // called every time this method is called with new_point = false.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800524 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700525 // This means, if an EvaluationCallback is associated with the problem then it
526 // is the user's responsibility to call PrepareForEvaluation before calling
527 // this method if necessary, i.e. iff the parameter values have been changed
528 // since the last call to evaluate / solve.'
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800529 //
Austin Schuh3de38b02024-06-25 18:25:10 -0700530 // This is because, as the name implies, we assume that the parameter blocks
531 // did not change since the last time PrepareForEvaluation was called (via
532 // Solve, Evaluate or EvaluateResidualBlock).
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800533 bool EvaluateResidualBlockAssumingParametersUnchanged(
534 ResidualBlockId residual_block_id,
535 bool apply_loss_function,
536 double* cost,
537 double* residuals,
538 double** jacobians) const;
539
Austin Schuh3de38b02024-06-25 18:25:10 -0700540 // Returns reference to the options with which the Problem was constructed.
541 const Options& options() const;
542
543 // Returns pointer to Problem implementation
544 internal::ProblemImpl* mutable_impl();
545
Austin Schuh70cc9552019-01-21 19:46:48 -0800546 private:
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800547 std::unique_ptr<internal::ProblemImpl> impl_;
Austin Schuh70cc9552019-01-21 19:46:48 -0800548};
549
550} // namespace ceres
551
552#include "ceres/internal/reenable_warnings.h"
553
554#endif // CERES_PUBLIC_PROBLEM_H_