diff --git a/CMakeLists.txt b/CMakeLists.txt index 91811264c..43159a935 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,14 +6,10 @@ if(NOT DEFINED CMAKE_MACOSX_RPATH) set(CMAKE_MACOSX_RPATH 0) endif() -option(GTSAM_NO_BOOST_CPP17 "Require and use boost" ON) add_definitions(-Wno-deprecated-declarations) add_definitions(-ftemplate-backtrace-limit=0) set(CMAKE_CXX_STANDARD 17) -if (GTSAM_NO_BOOST_CPP17) - add_definitions(-DNO_BOOST_CPP17) -endif() # Set the version number for the library set (GTSAM_VERSION_MAJOR 4) @@ -60,10 +56,7 @@ endif() include(cmake/HandleGeneralOptions.cmake) # CMake build options # Libraries: -# if (NOT GTSAM_NO_BOOST_CPP17) - include(cmake/HandleBoost.cmake) # Boost -# endif() - +include(cmake/HandleBoost.cmake) # Boost include(cmake/HandleCCache.cmake) # ccache include(cmake/HandleCPack.cmake) # CPack include(cmake/HandleEigen.cmake) # Eigen3 diff --git a/gtsam/nonlinear/ExpressionFactor.h b/gtsam/nonlinear/ExpressionFactor.h index 3427e6079..650bedfb1 100644 --- a/gtsam/nonlinear/ExpressionFactor.h +++ b/gtsam/nonlinear/ExpressionFactor.h @@ -28,97 +28,6 @@ namespace gtsam { -template -class EvaluateErrorInterface { -public: - enum { N = sizeof...(ValueTypes) }; - -private: - template - using IndexIsValid = typename std::enable_if<(I >= 1) && (I <= N), - void>::type; // 1-indexed! - -public: - /** - * Override `evaluateError` to finish implementing an n-way factor. - * - * Both the `x` and `H` arguments are written here as parameter packs, but - * when overriding this method, you probably want to explicitly write them - * out. For example, for a 2-way factor with variable types Pose3 and Point3, - * you should implement: - * ``` - * Vector evaluateError( - * const Pose3& x1, const Point3& x2, - * boost::optional H1 = boost::none, - * boost::optional H2 = boost::none) const override { ... } - * ``` - * - * If any of the optional Matrix reference arguments are specified, it should - * compute both the function evaluation and its derivative(s) in the requested - * variables. - * - * @param x The values of the variables to evaluate the error for. Passed in - * as separate arguments. - * @param[out] H The Jacobian with respect to each variable (optional). - */ - virtual Vector evaluateError(const ValueTypes&... x, OptionalMatrixTypeT... H) const = 0; - -#ifdef NO_BOOST_CPP17 - // if someone uses the evaluateError function by supplying all the optional - // arguments then redirect the call to the one which takes pointers - Vector evaluateError(const ValueTypes&... x, MatrixTypeT&... H) const { - return evaluateError(x..., (&H)...); - } -#endif - - /// @} - /// @name Convenience method overloads - /// @{ - - /** No-Jacobians requested function overload. - * This specializes the version below to avoid recursive calls since this is - * commonly used. - * - * e.g. `const Vector error = factor.evaluateError(pose, point);` - */ - inline Vector evaluateError(const ValueTypes&... x) const { - return evaluateError(x..., OptionalMatrixTypeT()...); - } - - /** Some (but not all) optional Jacobians are omitted (function overload) - * - * e.g. `const Vector error = factor.evaluateError(pose, point, Hpose);` - */ - template > - inline Vector evaluateError(const ValueTypes&... x, OptionalJacArgs&&... H) const { -#ifdef NO_BOOST_CPP17 - // A check to ensure all arguments passed are all either matrices or are all pointers to matrices - constexpr bool are_all_mat = (... && (std::is_same>::value)); - constexpr bool are_all_ptrs = (... && (std::is_same>::value || - std::is_same>::value)); - static_assert((are_all_mat || are_all_ptrs), - "Arguments that are passed to the evaluateError function can only be of following the types: Matrix, " - "or Matrix*"); - // if they pass all matrices then we want to pass their pointers instead - if constexpr (are_all_mat) { - return evaluateError(x..., (&H)...); - } else { - return evaluateError(x..., std::forward(H)..., static_cast(OptionalNone)); - } -#else - // A check to ensure all arguments passed are all either matrices or are optionals of matrix references - constexpr bool are_all_mat = (... && (std::is_same::value || - std::is_same>::value || - std::is_same>::value)); - static_assert( - are_all_mat, - "Arguments that are passed to the evaluateError function can only be of following the types: Matrix&, " - "boost::optional, or boost::none_t"); - return evaluateError(x..., std::forward(H)..., OptionalNone); -#endif - } -}; - /** * Factor that supports arbitrary expressions via AD. * @@ -398,14 +307,14 @@ struct traits> * @deprecated Prefer the more general ExpressionFactorN<>. */ template -class GTSAM_DEPRECATED ExpressionFactor2 : public ExpressionFactorN, public EvaluateErrorInterface { +class GTSAM_DEPRECATED ExpressionFactor2 : public ExpressionFactorN { public: /// Destructor ~ExpressionFactor2() override {} /// Backwards compatible evaluateError, to make existing tests compile - virtual Vector evaluateError(const A1& a1, const A2& a2, OptionalMatrixType H1, - OptionalMatrixType H2) const override { + Vector evaluateError(const A1& a1, const A2& a2, OptionalMatrixType H1 = OptionalNone, + OptionalMatrixType H2 = OptionalNone) const { Values values; values.insert(this->keys_[0], a1); values.insert(this->keys_[1], a2); @@ -416,6 +325,7 @@ public: return error; } + /// Recreate expression from given keys_ and measured_, used in load /// Needed to deserialize a derived factor virtual Expression expression(Key key1, Key key2) const { diff --git a/gtsam/nonlinear/NonlinearFactor.h b/gtsam/nonlinear/NonlinearFactor.h index 398bc833d..be1fbb889 100644 --- a/gtsam/nonlinear/NonlinearFactor.h +++ b/gtsam/nonlinear/NonlinearFactor.h @@ -33,11 +33,7 @@ namespace gtsam { /* ************************************************************************* */ -/* - * Some typedef based aliases to compile these interfaces without boost if - * the NO_BOOST_C17 flag is enabled - */ -#ifdef NO_BOOST_CPP17 + // These typedefs and aliases will help with making the evaluateError interface // independent of boost using OptionalNoneType = std::nullptr_t; @@ -52,16 +48,7 @@ using OptionalMatrixType = Matrix*; // independent of boost using OptionalMatrixVecType = std::vector*; #define OptionalMatrixVecNone static_cast*>(nullptr) -#else -// creating a none value to use when declaring our interfaces -using OptionalNoneType = boost::none_t; -#define OptionalNone boost::none -template -using OptionalMatrixTypeT = boost::optional; -using OptionalMatrixType = boost::optional; -using OptionalMatrixVecType = boost::optional&>; -#define OptionalMatrixVecNone boost::none -#endif + /** * Nonlinear factor base class * @@ -258,12 +245,12 @@ public: * both the function evaluation and its derivative(s) in H. */ virtual Vector unwhitenedError(const Values& x, OptionalMatrixVecType H = OptionalMatrixVecNone) const = 0; -#ifdef NO_BOOST_CPP17 + // support taking in the actual vector instead of the pointer as well Vector unwhitenedError(const Values& x, std::vector& H) const { return unwhitenedError(x, &H); } -#endif + /** * Vector of errors, whitened * This is the raw error, i.e., i.e. \f$ (h(x)-z)/\sigma \f$ in case of a Gaussian @@ -606,13 +593,11 @@ protected: virtual Vector evaluateError(const ValueTypes&... x, OptionalMatrixTypeT... H) const = 0; -#ifdef NO_BOOST_CPP17 // if someone uses the evaluateError function by supplying all the optional // arguments then redirect the call to the one which takes pointers Vector evaluateError(const ValueTypes&... x, MatrixTypeT&... H) const { return evaluateError(x..., (&H)...); } -#endif /// @} /// @name Convenience method overloads @@ -634,7 +619,6 @@ protected: */ template > inline Vector evaluateError(const ValueTypes&... x, OptionalJacArgs&&... H) const { -#ifdef NO_BOOST_CPP17 // A check to ensure all arguments passed are all either matrices or are all pointers to matrices constexpr bool are_all_mat = (... && (std::is_same>::value)); constexpr bool are_all_ptrs = (... && (std::is_same>::value || @@ -648,16 +632,6 @@ protected: } else { return evaluateError(x..., std::forward(H)..., static_cast(OptionalNone)); } -#else - // A check to ensure all arguments passed are all either matrices or are optionals of matrix references - constexpr bool are_all_mat = (... && (std::is_same::value || - std::is_same>::value || - std::is_same>::value)); - static_assert(are_all_mat, - "Arguments that are passed to the evaluateError function can only be of following the types: Matrix&, " - "boost::optional, or boost::none_t"); - return evaluateError(x..., std::forward(H)..., OptionalNone); -#endif } /// @} diff --git a/gtsam/sam/BearingFactor.h b/gtsam/sam/BearingFactor.h index 242c9b258..670e25d84 100644 --- a/gtsam/sam/BearingFactor.h +++ b/gtsam/sam/BearingFactor.h @@ -34,10 +34,9 @@ struct Bearing; */ template ::result_type> -struct BearingFactor : public ExpressionFactorN, public EvaluateErrorInterface{ +struct BearingFactor : public ExpressionFactorN { typedef ExpressionFactorN Base; - using EvaluateErrorInterface::evaluateError; /// default constructor BearingFactor() {} @@ -62,9 +61,8 @@ struct BearingFactor : public ExpressionFactorN, public EvaluateError Base::print(s, kf); } - virtual Vector evaluateError(const A1& a1, const A2& a2, - OptionalMatrixType H1, OptionalMatrixType H2) const override - { + Vector evaluateError(const A1& a1, const A2& a2, + OptionalMatrixType H1 = OptionalNone, OptionalMatrixType H2 = OptionalNone) const { std::vector Hs(2); const auto &keys = Factor::keys(); const Vector error = this->unwhitenedError( diff --git a/gtsam/sam/BearingRangeFactor.h b/gtsam/sam/BearingRangeFactor.h index bdd0888fb..4f3a38eac 100644 --- a/gtsam/sam/BearingRangeFactor.h +++ b/gtsam/sam/BearingRangeFactor.h @@ -33,7 +33,7 @@ template ::result_type, typename R = typename Range::result_type> class BearingRangeFactor - : public ExpressionFactorN, A1, A2>, public EvaluateErrorInterface{ + : public ExpressionFactorN, A1, A2> { private: typedef BearingRange T; typedef ExpressionFactorN Base; @@ -41,7 +41,6 @@ class BearingRangeFactor public: typedef boost::shared_ptr shared_ptr; - using EvaluateErrorInterface::evaluateError; /// Default constructor BearingRangeFactor() {} @@ -74,9 +73,8 @@ class BearingRangeFactor Expression(keys[1])); } - virtual Vector evaluateError(const A1& a1, const A2& a2, - OptionalMatrixType H1, OptionalMatrixType H2) const override - { + Vector evaluateError(const A1& a1, const A2& a2, + OptionalMatrixType H1 = OptionalNone, OptionalMatrixType H2 = OptionalNone) const { std::vector Hs(2); const auto &keys = Factor::keys(); const Vector error = this->unwhitenedError( diff --git a/gtsam/sam/RangeFactor.h b/gtsam/sam/RangeFactor.h index d5fb93179..e28dd5a5d 100644 --- a/gtsam/sam/RangeFactor.h +++ b/gtsam/sam/RangeFactor.h @@ -32,13 +32,12 @@ struct Range; * @ingroup sam */ template -class RangeFactor : public ExpressionFactorN , public EvaluateErrorInterface{ +class RangeFactor : public ExpressionFactorN { private: typedef RangeFactor This; typedef ExpressionFactorN Base; public: - using EvaluateErrorInterface::evaluateError; /// default constructor RangeFactor() {} @@ -60,8 +59,8 @@ class RangeFactor : public ExpressionFactorN , public EvaluateErrorIn return Expression(Range(), a1_, a2_); } - virtual Vector evaluateError(const A1& a1, const A2& a2, OptionalMatrixType H1, - OptionalMatrixType H2) const override { + Vector evaluateError(const A1& a1, const A2& a2, OptionalMatrixType H1 = OptionalNone, + OptionalMatrixType H2 = OptionalNone) const { std::vector Hs(2); const auto& keys = Factor::keys(); const Vector error = Base::unwhitenedError({{keys[0], genericValue(a1)}, {keys[1], genericValue(a2)}}, Hs); @@ -97,7 +96,7 @@ struct traits > */ template ::result_type> -class RangeFactorWithTransform : public ExpressionFactorN , public EvaluateErrorInterface{ +class RangeFactorWithTransform : public ExpressionFactorN { private: typedef RangeFactorWithTransform This; typedef ExpressionFactorN Base; @@ -105,7 +104,6 @@ class RangeFactorWithTransform : public ExpressionFactorN , public Ev A1 body_T_sensor_; ///< The pose of the sensor in the body frame public: - using EvaluateErrorInterface::evaluateError; //// Default constructor RangeFactorWithTransform() {} @@ -134,9 +132,8 @@ class RangeFactorWithTransform : public ExpressionFactorN , public Ev return Expression(Range(), nav_T_sensor_, a2_); } - virtual Vector evaluateError(const A1& a1, const A2& a2, - OptionalMatrixType H1, OptionalMatrixType H2) const override - { + Vector evaluateError(const A1& a1, const A2& a2, + OptionalMatrixType H1 = OptionalNone, OptionalMatrixType H2 = OptionalNone) const { std::vector Hs(2); const auto &keys = Factor::keys(); const Vector error = Base::unwhitenedError( @@ -147,6 +144,12 @@ class RangeFactorWithTransform : public ExpressionFactorN , public Ev return error; } + // An evaluateError overload to accept matrices (Matrix&) and pass it to the + // OptionalMatrixType evaluateError overload + Vector evaluateError(const A1& a1, const A2& a2, Matrix& H1, Matrix& H2) const { + return evaluateError(a1, a2, &H1, &H2); + } + /** print contents */ void print(const std::string& s = "", const KeyFormatter& keyFormatter = DefaultKeyFormatter) const override { diff --git a/gtsam/sam/tests/testRangeFactor.cpp b/gtsam/sam/tests/testRangeFactor.cpp index 200e1236a..6a71cbd2c 100644 --- a/gtsam/sam/tests/testRangeFactor.cpp +++ b/gtsam/sam/tests/testRangeFactor.cpp @@ -214,7 +214,7 @@ TEST( RangeFactor, Jacobian2D ) { // Use the factor to calculate the Jacobians Matrix H1Actual, H2Actual; - factor.evaluateError(pose, point, H1Actual, H2Actual); + factor.evaluateError(pose, point, &H1Actual, &H2Actual); // Use numerical derivatives to calculate the Jacobians Matrix H1Expected, H2Expected; diff --git a/gtsam/slam/EssentialMatrixFactor.h b/gtsam/slam/EssentialMatrixFactor.h index 7f3875d06..3e4a55dd6 100644 --- a/gtsam/slam/EssentialMatrixFactor.h +++ b/gtsam/slam/EssentialMatrixFactor.h @@ -295,15 +295,11 @@ class EssentialMatrixFactor3 : public EssentialMatrixFactor2 { // Version with derivatives Matrix D_e_cameraE, D_cameraE_E; // 2*5, 5*5 EssentialMatrix cameraE = E.rotate(cRb_, D_cameraE_E); -#ifdef NO_BOOST_CPP17 // Had to do this since the only overloaded function EssentialMatrixFactor2 // uses the type OptionalMatrixType. Which would be a pointer when we are // not using boost. There is no way to redirect that call to the top (NoiseModelFactorN) // dereference it and bring it back to the Base (EssentialMatrixFactor2) Vector e = Base::evaluateError(cameraE, d, &D_e_cameraE, Dd); -#else - Vector e = Base::evaluateError(cameraE, d, D_e_cameraE, Dd); -#endif *DE = D_e_cameraE * D_cameraE_E; // (2*5) * (5*5) return e; } diff --git a/gtsam_unstable/slam/BetweenFactorEM.h b/gtsam_unstable/slam/BetweenFactorEM.h index 871dd3eee..510011ede 100644 --- a/gtsam_unstable/slam/BetweenFactorEM.h +++ b/gtsam_unstable/slam/BetweenFactorEM.h @@ -228,11 +228,9 @@ public: return err_wh_eq; } -#ifdef NO_BOOST_CPP17 Vector whitenedError(const Values& x, std::vector& H) const { return whitenedError(x, &H); } -#endif /* ************************************************************************* */ Vector calcIndicatorProb(const Values& x) const { diff --git a/gtsam_unstable/slam/TransformBtwRobotsUnaryFactor.h b/gtsam_unstable/slam/TransformBtwRobotsUnaryFactor.h index 6d1ca832c..1a535eab6 100644 --- a/gtsam_unstable/slam/TransformBtwRobotsUnaryFactor.h +++ b/gtsam_unstable/slam/TransformBtwRobotsUnaryFactor.h @@ -186,11 +186,9 @@ namespace gtsam { } /* ************************************************************************* */ -#ifdef NO_BOOST_CPP17 gtsam::Vector whitenedError(const gtsam::Values& x, std::vector& H) const { return whitenedError(x, &H); } -#endif /* ************************************************************************* */ diff --git a/gtsam_unstable/slam/TransformBtwRobotsUnaryFactorEM.h b/gtsam_unstable/slam/TransformBtwRobotsUnaryFactorEM.h index 52ff220e1..591a50f13 100644 --- a/gtsam_unstable/slam/TransformBtwRobotsUnaryFactorEM.h +++ b/gtsam_unstable/slam/TransformBtwRobotsUnaryFactorEM.h @@ -245,11 +245,9 @@ namespace gtsam { } /* ************************************************************************* */ -#ifdef NO_BOOST_CPP17 Vector whitenedError(const Values& x, std::vector& H) const { return whitenedError(x, &H); } -#endif /* ************************************************************************* */ Vector calcIndicatorProb(const Values& x) const { diff --git a/tests/simulated3D.h b/tests/simulated3D.h index 54481fcbb..8926b376a 100644 --- a/tests/simulated3D.h +++ b/tests/simulated3D.h @@ -99,12 +99,8 @@ struct PointPrior3D: public NoiseModelFactor1 { /** * Models a linear 3D measurement between 3D points */ -<<<<<<< HEAD struct Simulated3DMeasurement: public NoiseModelFactorN { -======= -struct Simulated3DMeasurement: public NoiseModelFactor2 { using NoiseModelFactor2::evaluateError; ->>>>>>> 7b3c40e92 (everything compiles but tests fail in no boost mode) Point3 measured_; ///< Linear displacement between a pose and landmark