Eigen  3.2.93
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 namespace Eigen {
14 
15 namespace internal {
16 
17 // default implementation of digits10(), based on numeric_limits if specialized,
18 // 0 for integer types, and log10(epsilon()) otherwise.
19 template< typename T,
20  bool use_numeric_limits = std::numeric_limits<T>::is_specialized,
21  bool is_integer = NumTraits<T>::IsInteger>
22 struct default_digits10_impl
23 {
24  static int run() { return std::numeric_limits<T>::digits10; }
25 };
26 
27 template<typename T>
28 struct default_digits10_impl<T,false,false> // Floating point
29 {
30  static int run() {
31  using std::log10;
32  using std::ceil;
33  typedef typename NumTraits<T>::Real Real;
34  return int(ceil(-log10(NumTraits<Real>::epsilon())));
35  }
36 };
37 
38 template<typename T>
39 struct default_digits10_impl<T,false,true> // Integer
40 {
41  static int run() { return 0; }
42 };
43 
44 } // end namespace internal
45 
88 template<typename T> struct GenericNumTraits
89 {
90  enum {
91  IsInteger = std::numeric_limits<T>::is_integer,
92  IsSigned = std::numeric_limits<T>::is_signed,
93  IsComplex = 0,
94  RequireInitialization = internal::is_arithmetic<T>::value ? 0 : 1,
95  ReadCost = 1,
96  AddCost = 1,
97  MulCost = 1
98  };
99 
100  // Division is messy but important, because it is expensive and throughput
101  // varies significantly. The following numbers are based on min division
102  // throughput on Haswell.
103  template<bool Vectorized>
104  struct Div {
105  enum {
106 #ifdef EIGEN_VECTORIZE_AVX
107  AVX = true,
108 #else
109  AVX = false,
110 #endif
111  Cost = IsInteger ? (sizeof(T) == 8 ? (IsSigned ? 24 : 21) : (IsSigned ? 8 : 9)):
112  Vectorized ? (sizeof(T) == 8 ? (AVX ? 16 : 8) : (AVX ? 14 : 7)) : 8
113  };
114  };
115 
116 
117  typedef T Real;
118  typedef typename internal::conditional<
119  IsInteger,
120  typename internal::conditional<sizeof(T)<=2, float, double>::type,
121  T
122  >::type NonInteger;
123  typedef T Nested;
124  typedef T Literal;
125 
126  EIGEN_DEVICE_FUNC
127  static inline Real epsilon()
128  {
129  return numext::numeric_limits<T>::epsilon();
130  }
131 
132  EIGEN_DEVICE_FUNC
133  static inline int digits10()
134  {
135  return internal::default_digits10_impl<T>::run();
136  }
137 
138  EIGEN_DEVICE_FUNC
139  static inline Real dummy_precision()
140  {
141  // make sure to override this for floating-point types
142  return Real(0);
143  }
144 
145 
146  EIGEN_DEVICE_FUNC
147  static inline T highest() {
148  return (numext::numeric_limits<T>::max)();
149  }
150 
151  EIGEN_DEVICE_FUNC
152  static inline T lowest() {
153  return IsInteger ? (numext::numeric_limits<T>::min)() : (-(numext::numeric_limits<T>::max)());
154  }
155 
156  EIGEN_DEVICE_FUNC
157  static inline T infinity() {
158  return numext::numeric_limits<T>::infinity();
159  }
160 
161  EIGEN_DEVICE_FUNC
162  static inline T quiet_NaN() {
163  return numext::numeric_limits<T>::quiet_NaN();
164  }
165 };
166 
167 template<typename T> struct NumTraits : GenericNumTraits<T>
168 {};
169 
170 template<> struct NumTraits<float>
171  : GenericNumTraits<float>
172 {
173  EIGEN_DEVICE_FUNC
174  static inline float dummy_precision() { return 1e-5f; }
175 };
176 
177 template<> struct NumTraits<double> : GenericNumTraits<double>
178 {
179  EIGEN_DEVICE_FUNC
180  static inline double dummy_precision() { return 1e-12; }
181 };
182 
183 template<> struct NumTraits<long double>
184  : GenericNumTraits<long double>
185 {
186  static inline long double dummy_precision() { return 1e-15l; }
187 };
188 
189 template<typename _Real> struct NumTraits<std::complex<_Real> >
190  : GenericNumTraits<std::complex<_Real> >
191 {
192  typedef _Real Real;
193  typedef typename NumTraits<_Real>::Literal Literal;
194  enum {
195  IsComplex = 1,
196  RequireInitialization = NumTraits<_Real>::RequireInitialization,
197  ReadCost = 2 * NumTraits<_Real>::ReadCost,
198  AddCost = 2 * NumTraits<Real>::AddCost,
200  };
201 
202  EIGEN_DEVICE_FUNC
203  static inline Real epsilon() { return NumTraits<Real>::epsilon(); }
204  EIGEN_DEVICE_FUNC
205  static inline Real dummy_precision() { return NumTraits<Real>::dummy_precision(); }
206  EIGEN_DEVICE_FUNC
207  static inline int digits10() { return NumTraits<Real>::digits10(); }
208 };
209 
210 template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
211 struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
212 {
214  typedef typename NumTraits<Scalar>::Real RealScalar;
216  typedef typename NumTraits<Scalar>::NonInteger NonIntegerScalar;
218  typedef ArrayType & Nested;
219  typedef typename NumTraits<Scalar>::Literal Literal;
220 
221  enum {
222  IsComplex = NumTraits<Scalar>::IsComplex,
223  IsInteger = NumTraits<Scalar>::IsInteger,
224  IsSigned = NumTraits<Scalar>::IsSigned,
225  RequireInitialization = 1,
226  ReadCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::ReadCost,
227  AddCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::AddCost,
228  MulCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::MulCost
229  };
230 
231  EIGEN_DEVICE_FUNC
232  static inline RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); }
233  EIGEN_DEVICE_FUNC
234  static inline RealScalar dummy_precision() { return NumTraits<RealScalar>::dummy_precision(); }
235 };
236 
237 template<> struct NumTraits<std::string>
238  : GenericNumTraits<std::string>
239 {
240  enum {
241  RequireInitialization = 1,
242  ReadCost = HugeCost,
243  AddCost = HugeCost,
244  MulCost = HugeCost
245  };
246 
247  static inline int digits10() { return 0; }
248 
249 private:
250  static inline std::string epsilon();
251  static inline std::string dummy_precision();
252  static inline std::string lowest();
253  static inline std::string highest();
254  static inline std::string infinity();
255  static inline std::string quiet_NaN();
256 };
257 
258 } // end namespace Eigen
259 
260 #endif // EIGEN_NUMTRAITS_H
const int HugeCost
Definition: Constants.h:39
Namespace containing all symbols from the Eigen library.
Definition: Core:271
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:167
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_ceil_op< typename Derived::Scalar >, const Derived > ceil(const Eigen::ArrayBase< Derived > &x)
Definition: Eigen_Colamd.h:50
General-purpose arrays with easy API for coefficient-wise operations.
Definition: Array.h:45
const int Dynamic
Definition: Constants.h:21
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log10_op< typename Derived::Scalar >, const Derived > log10(const Eigen::ArrayBase< Derived > &x)