Medial Code Documentation
Loading...
Searching...
No Matches
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
13namespace Eigen {
14
15namespace internal {
16
17// default implementation of digits10(), based on numeric_limits if specialized,
18// 0 for integer types, and log10(epsilon()) otherwise.
19template< typename T,
20 bool use_numeric_limits = std::numeric_limits<T>::is_specialized,
21 bool is_integer = NumTraits<T>::IsInteger>
23{
24 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
25 static int run() { return std::numeric_limits<T>::digits10; }
26};
27
28template<typename T>
29struct default_digits10_impl<T,false,false> // Floating point
30{
31 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
32 static int run() {
33 using std::log10;
34 using std::ceil;
35 typedef typename NumTraits<T>::Real Real;
36 return int(ceil(-log10(NumTraits<Real>::epsilon())));
37 }
38};
39
40template<typename T>
41struct default_digits10_impl<T,false,true> // Integer
42{
43 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
44 static int run() { return 0; }
45};
46
47
48// default implementation of digits(), based on numeric_limits if specialized,
49// 0 for integer types, and log2(epsilon()) otherwise.
50template< typename T,
51 bool use_numeric_limits = std::numeric_limits<T>::is_specialized,
52 bool is_integer = NumTraits<T>::IsInteger>
54{
55 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
56 static int run() { return std::numeric_limits<T>::digits; }
57};
58
59template<typename T>
60struct default_digits_impl<T,false,false> // Floating point
61{
62 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
63 static int run() {
64 using std::log;
65 using std::ceil;
66 typedef typename NumTraits<T>::Real Real;
67 return int(ceil(-log(NumTraits<Real>::epsilon())/log(static_cast<Real>(2))));
68 }
69};
70
71template<typename T>
72struct default_digits_impl<T,false,true> // Integer
73{
74 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
75 static int run() { return 0; }
76};
77
78} // end namespace internal
79
80namespace numext {
83// TODO: Replace by std::bit_cast (available in C++20)
84template <typename Tgt, typename Src>
85EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Tgt bit_cast(const Src& src) {
86#if EIGEN_HAS_TYPE_TRAITS
87 // The behaviour of memcpy is not specified for non-trivially copyable types
88 EIGEN_STATIC_ASSERT(std::is_trivially_copyable<Src>::value, THIS_TYPE_IS_NOT_SUPPORTED);
89 EIGEN_STATIC_ASSERT(std::is_trivially_copyable<Tgt>::value && std::is_default_constructible<Tgt>::value,
90 THIS_TYPE_IS_NOT_SUPPORTED);
91#endif
92
93 EIGEN_STATIC_ASSERT(sizeof(Src) == sizeof(Tgt), THIS_TYPE_IS_NOT_SUPPORTED);
94 Tgt tgt;
95 EIGEN_USING_STD(memcpy)
96 memcpy(&tgt, &src, sizeof(Tgt));
97 return tgt;
98}
99} // namespace numext
100
101// clang-format off
153 // clang-format on
154
155template<typename T> struct GenericNumTraits
156{
157 enum {
158 IsInteger = std::numeric_limits<T>::is_integer,
159 IsSigned = std::numeric_limits<T>::is_signed,
160 IsComplex = 0,
161 RequireInitialization = internal::is_arithmetic<T>::value ? 0 : 1,
162 ReadCost = 1,
163 AddCost = 1,
164 MulCost = 1
165 };
166
167 typedef T Real;
168 typedef typename internal::conditional<
169 IsInteger,
170 typename internal::conditional<sizeof(T)<=2, float, double>::type,
171 T
172 >::type NonInteger;
173 typedef T Nested;
174 typedef T Literal;
175
176 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
177 static inline Real epsilon()
178 {
179 return numext::numeric_limits<T>::epsilon();
180 }
181
182 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
183 static inline int digits10()
184 {
186 }
187
188 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
189 static inline int digits()
190 {
192 }
193
194 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
195 static inline int min_exponent()
196 {
197 return numext::numeric_limits<T>::min_exponent;
198 }
199
200 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
201 static inline int max_exponent()
202 {
203 return numext::numeric_limits<T>::max_exponent;
204 }
205
206 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
207 static inline Real dummy_precision()
208 {
209 // make sure to override this for floating-point types
210 return Real(0);
211 }
212
213 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
214 static inline T highest() {
215 return (numext::numeric_limits<T>::max)();
216 }
217
218 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
219 static inline T lowest() {
220 return IsInteger ? (numext::numeric_limits<T>::min)()
221 : static_cast<T>(-(numext::numeric_limits<T>::max)());
222 }
223
224 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
225 static inline T infinity() {
226 return numext::numeric_limits<T>::infinity();
227 }
228
229 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
230 static inline T quiet_NaN() {
231 return numext::numeric_limits<T>::quiet_NaN();
232 }
233};
234
235template<typename T> struct NumTraits : GenericNumTraits<T>
236{};
237
238template<> struct NumTraits<float>
239 : GenericNumTraits<float>
240{
241 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
242 static inline float dummy_precision() { return 1e-5f; }
243};
244
245template<> struct NumTraits<double> : GenericNumTraits<double>
246{
247 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
248 static inline double dummy_precision() { return 1e-12; }
249};
250
251// GPU devices treat `long double` as `double`.
252#ifndef EIGEN_GPU_COMPILE_PHASE
253template<> struct NumTraits<long double>
254 : GenericNumTraits<long double>
255{
256 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
257 static inline long double dummy_precision() { return static_cast<long double>(1e-15l); }
258
259#if defined(EIGEN_ARCH_PPC) && (__LDBL_MANT_DIG__ == 106)
260 // PowerPC double double causes issues with some values
261 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
262 static inline long double epsilon()
263 {
264 // 2^(-(__LDBL_MANT_DIG__)+1)
265 return static_cast<long double>(2.4651903288156618919116517665087e-32l);
266 }
267#endif
268};
269#endif
270
271template<typename _Real> struct NumTraits<std::complex<_Real> >
272 : GenericNumTraits<std::complex<_Real> >
273{
274 typedef _Real Real;
275 typedef typename NumTraits<_Real>::Literal Literal;
276 enum {
277 IsComplex = 1,
278 RequireInitialization = NumTraits<_Real>::RequireInitialization,
279 ReadCost = 2 * NumTraits<_Real>::ReadCost,
280 AddCost = 2 * NumTraits<Real>::AddCost,
282 };
283
284 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
285 static inline Real epsilon() { return NumTraits<Real>::epsilon(); }
286 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
287 static inline Real dummy_precision() { return NumTraits<Real>::dummy_precision(); }
288 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
289 static inline int digits10() { return NumTraits<Real>::digits10(); }
290};
291
292template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
293struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
294{
296 typedef typename NumTraits<Scalar>::Real RealScalar;
300 typedef ArrayType & Nested;
301 typedef typename NumTraits<Scalar>::Literal Literal;
302
303 enum {
307 RequireInitialization = 1,
308 ReadCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::ReadCost),
309 AddCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::AddCost),
310 MulCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::MulCost)
311 };
312
313 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
314 static inline RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); }
315 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
316 static inline RealScalar dummy_precision() { return NumTraits<RealScalar>::dummy_precision(); }
317
318 EIGEN_CONSTEXPR
319 static inline int digits10() { return NumTraits<Scalar>::digits10(); }
320};
321
322template<> struct NumTraits<std::string>
323 : GenericNumTraits<std::string>
324{
325 enum {
326 RequireInitialization = 1,
327 ReadCost = HugeCost,
328 AddCost = HugeCost,
329 MulCost = HugeCost
330 };
331
332 EIGEN_CONSTEXPR
333 static inline int digits10() { return 0; }
334
335private:
336 static inline std::string epsilon();
337 static inline std::string dummy_precision();
338 static inline std::string lowest();
339 static inline std::string highest();
340 static inline std::string infinity();
341 static inline std::string quiet_NaN();
342};
343
344// Empty specialization for void to allow template specialization based on NumTraits<T>::Real with T==void and SFINAE.
345template<> struct NumTraits<void> {};
346
347template<> struct NumTraits<bool> : GenericNumTraits<bool> {};
348
349} // end namespace Eigen
350
351#endif // EIGEN_NUMTRAITS_H
General-purpose arrays with easy API for coefficient-wise operations.
Definition Array.h:47
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:50
Namespace containing all symbols from the Eigen library.
Definition LDLT.h:16
const int HugeCost
This value means that the cost to evaluate an expression coefficient is either very expensive or cann...
Definition Constants.h:44
const int Dynamic
This value means that a positive quantity (e.g., a size) is not known at compile-time,...
Definition Constants.h:22
Definition BFloat16.h:88
Definition NumTraits.h:156
Holds information about the various numeric (i.e.
Definition NumTraits.h:236
Definition Meta.h:109
Definition NumTraits.h:54
Definition Meta.h:133