| 
									
										
										
										
											2014-09-19 06:10:39 +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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-01 05:13:07 +08:00
										 |  |  |  * -------------------------------1------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2014-09-19 06:10:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2014-09-30 18:34:03 +08:00
										 |  |  |  * @file testExpression.cpp | 
					
						
							| 
									
										
										
										
											2014-09-19 06:10:39 +08:00
										 |  |  |  * @date September 18, 2014 | 
					
						
							|  |  |  |  * @author Frank Dellaert | 
					
						
							| 
									
										
										
										
											2014-09-29 18:06:04 +08:00
										 |  |  |  * @author Paul Furgale | 
					
						
							| 
									
										
										
										
											2014-09-19 06:10:39 +08:00
										 |  |  |  * @brief unit tests for Block Automatic Differentiation | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-30 18:29:57 +08:00
										 |  |  | #include <gtsam/geometry/PinholeCamera.h>
 | 
					
						
							| 
									
										
										
										
											2014-09-30 18:12:17 +08:00
										 |  |  | #include <gtsam/geometry/Cal3_S2.h>
 | 
					
						
							| 
									
										
										
										
											2014-09-30 18:34:03 +08:00
										 |  |  | #include <gtsam_unstable/nonlinear/Expression.h>
 | 
					
						
							| 
									
										
										
										
											2014-09-30 18:12:17 +08:00
										 |  |  | #include <gtsam/base/Testable.h>
 | 
					
						
							| 
									
										
										
										
											2014-10-05 19:27:41 +08:00
										 |  |  | #include <gtsam/base/LieScalar.h>
 | 
					
						
							| 
									
										
										
										
											2014-09-30 18:12:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-19 06:10:39 +08:00
										 |  |  | #include <CppUnitLite/TestHarness.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-14 15:53:47 +08:00
										 |  |  | #include <boost/assign/list_of.hpp>
 | 
					
						
							|  |  |  | using boost::assign::list_of; | 
					
						
							|  |  |  | using boost::assign::map_list_of; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-21 22:30:30 +08:00
										 |  |  | using namespace std; | 
					
						
							|  |  |  | using namespace gtsam; | 
					
						
							| 
									
										
										
										
											2014-09-19 06:10:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-22 00:22:28 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-09-21 23:59:34 +08:00
										 |  |  | template<class CAL> | 
					
						
							| 
									
										
										
										
											2014-10-07 22:11:55 +08:00
										 |  |  | Point2 uncalibrate(const CAL& K, const Point2& p, | 
					
						
							|  |  |  |     boost::optional<Matrix25&> Dcal, boost::optional<Matrix2&> Dp) { | 
					
						
							| 
									
										
										
										
											2014-09-22 00:36:19 +08:00
										 |  |  |   return K.uncalibrate(p, Dcal, Dp); | 
					
						
							| 
									
										
										
										
											2014-09-21 23:59:34 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 22:11:55 +08:00
										 |  |  | static const Rot3 someR = Rot3::RzRyRx(1, 2, 3); | 
					
						
							| 
									
										
										
										
											2014-10-05 17:22:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-19 06:10:39 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-10-11 13:39:13 +08:00
										 |  |  | // Constant
 | 
					
						
							| 
									
										
										
										
											2014-10-03 16:25:02 +08:00
										 |  |  | TEST(Expression, constant) { | 
					
						
							| 
									
										
										
										
											2014-10-05 17:22:14 +08:00
										 |  |  |   Expression<Rot3> R(someR); | 
					
						
							| 
									
										
										
										
											2014-10-03 16:25:02 +08:00
										 |  |  |   Values values; | 
					
						
							| 
									
										
										
										
											2014-11-01 18:56:38 +08:00
										 |  |  |   Rot3 actual = R.value(values); | 
					
						
							| 
									
										
										
										
											2014-10-13 02:16:08 +08:00
										 |  |  |   EXPECT(assert_equal(someR, actual)); | 
					
						
							| 
									
										
										
										
											2014-10-16 21:07:05 +08:00
										 |  |  |   EXPECT_LONGS_EQUAL(0, R.traceSize()) | 
					
						
							| 
									
										
										
										
											2014-10-03 16:25:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-10-11 13:39:13 +08:00
										 |  |  | // Leaf
 | 
					
						
							| 
									
										
										
										
											2014-10-15 16:38:54 +08:00
										 |  |  | TEST(Expression, Leaf) { | 
					
						
							| 
									
										
										
										
											2014-10-03 16:25:02 +08:00
										 |  |  |   Expression<Rot3> R(100); | 
					
						
							|  |  |  |   Values values; | 
					
						
							| 
									
										
										
										
											2014-10-07 22:11:55 +08:00
										 |  |  |   values.insert(100, someR); | 
					
						
							| 
									
										
										
										
											2014-10-13 02:16:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-01 18:56:38 +08:00
										 |  |  |   Rot3 actual2 = R.value(values); | 
					
						
							| 
									
										
										
										
											2014-10-13 02:16:08 +08:00
										 |  |  |   EXPECT(assert_equal(someR, actual2)); | 
					
						
							| 
									
										
										
										
											2014-10-03 16:25:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-15 16:38:54 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | // Many Leaves
 | 
					
						
							|  |  |  | TEST(Expression, Leaves) { | 
					
						
							|  |  |  |   Values values; | 
					
						
							|  |  |  |   Point3 somePoint(1, 2, 3); | 
					
						
							|  |  |  |   values.insert(Symbol('p', 10), somePoint); | 
					
						
							|  |  |  |   std::vector<Expression<Point3> > points = createUnknowns<Point3>(10, 'p', 1); | 
					
						
							|  |  |  |   EXPECT(assert_equal(somePoint,points.back().value(values))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-03 16:25:02 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-15 16:38:54 +08:00
										 |  |  | //TEST(Expression, NullaryMethod) {
 | 
					
						
							| 
									
										
										
										
											2014-10-05 19:27:41 +08:00
										 |  |  | //  Expression<Point3> p(67);
 | 
					
						
							|  |  |  | //  Expression<LieScalar> norm(p, &Point3::norm);
 | 
					
						
							|  |  |  | //  Values values;
 | 
					
						
							|  |  |  | //  values.insert(67,Point3(3,4,5));
 | 
					
						
							|  |  |  | //  Augmented<LieScalar> a = norm.augmented(values);
 | 
					
						
							|  |  |  | //  EXPECT(a.value() == sqrt(50));
 | 
					
						
							|  |  |  | //  JacobianMap expected;
 | 
					
						
							|  |  |  | //  expected[67] = (Matrix(1,3) << 3/sqrt(50),4/sqrt(50),5/sqrt(50));
 | 
					
						
							|  |  |  | //  EXPECT(assert_equal(expected.at(67),a.jacobians().at(67)));
 | 
					
						
							|  |  |  | //}
 | 
					
						
							| 
									
										
										
										
											2014-10-03 18:40:26 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-10-11 13:39:13 +08:00
										 |  |  | // Binary(Leaf,Leaf)
 | 
					
						
							|  |  |  | namespace binary { | 
					
						
							|  |  |  | // Create leaves
 | 
					
						
							|  |  |  | Expression<Pose3> x(1); | 
					
						
							|  |  |  | Expression<Point3> p(2); | 
					
						
							|  |  |  | Expression<Point3> p_cam(x, &Pose3::transform_to, p); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | // keys
 | 
					
						
							| 
									
										
										
										
											2014-10-14 15:53:47 +08:00
										 |  |  | TEST(Expression, BinaryKeys) { | 
					
						
							|  |  |  |   set<Key> expected = list_of(1)(2); | 
					
						
							|  |  |  |   EXPECT(expected == binary::p_cam.keys()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | // dimensions
 | 
					
						
							|  |  |  | TEST(Expression, BinaryDimensions) { | 
					
						
							| 
									
										
										
										
											2014-10-16 21:07:05 +08:00
										 |  |  |   map<Key, size_t> actual, expected = map_list_of<Key, size_t>(1, 6)(2, 3); | 
					
						
							| 
									
										
										
										
											2014-10-16 18:01:20 +08:00
										 |  |  |   binary::p_cam.dims(actual); | 
					
						
							|  |  |  |   EXPECT(actual==expected); | 
					
						
							| 
									
										
										
										
											2014-10-11 13:39:13 +08:00
										 |  |  | } | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-10-16 21:07:05 +08:00
										 |  |  | // dimensions
 | 
					
						
							|  |  |  | TEST(Expression, BinaryTraceSize) { | 
					
						
							|  |  |  |   typedef BinaryExpression<Point3, Pose3, Point3> Binary; | 
					
						
							|  |  |  |   size_t expectedTraceSize = sizeof(Binary::Record); | 
					
						
							|  |  |  |   EXPECT_LONGS_EQUAL(expectedTraceSize, binary::p_cam.traceSize()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-10-11 13:39:13 +08:00
										 |  |  | // Binary(Leaf,Unary(Binary(Leaf,Leaf)))
 | 
					
						
							|  |  |  | namespace tree { | 
					
						
							|  |  |  | using namespace binary; | 
					
						
							|  |  |  | // Create leaves
 | 
					
						
							|  |  |  | Expression<Cal3_S2> K(3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Create expression tree
 | 
					
						
							|  |  |  | Expression<Point2> projection(PinholeCamera<Cal3_S2>::project_to_camera, p_cam); | 
					
						
							|  |  |  | Expression<Point2> uv_hat(uncalibrate<Cal3_S2>, K, projection); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | // keys
 | 
					
						
							| 
									
										
										
										
											2014-10-14 15:53:47 +08:00
										 |  |  | TEST(Expression, TreeKeys) { | 
					
						
							|  |  |  |   set<Key> expected = list_of(1)(2)(3); | 
					
						
							|  |  |  |   EXPECT(expected == tree::uv_hat.keys()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | // dimensions
 | 
					
						
							|  |  |  | TEST(Expression, TreeDimensions) { | 
					
						
							| 
									
										
										
										
											2014-10-16 21:07:05 +08:00
										 |  |  |   map<Key, size_t> actual, expected = map_list_of<Key, size_t>(1, 6)(2, 3)(3, | 
					
						
							|  |  |  |       5); | 
					
						
							| 
									
										
										
										
											2014-10-16 18:01:20 +08:00
										 |  |  |   tree::uv_hat.dims(actual); | 
					
						
							|  |  |  |   EXPECT(actual==expected); | 
					
						
							| 
									
										
										
										
											2014-10-11 13:39:13 +08:00
										 |  |  | } | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-10-16 21:07:05 +08:00
										 |  |  | // TraceSize
 | 
					
						
							|  |  |  | TEST(Expression, TreeTraceSize) { | 
					
						
							|  |  |  |   typedef UnaryExpression<Point2, Point3> Unary; | 
					
						
							|  |  |  |   typedef BinaryExpression<Point3, Pose3, Point3> Binary1; | 
					
						
							|  |  |  |   typedef BinaryExpression<Point2, Point2, Cal3_S2> Binary2; | 
					
						
							|  |  |  |   size_t expectedTraceSize = sizeof(Unary::Record) + sizeof(Binary1::Record) | 
					
						
							|  |  |  |       + sizeof(Binary2::Record); | 
					
						
							|  |  |  |   EXPECT_LONGS_EQUAL(expectedTraceSize, tree::uv_hat.traceSize()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-09-28 00:22:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-03 05:26:59 +08:00
										 |  |  | TEST(Expression, compose1) { | 
					
						
							| 
									
										
										
										
											2014-09-29 18:14:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create expression
 | 
					
						
							| 
									
										
										
										
											2014-09-28 23:50:36 +08:00
										 |  |  |   Expression<Rot3> R1(1), R2(2); | 
					
						
							| 
									
										
										
										
											2014-09-29 13:22:25 +08:00
										 |  |  |   Expression<Rot3> R3 = R1 * R2; | 
					
						
							| 
									
										
										
										
											2014-09-29 18:14:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-30 18:29:57 +08:00
										 |  |  |   // Check keys
 | 
					
						
							| 
									
										
										
										
											2014-10-14 15:53:47 +08:00
										 |  |  |   set<Key> expected = list_of(1)(2); | 
					
						
							|  |  |  |   EXPECT(expected == R3.keys()); | 
					
						
							| 
									
										
										
										
											2014-09-29 18:14:59 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | // Test compose with arguments referring to the same rotation
 | 
					
						
							| 
									
										
										
										
											2014-10-01 16:36:24 +08:00
										 |  |  | TEST(Expression, compose2) { | 
					
						
							| 
									
										
										
										
											2014-09-29 18:14:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create expression
 | 
					
						
							|  |  |  |   Expression<Rot3> R1(1), R2(1); | 
					
						
							|  |  |  |   Expression<Rot3> R3 = R1 * R2; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-30 18:29:57 +08:00
										 |  |  |   // Check keys
 | 
					
						
							| 
									
										
										
										
											2014-10-14 15:53:47 +08:00
										 |  |  |   set<Key> expected = list_of(1); | 
					
						
							|  |  |  |   EXPECT(expected == R3.keys()); | 
					
						
							| 
									
										
										
										
											2014-09-28 23:50:36 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-03 05:26:59 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-10-03 05:39:17 +08:00
										 |  |  | // Test compose with one arguments referring to constant rotation
 | 
					
						
							| 
									
										
										
										
											2014-10-03 05:26:59 +08:00
										 |  |  | TEST(Expression, compose3) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Create expression
 | 
					
						
							|  |  |  |   Expression<Rot3> R1(Rot3::identity()), R2(3); | 
					
						
							|  |  |  |   Expression<Rot3> R3 = R1 * R2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Check keys
 | 
					
						
							| 
									
										
										
										
											2014-10-14 15:53:47 +08:00
										 |  |  |   set<Key> expected = list_of(3); | 
					
						
							|  |  |  |   EXPECT(expected == R3.keys()); | 
					
						
							| 
									
										
										
										
											2014-10-03 05:26:59 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-03 05:39:17 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | // Test with ternary function
 | 
					
						
							|  |  |  | Rot3 composeThree(const Rot3& R1, const Rot3& R2, const Rot3& R3, | 
					
						
							| 
									
										
										
										
											2014-10-07 22:11:55 +08:00
										 |  |  |     boost::optional<Matrix3&> H1, boost::optional<Matrix3&> H2, | 
					
						
							|  |  |  |     boost::optional<Matrix3&> H3) { | 
					
						
							| 
									
										
										
										
											2014-10-03 05:39:17 +08:00
										 |  |  |   // return dummy derivatives (not correct, but that's ok for testing here)
 | 
					
						
							|  |  |  |   if (H1) | 
					
						
							|  |  |  |     *H1 = eye(3); | 
					
						
							|  |  |  |   if (H2) | 
					
						
							|  |  |  |     *H2 = eye(3); | 
					
						
							|  |  |  |   if (H3) | 
					
						
							|  |  |  |     *H3 = eye(3); | 
					
						
							|  |  |  |   return R1 * (R2 * R3); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 04:09:24 +08:00
										 |  |  | TEST(Expression, ternary) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Create expression
 | 
					
						
							|  |  |  |   Expression<Rot3> A(1), B(2), C(3); | 
					
						
							|  |  |  |   Expression<Rot3> ABC(composeThree, A, B, C); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Check keys
 | 
					
						
							| 
									
										
										
										
											2014-10-14 15:53:47 +08:00
										 |  |  |   set<Key> expected = list_of(1)(2)(3); | 
					
						
							|  |  |  |   EXPECT(expected == ABC.keys()); | 
					
						
							| 
									
										
										
										
											2014-10-06 04:09:24 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-10-03 05:39:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-19 06:10:39 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | int main() { | 
					
						
							|  |  |  |   TestResult tr; | 
					
						
							|  |  |  |   return TestRegistry::runAllTests(tr); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | 
 |