~ubuntu-branches/ubuntu/raring/vc/raring-proposed

« back to all changes in this revision

Viewing changes to scalar/math.h

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-03-08 12:50:59 UTC
  • Revision ID: package-import@ubuntu.com-20130308125059-2vpu3hm02kgrqv96
Tags: upstream-0.7.0
ImportĀ upstreamĀ versionĀ 0.7.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "macros.h"
 
24
 
 
25
namespace Vc
 
26
{
 
27
namespace Scalar
 
28
{
 
29
 
 
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)
 
34
#undef VC_MINMAX
 
35
 
 
36
template<typename T> static Vc_ALWAYS_INLINE Vector<T> sqrt (const Vector<T> &x)
 
37
{
 
38
    return Vector<T>(std::sqrt(x.data()));
 
39
}
 
40
 
 
41
template<typename T> static Vc_ALWAYS_INLINE Vector<T> rsqrt(const Vector<T> &x)
 
42
{
 
43
    const typename Vector<T>::EntryType one = 1; return Vector<T>(one / std::sqrt(x.data()));
 
44
}
 
45
 
 
46
template<typename T> static Vc_ALWAYS_INLINE Vector<T> abs  (const Vector<T> &x)
 
47
{
 
48
    return Vector<T>(std::abs(x.data()));
 
49
}
 
50
 
 
51
template<typename T> static Vc_ALWAYS_INLINE void sincos(const Vector<T> &x, Vector<T> *sin, Vector<T> *cos)
 
52
{
 
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());
 
55
#elif defined(_WIN32)
 
56
    sin->data() = std::sin(x.data());
 
57
    cos->data() = std::cos(x.data());
 
58
#else
 
59
    sincosf(x.data(), &sin->data(), &cos->data());
 
60
#endif
 
61
}
 
62
 
 
63
template<> Vc_ALWAYS_INLINE void sincos(const Vector<double> &x, Vector<double> *sin, Vector<double> *cos)
 
64
{
 
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());
 
67
#elif defined(_WIN32)
 
68
    sin->data() = std::sin(x.data());
 
69
    cos->data() = std::cos(x.data());
 
70
#else
 
71
    ::sincos(x.data(), &sin->data(), &cos->data());
 
72
#endif
 
73
}
 
74
 
 
75
template<typename T> static Vc_ALWAYS_INLINE Vector<T> sin  (const Vector<T> &x)
 
76
{
 
77
    return Vector<T>(std::sin(x.data()));
 
78
}
 
79
 
 
80
template<typename T> static Vc_ALWAYS_INLINE Vector<T> asin (const Vector<T> &x)
 
81
{
 
82
    return Vector<T>(std::asin(x.data()));
 
83
}
 
84
 
 
85
template<typename T> static Vc_ALWAYS_INLINE Vector<T> cos  (const Vector<T> &x)
 
86
{
 
87
    return Vector<T>(std::cos(x.data()));
 
88
}
 
89
 
 
90
template<typename T> static Vc_ALWAYS_INLINE Vector<T> log  (const Vector<T> &x)
 
91
{
 
92
    return Vector<T>(std::log(x.data()));
 
93
}
 
94
 
 
95
template<typename T> static Vc_ALWAYS_INLINE Vector<T> log10(const Vector<T> &x)
 
96
{
 
97
    return Vector<T>(std::log10(x.data()));
 
98
}
 
99
 
 
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())); }
 
104
#else
 
105
namespace {
 
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
 
108
}
 
109
#define VC_LOG2(V) \
 
110
static Vc_ALWAYS_INLINE V log2(const V &x) \
 
111
{ \
 
112
    return V(std::log(x.data()) / c_ln2<V::EntryType>()); \
 
113
}
 
114
VC_ALL_FLOAT_VECTOR_TYPES(VC_LOG2)
 
115
#undef VC_LOG2
 
116
#endif
 
117
 
 
118
template<typename T> static Vc_ALWAYS_INLINE Vector<T> exp (const Vector<T> &x)
 
119
{
 
120
    return Vector<T>(std::exp(x.data()));
 
121
}
 
122
 
 
123
template<typename T> static Vc_ALWAYS_INLINE Vector<T> atan (const Vector<T> &x)
 
124
{
 
125
    return Vector<T>(std::atan( x.data() ));
 
126
}
 
127
 
 
128
template<typename T> static Vc_ALWAYS_INLINE Vector<T> atan2(const Vector<T> &x, const Vector<T> &y)
 
129
{
 
130
    return Vector<T>(std::atan2( x.data(), y.data() ));
 
131
}
 
132
 
 
133
template<typename T> static Vc_ALWAYS_INLINE Vector<T> trunc(const Vector<T> &x)
 
134
{
 
135
#if __cplusplus >= 201103 /*C++11*/
 
136
    return std::trunc(x.data());
 
137
#else
 
138
    return x.data() > 0 ? std::floor(x.data()) : std::ceil(x.data());
 
139
#endif
 
140
}
 
141
 
 
142
template<typename T> static Vc_ALWAYS_INLINE Vector<T> floor(const Vector<T> &x)
 
143
{
 
144
    return Vector<T>(std::floor(x.data()));
 
145
}
 
146
 
 
147
template<typename T> static Vc_ALWAYS_INLINE Vector<T> ceil(const Vector<T> &x)
 
148
{
 
149
    return Vector<T>(std::ceil(x.data()));
 
150
}
 
151
 
 
152
template<typename T> static Vc_ALWAYS_INLINE Vector<T> round(const Vector<T> &x)
 
153
{
 
154
    return x;
 
155
}
 
156
 
 
157
namespace
 
158
{
 
159
    template<typename T> bool _realIsEvenHalf(T x) {
 
160
        const T two = 2;
 
161
        const T half = 0.5;
 
162
        const T f = std::floor(x * half) * two;
 
163
        return (x - f) == half;
 
164
    }
 
165
} // namespace
 
166
template<> Vc_ALWAYS_INLINE Vector<float>  round(const Vector<float>  &x)
 
167
{
 
168
    return float_v(std::floor(x.data() + 0.5f) - (_realIsEvenHalf(x.data()) ? 1.f : 0.f));
 
169
}
 
170
 
 
171
template<> Vc_ALWAYS_INLINE Vector<sfloat> round(const Vector<sfloat> &x)
 
172
{
 
173
    return sfloat_v(std::floor(x.data() + 0.5f) - (_realIsEvenHalf(x.data()) ? 1.f : 0.f));
 
174
}
 
175
 
 
176
template<> Vc_ALWAYS_INLINE Vector<double> round(const Vector<double> &x)
 
177
{
 
178
    return double_v(std::floor(x.data() + 0.5 ) - (_realIsEvenHalf(x.data()) ? 1.  : 0. ));
 
179
}
 
180
 
 
181
template<typename T> static Vc_ALWAYS_INLINE Vector<T> reciprocal(const Vector<T> &x)
 
182
{
 
183
    const typename Vector<T>::EntryType one = 1; return Vector<T>(one / x.data());
 
184
}
 
185
 
 
186
#ifdef isfinite
 
187
#undef isfinite
 
188
#endif
 
189
#ifdef isnan
 
190
#undef isnan
 
191
#endif
 
192
template<typename T> static Vc_ALWAYS_INLINE typename Vector<T>::Mask isfinite(const Vector<T> &x)
 
193
{
 
194
    return typename Vector<T>::Mask(
 
195
#ifdef _MSC_VER
 
196
            !!_finite(x.data())
 
197
#elif defined(__INTEL_COMPILER)
 
198
            ::isfinite(x.data())
 
199
#else
 
200
            std::isfinite(x.data())
 
201
#endif
 
202
            );
 
203
}
 
204
 
 
205
template<typename T> static Vc_ALWAYS_INLINE typename Vector<T>::Mask isnan(const Vector<T> &x)
 
206
{
 
207
    return typename Vector<T>::Mask(
 
208
#ifdef _MSC_VER
 
209
            !!_isnan(x.data())
 
210
#elif defined(__INTEL_COMPILER)
 
211
            ::isnan(x.data())
 
212
#else
 
213
            std::isnan(x.data())
 
214
#endif
 
215
            );
 
216
}
 
217
 
 
218
Vc_ALWAYS_INLINE Vector<float> frexp(Vector<float> x, Vector<int> *e) {
 
219
    return float_v(::frexpf(x.data(), &e->data()));
 
220
}
 
221
Vc_ALWAYS_INLINE Vector<double> frexp(Vector<double> x, Vector<int> *e) {
 
222
    return double_v(::frexp(x.data(), &e->data()));
 
223
}
 
224
Vc_ALWAYS_INLINE sfloat_v frexp(sfloat_v x, short_v *e) {
 
225
    int ee;
 
226
    const float r = ::frexpf(x.data(), &ee);
 
227
    e->data() = ee;
 
228
    return sfloat_v(r);
 
229
}
 
230
 
 
231
Vc_ALWAYS_INLINE Vector<float> ldexp(Vector<float> x, Vector<int> e) {
 
232
    return float_v(::ldexpf(x.data(), e.data()));
 
233
}
 
234
Vc_ALWAYS_INLINE Vector<double> ldexp(Vector<double> x, Vector<int> e) {
 
235
    return double_v(::ldexp(x.data(), e.data()));
 
236
}
 
237
Vc_ALWAYS_INLINE sfloat_v ldexp(sfloat_v x, short_v e) {
 
238
    return sfloat_v(::ldexpf(x.data(), e.data()));
 
239
}
 
240
 
 
241
} // namespace Scalar
 
242
} // namespace Vc
 
243
 
 
244
#include "undomacros.h"
 
245
 
 
246
#endif // VC_SCALAR_MATH_H