ndarray
NumPy-friendly multidimensional arrays in C++
Loading...
Searching...
No Matches
types.h
Go to the documentation of this file.
1// -*- c++ -*-
2/*
3 * Copyright (c) 2010-2012, Jim Bosch
4 * All rights reserved.
5 *
6 * ndarray is distributed under a simple BSD-like license;
7 * see the LICENSE file that should be present in the root
8 * of the source distribution, or alternately available at:
9 * https://github.com/ndarray/ndarray
10 */
11#ifndef NDARRAY_types_h_INCLUDED
12#define NDARRAY_types_h_INCLUDED
13
15
16#include <complex>
17#include <limits>
18
19#include <boost/type_traits/is_complex.hpp>
20
21namespace ndarray {
22
25
33template <typename T, typename U=typename boost::remove_const<T>::type,
34 typename is_complex=typename boost::is_complex<U>::type,
35 typename is_arithmetic=typename boost::is_arithmetic<U>::type>
36struct NumericTraits {};
37
39template <typename T, typename U>
40struct NumericTraits<T,U,boost::false_type,boost::true_type> {
41 typedef U Type;
42 typedef boost::true_type IsReal;
43 typedef U RealType;
44 typedef std::complex<U> ComplexType;
45 typedef U ParamType;
46
47 static const int PRIORITY = sizeof(U) + (sizeof(long long) * (!std::numeric_limits<U>::is_integer));
48};
49
50template <typename T, typename U>
51struct NumericTraits<T,U,boost::true_type,boost::false_type> {
52 typedef U type;
53 typedef boost::false_type IsReal;
54 typedef typename U::value_type RealType;
55 typedef U ComplexType;
56 typedef U const & ParamType;
57
58 static const int PRIORITY = NumericTraits<RealType>::PRIORITY;
59};
61
66template <typename T1, typename T2,
67 bool winner=(NumericTraits<T1>::PRIORITY > NumericTraits<T2>::PRIORITY),
68 bool is_complex=(NumericTraits<T1>::IsReal::value && NumericTraits<T2>::IsReal::value)
69 >
70struct Promote {
71};
72
74
75// Real, T2 has priority
76template <typename T1, typename T2>
77struct Promote<T1,T2,false,true> {
78 typedef typename NumericTraits<T2>::Type Type;
79};
80
81// Real, T1 has priority
82template <typename T1, typename T2>
83struct Promote<T1,T2,true,true> {
84 typedef typename NumericTraits<T1>::Type Type;
85};
86
87// Complex, T2 has priority
88template <typename T1, typename T2>
89struct Promote<T1,T2,false,false> {
90 typedef typename NumericTraits<T2>::ComplexType Type;
91};
92
93// Complex, T1 has priority
94template <typename T1, typename T2>
95struct Promote<T1,T2,true,false> {
96 typedef typename NumericTraits<T1>::ComplexType Type;
97};
98
100
101namespace detail {
102
111template <typename T>
113
114 static inline T divide(T a, T b) {
115 if (b < static_cast<T>(1) && a > b*std::numeric_limits<T>::max())
116 return std::numeric_limits<T>::max();
117 if (a == static_cast<T>(0) || (b > static_cast<T>(1) && a < b*std::numeric_limits<T>::min()))
118 return static_cast<T>(0);
119 return a / b;
120 }
121
122 static inline T abs(T a) {
123 return (a < static_cast<T>(0)) ? -a : a;
124 }
125
126};
127
128} // namespace detail
129
136template <typename T1, typename T2=T1>
138 typedef T1 first_argument_type;
139 typedef T2 second_argument_type;
140 typedef bool result_type;
141
142 typedef typename Promote<T1,T2>::Type Promoted;
144
145 result_type operator()(T1 a, T2 b) const {
146 Promoted diff = Ops::abs(a - b);
147 Promoted da = Ops::divide(diff,Ops::abs(a));
148 Promoted db = Ops::divide(diff,Ops::abs(b));
149 return db <= _tolerance && da <= _tolerance;
150 }
151
152 explicit ApproximatelyEqual(Promoted tolerance) : _tolerance(Ops::abs(tolerance)) {}
153
154private:
155 Promoted _tolerance;
156};
157
164template <typename U1, typename U2>
165struct ApproximatelyEqual< std::complex<U1>, std::complex<U2> > {
166 typedef std::complex<U1> first_argument_type;
167 typedef std::complex<U2> second_argument_type;
168 typedef bool result_type;
169
170 typedef typename Promote<U1,U2>::Type Promoted;
171
172 result_type operator()(std::complex<U1> const & a, std::complex<U2> const & b) const {
173 return _real(a.real(),b.real()) && _real(a.imag(),b.imag());
174 }
175
176 explicit ApproximatelyEqual(Promoted tolerance) : _real(tolerance) {}
177
178private:
180};
181
183
184} // namespace ndarray
185
186#endif // !NDARRAY_types_h_INCLUDED
Binary predicate for floating point equality comparison with tolerance.
Definition types.h:137
Numeric type traits.
Definition types.h:36
Metafunction to compute numeric promotions.
Definition types.h:70