| 
									
										
										
										
											2014-06-08 12:34:23 +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    testPCGSolver.cpp | 
					
						
							|  |  |  |  * @brief   Unit tests for PCGSolver class | 
					
						
							|  |  |  |  * @author  Yong-Dian Jian | 
					
						
							| 
									
										
										
										
											2014-11-07 03:26:46 +08:00
										 |  |  |  * @date    Aug 06, 2014 | 
					
						
							| 
									
										
										
										
											2014-06-08 12:34:23 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <tests/smallExample.h>
 | 
					
						
							|  |  |  | #include <gtsam/slam/PriorFactor.h>
 | 
					
						
							|  |  |  | #include <gtsam/slam/BetweenFactor.h>
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/NonlinearFactorGraph.h>
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/Values.h>
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/NonlinearFactorGraph.h>
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/GaussNewtonOptimizer.h>
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/DoglegOptimizer.h>
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/LevenbergMarquardtOptimizer.h>
 | 
					
						
							|  |  |  | #include <gtsam/linear/GaussianFactorGraph.h>
 | 
					
						
							|  |  |  | #include <gtsam/linear/PCGSolver.h>
 | 
					
						
							|  |  |  | #include <gtsam/linear/Preconditioner.h>
 | 
					
						
							| 
									
										
										
										
											2014-06-16 11:14:06 +08:00
										 |  |  | #include <gtsam/linear/SubgraphPreconditioner.h>
 | 
					
						
							| 
									
										
										
										
											2014-06-08 12:34:23 +08:00
										 |  |  | #include <gtsam/linear/NoiseModel.h>
 | 
					
						
							|  |  |  | #include <gtsam/inference/Symbol.h>
 | 
					
						
							|  |  |  | #include <gtsam/geometry/Pose2.h>
 | 
					
						
							|  |  |  | #include <gtsam/base/Matrix.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <CppUnitLite/TestHarness.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/shared_ptr.hpp>
 | 
					
						
							|  |  |  | #include <boost/assign/std/list.hpp> // for operator +=
 | 
					
						
							|  |  |  | using namespace boost::assign; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <iostream>
 | 
					
						
							|  |  |  | #include <fstream>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using namespace std; | 
					
						
							|  |  |  | using namespace gtsam; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const double tol = 1e-3; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using symbol_shorthand::X; | 
					
						
							|  |  |  | using symbol_shorthand::L; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-11-07 03:26:46 +08:00
										 |  |  | // Test cholesky decomposition
 | 
					
						
							| 
									
										
										
										
											2014-06-09 04:15:00 +08:00
										 |  |  | TEST( PCGSolver, llt ) { | 
					
						
							|  |  |  |   Matrix R = (Matrix(3,3) << | 
					
						
							|  |  |  |                 1., -1., -1., | 
					
						
							|  |  |  |                 0.,  2., -1., | 
					
						
							| 
									
										
										
										
											2014-11-23 08:35:27 +08:00
										 |  |  |                 0.,  0.,  1.).finished(); | 
					
						
							| 
									
										
										
										
											2014-06-09 04:15:00 +08:00
										 |  |  |   Matrix AtA = R.transpose() * R; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Vector Rvector = (Vector(9) << 1., -1., -1., | 
					
						
							|  |  |  |                                  0.,  2., -1., | 
					
						
							| 
									
										
										
										
											2014-11-23 08:35:27 +08:00
										 |  |  |                                  0.,  0.,  1.).finished(); | 
					
						
							| 
									
										
										
										
											2014-06-09 04:15:00 +08:00
										 |  |  | //  Vector Rvector = (Vector(6) << 1., -1., -1.,
 | 
					
						
							|  |  |  | //                                      2., -1.,
 | 
					
						
							| 
									
										
										
										
											2014-11-23 08:35:27 +08:00
										 |  |  | //                                           1.).finished();
 | 
					
						
							| 
									
										
										
										
											2014-06-09 04:15:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-24 02:22:25 +08:00
										 |  |  |   Vector b = Vector3(1., 2., 3.); | 
					
						
							| 
									
										
										
										
											2014-06-09 04:15:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-24 02:22:25 +08:00
										 |  |  |   Vector x = Vector3(6.5, 2.5, 3.) ; | 
					
						
							| 
									
										
										
										
											2014-06-09 04:15:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* test cholesky */ | 
					
						
							|  |  |  |   Matrix Rhat = AtA.llt().matrixL().transpose(); | 
					
						
							|  |  |  |   EXPECT(assert_equal(R, Rhat, 1e-5)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* test backward substitution */ | 
					
						
							|  |  |  |   Vector xhat = Rhat.triangularView<Eigen::Upper>().solve(b); | 
					
						
							|  |  |  |   EXPECT(assert_equal(x, xhat, 1e-5)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* test in-place back substitution */ | 
					
						
							|  |  |  |   xhat = b; | 
					
						
							|  |  |  |   Rhat.triangularView<Eigen::Upper>().solveInPlace(xhat); | 
					
						
							|  |  |  |   EXPECT(assert_equal(x, xhat, 1e-5)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* test triangular matrix map */ | 
					
						
							|  |  |  |   Eigen::Map<Eigen::MatrixXd> Radapter(Rvector.data(), 3, 3); | 
					
						
							|  |  |  |   xhat = Radapter.transpose().triangularView<Eigen::Upper>().solve(b); | 
					
						
							|  |  |  |   EXPECT(assert_equal(x, xhat, 1e-5)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-11-07 03:26:46 +08:00
										 |  |  | // Test Dummy Preconditioner
 | 
					
						
							| 
									
										
										
										
											2014-06-09 04:15:00 +08:00
										 |  |  | TEST( PCGSolver, dummy ) | 
					
						
							| 
									
										
										
										
											2014-06-08 12:34:23 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   LevenbergMarquardtParams paramsPCG; | 
					
						
							|  |  |  |   paramsPCG.linearSolverType = LevenbergMarquardtParams::Iterative; | 
					
						
							|  |  |  |   PCGSolverParameters::shared_ptr pcg = boost::make_shared<PCGSolverParameters>(); | 
					
						
							|  |  |  |   pcg->preconditioner_ = boost::make_shared<DummyPreconditionerParameters>(); | 
					
						
							|  |  |  |   paramsPCG.iterativeParams = pcg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   NonlinearFactorGraph fg = example::createReallyNonlinearFactorGraph(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Point2 x0(10,10); | 
					
						
							|  |  |  |   Values c0; | 
					
						
							|  |  |  |   c0.insert(X(1), x0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Values actualPCG = LevenbergMarquardtOptimizer(fg, c0, paramsPCG).optimize(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   DOUBLES_EQUAL(0,fg.error(actualPCG),tol); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-09 04:15:00 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-11-07 03:26:46 +08:00
										 |  |  | // Test Block-Jacobi Precondioner
 | 
					
						
							| 
									
										
										
										
											2014-06-09 04:15:00 +08:00
										 |  |  | TEST( PCGSolver, blockjacobi ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   LevenbergMarquardtParams paramsPCG; | 
					
						
							|  |  |  |   paramsPCG.linearSolverType = LevenbergMarquardtParams::Iterative; | 
					
						
							|  |  |  |   PCGSolverParameters::shared_ptr pcg = boost::make_shared<PCGSolverParameters>(); | 
					
						
							|  |  |  |   pcg->preconditioner_ = boost::make_shared<BlockJacobiPreconditionerParameters>(); | 
					
						
							|  |  |  |   paramsPCG.iterativeParams = pcg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   NonlinearFactorGraph fg = example::createReallyNonlinearFactorGraph(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Point2 x0(10,10); | 
					
						
							|  |  |  |   Values c0; | 
					
						
							|  |  |  |   c0.insert(X(1), x0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Values actualPCG = LevenbergMarquardtOptimizer(fg, c0, paramsPCG).optimize(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   DOUBLES_EQUAL(0,fg.error(actualPCG),tol); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 11:14:06 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-11-07 03:26:46 +08:00
										 |  |  | // Test Incremental Subgraph PCG Solver
 | 
					
						
							| 
									
										
										
										
											2014-06-16 11:14:06 +08:00
										 |  |  | TEST( PCGSolver, subgraph ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   LevenbergMarquardtParams paramsPCG; | 
					
						
							|  |  |  |   paramsPCG.linearSolverType = LevenbergMarquardtParams::Iterative; | 
					
						
							|  |  |  |   PCGSolverParameters::shared_ptr pcg = boost::make_shared<PCGSolverParameters>(); | 
					
						
							|  |  |  |   pcg->preconditioner_ = boost::make_shared<SubgraphPreconditionerParameters>(); | 
					
						
							|  |  |  |   paramsPCG.iterativeParams = pcg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   NonlinearFactorGraph fg = example::createReallyNonlinearFactorGraph(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Point2 x0(10,10); | 
					
						
							|  |  |  |   Values c0; | 
					
						
							|  |  |  |   c0.insert(X(1), x0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Values actualPCG = LevenbergMarquardtOptimizer(fg, c0, paramsPCG).optimize(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   DOUBLES_EQUAL(0,fg.error(actualPCG),tol); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-08 12:34:23 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | int main() { | 
					
						
							|  |  |  |   TestResult tr; | 
					
						
							|  |  |  |   return TestRegistry::runAllTests(tr); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |