Project Alice
Loading...
Searching...
No Matches
uniform.hpp
Go to the documentation of this file.
1/*
2Copyright 2010-2011, D. E. Shaw Research.
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are
7met:
8
9* Redistributions of source code must retain the above copyright
10 notice, this list of conditions, and the following disclaimer.
11
12* Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions, and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16* Neither the name of D. E. Shaw Research nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#ifndef __r123_uniform_dot_hpp
34#define __r123_uniform_dot_hpp
35
88#include <Random123/features/compilerfeatures.h>
89#include <limits>
90#if R123_USE_CXX11_TYPE_TRAITS
91#include <type_traits>
92#endif
93#if __cplusplus >= 201103L
94#include <array>
95#endif
96
97namespace r123 {
103#if R123_USE_CXX11_TYPE_TRAITS
104using std::make_signed;
105using std::make_unsigned;
106#else
107// Sigh... We could try to find another <type_traits>, e.g., from
108// boost or TR1. Or we can do it ourselves in the r123 namespace.
109// It's not clear which will cause less headache...
110template<typename T>
111struct make_signed { };
112template<typename T>
113struct make_unsigned { };
114#define R123_MK_SIGNED_UNSIGNED(ST, UT) \
115 template<> \
116 struct make_signed<ST> { \
117 typedef ST type; \
118 }; \
119 template<> \
120 struct make_signed<UT> { \
121 typedef ST type; \
122 }; \
123 template<> \
124 struct make_unsigned<ST> { \
125 typedef UT type; \
126 }; \
127 template<> \
128 struct make_unsigned<UT> { \
129 typedef UT type; \
130 }
131
132R123_MK_SIGNED_UNSIGNED(int8_t, uint8_t);
133R123_MK_SIGNED_UNSIGNED(int16_t, uint16_t);
134R123_MK_SIGNED_UNSIGNED(int32_t, uint32_t);
135R123_MK_SIGNED_UNSIGNED(int64_t, uint64_t);
136#if R123_USE_GNU_UINT128
137R123_MK_SIGNED_UNSIGNED(__int128_t, __uint128_t);
138#endif
139#undef R123_MK_SIGNED_UNSIGNED
140#endif
141
142#if defined(__CUDACC__) || defined(_LIBCPP_HAS_NO_CONSTEXPR)
143// Amazing! cuda thinks numeric_limits::max() is a __host__ function, so
144// we can't use it in a device function.
145//
146// The LIBCPP_HAS_NO_CONSTEXP test catches situations where the libc++
147// library thinks that the compiler doesn't support constexpr, but we
148// think it does. As a consequence, the library declares
149// numeric_limits::max without constexpr. This workaround should only
150// affect a narrow range of compiler/library pairings.
151//
152// In both cases, we find max() by computing ~(unsigned)0 right-shifted
153// by is_signed.
154template<typename T>
155R123_CONSTEXPR R123_STATIC_INLINE R123_CUDA_DEVICE T maxTvalue() {
156 typedef typename make_unsigned<T>::type uT;
157 return (~uT(0)) >> std::numeric_limits<T>::is_signed;
158}
159#else
160template<typename T>
161R123_CONSTEXPR R123_STATIC_INLINE T maxTvalue() {
162 return std::numeric_limits<T>::max();
163}
164#endif
170
188template<typename Ftype, typename Itype>
190 typedef typename make_unsigned<Itype>::type Utype;
191 R123_CONSTEXPR Ftype factor = Ftype(1.) / (Ftype(maxTvalue<Utype>()) + Ftype(1.));
192 R123_CONSTEXPR Ftype halffactor = Ftype(0.5) * factor;
193#if R123_UNIFORM_FLOAT_STORE
194 volatile Ftype x = Utype(in) * factor;
195 return x + halffactor;
196#else
197 return Utype(in) * factor + halffactor;
198#endif
199}
200
202
220template<typename Ftype, typename Itype>
222 typedef typename make_signed<Itype>::type Stype;
223 R123_CONSTEXPR Ftype factor = Ftype(1.) / (Ftype(maxTvalue<Stype>()) + Ftype(1.));
224 R123_CONSTEXPR Ftype halffactor = Ftype(0.5) * factor;
225#if R123_UNIFORM_FLOAT_STORE
226 volatile Ftype x = Stype(in) * factor;
227 return x + halffactor;
228#else
229 return Stype(in) * factor + halffactor;
230#endif
231}
232
234
254template<typename Ftype, typename Itype>
256 typedef typename make_unsigned<Itype>::type Utype;
257 R123_CONSTEXPR int excess = std::numeric_limits<Utype>::digits - std::numeric_limits<Ftype>::digits;
258 if(excess >= 0) {
259 R123_CONSTEXPR int ex_nowarn = (excess >= 0) ? excess : 0;
260 R123_CONSTEXPR Ftype factor = Ftype(1.) / (Ftype(1.) + Ftype((maxTvalue<Utype>() >> ex_nowarn)));
261 return (1 | (Utype(in) >> ex_nowarn)) * factor;
262 } else
263 return u01<Ftype>(in);
264}
265
266#if R123_USE_CXX11_STD_ARRAY
267
269
274template<typename Ftype, typename CollType>
275static inline std::array<Ftype, CollType::static_size> u01all(CollType in) {
276 std::array<Ftype, CollType::static_size> ret;
277 auto p = ret.begin();
278 for(auto e : in) {
279 *p++ = u01<Ftype>(e);
280 }
281 return ret;
282}
283
285
290template<typename Ftype, typename CollType>
291static inline std::array<Ftype, CollType::static_size> uneg11all(CollType in) {
292 std::array<Ftype, CollType::static_size> ret;
293 auto p = ret.begin();
294 for(auto e : in) {
295 *p++ = uneg11<Ftype>(e);
296 }
297 return ret;
298}
299
301
306template<typename Ftype, typename CollType>
307static inline std::array<Ftype, CollType::static_size> u01fixedptall(CollType in) {
308 std::array<Ftype, CollType::static_size> ret;
309 auto p = ret.begin();
310 for(auto e : in) {
311 *p++ = u01fixedpt<Ftype>(e);
312 }
313 return ret;
314}
315#endif // __cplusplus >= 201103L
316
317} // namespace r123
318
319#endif
#define R123_CUDA_DEVICE
#define R123_STATIC_INLINE
R123_CUDA_DEVICE R123_STATIC_INLINE Ftype u01fixedpt(Itype in)
Return a value in (0,1) chosen from a set of equally spaced fixed-point values.
Definition: uniform.hpp:255
Definition: array.h:344
R123_CUDA_DEVICE R123_STATIC_INLINE Ftype uneg11(Itype in)
Return a signed value in [-1,1].
Definition: uniform.hpp:221
R123_CUDA_DEVICE R123_STATIC_INLINE Ftype u01(Itype in)
Return a uniform real value in (0, 1].
Definition: uniform.hpp:189
uint uint32_t
ulong uint64_t
uchar uint8_t