tiny_solver_test.cc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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: mierle@gmail.com (Keir Mierle)
  30. #include "ceres/tiny_solver.h"
  31. #include <algorithm>
  32. #include <cmath>
  33. #include "ceres/tiny_solver_test_util.h"
  34. #include "gtest/gtest.h"
  35. namespace ceres {
  36. using Vec2 = Eigen::Matrix<double, 2, 1>;
  37. using Vec3 = Eigen::Matrix<double, 3, 1>;
  38. using VecX = Eigen::VectorXd;
  39. class ExampleStatic {
  40. public:
  41. using Scalar = double;
  42. enum {
  43. // Can also be Eigen::Dynamic.
  44. NUM_RESIDUALS = 2,
  45. NUM_PARAMETERS = 3,
  46. };
  47. bool operator()(const double* parameters,
  48. double* residuals,
  49. double* jacobian) const {
  50. return EvaluateResidualsAndJacobians(parameters, residuals, jacobian);
  51. }
  52. };
  53. class ExampleParametersDynamic {
  54. public:
  55. using Scalar = double;
  56. enum {
  57. NUM_RESIDUALS = 2,
  58. NUM_PARAMETERS = Eigen::Dynamic,
  59. };
  60. int NumParameters() const { return 3; }
  61. bool operator()(const double* parameters,
  62. double* residuals,
  63. double* jacobian) const {
  64. return EvaluateResidualsAndJacobians(parameters, residuals, jacobian);
  65. }
  66. };
  67. class ExampleResidualsDynamic {
  68. public:
  69. using Scalar = double;
  70. enum {
  71. NUM_RESIDUALS = Eigen::Dynamic,
  72. NUM_PARAMETERS = 3,
  73. };
  74. int NumResiduals() const { return 2; }
  75. bool operator()(const double* parameters,
  76. double* residuals,
  77. double* jacobian) const {
  78. return EvaluateResidualsAndJacobians(parameters, residuals, jacobian);
  79. }
  80. };
  81. class ExampleAllDynamic {
  82. public:
  83. using Scalar = double;
  84. enum {
  85. NUM_RESIDUALS = Eigen::Dynamic,
  86. NUM_PARAMETERS = Eigen::Dynamic,
  87. };
  88. int NumResiduals() const { return 2; }
  89. int NumParameters() const { return 3; }
  90. bool operator()(const double* parameters,
  91. double* residuals,
  92. double* jacobian) const {
  93. return EvaluateResidualsAndJacobians(parameters, residuals, jacobian);
  94. }
  95. };
  96. template <typename Function, typename Vector>
  97. void TestHelper(const Function& f, const Vector& x0) {
  98. Vector x = x0;
  99. Vec2 residuals;
  100. f(x.data(), residuals.data(), nullptr);
  101. EXPECT_GT(residuals.squaredNorm() / 2.0, 1e-10);
  102. TinySolver<Function> solver;
  103. solver.Solve(f, &x);
  104. EXPECT_NEAR(0.0, solver.summary.final_cost, 1e-10);
  105. }
  106. // A test case for when the cost function is statically sized.
  107. TEST(TinySolver, SimpleExample) {
  108. Vec3 x0(0.76026643, -30.01799744, 0.55192142);
  109. ExampleStatic f;
  110. TestHelper(f, x0);
  111. }
  112. // A test case for when the number of parameters is dynamically sized.
  113. TEST(TinySolver, ParametersDynamic) {
  114. VecX x0(3);
  115. x0 << 0.76026643, -30.01799744, 0.55192142;
  116. ExampleParametersDynamic f;
  117. TestHelper(f, x0);
  118. }
  119. // A test case for when the number of residuals is dynamically sized.
  120. TEST(TinySolver, ResidualsDynamic) {
  121. Vec3 x0(0.76026643, -30.01799744, 0.55192142);
  122. ExampleResidualsDynamic f;
  123. TestHelper(f, x0);
  124. }
  125. // A test case for when the number of parameters and residuals is
  126. // dynamically sized.
  127. TEST(TinySolver, ParametersAndResidualsDynamic) {
  128. VecX x0(3);
  129. x0 << 0.76026643, -30.01799744, 0.55192142;
  130. ExampleAllDynamic f;
  131. TestHelper(f, x0);
  132. }
  133. } // namespace ceres