![]() |
Eigen
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> 00005 // 00006 // This Source Code Form is subject to the terms of the Mozilla 00007 // Public License v. 2.0. If a copy of the MPL was not distributed 00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00009 00010 #ifndef EIGEN_NUMTRAITS_H 00011 #define EIGEN_NUMTRAITS_H 00012 00013 namespace Eigen { 00014 00015 namespace internal { 00016 00017 // default implementation of digits10(), based on numeric_limits if specialized, 00018 // 0 for integer types, and log10(epsilon()) otherwise. 00019 template< typename T, 00020 bool use_numeric_limits = std::numeric_limits<T>::is_specialized, 00021 bool is_integer = NumTraits<T>::IsInteger> 00022 struct default_digits10_impl 00023 { 00024 static int run() { return std::numeric_limits<T>::digits10; } 00025 }; 00026 00027 template<typename T> 00028 struct default_digits10_impl<T,false,false> // Floating point 00029 { 00030 static int run() { 00031 using std::log10; 00032 using std::ceil; 00033 typedef typename NumTraits<T>::Real Real; 00034 return int(ceil(-log10(NumTraits<Real>::epsilon()))); 00035 } 00036 }; 00037 00038 template<typename T> 00039 struct default_digits10_impl<T,false,true> // Integer 00040 { 00041 static int run() { return 0; } 00042 }; 00043 00044 } // end namespace internal 00045 00088 template<typename T> struct GenericNumTraits 00089 { 00090 enum { 00091 IsInteger = std::numeric_limits<T>::is_integer, 00092 IsSigned = std::numeric_limits<T>::is_signed, 00093 IsComplex = 0, 00094 RequireInitialization = internal::is_arithmetic<T>::value ? 0 : 1, 00095 ReadCost = 1, 00096 AddCost = 1, 00097 MulCost = 1 00098 }; 00099 00100 typedef T Real; 00101 typedef typename internal::conditional< 00102 IsInteger, 00103 typename internal::conditional<sizeof(T)<=2, float, double>::type, 00104 T 00105 >::type NonInteger; 00106 typedef T Nested; 00107 typedef T Literal; 00108 00109 EIGEN_DEVICE_FUNC 00110 static inline Real epsilon() 00111 { 00112 return numext::numeric_limits<T>::epsilon(); 00113 } 00114 00115 EIGEN_DEVICE_FUNC 00116 static inline int digits10() 00117 { 00118 return internal::default_digits10_impl<T>::run(); 00119 } 00120 00121 EIGEN_DEVICE_FUNC 00122 static inline Real dummy_precision() 00123 { 00124 // make sure to override this for floating-point types 00125 return Real(0); 00126 } 00127 00128 00129 EIGEN_DEVICE_FUNC 00130 static inline T highest() { 00131 return (numext::numeric_limits<T>::max)(); 00132 } 00133 00134 EIGEN_DEVICE_FUNC 00135 static inline T lowest() { 00136 return IsInteger ? (numext::numeric_limits<T>::min)() : (-(numext::numeric_limits<T>::max)()); 00137 } 00138 00139 EIGEN_DEVICE_FUNC 00140 static inline T infinity() { 00141 return numext::numeric_limits<T>::infinity(); 00142 } 00143 00144 EIGEN_DEVICE_FUNC 00145 static inline T quiet_NaN() { 00146 return numext::numeric_limits<T>::quiet_NaN(); 00147 } 00148 }; 00149 00150 template<typename T> struct NumTraits : GenericNumTraits<T> 00151 {}; 00152 00153 template<> struct NumTraits<float> 00154 : GenericNumTraits<float> 00155 { 00156 EIGEN_DEVICE_FUNC 00157 static inline float dummy_precision() { return 1e-5f; } 00158 }; 00159 00160 template<> struct NumTraits<double> : GenericNumTraits<double> 00161 { 00162 EIGEN_DEVICE_FUNC 00163 static inline double dummy_precision() { return 1e-12; } 00164 }; 00165 00166 template<> struct NumTraits<long double> 00167 : GenericNumTraits<long double> 00168 { 00169 static inline long double dummy_precision() { return 1e-15l; } 00170 }; 00171 00172 template<typename _Real> struct NumTraits<std::complex<_Real> > 00173 : GenericNumTraits<std::complex<_Real> > 00174 { 00175 typedef _Real Real; 00176 typedef typename NumTraits<_Real>::Literal Literal; 00177 enum { 00178 IsComplex = 1, 00179 RequireInitialization = NumTraits<_Real>::RequireInitialization, 00180 ReadCost = 2 * NumTraits<_Real>::ReadCost, 00181 AddCost = 2 * NumTraits<Real>::AddCost, 00182 MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost 00183 }; 00184 00185 EIGEN_DEVICE_FUNC 00186 static inline Real epsilon() { return NumTraits<Real>::epsilon(); } 00187 EIGEN_DEVICE_FUNC 00188 static inline Real dummy_precision() { return NumTraits<Real>::dummy_precision(); } 00189 EIGEN_DEVICE_FUNC 00190 static inline int digits10() { return NumTraits<Real>::digits10(); } 00191 }; 00192 00193 template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols> 00194 struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > 00195 { 00196 typedef Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> ArrayType; 00197 typedef typename NumTraits<Scalar>::Real RealScalar; 00198 typedef Array<RealScalar, Rows, Cols, Options, MaxRows, MaxCols> Real; 00199 typedef typename NumTraits<Scalar>::NonInteger NonIntegerScalar; 00200 typedef Array<NonIntegerScalar, Rows, Cols, Options, MaxRows, MaxCols> NonInteger; 00201 typedef ArrayType & Nested; 00202 typedef typename NumTraits<Scalar>::Literal Literal; 00203 00204 enum { 00205 IsComplex = NumTraits<Scalar>::IsComplex, 00206 IsInteger = NumTraits<Scalar>::IsInteger, 00207 IsSigned = NumTraits<Scalar>::IsSigned, 00208 RequireInitialization = 1, 00209 ReadCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::ReadCost, 00210 AddCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::AddCost, 00211 MulCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::MulCost 00212 }; 00213 00214 EIGEN_DEVICE_FUNC 00215 static inline RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); } 00216 EIGEN_DEVICE_FUNC 00217 static inline RealScalar dummy_precision() { return NumTraits<RealScalar>::dummy_precision(); } 00218 }; 00219 00220 template<> struct NumTraits<std::string> 00221 : GenericNumTraits<std::string> 00222 { 00223 enum { 00224 RequireInitialization = 1, 00225 ReadCost = HugeCost, 00226 AddCost = HugeCost, 00227 MulCost = HugeCost 00228 }; 00229 00230 static inline int digits10() { return 0; } 00231 00232 private: 00233 static inline std::string epsilon(); 00234 static inline std::string dummy_precision(); 00235 static inline std::string lowest(); 00236 static inline std::string highest(); 00237 static inline std::string infinity(); 00238 static inline std::string quiet_NaN(); 00239 }; 00240 00241 // Empty specialization for void to allow template specialization based on NumTraits<T>::Real with T==void and SFINAE. 00242 template<> struct NumTraits<void> {}; 00243 00244 } // end namespace Eigen 00245 00246 #endif // EIGEN_NUMTRAITS_H