testIterative.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /* ----------------------------------------------------------------------------
  2. * GTSAM Copyright 2010, Georgia Tech Research Corporation,
  3. * Atlanta, Georgia 30332-0415
  4. * All Rights Reserved
  5. * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
  6. * See LICENSE for the license information
  7. * -------------------------------------------------------------------------- */
  8. /**
  9. * @file testIterative.cpp
  10. * @brief Unit tests for iterative methods
  11. * @author Frank Dellaert
  12. **/
  13. #include <tests/smallExample.h>
  14. #include <gtsam/slam/BetweenFactor.h>
  15. #include <gtsam/nonlinear/NonlinearEquality.h>
  16. #include <gtsam/inference/Symbol.h>
  17. #include <gtsam/linear/iterative.h>
  18. #include <gtsam/geometry/Pose2.h>
  19. #include <CppUnitLite/TestHarness.h>
  20. using namespace std;
  21. using namespace gtsam;
  22. using namespace example;
  23. using symbol_shorthand::X; // to create pose keys
  24. using symbol_shorthand::L; // to create landmark keys
  25. static ConjugateGradientParameters parameters;
  26. // add following below to add printing:
  27. // parameters.verbosity_ = ConjugateGradientParameters::COMPLEXITY;
  28. /* ************************************************************************* */
  29. TEST( Iterative, steepestDescent )
  30. {
  31. // Create factor graph
  32. GaussianFactorGraph fg = createGaussianFactorGraph();
  33. // eliminate and solve
  34. VectorValues expected = fg.optimize();
  35. // Do gradient descent
  36. VectorValues zero = VectorValues::Zero(expected); // TODO, how do we do this normally?
  37. VectorValues actual = steepestDescent(fg, zero, parameters);
  38. CHECK(assert_equal(expected,actual,1e-2));
  39. }
  40. /* ************************************************************************* */
  41. TEST( Iterative, conjugateGradientDescent )
  42. {
  43. // Create factor graph
  44. GaussianFactorGraph fg = createGaussianFactorGraph();
  45. // eliminate and solve
  46. VectorValues expected = fg.optimize();
  47. // get matrices
  48. Matrix A;
  49. Vector b;
  50. Vector x0 = Z_6x1;
  51. boost::tie(A, b) = fg.jacobian();
  52. Vector expectedX = (Vector(6) << -0.1, 0.1, -0.1, -0.1, 0.1, -0.2).finished();
  53. // Do conjugate gradient descent, System version
  54. System Ab(A, b);
  55. Vector actualX = conjugateGradientDescent(Ab, x0, parameters);
  56. CHECK(assert_equal(expectedX,actualX,1e-9));
  57. // Do conjugate gradient descent, Matrix version
  58. Vector actualX2 = conjugateGradientDescent(A, b, x0, parameters);
  59. CHECK(assert_equal(expectedX,actualX2,1e-9));
  60. // Do conjugate gradient descent on factor graph
  61. VectorValues zero = VectorValues::Zero(expected);
  62. VectorValues actual = conjugateGradientDescent(fg, zero, parameters);
  63. CHECK(assert_equal(expected,actual,1e-2));
  64. }
  65. /* ************************************************************************* */
  66. TEST( Iterative, conjugateGradientDescent_hard_constraint )
  67. {
  68. Values config;
  69. Pose2 pose1 = Pose2(0.,0.,0.);
  70. config.insert(X(1), pose1);
  71. config.insert(X(2), Pose2(1.5,0.,0.));
  72. NonlinearFactorGraph graph;
  73. graph += NonlinearEquality<Pose2>(X(1), pose1);
  74. graph += BetweenFactor<Pose2>(X(1),X(2), Pose2(1.,0.,0.), noiseModel::Isotropic::Sigma(3, 1));
  75. boost::shared_ptr<GaussianFactorGraph> fg = graph.linearize(config);
  76. VectorValues zeros = config.zeroVectors();
  77. ConjugateGradientParameters parameters;
  78. parameters.setEpsilon_abs(1e-3);
  79. parameters.setEpsilon_rel(1e-5);
  80. parameters.setMaxIterations(100);
  81. VectorValues actual = conjugateGradientDescent(*fg, zeros, parameters);
  82. VectorValues expected;
  83. expected.insert(X(1), Z_3x1);
  84. expected.insert(X(2), Vector3(-0.5,0.,0.));
  85. CHECK(assert_equal(expected, actual));
  86. }
  87. /* ************************************************************************* */
  88. TEST( Iterative, conjugateGradientDescent_soft_constraint )
  89. {
  90. Values config;
  91. config.insert(X(1), Pose2(0.,0.,0.));
  92. config.insert(X(2), Pose2(1.5,0.,0.));
  93. NonlinearFactorGraph graph;
  94. graph.addPrior(X(1), Pose2(0.,0.,0.), noiseModel::Isotropic::Sigma(3, 1e-10));
  95. graph += BetweenFactor<Pose2>(X(1),X(2), Pose2(1.,0.,0.), noiseModel::Isotropic::Sigma(3, 1));
  96. boost::shared_ptr<GaussianFactorGraph> fg = graph.linearize(config);
  97. VectorValues zeros = config.zeroVectors();
  98. ConjugateGradientParameters parameters;
  99. parameters.setEpsilon_abs(1e-3);
  100. parameters.setEpsilon_rel(1e-5);
  101. parameters.setMaxIterations(100);
  102. VectorValues actual = conjugateGradientDescent(*fg, zeros, parameters);
  103. VectorValues expected;
  104. expected.insert(X(1), Z_3x1);
  105. expected.insert(X(2), Vector3(-0.5,0.,0.));
  106. CHECK(assert_equal(expected, actual));
  107. }
  108. /* ************************************************************************* */
  109. int main() {
  110. TestResult tr;
  111. return TestRegistry::runAllTests(tr);
  112. }
  113. /* ************************************************************************* */