variadic_evaluate.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Ceres Solver - A fast non-linear least squares minimizer
  2. // Copyright 2023 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. // mierle@gmail.com (Keir Mierle)
  31. // jodebo_beck@gmx.de (Johannes Beck)
  32. #ifndef CERES_PUBLIC_INTERNAL_VARIADIC_EVALUATE_H_
  33. #define CERES_PUBLIC_INTERNAL_VARIADIC_EVALUATE_H_
  34. #include <cstddef>
  35. #include <type_traits>
  36. #include <utility>
  37. #include "ceres/cost_function.h"
  38. #include "ceres/internal/parameter_dims.h"
  39. namespace ceres::internal {
  40. // For fixed size cost functors
  41. template <typename Functor, typename T, int... Indices>
  42. inline bool VariadicEvaluateImpl(const Functor& functor,
  43. T const* const* input,
  44. T* output,
  45. std::false_type /*is_dynamic*/,
  46. std::integer_sequence<int, Indices...>) {
  47. static_assert(sizeof...(Indices) > 0,
  48. "Invalid number of parameter blocks. At least one parameter "
  49. "block must be specified.");
  50. return functor(input[Indices]..., output);
  51. }
  52. // For dynamic sized cost functors
  53. template <typename Functor, typename T>
  54. inline bool VariadicEvaluateImpl(const Functor& functor,
  55. T const* const* input,
  56. T* output,
  57. std::true_type /*is_dynamic*/,
  58. std::integer_sequence<int>) {
  59. return functor(input, output);
  60. }
  61. // For ceres cost functors (not ceres::CostFunction)
  62. template <typename ParameterDims, typename Functor, typename T>
  63. inline bool VariadicEvaluateImpl(const Functor& functor,
  64. T const* const* input,
  65. T* output,
  66. const void* /* NOT USED */) {
  67. using ParameterBlockIndices =
  68. std::make_integer_sequence<int, ParameterDims::kNumParameterBlocks>;
  69. using IsDynamic = std::integral_constant<bool, ParameterDims::kIsDynamic>;
  70. return VariadicEvaluateImpl(
  71. functor, input, output, IsDynamic(), ParameterBlockIndices());
  72. }
  73. // For ceres::CostFunction
  74. template <typename ParameterDims, typename Functor, typename T>
  75. inline bool VariadicEvaluateImpl(const Functor& functor,
  76. T const* const* input,
  77. T* output,
  78. const CostFunction* /* NOT USED */) {
  79. return functor.Evaluate(input, output, nullptr);
  80. }
  81. // Variadic evaluate is a helper function to evaluate ceres cost function or
  82. // functors using an input, output and the parameter dimensions. There are
  83. // several ways different possibilities:
  84. // 1) If the passed functor is a 'ceres::CostFunction' its evaluate method is
  85. // called.
  86. // 2) If the functor is not a 'ceres::CostFunction' and the specified parameter
  87. // dims is dynamic, the functor must have the following signature
  88. // 'bool(T const* const* input, T* output)'.
  89. // 3) If the functor is not a 'ceres::CostFunction' and the specified parameter
  90. // dims is not dynamic, the input is expanded by using the number of parameter
  91. // blocks. The signature of the functor must have the following signature
  92. // 'bool()(const T* i_1, const T* i_2, ... const T* i_n, T* output)'.
  93. template <typename ParameterDims, typename Functor, typename T>
  94. inline bool VariadicEvaluate(const Functor& functor,
  95. T const* const* input,
  96. T* output) {
  97. return VariadicEvaluateImpl<ParameterDims>(functor, input, output, &functor);
  98. }
  99. // When differentiating dynamically sized CostFunctions, VariadicEvaluate
  100. // expects a functor with the signature:
  101. //
  102. // bool operator()(double const* const* parameters, double* cost) const
  103. //
  104. // However for NumericDiffFirstOrderFunction, the functor has the signature
  105. //
  106. // bool operator()(double const* parameters, double* cost) const
  107. //
  108. // This thin wrapper adapts the latter to the former.
  109. template <typename Functor>
  110. class FirstOrderFunctorAdapter {
  111. public:
  112. explicit FirstOrderFunctorAdapter(const Functor& functor)
  113. : functor_(functor) {}
  114. bool operator()(double const* const* parameters, double* cost) const {
  115. return functor_(*parameters, cost);
  116. }
  117. private:
  118. const Functor& functor_;
  119. };
  120. } // namespace ceres::internal
  121. #endif // CERES_PUBLIC_INTERNAL_VARIADIC_EVALUATE_H_