Eigen  3.4.90 (git rev 67eeba6e720c5745abc77ae6c92ce0a44aa7b7ae)
NumTraits.h
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 {
26  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
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 {
33  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
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 {
45  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
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 {
57  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
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 {
64  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
65  static int run() {
66  using std::log;
67  using std::ceil;
68  typedef typename NumTraits<T>::Real Real;
69  return int(ceil(-log(NumTraits<Real>::epsilon())/log(static_cast<Real>(2))));
70  }
71 };
72 
73 template<typename T>
74 struct default_digits_impl<T,false,true> // Integer
75 {
76  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
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(&tgt, &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,
159  IsComplex = 0,
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 
171  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
172  static inline Real epsilon()
173  {
174  return numext::numeric_limits<T>::epsilon();
175  }
176 
177  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
178  static inline int digits10()
179  {
180  return internal::default_digits10_impl<T>::run();
181  }
182 
183  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
184  static inline int digits()
185  {
186  return internal::default_digits_impl<T>::run();
187  }
188 
189  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
190  static inline int min_exponent()
191  {
192  return numext::numeric_limits<T>::min_exponent;
193  }
194 
195  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
196  static inline int max_exponent()
197  {
198  return numext::numeric_limits<T>::max_exponent;
199  }
200 
201  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
202  static inline Real dummy_precision()
203  {
204  // make sure to override this for floating-point types
205  return Real(0);
206  }
207 
208  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
209  static inline T highest() {
210  return (numext::numeric_limits<T>::max)();
211  }
212 
213  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
214  static inline T lowest() {
215  return IsInteger ? (numext::numeric_limits<T>::min)()
216  : static_cast<T>(-(numext::numeric_limits<T>::max)());
217  }
218 
219  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
220  static inline T infinity() {
221  return numext::numeric_limits<T>::infinity();
222  }
223 
224  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
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 {
236  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
237  static inline float dummy_precision() { return 1e-5f; }
238 };
239 
240 template<> struct NumTraits<double> : GenericNumTraits<double>
241 {
242  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
243  static inline double dummy_precision() { return 1e-12; }
244 };
245 
246 template<> struct NumTraits<long double>
247  : GenericNumTraits<long double>
248 {
249  EIGEN_CONSTEXPR
250  static inline long double dummy_precision() { return 1e-15l; }
251 };
252 
253 template<typename Real_> struct NumTraits<std::complex<Real_> >
254  : GenericNumTraits<std::complex<Real_> >
255 {
256  typedef Real_ Real;
257  typedef typename NumTraits<Real_>::Literal Literal;
258  enum {
259  IsComplex = 1,
260  RequireInitialization = NumTraits<Real_>::RequireInitialization,
261  ReadCost = 2 * NumTraits<Real_>::ReadCost,
262  AddCost = 2 * NumTraits<Real>::AddCost,
263  MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
264  };
265 
266  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
267  static inline Real epsilon() { return NumTraits<Real>::epsilon(); }
268  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
269  static inline Real dummy_precision() { return NumTraits<Real>::dummy_precision(); }
270  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
271  static inline int digits10() { return NumTraits<Real>::digits10(); }
272 };
273 
274 template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
275 struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
276 {
277  typedef Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> ArrayType;
278  typedef typename NumTraits<Scalar>::Real RealScalar;
279  typedef Array<RealScalar, Rows, Cols, Options, MaxRows, MaxCols> Real;
280  typedef typename NumTraits<Scalar>::NonInteger NonIntegerScalar;
281  typedef Array<NonIntegerScalar, Rows, Cols, Options, MaxRows, MaxCols> NonInteger;
282  typedef ArrayType & Nested;
283  typedef typename NumTraits<Scalar>::Literal Literal;
284 
285  enum {
286  IsComplex = NumTraits<Scalar>::IsComplex,
287  IsInteger = NumTraits<Scalar>::IsInteger,
288  IsSigned = NumTraits<Scalar>::IsSigned,
289  RequireInitialization = 1,
290  ReadCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::ReadCost),
291  AddCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::AddCost),
292  MulCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::MulCost)
293  };
294 
295  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
296  static inline RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); }
297  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
298  static inline RealScalar dummy_precision() { return NumTraits<RealScalar>::dummy_precision(); }
299 
300  EIGEN_CONSTEXPR
301  static inline int digits10() { return NumTraits<Scalar>::digits10(); }
302 };
303 
304 template<> struct NumTraits<std::string>
305  : GenericNumTraits<std::string>
306 {
307  enum {
308  RequireInitialization = 1,
309  ReadCost = HugeCost,
310  AddCost = HugeCost,
311  MulCost = HugeCost
312  };
313 
314  EIGEN_CONSTEXPR
315  static inline int digits10() { return 0; }
316 
317 private:
318  static inline std::string epsilon();
319  static inline std::string dummy_precision();
320  static inline std::string lowest();
321  static inline std::string highest();
322  static inline std::string infinity();
323  static inline std::string quiet_NaN();
324 };
325 
326 // Empty specialization for void to allow template specialization based on NumTraits<T>::Real with T==void and SFINAE.
327 template<> struct NumTraits<void> {};
328 
329 template<> struct NumTraits<bool> : GenericNumTraits<bool> {};
330 
331 } // end namespace Eigen
332 
333 #endif // EIGEN_NUMTRAITS_H
Namespace containing all symbols from the Eigen library.
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 int Dynamic
Definition: Constants.h:24
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log_op< typename Derived::Scalar >, const Derived > log(const Eigen::ArrayBase< Derived > &x)
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:231