| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | /* ----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-11 22:39:48 +08:00
										 |  |  |  * GTSAM Copyright 2010, Georgia Tech Research Corporation, | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  |  * Atlanta, Georgia 30332-0415 | 
					
						
							|  |  |  |  * All Rights Reserved | 
					
						
							|  |  |  |  * Authors: Frank Dellaert, et al. (see THANKS for the full author list) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * See LICENSE for the license information | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  *  @file   testIterative.cpp | 
					
						
							|  |  |  |  *  @brief  Unit tests for iterative methods | 
					
						
							|  |  |  |  *  @author Frank Dellaert | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <tests/smallExample.h>
 | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  | #include <gtsam/slam/BetweenFactor.h>
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/NonlinearEquality.h>
 | 
					
						
							| 
									
										
										
										
											2013-08-19 23:32:16 +08:00
										 |  |  | #include <gtsam/inference/Symbol.h>
 | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  | #include <gtsam/linear/iterative.h>
 | 
					
						
							|  |  |  | #include <gtsam/geometry/Pose2.h>
 | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <CppUnitLite/TestHarness.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using namespace std; | 
					
						
							|  |  |  | using namespace gtsam; | 
					
						
							|  |  |  | using namespace example; | 
					
						
							|  |  |  | using symbol_shorthand::X; // to create pose keys
 | 
					
						
							|  |  |  | using symbol_shorthand::L; // to create landmark keys
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  | static ConjugateGradientParameters parameters; | 
					
						
							|  |  |  | // add following below to add printing:
 | 
					
						
							|  |  |  | // parameters.verbosity_ = ConjugateGradientParameters::COMPLEXITY;
 | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | TEST( Iterative, steepestDescent ) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   // Create factor graph
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   GaussianFactorGraph fg = createGaussianFactorGraph(); | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // eliminate and solve
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   VectorValues expected = fg.optimize(); | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   // Do gradient descent
 | 
					
						
							| 
									
										
										
										
											2013-08-06 06:31:44 +08:00
										 |  |  |   VectorValues zero = VectorValues::Zero(expected); // TODO, how do we do this normally?
 | 
					
						
							|  |  |  |   VectorValues actual = steepestDescent(fg, zero, parameters); | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   CHECK(assert_equal(expected,actual,1e-2)); | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | TEST( Iterative, conjugateGradientDescent ) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  |   // Create factor graph
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   GaussianFactorGraph fg = createGaussianFactorGraph(); | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // eliminate and solve
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   VectorValues expected = fg.optimize(); | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // get matrices
 | 
					
						
							| 
									
										
										
										
											2016-04-16 04:54:46 +08:00
										 |  |  |   Vector x0 = Z_6x1; | 
					
						
							| 
									
										
										
										
											2023-02-05 01:42:39 +08:00
										 |  |  |   const auto [A, b] = fg.jacobian(); | 
					
						
							| 
									
										
										
										
											2014-11-23 08:35:27 +08:00
										 |  |  |   Vector expectedX = (Vector(6) << -0.1, 0.1, -0.1, -0.1, 0.1, -0.2).finished(); | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Do conjugate gradient descent, System version
 | 
					
						
							|  |  |  |   System Ab(A, b); | 
					
						
							|  |  |  |   Vector actualX = conjugateGradientDescent(Ab, x0, parameters); | 
					
						
							|  |  |  |   CHECK(assert_equal(expectedX,actualX,1e-9)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Do conjugate gradient descent, Matrix version
 | 
					
						
							|  |  |  |   Vector actualX2 = conjugateGradientDescent(A, b, x0, parameters); | 
					
						
							|  |  |  |   CHECK(assert_equal(expectedX,actualX2,1e-9)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Do conjugate gradient descent on factor graph
 | 
					
						
							| 
									
										
										
										
											2013-08-06 06:31:44 +08:00
										 |  |  |   VectorValues zero = VectorValues::Zero(expected); | 
					
						
							|  |  |  |   VectorValues actual = conjugateGradientDescent(fg, zero, parameters); | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   CHECK(assert_equal(expected,actual,1e-2)); | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  | TEST( Iterative, conjugateGradientDescent_hard_constraint ) | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  |   Values config; | 
					
						
							|  |  |  |   Pose2 pose1 = Pose2(0.,0.,0.); | 
					
						
							|  |  |  |   config.insert(X(1), pose1); | 
					
						
							|  |  |  |   config.insert(X(2), Pose2(1.5,0.,0.)); | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   NonlinearFactorGraph graph; | 
					
						
							| 
									
										
										
										
											2023-02-06 16:40:32 +08:00
										 |  |  |   graph.emplace_shared<NonlinearEquality<Pose2>>(X(1), pose1); | 
					
						
							|  |  |  |   graph.emplace_shared<BetweenFactor<Pose2>>(X(1),X(2), Pose2(1.,0.,0.), noiseModel::Isotropic::Sigma(3, 1)); | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-18 06:05:12 +08:00
										 |  |  |   std::shared_ptr<GaussianFactorGraph> fg = graph.linearize(config); | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   VectorValues zeros = config.zeroVectors(); | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  |   ConjugateGradientParameters parameters; | 
					
						
							| 
									
										
										
										
											2024-10-16 11:43:52 +08:00
										 |  |  |   parameters.epsilon_abs = 1e-3; | 
					
						
							|  |  |  |   parameters.epsilon_rel = 1e-5; | 
					
						
							|  |  |  |   parameters.maxIterations = 100; | 
					
						
							| 
									
										
										
										
											2013-08-06 06:31:44 +08:00
										 |  |  |   VectorValues actual = conjugateGradientDescent(*fg, zeros, parameters); | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 06:31:44 +08:00
										 |  |  |   VectorValues expected; | 
					
						
							| 
									
										
										
										
											2016-04-16 04:54:46 +08:00
										 |  |  |   expected.insert(X(1), Z_3x1); | 
					
						
							| 
									
										
										
										
											2014-11-24 02:22:25 +08:00
										 |  |  |   expected.insert(X(2), Vector3(-0.5,0.,0.)); | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  |   CHECK(assert_equal(expected, actual)); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | TEST( Iterative, conjugateGradientDescent_soft_constraint ) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   Values config; | 
					
						
							|  |  |  |   config.insert(X(1), Pose2(0.,0.,0.)); | 
					
						
							|  |  |  |   config.insert(X(2), Pose2(1.5,0.,0.)); | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   NonlinearFactorGraph graph; | 
					
						
							| 
									
										
										
										
											2020-04-13 01:10:09 +08:00
										 |  |  |   graph.addPrior(X(1), Pose2(0.,0.,0.), noiseModel::Isotropic::Sigma(3, 1e-10)); | 
					
						
							| 
									
										
										
										
											2023-02-06 16:40:32 +08:00
										 |  |  |   graph.emplace_shared<BetweenFactor<Pose2>>(X(1),X(2), Pose2(1.,0.,0.), noiseModel::Isotropic::Sigma(3, 1)); | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-18 06:05:12 +08:00
										 |  |  |   std::shared_ptr<GaussianFactorGraph> fg = graph.linearize(config); | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   VectorValues zeros = config.zeroVectors(); | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   ConjugateGradientParameters parameters; | 
					
						
							| 
									
										
										
										
											2024-10-16 11:43:52 +08:00
										 |  |  |   parameters.epsilon_abs = 1e-3; | 
					
						
							|  |  |  |   parameters.epsilon_rel = 1e-5; | 
					
						
							|  |  |  |   parameters.maxIterations = 100; | 
					
						
							| 
									
										
										
										
											2013-08-06 06:31:44 +08:00
										 |  |  |   VectorValues actual = conjugateGradientDescent(*fg, zeros, parameters); | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 06:31:44 +08:00
										 |  |  |   VectorValues expected; | 
					
						
							| 
									
										
										
										
											2016-04-16 04:54:46 +08:00
										 |  |  |   expected.insert(X(1), Z_3x1); | 
					
						
							| 
									
										
										
										
											2014-11-24 02:22:25 +08:00
										 |  |  |   expected.insert(X(2), Vector3(-0.5,0.,0.)); | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   CHECK(assert_equal(expected, actual)); | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | int main() { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   TestResult tr; | 
					
						
							|  |  |  |   return TestRegistry::runAllTests(tr); | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | } | 
					
						
							|  |  |  | /* ************************************************************************* */ |