LSSTApplications  10.0+286,10.0+36,10.0+46,10.0-2-g4f67435,10.1+152,10.1+37,11.0,11.0+1,11.0-1-g47edd16,11.0-1-g60db491,11.0-1-g7418c06,11.0-2-g04d2804,11.0-2-g68503cd,11.0-2-g818369d,11.0-2-gb8b8ce7
LSSTDataManagementBasePackage
types.h
Go to the documentation of this file.
1 // -*- c++ -*-
2 /*
3  * LSST Data Management System
4  * Copyright 2008, 2009, 2010, 2011 LSST Corporation.
5  *
6  * This product includes software developed by the
7  * LSST Project (http://www.lsst.org/).
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the LSST License Statement and
20  * the GNU General Public License along with this program. If not,
21  * see <http://www.lsstcorp.org/LegalNotices/>.
22  */
23 #ifndef NDARRAY_types_h_INCLUDED
24 #define NDARRAY_types_h_INCLUDED
25 
27 
28 #include <complex>
29 #include <limits>
30 
31 #include <boost/type_traits/is_complex.hpp>
32 
33 namespace ndarray {
34 
37 
45 template <typename T, typename U=typename boost::remove_const<T>::type,
46  typename is_complex=typename boost::is_complex<U>::type,
47  typename is_arithmetic=typename boost::is_arithmetic<U>::type>
48 struct NumericTraits {};
49 
51 template <typename T, typename U>
52 struct NumericTraits<T,U,boost::false_type,boost::true_type> {
53  typedef U Type;
54  typedef boost::true_type IsReal;
55  typedef U RealType;
56  typedef std::complex<U> ComplexType;
57  typedef U ParamType;
58 
59  static const int PRIORITY = sizeof(U) + (sizeof(long long) * (!std::numeric_limits<U>::is_integer));
60 };
61 
62 template <typename T, typename U>
63 struct NumericTraits<T,U,boost::true_type,boost::false_type> {
64  typedef U type;
65  typedef boost::false_type IsReal;
66  typedef typename U::value_type RealType;
67  typedef U ComplexType;
68  typedef U const & ParamType;
69 
70  static const int PRIORITY = NumericTraits<RealType>::PRIORITY;
71 };
73 
78 template <typename T1, typename T2,
79  bool winner=(NumericTraits<T1>::PRIORITY > NumericTraits<T2>::PRIORITY),
80  bool is_complex=(NumericTraits<T1>::IsReal::value && NumericTraits<T2>::IsReal::value)
81  >
82 struct Promote {
83 };
84 
86 
87 // Real, T2 has priority
88 template <typename T1, typename T2>
89 struct Promote<T1,T2,false,true> {
90  typedef typename NumericTraits<T2>::Type Type;
91 };
92 
93 // Real, T1 has priority
94 template <typename T1, typename T2>
95 struct Promote<T1,T2,true,true> {
96  typedef typename NumericTraits<T1>::Type Type;
97 };
98 
99 // Complex, T2 has priority
100 template <typename T1, typename T2>
101 struct Promote<T1,T2,false,false> {
102  typedef typename NumericTraits<T2>::ComplexType Type;
103 };
104 
105 // Complex, T1 has priority
106 template <typename T1, typename T2>
107 struct Promote<T1,T2,true,false> {
108  typedef typename NumericTraits<T1>::ComplexType Type;
109 };
110 
112 
113 namespace detail {
114 
123 template <typename T>
125 
126  static inline T divide(T a, T b) {
127  if (b < static_cast<T>(1) && a > b*std::numeric_limits<T>::max())
128  return std::numeric_limits<T>::max();
129  if (a == static_cast<T>(0) || (b > static_cast<T>(1) && a < b*std::numeric_limits<T>::min()))
130  return static_cast<T>(0);
131  return a / b;
132  }
133 
134  static inline T abs(T a) {
135  return (a < static_cast<T>(0)) ? -a : a;
136  }
137 
138 };
139 
140 } // namespace detail
141 
148 template <typename T1, typename T2=T1>
152  typedef bool result_type;
153 
154  typedef typename Promote<T1,T2>::Type Promoted;
156 
157  result_type operator()(T1 a, T2 b) const {
158  Promoted diff = Ops::abs(a - b);
159  Promoted da = Ops::divide(diff,Ops::abs(a));
160  Promoted db = Ops::divide(diff,Ops::abs(b));
161  return db <= _tolerance && da <= _tolerance;
162  }
163 
164  explicit ApproximatelyEqual(Promoted tolerance) : _tolerance(Ops::abs(tolerance)) {}
165 
166 private:
168 };
169 
176 template <typename U1, typename U2>
177 struct ApproximatelyEqual< std::complex<U1>, std::complex<U2> > {
178  typedef std::complex<U1> first_argument_type;
179  typedef std::complex<U2> second_argument_type;
180  typedef bool result_type;
181 
182  typedef typename Promote<U1,U2>::Type Promoted;
183 
184  result_type operator()(std::complex<U1> const & a, std::complex<U2> const & b) const {
185  return _real(a.real(),b.real()) && _real(a.imag(),b.imag());
186  }
187 
188  explicit ApproximatelyEqual(Promoted tolerance) : _real(tolerance) {}
189 
190 private:
192 };
193 
195 
196 } // namespace ndarray
197 
198 #endif // !NDARRAY_types_h_INCLUDED
result_type operator()(std::complex< U1 > const &a, std::complex< U2 > const &b) const
Definition: types.h:184
result_type operator()(T1 a, T2 b) const
Definition: types.h:157
ApproximatelyEqual(Promoted tolerance)
Definition: types.h:164
Metafunction to compute numeric promotions.
Definition: types.h:82
Binary predicate for floating point equality comparison with tolerance.
Definition: types.h:149
Promote< T1, T2 >::Type Promoted
Definition: types.h:154
afw::table::Key< double > b
detail::SafeFloatingPointOps< Promoted > Ops
Definition: types.h:155
Numeric type traits.
Definition: types.h:48