problem.cc 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // Ceres Solver - A fast non-linear least squares minimizer
  2. // Copyright 2021 Google Inc. All rights reserved.
  3. // 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. #include "ceres/problem.h"
  32. #include <memory>
  33. #include <vector>
  34. #include "ceres/crs_matrix.h"
  35. #include "ceres/problem_impl.h"
  36. namespace ceres {
  37. Problem::Problem() : impl_(new internal::ProblemImpl) {}
  38. Problem::Problem(const Problem::Options& options)
  39. : impl_(new internal::ProblemImpl(options)) {}
  40. // Not inline defaulted in declaration due to use of std::unique_ptr.
  41. Problem::Problem(Problem&&) = default;
  42. Problem& Problem::operator=(Problem&&) = default;
  43. Problem::~Problem() = default;
  44. ResidualBlockId Problem::AddResidualBlock(
  45. CostFunction* cost_function,
  46. LossFunction* loss_function,
  47. const std::vector<double*>& parameter_blocks) {
  48. return impl_->AddResidualBlock(cost_function,
  49. loss_function,
  50. parameter_blocks.data(),
  51. static_cast<int>(parameter_blocks.size()));
  52. }
  53. ResidualBlockId Problem::AddResidualBlock(CostFunction* cost_function,
  54. LossFunction* loss_function,
  55. double* const* const parameter_blocks,
  56. int num_parameter_blocks) {
  57. return impl_->AddResidualBlock(
  58. cost_function, loss_function, parameter_blocks, num_parameter_blocks);
  59. }
  60. void Problem::AddParameterBlock(double* values, int size) {
  61. impl_->AddParameterBlock(values, size);
  62. }
  63. void Problem::AddParameterBlock(double* values, int size, Manifold* manifold) {
  64. impl_->AddParameterBlock(values, size, manifold);
  65. }
  66. void Problem::RemoveResidualBlock(ResidualBlockId residual_block) {
  67. impl_->RemoveResidualBlock(residual_block);
  68. }
  69. void Problem::RemoveParameterBlock(const double* values) {
  70. impl_->RemoveParameterBlock(values);
  71. }
  72. void Problem::SetParameterBlockConstant(const double* values) {
  73. impl_->SetParameterBlockConstant(values);
  74. }
  75. void Problem::SetParameterBlockVariable(double* values) {
  76. impl_->SetParameterBlockVariable(values);
  77. }
  78. bool Problem::IsParameterBlockConstant(const double* values) const {
  79. return impl_->IsParameterBlockConstant(values);
  80. }
  81. void Problem::SetManifold(double* values, Manifold* manifold) {
  82. impl_->SetManifold(values, manifold);
  83. }
  84. const Manifold* Problem::GetManifold(const double* values) const {
  85. return impl_->GetManifold(values);
  86. }
  87. bool Problem::HasManifold(const double* values) const {
  88. return impl_->HasManifold(values);
  89. }
  90. void Problem::SetParameterLowerBound(double* values,
  91. int index,
  92. double lower_bound) {
  93. impl_->SetParameterLowerBound(values, index, lower_bound);
  94. }
  95. void Problem::SetParameterUpperBound(double* values,
  96. int index,
  97. double upper_bound) {
  98. impl_->SetParameterUpperBound(values, index, upper_bound);
  99. }
  100. double Problem::GetParameterUpperBound(const double* values, int index) const {
  101. return impl_->GetParameterUpperBound(values, index);
  102. }
  103. double Problem::GetParameterLowerBound(const double* values, int index) const {
  104. return impl_->GetParameterLowerBound(values, index);
  105. }
  106. bool Problem::Evaluate(const EvaluateOptions& evaluate_options,
  107. double* cost,
  108. std::vector<double>* residuals,
  109. std::vector<double>* gradient,
  110. CRSMatrix* jacobian) {
  111. return impl_->Evaluate(evaluate_options, cost, residuals, gradient, jacobian);
  112. }
  113. bool Problem::EvaluateResidualBlock(ResidualBlockId residual_block_id,
  114. bool apply_loss_function,
  115. double* cost,
  116. double* residuals,
  117. double** jacobians) const {
  118. return impl_->EvaluateResidualBlock(residual_block_id,
  119. apply_loss_function,
  120. /* new_point = */ true,
  121. cost,
  122. residuals,
  123. jacobians);
  124. }
  125. bool Problem::EvaluateResidualBlockAssumingParametersUnchanged(
  126. ResidualBlockId residual_block_id,
  127. bool apply_loss_function,
  128. double* cost,
  129. double* residuals,
  130. double** jacobians) const {
  131. return impl_->EvaluateResidualBlock(residual_block_id,
  132. apply_loss_function,
  133. /* new_point = */ false,
  134. cost,
  135. residuals,
  136. jacobians);
  137. }
  138. int Problem::NumParameterBlocks() const { return impl_->NumParameterBlocks(); }
  139. int Problem::NumParameters() const { return impl_->NumParameters(); }
  140. int Problem::NumResidualBlocks() const { return impl_->NumResidualBlocks(); }
  141. int Problem::NumResiduals() const { return impl_->NumResiduals(); }
  142. int Problem::ParameterBlockSize(const double* values) const {
  143. return impl_->ParameterBlockSize(values);
  144. }
  145. int Problem::ParameterBlockTangentSize(const double* values) const {
  146. return impl_->ParameterBlockTangentSize(values);
  147. }
  148. bool Problem::HasParameterBlock(const double* values) const {
  149. return impl_->HasParameterBlock(values);
  150. }
  151. void Problem::GetParameterBlocks(std::vector<double*>* parameter_blocks) const {
  152. impl_->GetParameterBlocks(parameter_blocks);
  153. }
  154. void Problem::GetResidualBlocks(
  155. std::vector<ResidualBlockId>* residual_blocks) const {
  156. impl_->GetResidualBlocks(residual_blocks);
  157. }
  158. void Problem::GetParameterBlocksForResidualBlock(
  159. const ResidualBlockId residual_block,
  160. std::vector<double*>* parameter_blocks) const {
  161. impl_->GetParameterBlocksForResidualBlock(residual_block, parameter_blocks);
  162. }
  163. const CostFunction* Problem::GetCostFunctionForResidualBlock(
  164. const ResidualBlockId residual_block) const {
  165. return impl_->GetCostFunctionForResidualBlock(residual_block);
  166. }
  167. const LossFunction* Problem::GetLossFunctionForResidualBlock(
  168. const ResidualBlockId residual_block) const {
  169. return impl_->GetLossFunctionForResidualBlock(residual_block);
  170. }
  171. void Problem::GetResidualBlocksForParameterBlock(
  172. const double* values, std::vector<ResidualBlockId>* residual_blocks) const {
  173. impl_->GetResidualBlocksForParameterBlock(values, residual_blocks);
  174. }
  175. const Problem::Options& Problem::options() const { return impl_->options(); }
  176. internal::ProblemImpl* Problem::mutable_impl() { return impl_.get(); }
  177. } // namespace ceres