]> git.uio.no Git - u/mrichter/AliRoot.git/blob - Vc/include/Vc/scalar/math.h
Vc package added (version 0.6.79-dev)
[u/mrichter/AliRoot.git] / Vc / include / Vc / scalar / math.h
1 /*  This file is part of the Vc library.
2
3     Copyright (C) 2009-2012 Matthias Kretz <kretz@kde.org>
4
5     Vc is free software: you can redistribute it and/or modify
6     it under the terms of the GNU Lesser General Public License as
7     published by the Free Software Foundation, either version 3 of
8     the License, or (at your option) any later version.
9
10     Vc is distributed in the hope that it will be useful, but
11     WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with Vc.  If not, see <http://www.gnu.org/licenses/>.
17
18 */
19
20 #ifndef VC_SCALAR_MATH_H
21 #define VC_SCALAR_MATH_H
22
23 #include "../common/const.h"
24 #include "macros.h"
25
26 namespace Vc
27 {
28 namespace Scalar
29 {
30
31 #define VC_MINMAX(V) \
32 static inline V min(const V &x, const V &y) { return V(std::min(x.data(), y.data())); } \
33 static inline V max(const V &x, const V &y) { return V(std::max(x.data(), y.data())); }
34 VC_ALL_VECTOR_TYPES(VC_MINMAX)
35 #undef VC_MINMAX
36
37 template<typename T> static inline Vector<T> sqrt (const Vector<T> &x)
38 {
39     return Vector<T>(std::sqrt(x.data()));
40 }
41
42 template<typename T> static inline Vector<T> rsqrt(const Vector<T> &x)
43 {
44     const typename Vector<T>::EntryType one = 1; return Vector<T>(one / std::sqrt(x.data()));
45 }
46
47 template<typename T> static inline Vector<T> abs  (const Vector<T> &x)
48 {
49     return Vector<T>(std::abs(x.data()));
50 }
51
52 template<typename T> static inline void sincos(const Vector<T> &x, Vector<T> *sin, Vector<T> *cos)
53 {
54 #if (defined(VC_CLANG) && VC_HAS_BUILTIN(__builtin_sincosf)) || (!defined(VC_CLANG) && defined(__GNUC__))
55     __builtin_sincosf(x.data(), &sin->data(), &cos->data());
56 #elif VC_MSVC
57     sin->data() = std::sin(x.data());
58     cos->data() = std::cos(x.data());
59 #else
60     sincosf(x.data(), &sin->data(), &cos->data());
61 #endif
62 }
63
64 template<> inline void sincos(const Vector<double> &x, Vector<double> *sin, Vector<double> *cos)
65 {
66 #if (defined(VC_CLANG) && VC_HAS_BUILTIN(__builtin_sincos)) || (!defined(VC_CLANG) && defined(__GNUC__))
67     __builtin_sincos(x.data(), &sin->data(), &cos->data());
68 #elif VC_MSVC
69     sin->data() = std::sin(x.data());
70     cos->data() = std::cos(x.data());
71 #else
72     ::sincos(x.data(), &sin->data(), &cos->data());
73 #endif
74 }
75
76 template<typename T> static inline Vector<T> sin  (const Vector<T> &x)
77 {
78     return Vector<T>(std::sin(x.data()));
79 }
80
81 template<typename T> static inline Vector<T> asin (const Vector<T> &x)
82 {
83     return Vector<T>(std::asin(x.data()));
84 }
85
86 template<typename T> static inline Vector<T> cos  (const Vector<T> &x)
87 {
88     return Vector<T>(std::cos(x.data()));
89 }
90
91 template<typename T> static inline Vector<T> log  (const Vector<T> &x)
92 {
93     return Vector<T>(std::log(x.data()));
94 }
95
96 template<typename T> static inline Vector<T> log10(const Vector<T> &x)
97 {
98     return Vector<T>(std::log10(x.data()));
99 }
100
101 #if _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L
102 static inline double_v log2(double_v::AsArg x) { return double_v(::log2 (x.data())); }
103 static inline sfloat_v log2(sfloat_v::AsArg x) { return sfloat_v(::log2f(x.data())); }
104 static inline  float_v log2( float_v::AsArg x) { return  float_v(::log2f(x.data())); }
105 #else
106 #define VC_LOG2(V) \
107 static inline V log2(const V &x) \
108 { \
109     return V(std::log(x.data()) / Math<V::EntryType>::ln2()); \
110 }
111 VC_ALL_FLOAT_VECTOR_TYPES(VC_LOG2)
112 #undef VC_LOG2
113 #endif
114
115 template<typename T> static inline Vector<T> exp (const Vector<T> &x)
116 {
117     return Vector<T>(std::exp(x.data()));
118 }
119
120 template<typename T> static inline Vector<T> atan (const Vector<T> &x)
121 {
122     return Vector<T>(std::atan( x.data() ));
123 }
124
125 template<typename T> static inline Vector<T> atan2(const Vector<T> &x, const Vector<T> &y)
126 {
127     return Vector<T>(std::atan2( x.data(), y.data() ));
128 }
129
130 template<typename T> static inline Vector<T> floor(const Vector<T> &x)
131 {
132     return Vector<T>(std::floor(x.data()));
133 }
134
135 template<typename T> static inline Vector<T> ceil(const Vector<T> &x)
136 {
137     return Vector<T>(std::ceil(x.data()));
138 }
139
140 template<typename T> static inline Vector<T> round(const Vector<T> &x)
141 {
142     return x;
143 }
144
145 namespace
146 {
147     template<typename T> bool _realIsEvenHalf(T x) {
148         const T two = 2;
149         const T half = 0.5;
150         const T f = std::floor(x * half) * two;
151         return (x - f) == half;
152     }
153 } // namespace
154 template<> inline Vector<float>  round(const Vector<float>  &x)
155 {
156     return float_v(std::floor(x.data() + 0.5f) - (_realIsEvenHalf(x.data()) ? 1.f : 0.f));
157 }
158
159 template<> inline Vector<sfloat> round(const Vector<sfloat> &x)
160 {
161     return sfloat_v(std::floor(x.data() + 0.5f) - (_realIsEvenHalf(x.data()) ? 1.f : 0.f));
162 }
163
164 template<> inline Vector<double> round(const Vector<double> &x)
165 {
166     return double_v(std::floor(x.data() + 0.5 ) - (_realIsEvenHalf(x.data()) ? 1.  : 0. ));
167 }
168
169 template<typename T> static inline Vector<T> reciprocal(const Vector<T> &x)
170 {
171     const typename Vector<T>::EntryType one = 1; return Vector<T>(one / x.data());
172 }
173
174 #ifdef isfinite
175 #undef isfinite
176 #endif
177 #ifdef isnan
178 #undef isnan
179 #endif
180 template<typename T> static inline typename Vector<T>::Mask isfinite(const Vector<T> &x)
181 {
182     return typename Vector<T>::Mask(
183 #ifdef _MSC_VER
184             !!_finite(x.data())
185 #elif defined(__INTEL_COMPILER)
186             ::isfinite(x.data())
187 #else
188             std::isfinite(x.data())
189 #endif
190             );
191 }
192
193 template<typename T> static inline typename Vector<T>::Mask isnan(const Vector<T> &x)
194 {
195     return typename Vector<T>::Mask(
196 #ifdef _MSC_VER
197             !!_isnan(x.data())
198 #elif defined(__INTEL_COMPILER)
199             ::isnan(x.data())
200 #else
201             std::isnan(x.data())
202 #endif
203             );
204 }
205
206 inline Vector<float> frexp(Vector<float> x, Vector<int> *e) {
207     return float_v(::frexpf(x.data(), &e->data()));
208 }
209 inline Vector<double> frexp(Vector<double> x, Vector<int> *e) {
210     return double_v(::frexp(x.data(), &e->data()));
211 }
212 inline sfloat_v frexp(sfloat_v x, short_v *e) {
213     int ee;
214     const float r = ::frexpf(x.data(), &ee);
215     e->data() = ee;
216     return sfloat_v(r);
217 }
218
219 inline Vector<float> ldexp(Vector<float> x, Vector<int> e) {
220     return float_v(::ldexpf(x.data(), e.data()));
221 }
222 inline Vector<double> ldexp(Vector<double> x, Vector<int> e) {
223     return double_v(::ldexp(x.data(), e.data()));
224 }
225 inline sfloat_v ldexp(sfloat_v x, short_v e) {
226     return sfloat_v(::ldexpf(x.data(), e.data()));
227 }
228
229 } // namespace Scalar
230 } // namespace Vc
231
232 #include "undomacros.h"
233
234 #endif // VC_SCALAR_MATH_H