diff --git a/.cproject b/.cproject
index 9726fec60..ac9b166ec 100644
--- a/.cproject
+++ b/.cproject
@@ -532,14 +532,6 @@
 				true
 				true
 			
-			
-				make
-				-j4
-				testSimilarity3.run
-				true
-				true
-				true
-			
 			
 				make
 				-j2
@@ -755,6 +747,14 @@
 				true
 				true
 			
+			
+				make
+				-j4
+				testSimilarity3.run
+				true
+				true
+				true
+			
 			
 				make
 				-j5
@@ -1035,6 +1035,14 @@
 				true
 				true
 			
+			
+				make
+				-j4
+				testCyclic.run
+				true
+				true
+				true
+			
 			
 				make
 				-j2
@@ -1301,7 +1309,6 @@
 			
 			
 				make
-				
 				testSimulated2DOriented.run
 				true
 				false
@@ -1341,7 +1348,6 @@
 			
 			
 				make
-				
 				testSimulated2D.run
 				true
 				false
@@ -1349,7 +1355,6 @@
 			
 			
 				make
-				
 				testSimulated3D.run
 				true
 				false
@@ -1453,6 +1458,7 @@
 			
 			
 				make
+				
 				testErrors.run
 				true
 				false
@@ -1763,6 +1769,7 @@
 			
 			
 				cpack
+				
 				-G DEB
 				true
 				false
@@ -1770,6 +1777,7 @@
 			
 			
 				cpack
+				
 				-G RPM
 				true
 				false
@@ -1777,6 +1785,7 @@
 			
 			
 				cpack
+				
 				-G TGZ
 				true
 				false
@@ -1784,6 +1793,7 @@
 			
 			
 				cpack
+				
 				--config CPackSourceConfig.cmake
 				true
 				false
@@ -1975,7 +1985,6 @@
 			
 			
 				make
-				
 				tests/testGaussianISAM2
 				true
 				false
@@ -2037,22 +2046,6 @@
 				true
 				true
 			
-			
-				make
-				-j5
-				testExpressionMeta.run
-				true
-				true
-				true
-			
-			
-				make
-				-j4
-				testCustomChartExpression.run
-				true
-				true
-				true
-			
 			
 				make
 				-j5
@@ -2127,6 +2120,7 @@
 			
 			
 				make
+				
 				tests/testBayesTree.run
 				true
 				false
@@ -2134,6 +2128,7 @@
 			
 			
 				make
+				
 				testBinaryBayesNet.run
 				true
 				false
@@ -2181,6 +2176,7 @@
 			
 			
 				make
+				
 				testSymbolicBayesNet.run
 				true
 				false
@@ -2188,6 +2184,7 @@
 			
 			
 				make
+				
 				tests/testSymbolicFactor.run
 				true
 				false
@@ -2195,6 +2192,7 @@
 			
 			
 				make
+				
 				testSymbolicFactorGraph.run
 				true
 				false
@@ -2210,6 +2208,7 @@
 			
 			
 				make
+				
 				tests/testBayesTree
 				true
 				false
@@ -2783,6 +2782,14 @@
 				true
 				true
 			
+			
+				make
+				-j4
+				testExecutionTrace.run
+				true
+				true
+				true
+			
 			
 				make
 				-j5
@@ -3191,6 +3198,14 @@
 				true
 				true
 			
+			
+				make
+				-j4
+				testGroup.run
+				true
+				true
+				true
+			
 			
 				make
 				-j5
@@ -3329,6 +3344,7 @@
 			
 			
 				make
+				
 				testGraph.run
 				true
 				false
@@ -3336,6 +3352,7 @@
 			
 			
 				make
+				
 				testJunctionTree.run
 				true
 				false
@@ -3343,6 +3360,7 @@
 			
 			
 				make
+				
 				testSymbolicBayesNetB.run
 				true
 				false
@@ -3412,6 +3430,14 @@
 				true
 				true
 			
+			
+				make
+				-j4
+				testLie.run
+				true
+				true
+				true
+			
 			
 				make
 				-j2
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 38ee89760..6e9aa0009 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -192,36 +192,40 @@ endif()
 
 ###############################################################################
 # Option for using system Eigen or GTSAM-bundled Eigen
-### Disabled until our patches are included in Eigen ###
+### These patches only affect usage of MKL. If you want to enable MKL, you *must*
+### use our patched version of Eigen
 ### See:  http://eigen.tuxfamily.org/bz/show_bug.cgi?id=704 (Householder QR MKL selection)
 ###       http://eigen.tuxfamily.org/bz/show_bug.cgi?id=705 (Fix MKL LLT return code)
-###       http://eigen.tuxfamily.org/bz/show_bug.cgi?id=716 (Improved comma initialization)
-# option(GTSAM_USE_SYSTEM_EIGEN "Find and use system-installed Eigen. If 'off', use the one bundled with GTSAM" OFF)
-set(GTSAM_USE_SYSTEM_EIGEN OFF)
+option(GTSAM_USE_SYSTEM_EIGEN "Find and use system-installed Eigen. If 'off', use the one bundled with GTSAM" OFF)
 
 # Switch for using system Eigen or GTSAM-bundled Eigen
 if(GTSAM_USE_SYSTEM_EIGEN)
-	# Use generic Eigen include paths e.g. 
-	set(GTSAM_EIGEN_INCLUDE_PREFIX "")
-
 	find_package(Eigen3 REQUIRED)
 	include_directories(AFTER "${EIGEN3_INCLUDE_DIR}")
+	
+	# Use generic Eigen include paths e.g. 
+    set(GTSAM_EIGEN_INCLUDE_PREFIX "${EIGEN3_INCLUDE_DIR}")
+	
+	# check if MKL is also enabled - can have one or the other, but not both!
+	if(EIGEN_USE_MKL_ALL)
+	  message(FATAL_ERROR "MKL cannot be used together with system-installed Eigen, as MKL support relies on patches which are not yet in the system-installed Eigen. Disable either GTSAM_USE_SYSTEM_EIGEN or GTSAM_WITH_EIGEN_MKL")
+	endif()
 else()
-	# Use bundled Eigen include paths e.g. 
-	set(GTSAM_EIGEN_INCLUDE_PREFIX "gtsam/3rdparty/Eigen/")
-
+	# Use bundled Eigen include path. 
 	# Clear any variables set by FindEigen3
 	if(EIGEN3_INCLUDE_DIR)
 		set(EIGEN3_INCLUDE_DIR NOTFOUND CACHE STRING "" FORCE)
 	endif()
+	# Add the bundled version of eigen to the include path so that it can still be included
+	# with  #include 
+	include_directories(BEFORE "gtsam/3rdparty/Eigen/")
+	
+	# set full path to be used by external projects
+	# this will be added to GTSAM_INCLUDE_DIR by gtsam_extra.cmake.in
+	set(GTSAM_EIGEN_INCLUDE_PREFIX "${CMAKE_INSTALL_PREFIX}/include/gtsam/3rdparty/Eigen/")
+	
 endif()
 
-# Write Eigen include file with the paths for either the system Eigen or the GTSAM-bundled Eigen
-configure_file(gtsam/3rdparty/gtsam_eigen_includes.h.in gtsam/3rdparty/gtsam_eigen_includes.h)
-
-# Install the configuration file for Eigen
-install(FILES ${PROJECT_BINARY_DIR}/gtsam/3rdparty/gtsam_eigen_includes.h DESTINATION include/gtsam/3rdparty)
-
 ###############################################################################
 # Global compile options
 
@@ -389,6 +393,11 @@ if(NOT MSVC AND NOT XCODE_VERSION)
     message(STATUS "  C compilation flags            : ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${cmake_build_type_toupper}}")
     message(STATUS "  C++ compilation flags          : ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${cmake_build_type_toupper}}")
 endif()
+if(GTSAM_USE_SYSTEM_EIGEN)
+    message(STATUS "  Use System Eigen               : Yes")
+else()
+    message(STATUS "  Use System Eigen               : No")
+endif()
 if(GTSAM_USE_TBB)
 	message(STATUS "  Use Intel TBB                  : Yes")
 elseif(TBB_FOUND)
diff --git a/cmake/GtsamBuildTypes.cmake b/cmake/GtsamBuildTypes.cmake
index 1bead58d8..c2cd7b449 100644
--- a/cmake/GtsamBuildTypes.cmake
+++ b/cmake/GtsamBuildTypes.cmake
@@ -53,11 +53,12 @@ if(NOT FIRST_PASS_DONE)
   endif()
 endif()
 
-# Clang on Mac uses a template depth that is less than standard and is too small
+# Clang uses a template depth that is less than standard and is too small
 if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
-	if(NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "5.0")
-		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=1024")
-	endif()
+    # Apple Clang before 5.0 does not support -ftemplate-depth.
+    if(NOT (APPLE AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "5.0"))
+        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=1024")
+    endif()
 endif()
 
 # Set up build type library postfixes
@@ -97,7 +98,8 @@ if(    NOT cmake_build_type_tolower STREQUAL ""
    AND NOT cmake_build_type_tolower STREQUAL "release"
    AND NOT cmake_build_type_tolower STREQUAL "timing"
    AND NOT cmake_build_type_tolower STREQUAL "profiling"
-   AND NOT cmake_build_type_tolower STREQUAL "relwithdebinfo")
+   AND NOT cmake_build_type_tolower STREQUAL "relwithdebinfo"
+   AND NOT cmake_build_type_tolower STREQUAL "minsizerel")
   message(FATAL_ERROR "Unknown build type \"${CMAKE_BUILD_TYPE}\". Allowed values are None, Debug, Release, Timing, Profiling, RelWithDebInfo (case-insensitive).")
 endif()
 
diff --git a/cmake/GtsamMatlabWrap.cmake b/cmake/GtsamMatlabWrap.cmake
index ba616b025..d1d3d93dd 100644
--- a/cmake/GtsamMatlabWrap.cmake
+++ b/cmake/GtsamMatlabWrap.cmake
@@ -270,7 +270,7 @@ function(install_wrapped_library_internal interfaceHeader)
 	if(GTSAM_BUILD_TYPE_POSTFIXES)
 		foreach(build_type ${CMAKE_CONFIGURATION_TYPES})
 			string(TOUPPER "${build_type}" build_type_upper)
-			if("${build_type_upper}" STREQUAL "RELEASE")
+			if(${build_type_upper} STREQUAL "RELEASE")
 				set(build_type_tag "") # Don't create release mode tag on installed directory
 			else()
 				set(build_type_tag "${build_type}")
@@ -367,13 +367,18 @@ endfunction()
 # should be installed to all build type toolboxes
 function(install_matlab_scripts source_directory patterns)
 	set(patterns_args "")
+	set(exclude_patterns "")
+	if(NOT GTSAM_WRAP_SERIALIZATION)
+	    set(exclude_patterns "testSerialization.m")
+	endif()
+
 	foreach(pattern ${patterns})
 		list(APPEND patterns_args PATTERN "${pattern}")
 	endforeach()
 	if(GTSAM_BUILD_TYPE_POSTFIXES)
 		foreach(build_type ${CMAKE_CONFIGURATION_TYPES})
 			string(TOUPPER "${build_type}" build_type_upper)
-			if("${build_type_upper}" STREQUAL "RELEASE")
+			if(${build_type_upper} STREQUAL "RELEASE")
 				set(build_type_tag "") # Don't create release mode tag on installed directory
 			else()
 				set(build_type_tag "${build_type}")
@@ -381,10 +386,10 @@ function(install_matlab_scripts source_directory patterns)
 			# Split up filename to strip trailing '/' in GTSAM_TOOLBOX_INSTALL_PATH if there is one
 			get_filename_component(location "${GTSAM_TOOLBOX_INSTALL_PATH}" PATH)
 			get_filename_component(name "${GTSAM_TOOLBOX_INSTALL_PATH}" NAME)
-			install(DIRECTORY "${source_directory}" DESTINATION "${location}/${name}${build_type_tag}" CONFIGURATIONS "${build_type}" FILES_MATCHING ${patterns_args} PATTERN ".svn" EXCLUDE)
+			install(DIRECTORY "${source_directory}" DESTINATION "${location}/${name}${build_type_tag}" CONFIGURATIONS "${build_type}" FILES_MATCHING ${patterns_args} PATTERN "${exclude_patterns}" EXCLUDE)
 		endforeach()
 	else()
-		install(DIRECTORY "${source_directory}" DESTINATION "${GTSAM_TOOLBOX_INSTALL_PATH}" FILES_MATCHING ${patterns_args} PATTERN ".svn" EXCLUDE)
+		install(DIRECTORY "${source_directory}" DESTINATION "${GTSAM_TOOLBOX_INSTALL_PATH}" FILES_MATCHING ${patterns_args} PATTERN "${exclude_patterns}" EXCLUDE)
 	endif()
 
 endfunction()
diff --git a/examples/SolverComparer.cpp b/examples/SolverComparer.cpp
index 923b0b9de..0393affe1 100644
--- a/examples/SolverComparer.cpp
+++ b/examples/SolverComparer.cpp
@@ -31,28 +31,29 @@
 *
 */
 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
 #include 
-#include 
-#include 
-#include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
-#include 
-#include 
-#include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
+#include 
+
+#include 
+#include 
 
 #ifdef GTSAM_USE_TBB
 #include 
@@ -72,23 +73,6 @@ typedef NoiseModelFactor1 NM1;
 typedef NoiseModelFactor2 NM2;
 typedef BearingRangeFactor BR;
 
-//GTSAM_VALUE_EXPORT(Value);
-//GTSAM_VALUE_EXPORT(Pose);
-//GTSAM_VALUE_EXPORT(Rot2);
-//GTSAM_VALUE_EXPORT(Point2);
-//GTSAM_VALUE_EXPORT(NonlinearFactor);
-//GTSAM_VALUE_EXPORT(NoiseModelFactor);
-//GTSAM_VALUE_EXPORT(NM1);
-//GTSAM_VALUE_EXPORT(NM2);
-//GTSAM_VALUE_EXPORT(BetweenFactor);
-//GTSAM_VALUE_EXPORT(PriorFactor);
-//GTSAM_VALUE_EXPORT(BR);
-//GTSAM_VALUE_EXPORT(noiseModel::Base);
-//GTSAM_VALUE_EXPORT(noiseModel::Isotropic);
-//GTSAM_VALUE_EXPORT(noiseModel::Gaussian);
-//GTSAM_VALUE_EXPORT(noiseModel::Diagonal);
-//GTSAM_VALUE_EXPORT(noiseModel::Unit);
-
 double chi2_red(const gtsam::NonlinearFactorGraph& graph, const gtsam::Values& config) {
   // Compute degrees of freedom (observations - variables)
   // In ocaml, +1 was added to the observations to account for the prior, but
@@ -269,12 +253,12 @@ void runIncremental()
       boost::dynamic_pointer_cast >(datasetMeasurements[nextMeasurement]))
     {
       Key key1 = measurement->key1(), key2 = measurement->key2();
-      if((key1 >= firstStep && key1 < key2) || (key2 >= firstStep && key2 < key1)) {
+      if(((int)key1 >= firstStep && key1 < key2) || ((int)key2 >= firstStep && key2 < key1)) {
         // We found an odometry starting at firstStep
         firstPose = std::min(key1, key2);
         break;
       }
-      if((key2 >= firstStep && key1 < key2) || (key1 >= firstStep && key2 < key1)) {
+      if(((int)key2 >= firstStep && key1 < key2) || ((int)key1 >= firstStep && key2 < key1)) {
         // We found an odometry joining firstStep with a previous pose
         havePreviousPose = true;
         firstPose = std::max(key1, key2);
@@ -303,7 +287,9 @@ void runIncremental()
 
   cout << "Playing forward time steps..." << endl;
 
-  for(size_t step = firstPose; nextMeasurement < datasetMeasurements.size() && (lastStep == -1 || step <= lastStep); ++step)
+  for (size_t step = firstPose;
+      nextMeasurement < datasetMeasurements.size() && (lastStep == -1 || (int)step <= lastStep);
+      ++step)
   {
     Values newVariables;
     NonlinearFactorGraph newFactors;
diff --git a/gtsam.h b/gtsam.h
index 1aee996dc..70f3b566f 100644
--- a/gtsam.h
+++ b/gtsam.h
@@ -288,6 +288,32 @@ class Point2 {
   void serialize() const;
 };
 
+// std::vector
+class Point2Vector
+{
+  // Constructors
+  Point2Vector();
+  Point2Vector(const gtsam::Point2Vector& v);
+
+  //Capacity
+  size_t size() const;
+  size_t max_size() const;
+  void resize(size_t sz);
+  size_t capacity() const;
+  bool empty() const;
+  void reserve(size_t n);
+
+  //Element access
+  gtsam::Point2 at(size_t n) const;
+  gtsam::Point2 front() const;
+  gtsam::Point2 back() const;
+
+  //Modifiers
+  void assign(size_t n, const gtsam::Point2& u);
+  void push_back(const gtsam::Point2& x);
+  void pop_back();
+};
+
 class StereoPoint2 {
   // Standard Constructors
   StereoPoint2();
@@ -304,8 +330,6 @@ class StereoPoint2 {
   gtsam::StereoPoint2 between(const gtsam::StereoPoint2& p2) const;
 
   // Manifold
-  static size_t Dim();
-  size_t dim() const;
   gtsam::StereoPoint2 retract(Vector v) const;
   Vector localCoordinates(const gtsam::StereoPoint2& p) const;
 
@@ -550,6 +574,16 @@ class Pose3 {
   void serialize() const;
 };
 
+// std::vector
+class Pose3Vector
+{
+  Pose3Vector();
+  size_t size() const;
+  bool empty() const;
+  gtsam::Pose3 at(size_t n) const;
+  void push_back(const gtsam::Pose3& x);
+};
+
 #include 
 class Unit3 {
   // Standard Constructors
@@ -788,56 +822,16 @@ class CalibratedCamera {
   void serialize() const;
 };
 
-class SimpleCamera {
-  // Standard Constructors and Named Constructors
-  SimpleCamera();
-  SimpleCamera(const gtsam::Pose3& pose);
-  SimpleCamera(const gtsam::Pose3& pose, const gtsam::Cal3_S2& K);
-  static gtsam::SimpleCamera Level(const gtsam::Cal3_S2& K,
-      const gtsam::Pose2& pose, double height);
-  static gtsam::SimpleCamera Level(const gtsam::Pose2& pose, double height);
-  static gtsam::SimpleCamera Lookat(const gtsam::Point3& eye,
-      const gtsam::Point3& target, const gtsam::Point3& upVector,
-      const gtsam::Cal3_S2& K);
-
-  // Testable
-  void print(string s) const;
-  bool equals(const gtsam::SimpleCamera& camera, double tol) const;
-
-  // Standard Interface
-  gtsam::Pose3 pose() const;
-  gtsam::Cal3_S2 calibration();
-
-  // Manifold
-  gtsam::SimpleCamera retract(const Vector& d) const;
-  Vector localCoordinates(const gtsam::SimpleCamera& T2) const;
-  size_t dim() const;
-  static size_t Dim();
-
-  // Transformations and measurement functions
-  static gtsam::Point2 project_to_camera(const gtsam::Point3& cameraPoint);
-  pair projectSafe(const gtsam::Point3& pw) const;
-  gtsam::Point2 project(const gtsam::Point3& point);
-  gtsam::Point3 backproject(const gtsam::Point2& p, double depth) const;
-  double range(const gtsam::Point3& point);
-  double range(const gtsam::Pose3& point);
-
-  // enabling serialization functionality
-  void serialize() const;
-};
-
-template
+template
 class PinholeCamera {
   // Standard Constructors and Named Constructors
   PinholeCamera();
   PinholeCamera(const gtsam::Pose3& pose);
-  PinholeCamera(const gtsam::Pose3& pose, const gtsam::Cal3DS2& K);
-  static This Level(const gtsam::Cal3DS2& K,
-    const gtsam::Pose2& pose, double height);
+  PinholeCamera(const gtsam::Pose3& pose, const CALIBRATION& K);
+  static This Level(const CALIBRATION& K, const gtsam::Pose2& pose, double height);
   static This Level(const gtsam::Pose2& pose, double height);
-  static This Lookat(const gtsam::Point3& eye,
-    const gtsam::Point3& target, const gtsam::Point3& upVector,
-    const gtsam::Cal3DS2& K);
+  static This Lookat(const gtsam::Point3& eye, const gtsam::Point3& target,
+      const gtsam::Point3& upVector, const CALIBRATION& K);
 
   // Testable
   void print(string s) const;
@@ -865,6 +859,50 @@ class PinholeCamera {
   void serialize() const;
 };
 
+virtual class SimpleCamera {
+  // Standard Constructors and Named Constructors
+  SimpleCamera();
+  SimpleCamera(const gtsam::Pose3& pose);
+  SimpleCamera(const gtsam::Pose3& pose, const gtsam::Cal3_S2& K);
+  static gtsam::SimpleCamera Level(const gtsam::Cal3_S2& K, const gtsam::Pose2& pose, double height);
+  static gtsam::SimpleCamera Level(const gtsam::Pose2& pose, double height);
+  static gtsam::SimpleCamera Lookat(const gtsam::Point3& eye, const gtsam::Point3& target,
+      const gtsam::Point3& upVector, const gtsam::Cal3_S2& K);
+
+  // Testable
+  void print(string s) const;
+  bool equals(const gtsam::SimpleCamera& camera, double tol) const;
+
+  // Standard Interface
+  gtsam::Pose3 pose() const;
+  gtsam::Cal3_S2 calibration() const;
+
+  // Manifold
+  gtsam::SimpleCamera retract(const Vector& d) const;
+  Vector localCoordinates(const gtsam::SimpleCamera& T2) const;
+  size_t dim() const;
+  static size_t Dim();
+
+  // Transformations and measurement functions
+  static gtsam::Point2 project_to_camera(const gtsam::Point3& cameraPoint);
+  pair projectSafe(const gtsam::Point3& pw) const;
+  gtsam::Point2 project(const gtsam::Point3& point);
+  gtsam::Point3 backproject(const gtsam::Point2& p, double depth) const;
+  double range(const gtsam::Point3& point);
+  double range(const gtsam::Pose3& point);
+
+  // enabling serialization functionality
+  void serialize() const;
+
+};
+
+// Some typedefs for common camera types
+// PinholeCameraCal3_S2 is the same as SimpleCamera above
+typedef gtsam::PinholeCamera PinholeCameraCal3_S2;
+typedef gtsam::PinholeCamera PinholeCameraCal3DS2;
+typedef gtsam::PinholeCamera PinholeCameraCal3Unified;
+typedef gtsam::PinholeCamera PinholeCameraCal3Bundler;
+
 class StereoCamera {
   // Standard Constructors and Named Constructors
   StereoCamera();
@@ -893,6 +931,16 @@ class StereoCamera {
   void serialize() const;
 };
 
+#include 
+
+// Templates appear not yet supported for free functions
+gtsam::Point3 triangulatePoint3(const gtsam::Pose3Vector& poses,
+    gtsam::Cal3_S2* sharedCal, const gtsam::Point2Vector& measurements,
+    double rank_tol, bool optimize);
+gtsam::Point3 triangulatePoint3(const gtsam::Pose3Vector& poses,
+    gtsam::Cal3Bundler* sharedCal, const gtsam::Point2Vector& measurements,
+    double rank_tol, bool optimize);
+
 //*************************************************************************
 // Symbolic
 //*************************************************************************
@@ -2176,9 +2224,6 @@ class NonlinearISAM {
 //*************************************************************************
 // Nonlinear factor types
 //*************************************************************************
-#include 
-#include 
-#include 
 #include 
 #include 
 #include 
diff --git a/gtsam/3rdparty/CMakeLists.txt b/gtsam/3rdparty/CMakeLists.txt
index 301548dcf..4adbfb250 100644
--- a/gtsam/3rdparty/CMakeLists.txt
+++ b/gtsam/3rdparty/CMakeLists.txt
@@ -58,10 +58,10 @@ add_subdirectory(ceres)
 include(GeographicLib/cmake/FindGeographicLib.cmake)
 
 # Set up the option to install GeographicLib
-if(GEOGRAPHICLIB_FOUND)
-  set(install_geographiclib_default OFF)
-else()
+if(GEOGRAPHICLIB-NOTFOUND)
   set(install_geographiclib_default ON)
+else()
+  set(install_geographiclib_default OFF)
 endif()
 option(GTSAM_INSTALL_GEOGRAPHICLIB "Build and install the 3rd-party library GeographicLib" ${install_geographiclib_default})
 
diff --git a/gtsam/3rdparty/Eigen/.hg_archival.txt b/gtsam/3rdparty/Eigen/.hg_archival.txt
index 9fceca658..aea5a5515 100644
--- a/gtsam/3rdparty/Eigen/.hg_archival.txt
+++ b/gtsam/3rdparty/Eigen/.hg_archival.txt
@@ -1,4 +1,4 @@
 repo: 8a21fd850624c931e448cbcfb38168cb2717c790
-node: ffa86ffb557094721ca71dcea6aed2651b9fd610
+node: 10219c95fe653d4962aa9db4946f6fbea96dd740
 branch: 3.2
-tag: 3.2.0
+tag: 3.2.4
diff --git a/gtsam/3rdparty/Eigen/.hgtags b/gtsam/3rdparty/Eigen/.hgtags
index 1b9b1142e..7a6e19411 100644
--- a/gtsam/3rdparty/Eigen/.hgtags
+++ b/gtsam/3rdparty/Eigen/.hgtags
@@ -23,3 +23,7 @@ bf4cb8c934fa3a79f45f1e629610f0225e93e493 3.1.0-rc2
 da195914abcc1d739027cbee7c52077aab30b336 3.2-beta1
 4b687cad1d23066f66863f4f87298447298443df 3.2-rc1
 1eeda7b1258bcd306018c0738e2b6a8543661141 3.2-rc2
+ffa86ffb557094721ca71dcea6aed2651b9fd610 3.2.0
+6b38706d90a9fe182e66ab88477b3dbde34b9f66 3.2.1
+1306d75b4a21891e59ff9bd96678882cf831e39f 3.2.2
+36fd1ba04c120cfdd90f3e4cede47f43b21d19ad 3.2.3
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Cholesky/LDLT.h b/gtsam/3rdparty/Eigen/Eigen/src/Cholesky/LDLT.h
index c52b7d1a6..02ab93880 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Cholesky/LDLT.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Cholesky/LDLT.h
@@ -442,6 +442,7 @@ LDLT& LDLT::compute(const MatrixType& a)
   m_transpositions.resize(size);
   m_isInitialized = false;
   m_temporary.resize(size);
+  m_sign = internal::ZeroSign;
 
   internal::ldlt_inplace::unblocked(m_matrix, m_transpositions, m_temporary, m_sign);
 
@@ -502,7 +503,6 @@ struct solve_retval, Rhs>
     using std::abs;
     using std::max;
     typedef typename LDLTType::MatrixType MatrixType;
-    typedef typename LDLTType::Scalar Scalar;
     typedef typename LDLTType::RealScalar RealScalar;
     const typename Diagonal::RealReturnType vectorD(dec().vectorD());
     // In some previous versions, tolerance was set to the max of 1/highest and the maximal diagonal entry * epsilon
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/ArrayWrapper.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/ArrayWrapper.h
index a791bc358..b4641e2a0 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/ArrayWrapper.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/ArrayWrapper.h
@@ -29,6 +29,11 @@ struct traits >
   : public traits::type >
 {
   typedef ArrayXpr XprKind;
+  // Let's remove NestByRefBit
+  enum {
+    Flags0 = traits::type >::Flags,
+    Flags = Flags0 & ~NestByRefBit
+  };
 };
 }
 
@@ -149,6 +154,11 @@ struct traits >
  : public traits::type >
 {
   typedef MatrixXpr XprKind;
+  // Let's remove NestByRefBit
+  enum {
+    Flags0 = traits::type >::Flags,
+    Flags = Flags0 & ~NestByRefBit
+  };
 };
 }
 
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/DenseBase.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/DenseBase.h
index c5800f6c8..04862f374 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/DenseBase.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/DenseBase.h
@@ -462,8 +462,10 @@ template class DenseBase
     template RealScalar lpNorm() const;
 
     template
-    const Replicate replicate() const;
-    const Replicate replicate(Index rowFacor,Index colFactor) const;
+    inline const Replicate replicate() const;
+    
+    typedef Replicate ReplicateReturnType;
+    inline const ReplicateReturnType replicate(Index rowFacor,Index colFactor) const;
 
     typedef Reverse ReverseReturnType;
     typedef const Reverse ConstReverseReturnType;
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/Diagonal.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/Diagonal.h
index aab8007b3..68cf6d4b0 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/Diagonal.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/Diagonal.h
@@ -190,18 +190,18 @@ MatrixBase::diagonal() const
   *
   * \sa MatrixBase::diagonal(), class Diagonal */
 template
-inline typename MatrixBase::template DiagonalIndexReturnType::Type
+inline typename MatrixBase::DiagonalDynamicIndexReturnType
 MatrixBase::diagonal(Index index)
 {
-  return typename DiagonalIndexReturnType::Type(derived(), index);
+  return DiagonalDynamicIndexReturnType(derived(), index);
 }
 
 /** This is the const version of diagonal(Index). */
 template
-inline typename MatrixBase::template ConstDiagonalIndexReturnType::Type
+inline typename MatrixBase::ConstDiagonalDynamicIndexReturnType
 MatrixBase::diagonal(Index index) const
 {
-  return typename ConstDiagonalIndexReturnType::Type(derived(), index);
+  return ConstDiagonalDynamicIndexReturnType(derived(), index);
 }
 
 /** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/GeneralProduct.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/GeneralProduct.h
index 2a59d9464..9e805a80f 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/GeneralProduct.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/GeneralProduct.h
@@ -232,7 +232,7 @@ EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest&
   // FIXME not very good if rhs is real and lhs complex while alpha is real too
   const Index cols = dest.cols();
   for (Index j=0; j
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/MapBase.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/MapBase.h
index ab50c9b81..cebed2bb6 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/MapBase.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/MapBase.h
@@ -168,6 +168,7 @@ template class MapBase
 template class MapBase
   : public MapBase
 {
+    typedef MapBase ReadOnlyMapBase;
   public:
 
     typedef MapBase Base;
@@ -230,11 +231,13 @@ template class MapBase
 
     Derived& operator=(const MapBase& other)
     {
-      Base::Base::operator=(other);
+      ReadOnlyMapBase::Base::operator=(other);
       return derived();
     }
 
-    using Base::Base::operator=;
+    // In theory we could simply refer to Base:Base::operator=, but MSVC does not like Base::Base,
+    // see bugs 821 and 920.
+    using ReadOnlyMapBase::Base::operator=;
 };
 
 #undef EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/MatrixBase.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/MatrixBase.h
index 344b38f2f..cc3279746 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/MatrixBase.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/MatrixBase.h
@@ -215,7 +215,7 @@ template class MatrixBase
 
     typedef Diagonal DiagonalReturnType;
     DiagonalReturnType diagonal();
-	typedef typename internal::add_const >::type ConstDiagonalReturnType;
+    typedef typename internal::add_const >::type ConstDiagonalReturnType;
     ConstDiagonalReturnType diagonal() const;
 
     template struct DiagonalIndexReturnType { typedef Diagonal Type; };
@@ -223,16 +223,12 @@ template class MatrixBase
 
     template typename DiagonalIndexReturnType::Type diagonal();
     template typename ConstDiagonalIndexReturnType::Type diagonal() const;
+    
+    typedef Diagonal DiagonalDynamicIndexReturnType;
+    typedef typename internal::add_const >::type ConstDiagonalDynamicIndexReturnType;
 
-    // Note: The "MatrixBase::" prefixes are added to help MSVC9 to match these declarations with the later implementations.
-    // On the other hand they confuse MSVC8...
-    #if (defined _MSC_VER) && (_MSC_VER >= 1500) // 2008 or later
-    typename MatrixBase::template DiagonalIndexReturnType::Type diagonal(Index index);
-    typename MatrixBase::template ConstDiagonalIndexReturnType::Type diagonal(Index index) const;
-    #else
-    typename DiagonalIndexReturnType::Type diagonal(Index index);
-    typename ConstDiagonalIndexReturnType::Type diagonal(Index index) const;
-    #endif
+    DiagonalDynamicIndexReturnType diagonal(Index index);
+    ConstDiagonalDynamicIndexReturnType diagonal(Index index) const;
 
     #ifdef EIGEN2_SUPPORT
     template typename internal::eigen2_part_return_type::type part();
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/PermutationMatrix.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/PermutationMatrix.h
index 1297b8413..f26f3e5cc 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/PermutationMatrix.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/PermutationMatrix.h
@@ -555,7 +555,10 @@ struct permut_matrix_product_retval
       const Index n = Side==OnTheLeft ? rows() : cols();
       // FIXME we need an is_same for expression that is not sensitive to constness. For instance
       // is_same_xpr, Block >::value should be true.
-      if(is_same::value && extract_data(dst) == extract_data(m_matrix))
+      if(    is_same::value
+          && blas_traits::HasUsableDirectAccess
+          && blas_traits::HasUsableDirectAccess
+          && extract_data(dst) == extract_data(m_matrix))
       {
         // apply the permutation inplace
         Matrix mask(m_permutation.size());
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/ProductBase.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/ProductBase.h
index a494b5f87..cf74470a9 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/ProductBase.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/ProductBase.h
@@ -85,7 +85,14 @@ class ProductBase : public MatrixBase
 
   public:
 
+#ifndef EIGEN_NO_MALLOC
+    typedef typename Base::PlainObject BasePlainObject;
+    typedef Matrix DynPlainObject;
+    typedef typename internal::conditional<(BasePlainObject::SizeAtCompileTime==Dynamic) || (BasePlainObject::SizeAtCompileTime*int(sizeof(Scalar)) < int(EIGEN_STACK_ALLOCATION_LIMIT)),
+                                           BasePlainObject, DynPlainObject>::type PlainObject;
+#else
     typedef typename Base::PlainObject PlainObject;
+#endif
 
     ProductBase(const Lhs& a_lhs, const Rhs& a_rhs)
       : m_lhs(a_lhs), m_rhs(a_rhs)
@@ -180,7 +187,12 @@ namespace internal {
 template
 struct nested, N, PlainObject>
 {
-  typedef PlainObject const& type;
+  typedef typename GeneralProduct::PlainObject const& type;
+};
+template
+struct nested, N, PlainObject>
+{
+  typedef typename GeneralProduct::PlainObject const& type;
 };
 }
 
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/Ref.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/Ref.h
index cd6d949c4..df87b1af4 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/Ref.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/Ref.h
@@ -188,6 +188,8 @@ template class Ref
   : public RefBase[ >
 {
     typedef internal::traits][ Traits;
+    template
+    inline Ref(const PlainObjectBase& expr);
   public:
 
     typedef RefBase][ Base;
@@ -196,20 +198,21 @@ template class Ref
 
     #ifndef EIGEN_PARSED_BY_DOXYGEN
     template
-    inline Ref(PlainObjectBase& expr,
-               typename internal::enable_if::MatchAtCompileTime),Derived>::type* = 0)
+    inline Ref(PlainObjectBase& expr)
     {
-      Base::construct(expr);
+      EIGEN_STATIC_ASSERT(static_cast(Traits::template match::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
+      Base::construct(expr.derived());
     }
     template
-    inline Ref(const DenseBase& expr,
-               typename internal::enable_if::value&&bool(Traits::template match::MatchAtCompileTime)),Derived>::type* = 0,
-               int = Derived::ThisConstantIsPrivateInPlainObjectBase)
+    inline Ref(const DenseBase& expr)
     #else
     template
     inline Ref(DenseBase& expr)
     #endif
     {
+      EIGEN_STATIC_ASSERT(static_cast(internal::is_lvalue::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
+      EIGEN_STATIC_ASSERT(static_cast(Traits::template match::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
+      enum { THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY = Derived::ThisConstantIsPrivateInPlainObjectBase};
       Base::construct(expr.const_cast_derived());
     }
 
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/Replicate.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/Replicate.h
index dde86a834..ac4537c14 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/Replicate.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/Replicate.h
@@ -135,7 +135,7 @@ template class Replicate
   */
 template
 template
-inline const Replicate
+const Replicate
 DenseBase::replicate() const
 {
   return Replicate(derived());
@@ -150,7 +150,7 @@ DenseBase::replicate() const
   * \sa VectorwiseOp::replicate(), DenseBase::replicate(), class Replicate
   */
 template
-inline const Replicate
+const typename DenseBase::ReplicateReturnType
 DenseBase::replicate(Index rowFactor,Index colFactor) const
 {
   return Replicate(derived(),rowFactor,colFactor);
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/TriangularMatrix.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/TriangularMatrix.h
index 845ae1aec..4d65392c6 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/TriangularMatrix.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/TriangularMatrix.h
@@ -380,19 +380,19 @@ template class TriangularView
     EIGEN_STRONG_INLINE TriangularView& operator=(const ProductBase& other)
     {
       setZero();
-      return assignProduct(other,1);
+      return assignProduct(other.derived(),1);
     }
     
     template
     EIGEN_STRONG_INLINE TriangularView& operator+=(const ProductBase& other)
     {
-      return assignProduct(other,1);
+      return assignProduct(other.derived(),1);
     }
     
     template
     EIGEN_STRONG_INLINE TriangularView& operator-=(const ProductBase& other)
     {
-      return assignProduct(other,-1);
+      return assignProduct(other.derived(),-1);
     }
     
     
@@ -400,25 +400,34 @@ template class TriangularView
     EIGEN_STRONG_INLINE TriangularView& operator=(const ScaledProduct& other)
     {
       setZero();
-      return assignProduct(other,other.alpha());
+      return assignProduct(other.derived(),other.alpha());
     }
     
     template
     EIGEN_STRONG_INLINE TriangularView& operator+=(const ScaledProduct& other)
     {
-      return assignProduct(other,other.alpha());
+      return assignProduct(other.derived(),other.alpha());
     }
     
     template
     EIGEN_STRONG_INLINE TriangularView& operator-=(const ScaledProduct& other)
     {
-      return assignProduct(other,-other.alpha());
+      return assignProduct(other.derived(),-other.alpha());
     }
     
   protected:
     
     template
     EIGEN_STRONG_INLINE TriangularView& assignProduct(const ProductBase& prod, const Scalar& alpha);
+    
+    template
+    EIGEN_STRONG_INLINE TriangularView& assignProduct(const TriangularProduct& prod, const Scalar& alpha)
+    {
+      lazyAssign(alpha*prod.eval());
+      return *this;
+    }
 
     MatrixTypeNested m_matrix;
 };
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/arch/NEON/Complex.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/arch/NEON/Complex.h
index f183d31de..8d9255eef 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/arch/NEON/Complex.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/arch/NEON/Complex.h
@@ -110,7 +110,7 @@ template<> EIGEN_STRONG_INLINE Packet2cf ploaddup(const std::complex<
 template<> EIGEN_STRONG_INLINE void pstore  >(std::complex *   to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((float*)to, from.v); }
 template<> EIGEN_STRONG_INLINE void pstoreu >(std::complex *   to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v); }
 
-template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex *   addr) { __pld((float *)addr); }
+template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex *   addr) { EIGEN_ARM_PREFETCH((float *)addr); }
 
 template<> EIGEN_STRONG_INLINE std::complex  pfirst(const Packet2cf& a)
 {
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h
index 163bac215..94dfab330 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h
@@ -48,9 +48,18 @@ typedef uint32x4_t  Packet4ui;
   #define EIGEN_INIT_NEON_PACKET2(X, Y)       {X, Y}
   #define EIGEN_INIT_NEON_PACKET4(X, Y, Z, W) {X, Y, Z, W}
 #endif
-    
-#ifndef __pld
-#define __pld(x) asm volatile ( "   pld [%[addr]]\n" :: [addr] "r" (x) : "cc" );
+
+// arm64 does have the pld instruction. If available, let's trust the __builtin_prefetch built-in function
+// which available on LLVM and GCC (at least)
+#if EIGEN_HAS_BUILTIN(__builtin_prefetch) || defined(__GNUC__)
+  #define EIGEN_ARM_PREFETCH(ADDR) __builtin_prefetch(ADDR);
+#elif defined __pld
+  #define EIGEN_ARM_PREFETCH(ADDR) __pld(ADDR)
+#elif !defined(__aarch64__)
+  #define EIGEN_ARM_PREFETCH(ADDR) __asm__ __volatile__ ( "   pld [%[addr]]\n" :: [addr] "r" (ADDR) : "cc" );
+#else
+  // by default no explicit prefetching
+  #define EIGEN_ARM_PREFETCH(ADDR)
 #endif
 
 template<> struct packet_traits  : default_packet_traits
@@ -209,8 +218,8 @@ template<> EIGEN_STRONG_INLINE void pstore(int*       to, const Packet4i& f
 template<> EIGEN_STRONG_INLINE void pstoreu(float*  to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_f32(to, from); }
 template<> EIGEN_STRONG_INLINE void pstoreu(int*      to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_s32(to, from); }
 
-template<> EIGEN_STRONG_INLINE void prefetch(const float* addr) { __pld(addr); }
-template<> EIGEN_STRONG_INLINE void prefetch(const int*     addr) { __pld(addr); }
+template<> EIGEN_STRONG_INLINE void prefetch(const float* addr) { EIGEN_ARM_PREFETCH(addr); }
+template<> EIGEN_STRONG_INLINE void prefetch(const int*     addr) { EIGEN_ARM_PREFETCH(addr); }
 
 // FIXME only store the 2 first elements ?
 template<> EIGEN_STRONG_INLINE float  pfirst(const Packet4f& a) { float EIGEN_ALIGN16 x[4]; vst1q_f32(x, a); return x[0]; }
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/arch/SSE/MathFunctions.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/arch/SSE/MathFunctions.h
index 99cbd0d95..d16f30bb0 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/arch/SSE/MathFunctions.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/arch/SSE/MathFunctions.h
@@ -52,7 +52,7 @@ Packet4f plog(const Packet4f& _x)
 
   Packet4i emm0;
 
-  Packet4f invalid_mask = _mm_cmplt_ps(x, _mm_setzero_ps());
+  Packet4f invalid_mask = _mm_cmpnge_ps(x, _mm_setzero_ps()); // not greater equal is true if x is NaN
   Packet4f iszero_mask = _mm_cmpeq_ps(x, _mm_setzero_ps());
 
   x = pmax(x, p4f_min_norm_pos);  /* cut off denormalized stuff */
@@ -166,7 +166,7 @@ Packet4f pexp(const Packet4f& _x)
   emm0 = _mm_cvttps_epi32(fx);
   emm0 = _mm_add_epi32(emm0, p4i_0x7f);
   emm0 = _mm_slli_epi32(emm0, 23);
-  return pmul(y, _mm_castsi128_ps(emm0));
+  return pmax(pmul(y, Packet4f(_mm_castsi128_ps(emm0))), _x);
 }
 template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
 Packet2d pexp(const Packet2d& _x)
@@ -239,7 +239,7 @@ Packet2d pexp(const Packet2d& _x)
   emm0 = _mm_add_epi32(emm0, p4i_1023_0);
   emm0 = _mm_slli_epi32(emm0, 20);
   emm0 = _mm_shuffle_epi32(emm0, _MM_SHUFFLE(1,2,0,3));
-  return pmul(x, _mm_castsi128_pd(emm0));
+  return pmax(pmul(x, Packet2d(_mm_castsi128_pd(emm0))), _x);
 }
 
 /* evaluation of 4 sines at onces, using SSE2 intrinsics.
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/products/CoeffBasedProduct.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/products/CoeffBasedProduct.h
index c06a0df1c..421f925e1 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/products/CoeffBasedProduct.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/products/CoeffBasedProduct.h
@@ -90,6 +90,7 @@ struct traits >
             | (SameType && (CanVectorizeLhs || CanVectorizeRhs) ? PacketAccessBit : 0),
 
       CoeffReadCost = InnerSize == Dynamic ? Dynamic
+                    : InnerSize == 0 ? 0
                     : InnerSize * (NumTraits::MulCost + LhsCoeffReadCost + RhsCoeffReadCost)
                       + (InnerSize - 1) * NumTraits::AddCost,
 
@@ -133,7 +134,7 @@ class CoeffBasedProduct
     };
 
     typedef internal::product_coeff_impl ScalarCoeffImpl;
 
     typedef CoeffBasedProduct LazyCoeffBasedProductType;
@@ -184,7 +185,7 @@ class CoeffBasedProduct
     {
       PacketScalar res;
       internal::product_packet_impl
         ::run(row, col, m_lhs, m_rhs, res);
       return res;
@@ -262,10 +263,7 @@ struct product_coeff_impl
   typedef typename Lhs::Index Index;
   static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar& res)
   {
-    eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix");
-    res = lhs.coeff(row, 0) * rhs.coeff(0, col);
-      for(Index i = 1; i < lhs.cols(); ++i)
-        res += lhs.coeff(row, i) * rhs.coeff(i, col);
+    res = (lhs.row(row).transpose().cwiseProduct( rhs.col(col) )).sum();
   }
 };
 
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/util/Macros.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/util/Macros.h
index 3a010ec6a..6d1e6c133 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/util/Macros.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/util/Macros.h
@@ -13,7 +13,7 @@
 
 #define EIGEN_WORLD_VERSION 3
 #define EIGEN_MAJOR_VERSION 2
-#define EIGEN_MINOR_VERSION 2
+#define EIGEN_MINOR_VERSION 4
 
 #define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
                                       (EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
@@ -96,6 +96,13 @@
 #define EIGEN_DEFAULT_DENSE_INDEX_TYPE std::ptrdiff_t
 #endif
 
+// Cross compiler wrapper around LLVM's __has_builtin
+#ifdef __has_builtin
+#  define EIGEN_HAS_BUILTIN(x) __has_builtin(x)
+#else
+#  define EIGEN_HAS_BUILTIN(x) 0
+#endif
+
 /** Allows to disable some optimizations which might affect the accuracy of the result.
   * Such optimization are enabled by default, and set EIGEN_FAST_MATH to 0 to disable them.
   * They currently include:
@@ -247,7 +254,7 @@ namespace Eigen {
 
 #if !defined(EIGEN_ASM_COMMENT)
   #if (defined __GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
-    #define EIGEN_ASM_COMMENT(X)  asm("#" X)
+    #define EIGEN_ASM_COMMENT(X)  __asm__("#" X)
   #else
     #define EIGEN_ASM_COMMENT(X)
   #endif
@@ -306,7 +313,7 @@ namespace Eigen {
 // just an empty macro !
 #define EIGEN_EMPTY
 
-#if defined(_MSC_VER) && (!defined(__INTEL_COMPILER))
+#if defined(_MSC_VER) && (_MSC_VER < 1900) && (!defined(__INTEL_COMPILER))
 #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
   using Base::operator =;
 #elif defined(__clang__) // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/util/Memory.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/util/Memory.h
index 6c2461725..41dd7db06 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/util/Memory.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/util/Memory.h
@@ -63,7 +63,7 @@
 // Currently, let's include it only on unix systems:
 #if defined(__unix__) || defined(__unix)
   #include 
-  #if ((defined __QNXNTO__) || (defined _GNU_SOURCE) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)
+  #if ((defined __QNXNTO__) || (defined _GNU_SOURCE) || (defined __PGI) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)
     #define EIGEN_HAS_POSIX_MEMALIGN 1
   #endif
 #endif
@@ -417,6 +417,8 @@ template inline T* conditional_aligned_realloc_new(T* pt
 
 template inline T* conditional_aligned_new_auto(size_t size)
 {
+  if(size==0)
+    return 0; // short-cut. Also fixes Bug 884
   check_size_for_overflow(size);
   T *result = reinterpret_cast(conditional_aligned_malloc(sizeof(T)*size));
   if(NumTraits::RequireInitialization)
@@ -464,9 +466,8 @@ template inline void conditional_aligned_delete_auto(T *
 template
 static inline Index first_aligned(const Scalar* array, Index size)
 {
-  enum { PacketSize = packet_traits::size,
-         PacketAlignedMask = PacketSize-1
-  };
+  static const Index PacketSize = packet_traits::size;
+  static const Index PacketAlignedMask = PacketSize-1;
 
   if(PacketSize==1)
   {
@@ -612,7 +613,6 @@ template class aligned_stack_memory_handler
       void* operator new(size_t size, const std::nothrow_t&) throw() { \
         try { return Eigen::internal::conditional_aligned_malloc(size); } \
         catch (...) { return 0; } \
-        return 0; \
       }
   #else
     #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/util/StaticAssert.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/util/StaticAssert.h
index 8872c5b64..bac5d9fe9 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/util/StaticAssert.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/util/StaticAssert.h
@@ -90,7 +90,9 @@
         YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED,
         THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE,
         THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH,
-        OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG
+        OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG,
+        IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY,
+        STORAGE_LAYOUT_DOES_NOT_MATCH
       };
     };
 
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Core/util/XprHelper.h b/gtsam/3rdparty/Eigen/Eigen/src/Core/util/XprHelper.h
index 3c4773054..781965d2c 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Core/util/XprHelper.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Core/util/XprHelper.h
@@ -341,7 +341,7 @@ template::type> str
 };
 
 template
-T* const_cast_ptr(const T* ptr)
+inline T* const_cast_ptr(const T* ptr)
 {
   return const_cast(ptr);
 }
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Eigen2Support/LeastSquares.h b/gtsam/3rdparty/Eigen/Eigen/src/Eigen2Support/LeastSquares.h
index 0e6fdb488..7992d4944 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Eigen2Support/LeastSquares.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Eigen2Support/LeastSquares.h
@@ -147,7 +147,6 @@ void fitHyperplane(int numPoints,
 
   // compute the covariance matrix
   CovMatrixType covMat = CovMatrixType::Zero(size, size);
-  VectorType remean = VectorType::Zero(size);
   for(int i = 0; i < numPoints; ++i)
   {
     VectorType diff = (*(points[i]) - mean).conjugate();
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Eigenvalues/RealQZ.h b/gtsam/3rdparty/Eigen/Eigen/src/Eigenvalues/RealQZ.h
index 5706eeebe..4f36091db 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Eigenvalues/RealQZ.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Eigenvalues/RealQZ.h
@@ -313,7 +313,7 @@ namespace Eigen {
       using std::abs;
       using std::sqrt;
       const Index dim=m_S.cols();
-      if (abs(m_S.coeff(i+1,i)==Scalar(0)))
+      if (abs(m_S.coeff(i+1,i))==Scalar(0))
         return;
       Index z = findSmallDiagEntry(i,i+1);
       if (z==i-1)
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/gtsam/3rdparty/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
index 3993046a8..be89de4a9 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
@@ -563,7 +563,6 @@ template struct direct_selfadjoint_eigenvalues::epsilon();
-      safeNorm2 *= safeNorm2;
       if((eivals(2)-eivals(0))<=Eigen::NumTraits::epsilon())
       {
         eivecs.setIdentity();
@@ -577,7 +576,7 @@ template struct direct_selfadjoint_eigenvalues d1 ? 2 : 0;
-        d0 = d0 > d1 ? d1 : d0;
+        d0 = d0 > d1 ? d0 : d1;
 
         tmp.diagonal().array () -= eivals(k);
         VectorType cross;
@@ -585,19 +584,25 @@ template struct direct_selfadjoint_eigenvaluessafeNorm2)
+        {
           eivecs.col(k) = cross / sqrt(n);
+        }
         else
         {
           n = (cross = tmp.row(0).cross(tmp.row(2))).squaredNorm();
 
           if(n>safeNorm2)
+          {
             eivecs.col(k) = cross / sqrt(n);
+          }
           else
           {
             n = (cross = tmp.row(1).cross(tmp.row(2))).squaredNorm();
 
             if(n>safeNorm2)
+            {
               eivecs.col(k) = cross / sqrt(n);
+            }
             else
             {
               // the input matrix and/or the eigenvaues probably contains some inf/NaN,
@@ -617,12 +622,16 @@ template struct direct_selfadjoint_eigenvalues::epsilon())
+        {
           eivecs.col(1) = eivecs.col(k).unitOrthogonal();
+        }
         else
         {
-          n = (cross = eivecs.col(k).cross(tmp.row(0).normalized())).squaredNorm();
+          n = (cross = eivecs.col(k).cross(tmp.row(0))).squaredNorm();
           if(n>safeNorm2)
+          {
             eivecs.col(1) = cross / sqrt(n);
+          }
           else
           {
             n = (cross = eivecs.col(k).cross(tmp.row(1))).squaredNorm();
@@ -636,13 +645,14 @@ template struct direct_selfadjoint_eigenvalues::epsilon())
+    {
+      Matrix m; m << v0.transpose(), v1.transpose();
+      JacobiSVD > svd(m, ComputeFullV);
+      result.normal() = svd.matrixV().col(2);
+    }
+    else
+      result.normal() /= norm;
     result.offset() = -p0.dot(result.normal());
     return result;
   }
diff --git a/gtsam/3rdparty/Eigen/Eigen/src/Geometry/Rotation2D.h b/gtsam/3rdparty/Eigen/Eigen/src/Geometry/Rotation2D.h
index 1cac343a5..a2d59fce1 100644
--- a/gtsam/3rdparty/Eigen/Eigen/src/Geometry/Rotation2D.h
+++ b/gtsam/3rdparty/Eigen/Eigen/src/Geometry/Rotation2D.h
@@ -60,6 +60,9 @@ public:
 
   /** Construct a 2D counter clock wise rotation from the angle \a a in radian. */
   inline Rotation2D(const Scalar& a) : m_angle(a) {}
+  
+  /** Default constructor wihtout initialization. The represented rotation is undefined. */
+  Rotation2D() {}
 
   /** \returns the rotation angle */
   inline Scalar angle() const { return m_angle; }
@@ -81,10 +84,10 @@ public:
   /** Applies the rotation to a 2D vector */
   Vector2 operator* (const Vector2& vec) const
   { return toRotationMatrix() * vec; }
-
+  
   template]