NumTraits.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_NUMTRAITS_H
11 #define EIGEN_NUMTRAITS_H
12 
13 #include "./InternalHeaderCheck.h"
14 
15 namespace Eigen {
16 
17 namespace internal {
18 
19 // default implementation of digits10(), based on numeric_limits if specialized,
20 // 0 for integer types, and log10(epsilon()) otherwise.
21 template< typename T,
22  bool use_numeric_limits = std::numeric_limits<T>::is_specialized,
23  bool is_integer = NumTraits<T>::IsInteger>
24 struct default_digits10_impl
25 {
27  static int run() { return std::numeric_limits<T>::digits10; }
28 };
29 
30 template<typename T>
31 struct default_digits10_impl<T,false,false> // Floating point
32 {
34  static int run() {
35  using std::log10;
36  using std::ceil;
37  typedef typename NumTraits<T>::Real Real;
38  return int(ceil(-log10(NumTraits<Real>::epsilon())));
39  }
40 };
41 
42 template<typename T>
43 struct default_digits10_impl<T,false,true> // Integer
44 {
46  static int run() { return 0; }
47 };
48 
49 
50 // default implementation of digits(), based on numeric_limits if specialized,
51 // 0 for integer types, and log2(epsilon()) otherwise.
52 template< typename T,
53  bool use_numeric_limits = std::numeric_limits<T>::is_specialized,
54  bool is_integer = NumTraits<T>::IsInteger>
55 struct default_digits_impl
56 {
58  static int run() { return std::numeric_limits<T>::digits; }
59 };
60 
61 template<typename T>
62 struct default_digits_impl<T,false,false> // Floating point
63 {
65  static int run() {
66  using std::log2;
67  using std::ceil;
68  typedef typename NumTraits<T>::Real Real;
69  return int(ceil(-log2(NumTraits<Real>::epsilon())));
70  }
71 };
72 
73 template<typename T>
74 struct default_digits_impl<T,false,true> // Integer
75 {
77  static int run() { return 0; }
78 };
79 
80 } // end namespace internal
81 
82 namespace numext {
85 // TODO: Replace by std::bit_cast (available in C++20)
86 template <typename Tgt, typename Src>
87 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Tgt bit_cast(const Src& src) {
88  // The behaviour of memcpy is not specified for non-trivially copyable types
89  EIGEN_STATIC_ASSERT(std::is_trivially_copyable<Src>::value, THIS_TYPE_IS_NOT_SUPPORTED);
90  EIGEN_STATIC_ASSERT(std::is_trivially_copyable<Tgt>::value && std::is_default_constructible<Tgt>::value,
91  THIS_TYPE_IS_NOT_SUPPORTED);
92  EIGEN_STATIC_ASSERT(sizeof(Src) == sizeof(Tgt), THIS_TYPE_IS_NOT_SUPPORTED);
93 
94  Tgt tgt;
95  // Load src into registers first. This allows the memcpy to be elided by CUDA.
96  const Src staged = src;
97  EIGEN_USING_STD(memcpy)
98  memcpy(static_cast<void*>(&tgt),static_cast<const void*>(&staged), sizeof(Tgt));
99  return tgt;
100 }
101 } // namespace numext
102 
154 template<typename T> struct GenericNumTraits
155 {
156  enum {
157  IsInteger = std::numeric_limits<T>::is_integer,
158  IsSigned = std::numeric_limits<T>::is_signed,
160  RequireInitialization = internal::is_arithmetic<T>::value ? 0 : 1,
161  ReadCost = 1,
162  AddCost = 1,
163  MulCost = 1
164  };
165 
166  typedef T Real;
167  typedef std::conditional_t<IsInteger, std::conditional_t<sizeof(T)<=2, float, double>, T> NonInteger;
168  typedef T Nested;
169  typedef T Literal;
170 
172  static inline Real epsilon()
173  {
174  return numext::numeric_limits<T>::epsilon();
175  }
176 
178  static inline int digits10()
179  {
180  return internal::default_digits10_impl<T>::run();
181  }
182 
184  static inline int digits()
185  {
186  return internal::default_digits_impl<T>::run();
187  }
188 
190  static inline int min_exponent()
191  {
192  return numext::numeric_limits<T>::min_exponent;
193  }
194 
196  static inline int max_exponent()
197  {
198  return numext::numeric_limits<T>::max_exponent;
199  }
200 
202  static inline Real dummy_precision()
203  {
204  // make sure to override this for floating-point types
205  return Real(0);
206  }
207 
209  static inline T highest() {
211  }
212 
214  static inline T lowest() {
216  : static_cast<T>(-(numext::numeric_limits<T>::max)());
217  }
218 
220  static inline T infinity() {
221  return numext::numeric_limits<T>::infinity();
222  }
223 
225  static inline T quiet_NaN() {
226  return numext::numeric_limits<T>::quiet_NaN();
227  }
228 };
229 
230 template<typename T> struct NumTraits : GenericNumTraits<T>
231 {};
232 
233 template<> struct NumTraits<float>
234  : GenericNumTraits<float>
235 {
237  static inline float dummy_precision() { return 1e-5f; }
238 };
239 
240 template<> struct NumTraits<double> : GenericNumTraits<double>
241 {
243  static inline double dummy_precision() { return 1e-12; }
244 };
245 
246 // GPU devices treat `long double` as `double`.
247 #ifndef EIGEN_GPU_COMPILE_PHASE
248 template<> struct NumTraits<long double>
249  : GenericNumTraits<long double>
250 {
252  static inline long double dummy_precision() { return static_cast<long double>(1e-15l); }
253 
254 #if defined(EIGEN_ARCH_PPC) && (__LDBL_MANT_DIG__ == 106)
255  // PowerPC double double causes issues with some values
257  static inline long double epsilon()
258  {
259  // 2^(-(__LDBL_MANT_DIG__)+1)
260  return static_cast<long double>(2.4651903288156618919116517665087e-32l);
261  }
262 #endif
263 };
264 #endif
265 
266 template<typename Real_> struct NumTraits<std::complex<Real_> >
267  : GenericNumTraits<std::complex<Real_> >
268 {
269  typedef Real_ Real;
271  enum {
277  };
278 
280  static inline Real epsilon() { return NumTraits<Real>::epsilon(); }
284  static inline int digits10() { return NumTraits<Real>::digits10(); }
285 };
286 
287 template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
288 struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
289 {
295  typedef ArrayType & Nested;
297 
298  enum {
303  ReadCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::ReadCost),
304  AddCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::AddCost),
305  MulCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::MulCost)
306  };
307 
309  static inline RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); }
312 
314  static inline int digits10() { return NumTraits<Scalar>::digits10(); }
315 };
316 
317 template<> struct NumTraits<std::string>
318  : GenericNumTraits<std::string>
319 {
320  enum {
324  MulCost = HugeCost
325  };
326 
328  static inline int digits10() { return 0; }
329 
330 private:
331  static inline std::string epsilon();
332  static inline std::string dummy_precision();
333  static inline std::string lowest();
334  static inline std::string highest();
335  static inline std::string infinity();
336  static inline std::string quiet_NaN();
337 };
338 
339 // Empty specialization for void to allow template specialization based on NumTraits<T>::Real with T==void and SFINAE.
340 template<> struct NumTraits<void> {};
341 
342 template<> struct NumTraits<bool> : GenericNumTraits<bool> {};
343 
344 } // end namespace Eigen
345 
346 #endif // EIGEN_NUMTRAITS_H
const CeilReturnType ceil() const
const Log2ReturnType log2() const
const Log10ReturnType log10() const
Array< double, 1, 3 > e(1./3., 0.5, 2.)
#define EIGEN_USING_STD(FUNC)
Definition: Macros.h:1080
#define EIGEN_CONSTEXPR
Definition: Macros.h:747
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:883
#define EIGEN_STATIC_ASSERT(X, MSG)
Definition: StaticAssert.h:26
Eigen::Triplet< double > T
General-purpose arrays with easy API for coefficient-wise operations.
Definition: Array.h:49
bfloat16() max(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:690
bfloat16() min(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:684
Tgt bit_cast(const Src &src)
Definition: NumTraits.h:87
: InteropHeaders
Definition: Core:139
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log10_op< typename Derived::Scalar >, const Derived > log10(const Eigen::ArrayBase< Derived > &x)
const int HugeCost
Definition: Constants.h:46
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_ceil_op< typename Derived::Scalar >, const Derived > ceil(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log2_op< typename Derived::Scalar >, const Derived > log2(const Eigen::ArrayBase< Derived > &x)
const int Dynamic
Definition: Constants.h:24
Definition: BFloat16.h:222
Array< RealScalar, Rows, Cols, Options, MaxRows, MaxCols > Real
Definition: NumTraits.h:292
Array< Scalar, Rows, Cols, Options, MaxRows, MaxCols > ArrayType
Definition: NumTraits.h:290
Array< NonIntegerScalar, Rows, Cols, Options, MaxRows, MaxCols > NonInteger
Definition: NumTraits.h:294
static EIGEN_CONSTEXPR double dummy_precision()
Definition: NumTraits.h:243
static EIGEN_CONSTEXPR float dummy_precision()
Definition: NumTraits.h:237
static EIGEN_CONSTEXPR long double dummy_precision()
Definition: NumTraits.h:252
static EIGEN_CONSTEXPR Real epsilon()
Definition: NumTraits.h:280
static EIGEN_CONSTEXPR Real dummy_precision()
Definition: NumTraits.h:282
NumTraits< Real_ >::Literal Literal
Definition: NumTraits.h:270
static EIGEN_CONSTEXPR int digits10()
Definition: NumTraits.h:284
static std::string infinity()
static std::string quiet_NaN()
static EIGEN_CONSTEXPR int digits10()
Definition: NumTraits.h:328
static std::string dummy_precision()
static std::string epsilon()
static std::string highest()
static std::string lowest()
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:231