Home | History | Annotate | Download | only in google3
      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