blob: 00c1786c3eae1a3e8cc285f75a44daa6c9783aa9 [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#include "ceres/problem.h"
33
Austin Schuh3de38b02024-06-25 18:25:10 -070034#include <memory>
Austin Schuh70cc9552019-01-21 19:46:48 -080035#include <vector>
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080036
Austin Schuh70cc9552019-01-21 19:46:48 -080037#include "ceres/crs_matrix.h"
38#include "ceres/problem_impl.h"
39
40namespace ceres {
41
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080042Problem::Problem() : impl_(new internal::ProblemImpl) {}
Austin Schuh70cc9552019-01-21 19:46:48 -080043Problem::Problem(const Problem::Options& options)
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080044 : impl_(new internal::ProblemImpl(options)) {}
45// Not inline defaulted in declaration due to use of std::unique_ptr.
46Problem::Problem(Problem&&) = default;
47Problem& Problem::operator=(Problem&&) = default;
Austin Schuh3de38b02024-06-25 18:25:10 -070048Problem::~Problem() = default;
Austin Schuh70cc9552019-01-21 19:46:48 -080049
50ResidualBlockId Problem::AddResidualBlock(
51 CostFunction* cost_function,
52 LossFunction* loss_function,
Austin Schuh3de38b02024-06-25 18:25:10 -070053 const std::vector<double*>& parameter_blocks) {
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080054 return impl_->AddResidualBlock(cost_function,
55 loss_function,
56 parameter_blocks.data(),
57 static_cast<int>(parameter_blocks.size()));
Austin Schuh70cc9552019-01-21 19:46:48 -080058}
59
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080060ResidualBlockId Problem::AddResidualBlock(CostFunction* cost_function,
61 LossFunction* loss_function,
62 double* const* const parameter_blocks,
63 int num_parameter_blocks) {
64 return impl_->AddResidualBlock(
65 cost_function, loss_function, parameter_blocks, num_parameter_blocks);
Austin Schuh70cc9552019-01-21 19:46:48 -080066}
67
68void Problem::AddParameterBlock(double* values, int size) {
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080069 impl_->AddParameterBlock(values, size);
Austin Schuh70cc9552019-01-21 19:46:48 -080070}
71
Austin Schuh3de38b02024-06-25 18:25:10 -070072void Problem::AddParameterBlock(double* values, int size, Manifold* manifold) {
73 impl_->AddParameterBlock(values, size, manifold);
Austin Schuh70cc9552019-01-21 19:46:48 -080074}
75
76void Problem::RemoveResidualBlock(ResidualBlockId residual_block) {
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080077 impl_->RemoveResidualBlock(residual_block);
Austin Schuh70cc9552019-01-21 19:46:48 -080078}
79
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080080void Problem::RemoveParameterBlock(const double* values) {
81 impl_->RemoveParameterBlock(values);
Austin Schuh70cc9552019-01-21 19:46:48 -080082}
83
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080084void Problem::SetParameterBlockConstant(const double* values) {
85 impl_->SetParameterBlockConstant(values);
Austin Schuh70cc9552019-01-21 19:46:48 -080086}
87
88void Problem::SetParameterBlockVariable(double* values) {
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080089 impl_->SetParameterBlockVariable(values);
Austin Schuh70cc9552019-01-21 19:46:48 -080090}
91
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080092bool Problem::IsParameterBlockConstant(const double* values) const {
93 return impl_->IsParameterBlockConstant(values);
Austin Schuh70cc9552019-01-21 19:46:48 -080094}
95
Austin Schuh3de38b02024-06-25 18:25:10 -070096void Problem::SetManifold(double* values, Manifold* manifold) {
97 impl_->SetManifold(values, manifold);
Austin Schuh70cc9552019-01-21 19:46:48 -080098}
99
Austin Schuh3de38b02024-06-25 18:25:10 -0700100const Manifold* Problem::GetManifold(const double* values) const {
101 return impl_->GetManifold(values);
102}
103
104bool Problem::HasManifold(const double* values) const {
105 return impl_->HasManifold(values);
Austin Schuh70cc9552019-01-21 19:46:48 -0800106}
107
108void Problem::SetParameterLowerBound(double* values,
109 int index,
110 double lower_bound) {
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800111 impl_->SetParameterLowerBound(values, index, lower_bound);
Austin Schuh70cc9552019-01-21 19:46:48 -0800112}
113
114void Problem::SetParameterUpperBound(double* values,
115 int index,
116 double upper_bound) {
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800117 impl_->SetParameterUpperBound(values, index, upper_bound);
Austin Schuh70cc9552019-01-21 19:46:48 -0800118}
119
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800120double Problem::GetParameterUpperBound(const double* values, int index) const {
121 return impl_->GetParameterUpperBound(values, index);
Austin Schuh70cc9552019-01-21 19:46:48 -0800122}
123
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800124double Problem::GetParameterLowerBound(const double* values, int index) const {
125 return impl_->GetParameterLowerBound(values, index);
Austin Schuh70cc9552019-01-21 19:46:48 -0800126}
127
128bool Problem::Evaluate(const EvaluateOptions& evaluate_options,
129 double* cost,
Austin Schuh3de38b02024-06-25 18:25:10 -0700130 std::vector<double>* residuals,
131 std::vector<double>* gradient,
Austin Schuh70cc9552019-01-21 19:46:48 -0800132 CRSMatrix* jacobian) {
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800133 return impl_->Evaluate(evaluate_options, cost, residuals, gradient, jacobian);
Austin Schuh70cc9552019-01-21 19:46:48 -0800134}
135
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800136bool Problem::EvaluateResidualBlock(ResidualBlockId residual_block_id,
137 bool apply_loss_function,
138 double* cost,
139 double* residuals,
140 double** jacobians) const {
141 return impl_->EvaluateResidualBlock(residual_block_id,
142 apply_loss_function,
143 /* new_point = */ true,
144 cost,
145 residuals,
146 jacobians);
Austin Schuh70cc9552019-01-21 19:46:48 -0800147}
148
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800149bool Problem::EvaluateResidualBlockAssumingParametersUnchanged(
150 ResidualBlockId residual_block_id,
151 bool apply_loss_function,
152 double* cost,
153 double* residuals,
154 double** jacobians) const {
155 return impl_->EvaluateResidualBlock(residual_block_id,
156 apply_loss_function,
157 /* new_point = */ false,
158 cost,
159 residuals,
160 jacobians);
Austin Schuh70cc9552019-01-21 19:46:48 -0800161}
162
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800163int Problem::NumParameterBlocks() const { return impl_->NumParameterBlocks(); }
Austin Schuh70cc9552019-01-21 19:46:48 -0800164
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800165int Problem::NumParameters() const { return impl_->NumParameters(); }
166
167int Problem::NumResidualBlocks() const { return impl_->NumResidualBlocks(); }
168
169int Problem::NumResiduals() const { return impl_->NumResiduals(); }
Austin Schuh70cc9552019-01-21 19:46:48 -0800170
Austin Schuh3de38b02024-06-25 18:25:10 -0700171int Problem::ParameterBlockSize(const double* values) const {
172 return impl_->ParameterBlockSize(values);
Austin Schuh70cc9552019-01-21 19:46:48 -0800173}
174
Austin Schuh3de38b02024-06-25 18:25:10 -0700175int Problem::ParameterBlockTangentSize(const double* values) const {
176 return impl_->ParameterBlockTangentSize(values);
Austin Schuh70cc9552019-01-21 19:46:48 -0800177}
178
179bool Problem::HasParameterBlock(const double* values) const {
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800180 return impl_->HasParameterBlock(values);
Austin Schuh70cc9552019-01-21 19:46:48 -0800181}
182
Austin Schuh3de38b02024-06-25 18:25:10 -0700183void Problem::GetParameterBlocks(std::vector<double*>* parameter_blocks) const {
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800184 impl_->GetParameterBlocks(parameter_blocks);
Austin Schuh70cc9552019-01-21 19:46:48 -0800185}
186
187void Problem::GetResidualBlocks(
Austin Schuh3de38b02024-06-25 18:25:10 -0700188 std::vector<ResidualBlockId>* residual_blocks) const {
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800189 impl_->GetResidualBlocks(residual_blocks);
Austin Schuh70cc9552019-01-21 19:46:48 -0800190}
191
192void Problem::GetParameterBlocksForResidualBlock(
193 const ResidualBlockId residual_block,
Austin Schuh3de38b02024-06-25 18:25:10 -0700194 std::vector<double*>* parameter_blocks) const {
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800195 impl_->GetParameterBlocksForResidualBlock(residual_block, parameter_blocks);
Austin Schuh70cc9552019-01-21 19:46:48 -0800196}
197
198const CostFunction* Problem::GetCostFunctionForResidualBlock(
199 const ResidualBlockId residual_block) const {
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800200 return impl_->GetCostFunctionForResidualBlock(residual_block);
Austin Schuh70cc9552019-01-21 19:46:48 -0800201}
202
203const LossFunction* Problem::GetLossFunctionForResidualBlock(
204 const ResidualBlockId residual_block) const {
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800205 return impl_->GetLossFunctionForResidualBlock(residual_block);
Austin Schuh70cc9552019-01-21 19:46:48 -0800206}
207
208void Problem::GetResidualBlocksForParameterBlock(
Austin Schuh3de38b02024-06-25 18:25:10 -0700209 const double* values, std::vector<ResidualBlockId>* residual_blocks) const {
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800210 impl_->GetResidualBlocksForParameterBlock(values, residual_blocks);
Austin Schuh70cc9552019-01-21 19:46:48 -0800211}
212
Austin Schuh3de38b02024-06-25 18:25:10 -0700213const Problem::Options& Problem::options() const { return impl_->options(); }
214
215internal::ProblemImpl* Problem::mutable_impl() { return impl_.get(); }
216
Austin Schuh70cc9552019-01-21 19:46:48 -0800217} // namespace ceres