Teh first one
[mldemos:kalians-mldemos.git] / _AlgorithmsPlugins / KPCA / Eigen / src / Core / 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 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24
25 #ifndef EIGEN_NUMTRAITS_H
26 #define EIGEN_NUMTRAITS_H
27
28 /** \class NumTraits
29   * \ingroup Core_Module
30   *
31   * \brief Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
32   *
33   * \param T the numeric type at hand
34   *
35   * This class stores enums, typedefs and static methods giving information about a numeric type.
36   *
37   * The provided data consists of:
38   * \li A typedef \a Real, giving the "real part" type of \a T. If \a T is already real,
39   *     then \a Real is just a typedef to \a T. If \a T is \c std::complex<U> then \a Real
40   *     is a typedef to \a U.
41   * \li A typedef \a NonInteger, giving the type that should be used for operations producing non-integral values,
42   *     such as quotients, square roots, etc. If \a T is a floating-point type, then this typedef just gives
43   *     \a T again. Note however that many Eigen functions such as internal::sqrt simply refuse to
44   *     take integers. Outside of a few cases, Eigen doesn't do automatic type promotion. Thus, this typedef is
45   *     only intended as a helper for code that needs to explicitly promote types.
46   * \li A typedef \a Nested giving the type to use to nest a value inside of the expression tree. If you don't know what
47   *     this means, just use \a T here.
48   * \li An enum value \a IsComplex. It is equal to 1 if \a T is a \c std::complex
49   *     type, and to 0 otherwise.
50   * \li An enum value \a IsInteger. It is equal to \c 1 if \a T is an integer type such as \c int,
51   *     and to \c 0 otherwise.
52   * \li Enum values ReadCost, AddCost and MulCost representing a rough estimate of the number of CPU cycles needed
53   *     to by move / add / mul instructions respectively, assuming the data is already stored in CPU registers.
54   *     Stay vague here. No need to do architecture-specific stuff.
55   * \li An enum value \a IsSigned. It is equal to \c 1 if \a T is a signed type and to 0 if \a T is unsigned.
56   * \li An enum value \a RequireInitialization. It is equal to \c 1 if the constructor of the numeric type \a T must
57   *     be called, and to 0 if it is safe not to call it. Default is 0 if \a T is an arithmetic type, and 1 otherwise.
58   * \li An epsilon() function which, unlike std::numeric_limits::epsilon(), returns a \a Real instead of a \a T.
59   * \li A dummy_precision() function returning a weak epsilon value. It is mainly used as a default
60   *     value by the fuzzy comparison operators.
61   * \li highest() and lowest() functions returning the highest and lowest possible values respectively.
62   */
63
64 template<typename T> struct GenericNumTraits
65 {
66   enum {
67     IsInteger = std::numeric_limits<T>::is_integer,
68     IsSigned = std::numeric_limits<T>::is_signed,
69     IsComplex = 0,
70     RequireInitialization = internal::is_arithmetic<T>::value ? 0 : 1,
71     ReadCost = 1,
72     AddCost = 1,
73     MulCost = 1
74   };
75
76   typedef T Real;
77   typedef typename internal::conditional<
78                      IsInteger,
79                      typename internal::conditional<sizeof(T)<=2, float, double>::type,
80                      T
81                    >::type NonInteger;
82   typedef T Nested;
83
84   inline static Real epsilon() { return std::numeric_limits<T>::epsilon(); }
85   inline static Real dummy_precision()
86   {
87     // make sure to override this for floating-point types
88     return Real(0);
89   }
90   inline static T highest() { return std::numeric_limits<T>::max(); }
91   inline static T lowest()  { return IsInteger ? std::numeric_limits<T>::min() : (-std::numeric_limits<T>::max()); }
92   
93 #ifdef EIGEN2_SUPPORT
94   enum {
95     HasFloatingPoint = !IsInteger
96   };
97   typedef NonInteger FloatingPoint;
98 #endif
99 };
100
101 template<typename T> struct NumTraits : GenericNumTraits<T>
102 {};
103
104 template<> struct NumTraits<float>
105   : GenericNumTraits<float>
106 {
107   inline static float dummy_precision() { return 1e-5f; }
108 };
109
110 template<> struct NumTraits<double> : GenericNumTraits<double>
111 {
112   inline static double dummy_precision() { return 1e-12; }
113 };
114
115 template<> struct NumTraits<long double>
116   : GenericNumTraits<long double>
117 {
118   static inline long double dummy_precision() { return 1e-15l; }
119 };
120
121 template<typename _Real> struct NumTraits<std::complex<_Real> >
122   : GenericNumTraits<std::complex<_Real> >
123 {
124   typedef _Real Real;
125   enum {
126     IsComplex = 1,
127     RequireInitialization = NumTraits<_Real>::RequireInitialization,
128     ReadCost = 2 * NumTraits<_Real>::ReadCost,
129     AddCost = 2 * NumTraits<Real>::AddCost,
130     MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
131   };
132
133   inline static Real epsilon() { return NumTraits<Real>::epsilon(); }
134   inline static Real dummy_precision() { return NumTraits<Real>::dummy_precision(); }
135 };
136
137 template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
138 struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
139 {
140   typedef Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> ArrayType;
141   typedef typename NumTraits<Scalar>::Real RealScalar;
142   typedef Array<RealScalar, Rows, Cols, Options, MaxRows, MaxCols> Real;
143   typedef typename NumTraits<Scalar>::NonInteger NonIntegerScalar;
144   typedef Array<NonIntegerScalar, Rows, Cols, Options, MaxRows, MaxCols> NonInteger;
145   typedef ArrayType & Nested;
146   
147   enum {
148     IsComplex = NumTraits<Scalar>::IsComplex,
149     IsInteger = NumTraits<Scalar>::IsInteger,
150     IsSigned  = NumTraits<Scalar>::IsSigned,
151     RequireInitialization = 1,
152     ReadCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::ReadCost,
153     AddCost  = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::AddCost,
154     MulCost  = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::MulCost
155   };
156 };
157
158
159
160 #endif // EIGEN_NUMTRAITS_H