1 /* This file is part of the Vc library.
3 Copyright (C) 2009-2012 Matthias Kretz <kretz@kde.org>
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.
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.
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/>.
20 #ifndef VC_SCALAR_MATH_H
21 #define VC_SCALAR_MATH_H
23 #include "../common/const.h"
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)
37 template<typename T> static inline Vector<T> sqrt (const Vector<T> &x)
39 return Vector<T>(std::sqrt(x.data()));
42 template<typename T> static inline Vector<T> rsqrt(const Vector<T> &x)
44 const typename Vector<T>::EntryType one = 1; return Vector<T>(one / std::sqrt(x.data()));
47 template<typename T> static inline Vector<T> abs (const Vector<T> &x)
49 return Vector<T>(std::abs(x.data()));
52 template<typename T> static inline void sincos(const Vector<T> &x, Vector<T> *sin, Vector<T> *cos)
54 #if (defined(VC_CLANG) && VC_HAS_BUILTIN(__builtin_sincosf)) || (!defined(VC_CLANG) && defined(__GNUC__))
55 __builtin_sincosf(x.data(), &sin->data(), &cos->data());
57 sin->data() = std::sin(x.data());
58 cos->data() = std::cos(x.data());
60 sincosf(x.data(), &sin->data(), &cos->data());
64 template<> inline void sincos(const Vector<double> &x, Vector<double> *sin, Vector<double> *cos)
66 #if (defined(VC_CLANG) && VC_HAS_BUILTIN(__builtin_sincos)) || (!defined(VC_CLANG) && defined(__GNUC__))
67 __builtin_sincos(x.data(), &sin->data(), &cos->data());
69 sin->data() = std::sin(x.data());
70 cos->data() = std::cos(x.data());
72 ::sincos(x.data(), &sin->data(), &cos->data());
76 template<typename T> static inline Vector<T> sin (const Vector<T> &x)
78 return Vector<T>(std::sin(x.data()));
81 template<typename T> static inline Vector<T> asin (const Vector<T> &x)
83 return Vector<T>(std::asin(x.data()));
86 template<typename T> static inline Vector<T> cos (const Vector<T> &x)
88 return Vector<T>(std::cos(x.data()));
91 template<typename T> static inline Vector<T> log (const Vector<T> &x)
93 return Vector<T>(std::log(x.data()));
96 template<typename T> static inline Vector<T> log10(const Vector<T> &x)
98 return Vector<T>(std::log10(x.data()));
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())); }
107 static inline V log2(const V &x) \
109 return V(std::log(x.data()) / Math<V::EntryType>::ln2()); \
111 VC_ALL_FLOAT_VECTOR_TYPES(VC_LOG2)
115 template<typename T> static inline Vector<T> exp (const Vector<T> &x)
117 return Vector<T>(std::exp(x.data()));
120 template<typename T> static inline Vector<T> atan (const Vector<T> &x)
122 return Vector<T>(std::atan( x.data() ));
125 template<typename T> static inline Vector<T> atan2(const Vector<T> &x, const Vector<T> &y)
127 return Vector<T>(std::atan2( x.data(), y.data() ));
130 template<typename T> static inline Vector<T> floor(const Vector<T> &x)
132 return Vector<T>(std::floor(x.data()));
135 template<typename T> static inline Vector<T> ceil(const Vector<T> &x)
137 return Vector<T>(std::ceil(x.data()));
140 template<typename T> static inline Vector<T> round(const Vector<T> &x)
147 template<typename T> bool _realIsEvenHalf(T x) {
150 const T f = std::floor(x * half) * two;
151 return (x - f) == half;
154 template<> inline Vector<float> round(const Vector<float> &x)
156 return float_v(std::floor(x.data() + 0.5f) - (_realIsEvenHalf(x.data()) ? 1.f : 0.f));
159 template<> inline Vector<sfloat> round(const Vector<sfloat> &x)
161 return sfloat_v(std::floor(x.data() + 0.5f) - (_realIsEvenHalf(x.data()) ? 1.f : 0.f));
164 template<> inline Vector<double> round(const Vector<double> &x)
166 return double_v(std::floor(x.data() + 0.5 ) - (_realIsEvenHalf(x.data()) ? 1. : 0. ));
169 template<typename T> static inline Vector<T> reciprocal(const Vector<T> &x)
171 const typename Vector<T>::EntryType one = 1; return Vector<T>(one / x.data());
180 template<typename T> static inline typename Vector<T>::Mask isfinite(const Vector<T> &x)
182 return typename Vector<T>::Mask(
185 #elif defined(__INTEL_COMPILER)
188 std::isfinite(x.data())
193 template<typename T> static inline typename Vector<T>::Mask isnan(const Vector<T> &x)
195 return typename Vector<T>::Mask(
198 #elif defined(__INTEL_COMPILER)
206 inline Vector<float> frexp(Vector<float> x, Vector<int> *e) {
207 return float_v(::frexpf(x.data(), &e->data()));
209 inline Vector<double> frexp(Vector<double> x, Vector<int> *e) {
210 return double_v(::frexp(x.data(), &e->data()));
212 inline sfloat_v frexp(sfloat_v x, short_v *e) {
214 const float r = ::frexpf(x.data(), &ee);
219 inline Vector<float> ldexp(Vector<float> x, Vector<int> e) {
220 return float_v(::ldexpf(x.data(), e.data()));
222 inline Vector<double> ldexp(Vector<double> x, Vector<int> e) {
223 return double_v(::ldexp(x.data(), e.data()));
225 inline sfloat_v ldexp(sfloat_v x, short_v e) {
226 return sfloat_v(::ldexpf(x.data(), e.data()));
229 } // namespace Scalar
232 #include "undomacros.h"
234 #endif // VC_SCALAR_MATH_H