-
Notifications
You must be signed in to change notification settings - Fork 0
/
cmath
166 lines (130 loc) · 4.42 KB
/
cmath
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/**
* @file cmath
* @author Jens Munk Hansen <[email protected]>
* @date Tue Mar 27 21:49:58 2018
*
* @brief
*
* Copyright 2018 Jens Munk Hansen
*/
#pragma once
#include <sps/cenv.h>
#include <sps/math.h>
#include <cmath>
#include <type_traits> // std::enable_if
#include <limits> // std::numeric_limits
/*
template <typename T> int sgn(T val) {
return (T(0) < val) - (val < T(0));
}
template <typename T> inline constexpr
int signum(T x, std::false_type is_signed) {
return T(0) < x;
}
template <typename T> inline constexpr
int signum(T x, std::true_type is_signed) {
return (T(0) < x) - (x < T(0));
}
template <typename T> inline constexpr
int signum(T x) {
return signum(x, std::is_signed<T>());
}
*/
namespace sps {
#ifdef CXX11
template<class T>
typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
almost_equal(T x, T y, int ulp) {
// the machine epsilon has to be scaled to the magnitude of the values used
// and multiplied by the desired precision in ULPs (units in the last place)
return (std::abs(x-y) < std::numeric_limits<T>::epsilon() * std::abs(x+y) * ulp)
// unless the result is subnormal
|| std::abs(x-y) < std::numeric_limits<T>::min();
}
#endif
/** @name Templated trigonometric functions. A way to enforce precission
*
*/
///@{
template <typename T>
inline T sin(const T& v) { return std::sin(v); }
template <typename T>
inline T cos(const T& v) { return std::cos(v); }
template <typename T>
inline T tan(const T& v) { return std::tan(v); }
template <typename T>
inline T asin(const T& v) { return std::asin(v); }
template <typename T>
inline T acos(const T& v) { return std::acos(v); }
template <typename T>
inline T atan(const T& v) { return std::atan(v); }
template <typename T>
inline T log(const T& v) { return std::log(v); }
template <>
inline float sin<float>(const float& v) { return sinf(v); }
template <>
inline float cos<float>(const float& v) { return cosf(v); }
template <>
inline float asin<float>(const float& v) { return asinf(v); }
template <>
inline float acos<float>(const float& v) { return acosf(v); }
template <>
inline float tan<float>(const float& v) { return tanf(v); }
template <>
inline float atan<float>(const float& v) { return ::atanf(v); }
template <>
inline float log(const float& v) { return ::logf(v); }
template <>
inline double sin<double>(const double& v) { return std::sin(v); }
template <>
inline double cos<double>(const double& v) { return std::cos(v); }
template <>
inline double asin<double>(const double& v) { return std::asin(v); }
template <>
inline double acos<double>(const double& v) { return std::acos(v); }
template <>
inline double tan<double>(const double& v) { return std::tan(v); }
template <>
inline double atan<double>(const double& v) { return std::atan(v); }
template <>
inline double log(const double& v) { return std::log(v); }
// Consider using traits and using traits = sps::trig_traits<float>
template <typename T>
struct trig_traits {
static constexpr T pi() { return T(M_PI);}
static inline auto sin(const T& v) { return std::sin(v); }
static inline auto cos(const T& v) { return std::cos(v); }
static inline auto tan(const T& v) { return std::tan(v); }
static inline auto asin(const T& v) { return std::asin(v); }
static inline auto acos(const T& v) { return std::acos(v); }
};
template <>
struct trig_traits<float> {
static constexpr float pi() { return float(M_PI); }
static inline auto sin(const float& v) { return sinf(v); }
static inline auto cos(const float& v) { return cosf(v); }
static inline auto tan(const float& v) { return tanf(v); }
static inline auto asin(const float& v) { return asinf(v); }
static inline auto acos(const float& v) { return acosf(v); }
};
} // namespace sps
///@}
template float sps::sin(const float& v);
template float sps::cos(const float& v);
template float sps::acos(const float& v);
template float sps::acos(const float& v);
template float sps::tan(const float& v);
template double sps::sin(const double& v);
template double sps::cos(const double& v);
template double sps::asin(const double& v);
template double sps::acos(const double& v);
template double sps::tan(const double& v);
template struct sps::trig_traits<float>;
template struct sps::trig_traits<double>;
/* Local variables: */
/* mode: c++ */
/* indent-tab-mode: nil */
/* tab-width: 2 */
/* c-basic-offset: 2 */
/* indent-tabs-mode: nil */
/* End: */