| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | /* ----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * GTSAM Copyright 2010, Georgia Tech Research Corporation,  | 
					
						
							|  |  |  |  * 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/PriorFactor.h>
 | 
					
						
							|  |  |  | #include <gtsam/slam/BetweenFactor.h>
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/NonlinearEquality.h>
 | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | #include <gtsam/nonlinear/Ordering.h>
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/Symbol.h>
 | 
					
						
							|  |  |  | #include <gtsam/linear/GaussianSequentialSolver.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
 | 
					
						
							|  |  |  |   Ordering ordering; | 
					
						
							|  |  |  |   ordering += L(1), X(1), X(2); | 
					
						
							|  |  |  |   GaussianFactorGraph fg = createGaussianFactorGraph(ordering); | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // eliminate and solve
 | 
					
						
							|  |  |  |   VectorValues expected = *GaussianSequentialSolver(fg).optimize(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   // Do gradient descent
 | 
					
						
							|  |  |  |   VectorValues zero = VectorValues::Zero(expected); // TODO, how do we do this normally?
 | 
					
						
							|  |  |  |   VectorValues actual = steepestDescent(fg, zero, parameters); | 
					
						
							|  |  |  |   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
 | 
					
						
							|  |  |  |   Ordering ordering; | 
					
						
							|  |  |  |   ordering += L(1), X(1), X(2); | 
					
						
							|  |  |  |   GaussianFactorGraph fg = createGaussianFactorGraph(ordering); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // eliminate and solve
 | 
					
						
							|  |  |  |   VectorValues expected = *GaussianSequentialSolver(fg).optimize(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // get matrices
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   Matrix A; | 
					
						
							|  |  |  |   Vector b; | 
					
						
							|  |  |  |   Vector x0 = gtsam::zero(6); | 
					
						
							|  |  |  |   boost::tie(A, b) = fg.jacobian(); | 
					
						
							|  |  |  |   Vector expectedX = Vector_(6, -0.1, 0.1, -0.1, -0.1, 0.1, -0.2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // 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
 | 
					
						
							|  |  |  |   VectorValues zero = VectorValues::Zero(expected); | 
					
						
							|  |  |  |   VectorValues actual = conjugateGradientDescent(fg, zero, parameters); | 
					
						
							|  |  |  |   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; | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  |   graph.add(NonlinearEquality<Pose2>(X(1), pose1)); | 
					
						
							|  |  |  |   graph.add(BetweenFactor<Pose2>(X(1),X(2), Pose2(1.,0.,0.), noiseModel::Isotropic::Sigma(3, 1))); | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  |   Ordering ordering; | 
					
						
							|  |  |  |   ordering += X(1), X(2); | 
					
						
							|  |  |  |   boost::shared_ptr<GaussianFactorGraph> fg = graph.linearize(config,ordering); | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  |   VectorValues zeros = VectorValues::Zero(2, 3); | 
					
						
							| 
									
										
										
										
											2012-09-04 02:01:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  |   ConjugateGradientParameters parameters; | 
					
						
							|  |  |  |   parameters.setEpsilon_abs(1e-3); | 
					
						
							|  |  |  |   parameters.setEpsilon_rel(1e-5); | 
					
						
							|  |  |  |   parameters.setMaxIterations(100); | 
					
						
							|  |  |  |   VectorValues actual = conjugateGradientDescent(*fg, zeros, parameters); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   VectorValues expected; | 
					
						
							|  |  |  |   expected.insert(0, zero(3)); | 
					
						
							|  |  |  |   expected.insert(1, Vector_(3,-0.5,0.,0.)); | 
					
						
							|  |  |  |   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; | 
					
						
							|  |  |  |   graph.add(PriorFactor<Pose2>(X(1), Pose2(0.,0.,0.), noiseModel::Isotropic::Sigma(3, 1e-10))); | 
					
						
							|  |  |  |   graph.add(BetweenFactor<Pose2>(X(1),X(2), Pose2(1.,0.,0.), noiseModel::Isotropic::Sigma(3, 1))); | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Ordering ordering; | 
					
						
							|  |  |  |   ordering += X(1), X(2); | 
					
						
							|  |  |  |   boost::shared_ptr<GaussianFactorGraph> fg = graph.linearize(config,ordering); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   VectorValues zeros = VectorValues::Zero(2, 3); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   ConjugateGradientParameters parameters; | 
					
						
							|  |  |  |   parameters.setEpsilon_abs(1e-3); | 
					
						
							|  |  |  |   parameters.setEpsilon_rel(1e-5); | 
					
						
							|  |  |  |   parameters.setMaxIterations(100); | 
					
						
							|  |  |  |   VectorValues actual = conjugateGradientDescent(*fg, zeros, parameters); | 
					
						
							| 
									
										
										
										
											2012-09-05 11:06:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   VectorValues expected; | 
					
						
							|  |  |  |   expected.insert(0, zero(3)); | 
					
						
							|  |  |  |   expected.insert(1, Vector_(3,-0.5,0.,0.)); | 
					
						
							|  |  |  |   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
										 |  |  | } | 
					
						
							|  |  |  | /* ************************************************************************* */ |