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
30
#define VC_MINMAX(V) \
31
static Vc_ALWAYS_INLINE V min(const V &x, const V &y) { return V(std::min(x.data(), y.data())); } \
32
static Vc_ALWAYS_INLINE V max(const V &x, const V &y) { return V(std::max(x.data(), y.data())); }
33
VC_ALL_VECTOR_TYPES(VC_MINMAX)
36
template<typename T> static Vc_ALWAYS_INLINE Vector<T> sqrt (const Vector<T> &x)
38
return Vector<T>(std::sqrt(x.data()));
41
template<typename T> static Vc_ALWAYS_INLINE Vector<T> rsqrt(const Vector<T> &x)
43
const typename Vector<T>::EntryType one = 1; return Vector<T>(one / std::sqrt(x.data()));
46
template<typename T> static Vc_ALWAYS_INLINE Vector<T> abs (const Vector<T> &x)
48
return Vector<T>(std::abs(x.data()));
51
template<typename T> static Vc_ALWAYS_INLINE void sincos(const Vector<T> &x, Vector<T> *sin, Vector<T> *cos)
53
#if (defined(VC_CLANG) && VC_HAS_BUILTIN(__builtin_sincosf)) || (!defined(VC_CLANG) && defined(__GNUC__) && !defined(_WIN32))
54
__builtin_sincosf(x.data(), &sin->data(), &cos->data());
56
sin->data() = std::sin(x.data());
57
cos->data() = std::cos(x.data());
59
sincosf(x.data(), &sin->data(), &cos->data());
63
template<> Vc_ALWAYS_INLINE void sincos(const Vector<double> &x, Vector<double> *sin, Vector<double> *cos)
65
#if (defined(VC_CLANG) && VC_HAS_BUILTIN(__builtin_sincos)) || (!defined(VC_CLANG) && defined(__GNUC__) && !defined(_WIN32))
66
__builtin_sincos(x.data(), &sin->data(), &cos->data());
68
sin->data() = std::sin(x.data());
69
cos->data() = std::cos(x.data());
71
::sincos(x.data(), &sin->data(), &cos->data());
75
template<typename T> static Vc_ALWAYS_INLINE Vector<T> sin (const Vector<T> &x)
77
return Vector<T>(std::sin(x.data()));
80
template<typename T> static Vc_ALWAYS_INLINE Vector<T> asin (const Vector<T> &x)
82
return Vector<T>(std::asin(x.data()));
85
template<typename T> static Vc_ALWAYS_INLINE Vector<T> cos (const Vector<T> &x)
87
return Vector<T>(std::cos(x.data()));
90
template<typename T> static Vc_ALWAYS_INLINE Vector<T> log (const Vector<T> &x)
92
return Vector<T>(std::log(x.data()));
95
template<typename T> static Vc_ALWAYS_INLINE Vector<T> log10(const Vector<T> &x)
97
return Vector<T>(std::log10(x.data()));
100
#if _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L
101
static Vc_ALWAYS_INLINE double_v log2(double_v::AsArg x) { return double_v(::log2 (x.data())); }
102
static Vc_ALWAYS_INLINE sfloat_v log2(sfloat_v::AsArg x) { return sfloat_v(::log2f(x.data())); }
103
static Vc_ALWAYS_INLINE float_v log2( float_v::AsArg x) { return float_v(::log2f(x.data())); }
106
template<typename T> static _VC_CONSTEXPR T c_ln2() { return Vc_buildFloat(1, 0x317218, -1); } // .693147182464599609375
107
template<> _VC_CONSTEXPR double c_ln2() { return Vc_buildDouble(1, 0x62E42FEFA39EFull, -1); } // .69314718055994528622676398299518041312694549560546875
110
static Vc_ALWAYS_INLINE V log2(const V &x) \
112
return V(std::log(x.data()) / c_ln2<V::EntryType>()); \
114
VC_ALL_FLOAT_VECTOR_TYPES(VC_LOG2)
118
template<typename T> static Vc_ALWAYS_INLINE Vector<T> exp (const Vector<T> &x)
120
return Vector<T>(std::exp(x.data()));
123
template<typename T> static Vc_ALWAYS_INLINE Vector<T> atan (const Vector<T> &x)
125
return Vector<T>(std::atan( x.data() ));
128
template<typename T> static Vc_ALWAYS_INLINE Vector<T> atan2(const Vector<T> &x, const Vector<T> &y)
130
return Vector<T>(std::atan2( x.data(), y.data() ));
133
template<typename T> static Vc_ALWAYS_INLINE Vector<T> trunc(const Vector<T> &x)
135
#if __cplusplus >= 201103 /*C++11*/
136
return std::trunc(x.data());
138
return x.data() > 0 ? std::floor(x.data()) : std::ceil(x.data());
142
template<typename T> static Vc_ALWAYS_INLINE Vector<T> floor(const Vector<T> &x)
144
return Vector<T>(std::floor(x.data()));
147
template<typename T> static Vc_ALWAYS_INLINE Vector<T> ceil(const Vector<T> &x)
149
return Vector<T>(std::ceil(x.data()));
152
template<typename T> static Vc_ALWAYS_INLINE Vector<T> round(const Vector<T> &x)
159
template<typename T> bool _realIsEvenHalf(T x) {
162
const T f = std::floor(x * half) * two;
163
return (x - f) == half;
166
template<> Vc_ALWAYS_INLINE Vector<float> round(const Vector<float> &x)
168
return float_v(std::floor(x.data() + 0.5f) - (_realIsEvenHalf(x.data()) ? 1.f : 0.f));
171
template<> Vc_ALWAYS_INLINE Vector<sfloat> round(const Vector<sfloat> &x)
173
return sfloat_v(std::floor(x.data() + 0.5f) - (_realIsEvenHalf(x.data()) ? 1.f : 0.f));
176
template<> Vc_ALWAYS_INLINE Vector<double> round(const Vector<double> &x)
178
return double_v(std::floor(x.data() + 0.5 ) - (_realIsEvenHalf(x.data()) ? 1. : 0. ));
181
template<typename T> static Vc_ALWAYS_INLINE Vector<T> reciprocal(const Vector<T> &x)
183
const typename Vector<T>::EntryType one = 1; return Vector<T>(one / x.data());
192
template<typename T> static Vc_ALWAYS_INLINE typename Vector<T>::Mask isfinite(const Vector<T> &x)
194
return typename Vector<T>::Mask(
197
#elif defined(__INTEL_COMPILER)
200
std::isfinite(x.data())
205
template<typename T> static Vc_ALWAYS_INLINE typename Vector<T>::Mask isnan(const Vector<T> &x)
207
return typename Vector<T>::Mask(
210
#elif defined(__INTEL_COMPILER)
218
Vc_ALWAYS_INLINE Vector<float> frexp(Vector<float> x, Vector<int> *e) {
219
return float_v(::frexpf(x.data(), &e->data()));
221
Vc_ALWAYS_INLINE Vector<double> frexp(Vector<double> x, Vector<int> *e) {
222
return double_v(::frexp(x.data(), &e->data()));
224
Vc_ALWAYS_INLINE sfloat_v frexp(sfloat_v x, short_v *e) {
226
const float r = ::frexpf(x.data(), &ee);
231
Vc_ALWAYS_INLINE Vector<float> ldexp(Vector<float> x, Vector<int> e) {
232
return float_v(::ldexpf(x.data(), e.data()));
234
Vc_ALWAYS_INLINE Vector<double> ldexp(Vector<double> x, Vector<int> e) {
235
return double_v(::ldexp(x.data(), e.data()));
237
Vc_ALWAYS_INLINE sfloat_v ldexp(sfloat_v x, short_v e) {
238
return sfloat_v(::ldexpf(x.data(), e.data()));
241
} // namespace Scalar
244
#include "undomacros.h"
246
#endif // VC_SCALAR_MATH_H