1 // Type traits for google3's custom MathUtil traits class. This is needed to 2 // enable embedding Jet objects inside the Quaternion class, found in 3 // util/math/quaternion.h. Including this file makes it possible to use 4 // quaternions inside Ceres cost functions which are automatically 5 // differentiated; for example: 6 // 7 // struct MyCostFunction { 8 // template<T> 9 // bool Map(const T* const quaternion_parameters, T* residuals) { 10 // Quaternion<T> quaternion(quaternion_parameters); 11 // ... 12 // } 13 // } 14 // 15 // NOTE(keir): This header must be included before quaternion.h or other 16 // file relying on traits. Adding a direct dependency on this header from 17 // mathlimits.h is a bad idea, so it is up to clients to use the correct include 18 // order. 19 20 #ifndef JET_TRAITS_H 21 #define JET_TRAITS_H 22 23 #include "ceres/jet.h" 24 #include "util/math/mathlimits.h" 25 26 template<typename T, int N> 27 struct MathLimits<ceres::Jet<T, N> > { 28 typedef ceres::Jet<T, N> Type; 29 typedef ceres::Jet<T, N> UnsignedType; 30 static const bool kIsSigned = true; 31 static const bool kIsInteger = false; 32 static const Type kPosMin; 33 static const Type kPosMax; 34 static const Type kMin; 35 static const Type kMax; 36 static const Type kNegMin; 37 static const Type kNegMax; 38 static const int kMin10Exp; 39 static const int kMax10Exp; 40 static const Type kEpsilon; 41 static const Type kStdError; 42 static const int kPrecisionDigits; 43 static const Type kNaN; 44 static const Type kPosInf; 45 static const Type kNegInf; 46 static bool IsFinite(const Type x) { return isfinite(x); } 47 static bool IsNaN (const Type x) { return isnan(x); } 48 static bool IsInf (const Type x) { return isinf(x); } 49 static bool IsPosInf(const Type x) { 50 bool found_inf = MathLimits<T>::IsPosInf(x.a); 51 for (int i = 0; i < N && !found_inf; ++i) { 52 found_inf = MathLimits<T>::IsPosInf(x.v[i]); 53 } 54 return found_inf; 55 } 56 static bool IsNegInf(const Type x) { 57 bool found_inf = MathLimits<T>::IsNegInf(x.a); 58 for (int i = 0; i < N && !found_inf; ++i) { 59 found_inf = MathLimits<T>::IsNegInf(x.v[i]); 60 } 61 return found_inf; 62 } 63 }; 64 65 // Since every one of these items is a simple forward to the scalar type 66 // underlying the jet, use a tablular format which makes the structure clear. 67 template<typename T, int N> const ceres::Jet<T, N> MathLimits<ceres::Jet<T, N> >::kPosMin = ceres::Jet<T, N>(MathLimits<T>::kPosMin); // NOLINT 68 template<typename T, int N> const ceres::Jet<T, N> MathLimits<ceres::Jet<T, N> >::kPosMax = ceres::Jet<T, N>(MathLimits<T>::kPosMax); // NOLINT 69 template<typename T, int N> const ceres::Jet<T, N> MathLimits<ceres::Jet<T, N> >::kMin = ceres::Jet<T, N>(MathLimits<T>::kMin); // NOLINT 70 template<typename T, int N> const ceres::Jet<T, N> MathLimits<ceres::Jet<T, N> >::kMax = ceres::Jet<T, N>(MathLimits<T>::kMax); // NOLINT 71 template<typename T, int N> const ceres::Jet<T, N> MathLimits<ceres::Jet<T, N> >::kNegMin = ceres::Jet<T, N>(MathLimits<T>::kNegMin); // NOLINT 72 template<typename T, int N> const ceres::Jet<T, N> MathLimits<ceres::Jet<T, N> >::kNegMax = ceres::Jet<T, N>(MathLimits<T>::kNegMax); // NOLINT 73 template<typename T, int N> const int MathLimits<ceres::Jet<T, N> >::kMin10Exp = MathLimits<T>::kMin10Exp; // NOLINT 74 template<typename T, int N> const int MathLimits<ceres::Jet<T, N> >::kMax10Exp = MathLimits<T>::kMax10Exp; // NOLINT 75 template<typename T, int N> const ceres::Jet<T, N> MathLimits<ceres::Jet<T, N> >::kEpsilon = ceres::Jet<T, N>(MathLimits<T>::kEpsilon); // NOLINT 76 template<typename T, int N> const ceres::Jet<T, N> MathLimits<ceres::Jet<T, N> >::kStdError = ceres::Jet<T, N>(MathLimits<T>::kStdError); // NOLINT 77 template<typename T, int N> const int MathLimits<ceres::Jet<T, N> >::kPrecisionDigits = MathLimits<T>::kPrecisionDigits; // NOLINT 78 template<typename T, int N> const ceres::Jet<T, N> MathLimits<ceres::Jet<T, N> >::kNaN = ceres::Jet<T, N>(MathLimits<T>::kNaN); // NOLINT 79 template<typename T, int N> const ceres::Jet<T, N> MathLimits<ceres::Jet<T, N> >::kPosInf = ceres::Jet<T, N>(MathLimits<T>::kPosInf); // NOLINT 80 template<typename T, int N> const ceres::Jet<T, N> MathLimits<ceres::Jet<T, N> >::kNegInf = ceres::Jet<T, N>(MathLimits<T>::kNegInf); // NOLINT 81 82 #endif // JET_TRAITS_H 83