| 
									
										
										
										
											2014-11-21 22:48:02 +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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * -------------------------------1------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * @file testCallRecord.cpp | 
					
						
							|  |  |  |  * @date November 21, 2014 | 
					
						
							|  |  |  |  * @author Frank Dellaert | 
					
						
							|  |  |  |  * @author Paul Furgale | 
					
						
							|  |  |  |  * @author Hannes Sommer | 
					
						
							| 
									
										
										
										
											2014-11-22 04:09:03 +08:00
										 |  |  |  * @brief unit tests for CallRecord class | 
					
						
							| 
									
										
										
										
											2014-11-21 22:48:02 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-22 04:09:03 +08:00
										 |  |  | #include <gtsam_unstable/nonlinear/CallRecord.h>
 | 
					
						
							| 
									
										
										
										
											2014-11-21 22:48:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <CppUnitLite/TestHarness.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-22 05:36:45 +08:00
										 |  |  | #include <gtsam/base/Matrix.h>
 | 
					
						
							|  |  |  | #include <gtsam/base/Testable.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-21 22:48:02 +08:00
										 |  |  | using namespace std; | 
					
						
							|  |  |  | using namespace gtsam; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | static const int Cols = 3; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-22 05:36:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | int dynamicIfAboveMax(int i){ | 
					
						
							|  |  |  |   if(i > MaxVirtualStaticRows){ | 
					
						
							|  |  |  |     return Eigen::Dynamic; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else return i; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | struct CallConfig { | 
					
						
							|  |  |  |   int compTimeRows; | 
					
						
							|  |  |  |   int compTimeCols; | 
					
						
							|  |  |  |   int runTimeRows; | 
					
						
							|  |  |  |   int runTimeCols; | 
					
						
							|  |  |  |   CallConfig() {} | 
					
						
							|  |  |  |   CallConfig(int rows, int cols): | 
					
						
							|  |  |  |     compTimeRows(dynamicIfAboveMax(rows)), | 
					
						
							|  |  |  |     compTimeCols(cols), | 
					
						
							|  |  |  |     runTimeRows(rows), | 
					
						
							|  |  |  |     runTimeCols(cols) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   CallConfig(int compTimeRows, int compTimeCols, int runTimeRows, int runTimeCols): | 
					
						
							|  |  |  |     compTimeRows(compTimeRows), | 
					
						
							|  |  |  |     compTimeCols(compTimeCols), | 
					
						
							|  |  |  |     runTimeRows(runTimeRows), | 
					
						
							|  |  |  |     runTimeCols(runTimeCols) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool equals(const CallConfig & c, double /*tol*/) const { | 
					
						
							|  |  |  |     return | 
					
						
							|  |  |  |         this->compTimeRows == c.compTimeRows && | 
					
						
							|  |  |  |         this->compTimeCols == c.compTimeCols && | 
					
						
							|  |  |  |         this->runTimeRows == c.runTimeRows && | 
					
						
							|  |  |  |         this->runTimeCols == c.runTimeCols; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   void print(const std::string & prefix) const { | 
					
						
							|  |  |  |     std::cout << prefix << "{" << compTimeRows << ", " << compTimeCols << ", " << runTimeRows << ", " << runTimeCols << "}\n" ; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-21 22:48:02 +08:00
										 |  |  | struct Record: public internal::CallRecordImplementor<Record, Cols> { | 
					
						
							|  |  |  |   virtual ~Record() { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   void print(const std::string& indent) const { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   void startReverseAD(JacobianMap& jacobians) const { | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-11-22 05:36:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   mutable CallConfig cc; | 
					
						
							|  |  |  |  private: | 
					
						
							| 
									
										
										
										
											2014-11-21 22:48:02 +08:00
										 |  |  |   template<typename SomeMatrix> | 
					
						
							|  |  |  |   void reverseAD(const SomeMatrix & dFdT, JacobianMap& jacobians) const { | 
					
						
							| 
									
										
										
										
											2014-11-22 05:36:45 +08:00
										 |  |  |     cc.compTimeRows = SomeMatrix::RowsAtCompileTime; | 
					
						
							|  |  |  |     cc.compTimeCols = SomeMatrix::ColsAtCompileTime; | 
					
						
							|  |  |  |     cc.runTimeRows = dFdT.rows(); | 
					
						
							|  |  |  |     cc.runTimeCols = dFdT.cols(); | 
					
						
							| 
									
										
										
										
											2014-11-21 22:48:02 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-11-22 05:36:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   template<typename Derived, int Rows, int OtherCols> | 
					
						
							|  |  |  |   friend struct internal::ReverseADImplementor; | 
					
						
							| 
									
										
										
										
											2014-11-21 22:48:02 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-22 05:36:45 +08:00
										 |  |  | JacobianMap & NJM= *static_cast<JacobianMap *>(NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-21 22:48:02 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-11-22 05:36:45 +08:00
										 |  |  | typedef Eigen::Matrix<double, Eigen::Dynamic, Cols> DynRowMat; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(CallRecord, virtualReverseAdDispatching) { | 
					
						
							| 
									
										
										
										
											2014-11-21 22:48:02 +08:00
										 |  |  |   Record record; | 
					
						
							| 
									
										
										
										
											2014-11-22 05:36:45 +08:00
										 |  |  |   { | 
					
						
							|  |  |  |     const int Rows = 1; | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(Eigen::Matrix<double, Rows, Cols>(), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Rows, Cols)))); | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(DynRowMat(Rows, Cols), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Eigen::Dynamic, Cols, Rows, Cols)))); | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(Eigen::MatrixXd(Rows, Cols), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Eigen::Dynamic, Eigen::Dynamic, Rows, Cols)))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     const int Rows = 2; | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(Eigen::Matrix<double, Rows, Cols>(), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Rows, Cols)))); | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(DynRowMat(Rows, Cols), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Eigen::Dynamic, Cols, Rows, Cols)))); | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(Eigen::MatrixXd(Rows, Cols), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Eigen::Dynamic, Eigen::Dynamic, Rows, Cols)))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     const int Rows = 3; | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(Eigen::Matrix<double, Rows, Cols>(), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Rows, Cols)))); | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(DynRowMat(Rows, Cols), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Eigen::Dynamic, Cols, Rows, Cols)))); | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(Eigen::MatrixXd(Rows, Cols), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Eigen::Dynamic, Eigen::Dynamic, Rows, Cols)))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     const int Rows = MaxVirtualStaticRows; | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(Eigen::Matrix<double, Rows, Cols>(), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Rows, Cols)))); | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(DynRowMat(Rows, Cols), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Eigen::Dynamic, Cols, Rows, Cols)))); | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(Eigen::MatrixXd(Rows, Cols), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Eigen::Dynamic, Eigen::Dynamic, Rows, Cols)))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     const int Rows = MaxVirtualStaticRows + 1; | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(Eigen::Matrix<double, Rows, Cols>(), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Rows, Cols)))); | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(DynRowMat(Rows, Cols), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Eigen::Dynamic, Cols, Rows, Cols)))); | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(Eigen::MatrixXd(Rows, Cols), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Eigen::Dynamic, Eigen::Dynamic, Rows, Cols)))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     const int Rows = MaxVirtualStaticRows + 2; | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(Eigen::Matrix<double, Rows, Cols>(), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Rows, Cols)))); | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(DynRowMat(Rows, Cols), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Eigen::Dynamic, Cols, Rows, Cols)))); | 
					
						
							|  |  |  |     record.CallRecord::reverseAD(Eigen::MatrixXd(Rows, Cols), NJM); | 
					
						
							|  |  |  |     EXPECT((assert_equal(record.cc, CallConfig(Eigen::Dynamic, Eigen::Dynamic, Rows, Cols)))); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-11-21 22:48:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | int main() { | 
					
						
							|  |  |  |   TestResult tr; | 
					
						
							|  |  |  |   return TestRegistry::runAllTests(tr); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | 
 |