diff options
Diffstat (limited to 'numpy/random/src')
49 files changed, 650 insertions, 6509 deletions
diff --git a/numpy/random/src/common/LICENSE.md b/numpy/random/src/common/LICENSE.md deleted file mode 100644 index 71bf8cf46..000000000 --- a/numpy/random/src/common/LICENSE.md +++ /dev/null @@ -1,29 +0,0 @@ -ISO C9x compliant stdint.h for Microsoft Visual Studio -Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 - -Copyright (c) 2006-2013 Alexander Chemeris - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. Neither the name of the product nor the names of its contributors may - be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file diff --git a/numpy/random/src/common/inttypes.h b/numpy/random/src/common/inttypes.h deleted file mode 100644 index 8f8b61108..000000000 --- a/numpy/random/src/common/inttypes.h +++ /dev/null @@ -1,306 +0,0 @@ -// ISO C9x compliant inttypes.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2013 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the product nor the names of its contributors may -// be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_INTTYPES_H_ // [ -#define _MSC_INTTYPES_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include "stdint.h" - -// 7.8 Format conversion of integer types - -typedef struct { - intmax_t quot; - intmax_t rem; -} imaxdiv_t; - -// 7.8.1 Macros for format specifiers - -#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 - -// The fprintf macros for signed integers are: -#define PRId8 "d" -#define PRIi8 "i" -#define PRIdLEAST8 "d" -#define PRIiLEAST8 "i" -#define PRIdFAST8 "d" -#define PRIiFAST8 "i" - -#define PRId16 "hd" -#define PRIi16 "hi" -#define PRIdLEAST16 "hd" -#define PRIiLEAST16 "hi" -#define PRIdFAST16 "hd" -#define PRIiFAST16 "hi" - -#define PRId32 "I32d" -#define PRIi32 "I32i" -#define PRIdLEAST32 "I32d" -#define PRIiLEAST32 "I32i" -#define PRIdFAST32 "I32d" -#define PRIiFAST32 "I32i" - -#define PRId64 "I64d" -#define PRIi64 "I64i" -#define PRIdLEAST64 "I64d" -#define PRIiLEAST64 "I64i" -#define PRIdFAST64 "I64d" -#define PRIiFAST64 "I64i" - -#define PRIdMAX "I64d" -#define PRIiMAX "I64i" - -#define PRIdPTR "Id" -#define PRIiPTR "Ii" - -// The fprintf macros for unsigned integers are: -#define PRIo8 "o" -#define PRIu8 "u" -#define PRIx8 "x" -#define PRIX8 "X" -#define PRIoLEAST8 "o" -#define PRIuLEAST8 "u" -#define PRIxLEAST8 "x" -#define PRIXLEAST8 "X" -#define PRIoFAST8 "o" -#define PRIuFAST8 "u" -#define PRIxFAST8 "x" -#define PRIXFAST8 "X" - -#define PRIo16 "ho" -#define PRIu16 "hu" -#define PRIx16 "hx" -#define PRIX16 "hX" -#define PRIoLEAST16 "ho" -#define PRIuLEAST16 "hu" -#define PRIxLEAST16 "hx" -#define PRIXLEAST16 "hX" -#define PRIoFAST16 "ho" -#define PRIuFAST16 "hu" -#define PRIxFAST16 "hx" -#define PRIXFAST16 "hX" - -#define PRIo32 "I32o" -#define PRIu32 "I32u" -#define PRIx32 "I32x" -#define PRIX32 "I32X" -#define PRIoLEAST32 "I32o" -#define PRIuLEAST32 "I32u" -#define PRIxLEAST32 "I32x" -#define PRIXLEAST32 "I32X" -#define PRIoFAST32 "I32o" -#define PRIuFAST32 "I32u" -#define PRIxFAST32 "I32x" -#define PRIXFAST32 "I32X" - -#define PRIo64 "I64o" -#define PRIu64 "I64u" -#define PRIx64 "I64x" -#define PRIX64 "I64X" -#define PRIoLEAST64 "I64o" -#define PRIuLEAST64 "I64u" -#define PRIxLEAST64 "I64x" -#define PRIXLEAST64 "I64X" -#define PRIoFAST64 "I64o" -#define PRIuFAST64 "I64u" -#define PRIxFAST64 "I64x" -#define PRIXFAST64 "I64X" - -#define PRIoMAX "I64o" -#define PRIuMAX "I64u" -#define PRIxMAX "I64x" -#define PRIXMAX "I64X" - -#define PRIoPTR "Io" -#define PRIuPTR "Iu" -#define PRIxPTR "Ix" -#define PRIXPTR "IX" - -// The fscanf macros for signed integers are: -#define SCNd8 "d" -#define SCNi8 "i" -#define SCNdLEAST8 "d" -#define SCNiLEAST8 "i" -#define SCNdFAST8 "d" -#define SCNiFAST8 "i" - -#define SCNd16 "hd" -#define SCNi16 "hi" -#define SCNdLEAST16 "hd" -#define SCNiLEAST16 "hi" -#define SCNdFAST16 "hd" -#define SCNiFAST16 "hi" - -#define SCNd32 "ld" -#define SCNi32 "li" -#define SCNdLEAST32 "ld" -#define SCNiLEAST32 "li" -#define SCNdFAST32 "ld" -#define SCNiFAST32 "li" - -#define SCNd64 "I64d" -#define SCNi64 "I64i" -#define SCNdLEAST64 "I64d" -#define SCNiLEAST64 "I64i" -#define SCNdFAST64 "I64d" -#define SCNiFAST64 "I64i" - -#define SCNdMAX "I64d" -#define SCNiMAX "I64i" - -#ifdef _WIN64 // [ -# define SCNdPTR "I64d" -# define SCNiPTR "I64i" -#else // _WIN64 ][ -# define SCNdPTR "ld" -# define SCNiPTR "li" -#endif // _WIN64 ] - -// The fscanf macros for unsigned integers are: -#define SCNo8 "o" -#define SCNu8 "u" -#define SCNx8 "x" -#define SCNX8 "X" -#define SCNoLEAST8 "o" -#define SCNuLEAST8 "u" -#define SCNxLEAST8 "x" -#define SCNXLEAST8 "X" -#define SCNoFAST8 "o" -#define SCNuFAST8 "u" -#define SCNxFAST8 "x" -#define SCNXFAST8 "X" - -#define SCNo16 "ho" -#define SCNu16 "hu" -#define SCNx16 "hx" -#define SCNX16 "hX" -#define SCNoLEAST16 "ho" -#define SCNuLEAST16 "hu" -#define SCNxLEAST16 "hx" -#define SCNXLEAST16 "hX" -#define SCNoFAST16 "ho" -#define SCNuFAST16 "hu" -#define SCNxFAST16 "hx" -#define SCNXFAST16 "hX" - -#define SCNo32 "lo" -#define SCNu32 "lu" -#define SCNx32 "lx" -#define SCNX32 "lX" -#define SCNoLEAST32 "lo" -#define SCNuLEAST32 "lu" -#define SCNxLEAST32 "lx" -#define SCNXLEAST32 "lX" -#define SCNoFAST32 "lo" -#define SCNuFAST32 "lu" -#define SCNxFAST32 "lx" -#define SCNXFAST32 "lX" - -#define SCNo64 "I64o" -#define SCNu64 "I64u" -#define SCNx64 "I64x" -#define SCNX64 "I64X" -#define SCNoLEAST64 "I64o" -#define SCNuLEAST64 "I64u" -#define SCNxLEAST64 "I64x" -#define SCNXLEAST64 "I64X" -#define SCNoFAST64 "I64o" -#define SCNuFAST64 "I64u" -#define SCNxFAST64 "I64x" -#define SCNXFAST64 "I64X" - -#define SCNoMAX "I64o" -#define SCNuMAX "I64u" -#define SCNxMAX "I64x" -#define SCNXMAX "I64X" - -#ifdef _WIN64 // [ -# define SCNoPTR "I64o" -# define SCNuPTR "I64u" -# define SCNxPTR "I64x" -# define SCNXPTR "I64X" -#else // _WIN64 ][ -# define SCNoPTR "lo" -# define SCNuPTR "lu" -# define SCNxPTR "lx" -# define SCNXPTR "lX" -#endif // _WIN64 ] - -#endif // __STDC_FORMAT_MACROS ] - -// 7.8.2 Functions for greatest-width integer types - -// 7.8.2.1 The imaxabs function -#define imaxabs _abs64 - -// 7.8.2.2 The imaxdiv function - -// This is modified version of div() function from Microsoft's div.c found -// in %MSVC.NET%\crt\src\div.c -#ifdef STATIC_IMAXDIV // [ -static -#else // STATIC_IMAXDIV ][ -_inline -#endif // STATIC_IMAXDIV ] -imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) -{ - imaxdiv_t result; - - result.quot = numer / denom; - result.rem = numer % denom; - - if (numer < 0 && result.rem > 0) { - // did division wrong; must fix up - ++result.quot; - result.rem -= denom; - } - - return result; -} - -// 7.8.2.3 The strtoimax and strtoumax functions -#define strtoimax _strtoi64 -#define strtoumax _strtoui64 - -// 7.8.2.4 The wcstoimax and wcstoumax functions -#define wcstoimax _wcstoi64 -#define wcstoumax _wcstoui64 - - -#endif // _MSC_INTTYPES_H_ ]
\ No newline at end of file diff --git a/numpy/random/src/common/stdint.h b/numpy/random/src/common/stdint.h deleted file mode 100644 index 710de1570..000000000 --- a/numpy/random/src/common/stdint.h +++ /dev/null @@ -1,258 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2013 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the product nor the names of its contributors may -// be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#if _MSC_VER >= 1600 // [ -#include <stdint.h> -#else // ] _MSC_VER >= 1600 [ - -#include <limits.h> - -// For Visual Studio 6 in C++ mode and for many Visual Studio versions when -// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}' -// or compiler give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#ifdef __cplusplus -extern "C" { -#endif -#include <wchar.h> -#ifdef __cplusplus -} -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -#define _W64 __w64 -#else -#define _W64 -#endif -#endif - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types - -// Visual Studio 6 and Embedded Visual C++ 4 doesn't -// realize that, e.g. char has the same size as __int8 -// so we give up on __intX for them. -#if (_MSC_VER < 1300) -typedef signed char int8_t; -typedef signed short int16_t; -typedef signed int int32_t; -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -#else -typedef signed __int8 int8_t; -typedef signed __int16 int16_t; -typedef signed __int32 int32_t; -typedef unsigned __int8 uint8_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int32 uint32_t; -#endif -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int16_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint16_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ -typedef signed __int64 intptr_t; -typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ -typedef _W64 signed int intptr_t; -typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || \ - defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and - // footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -#define INTPTR_MIN INT64_MIN -#define INTPTR_MAX INT64_MAX -#define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -#define INTPTR_MIN INT32_MIN -#define INTPTR_MAX INT32_MAX -#define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -#define PTRDIFF_MIN _I64_MIN -#define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -#define PTRDIFF_MIN _I32_MIN -#define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -#ifdef _WIN64 // [ -#define SIZE_MAX _UI64_MAX -#else // _WIN64 ][ -#define SIZE_MAX _UI32_MAX -#endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h> -#ifndef WCHAR_MIN // [ -#define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -#define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || \ - defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>. -// Check out Issue 9 for the details. -#ifndef INTMAX_C // [ -#define INTMAX_C INT64_C -#endif // INTMAX_C ] -#ifndef UINTMAX_C // [ -#define UINTMAX_C UINT64_C -#endif // UINTMAX_C ] - -#endif // __STDC_CONSTANT_MACROS ] - -#endif // _MSC_VER >= 1600 ] - -#endif // _MSC_STDINT_H_ ]
\ No newline at end of file diff --git a/numpy/random/src/distributions/distributions.c b/numpy/random/src/distributions/distributions.c index 73396a50b..789440f8b 100644 --- a/numpy/random/src/distributions/distributions.c +++ b/numpy/random/src/distributions/distributions.c @@ -7,110 +7,109 @@ #endif /* Random generators for external use */ -float random_float(brng_t *brng_state) { - return next_float(brng_state); -} +float random_float(bitgen_t *bitgen_state) { return next_float(bitgen_state); } -double random_double(brng_t *brng_state) { - return next_double(brng_state); +double random_double(bitgen_t *bitgen_state) { + return next_double(bitgen_state); } -static NPY_INLINE double next_standard_exponential(brng_t *brng_state) { - return -log(1.0 - next_double(brng_state)); +static NPY_INLINE double next_standard_exponential(bitgen_t *bitgen_state) { + return -log(1.0 - next_double(bitgen_state)); } -double random_standard_exponential(brng_t *brng_state) { - return next_standard_exponential(brng_state); +double random_standard_exponential(bitgen_t *bitgen_state) { + return next_standard_exponential(bitgen_state); } -void random_standard_exponential_fill(brng_t *brng_state, npy_intp cnt, +void random_standard_exponential_fill(bitgen_t *bitgen_state, npy_intp cnt, double *out) { npy_intp i; for (i = 0; i < cnt; i++) { - out[i] = next_standard_exponential(brng_state); + out[i] = next_standard_exponential(bitgen_state); } } -float random_standard_exponential_f(brng_t *brng_state) { - return -logf(1.0f - next_float(brng_state)); +float random_standard_exponential_f(bitgen_t *bitgen_state) { + return -logf(1.0f - next_float(bitgen_state)); } -void random_double_fill(brng_t *brng_state, npy_intp cnt, double *out) { +void random_double_fill(bitgen_t *bitgen_state, npy_intp cnt, double *out) { npy_intp i; for (i = 0; i < cnt; i++) { - out[i] = next_double(brng_state); + out[i] = next_double(bitgen_state); } } #if 0 -double random_gauss(brng_t *brng_state) { - if (brng_state->has_gauss) { - const double temp = brng_state->gauss; - brng_state->has_gauss = false; - brng_state->gauss = 0.0; +double random_gauss(bitgen_t *bitgen_state) { + if (bitgen_state->has_gauss) { + const double temp = bitgen_state->gauss; + bitgen_state->has_gauss = false; + bitgen_state->gauss = 0.0; return temp; } else { double f, x1, x2, r2; do { - x1 = 2.0 * next_double(brng_state) - 1.0; - x2 = 2.0 * next_double(brng_state) - 1.0; + x1 = 2.0 * next_double(bitgen_state) - 1.0; + x2 = 2.0 * next_double(bitgen_state) - 1.0; r2 = x1 * x1 + x2 * x2; } while (r2 >= 1.0 || r2 == 0.0); /* Polar method, a more efficient version of the Box-Muller approach. */ f = sqrt(-2.0 * log(r2) / r2); /* Keep for next call */ - brng_state->gauss = f * x1; - brng_state->has_gauss = true; + bitgen_state->gauss = f * x1; + bitgen_state->has_gauss = true; return f * x2; } } -float random_gauss_f(brng_t *brng_state) { - if (brng_state->has_gauss_f) { - const float temp = brng_state->gauss_f; - brng_state->has_gauss_f = false; - brng_state->gauss_f = 0.0f; +float random_gauss_f(bitgen_t *bitgen_state) { + if (bitgen_state->has_gauss_f) { + const float temp = bitgen_state->gauss_f; + bitgen_state->has_gauss_f = false; + bitgen_state->gauss_f = 0.0f; return temp; } else { float f, x1, x2, r2; do { - x1 = 2.0f * next_float(brng_state) - 1.0f; - x2 = 2.0f * next_float(brng_state) - 1.0f; + x1 = 2.0f * next_float(bitgen_state) - 1.0f; + x2 = 2.0f * next_float(bitgen_state) - 1.0f; r2 = x1 * x1 + x2 * x2; } while (r2 >= 1.0 || r2 == 0.0); /* Polar method, a more efficient version of the Box-Muller approach. */ f = sqrtf(-2.0f * logf(r2) / r2); /* Keep for next call */ - brng_state->gauss_f = f * x1; - brng_state->has_gauss_f = true; + bitgen_state->gauss_f = f * x1; + bitgen_state->has_gauss_f = true; return f * x2; } } #endif -static NPY_INLINE double standard_exponential_zig(brng_t *brng_state); +static NPY_INLINE double standard_exponential_zig(bitgen_t *bitgen_state); -static double standard_exponential_zig_unlikely(brng_t *brng_state, uint8_t idx, - double x) { +static double standard_exponential_zig_unlikely(bitgen_t *bitgen_state, + uint8_t idx, double x) { if (idx == 0) { - return ziggurat_exp_r - log(next_double(brng_state)); - } else if ((fe_double[idx - 1] - fe_double[idx]) * next_double(brng_state) + + /* Switch to 1.0 - U to avoid log(0.0), see GH 13361 */ + return ziggurat_exp_r - log(1.0 - next_double(bitgen_state)); + } else if ((fe_double[idx - 1] - fe_double[idx]) * next_double(bitgen_state) + fe_double[idx] < exp(-x)) { return x; } else { - return standard_exponential_zig(brng_state); + return standard_exponential_zig(bitgen_state); } } -static NPY_INLINE double standard_exponential_zig(brng_t *brng_state) { +static NPY_INLINE double standard_exponential_zig(bitgen_t *bitgen_state) { uint64_t ri; uint8_t idx; double x; - ri = next_uint64(brng_state); + ri = next_uint64(bitgen_state); ri >>= 3; idx = ri & 0xFF; ri >>= 8; @@ -118,41 +117,42 @@ static NPY_INLINE double standard_exponential_zig(brng_t *brng_state) { if (ri < ke_double[idx]) { return x; /* 98.9% of the time we return here 1st try */ } - return standard_exponential_zig_unlikely(brng_state, idx, x); + return standard_exponential_zig_unlikely(bitgen_state, idx, x); } -double random_standard_exponential_zig(brng_t *brng_state) { - return standard_exponential_zig(brng_state); +double random_standard_exponential_zig(bitgen_t *bitgen_state) { + return standard_exponential_zig(bitgen_state); } -void random_standard_exponential_zig_fill(brng_t *brng_state, npy_intp cnt, +void random_standard_exponential_zig_fill(bitgen_t *bitgen_state, npy_intp cnt, double *out) { npy_intp i; for (i = 0; i < cnt; i++) { - out[i] = standard_exponential_zig(brng_state); + out[i] = standard_exponential_zig(bitgen_state); } } -static NPY_INLINE float standard_exponential_zig_f(brng_t *brng_state); +static NPY_INLINE float standard_exponential_zig_f(bitgen_t *bitgen_state); -static float standard_exponential_zig_unlikely_f(brng_t *brng_state, +static float standard_exponential_zig_unlikely_f(bitgen_t *bitgen_state, uint8_t idx, float x) { if (idx == 0) { - return ziggurat_exp_r_f - logf(next_float(brng_state)); - } else if ((fe_float[idx - 1] - fe_float[idx]) * next_float(brng_state) + + /* Switch to 1.0 - U to avoid log(0.0), see GH 13361 */ + return ziggurat_exp_r_f - logf(1.0f - next_float(bitgen_state)); + } else if ((fe_float[idx - 1] - fe_float[idx]) * next_float(bitgen_state) + fe_float[idx] < expf(-x)) { return x; } else { - return standard_exponential_zig_f(brng_state); + return standard_exponential_zig_f(bitgen_state); } } -static NPY_INLINE float standard_exponential_zig_f(brng_t *brng_state) { +static NPY_INLINE float standard_exponential_zig_f(bitgen_t *bitgen_state) { uint32_t ri; uint8_t idx; float x; - ri = next_uint32(brng_state); + ri = next_uint32(bitgen_state); ri >>= 1; idx = ri & 0xFF; ri >>= 8; @@ -160,14 +160,14 @@ static NPY_INLINE float standard_exponential_zig_f(brng_t *brng_state) { if (ri < ke_float[idx]) { return x; /* 98.9% of the time we return here 1st try */ } - return standard_exponential_zig_unlikely_f(brng_state, idx, x); + return standard_exponential_zig_unlikely_f(bitgen_state, idx, x); } -float random_standard_exponential_zig_f(brng_t *brng_state) { - return standard_exponential_zig_f(brng_state); +float random_standard_exponential_zig_f(bitgen_t *bitgen_state) { + return standard_exponential_zig_f(bitgen_state); } -static NPY_INLINE double next_gauss_zig(brng_t *brng_state) { +static NPY_INLINE double next_gauss_zig(bitgen_t *bitgen_state) { uint64_t r; int sign; int64_t rabs; @@ -175,7 +175,7 @@ static NPY_INLINE double next_gauss_zig(brng_t *brng_state) { double x, xx, yy; for (;;) { /* r = e3n52sb8 */ - r = next_uint64(brng_state); + r = next_uint64(bitgen_state); idx = r & 0xff; r >>= 8; sign = r & 0x1; @@ -187,32 +187,33 @@ static NPY_INLINE double next_gauss_zig(brng_t *brng_state) { return x; /* 99.3% of the time return here */ if (idx == 0) { for (;;) { - xx = -ziggurat_nor_inv_r * log(next_double(brng_state)); - yy = -log(next_double(brng_state)); + /* Switch to 1.0 - U to avoid log(0.0), see GH 13361 */ + xx = -ziggurat_nor_inv_r * log(1.0 - next_double(bitgen_state)); + yy = -log(1.0 - next_double(bitgen_state)); if (yy + yy > xx * xx) return ((rabs >> 8) & 0x1) ? -(ziggurat_nor_r + xx) : ziggurat_nor_r + xx; } } else { - if (((fi_double[idx - 1] - fi_double[idx]) * next_double(brng_state) + + if (((fi_double[idx - 1] - fi_double[idx]) * next_double(bitgen_state) + fi_double[idx]) < exp(-0.5 * x * x)) return x; } } } -double random_gauss_zig(brng_t *brng_state) { - return next_gauss_zig(brng_state); +double random_gauss_zig(bitgen_t *bitgen_state) { + return next_gauss_zig(bitgen_state); } -void random_gauss_zig_fill(brng_t *brng_state, npy_intp cnt, double *out) { +void random_gauss_zig_fill(bitgen_t *bitgen_state, npy_intp cnt, double *out) { npy_intp i; for (i = 0; i < cnt; i++) { - out[i] = next_gauss_zig(brng_state); + out[i] = next_gauss_zig(bitgen_state); } } -float random_gauss_zig_f(brng_t *brng_state) { +float random_gauss_zig_f(bitgen_t *bitgen_state) { uint32_t r; int sign; int32_t rabs; @@ -220,7 +221,7 @@ float random_gauss_zig_f(brng_t *brng_state) { float x, xx, yy; for (;;) { /* r = n23sb8 */ - r = next_uint32(brng_state); + r = next_uint32(bitgen_state); idx = r & 0xff; sign = (r >> 8) & 0x1; rabs = (int32_t)((r >> 9) & 0x0007fffff); @@ -231,14 +232,15 @@ float random_gauss_zig_f(brng_t *brng_state) { return x; /* # 99.3% of the time return here */ if (idx == 0) { for (;;) { - xx = -ziggurat_nor_inv_r_f * logf(next_float(brng_state)); - yy = -logf(next_float(brng_state)); + /* Switch to 1.0 - U to avoid log(0.0), see GH 13361 */ + xx = -ziggurat_nor_inv_r_f * logf(1.0f - next_float(bitgen_state)); + yy = -logf(1.0f - next_float(bitgen_state)); if (yy + yy > xx * xx) return ((rabs >> 8) & 0x1) ? -(ziggurat_nor_r_f + xx) : ziggurat_nor_r_f + xx; } } else { - if (((fi_float[idx - 1] - fi_float[idx]) * next_float(brng_state) + + if (((fi_float[idx - 1] - fi_float[idx]) * next_float(bitgen_state) + fi_float[idx]) < exp(-0.5 * x * x)) return x; } @@ -246,16 +248,16 @@ float random_gauss_zig_f(brng_t *brng_state) { } /* -static NPY_INLINE double standard_gamma(brng_t *brng_state, double shape) { +static NPY_INLINE double standard_gamma(bitgen_t *bitgen_state, double shape) { double b, c; double U, V, X, Y; if (shape == 1.0) { - return random_standard_exponential(brng_state); + return random_standard_exponential(bitgen_state); } else if (shape < 1.0) { for (;;) { - U = next_double(brng_state); - V = random_standard_exponential(brng_state); + U = next_double(bitgen_state); + V = random_standard_exponential(bitgen_state); if (U <= 1.0 - shape) { X = pow(U, 1. / shape); if (X <= V) { @@ -274,12 +276,12 @@ static NPY_INLINE double standard_gamma(brng_t *brng_state, double shape) { c = 1. / sqrt(9 * b); for (;;) { do { - X = random_gauss(brng_state); + X = random_gauss(bitgen_state); V = 1.0 + c * X; } while (V <= 0.0); V = V * V * V; - U = next_double(brng_state); + U = next_double(bitgen_state); if (U < 1.0 - 0.0331 * (X * X) * (X * X)) return (b * V); if (log(U) < 0.5 * X * X + b * (1. - V + log(V))) @@ -288,16 +290,15 @@ static NPY_INLINE double standard_gamma(brng_t *brng_state, double shape) { } } -static NPY_INLINE float standard_gamma_float(brng_t *brng_state, float shape) { - float b, c; - float U, V, X, Y; +static NPY_INLINE float standard_gamma_float(bitgen_t *bitgen_state, float +shape) { float b, c; float U, V, X, Y; if (shape == 1.0f) { - return random_standard_exponential_f(brng_state); + return random_standard_exponential_f(bitgen_state); } else if (shape < 1.0f) { for (;;) { - U = next_float(brng_state); - V = random_standard_exponential_f(brng_state); + U = next_float(bitgen_state); + V = random_standard_exponential_f(bitgen_state); if (U <= 1.0f - shape) { X = powf(U, 1.0f / shape); if (X <= V) { @@ -316,12 +317,12 @@ static NPY_INLINE float standard_gamma_float(brng_t *brng_state, float shape) { c = 1.0f / sqrtf(9.0f * b); for (;;) { do { - X = random_gauss_f(brng_state); + X = random_gauss_f(bitgen_state); V = 1.0f + c * X; } while (V <= 0.0f); V = V * V * V; - U = next_float(brng_state); + U = next_float(bitgen_state); if (U < 1.0f - 0.0331f * (X * X) * (X * X)) return (b * V); if (logf(U) < 0.5f * X * X + b * (1.0f - V + logf(V))) @@ -331,27 +332,28 @@ static NPY_INLINE float standard_gamma_float(brng_t *brng_state, float shape) { } -double random_standard_gamma(brng_t *brng_state, double shape) { - return standard_gamma(brng_state, shape); +double random_standard_gamma(bitgen_t *bitgen_state, double shape) { + return standard_gamma(bitgen_state, shape); } -float random_standard_gamma_f(brng_t *brng_state, float shape) { - return standard_gamma_float(brng_state, shape); +float random_standard_gamma_f(bitgen_t *bitgen_state, float shape) { + return standard_gamma_float(bitgen_state, shape); } */ -static NPY_INLINE double standard_gamma_zig(brng_t *brng_state, double shape) { +static NPY_INLINE double standard_gamma_zig(bitgen_t *bitgen_state, + double shape) { double b, c; double U, V, X, Y; if (shape == 1.0) { - return random_standard_exponential_zig(brng_state); + return random_standard_exponential_zig(bitgen_state); } else if (shape == 0.0) { return 0.0; } else if (shape < 1.0) { for (;;) { - U = next_double(brng_state); - V = random_standard_exponential_zig(brng_state); + U = next_double(bitgen_state); + V = random_standard_exponential_zig(bitgen_state); if (U <= 1.0 - shape) { X = pow(U, 1. / shape); if (X <= V) { @@ -370,32 +372,34 @@ static NPY_INLINE double standard_gamma_zig(brng_t *brng_state, double shape) { c = 1. / sqrt(9 * b); for (;;) { do { - X = random_gauss_zig(brng_state); + X = random_gauss_zig(bitgen_state); V = 1.0 + c * X; } while (V <= 0.0); V = V * V * V; - U = next_double(brng_state); + U = next_double(bitgen_state); if (U < 1.0 - 0.0331 * (X * X) * (X * X)) return (b * V); + /* log(0.0) ok here */ if (log(U) < 0.5 * X * X + b * (1. - V + log(V))) return (b * V); } } } -static NPY_INLINE float standard_gamma_zig_f(brng_t *brng_state, float shape) { +static NPY_INLINE float standard_gamma_zig_f(bitgen_t *bitgen_state, + float shape) { float b, c; float U, V, X, Y; if (shape == 1.0f) { - return random_standard_exponential_zig_f(brng_state); + return random_standard_exponential_zig_f(bitgen_state); } else if (shape == 0.0) { return 0.0; } else if (shape < 1.0f) { for (;;) { - U = next_float(brng_state); - V = random_standard_exponential_zig_f(brng_state); + U = next_float(bitgen_state); + V = random_standard_exponential_zig_f(bitgen_state); if (U <= 1.0f - shape) { X = powf(U, 1.0f / shape); if (X <= V) { @@ -414,49 +418,50 @@ static NPY_INLINE float standard_gamma_zig_f(brng_t *brng_state, float shape) { c = 1.0f / sqrtf(9.0f * b); for (;;) { do { - X = random_gauss_zig_f(brng_state); + X = random_gauss_zig_f(bitgen_state); V = 1.0f + c * X; } while (V <= 0.0f); V = V * V * V; - U = next_float(brng_state); + U = next_float(bitgen_state); if (U < 1.0f - 0.0331f * (X * X) * (X * X)) return (b * V); + /* logf(0.0) ok here */ if (logf(U) < 0.5f * X * X + b * (1.0f - V + logf(V))) return (b * V); } } } -double random_standard_gamma_zig(brng_t *brng_state, double shape) { - return standard_gamma_zig(brng_state, shape); +double random_standard_gamma_zig(bitgen_t *bitgen_state, double shape) { + return standard_gamma_zig(bitgen_state, shape); } -float random_standard_gamma_zig_f(brng_t *brng_state, float shape) { - return standard_gamma_zig_f(brng_state, shape); +float random_standard_gamma_zig_f(bitgen_t *bitgen_state, float shape) { + return standard_gamma_zig_f(bitgen_state, shape); } -int64_t random_positive_int64(brng_t *brng_state) { - return next_uint64(brng_state) >> 1; +int64_t random_positive_int64(bitgen_t *bitgen_state) { + return next_uint64(bitgen_state) >> 1; } -int32_t random_positive_int32(brng_t *brng_state) { - return next_uint32(brng_state) >> 1; +int32_t random_positive_int32(bitgen_t *bitgen_state) { + return next_uint32(bitgen_state) >> 1; } -int64_t random_positive_int(brng_t *brng_state) { +int64_t random_positive_int(bitgen_t *bitgen_state) { #if ULONG_MAX <= 0xffffffffUL - return (int64_t)(next_uint32(brng_state) >> 1); + return (int64_t)(next_uint32(bitgen_state) >> 1); #else - return (int64_t)(next_uint64(brng_state) >> 1); + return (int64_t)(next_uint64(bitgen_state) >> 1); #endif } -uint64_t random_uint(brng_t *brng_state) { +uint64_t random_uint(bitgen_t *bitgen_state) { #if ULONG_MAX <= 0xffffffffUL - return next_uint32(brng_state); + return next_uint32(bitgen_state); #else - return next_uint64(brng_state); + return next_uint64(bitgen_state); #endif } @@ -500,47 +505,48 @@ static double loggam(double x) { } /* -double random_normal(brng_t *brng_state, double loc, double scale) { - return loc + scale * random_gauss(brng_state); +double random_normal(bitgen_t *bitgen_state, double loc, double scale) { + return loc + scale * random_gauss(bitgen_state); } */ -double random_normal_zig(brng_t *brng_state, double loc, double scale) { - return loc + scale * random_gauss_zig(brng_state); +double random_normal_zig(bitgen_t *bitgen_state, double loc, double scale) { + return loc + scale * random_gauss_zig(bitgen_state); } -double random_exponential(brng_t *brng_state, double scale) { - return scale * standard_exponential_zig(brng_state); +double random_exponential(bitgen_t *bitgen_state, double scale) { + return scale * standard_exponential_zig(bitgen_state); } -double random_uniform(brng_t *brng_state, double lower, double range) { - return lower + range * next_double(brng_state); +double random_uniform(bitgen_t *bitgen_state, double lower, double range) { + return lower + range * next_double(bitgen_state); } -double random_gamma(brng_t *brng_state, double shape, double scale) { - return scale * random_standard_gamma_zig(brng_state, shape); +double random_gamma(bitgen_t *bitgen_state, double shape, double scale) { + return scale * random_standard_gamma_zig(bitgen_state, shape); } -float random_gamma_float(brng_t *brng_state, float shape, float scale) { - return scale * random_standard_gamma_zig_f(brng_state, shape); +float random_gamma_float(bitgen_t *bitgen_state, float shape, float scale) { + return scale * random_standard_gamma_zig_f(bitgen_state, shape); } -double random_beta(brng_t *brng_state, double a, double b) { +double random_beta(bitgen_t *bitgen_state, double a, double b) { double Ga, Gb; if ((a <= 1.0) && (b <= 1.0)) { - double U, V, X, Y; + double U, V, X, Y, XpY; /* Use Johnk's algorithm */ while (1) { - U = next_double(brng_state); - V = next_double(brng_state); + U = next_double(bitgen_state); + V = next_double(bitgen_state); X = pow(U, 1.0 / a); Y = pow(V, 1.0 / b); - - if ((X + Y) <= 1.0) { + XpY = X + Y; + /* Reject if both U and V are 0.0, which is approx 1 in 10^106 */ + if ((XpY <= 1.0) && (XpY > 0.0)) { if (X + Y > 0) { - return X / (X + Y); + return X / XpY; } else { double logX = log(U) / a; double logY = log(V) / b; @@ -553,83 +559,94 @@ double random_beta(brng_t *brng_state, double a, double b) { } } } else { - Ga = random_standard_gamma_zig(brng_state, a); - Gb = random_standard_gamma_zig(brng_state, b); + Ga = random_standard_gamma_zig(bitgen_state, a); + Gb = random_standard_gamma_zig(bitgen_state, b); return Ga / (Ga + Gb); } } -double random_chisquare(brng_t *brng_state, double df) { - return 2.0 * random_standard_gamma_zig(brng_state, df / 2.0); +double random_chisquare(bitgen_t *bitgen_state, double df) { + return 2.0 * random_standard_gamma_zig(bitgen_state, df / 2.0); } -double random_f(brng_t *brng_state, double dfnum, double dfden) { - return ((random_chisquare(brng_state, dfnum) * dfden) / - (random_chisquare(brng_state, dfden) * dfnum)); +double random_f(bitgen_t *bitgen_state, double dfnum, double dfden) { + return ((random_chisquare(bitgen_state, dfnum) * dfden) / + (random_chisquare(bitgen_state, dfden) * dfnum)); } -double random_standard_cauchy(brng_t *brng_state) { - return random_gauss_zig(brng_state) / random_gauss_zig(brng_state); +double random_standard_cauchy(bitgen_t *bitgen_state) { + return random_gauss_zig(bitgen_state) / random_gauss_zig(bitgen_state); } -double random_pareto(brng_t *brng_state, double a) { - return exp(standard_exponential_zig(brng_state) / a) - 1; +double random_pareto(bitgen_t *bitgen_state, double a) { + return exp(standard_exponential_zig(bitgen_state) / a) - 1; } -double random_weibull(brng_t *brng_state, double a) { +double random_weibull(bitgen_t *bitgen_state, double a) { if (a == 0.0) { return 0.0; } - return pow(standard_exponential_zig(brng_state), 1. / a); + return pow(standard_exponential_zig(bitgen_state), 1. / a); } -double random_power(brng_t *brng_state, double a) { - return pow(1 - exp(-standard_exponential_zig(brng_state)), 1. / a); +double random_power(bitgen_t *bitgen_state, double a) { + return pow(1 - exp(-standard_exponential_zig(bitgen_state)), 1. / a); } -double random_laplace(brng_t *brng_state, double loc, double scale) { +double random_laplace(bitgen_t *bitgen_state, double loc, double scale) { double U; - U = next_double(brng_state); - if (U < 0.5) { + U = next_double(bitgen_state); + if (U >= 0.5) { + U = loc - scale * log(2.0 - U - U); + } else if (U > 0.0) { U = loc + scale * log(U + U); } else { - U = loc - scale * log(2.0 - U - U); + /* Reject U == 0.0 and call again to get next value */ + U = random_laplace(bitgen_state, loc, scale); } return U; } -double random_gumbel(brng_t *brng_state, double loc, double scale) { +double random_gumbel(bitgen_t *bitgen_state, double loc, double scale) { double U; - U = 1.0 - next_double(brng_state); - return loc - scale * log(-log(U)); + U = 1.0 - next_double(bitgen_state); + if (U < 1.0) { + return loc - scale * log(-log(U)); + } + /* Reject U == 1.0 and call again to get next value */ + return random_gumbel(bitgen_state, loc, scale); } -double random_logistic(brng_t *brng_state, double loc, double scale) { +double random_logistic(bitgen_t *bitgen_state, double loc, double scale) { double U; - U = next_double(brng_state); - return loc + scale * log(U / (1.0 - U)); + U = next_double(bitgen_state); + if (U > 0.0) { + return loc + scale * log(U / (1.0 - U)); + } + /* Reject U == 0.0 and call again to get next value */ + return random_logistic(bitgen_state, loc, scale); } -double random_lognormal(brng_t *brng_state, double mean, double sigma) { - return exp(random_normal_zig(brng_state, mean, sigma)); +double random_lognormal(bitgen_t *bitgen_state, double mean, double sigma) { + return exp(random_normal_zig(bitgen_state, mean, sigma)); } -double random_rayleigh(brng_t *brng_state, double mode) { - return mode * sqrt(-2.0 * log(1.0 - next_double(brng_state))); +double random_rayleigh(bitgen_t *bitgen_state, double mode) { + return mode * sqrt(-2.0 * log(1.0 - next_double(bitgen_state))); } -double random_standard_t(brng_t *brng_state, double df) { +double random_standard_t(bitgen_t *bitgen_state, double df) { double num, denom; - num = random_gauss_zig(brng_state); - denom = random_standard_gamma_zig(brng_state, df / 2); + num = random_gauss_zig(bitgen_state); + denom = random_standard_gamma_zig(bitgen_state, df / 2); return sqrt(df / 2) * num / sqrt(denom); } -static int64_t random_poisson_mult(brng_t *brng_state, double lam) { +static int64_t random_poisson_mult(bitgen_t *bitgen_state, double lam) { int64_t X; double prod, U, enlam; @@ -637,7 +654,7 @@ static int64_t random_poisson_mult(brng_t *brng_state, double lam) { X = 0; prod = 1.0; while (1) { - U = next_double(brng_state); + U = next_double(bitgen_state); prod *= U; if (prod > enlam) { X += 1; @@ -654,7 +671,7 @@ static int64_t random_poisson_mult(brng_t *brng_state, double lam) { */ #define LS2PI 0.91893853320467267 #define TWELFTH 0.083333333333333333333333 -static int64_t random_poisson_ptrs(brng_t *brng_state, double lam) { +static int64_t random_poisson_ptrs(bitgen_t *bitgen_state, double lam) { int64_t k; double U, V, slam, loglam, a, b, invalpha, vr, us; @@ -666,8 +683,8 @@ static int64_t random_poisson_ptrs(brng_t *brng_state, double lam) { vr = 0.9277 - 3.6224 / (b - 2); while (1) { - U = next_double(brng_state) - 0.5; - V = next_double(brng_state); + U = next_double(bitgen_state) - 0.5; + V = next_double(bitgen_state); us = 0.5 - fabs(U); k = (int64_t)floor((2 * a / us + b) * U + lam + 0.43); if ((us >= 0.07) && (V <= vr)) { @@ -676,6 +693,8 @@ static int64_t random_poisson_ptrs(brng_t *brng_state, double lam) { if ((k < 0) || ((us < 0.013) && (V > us))) { continue; } + /* log(V) == log(0.0) ok here */ + /* if U==0.0 so that us==0.0, log is ok since always returns */ if ((log(V) + log(invalpha) - log(a / (us * us) + b)) <= (-lam + k * loglam - loggam(k + 1))) { return k; @@ -683,22 +702,22 @@ static int64_t random_poisson_ptrs(brng_t *brng_state, double lam) { } } -int64_t random_poisson(brng_t *brng_state, double lam) { +int64_t random_poisson(bitgen_t *bitgen_state, double lam) { if (lam >= 10) { - return random_poisson_ptrs(brng_state, lam); + return random_poisson_ptrs(bitgen_state, lam); } else if (lam == 0) { return 0; } else { - return random_poisson_mult(brng_state, lam); + return random_poisson_mult(bitgen_state, lam); } } -int64_t random_negative_binomial(brng_t *brng_state, double n, double p) { - double Y = random_gamma(brng_state, n, (1 - p) / p); - return random_poisson(brng_state, Y); +int64_t random_negative_binomial(bitgen_t *bitgen_state, double n, double p) { + double Y = random_gamma(bitgen_state, n, (1 - p) / p); + return random_poisson(bitgen_state, Y); } -int64_t random_binomial_btpe(brng_t *brng_state, int64_t n, double p, +int64_t random_binomial_btpe(bitgen_t *bitgen_state, int64_t n, double p, binomial_t *binomial) { double r, q, fm, p1, xm, xl, xr, c, laml, lamr, p2, p3, p4; double a, u, v, s, F, rho, t, A, nrq, x1, x2, f1, f2, z, z2, w, w2, x; @@ -746,8 +765,8 @@ int64_t random_binomial_btpe(brng_t *brng_state, int64_t n, double p, /* sigh ... */ Step10: nrq = n * r * q; - u = next_double(brng_state) * p4; - v = next_double(brng_state); + u = next_double(bitgen_state) * p4; + v = next_double(bitgen_state); if (u > p1) goto Step20; y = (int64_t)floor(xm - p1 * v + u); @@ -767,14 +786,16 @@ Step30: if (u > p3) goto Step40; y = (int64_t)floor(xl + log(v) / laml); - if (y < 0) + /* Reject if v==0.0 since previous cast is undefined */ + if ((y < 0) || (v == 0.0)) goto Step10; v = v * (u - p2) * laml; goto Step50; Step40: y = (int64_t)floor(xr - log(v) / lamr); - if (y > n) + /* Reject if v==0.0 since previous cast is undefined */ + if ((y > n) || (v == 0.0)) goto Step10; v = v * (u - p3) * lamr; @@ -803,6 +824,7 @@ Step52: rho = (k / (nrq)) * ((k * (k / 3.0 + 0.625) + 0.16666666666666666) / nrq + 0.5); t = -k * k / (2 * nrq); + /* log(0.0) ok here */ A = log(v); if (A < (t - rho)) goto Step60; @@ -838,7 +860,7 @@ Step60: return y; } -int64_t random_binomial_inversion(brng_t *brng_state, int64_t n, double p, +int64_t random_binomial_inversion(bitgen_t *bitgen_state, int64_t n, double p, binomial_t *binomial) { double q, qn, np, px, U; int64_t X, bound; @@ -860,13 +882,13 @@ int64_t random_binomial_inversion(brng_t *brng_state, int64_t n, double p, } X = 0; px = qn; - U = next_double(brng_state); + U = next_double(bitgen_state); while (U > px) { X++; if (X > bound) { X = 0; px = qn; - U = next_double(brng_state); + U = next_double(bitgen_state); } else { U -= px; px = ((n - X + 1) * p * px) / (X * q); @@ -875,7 +897,7 @@ int64_t random_binomial_inversion(brng_t *brng_state, int64_t n, double p, return X; } -int64_t random_binomial(brng_t *brng_state, double p, int64_t n, +int64_t random_binomial(bitgen_t *bitgen_state, double p, int64_t n, binomial_t *binomial) { double q; @@ -884,52 +906,53 @@ int64_t random_binomial(brng_t *brng_state, double p, int64_t n, if (p <= 0.5) { if (p * n <= 30.0) { - return random_binomial_inversion(brng_state, n, p, binomial); + return random_binomial_inversion(bitgen_state, n, p, binomial); } else { - return random_binomial_btpe(brng_state, n, p, binomial); + return random_binomial_btpe(bitgen_state, n, p, binomial); } } else { q = 1.0 - p; if (q * n <= 30.0) { - return n - random_binomial_inversion(brng_state, n, q, binomial); + return n - random_binomial_inversion(bitgen_state, n, q, binomial); } else { - return n - random_binomial_btpe(brng_state, n, q, binomial); + return n - random_binomial_btpe(bitgen_state, n, q, binomial); } } } -double random_noncentral_chisquare(brng_t *brng_state, double df, double nonc) { - if (npy_isnan(nonc)){ +double random_noncentral_chisquare(bitgen_t *bitgen_state, double df, + double nonc) { + if (npy_isnan(nonc)) { return NPY_NAN; } if (nonc == 0) { - return random_chisquare(brng_state, df); + return random_chisquare(bitgen_state, df); } if (1 < df) { - const double Chi2 = random_chisquare(brng_state, df - 1); - const double n = random_gauss_zig(brng_state) + sqrt(nonc); + const double Chi2 = random_chisquare(bitgen_state, df - 1); + const double n = random_gauss_zig(bitgen_state) + sqrt(nonc); return Chi2 + n * n; } else { - const int64_t i = random_poisson(brng_state, nonc / 2.0); - return random_chisquare(brng_state, df + 2 * i); + const int64_t i = random_poisson(bitgen_state, nonc / 2.0); + return random_chisquare(bitgen_state, df + 2 * i); } } -double random_noncentral_f(brng_t *brng_state, double dfnum, double dfden, +double random_noncentral_f(bitgen_t *bitgen_state, double dfnum, double dfden, double nonc) { - double t = random_noncentral_chisquare(brng_state, dfnum, nonc) * dfden; - return t / (random_chisquare(brng_state, dfden) * dfnum); + double t = random_noncentral_chisquare(bitgen_state, dfnum, nonc) * dfden; + return t / (random_chisquare(bitgen_state, dfden) * dfnum); } -double random_wald(brng_t *brng_state, double mean, double scale) { +double random_wald(bitgen_t *bitgen_state, double mean, double scale) { double U, X, Y; double mu_2l; mu_2l = mean / (2 * scale); - Y = random_gauss_zig(brng_state); + Y = random_gauss_zig(bitgen_state); Y = mean * Y * Y; X = mean + mu_2l * (Y - sqrt(4 * scale * Y + Y * Y)); - U = next_double(brng_state); + U = next_double(bitgen_state); if (U <= mean / (mean + X)) { return X; } else { @@ -937,16 +960,16 @@ double random_wald(brng_t *brng_state, double mean, double scale) { } } -double random_vonmises(brng_t *brng_state, double mu, double kappa) { +double random_vonmises(bitgen_t *bitgen_state, double mu, double kappa) { double s; double U, V, W, Y, Z; double result, mod; int neg; - if (npy_isnan(kappa)){ + if (npy_isnan(kappa)) { return NPY_NAN; } if (kappa < 1e-8) { - return M_PI * (2 * next_double(brng_state) - 1); + return M_PI * (2 * next_double(bitgen_state) - 1); } else { /* with double precision rho is zero until 1.4e-8 */ if (kappa < 1e-5) { @@ -962,17 +985,21 @@ double random_vonmises(brng_t *brng_state, double mu, double kappa) { } while (1) { - U = next_double(brng_state); + U = next_double(bitgen_state); Z = cos(M_PI * U); W = (1 + s * Z) / (s + Z); Y = kappa * (s - W); - V = next_double(brng_state); + V = next_double(bitgen_state); + /* + * V==0.0 is ok here since Y >= 0 always leads + * to accept, while Y < 0 always rejects + */ if ((Y * (2 - Y) - V >= 0) || (log(Y / V) + 1 - Y >= 0)) { break; } } - U = next_double(brng_state); + U = next_double(bitgen_state); result = acos(W); if (U < 0.5) { @@ -990,22 +1017,22 @@ double random_vonmises(brng_t *brng_state, double mu, double kappa) { } } -int64_t random_logseries(brng_t *brng_state, double p) { +int64_t random_logseries(bitgen_t *bitgen_state, double p) { double q, r, U, V; int64_t result; r = log(1.0 - p); while (1) { - V = next_double(brng_state); + V = next_double(bitgen_state); if (V >= p) { return 1; } - U = next_double(brng_state); + U = next_double(bitgen_state); q = 1.0 - exp(r * U); if (V <= q * q) { result = (int64_t)floor(1 + log(V) / log(q)); - if (result < 1) { + if ((result < 1) || (V == 0.0)) { continue; } else { return result; @@ -1018,7 +1045,7 @@ int64_t random_logseries(brng_t *brng_state, double p) { } } -int64_t random_geometric_search(brng_t *brng_state, double p) { +int64_t random_geometric_search(bitgen_t *bitgen_state, double p) { double U; int64_t X; double sum, prod, q; @@ -1026,7 +1053,7 @@ int64_t random_geometric_search(brng_t *brng_state, double p) { X = 1; sum = prod = p; q = 1.0 - p; - U = next_double(brng_state); + U = next_double(bitgen_state); while (U > sum) { prod *= q; sum += prod; @@ -1035,19 +1062,19 @@ int64_t random_geometric_search(brng_t *brng_state, double p) { return X; } -int64_t random_geometric_inversion(brng_t *brng_state, double p) { - return (int64_t)ceil(log(1.0 - next_double(brng_state)) / log(1.0 - p)); +int64_t random_geometric_inversion(bitgen_t *bitgen_state, double p) { + return (int64_t)ceil(log(1.0 - next_double(bitgen_state)) / log(1.0 - p)); } -int64_t random_geometric(brng_t *brng_state, double p) { +int64_t random_geometric(bitgen_t *bitgen_state, double p) { if (p >= 0.333333333333333333333333) { - return random_geometric_search(brng_state, p); + return random_geometric_search(bitgen_state, p); } else { - return random_geometric_inversion(brng_state, p); + return random_geometric_inversion(bitgen_state, p); } } -int64_t random_zipf(brng_t *brng_state, double a) { +int64_t random_zipf(bitgen_t *bitgen_state, double a) { double am1, b; am1 = a - 1.0; @@ -1055,8 +1082,8 @@ int64_t random_zipf(brng_t *brng_state, double a) { while (1) { double T, U, V, X; - U = 1.0 - random_double(brng_state); - V = random_double(brng_state); + U = 1.0 - random_double(bitgen_state); + V = random_double(bitgen_state); X = floor(pow(U, -1.0 / am1)); /* * The real result may be above what can be represented in a signed @@ -1075,7 +1102,7 @@ int64_t random_zipf(brng_t *brng_state, double a) { } } -double random_triangular(brng_t *brng_state, double left, double mode, +double random_triangular(bitgen_t *bitgen_state, double left, double mode, double right) { double base, leftbase, ratio, leftprod, rightprod; double U; @@ -1086,7 +1113,7 @@ double random_triangular(brng_t *brng_state, double left, double mode, leftprod = leftbase * base; rightprod = (right - mode) * base; - U = next_double(brng_state); + U = next_double(bitgen_state); if (U <= ratio) { return left + sqrt(U * leftprod); } else { @@ -1094,8 +1121,8 @@ double random_triangular(brng_t *brng_state, double left, double mode, } } -int64_t random_hypergeometric_hyp(brng_t *brng_state, int64_t good, int64_t bad, - int64_t sample) { +int64_t random_hypergeometric_hyp(bitgen_t *bitgen_state, int64_t good, + int64_t bad, int64_t sample) { int64_t d1, k, z; double d2, u, y; @@ -1105,7 +1132,7 @@ int64_t random_hypergeometric_hyp(brng_t *brng_state, int64_t good, int64_t bad, y = d2; k = sample; while (y > 0.0) { - u = next_double(brng_state); + u = next_double(bitgen_state); y -= (int64_t)floor(u + y / (d1 + k)); k--; if (k == 0) @@ -1121,7 +1148,7 @@ int64_t random_hypergeometric_hyp(brng_t *brng_state, int64_t good, int64_t bad, /* D2 = 3 - 2*sqrt(3/e) */ #define D1 1.7155277699214135 #define D2 0.8989161620588988 -int64_t random_hypergeometric_hrua(brng_t *brng_state, int64_t good, +int64_t random_hypergeometric_hrua(bitgen_t *bitgen_state, int64_t good, int64_t bad, int64_t sample) { int64_t mingoodbad, maxgoodbad, popsize, m, d9; double d4, d5, d6, d7, d8, d10, d11; @@ -1144,8 +1171,8 @@ int64_t random_hypergeometric_hrua(brng_t *brng_state, int64_t good, /* 16 for 16-decimal-digit precision in D1 and D2 */ while (1) { - X = next_double(brng_state); - Y = next_double(brng_state); + X = next_double(bitgen_state); + Y = next_double(bitgen_state); W = d6 + d8 * (Y - 0.5) / X; /* fast rejection: */ @@ -1163,7 +1190,7 @@ int64_t random_hypergeometric_hrua(brng_t *brng_state, int64_t good, /* fast rejection: */ if (X * (X - T) >= 1) continue; - + /* log(0.0) is ok here, since always accept */ if (2.0 * log(X) <= T) break; /* acceptance */ } @@ -1181,18 +1208,18 @@ int64_t random_hypergeometric_hrua(brng_t *brng_state, int64_t good, #undef D1 #undef D2 -int64_t random_hypergeometric(brng_t *brng_state, int64_t good, int64_t bad, +int64_t random_hypergeometric(bitgen_t *bitgen_state, int64_t good, int64_t bad, int64_t sample) { if (sample > 10) { - return random_hypergeometric_hrua(brng_state, good, bad, sample); + return random_hypergeometric_hrua(bitgen_state, good, bad, sample); } else if (sample > 0) { - return random_hypergeometric_hyp(brng_state, good, bad, sample); + return random_hypergeometric_hyp(bitgen_state, good, bad, sample); } else { - return 0; + return 0; } } -uint64_t random_interval(brng_t *brng_state, uint64_t max) { +uint64_t random_interval(bitgen_t *bitgen_state, uint64_t max) { uint64_t mask, value; if (max == 0) { return 0; @@ -1210,15 +1237,16 @@ uint64_t random_interval(brng_t *brng_state, uint64_t max) { /* Search a random value in [0..mask] <= max */ if (max <= 0xffffffffUL) { - while ((value = (next_uint32(brng_state) & mask)) > max) + while ((value = (next_uint32(bitgen_state) & mask)) > max) ; } else { - while ((value = (next_uint64(brng_state) & mask)) > max) + while ((value = (next_uint64(bitgen_state) & mask)) > max) ; } return value; } +/* Bounded generators */ static NPY_INLINE uint64_t gen_mask(uint64_t max) { uint64_t mask = max; mask |= mask >> 1; @@ -1231,10 +1259,10 @@ static NPY_INLINE uint64_t gen_mask(uint64_t max) { } /* Generate 16 bit random numbers using a 32 bit buffer. */ -static NPY_INLINE uint16_t buffered_uint16(brng_t *brng_state, int *bcnt, +static NPY_INLINE uint16_t buffered_uint16(bitgen_t *bitgen_state, int *bcnt, uint32_t *buf) { if (!(bcnt[0])) { - buf[0] = next_uint32(brng_state); + buf[0] = next_uint32(bitgen_state); bcnt[0] = 1; } else { buf[0] >>= 16; @@ -1245,10 +1273,10 @@ static NPY_INLINE uint16_t buffered_uint16(brng_t *brng_state, int *bcnt, } /* Generate 8 bit random numbers using a 32 bit buffer. */ -static NPY_INLINE uint8_t buffered_uint8(brng_t *brng_state, int *bcnt, +static NPY_INLINE uint8_t buffered_uint8(bitgen_t *bitgen_state, int *bcnt, uint32_t *buf) { if (!(bcnt[0])) { - buf[0] = next_uint32(brng_state); + buf[0] = next_uint32(bitgen_state); bcnt[0] = 3; } else { buf[0] >>= 8; @@ -1259,11 +1287,11 @@ static NPY_INLINE uint8_t buffered_uint8(brng_t *brng_state, int *bcnt, } /* Static `masked rejection` function called by random_bounded_uint64(...) */ -static NPY_INLINE uint64_t bounded_masked_uint64(brng_t *brng_state, +static NPY_INLINE uint64_t bounded_masked_uint64(bitgen_t *bitgen_state, uint64_t rng, uint64_t mask) { uint64_t val; - while ((val = (next_uint64(brng_state) & mask)) > rng) + while ((val = (next_uint64(bitgen_state) & mask)) > rng) ; return val; @@ -1271,8 +1299,9 @@ static NPY_INLINE uint64_t bounded_masked_uint64(brng_t *brng_state, /* Static `masked rejection` function called by * random_buffered_bounded_uint32(...) */ -static NPY_INLINE uint32_t buffered_bounded_masked_uint32( - brng_t *brng_state, uint32_t rng, uint32_t mask, int *bcnt, uint32_t *buf) { +static NPY_INLINE uint32_t +buffered_bounded_masked_uint32(bitgen_t *bitgen_state, uint32_t rng, + uint32_t mask, int *bcnt, uint32_t *buf) { /* * The buffer and buffer count are not used here but are included to allow * this function to be templated with the similar uint8 and uint16 @@ -1281,7 +1310,7 @@ static NPY_INLINE uint32_t buffered_bounded_masked_uint32( uint32_t val; - while ((val = (next_uint32(brng_state) & mask)) > rng) + while ((val = (next_uint32(bitgen_state) & mask)) > rng) ; return val; @@ -1289,11 +1318,12 @@ static NPY_INLINE uint32_t buffered_bounded_masked_uint32( /* Static `masked rejection` function called by * random_buffered_bounded_uint16(...) */ -static NPY_INLINE uint16_t buffered_bounded_masked_uint16( - brng_t *brng_state, uint16_t rng, uint16_t mask, int *bcnt, uint32_t *buf) { +static NPY_INLINE uint16_t +buffered_bounded_masked_uint16(bitgen_t *bitgen_state, uint16_t rng, + uint16_t mask, int *bcnt, uint32_t *buf) { uint16_t val; - while ((val = (buffered_uint16(brng_state, bcnt, buf) & mask)) > rng) + while ((val = (buffered_uint16(bitgen_state, bcnt, buf) & mask)) > rng) ; return val; @@ -1301,20 +1331,36 @@ static NPY_INLINE uint16_t buffered_bounded_masked_uint16( /* Static `masked rejection` function called by * random_buffered_bounded_uint8(...) */ -static NPY_INLINE uint8_t buffered_bounded_masked_uint8(brng_t *brng_state, +static NPY_INLINE uint8_t buffered_bounded_masked_uint8(bitgen_t *bitgen_state, uint8_t rng, uint8_t mask, int *bcnt, uint32_t *buf) { uint8_t val; - while ((val = (buffered_uint8(brng_state, bcnt, buf) & mask)) > rng) + while ((val = (buffered_uint8(bitgen_state, bcnt, buf) & mask)) > rng) ; return val; } +static NPY_INLINE npy_bool buffered_bounded_bool(bitgen_t *bitgen_state, + npy_bool off, npy_bool rng, + npy_bool mask, int *bcnt, + uint32_t *buf) { + if (rng == 0) + return off; + if (!(bcnt[0])) { + buf[0] = next_uint32(bitgen_state); + bcnt[0] = 31; + } else { + buf[0] >>= 1; + bcnt[0] -= 1; + } + return (buf[0] & 0x00000001UL) != 0; +} + /* Static `Lemire rejection` function called by random_bounded_uint64(...) */ -static NPY_INLINE uint64_t bounded_lemire_uint64(brng_t *brng_state, +static NPY_INLINE uint64_t bounded_lemire_uint64(bitgen_t *bitgen_state, uint64_t rng) { /* * Uses Lemire's algorithm - https://arxiv.org/abs/1805.10941 @@ -1331,7 +1377,7 @@ static NPY_INLINE uint64_t bounded_lemire_uint64(brng_t *brng_state, uint64_t leftover; /* Generate a scaled random number. */ - m = ((__uint128_t)next_uint64(brng_state)) * rng_excl; + m = ((__uint128_t)next_uint64(bitgen_state)) * rng_excl; /* Rejection sampling to remove any bias. */ leftover = m & 0xFFFFFFFFFFFFFFFFULL; @@ -1344,7 +1390,7 @@ static NPY_INLINE uint64_t bounded_lemire_uint64(brng_t *brng_state, * rng_excl; */ while (leftover < threshold) { - m = ((__uint128_t)next_uint64(brng_state)) * rng_excl; + m = ((__uint128_t)next_uint64(bitgen_state)) * rng_excl; leftover = m & 0xFFFFFFFFFFFFFFFFULL; } } @@ -1357,7 +1403,7 @@ static NPY_INLINE uint64_t bounded_lemire_uint64(brng_t *brng_state, uint64_t x; uint64_t leftover; - x = next_uint64(brng_state); + x = next_uint64(bitgen_state); /* Rejection sampling to remove any bias. */ leftover = x * rng_excl; /* The lower 64-bits of the mult. */ @@ -1370,7 +1416,7 @@ static NPY_INLINE uint64_t bounded_lemire_uint64(brng_t *brng_state, * rng_excl; */ while (leftover < threshold) { - x = next_uint64(brng_state); + x = next_uint64(bitgen_state); leftover = x * rng_excl; } } @@ -1403,10 +1449,8 @@ static NPY_INLINE uint64_t bounded_lemire_uint64(brng_t *brng_state, /* Static `Lemire rejection` function called by * random_buffered_bounded_uint32(...) */ -static NPY_INLINE uint32_t buffered_bounded_lemire_uint32(brng_t *brng_state, - uint32_t rng, - int *bcnt, - uint32_t *buf) { +static NPY_INLINE uint32_t buffered_bounded_lemire_uint32( + bitgen_t *bitgen_state, uint32_t rng, int *bcnt, uint32_t *buf) { /* * Uses Lemire's algorithm - https://arxiv.org/abs/1805.10941 * @@ -1423,7 +1467,7 @@ static NPY_INLINE uint32_t buffered_bounded_lemire_uint32(brng_t *brng_state, uint32_t leftover; /* Generate a scaled random number. */ - m = ((uint64_t)next_uint32(brng_state)) * rng_excl; + m = ((uint64_t)next_uint32(bitgen_state)) * rng_excl; /* Rejection sampling to remove any bias */ leftover = m & 0xFFFFFFFFUL; @@ -1434,7 +1478,7 @@ static NPY_INLINE uint32_t buffered_bounded_lemire_uint32(brng_t *brng_state, /* Same as: threshold=((uint64_t)(0x100000000ULL - rng_excl)) % rng_excl; */ while (leftover < threshold) { - m = ((uint64_t)next_uint32(brng_state)) * rng_excl; + m = ((uint64_t)next_uint32(bitgen_state)) * rng_excl; leftover = m & 0xFFFFFFFFUL; } } @@ -1444,10 +1488,8 @@ static NPY_INLINE uint32_t buffered_bounded_lemire_uint32(brng_t *brng_state, /* Static `Lemire rejection` function called by * random_buffered_bounded_uint16(...) */ -static NPY_INLINE uint16_t buffered_bounded_lemire_uint16(brng_t *brng_state, - uint16_t rng, - int *bcnt, - uint32_t *buf) { +static NPY_INLINE uint16_t buffered_bounded_lemire_uint16( + bitgen_t *bitgen_state, uint16_t rng, int *bcnt, uint32_t *buf) { /* * Uses Lemire's algorithm - https://arxiv.org/abs/1805.10941 * @@ -1460,7 +1502,7 @@ static NPY_INLINE uint16_t buffered_bounded_lemire_uint16(brng_t *brng_state, uint16_t leftover; /* Generate a scaled random number. */ - m = ((uint32_t)buffered_uint16(brng_state, bcnt, buf)) * rng_excl; + m = ((uint32_t)buffered_uint16(bitgen_state, bcnt, buf)) * rng_excl; /* Rejection sampling to remove any bias */ leftover = m & 0xFFFFUL; @@ -1471,7 +1513,7 @@ static NPY_INLINE uint16_t buffered_bounded_lemire_uint16(brng_t *brng_state, /* Same as: threshold=((uint32_t)(0x10000ULL - rng_excl)) % rng_excl; */ while (leftover < threshold) { - m = ((uint32_t)buffered_uint16(brng_state, bcnt, buf)) * rng_excl; + m = ((uint32_t)buffered_uint16(bitgen_state, bcnt, buf)) * rng_excl; leftover = m & 0xFFFFUL; } } @@ -1481,7 +1523,7 @@ static NPY_INLINE uint16_t buffered_bounded_lemire_uint16(brng_t *brng_state, /* Static `Lemire rejection` function called by * random_buffered_bounded_uint8(...) */ -static NPY_INLINE uint8_t buffered_bounded_lemire_uint8(brng_t *brng_state, +static NPY_INLINE uint8_t buffered_bounded_lemire_uint8(bitgen_t *bitgen_state, uint8_t rng, int *bcnt, uint32_t *buf) { /* @@ -1496,7 +1538,7 @@ static NPY_INLINE uint8_t buffered_bounded_lemire_uint8(brng_t *brng_state, uint8_t leftover; /* Generate a scaled random number. */ - m = ((uint16_t)buffered_uint8(brng_state, bcnt, buf)) * rng_excl; + m = ((uint16_t)buffered_uint8(bitgen_state, bcnt, buf)) * rng_excl; /* Rejection sampling to remove any bias */ leftover = m & 0xFFUL; @@ -1507,7 +1549,7 @@ static NPY_INLINE uint8_t buffered_bounded_lemire_uint8(brng_t *brng_state, /* Same as: threshold=((uint16_t)(0x100ULL - rng_excl)) % rng_excl; */ while (leftover < threshold) { - m = ((uint16_t)buffered_uint8(brng_state, bcnt, buf)) * rng_excl; + m = ((uint16_t)buffered_uint8(bitgen_state, bcnt, buf)) * rng_excl; leftover = m & 0xFFUL; } } @@ -1519,26 +1561,27 @@ static NPY_INLINE uint8_t buffered_bounded_lemire_uint8(brng_t *brng_state, * Returns a single random npy_uint64 between off and off + rng * inclusive. The numbers wrap if rng is sufficiently large. */ -uint64_t random_bounded_uint64(brng_t *brng_state, uint64_t off, uint64_t rng, - uint64_t mask, bool use_masked) { +uint64_t random_bounded_uint64(bitgen_t *bitgen_state, uint64_t off, + uint64_t rng, uint64_t mask, bool use_masked) { if (rng == 0) { return off; } else if (rng < 0xFFFFFFFFUL) { /* Call 32-bit generator if range in 32-bit. */ if (use_masked) { - return off + - buffered_bounded_masked_uint32(brng_state, rng, mask, NULL, NULL); + return off + buffered_bounded_masked_uint32(bitgen_state, rng, mask, NULL, + NULL); } else { - return off + buffered_bounded_lemire_uint32(brng_state, rng, NULL, NULL); + return off + + buffered_bounded_lemire_uint32(bitgen_state, rng, NULL, NULL); } } else if (rng == 0xFFFFFFFFFFFFFFFFULL) { /* Lemire64 doesn't support inclusive rng = 0xFFFFFFFFFFFFFFFF. */ - return off + next_uint64(brng_state); + return off + next_uint64(bitgen_state); } else { if (use_masked) { - return off + bounded_masked_uint64(brng_state, rng, mask); + return off + bounded_masked_uint64(bitgen_state, rng, mask); } else { - return off + bounded_lemire_uint64(brng_state, rng); + return off + bounded_lemire_uint64(bitgen_state, rng); } } } @@ -1547,7 +1590,7 @@ uint64_t random_bounded_uint64(brng_t *brng_state, uint64_t off, uint64_t rng, * Returns a single random npy_uint64 between off and off + rng * inclusive. The numbers wrap if rng is sufficiently large. */ -uint32_t random_buffered_bounded_uint32(brng_t *brng_state, uint32_t off, +uint32_t random_buffered_bounded_uint32(bitgen_t *bitgen_state, uint32_t off, uint32_t rng, uint32_t mask, bool use_masked, int *bcnt, uint32_t *buf) { @@ -1559,13 +1602,13 @@ uint32_t random_buffered_bounded_uint32(brng_t *brng_state, uint32_t off, return off; } else if (rng == 0xFFFFFFFFUL) { /* Lemire32 doesn't support inclusive rng = 0xFFFFFFFF. */ - return off + next_uint32(brng_state); + return off + next_uint32(bitgen_state); } else { if (use_masked) { return off + - buffered_bounded_masked_uint32(brng_state, rng, mask, bcnt, buf); + buffered_bounded_masked_uint32(bitgen_state, rng, mask, bcnt, buf); } else { - return off + buffered_bounded_lemire_uint32(brng_state, rng, bcnt, buf); + return off + buffered_bounded_lemire_uint32(bitgen_state, rng, bcnt, buf); } } } @@ -1574,7 +1617,7 @@ uint32_t random_buffered_bounded_uint32(brng_t *brng_state, uint32_t off, * Returns a single random npy_uint16 between off and off + rng * inclusive. The numbers wrap if rng is sufficiently large. */ -uint16_t random_buffered_bounded_uint16(brng_t *brng_state, uint16_t off, +uint16_t random_buffered_bounded_uint16(bitgen_t *bitgen_state, uint16_t off, uint16_t rng, uint16_t mask, bool use_masked, int *bcnt, uint32_t *buf) { @@ -1582,13 +1625,13 @@ uint16_t random_buffered_bounded_uint16(brng_t *brng_state, uint16_t off, return off; } else if (rng == 0xFFFFUL) { /* Lemire16 doesn't support inclusive rng = 0xFFFF. */ - return off + buffered_uint16(brng_state, bcnt, buf); + return off + buffered_uint16(bitgen_state, bcnt, buf); } else { if (use_masked) { return off + - buffered_bounded_masked_uint16(brng_state, rng, mask, bcnt, buf); + buffered_bounded_masked_uint16(bitgen_state, rng, mask, bcnt, buf); } else { - return off + buffered_bounded_lemire_uint16(brng_state, rng, bcnt, buf); + return off + buffered_bounded_lemire_uint16(bitgen_state, rng, bcnt, buf); } } } @@ -1597,7 +1640,7 @@ uint16_t random_buffered_bounded_uint16(brng_t *brng_state, uint16_t off, * Returns a single random npy_uint8 between off and off + rng * inclusive. The numbers wrap if rng is sufficiently large. */ -uint8_t random_buffered_bounded_uint8(brng_t *brng_state, uint8_t off, +uint8_t random_buffered_bounded_uint8(bitgen_t *bitgen_state, uint8_t off, uint8_t rng, uint8_t mask, bool use_masked, int *bcnt, uint32_t *buf) { @@ -1605,46 +1648,31 @@ uint8_t random_buffered_bounded_uint8(brng_t *brng_state, uint8_t off, return off; } else if (rng == 0xFFUL) { /* Lemire8 doesn't support inclusive rng = 0xFF. */ - return off + buffered_uint8(brng_state, bcnt, buf); + return off + buffered_uint8(bitgen_state, bcnt, buf); } else { if (use_masked) { return off + - buffered_bounded_masked_uint8(brng_state, rng, mask, bcnt, buf); + buffered_bounded_masked_uint8(bitgen_state, rng, mask, bcnt, buf); } else { - return off + buffered_bounded_lemire_uint8(brng_state, rng, bcnt, buf); + return off + buffered_bounded_lemire_uint8(bitgen_state, rng, bcnt, buf); } } } -static NPY_INLINE npy_bool buffered_bounded_bool(brng_t *brng_state, - npy_bool off, npy_bool rng, - npy_bool mask, int *bcnt, - uint32_t *buf) { - if (rng == 0) - return off; - if (!(bcnt[0])) { - buf[0] = next_uint32(brng_state); - bcnt[0] = 31; - } else { - buf[0] >>= 1; - bcnt[0] -= 1; - } - return (buf[0] & 0x00000001UL) != 0; -} - -npy_bool random_buffered_bounded_bool(brng_t *brng_state, npy_bool off, +npy_bool random_buffered_bounded_bool(bitgen_t *bitgen_state, npy_bool off, npy_bool rng, npy_bool mask, bool use_masked, int *bcnt, uint32_t *buf) { - return buffered_bounded_bool(brng_state, off, rng, mask, bcnt, buf); + return buffered_bounded_bool(bitgen_state, off, rng, mask, bcnt, buf); } /* * Fills an array with cnt random npy_uint64 between off and off + rng * inclusive. The numbers wrap if rng is sufficiently large. */ -void random_bounded_uint64_fill(brng_t *brng_state, uint64_t off, uint64_t rng, - npy_intp cnt, bool use_masked, uint64_t *out) { +void random_bounded_uint64_fill(bitgen_t *bitgen_state, uint64_t off, + uint64_t rng, npy_intp cnt, bool use_masked, + uint64_t *out) { npy_intp i; if (rng == 0) { @@ -1661,19 +1689,19 @@ void random_bounded_uint64_fill(brng_t *brng_state, uint64_t off, uint64_t rng, uint64_t mask = gen_mask(rng); for (i = 0; i < cnt; i++) { - out[i] = off + buffered_bounded_masked_uint32(brng_state, rng, mask, + out[i] = off + buffered_bounded_masked_uint32(bitgen_state, rng, mask, &bcnt, &buf); } } else { for (i = 0; i < cnt; i++) { - out[i] = - off + buffered_bounded_lemire_uint32(brng_state, rng, &bcnt, &buf); + out[i] = off + + buffered_bounded_lemire_uint32(bitgen_state, rng, &bcnt, &buf); } } } else if (rng == 0xFFFFFFFFFFFFFFFFULL) { /* Lemire64 doesn't support rng = 0xFFFFFFFFFFFFFFFF. */ for (i = 0; i < cnt; i++) { - out[i] = off + next_uint64(brng_state); + out[i] = off + next_uint64(bitgen_state); } } else { if (use_masked) { @@ -1681,11 +1709,11 @@ void random_bounded_uint64_fill(brng_t *brng_state, uint64_t off, uint64_t rng, uint64_t mask = gen_mask(rng); for (i = 0; i < cnt; i++) { - out[i] = off + bounded_masked_uint64(brng_state, rng, mask); + out[i] = off + bounded_masked_uint64(bitgen_state, rng, mask); } } else { for (i = 0; i < cnt; i++) { - out[i] = off + bounded_lemire_uint64(brng_state, rng); + out[i] = off + bounded_lemire_uint64(bitgen_state, rng); } } } @@ -1695,8 +1723,9 @@ void random_bounded_uint64_fill(brng_t *brng_state, uint64_t off, uint64_t rng, * Fills an array with cnt random npy_uint32 between off and off + rng * inclusive. The numbers wrap if rng is sufficiently large. */ -void random_bounded_uint32_fill(brng_t *brng_state, uint32_t off, uint32_t rng, - npy_intp cnt, bool use_masked, uint32_t *out) { +void random_bounded_uint32_fill(bitgen_t *bitgen_state, uint32_t off, + uint32_t rng, npy_intp cnt, bool use_masked, + uint32_t *out) { npy_intp i; uint32_t buf = 0; int bcnt = 0; @@ -1708,7 +1737,7 @@ void random_bounded_uint32_fill(brng_t *brng_state, uint32_t off, uint32_t rng, } else if (rng == 0xFFFFFFFFUL) { /* Lemire32 doesn't support rng = 0xFFFFFFFF. */ for (i = 0; i < cnt; i++) { - out[i] = off + next_uint32(brng_state); + out[i] = off + next_uint32(bitgen_state); } } else { if (use_masked) { @@ -1716,13 +1745,13 @@ void random_bounded_uint32_fill(brng_t *brng_state, uint32_t off, uint32_t rng, uint32_t mask = (uint32_t)gen_mask(rng); for (i = 0; i < cnt; i++) { - out[i] = off + buffered_bounded_masked_uint32(brng_state, rng, mask, + out[i] = off + buffered_bounded_masked_uint32(bitgen_state, rng, mask, &bcnt, &buf); } } else { for (i = 0; i < cnt; i++) { - out[i] = - off + buffered_bounded_lemire_uint32(brng_state, rng, &bcnt, &buf); + out[i] = off + + buffered_bounded_lemire_uint32(bitgen_state, rng, &bcnt, &buf); } } } @@ -1732,8 +1761,9 @@ void random_bounded_uint32_fill(brng_t *brng_state, uint32_t off, uint32_t rng, * Fills an array with cnt random npy_uint16 between off and off + rng * inclusive. The numbers wrap if rng is sufficiently large. */ -void random_bounded_uint16_fill(brng_t *brng_state, uint16_t off, uint16_t rng, - npy_intp cnt, bool use_masked, uint16_t *out) { +void random_bounded_uint16_fill(bitgen_t *bitgen_state, uint16_t off, + uint16_t rng, npy_intp cnt, bool use_masked, + uint16_t *out) { npy_intp i; uint32_t buf = 0; int bcnt = 0; @@ -1745,7 +1775,7 @@ void random_bounded_uint16_fill(brng_t *brng_state, uint16_t off, uint16_t rng, } else if (rng == 0xFFFFUL) { /* Lemire16 doesn't support rng = 0xFFFF. */ for (i = 0; i < cnt; i++) { - out[i] = off + buffered_uint16(brng_state, &bcnt, &buf); + out[i] = off + buffered_uint16(bitgen_state, &bcnt, &buf); } } else { if (use_masked) { @@ -1753,13 +1783,13 @@ void random_bounded_uint16_fill(brng_t *brng_state, uint16_t off, uint16_t rng, uint16_t mask = (uint16_t)gen_mask(rng); for (i = 0; i < cnt; i++) { - out[i] = off + buffered_bounded_masked_uint16(brng_state, rng, mask, + out[i] = off + buffered_bounded_masked_uint16(bitgen_state, rng, mask, &bcnt, &buf); } } else { for (i = 0; i < cnt; i++) { - out[i] = - off + buffered_bounded_lemire_uint16(brng_state, rng, &bcnt, &buf); + out[i] = off + + buffered_bounded_lemire_uint16(bitgen_state, rng, &bcnt, &buf); } } } @@ -1769,7 +1799,7 @@ void random_bounded_uint16_fill(brng_t *brng_state, uint16_t off, uint16_t rng, * Fills an array with cnt random npy_uint8 between off and off + rng * inclusive. The numbers wrap if rng is sufficiently large. */ -void random_bounded_uint8_fill(brng_t *brng_state, uint8_t off, uint8_t rng, +void random_bounded_uint8_fill(bitgen_t *bitgen_state, uint8_t off, uint8_t rng, npy_intp cnt, bool use_masked, uint8_t *out) { npy_intp i; uint32_t buf = 0; @@ -1782,7 +1812,7 @@ void random_bounded_uint8_fill(brng_t *brng_state, uint8_t off, uint8_t rng, } else if (rng == 0xFFUL) { /* Lemire8 doesn't support rng = 0xFF. */ for (i = 0; i < cnt; i++) { - out[i] = off + buffered_uint8(brng_state, &bcnt, &buf); + out[i] = off + buffered_uint8(bitgen_state, &bcnt, &buf); } } else { if (use_masked) { @@ -1790,13 +1820,13 @@ void random_bounded_uint8_fill(brng_t *brng_state, uint8_t off, uint8_t rng, uint8_t mask = (uint8_t)gen_mask(rng); for (i = 0; i < cnt; i++) { - out[i] = off + buffered_bounded_masked_uint8(brng_state, rng, mask, + out[i] = off + buffered_bounded_masked_uint8(bitgen_state, rng, mask, &bcnt, &buf); } } else { for (i = 0; i < cnt; i++) { out[i] = - off + buffered_bounded_lemire_uint8(brng_state, rng, &bcnt, &buf); + off + buffered_bounded_lemire_uint8(bitgen_state, rng, &bcnt, &buf); } } } @@ -1806,25 +1836,26 @@ void random_bounded_uint8_fill(brng_t *brng_state, uint8_t off, uint8_t rng, * Fills an array with cnt random npy_bool between off and off + rng * inclusive. */ -void random_bounded_bool_fill(brng_t *brng_state, npy_bool off, npy_bool rng, - npy_intp cnt, bool use_masked, npy_bool *out) { +void random_bounded_bool_fill(bitgen_t *bitgen_state, npy_bool off, + npy_bool rng, npy_intp cnt, bool use_masked, + npy_bool *out) { npy_bool mask = 0; npy_intp i; uint32_t buf = 0; int bcnt = 0; for (i = 0; i < cnt; i++) { - out[i] = buffered_bounded_bool(brng_state, off, rng, mask, &bcnt, &buf); + out[i] = buffered_bounded_bool(bitgen_state, off, rng, mask, &bcnt, &buf); } } -void random_multinomial(brng_t *brng_state, int64_t n, int64_t *mnix, +void random_multinomial(bitgen_t *bitgen_state, int64_t n, int64_t *mnix, double *pix, npy_intp d, binomial_t *binomial) { double remaining_p = 1.0; npy_intp j; int64_t dn = n; for (j = 0; j < (d - 1); j++) { - mnix[j] = random_binomial(brng_state, pix[j] / remaining_p, dn, binomial); + mnix[j] = random_binomial(bitgen_state, pix[j] / remaining_p, dn, binomial); dn = dn - mnix[j]; if (dn <= 0) { break; diff --git a/numpy/random/src/distributions/distributions.h b/numpy/random/src/distributions/distributions.h index 8ec4a83e8..d1d439d78 100644 --- a/numpy/random/src/distributions/distributions.h +++ b/numpy/random/src/distributions/distributions.h @@ -3,20 +3,8 @@ #pragma once #include <stddef.h> -#ifdef _WIN32 -#if _MSC_VER == 1500 -#include "../common/stdint.h" -typedef int bool; -#define false 0 -#define true 1 -#else -#include <stdbool.h> -#include <stdint.h> -#endif -#else #include <stdbool.h> #include <stdint.h> -#endif #include "Python.h" #include "numpy/npy_common.h" @@ -72,152 +60,152 @@ typedef struct s_binomial_t { double p4; } binomial_t; -typedef struct brng { +typedef struct bitgen { void *state; uint64_t (*next_uint64)(void *st); uint32_t (*next_uint32)(void *st); double (*next_double)(void *st); uint64_t (*next_raw)(void *st); -} brng_t; +} bitgen_t; /* Inline generators for internal use */ -static NPY_INLINE uint32_t next_uint32(brng_t *brng_state) { - return brng_state->next_uint32(brng_state->state); +static NPY_INLINE uint32_t next_uint32(bitgen_t *bitgen_state) { + return bitgen_state->next_uint32(bitgen_state->state); } -static NPY_INLINE uint64_t next_uint64(brng_t *brng_state) { - return brng_state->next_uint64(brng_state->state); +static NPY_INLINE uint64_t next_uint64(bitgen_t *bitgen_state) { + return bitgen_state->next_uint64(bitgen_state->state); } -static NPY_INLINE float next_float(brng_t *brng_state) { - return (next_uint32(brng_state) >> 9) * (1.0f / 8388608.0f); +static NPY_INLINE float next_float(bitgen_t *bitgen_state) { + return (next_uint32(bitgen_state) >> 9) * (1.0f / 8388608.0f); } -static NPY_INLINE double next_double(brng_t *brng_state) { - return brng_state->next_double(brng_state->state); +static NPY_INLINE double next_double(bitgen_t *bitgen_state) { + return bitgen_state->next_double(bitgen_state->state); } -DECLDIR float random_float(brng_t *brng_state); -DECLDIR double random_double(brng_t *brng_state); -DECLDIR void random_double_fill(brng_t *brng_state, npy_intp cnt, double *out); +DECLDIR float random_float(bitgen_t *bitgen_state); +DECLDIR double random_double(bitgen_t *bitgen_state); +DECLDIR void random_double_fill(bitgen_t *bitgen_state, npy_intp cnt, double *out); -DECLDIR int64_t random_positive_int64(brng_t *brng_state); -DECLDIR int32_t random_positive_int32(brng_t *brng_state); -DECLDIR int64_t random_positive_int(brng_t *brng_state); -DECLDIR uint64_t random_uint(brng_t *brng_state); +DECLDIR int64_t random_positive_int64(bitgen_t *bitgen_state); +DECLDIR int32_t random_positive_int32(bitgen_t *bitgen_state); +DECLDIR int64_t random_positive_int(bitgen_t *bitgen_state); +DECLDIR uint64_t random_uint(bitgen_t *bitgen_state); -DECLDIR double random_standard_exponential(brng_t *brng_state); -DECLDIR void random_standard_exponential_fill(brng_t *brng_state, npy_intp cnt, +DECLDIR double random_standard_exponential(bitgen_t *bitgen_state); +DECLDIR void random_standard_exponential_fill(bitgen_t *bitgen_state, npy_intp cnt, double *out); -DECLDIR float random_standard_exponential_f(brng_t *brng_state); -DECLDIR double random_standard_exponential_zig(brng_t *brng_state); -DECLDIR void random_standard_exponential_zig_fill(brng_t *brng_state, +DECLDIR float random_standard_exponential_f(bitgen_t *bitgen_state); +DECLDIR double random_standard_exponential_zig(bitgen_t *bitgen_state); +DECLDIR void random_standard_exponential_zig_fill(bitgen_t *bitgen_state, npy_intp cnt, double *out); -DECLDIR float random_standard_exponential_zig_f(brng_t *brng_state); +DECLDIR float random_standard_exponential_zig_f(bitgen_t *bitgen_state); /* -DECLDIR double random_gauss(brng_t *brng_state); -DECLDIR float random_gauss_f(brng_t *brng_state); +DECLDIR double random_gauss(bitgen_t *bitgen_state); +DECLDIR float random_gauss_f(bitgen_t *bitgen_state); */ -DECLDIR double random_gauss_zig(brng_t *brng_state); -DECLDIR float random_gauss_zig_f(brng_t *brng_state); -DECLDIR void random_gauss_zig_fill(brng_t *brng_state, npy_intp cnt, +DECLDIR double random_gauss_zig(bitgen_t *bitgen_state); +DECLDIR float random_gauss_zig_f(bitgen_t *bitgen_state); +DECLDIR void random_gauss_zig_fill(bitgen_t *bitgen_state, npy_intp cnt, double *out); /* -DECLDIR double random_standard_gamma(brng_t *brng_state, double shape); -DECLDIR float random_standard_gamma_f(brng_t *brng_state, float shape); +DECLDIR double random_standard_gamma(bitgen_t *bitgen_state, double shape); +DECLDIR float random_standard_gamma_f(bitgen_t *bitgen_state, float shape); */ -DECLDIR double random_standard_gamma_zig(brng_t *brng_state, double shape); -DECLDIR float random_standard_gamma_zig_f(brng_t *brng_state, float shape); +DECLDIR double random_standard_gamma_zig(bitgen_t *bitgen_state, double shape); +DECLDIR float random_standard_gamma_zig_f(bitgen_t *bitgen_state, float shape); /* -DECLDIR double random_normal(brng_t *brng_state, double loc, double scale); +DECLDIR double random_normal(bitgen_t *bitgen_state, double loc, double scale); */ -DECLDIR double random_normal_zig(brng_t *brng_state, double loc, double scale); - -DECLDIR double random_gamma(brng_t *brng_state, double shape, double scale); -DECLDIR float random_gamma_float(brng_t *brng_state, float shape, float scale); - -DECLDIR double random_exponential(brng_t *brng_state, double scale); -DECLDIR double random_uniform(brng_t *brng_state, double lower, double range); -DECLDIR double random_beta(brng_t *brng_state, double a, double b); -DECLDIR double random_chisquare(brng_t *brng_state, double df); -DECLDIR double random_f(brng_t *brng_state, double dfnum, double dfden); -DECLDIR double random_standard_cauchy(brng_t *brng_state); -DECLDIR double random_pareto(brng_t *brng_state, double a); -DECLDIR double random_weibull(brng_t *brng_state, double a); -DECLDIR double random_power(brng_t *brng_state, double a); -DECLDIR double random_laplace(brng_t *brng_state, double loc, double scale); -DECLDIR double random_gumbel(brng_t *brng_state, double loc, double scale); -DECLDIR double random_logistic(brng_t *brng_state, double loc, double scale); -DECLDIR double random_lognormal(brng_t *brng_state, double mean, double sigma); -DECLDIR double random_rayleigh(brng_t *brng_state, double mode); -DECLDIR double random_standard_t(brng_t *brng_state, double df); -DECLDIR double random_noncentral_chisquare(brng_t *brng_state, double df, +DECLDIR double random_normal_zig(bitgen_t *bitgen_state, double loc, double scale); + +DECLDIR double random_gamma(bitgen_t *bitgen_state, double shape, double scale); +DECLDIR float random_gamma_float(bitgen_t *bitgen_state, float shape, float scale); + +DECLDIR double random_exponential(bitgen_t *bitgen_state, double scale); +DECLDIR double random_uniform(bitgen_t *bitgen_state, double lower, double range); +DECLDIR double random_beta(bitgen_t *bitgen_state, double a, double b); +DECLDIR double random_chisquare(bitgen_t *bitgen_state, double df); +DECLDIR double random_f(bitgen_t *bitgen_state, double dfnum, double dfden); +DECLDIR double random_standard_cauchy(bitgen_t *bitgen_state); +DECLDIR double random_pareto(bitgen_t *bitgen_state, double a); +DECLDIR double random_weibull(bitgen_t *bitgen_state, double a); +DECLDIR double random_power(bitgen_t *bitgen_state, double a); +DECLDIR double random_laplace(bitgen_t *bitgen_state, double loc, double scale); +DECLDIR double random_gumbel(bitgen_t *bitgen_state, double loc, double scale); +DECLDIR double random_logistic(bitgen_t *bitgen_state, double loc, double scale); +DECLDIR double random_lognormal(bitgen_t *bitgen_state, double mean, double sigma); +DECLDIR double random_rayleigh(bitgen_t *bitgen_state, double mode); +DECLDIR double random_standard_t(bitgen_t *bitgen_state, double df); +DECLDIR double random_noncentral_chisquare(bitgen_t *bitgen_state, double df, double nonc); -DECLDIR double random_noncentral_f(brng_t *brng_state, double dfnum, +DECLDIR double random_noncentral_f(bitgen_t *bitgen_state, double dfnum, double dfden, double nonc); -DECLDIR double random_wald(brng_t *brng_state, double mean, double scale); -DECLDIR double random_vonmises(brng_t *brng_state, double mu, double kappa); -DECLDIR double random_triangular(brng_t *brng_state, double left, double mode, +DECLDIR double random_wald(bitgen_t *bitgen_state, double mean, double scale); +DECLDIR double random_vonmises(bitgen_t *bitgen_state, double mu, double kappa); +DECLDIR double random_triangular(bitgen_t *bitgen_state, double left, double mode, double right); -DECLDIR int64_t random_poisson(brng_t *brng_state, double lam); -DECLDIR int64_t random_negative_binomial(brng_t *brng_state, double n, +DECLDIR int64_t random_poisson(bitgen_t *bitgen_state, double lam); +DECLDIR int64_t random_negative_binomial(bitgen_t *bitgen_state, double n, double p); -DECLDIR int64_t random_binomial(brng_t *brng_state, double p, int64_t n, +DECLDIR int64_t random_binomial(bitgen_t *bitgen_state, double p, int64_t n, binomial_t *binomial); -DECLDIR int64_t random_logseries(brng_t *brng_state, double p); -DECLDIR int64_t random_geometric_search(brng_t *brng_state, double p); -DECLDIR int64_t random_geometric_inversion(brng_t *brng_state, double p); -DECLDIR int64_t random_geometric(brng_t *brng_state, double p); -DECLDIR int64_t random_zipf(brng_t *brng_state, double a); -DECLDIR int64_t random_hypergeometric(brng_t *brng_state, int64_t good, +DECLDIR int64_t random_logseries(bitgen_t *bitgen_state, double p); +DECLDIR int64_t random_geometric_search(bitgen_t *bitgen_state, double p); +DECLDIR int64_t random_geometric_inversion(bitgen_t *bitgen_state, double p); +DECLDIR int64_t random_geometric(bitgen_t *bitgen_state, double p); +DECLDIR int64_t random_zipf(bitgen_t *bitgen_state, double a); +DECLDIR int64_t random_hypergeometric(bitgen_t *bitgen_state, int64_t good, int64_t bad, int64_t sample); -DECLDIR uint64_t random_interval(brng_t *brng_state, uint64_t max); +DECLDIR uint64_t random_interval(bitgen_t *bitgen_state, uint64_t max); /* Generate random uint64 numbers in closed interval [off, off + rng]. */ -DECLDIR uint64_t random_bounded_uint64(brng_t *brng_state, uint64_t off, +DECLDIR uint64_t random_bounded_uint64(bitgen_t *bitgen_state, uint64_t off, uint64_t rng, uint64_t mask, bool use_masked); /* Generate random uint32 numbers in closed interval [off, off + rng]. */ -DECLDIR uint32_t random_buffered_bounded_uint32(brng_t *brng_state, +DECLDIR uint32_t random_buffered_bounded_uint32(bitgen_t *bitgen_state, uint32_t off, uint32_t rng, uint32_t mask, bool use_masked, int *bcnt, uint32_t *buf); -DECLDIR uint16_t random_buffered_bounded_uint16(brng_t *brng_state, +DECLDIR uint16_t random_buffered_bounded_uint16(bitgen_t *bitgen_state, uint16_t off, uint16_t rng, uint16_t mask, bool use_masked, int *bcnt, uint32_t *buf); -DECLDIR uint8_t random_buffered_bounded_uint8(brng_t *brng_state, uint8_t off, +DECLDIR uint8_t random_buffered_bounded_uint8(bitgen_t *bitgen_state, uint8_t off, uint8_t rng, uint8_t mask, bool use_masked, int *bcnt, uint32_t *buf); -DECLDIR npy_bool random_buffered_bounded_bool(brng_t *brng_state, npy_bool off, +DECLDIR npy_bool random_buffered_bounded_bool(bitgen_t *bitgen_state, npy_bool off, npy_bool rng, npy_bool mask, bool use_masked, int *bcnt, uint32_t *buf); -DECLDIR void random_bounded_uint64_fill(brng_t *brng_state, uint64_t off, +DECLDIR void random_bounded_uint64_fill(bitgen_t *bitgen_state, uint64_t off, uint64_t rng, npy_intp cnt, bool use_masked, uint64_t *out); -DECLDIR void random_bounded_uint32_fill(brng_t *brng_state, uint32_t off, +DECLDIR void random_bounded_uint32_fill(bitgen_t *bitgen_state, uint32_t off, uint32_t rng, npy_intp cnt, bool use_masked, uint32_t *out); -DECLDIR void random_bounded_uint16_fill(brng_t *brng_state, uint16_t off, +DECLDIR void random_bounded_uint16_fill(bitgen_t *bitgen_state, uint16_t off, uint16_t rng, npy_intp cnt, bool use_masked, uint16_t *out); -DECLDIR void random_bounded_uint8_fill(brng_t *brng_state, uint8_t off, +DECLDIR void random_bounded_uint8_fill(bitgen_t *bitgen_state, uint8_t off, uint8_t rng, npy_intp cnt, bool use_masked, uint8_t *out); -DECLDIR void random_bounded_bool_fill(brng_t *brng_state, npy_bool off, +DECLDIR void random_bounded_bool_fill(bitgen_t *bitgen_state, npy_bool off, npy_bool rng, npy_intp cnt, bool use_masked, npy_bool *out); -DECLDIR void random_multinomial(brng_t *brng_state, int64_t n, int64_t *mnix, +DECLDIR void random_multinomial(bitgen_t *bitgen_state, int64_t n, int64_t *mnix, double *pix, npy_intp d, binomial_t *binomial); #endif diff --git a/numpy/random/src/entropy/LICENSE.md b/numpy/random/src/entropy/LICENSE.md deleted file mode 100644 index b7276aad7..000000000 --- a/numpy/random/src/entropy/LICENSE.md +++ /dev/null @@ -1,25 +0,0 @@ -# ENTROPY - -_Parts of this module were derived from PCG_ - - -PCG Random Number Generation for C. - -Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -For additional information about the PCG random number generation scheme, -including its license and other licensing options, visit - - http://www.pcg-random.org diff --git a/numpy/random/src/entropy/entropy.c b/numpy/random/src/entropy/entropy.c index ead4bef83..eaca37a9c 100644 --- a/numpy/random/src/entropy/entropy.c +++ b/numpy/random/src/entropy/entropy.c @@ -1,34 +1,3 @@ -/* - * PCG Random Number Generation for C. - * - * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * For additional information about the PCG random number generation scheme, - * including its license and other licensing options, visit - * - * http://www.pcg-random.org - */ - -/* This code provides a mechanism for getting external randomness for - * seeding purposes. Usually, it's just a wrapper around reading - * /dev/random. - * - * Alas, because not every system provides /dev/random, we need a fallback. - * We also need to try to test whether or not to use the fallback. - */ - #include <stddef.h> #include <stdio.h> #include <stdlib.h> @@ -47,38 +16,12 @@ #include <sys/time.h> #include <time.h> #include <unistd.h> -#endif - -#ifndef IS_UNIX -#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || \ - (defined(__APPLE__) && defined(__MACH__))) -#define IS_UNIX 1 -#else -#define IS_UNIX 0 -#endif -#endif - -// If HAVE_DEV_RANDOM is set, we use that value, otherwise we guess -#ifndef HAVE_DEV_RANDOM -#define HAVE_DEV_RANDOM IS_UNIX -#endif - -#if HAVE_DEV_RANDOM #include <fcntl.h> -#include <unistd.h> #endif -#if HAVE_DEV_RANDOM -/* entropy_getbytes(dest, size): - * Use /dev/random to get some external entropy for seeding purposes. - * - * Note: - * If reading /dev/random fails (which ought to never happen), it returns - * false, otherwise it returns true. If it fails, you could instead call - * fallback_entropy_getbytes which always succeeds. - */ - bool entropy_getbytes(void *dest, size_t size) { +#ifndef _WIN32 + int fd = open("/dev/urandom", O_RDONLY); if (fd < 0) return false; @@ -86,11 +29,9 @@ bool entropy_getbytes(void *dest, size_t size) { if ((sz < 0) || ((size_t)sz < size)) return false; return close(fd) == 0; -} -#endif -#ifdef _WIN32 -bool entropy_getbytes(void *dest, size_t size) { +#else + HCRYPTPROV hCryptProv; BOOL done; @@ -106,8 +47,8 @@ bool entropy_getbytes(void *dest, size_t size) { } return true; -} #endif +} /* Thomas Wang 32/64 bits integer hash function */ uint32_t entropy_hash_32(uint32_t key) { @@ -155,7 +96,6 @@ uint32_t entropy_randombytes(void) { bool entropy_fallback_getbytes(void *dest, size_t size) { int hashes = (int)size; uint32_t *hash = malloc(hashes * sizeof(uint32_t)); - // uint32_t hash[hashes]; int i; for (i = 0; i < hashes; i++) { hash[i] = entropy_randombytes(); diff --git a/numpy/random/src/entropy/entropy.h b/numpy/random/src/entropy/entropy.h index 785603dd3..f00caf61d 100644 --- a/numpy/random/src/entropy/entropy.h +++ b/numpy/random/src/entropy/entropy.h @@ -1,43 +1,9 @@ #ifndef _RANDOMDGEN__ENTROPY_H_ #define _RANDOMDGEN__ENTROPY_H_ -/* - * PCG Random Number Generation for C. - * - * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * For additional information about the PCG random number generation scheme, - * including its license and other licensing options, visit - * - * http://www.pcg-random.org - */ #include <stddef.h> -#ifdef _WIN32 -#if _MSC_VER == 1500 -#include "../common/stdint.h" -typedef int bool; -#define false 0 -#define true 1 -#else #include <stdbool.h> #include <stdint.h> -#endif -#else -#include <stdbool.h> -#include <stdint.h> -#endif extern void entropy_fill(void *dest, size_t size); diff --git a/numpy/random/src/legacy/LICENSE.md b/numpy/random/src/legacy/LICENSE.md deleted file mode 100644 index 88b1791b2..000000000 --- a/numpy/random/src/legacy/LICENSE.md +++ /dev/null @@ -1,30 +0,0 @@ -Copyright (c) 2005-2017, NumPy Developers. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - -* Neither the name of the NumPy Developers nor the names of any - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/numpy/random/src/legacy/distributions-boxmuller.c b/numpy/random/src/legacy/distributions-boxmuller.c index 5d3ba27f8..2c715799f 100644 --- a/numpy/random/src/legacy/distributions-boxmuller.c +++ b/numpy/random/src/legacy/distributions-boxmuller.c @@ -1,10 +1,10 @@ #include "distributions-boxmuller.h" -static NPY_INLINE double legacy_double(aug_brng_t *aug_state) { - return aug_state->basicrng->next_double(aug_state->basicrng->state); +static NPY_INLINE double legacy_double(aug_bitgen_t *aug_state) { + return aug_state->bit_generator->next_double(aug_state->bit_generator->state); } -double legacy_gauss(aug_brng_t *aug_state) { +double legacy_gauss(aug_bitgen_t *aug_state) { if (aug_state->has_gauss) { const double temp = aug_state->gauss; aug_state->has_gauss = false; @@ -28,12 +28,12 @@ double legacy_gauss(aug_brng_t *aug_state) { } } -double legacy_standard_exponential(aug_brng_t *aug_state) { +double legacy_standard_exponential(aug_bitgen_t *aug_state) { /* We use -log(1-U) since U is [0, 1) */ return -log(1.0 - legacy_double(aug_state)); } -double legacy_standard_gamma(aug_brng_t *aug_state, double shape) { +double legacy_standard_gamma(aug_bitgen_t *aug_state, double shape) { double b, c; double U, V, X, Y; @@ -78,30 +78,30 @@ double legacy_standard_gamma(aug_brng_t *aug_state, double shape) { } } -double legacy_gamma(aug_brng_t *aug_state, double shape, double scale) { +double legacy_gamma(aug_bitgen_t *aug_state, double shape, double scale) { return scale * legacy_standard_gamma(aug_state, shape); } -double legacy_pareto(aug_brng_t *aug_state, double a) { +double legacy_pareto(aug_bitgen_t *aug_state, double a) { return exp(legacy_standard_exponential(aug_state) / a) - 1; } -double legacy_weibull(aug_brng_t *aug_state, double a) { +double legacy_weibull(aug_bitgen_t *aug_state, double a) { if (a == 0.0) { return 0.0; } return pow(legacy_standard_exponential(aug_state), 1. / a); } -double legacy_power(aug_brng_t *aug_state, double a) { +double legacy_power(aug_bitgen_t *aug_state, double a) { return pow(1 - exp(-legacy_standard_exponential(aug_state)), 1. / a); } -double legacy_chisquare(aug_brng_t *aug_state, double df) { +double legacy_chisquare(aug_bitgen_t *aug_state, double df) { return 2.0 * legacy_standard_gamma(aug_state, df / 2.0); } -double legacy_noncentral_chisquare(aug_brng_t *aug_state, double df, +double legacy_noncentral_chisquare(aug_bitgen_t *aug_state, double df, double nonc) { double out; if (nonc == 0) { @@ -112,7 +112,7 @@ double legacy_noncentral_chisquare(aug_brng_t *aug_state, double df, const double n = legacy_gauss(aug_state) + sqrt(nonc); return Chi2 + n * n; } else { - const long i = random_poisson(aug_state->basicrng, nonc / 2.0); + const long i = random_poisson(aug_state->bit_generator, nonc / 2.0); out = legacy_chisquare(aug_state, df + 2 * i); /* Insert nan guard here to avoid changing the stream */ if (npy_isnan(nonc)){ @@ -123,13 +123,13 @@ double legacy_noncentral_chisquare(aug_brng_t *aug_state, double df, } } -double legacy_noncentral_f(aug_brng_t *aug_state, double dfnum, double dfden, +double legacy_noncentral_f(aug_bitgen_t *aug_state, double dfnum, double dfden, double nonc) { double t = legacy_noncentral_chisquare(aug_state, dfnum, nonc) * dfden; return t / (legacy_chisquare(aug_state, dfden) * dfnum); } -double legacy_wald(aug_brng_t *aug_state, double mean, double scale) { +double legacy_wald(aug_bitgen_t *aug_state, double mean, double scale) { double U, X, Y; double mu_2l; @@ -145,15 +145,15 @@ double legacy_wald(aug_brng_t *aug_state, double mean, double scale) { } } -double legacy_normal(aug_brng_t *aug_state, double loc, double scale) { +double legacy_normal(aug_bitgen_t *aug_state, double loc, double scale) { return loc + scale * legacy_gauss(aug_state); } -double legacy_lognormal(aug_brng_t *aug_state, double mean, double sigma) { +double legacy_lognormal(aug_bitgen_t *aug_state, double mean, double sigma) { return exp(legacy_normal(aug_state, mean, sigma)); } -double legacy_standard_t(aug_brng_t *aug_state, double df) { +double legacy_standard_t(aug_bitgen_t *aug_state, double df) { double num, denom; num = legacy_gauss(aug_state); @@ -161,16 +161,16 @@ double legacy_standard_t(aug_brng_t *aug_state, double df) { return sqrt(df / 2) * num / sqrt(denom); } -int64_t legacy_negative_binomial(aug_brng_t *aug_state, double n, double p) { +int64_t legacy_negative_binomial(aug_bitgen_t *aug_state, double n, double p) { double Y = legacy_gamma(aug_state, n, (1 - p) / p); - return random_poisson(aug_state->basicrng, Y); + return random_poisson(aug_state->bit_generator, Y); } -double legacy_standard_cauchy(aug_brng_t *aug_state) { +double legacy_standard_cauchy(aug_bitgen_t *aug_state) { return legacy_gauss(aug_state) / legacy_gauss(aug_state); } -double legacy_beta(aug_brng_t *aug_state, double a, double b) { +double legacy_beta(aug_bitgen_t *aug_state, double a, double b) { double Ga, Gb; if ((a <= 1.0) && (b <= 1.0)) { @@ -204,11 +204,11 @@ double legacy_beta(aug_brng_t *aug_state, double a, double b) { } } -double legacy_f(aug_brng_t *aug_state, double dfnum, double dfden) { +double legacy_f(aug_bitgen_t *aug_state, double dfnum, double dfden) { return ((legacy_chisquare(aug_state, dfnum) * dfden) / (legacy_chisquare(aug_state, dfden) * dfnum)); } -double legacy_exponential(aug_brng_t *aug_state, double scale) { +double legacy_exponential(aug_bitgen_t *aug_state, double scale) { return scale * legacy_standard_exponential(aug_state); } diff --git a/numpy/random/src/legacy/distributions-boxmuller.h b/numpy/random/src/legacy/distributions-boxmuller.h index 445686e6c..07e093b26 100644 --- a/numpy/random/src/legacy/distributions-boxmuller.h +++ b/numpy/random/src/legacy/distributions-boxmuller.h @@ -4,37 +4,37 @@ #include "../distributions/distributions.h" -typedef struct aug_brng { - brng_t *basicrng; +typedef struct aug_bitgen { + bitgen_t *bit_generator; int has_gauss; double gauss; -} aug_brng_t; +} aug_bitgen_t; -extern double legacy_gauss(aug_brng_t *aug_state); -extern double legacy_standard_exponential(aug_brng_t *aug_state); -extern double legacy_pareto(aug_brng_t *aug_state, double a); -extern double legacy_weibull(aug_brng_t *aug_state, double a); -extern double legacy_power(aug_brng_t *aug_state, double a); -extern double legacy_gamma(aug_brng_t *aug_state, double shape, double scale); -extern double legacy_pareto(aug_brng_t *aug_state, double a); -extern double legacy_weibull(aug_brng_t *aug_state, double a); -extern double legacy_chisquare(aug_brng_t *aug_state, double df); -extern double legacy_noncentral_chisquare(aug_brng_t *aug_state, double df, +extern double legacy_gauss(aug_bitgen_t *aug_state); +extern double legacy_standard_exponential(aug_bitgen_t *aug_state); +extern double legacy_pareto(aug_bitgen_t *aug_state, double a); +extern double legacy_weibull(aug_bitgen_t *aug_state, double a); +extern double legacy_power(aug_bitgen_t *aug_state, double a); +extern double legacy_gamma(aug_bitgen_t *aug_state, double shape, double scale); +extern double legacy_pareto(aug_bitgen_t *aug_state, double a); +extern double legacy_weibull(aug_bitgen_t *aug_state, double a); +extern double legacy_chisquare(aug_bitgen_t *aug_state, double df); +extern double legacy_noncentral_chisquare(aug_bitgen_t *aug_state, double df, double nonc); -extern double legacy_noncentral_f(aug_brng_t *aug_state, double dfnum, +extern double legacy_noncentral_f(aug_bitgen_t *aug_state, double dfnum, double dfden, double nonc); -extern double legacy_wald(aug_brng_t *aug_state, double mean, double scale); -extern double legacy_lognormal(aug_brng_t *aug_state, double mean, +extern double legacy_wald(aug_bitgen_t *aug_state, double mean, double scale); +extern double legacy_lognormal(aug_bitgen_t *aug_state, double mean, double sigma); -extern double legacy_standard_t(aug_brng_t *aug_state, double df); -extern int64_t legacy_negative_binomial(aug_brng_t *aug_state, double n, +extern double legacy_standard_t(aug_bitgen_t *aug_state, double df); +extern int64_t legacy_negative_binomial(aug_bitgen_t *aug_state, double n, double p); -extern double legacy_standard_cauchy(aug_brng_t *state); -extern double legacy_beta(aug_brng_t *aug_state, double a, double b); -extern double legacy_f(aug_brng_t *aug_state, double dfnum, double dfden); -extern double legacy_normal(aug_brng_t *aug_state, double loc, double scale); -extern double legacy_standard_gamma(aug_brng_t *aug_state, double shape); -extern double legacy_exponential(aug_brng_t *aug_state, double scale); +extern double legacy_standard_cauchy(aug_bitgen_t *state); +extern double legacy_beta(aug_bitgen_t *aug_state, double a, double b); +extern double legacy_f(aug_bitgen_t *aug_state, double dfnum, double dfden); +extern double legacy_normal(aug_bitgen_t *aug_state, double loc, double scale); +extern double legacy_standard_gamma(aug_bitgen_t *aug_state, double shape); +extern double legacy_exponential(aug_bitgen_t *aug_state, double scale); #endif diff --git a/numpy/random/src/mt19937/mt19937.h b/numpy/random/src/mt19937/mt19937.h index 8105329ec..1b39e0b64 100644 --- a/numpy/random/src/mt19937/mt19937.h +++ b/numpy/random/src/mt19937/mt19937.h @@ -1,14 +1,6 @@ #pragma once #include <math.h> -#ifdef _WIN32 -#if _MSC_VER == 1500 -#include "../common/stdint.h" -#else -#include <stdint.h> -#endif -#else #include <stdint.h> -#endif #ifdef _WIN32 #define inline __forceinline diff --git a/numpy/random/src/pcg32/LICENSE.md b/numpy/random/src/pcg32/LICENSE.md deleted file mode 100644 index 3db2ac2e8..000000000 --- a/numpy/random/src/pcg32/LICENSE.md +++ /dev/null @@ -1,22 +0,0 @@ -# PCG32 - -PCG Random Number Generation for C. - -Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -For additional information about the PCG random number generation scheme, -including its license and other licensing options, visit - - http://www.pcg-random.org diff --git a/numpy/random/src/pcg32/pcg-advance-64.c b/numpy/random/src/pcg32/pcg-advance-64.c deleted file mode 100644 index 8210e7565..000000000 --- a/numpy/random/src/pcg32/pcg-advance-64.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * PCG Random Number Generation for C. - * - * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * For additional information about the PCG random number generation scheme, - * including its license and other licensing options, visit - * - * http://www.pcg-random.org - */ - -/* - * This code is derived from the canonical C++ PCG implementation, which - * has many additional features and is preferable if you can use C++ in - * your project. - * - * Repetative C code is derived using C preprocessor metaprogramming - * techniques. - */ - -#include "pcg_variants.h" - -/* Multi-step advance functions (jump-ahead, jump-back) - * - * The method used here is based on Brown, "Random Number Generation - * with Arbitrary Stride,", Transactions of the American Nuclear - * Society (Nov. 1994). The algorithm is very similar to fast - * exponentiation. - * - * Even though delta is an unsigned integer, we can pass a - * signed integer to go backwards, it just goes "the long way round". - */ - -uint64_t pcg_advance_lcg_64(uint64_t state, uint64_t delta, uint64_t cur_mult, - uint64_t cur_plus) -{ - uint64_t acc_mult = 1u; - uint64_t acc_plus = 0u; - while (delta > 0) { - if (delta & 1) { - acc_mult *= cur_mult; - acc_plus = acc_plus * cur_mult + cur_plus; - } - cur_plus = (cur_mult + 1) * cur_plus; - cur_mult *= cur_mult; - delta /= 2; - } - return acc_mult * state + acc_plus; -} - diff --git a/numpy/random/src/pcg32/pcg32-test-data-gen.c b/numpy/random/src/pcg32/pcg32-test-data-gen.c deleted file mode 100644 index cccaf84b9..000000000 --- a/numpy/random/src/pcg32/pcg32-test-data-gen.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Generate testing csv files - * - * - * gcc pcg32-test-data-gen.c pcg32.orig.c ../splitmix64/splitmix64.c -o - * pgc64-test-data-gen - */ - -#include "pcg_variants.h" -#include <inttypes.h> -#include <stdio.h> - -#define N 1000 - -int main() { - pcg32_random_t rng; - uint64_t inc, seed = 0xDEADBEAF; - inc = 0; - int i; - uint64_t store[N]; - pcg32_srandom_r(&rng, seed, inc); - for (i = 0; i < N; i++) { - store[i] = pcg32_random_r(&rng); - } - - FILE *fp; - fp = fopen("pcg32-testset-1.csv", "w"); - if (fp == NULL) { - printf("Couldn't open file\n"); - return -1; - } - fprintf(fp, "seed, 0x%" PRIx64 "\n", seed); - for (i = 0; i < N; i++) { - fprintf(fp, "%d, 0x%" PRIx64 "\n", i, store[i]); - if (i == 999) { - printf("%d, 0x%" PRIx64 "\n", i, store[i]); - } - } - fclose(fp); - - seed = 0; - pcg32_srandom_r(&rng, seed, inc); - for (i = 0; i < N; i++) { - store[i] = pcg32_random_r(&rng); - } - fp = fopen("pcg32-testset-2.csv", "w"); - if (fp == NULL) { - printf("Couldn't open file\n"); - return -1; - } - fprintf(fp, "seed, 0x%" PRIx64 "\n", seed); - for (i = 0; i < N; i++) { - fprintf(fp, "%d, 0x%" PRIx64 "\n", i, store[i]); - if (i == 999) { - printf("%d, 0x%" PRIx64 "\n", i, store[i]); - } - } - fclose(fp); -} diff --git a/numpy/random/src/pcg32/pcg32.c b/numpy/random/src/pcg32/pcg32.c deleted file mode 100644 index 5fbf6759f..000000000 --- a/numpy/random/src/pcg32/pcg32.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "pcg32.h" - -extern inline uint64_t pcg32_next64(pcg32_state *state); -extern inline uint32_t pcg32_next32(pcg32_state *state); -extern inline double pcg32_next_double(pcg32_state *state); - -uint64_t pcg_advance_lcg_64(uint64_t state, uint64_t delta, uint64_t cur_mult, - uint64_t cur_plus) { - uint64_t acc_mult, acc_plus; - acc_mult = 1u; - acc_plus = 0u; - while (delta > 0) { - if (delta & 1) { - acc_mult *= cur_mult; - acc_plus = acc_plus * cur_mult + cur_plus; - } - cur_plus = (cur_mult + 1) * cur_plus; - cur_mult *= cur_mult; - delta /= 2; - } - return acc_mult * state + acc_plus; -} - -extern void pcg32_advance_state(pcg32_state *state, uint64_t step) { - pcg32_advance_r(state->pcg_state, step); -} - -extern void pcg32_set_seed(pcg32_state *state, uint64_t seed, uint64_t inc) { - pcg32_srandom_r(state->pcg_state, seed, inc); -} diff --git a/numpy/random/src/pcg32/pcg32.h b/numpy/random/src/pcg32/pcg32.h deleted file mode 100644 index 557113d8f..000000000 --- a/numpy/random/src/pcg32/pcg32.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef _RANDOMDGEN__PCG32_H_ -#define _RANDOMDGEN__PCG32_H_ - -#ifdef _WIN32 -#ifndef _INTTYPES -#include "../common/stdint.h" -#endif -#define inline __inline __forceinline -#else -#include <inttypes.h> -#endif - -#define PCG_DEFAULT_MULTIPLIER_64 6364136223846793005ULL - -struct pcg_state_setseq_64 { - uint64_t state; - uint64_t inc; -}; - -static inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot) { -#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) - asm("rorl %%cl, %0" : "=r"(value) : "0"(value), "c"(rot)); - return value; -#else - return (value >> rot) | (value << ((-rot) & 31)); -#endif -} - -static inline void pcg_setseq_64_step_r(struct pcg_state_setseq_64 *rng) { - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 + rng->inc; -} - -static inline uint32_t pcg_output_xsh_rr_64_32(uint64_t state) { - return pcg_rotr_32(((state >> 18u) ^ state) >> 27u, state >> 59u); -} - -static inline uint32_t -pcg_setseq_64_xsh_rr_32_random_r(struct pcg_state_setseq_64 *rng) { - uint64_t oldstate; - oldstate = rng->state; - pcg_setseq_64_step_r(rng); - return pcg_output_xsh_rr_64_32(oldstate); -} - -static inline void pcg_setseq_64_srandom_r(struct pcg_state_setseq_64 *rng, - uint64_t initstate, - uint64_t initseq) { - rng->state = 0U; - rng->inc = (initseq << 1u) | 1u; - pcg_setseq_64_step_r(rng); - rng->state += initstate; - pcg_setseq_64_step_r(rng); -} - -extern uint64_t pcg_advance_lcg_64(uint64_t state, uint64_t delta, - uint64_t cur_mult, uint64_t cur_plus); - -static inline void pcg_setseq_64_advance_r(struct pcg_state_setseq_64 *rng, - uint64_t delta) { - rng->state = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, - rng->inc); -} - -typedef struct pcg_state_setseq_64 pcg32_random_t; -#define pcg32_random_r pcg_setseq_64_xsh_rr_32_random_r -#define pcg32_srandom_r pcg_setseq_64_srandom_r -#define pcg32_advance_r pcg_setseq_64_advance_r - -typedef struct s_pcg32_state { pcg32_random_t *pcg_state; } pcg32_state; - -static inline uint64_t pcg32_next64(pcg32_state *state) { - return (uint64_t)(pcg32_random_r(state->pcg_state)) << 32 | - pcg32_random_r(state->pcg_state); -} - -static inline uint32_t pcg32_next32(pcg32_state *state) { - return pcg32_random_r(state->pcg_state); -} - -static inline double pcg32_next_double(pcg32_state *state) { - int32_t a = pcg32_random_r(state->pcg_state) >> 5, - b = pcg32_random_r(state->pcg_state) >> 6; - return (a * 67108864.0 + b) / 9007199254740992.0; -} - -void pcg32_advance_state(pcg32_state *state, uint64_t step); -void pcg32_set_seed(pcg32_state *state, uint64_t seed, uint64_t inc); - -#endif diff --git a/numpy/random/src/pcg32/pcg_variants.h b/numpy/random/src/pcg32/pcg_variants.h deleted file mode 100644 index 32daac1ce..000000000 --- a/numpy/random/src/pcg32/pcg_variants.h +++ /dev/null @@ -1,2210 +0,0 @@ -/* - * PCG Random Number Generation for C. - * - * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * For additional information about the PCG random number generation scheme, - * including its license and other licensing options, visit - * - * http://www.pcg-random.org - */ - -/* - * This code is derived from the canonical C++ PCG implementation, which - * has many additional features and is preferable if you can use C++ in - * your project. - * - * Much of the derivation was performed mechanically. In particular, the - * output functions were generated by compiling the C++ output functions - * into LLVM bitcode and then transforming that using the LLVM C backend - * (from https://github.com/draperlaboratory/llvm-cbe), and then - * postprocessing and hand editing the output. - * - * Much of the remaining code was generated by C-preprocessor metaprogramming. - */ - -#ifndef PCG_VARIANTS_H_INCLUDED -#define PCG_VARIANTS_H_INCLUDED 1 - -#include <inttypes.h> - -#if __SIZEOF_INT128__ - typedef __uint128_t pcg128_t; - #define PCG_128BIT_CONSTANT(high,low) \ - ((((pcg128_t)high) << 64) + low) - #define PCG_HAS_128BIT_OPS 1 -#endif - -#if __GNUC_GNU_INLINE__ && !defined(__cplusplus) - #error Nonstandard GNU inlining semantics. Compile with -std=c99 or better. - // We could instead use macros PCG_INLINE and PCG_EXTERN_INLINE - // but better to just reject ancient C code. -#endif - -#if __cplusplus -extern "C" { -#endif - -/* - * Rotate helper functions. - */ - -inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot) -{ -/* Unfortunately, clang is kinda pathetic when it comes to properly - * recognizing idiomatic rotate code, so for clang we actually provide - * assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss. - */ -#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) - asm ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); - return value; -#else - return (value >> rot) | (value << ((- rot) & 7)); -#endif -} - -inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot) -{ -#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) - asm ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); - return value; -#else - return (value >> rot) | (value << ((- rot) & 15)); -#endif -} - -inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot) -{ -#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) - asm ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); - return value; -#else - return (value >> rot) | (value << ((- rot) & 31)); -#endif -} - -inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot) -{ -#if 0 && PCG_USE_INLINE_ASM && __clang__ && __x86_64__ - // For whatever reason, clang actually *does* generate rotq by - // itself, so we don't need this code. - asm ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); - return value; -#else - return (value >> rot) | (value << ((- rot) & 63)); -#endif -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t pcg_rotr_128(pcg128_t value, unsigned int rot) -{ - return (value >> rot) | (value << ((- rot) & 127)); -} -#endif - -/* - * Output functions. These are the core of the PCG generation scheme. - */ - -// XSH RS - -inline uint8_t pcg_output_xsh_rs_16_8(uint16_t state) -{ - return (uint8_t)(((state >> 7u) ^ state) >> ((state >> 14u) + 3u)); -} - -inline uint16_t pcg_output_xsh_rs_32_16(uint32_t state) -{ - return (uint16_t)(((state >> 11u) ^ state) >> ((state >> 30u) + 11u)); -} - -inline uint32_t pcg_output_xsh_rs_64_32(uint64_t state) -{ - - return (uint32_t)(((state >> 22u) ^ state) >> ((state >> 61u) + 22u)); -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_output_xsh_rs_128_64(pcg128_t state) -{ - return (uint64_t)(((state >> 43u) ^ state) >> ((state >> 124u) + 45u)); -} -#endif - -// XSH RR - -inline uint8_t pcg_output_xsh_rr_16_8(uint16_t state) -{ - return pcg_rotr_8(((state >> 5u) ^ state) >> 5u, state >> 13u); -} - -inline uint16_t pcg_output_xsh_rr_32_16(uint32_t state) -{ - return pcg_rotr_16(((state >> 10u) ^ state) >> 12u, state >> 28u); -} - -inline uint32_t pcg_output_xsh_rr_64_32(uint64_t state) -{ - return pcg_rotr_32(((state >> 18u) ^ state) >> 27u, state >> 59u); -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_output_xsh_rr_128_64(pcg128_t state) -{ - return pcg_rotr_64(((state >> 29u) ^ state) >> 58u, state >> 122u); -} -#endif - -// RXS M XS - -inline uint8_t pcg_output_rxs_m_xs_8_8(uint8_t state) -{ - uint8_t word = ((state >> ((state >> 6u) + 2u)) ^ state) * 217u; - return (word >> 6u) ^ word; -} - -inline uint16_t pcg_output_rxs_m_xs_16_16(uint16_t state) -{ - uint16_t word = ((state >> ((state >> 13u) + 3u)) ^ state) * 62169u; - return (word >> 11u) ^ word; -} - -inline uint32_t pcg_output_rxs_m_xs_32_32(uint32_t state) -{ - uint32_t word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u; - return (word >> 22u) ^ word; -} - -inline uint64_t pcg_output_rxs_m_xs_64_64(uint64_t state) -{ - uint64_t word = ((state >> ((state >> 59u) + 5u)) ^ state) - * 12605985483714917081ull; - return (word >> 43u) ^ word; -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t pcg_output_rxs_m_xs_128_128(pcg128_t state) -{ - pcg128_t word = ((state >> ((state >> 122u) + 6u)) ^ state) - * (PCG_128BIT_CONSTANT(17766728186571221404ULL, - 12605985483714917081ULL)); - // 327738287884841127335028083622016905945 - return (word >> 86u) ^ word; -} -#endif - -// XSL RR (only defined for >= 64 bits) - -inline uint32_t pcg_output_xsl_rr_64_32(uint64_t state) -{ - return pcg_rotr_32(((uint32_t)(state >> 32u)) ^ (uint32_t)state, - state >> 59u); -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state) -{ - return pcg_rotr_64(((uint64_t)(state >> 64u)) ^ (uint64_t)state, - state >> 122u); -} -#endif - -// XSL RR RR (only defined for >= 64 bits) - -inline uint64_t pcg_output_xsl_rr_rr_64_64(uint64_t state) -{ - uint32_t rot1 = (uint32_t)(state >> 59u); - uint32_t high = (uint32_t)(state >> 32u); - uint32_t low = (uint32_t)state; - uint32_t xored = high ^ low; - uint32_t newlow = pcg_rotr_32(xored, rot1); - uint32_t newhigh = pcg_rotr_32(high, newlow & 31u); - return (((uint64_t)newhigh) << 32u) | newlow; -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t pcg_output_xsl_rr_rr_128_128(pcg128_t state) -{ - uint32_t rot1 = (uint32_t)(state >> 122u); - uint64_t high = (uint64_t)(state >> 64u); - uint64_t low = (uint64_t)state; - uint64_t xored = high ^ low; - uint64_t newlow = pcg_rotr_64(xored, rot1); - uint64_t newhigh = pcg_rotr_64(high, newlow & 63u); - return (((pcg128_t)newhigh) << 64u) | newlow; -} -#endif - -#define PCG_DEFAULT_MULTIPLIER_8 141U -#define PCG_DEFAULT_MULTIPLIER_16 12829U -#define PCG_DEFAULT_MULTIPLIER_32 747796405U -#define PCG_DEFAULT_MULTIPLIER_64 6364136223846793005ULL - -#define PCG_DEFAULT_INCREMENT_8 77U -#define PCG_DEFAULT_INCREMENT_16 47989U -#define PCG_DEFAULT_INCREMENT_32 2891336453U -#define PCG_DEFAULT_INCREMENT_64 1442695040888963407ULL - -#if PCG_HAS_128BIT_OPS -#define PCG_DEFAULT_MULTIPLIER_128 \ - PCG_128BIT_CONSTANT(2549297995355413924ULL,4865540595714422341ULL) -#define PCG_DEFAULT_INCREMENT_128 \ - PCG_128BIT_CONSTANT(6364136223846793005ULL,1442695040888963407ULL) -#endif - -/* - * Static initialization constants (if you can't call srandom for some - * bizarre reason). - */ - -#define PCG_STATE_ONESEQ_8_INITIALIZER { 0xd7U } -#define PCG_STATE_ONESEQ_16_INITIALIZER { 0x20dfU } -#define PCG_STATE_ONESEQ_32_INITIALIZER { 0x46b56677U } -#define PCG_STATE_ONESEQ_64_INITIALIZER { 0x4d595df4d0f33173ULL } -#if PCG_HAS_128BIT_OPS -#define PCG_STATE_ONESEQ_128_INITIALIZER \ - { PCG_128BIT_CONSTANT(0xb8dc10e158a92392ULL, 0x98046df007ec0a53ULL) } -#endif - -#define PCG_STATE_UNIQUE_8_INITIALIZER PCG_STATE_ONESEQ_8_INITIALIZER -#define PCG_STATE_UNIQUE_16_INITIALIZER PCG_STATE_ONESEQ_16_INITIALIZER -#define PCG_STATE_UNIQUE_32_INITIALIZER PCG_STATE_ONESEQ_32_INITIALIZER -#define PCG_STATE_UNIQUE_64_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER -#if PCG_HAS_128BIT_OPS -#define PCG_STATE_UNIQUE_128_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER -#endif - -#define PCG_STATE_MCG_8_INITIALIZER { 0xe5U } -#define PCG_STATE_MCG_16_INITIALIZER { 0xa5e5U } -#define PCG_STATE_MCG_32_INITIALIZER { 0xd15ea5e5U } -#define PCG_STATE_MCG_64_INITIALIZER { 0xcafef00dd15ea5e5ULL } -#if PCG_HAS_128BIT_OPS -#define PCG_STATE_MCG_128_INITIALIZER \ - { PCG_128BIT_CONSTANT(0x0000000000000000ULL, 0xcafef00dd15ea5e5ULL) } -#endif - -#define PCG_STATE_SETSEQ_8_INITIALIZER { 0x9bU, 0xdbU } -#define PCG_STATE_SETSEQ_16_INITIALIZER { 0xe39bU, 0x5bdbU } -#define PCG_STATE_SETSEQ_32_INITIALIZER { 0xec02d89bU, 0x94b95bdbU } -#define PCG_STATE_SETSEQ_64_INITIALIZER \ - { 0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL } -#if PCG_HAS_128BIT_OPS -#define PCG_STATE_SETSEQ_128_INITIALIZER \ - { PCG_128BIT_CONSTANT(0x979c9a98d8462005ULL, 0x7d3e9cb6cfe0549bULL), \ - PCG_128BIT_CONSTANT(0x0000000000000001ULL, 0xda3e39cb94b95bdbULL) } -#endif - -/* Representations for the oneseq, mcg, and unique variants */ - -struct pcg_state_8 { - uint8_t state; -}; - -struct pcg_state_16 { - uint16_t state; -}; - -struct pcg_state_32 { - uint32_t state; -}; - -struct pcg_state_64 { - uint64_t state; -}; - -#if PCG_HAS_128BIT_OPS -struct pcg_state_128 { - pcg128_t state; -}; -#endif - -/* Representations setseq variants */ - -struct pcg_state_setseq_8 { - uint8_t state; - uint8_t inc; -}; - -struct pcg_state_setseq_16 { - uint16_t state; - uint16_t inc; -}; - -struct pcg_state_setseq_32 { - uint32_t state; - uint32_t inc; -}; - -struct pcg_state_setseq_64 { - uint64_t state; - uint64_t inc; -}; - -#if PCG_HAS_128BIT_OPS -struct pcg_state_setseq_128 { - pcg128_t state; - pcg128_t inc; -}; -#endif - -/* Multi-step advance functions (jump-ahead, jump-back) */ - -extern uint8_t pcg_advance_lcg_8(uint8_t state, uint8_t delta, uint8_t cur_mult, - uint8_t cur_plus); -extern uint16_t pcg_advance_lcg_16(uint16_t state, uint16_t delta, - uint16_t cur_mult, uint16_t cur_plus); -extern uint32_t pcg_advance_lcg_32(uint32_t state, uint32_t delta, - uint32_t cur_mult, uint32_t cur_plus); -extern uint64_t pcg_advance_lcg_64(uint64_t state, uint64_t delta, - uint64_t cur_mult, uint64_t cur_plus); - -#if PCG_HAS_128BIT_OPS -extern pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta, - pcg128_t cur_mult, pcg128_t cur_plus); -#endif - -/* Functions to advance the underlying LCG, one version for each size and - * each style. These functions are considered semi-private. There is rarely - * a good reason to call them directly. - */ - -inline void pcg_oneseq_8_step_r(struct pcg_state_8* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8 - + PCG_DEFAULT_INCREMENT_8; -} - -inline void pcg_oneseq_8_advance_r(struct pcg_state_8* rng, uint8_t delta) -{ - rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, - PCG_DEFAULT_INCREMENT_8); -} - -inline void pcg_mcg_8_step_r(struct pcg_state_8* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8; -} - -inline void pcg_mcg_8_advance_r(struct pcg_state_8* rng, uint8_t delta) -{ - rng->state - = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, 0u); -} - -inline void pcg_unique_8_step_r(struct pcg_state_8* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8 - + (uint8_t)(((intptr_t)rng) | 1u); -} - -inline void pcg_unique_8_advance_r(struct pcg_state_8* rng, uint8_t delta) -{ - rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, - (uint8_t)(((intptr_t)rng) | 1u)); -} - -inline void pcg_setseq_8_step_r(struct pcg_state_setseq_8* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8 + rng->inc; -} - -inline void pcg_setseq_8_advance_r(struct pcg_state_setseq_8* rng, - uint8_t delta) -{ - rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, - rng->inc); -} - -inline void pcg_oneseq_16_step_r(struct pcg_state_16* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16 - + PCG_DEFAULT_INCREMENT_16; -} - -inline void pcg_oneseq_16_advance_r(struct pcg_state_16* rng, uint16_t delta) -{ - rng->state = pcg_advance_lcg_16( - rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, PCG_DEFAULT_INCREMENT_16); -} - -inline void pcg_mcg_16_step_r(struct pcg_state_16* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16; -} - -inline void pcg_mcg_16_advance_r(struct pcg_state_16* rng, uint16_t delta) -{ - rng->state - = pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, 0u); -} - -inline void pcg_unique_16_step_r(struct pcg_state_16* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16 - + (uint16_t)(((intptr_t)rng) | 1u); -} - -inline void pcg_unique_16_advance_r(struct pcg_state_16* rng, uint16_t delta) -{ - rng->state - = pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, - (uint16_t)(((intptr_t)rng) | 1u)); -} - -inline void pcg_setseq_16_step_r(struct pcg_state_setseq_16* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16 + rng->inc; -} - -inline void pcg_setseq_16_advance_r(struct pcg_state_setseq_16* rng, - uint16_t delta) -{ - rng->state = pcg_advance_lcg_16(rng->state, delta, - PCG_DEFAULT_MULTIPLIER_16, rng->inc); -} - -inline void pcg_oneseq_32_step_r(struct pcg_state_32* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32 - + PCG_DEFAULT_INCREMENT_32; -} - -inline void pcg_oneseq_32_advance_r(struct pcg_state_32* rng, uint32_t delta) -{ - rng->state = pcg_advance_lcg_32( - rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, PCG_DEFAULT_INCREMENT_32); -} - -inline void pcg_mcg_32_step_r(struct pcg_state_32* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32; -} - -inline void pcg_mcg_32_advance_r(struct pcg_state_32* rng, uint32_t delta) -{ - rng->state - = pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, 0u); -} - -inline void pcg_unique_32_step_r(struct pcg_state_32* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32 - + (uint32_t)(((intptr_t)rng) | 1u); -} - -inline void pcg_unique_32_advance_r(struct pcg_state_32* rng, uint32_t delta) -{ - rng->state - = pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, - (uint32_t)(((intptr_t)rng) | 1u)); -} - -inline void pcg_setseq_32_step_r(struct pcg_state_setseq_32* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32 + rng->inc; -} - -inline void pcg_setseq_32_advance_r(struct pcg_state_setseq_32* rng, - uint32_t delta) -{ - rng->state = pcg_advance_lcg_32(rng->state, delta, - PCG_DEFAULT_MULTIPLIER_32, rng->inc); -} - -inline void pcg_oneseq_64_step_r(struct pcg_state_64* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 - + PCG_DEFAULT_INCREMENT_64; -} - -inline void pcg_oneseq_64_advance_r(struct pcg_state_64* rng, uint64_t delta) -{ - rng->state = pcg_advance_lcg_64( - rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, PCG_DEFAULT_INCREMENT_64); -} - -inline void pcg_mcg_64_step_r(struct pcg_state_64* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64; -} - -inline void pcg_mcg_64_advance_r(struct pcg_state_64* rng, uint64_t delta) -{ - rng->state - = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, 0u); -} - -inline void pcg_unique_64_step_r(struct pcg_state_64* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 - + (uint64_t)(((intptr_t)rng) | 1u); -} - -inline void pcg_unique_64_advance_r(struct pcg_state_64* rng, uint64_t delta) -{ - rng->state - = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, - (uint64_t)(((intptr_t)rng) | 1u)); -} - -inline void pcg_setseq_64_step_r(struct pcg_state_setseq_64* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 + rng->inc; -} - -inline void pcg_setseq_64_advance_r(struct pcg_state_setseq_64* rng, - uint64_t delta) -{ - rng->state = pcg_advance_lcg_64(rng->state, delta, - PCG_DEFAULT_MULTIPLIER_64, rng->inc); -} - -#if PCG_HAS_128BIT_OPS -inline void pcg_oneseq_128_step_r(struct pcg_state_128* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 - + PCG_DEFAULT_INCREMENT_128; -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_oneseq_128_advance_r(struct pcg_state_128* rng, pcg128_t delta) -{ - rng->state - = pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128, - PCG_DEFAULT_INCREMENT_128); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_mcg_128_step_r(struct pcg_state_128* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128; -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_mcg_128_advance_r(struct pcg_state_128* rng, pcg128_t delta) -{ - rng->state = pcg_advance_lcg_128(rng->state, delta, - PCG_DEFAULT_MULTIPLIER_128, 0u); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_unique_128_step_r(struct pcg_state_128* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 - + (pcg128_t)(((intptr_t)rng) | 1u); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_unique_128_advance_r(struct pcg_state_128* rng, pcg128_t delta) -{ - rng->state - = pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128, - (pcg128_t)(((intptr_t)rng) | 1u)); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_setseq_128_step_r(struct pcg_state_setseq_128* rng) -{ - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 + rng->inc; -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_setseq_128_advance_r(struct pcg_state_setseq_128* rng, - pcg128_t delta) -{ - rng->state = pcg_advance_lcg_128(rng->state, delta, - PCG_DEFAULT_MULTIPLIER_128, rng->inc); -} -#endif - -/* Functions to seed the RNG state, one version for each size and each - * style. Unlike the step functions, regular users can and should call - * these functions. - */ - -inline void pcg_oneseq_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate) -{ - rng->state = 0U; - pcg_oneseq_8_step_r(rng); - rng->state += initstate; - pcg_oneseq_8_step_r(rng); -} - -inline void pcg_mcg_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate) -{ - rng->state = initstate | 1u; -} - -inline void pcg_unique_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate) -{ - rng->state = 0U; - pcg_unique_8_step_r(rng); - rng->state += initstate; - pcg_unique_8_step_r(rng); -} - -inline void pcg_setseq_8_srandom_r(struct pcg_state_setseq_8* rng, - uint8_t initstate, uint8_t initseq) -{ - rng->state = 0U; - rng->inc = (initseq << 1u) | 1u; - pcg_setseq_8_step_r(rng); - rng->state += initstate; - pcg_setseq_8_step_r(rng); -} - -inline void pcg_oneseq_16_srandom_r(struct pcg_state_16* rng, - uint16_t initstate) -{ - rng->state = 0U; - pcg_oneseq_16_step_r(rng); - rng->state += initstate; - pcg_oneseq_16_step_r(rng); -} - -inline void pcg_mcg_16_srandom_r(struct pcg_state_16* rng, uint16_t initstate) -{ - rng->state = initstate | 1u; -} - -inline void pcg_unique_16_srandom_r(struct pcg_state_16* rng, - uint16_t initstate) -{ - rng->state = 0U; - pcg_unique_16_step_r(rng); - rng->state += initstate; - pcg_unique_16_step_r(rng); -} - -inline void pcg_setseq_16_srandom_r(struct pcg_state_setseq_16* rng, - uint16_t initstate, uint16_t initseq) -{ - rng->state = 0U; - rng->inc = (initseq << 1u) | 1u; - pcg_setseq_16_step_r(rng); - rng->state += initstate; - pcg_setseq_16_step_r(rng); -} - -inline void pcg_oneseq_32_srandom_r(struct pcg_state_32* rng, - uint32_t initstate) -{ - rng->state = 0U; - pcg_oneseq_32_step_r(rng); - rng->state += initstate; - pcg_oneseq_32_step_r(rng); -} - -inline void pcg_mcg_32_srandom_r(struct pcg_state_32* rng, uint32_t initstate) -{ - rng->state = initstate | 1u; -} - -inline void pcg_unique_32_srandom_r(struct pcg_state_32* rng, - uint32_t initstate) -{ - rng->state = 0U; - pcg_unique_32_step_r(rng); - rng->state += initstate; - pcg_unique_32_step_r(rng); -} - -inline void pcg_setseq_32_srandom_r(struct pcg_state_setseq_32* rng, - uint32_t initstate, uint32_t initseq) -{ - rng->state = 0U; - rng->inc = (initseq << 1u) | 1u; - pcg_setseq_32_step_r(rng); - rng->state += initstate; - pcg_setseq_32_step_r(rng); -} - -inline void pcg_oneseq_64_srandom_r(struct pcg_state_64* rng, - uint64_t initstate) -{ - rng->state = 0U; - pcg_oneseq_64_step_r(rng); - rng->state += initstate; - pcg_oneseq_64_step_r(rng); -} - -inline void pcg_mcg_64_srandom_r(struct pcg_state_64* rng, uint64_t initstate) -{ - rng->state = initstate | 1u; -} - -inline void pcg_unique_64_srandom_r(struct pcg_state_64* rng, - uint64_t initstate) -{ - rng->state = 0U; - pcg_unique_64_step_r(rng); - rng->state += initstate; - pcg_unique_64_step_r(rng); -} - -inline void pcg_setseq_64_srandom_r(struct pcg_state_setseq_64* rng, - uint64_t initstate, uint64_t initseq) -{ - rng->state = 0U; - rng->inc = (initseq << 1u) | 1u; - pcg_setseq_64_step_r(rng); - rng->state += initstate; - pcg_setseq_64_step_r(rng); -} - -#if PCG_HAS_128BIT_OPS -inline void pcg_oneseq_128_srandom_r(struct pcg_state_128* rng, - pcg128_t initstate) -{ - rng->state = 0U; - pcg_oneseq_128_step_r(rng); - rng->state += initstate; - pcg_oneseq_128_step_r(rng); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_mcg_128_srandom_r(struct pcg_state_128* rng, pcg128_t initstate) -{ - rng->state = initstate | 1u; -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_unique_128_srandom_r(struct pcg_state_128* rng, - pcg128_t initstate) -{ - rng->state = 0U; - pcg_unique_128_step_r(rng); - rng->state += initstate; - pcg_unique_128_step_r(rng); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_setseq_128_srandom_r(struct pcg_state_setseq_128* rng, - pcg128_t initstate, pcg128_t initseq) -{ - rng->state = 0U; - rng->inc = (initseq << 1u) | 1u; - pcg_setseq_128_step_r(rng); - rng->state += initstate; - pcg_setseq_128_step_r(rng); -} -#endif - -/* Now, finally we create each of the individual generators. We provide - * a random_r function that provides a random number of the appropriate - * type (using the full range of the type) and a boundedrand_r version - * that provides - * - * Implementation notes for boundedrand_r: - * - * To avoid bias, we need to make the range of the RNG a multiple of - * bound, which we do by dropping output less than a threshold. - * Let's consider a 32-bit case... A naive scheme to calculate the - * threshold would be to do - * - * uint32_t threshold = 0x100000000ull % bound; - * - * but 64-bit div/mod is slower than 32-bit div/mod (especially on - * 32-bit platforms). In essence, we do - * - * uint32_t threshold = (0x100000000ull-bound) % bound; - * - * because this version will calculate the same modulus, but the LHS - * value is less than 2^32. - * - * (Note that using modulo is only wise for good RNGs, poorer RNGs - * such as raw LCGs do better using a technique based on division.) - * Empricical tests show that division is preferable to modulus for - * reducting the range of an RNG. It's faster, and sometimes it can - * even be statistically prefereable. - */ - -/* Generation functions for XSH RS */ - -inline uint8_t pcg_oneseq_16_xsh_rs_8_random_r(struct pcg_state_16* rng) -{ - uint16_t oldstate = rng->state; - pcg_oneseq_16_step_r(rng); - return pcg_output_xsh_rs_16_8(oldstate); -} - -inline uint8_t pcg_oneseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, - uint8_t bound) -{ - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_oneseq_16_xsh_rs_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t pcg_oneseq_32_xsh_rs_16_random_r(struct pcg_state_32* rng) -{ - uint32_t oldstate = rng->state; - pcg_oneseq_32_step_r(rng); - return pcg_output_xsh_rs_32_16(oldstate); -} - -inline uint16_t pcg_oneseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, - uint16_t bound) -{ - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_oneseq_32_xsh_rs_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_oneseq_64_xsh_rs_32_random_r(struct pcg_state_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_oneseq_64_step_r(rng); - return pcg_output_xsh_rs_64_32(oldstate); -} - -inline uint32_t pcg_oneseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, - uint32_t bound) -{ - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_oneseq_64_xsh_rs_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_oneseq_128_xsh_rs_64_random_r(struct pcg_state_128* rng) -{ - pcg_oneseq_128_step_r(rng); - return pcg_output_xsh_rs_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_oneseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_oneseq_128_xsh_rs_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint8_t pcg_unique_16_xsh_rs_8_random_r(struct pcg_state_16* rng) -{ - uint16_t oldstate = rng->state; - pcg_unique_16_step_r(rng); - return pcg_output_xsh_rs_16_8(oldstate); -} - -inline uint8_t pcg_unique_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, - uint8_t bound) -{ - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_unique_16_xsh_rs_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t pcg_unique_32_xsh_rs_16_random_r(struct pcg_state_32* rng) -{ - uint32_t oldstate = rng->state; - pcg_unique_32_step_r(rng); - return pcg_output_xsh_rs_32_16(oldstate); -} - -inline uint16_t pcg_unique_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, - uint16_t bound) -{ - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_unique_32_xsh_rs_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_unique_64_xsh_rs_32_random_r(struct pcg_state_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_unique_64_step_r(rng); - return pcg_output_xsh_rs_64_32(oldstate); -} - -inline uint32_t pcg_unique_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, - uint32_t bound) -{ - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_unique_64_xsh_rs_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_unique_128_xsh_rs_64_random_r(struct pcg_state_128* rng) -{ - pcg_unique_128_step_r(rng); - return pcg_output_xsh_rs_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_unique_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_unique_128_xsh_rs_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint8_t pcg_setseq_16_xsh_rs_8_random_r(struct pcg_state_setseq_16* rng) -{ - uint16_t oldstate = rng->state; - pcg_setseq_16_step_r(rng); - return pcg_output_xsh_rs_16_8(oldstate); -} - -inline uint8_t -pcg_setseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_setseq_16* rng, - uint8_t bound) -{ - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_setseq_16_xsh_rs_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t -pcg_setseq_32_xsh_rs_16_random_r(struct pcg_state_setseq_32* rng) -{ - uint32_t oldstate = rng->state; - pcg_setseq_32_step_r(rng); - return pcg_output_xsh_rs_32_16(oldstate); -} - -inline uint16_t -pcg_setseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_setseq_32* rng, - uint16_t bound) -{ - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_setseq_32_xsh_rs_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t -pcg_setseq_64_xsh_rs_32_random_r(struct pcg_state_setseq_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_setseq_64_step_r(rng); - return pcg_output_xsh_rs_64_32(oldstate); -} - -inline uint32_t -pcg_setseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_setseq_64* rng, - uint32_t bound) -{ - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_setseq_64_xsh_rs_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_setseq_128_xsh_rs_64_random_r(struct pcg_state_setseq_128* rng) -{ - pcg_setseq_128_step_r(rng); - return pcg_output_xsh_rs_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_setseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_setseq_128* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_setseq_128_xsh_rs_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint8_t pcg_mcg_16_xsh_rs_8_random_r(struct pcg_state_16* rng) -{ - uint16_t oldstate = rng->state; - pcg_mcg_16_step_r(rng); - return pcg_output_xsh_rs_16_8(oldstate); -} - -inline uint8_t pcg_mcg_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, - uint8_t bound) -{ - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_mcg_16_xsh_rs_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t pcg_mcg_32_xsh_rs_16_random_r(struct pcg_state_32* rng) -{ - uint32_t oldstate = rng->state; - pcg_mcg_32_step_r(rng); - return pcg_output_xsh_rs_32_16(oldstate); -} - -inline uint16_t pcg_mcg_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, - uint16_t bound) -{ - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_mcg_32_xsh_rs_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_mcg_64_xsh_rs_32_random_r(struct pcg_state_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_mcg_64_step_r(rng); - return pcg_output_xsh_rs_64_32(oldstate); -} - -inline uint32_t pcg_mcg_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, - uint32_t bound) -{ - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_mcg_64_xsh_rs_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_mcg_128_xsh_rs_64_random_r(struct pcg_state_128* rng) -{ - pcg_mcg_128_step_r(rng); - return pcg_output_xsh_rs_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_mcg_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_mcg_128_xsh_rs_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -/* Generation functions for XSH RR */ - -inline uint8_t pcg_oneseq_16_xsh_rr_8_random_r(struct pcg_state_16* rng) -{ - uint16_t oldstate = rng->state; - pcg_oneseq_16_step_r(rng); - return pcg_output_xsh_rr_16_8(oldstate); -} - -inline uint8_t pcg_oneseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, - uint8_t bound) -{ - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_oneseq_16_xsh_rr_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t pcg_oneseq_32_xsh_rr_16_random_r(struct pcg_state_32* rng) -{ - uint32_t oldstate = rng->state; - pcg_oneseq_32_step_r(rng); - return pcg_output_xsh_rr_32_16(oldstate); -} - -inline uint16_t pcg_oneseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, - uint16_t bound) -{ - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_oneseq_32_xsh_rr_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_oneseq_64_xsh_rr_32_random_r(struct pcg_state_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_oneseq_64_step_r(rng); - return pcg_output_xsh_rr_64_32(oldstate); -} - -inline uint32_t pcg_oneseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, - uint32_t bound) -{ - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_oneseq_64_xsh_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_oneseq_128_xsh_rr_64_random_r(struct pcg_state_128* rng) -{ - pcg_oneseq_128_step_r(rng); - return pcg_output_xsh_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_oneseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_oneseq_128_xsh_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint8_t pcg_unique_16_xsh_rr_8_random_r(struct pcg_state_16* rng) -{ - uint16_t oldstate = rng->state; - pcg_unique_16_step_r(rng); - return pcg_output_xsh_rr_16_8(oldstate); -} - -inline uint8_t pcg_unique_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, - uint8_t bound) -{ - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_unique_16_xsh_rr_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t pcg_unique_32_xsh_rr_16_random_r(struct pcg_state_32* rng) -{ - uint32_t oldstate = rng->state; - pcg_unique_32_step_r(rng); - return pcg_output_xsh_rr_32_16(oldstate); -} - -inline uint16_t pcg_unique_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, - uint16_t bound) -{ - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_unique_32_xsh_rr_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_unique_64_xsh_rr_32_random_r(struct pcg_state_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_unique_64_step_r(rng); - return pcg_output_xsh_rr_64_32(oldstate); -} - -inline uint32_t pcg_unique_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, - uint32_t bound) -{ - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_unique_64_xsh_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_unique_128_xsh_rr_64_random_r(struct pcg_state_128* rng) -{ - pcg_unique_128_step_r(rng); - return pcg_output_xsh_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_unique_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_unique_128_xsh_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint8_t pcg_setseq_16_xsh_rr_8_random_r(struct pcg_state_setseq_16* rng) -{ - uint16_t oldstate = rng->state; - pcg_setseq_16_step_r(rng); - return pcg_output_xsh_rr_16_8(oldstate); -} - -inline uint8_t -pcg_setseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_setseq_16* rng, - uint8_t bound) -{ - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_setseq_16_xsh_rr_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t -pcg_setseq_32_xsh_rr_16_random_r(struct pcg_state_setseq_32* rng) -{ - uint32_t oldstate = rng->state; - pcg_setseq_32_step_r(rng); - return pcg_output_xsh_rr_32_16(oldstate); -} - -inline uint16_t -pcg_setseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_setseq_32* rng, - uint16_t bound) -{ - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_setseq_32_xsh_rr_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t -pcg_setseq_64_xsh_rr_32_random_r(struct pcg_state_setseq_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_setseq_64_step_r(rng); - return pcg_output_xsh_rr_64_32(oldstate); -} - -inline uint32_t -pcg_setseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng, - uint32_t bound) -{ - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_setseq_64_xsh_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_setseq_128_xsh_rr_64_random_r(struct pcg_state_setseq_128* rng) -{ - pcg_setseq_128_step_r(rng); - return pcg_output_xsh_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_setseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_setseq_128_xsh_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint8_t pcg_mcg_16_xsh_rr_8_random_r(struct pcg_state_16* rng) -{ - uint16_t oldstate = rng->state; - pcg_mcg_16_step_r(rng); - return pcg_output_xsh_rr_16_8(oldstate); -} - -inline uint8_t pcg_mcg_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, - uint8_t bound) -{ - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_mcg_16_xsh_rr_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t pcg_mcg_32_xsh_rr_16_random_r(struct pcg_state_32* rng) -{ - uint32_t oldstate = rng->state; - pcg_mcg_32_step_r(rng); - return pcg_output_xsh_rr_32_16(oldstate); -} - -inline uint16_t pcg_mcg_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, - uint16_t bound) -{ - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_mcg_32_xsh_rr_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_mcg_64_xsh_rr_32_random_r(struct pcg_state_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_mcg_64_step_r(rng); - return pcg_output_xsh_rr_64_32(oldstate); -} - -inline uint32_t pcg_mcg_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, - uint32_t bound) -{ - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_mcg_64_xsh_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_mcg_128_xsh_rr_64_random_r(struct pcg_state_128* rng) -{ - pcg_mcg_128_step_r(rng); - return pcg_output_xsh_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_mcg_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_mcg_128_xsh_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -/* Generation functions for RXS M XS (no MCG versions because they - * don't make sense when you want to use the entire state) - */ - -inline uint8_t pcg_oneseq_8_rxs_m_xs_8_random_r(struct pcg_state_8* rng) -{ - uint8_t oldstate = rng->state; - pcg_oneseq_8_step_r(rng); - return pcg_output_rxs_m_xs_8_8(oldstate); -} - -inline uint8_t pcg_oneseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_8* rng, - uint8_t bound) -{ - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_oneseq_8_rxs_m_xs_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t pcg_oneseq_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng) -{ - uint16_t oldstate = rng->state; - pcg_oneseq_16_step_r(rng); - return pcg_output_rxs_m_xs_16_16(oldstate); -} - -inline uint16_t -pcg_oneseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng, - uint16_t bound) -{ - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_oneseq_16_rxs_m_xs_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_oneseq_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng) -{ - uint32_t oldstate = rng->state; - pcg_oneseq_32_step_r(rng); - return pcg_output_rxs_m_xs_32_32(oldstate); -} - -inline uint32_t -pcg_oneseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng, - uint32_t bound) -{ - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_oneseq_32_rxs_m_xs_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint64_t pcg_oneseq_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_oneseq_64_step_r(rng); - return pcg_output_rxs_m_xs_64_64(oldstate); -} - -inline uint64_t -pcg_oneseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_oneseq_64_rxs_m_xs_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t pcg_oneseq_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng) -{ - pcg_oneseq_128_step_r(rng); - return pcg_output_rxs_m_xs_128_128(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_oneseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng, - pcg128_t bound) -{ - pcg128_t threshold = -bound % bound; - for (;;) { - pcg128_t r = pcg_oneseq_128_rxs_m_xs_128_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint16_t pcg_unique_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng) -{ - uint16_t oldstate = rng->state; - pcg_unique_16_step_r(rng); - return pcg_output_rxs_m_xs_16_16(oldstate); -} - -inline uint16_t -pcg_unique_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng, - uint16_t bound) -{ - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_unique_16_rxs_m_xs_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_unique_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng) -{ - uint32_t oldstate = rng->state; - pcg_unique_32_step_r(rng); - return pcg_output_rxs_m_xs_32_32(oldstate); -} - -inline uint32_t -pcg_unique_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng, - uint32_t bound) -{ - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_unique_32_rxs_m_xs_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint64_t pcg_unique_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_unique_64_step_r(rng); - return pcg_output_rxs_m_xs_64_64(oldstate); -} - -inline uint64_t -pcg_unique_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_unique_64_rxs_m_xs_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t pcg_unique_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng) -{ - pcg_unique_128_step_r(rng); - return pcg_output_rxs_m_xs_128_128(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_unique_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng, - pcg128_t bound) -{ - pcg128_t threshold = -bound % bound; - for (;;) { - pcg128_t r = pcg_unique_128_rxs_m_xs_128_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint8_t pcg_setseq_8_rxs_m_xs_8_random_r(struct pcg_state_setseq_8* rng) -{ - uint8_t oldstate = rng->state; - pcg_setseq_8_step_r(rng); - return pcg_output_rxs_m_xs_8_8(oldstate); -} - -inline uint8_t -pcg_setseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_setseq_8* rng, - uint8_t bound) -{ - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_setseq_8_rxs_m_xs_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t -pcg_setseq_16_rxs_m_xs_16_random_r(struct pcg_state_setseq_16* rng) -{ - uint16_t oldstate = rng->state; - pcg_setseq_16_step_r(rng); - return pcg_output_rxs_m_xs_16_16(oldstate); -} - -inline uint16_t -pcg_setseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_setseq_16* rng, - uint16_t bound) -{ - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_setseq_16_rxs_m_xs_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t -pcg_setseq_32_rxs_m_xs_32_random_r(struct pcg_state_setseq_32* rng) -{ - uint32_t oldstate = rng->state; - pcg_setseq_32_step_r(rng); - return pcg_output_rxs_m_xs_32_32(oldstate); -} - -inline uint32_t -pcg_setseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_setseq_32* rng, - uint32_t bound) -{ - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_setseq_32_rxs_m_xs_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint64_t -pcg_setseq_64_rxs_m_xs_64_random_r(struct pcg_state_setseq_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_setseq_64_step_r(rng); - return pcg_output_rxs_m_xs_64_64(oldstate); -} - -inline uint64_t -pcg_setseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_setseq_64* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_setseq_64_rxs_m_xs_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_setseq_128_rxs_m_xs_128_random_r(struct pcg_state_setseq_128* rng) -{ - pcg_setseq_128_step_r(rng); - return pcg_output_rxs_m_xs_128_128(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_setseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_setseq_128* rng, - pcg128_t bound) -{ - pcg128_t threshold = -bound % bound; - for (;;) { - pcg128_t r = pcg_setseq_128_rxs_m_xs_128_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -/* Generation functions for XSL RR (only defined for "large" types) */ - -inline uint32_t pcg_oneseq_64_xsl_rr_32_random_r(struct pcg_state_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_oneseq_64_step_r(rng); - return pcg_output_xsl_rr_64_32(oldstate); -} - -inline uint32_t pcg_oneseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, - uint32_t bound) -{ - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_oneseq_64_xsl_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_oneseq_128_xsl_rr_64_random_r(struct pcg_state_128* rng) -{ - pcg_oneseq_128_step_r(rng); - return pcg_output_xsl_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_oneseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_oneseq_128_xsl_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint32_t pcg_unique_64_xsl_rr_32_random_r(struct pcg_state_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_unique_64_step_r(rng); - return pcg_output_xsl_rr_64_32(oldstate); -} - -inline uint32_t pcg_unique_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, - uint32_t bound) -{ - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_unique_64_xsl_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_unique_128_xsl_rr_64_random_r(struct pcg_state_128* rng) -{ - pcg_unique_128_step_r(rng); - return pcg_output_xsl_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_unique_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_unique_128_xsl_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint32_t -pcg_setseq_64_xsl_rr_32_random_r(struct pcg_state_setseq_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_setseq_64_step_r(rng); - return pcg_output_xsl_rr_64_32(oldstate); -} - -inline uint32_t -pcg_setseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng, - uint32_t bound) -{ - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_setseq_64_xsl_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_setseq_128_xsl_rr_64_random_r(struct pcg_state_setseq_128* rng) -{ - pcg_setseq_128_step_r(rng); - return pcg_output_xsl_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_setseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_setseq_128_xsl_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint32_t pcg_mcg_64_xsl_rr_32_random_r(struct pcg_state_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_mcg_64_step_r(rng); - return pcg_output_xsl_rr_64_32(oldstate); -} - -inline uint32_t pcg_mcg_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, - uint32_t bound) -{ - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_mcg_64_xsl_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_mcg_128_xsl_rr_64_random_r(struct pcg_state_128* rng) -{ - pcg_mcg_128_step_r(rng); - return pcg_output_xsl_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_mcg_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_mcg_128_xsl_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -/* Generation functions for XSL RR RR (only defined for "large" types) */ - -inline uint64_t pcg_oneseq_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_oneseq_64_step_r(rng); - return pcg_output_xsl_rr_rr_64_64(oldstate); -} - -inline uint64_t -pcg_oneseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_oneseq_64_xsl_rr_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t pcg_oneseq_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng) -{ - pcg_oneseq_128_step_r(rng); - return pcg_output_xsl_rr_rr_128_128(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_oneseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng, - pcg128_t bound) -{ - pcg128_t threshold = -bound % bound; - for (;;) { - pcg128_t r = pcg_oneseq_128_xsl_rr_rr_128_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint64_t pcg_unique_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_unique_64_step_r(rng); - return pcg_output_xsl_rr_rr_64_64(oldstate); -} - -inline uint64_t -pcg_unique_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_unique_64_xsl_rr_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t pcg_unique_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng) -{ - pcg_unique_128_step_r(rng); - return pcg_output_xsl_rr_rr_128_128(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_unique_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng, - pcg128_t bound) -{ - pcg128_t threshold = -bound % bound; - for (;;) { - pcg128_t r = pcg_unique_128_xsl_rr_rr_128_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint64_t -pcg_setseq_64_xsl_rr_rr_64_random_r(struct pcg_state_setseq_64* rng) -{ - uint64_t oldstate = rng->state; - pcg_setseq_64_step_r(rng); - return pcg_output_xsl_rr_rr_64_64(oldstate); -} - -inline uint64_t -pcg_setseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_setseq_64* rng, - uint64_t bound) -{ - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_setseq_64_xsl_rr_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_setseq_128_xsl_rr_rr_128_random_r(struct pcg_state_setseq_128* rng) -{ - pcg_setseq_128_step_r(rng); - return pcg_output_xsl_rr_rr_128_128(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_setseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_setseq_128* rng, - pcg128_t bound) -{ - pcg128_t threshold = -bound % bound; - for (;;) { - pcg128_t r = pcg_setseq_128_xsl_rr_rr_128_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -//// Typedefs -typedef struct pcg_state_setseq_64 pcg32_random_t; -typedef struct pcg_state_64 pcg32s_random_t; -typedef struct pcg_state_64 pcg32u_random_t; -typedef struct pcg_state_64 pcg32f_random_t; -//// random_r -#define pcg32_random_r pcg_setseq_64_xsh_rr_32_random_r -#define pcg32s_random_r pcg_oneseq_64_xsh_rr_32_random_r -#define pcg32u_random_r pcg_unique_64_xsh_rr_32_random_r -#define pcg32f_random_r pcg_mcg_64_xsh_rs_32_random_r -//// boundedrand_r -#define pcg32_boundedrand_r pcg_setseq_64_xsh_rr_32_boundedrand_r -#define pcg32s_boundedrand_r pcg_oneseq_64_xsh_rr_32_boundedrand_r -#define pcg32u_boundedrand_r pcg_unique_64_xsh_rr_32_boundedrand_r -#define pcg32f_boundedrand_r pcg_mcg_64_xsh_rs_32_boundedrand_r -//// srandom_r -#define pcg32_srandom_r pcg_setseq_64_srandom_r -#define pcg32s_srandom_r pcg_oneseq_64_srandom_r -#define pcg32u_srandom_r pcg_unique_64_srandom_r -#define pcg32f_srandom_r pcg_mcg_64_srandom_r -//// advance_r -#define pcg32_advance_r pcg_setseq_64_advance_r -#define pcg32s_advance_r pcg_oneseq_64_advance_r -#define pcg32u_advance_r pcg_unique_64_advance_r -#define pcg32f_advance_r pcg_mcg_64_advance_r - -#if PCG_HAS_128BIT_OPS -//// Typedefs -typedef struct pcg_state_setseq_128 pcg64_random_t; -typedef struct pcg_state_128 pcg64s_random_t; -typedef struct pcg_state_128 pcg64u_random_t; -typedef struct pcg_state_128 pcg64f_random_t; -//// random_r -#define pcg64_random_r pcg_setseq_128_xsl_rr_64_random_r -#define pcg64s_random_r pcg_oneseq_128_xsl_rr_64_random_r -#define pcg64u_random_r pcg_unique_128_xsl_rr_64_random_r -#define pcg64f_random_r pcg_mcg_128_xsl_rr_64_random_r -//// boundedrand_r -#define pcg64_boundedrand_r pcg_setseq_128_xsl_rr_64_boundedrand_r -#define pcg64s_boundedrand_r pcg_oneseq_128_xsl_rr_64_boundedrand_r -#define pcg64u_boundedrand_r pcg_unique_128_xsl_rr_64_boundedrand_r -#define pcg64f_boundedrand_r pcg_mcg_128_xsl_rr_64_boundedrand_r -//// srandom_r -#define pcg64_srandom_r pcg_setseq_128_srandom_r -#define pcg64s_srandom_r pcg_oneseq_128_srandom_r -#define pcg64u_srandom_r pcg_unique_128_srandom_r -#define pcg64f_srandom_r pcg_mcg_128_srandom_r -//// advance_r -#define pcg64_advance_r pcg_setseq_128_advance_r -#define pcg64s_advance_r pcg_oneseq_128_advance_r -#define pcg64u_advance_r pcg_unique_128_advance_r -#define pcg64f_advance_r pcg_mcg_128_advance_r -#endif - -//// Typedefs -typedef struct pcg_state_8 pcg8si_random_t; -typedef struct pcg_state_16 pcg16si_random_t; -typedef struct pcg_state_32 pcg32si_random_t; -typedef struct pcg_state_64 pcg64si_random_t; -//// random_r -#define pcg8si_random_r pcg_oneseq_8_rxs_m_xs_8_random_r -#define pcg16si_random_r pcg_oneseq_16_rxs_m_xs_16_random_r -#define pcg32si_random_r pcg_oneseq_32_rxs_m_xs_32_random_r -#define pcg64si_random_r pcg_oneseq_64_rxs_m_xs_64_random_r -//// boundedrand_r -#define pcg8si_boundedrand_r pcg_oneseq_8_rxs_m_xs_8_boundedrand_r -#define pcg16si_boundedrand_r pcg_oneseq_16_rxs_m_xs_16_boundedrand_r -#define pcg32si_boundedrand_r pcg_oneseq_32_rxs_m_xs_32_boundedrand_r -#define pcg64si_boundedrand_r pcg_oneseq_64_rxs_m_xs_64_boundedrand_r -//// srandom_r -#define pcg8si_srandom_r pcg_oneseq_8_srandom_r -#define pcg16si_srandom_r pcg_oneseq_16_srandom_r -#define pcg32si_srandom_r pcg_oneseq_32_srandom_r -#define pcg64si_srandom_r pcg_oneseq_64_srandom_r -//// advance_r -#define pcg8si_advance_r pcg_oneseq_8_advance_r -#define pcg16si_advance_r pcg_oneseq_16_advance_r -#define pcg32si_advance_r pcg_oneseq_32_advance_r -#define pcg64si_advance_r pcg_oneseq_64_advance_r - -#if PCG_HAS_128BIT_OPS -typedef struct pcg_state_128 pcg128si_random_t; -#define pcg128si_random_r pcg_oneseq_128_rxs_m_xs_128_random_r -#define pcg128si_boundedrand_r pcg_oneseq_128_rxs_m_xs_128_boundedrand_r -#define pcg128si_srandom_r pcg_oneseq_128_srandom_r -#define pcg128si_advance_r pcg_oneseq_128_advance_r -#endif - -//// Typedefs -typedef struct pcg_state_setseq_8 pcg8i_random_t; -typedef struct pcg_state_setseq_16 pcg16i_random_t; -typedef struct pcg_state_setseq_32 pcg32i_random_t; -typedef struct pcg_state_setseq_64 pcg64i_random_t; -//// random_r -#define pcg8i_random_r pcg_setseq_8_rxs_m_xs_8_random_r -#define pcg16i_random_r pcg_setseq_16_rxs_m_xs_16_random_r -#define pcg32i_random_r pcg_setseq_32_rxs_m_xs_32_random_r -#define pcg64i_random_r pcg_setseq_64_rxs_m_xs_64_random_r -//// boundedrand_r -#define pcg8i_boundedrand_r pcg_setseq_8_rxs_m_xs_8_boundedrand_r -#define pcg16i_boundedrand_r pcg_setseq_16_rxs_m_xs_16_boundedrand_r -#define pcg32i_boundedrand_r pcg_setseq_32_rxs_m_xs_32_boundedrand_r -#define pcg64i_boundedrand_r pcg_setseq_64_rxs_m_xs_64_boundedrand_r -//// srandom_r -#define pcg8i_srandom_r pcg_setseq_8_srandom_r -#define pcg16i_srandom_r pcg_setseq_16_srandom_r -#define pcg32i_srandom_r pcg_setseq_32_srandom_r -#define pcg64i_srandom_r pcg_setseq_64_srandom_r -//// advance_r -#define pcg8i_advance_r pcg_setseq_8_advance_r -#define pcg16i_advance_r pcg_setseq_16_advance_r -#define pcg32i_advance_r pcg_setseq_32_advance_r -#define pcg64i_advance_r pcg_setseq_64_advance_r - -#if PCG_HAS_128BIT_OPS -typedef struct pcg_state_setseq_128 pcg128i_random_t; -#define pcg128i_random_r pcg_setseq_128_rxs_m_xs_128_random_r -#define pcg128i_boundedrand_r pcg_setseq_128_rxs_m_xs_128_boundedrand_r -#define pcg128i_srandom_r pcg_setseq_128_srandom_r -#define pcg128i_advance_r pcg_setseq_128_advance_r -#endif - -extern uint32_t pcg32_random(); -extern uint32_t pcg32_boundedrand(uint32_t bound); -extern void pcg32_srandom(uint64_t seed, uint64_t seq); -extern void pcg32_advance(uint64_t delta); - -#if PCG_HAS_128BIT_OPS -extern uint64_t pcg64_random(); -extern uint64_t pcg64_boundedrand(uint64_t bound); -extern void pcg64_srandom(pcg128_t seed, pcg128_t seq); -extern void pcg64_advance(pcg128_t delta); -#endif - -/* - * Static initialization constants (if you can't call srandom for some - * bizarre reason). - */ - -#define PCG32_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER -#define PCG32U_INITIALIZER PCG_STATE_UNIQUE_64_INITIALIZER -#define PCG32S_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER -#define PCG32F_INITIALIZER PCG_STATE_MCG_64_INITIALIZER - -#if PCG_HAS_128BIT_OPS -#define PCG64_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER -#define PCG64U_INITIALIZER PCG_STATE_UNIQUE_128_INITIALIZER -#define PCG64S_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER -#define PCG64F_INITIALIZER PCG_STATE_MCG_128_INITIALIZER -#endif - -#define PCG8SI_INITIALIZER PCG_STATE_ONESEQ_8_INITIALIZER -#define PCG16SI_INITIALIZER PCG_STATE_ONESEQ_16_INITIALIZER -#define PCG32SI_INITIALIZER PCG_STATE_ONESEQ_32_INITIALIZER -#define PCG64SI_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER -#if PCG_HAS_128BIT_OPS -#define PCG128SI_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER -#endif - -#define PCG8I_INITIALIZER PCG_STATE_SETSEQ_8_INITIALIZER -#define PCG16I_INITIALIZER PCG_STATE_SETSEQ_16_INITIALIZER -#define PCG32I_INITIALIZER PCG_STATE_SETSEQ_32_INITIALIZER -#define PCG64I_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER -#if PCG_HAS_128BIT_OPS -#define PCG128I_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER -#endif - -#if __cplusplus -} -#endif - -#endif // PCG_VARIANTS_H_INCLUDED diff --git a/numpy/random/src/pcg64/LICENSE.md b/numpy/random/src/pcg64/LICENSE.md deleted file mode 100644 index dd6a17ee8..000000000 --- a/numpy/random/src/pcg64/LICENSE.md +++ /dev/null @@ -1,22 +0,0 @@ -# PCG64 - -PCG Random Number Generation for C. - -Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -For additional information about the PCG random number generation scheme, -including its license and other licensing options, visit - - http://www.pcg-random.org diff --git a/numpy/random/src/pcg64/pcg64-benchmark.c b/numpy/random/src/pcg64/pcg64-benchmark.c deleted file mode 100644 index 76f3ec78c..000000000 --- a/numpy/random/src/pcg64/pcg64-benchmark.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * cl pcg64-benchmark.c pcg64.c ../splitmix64/splitmix64.c /Ox - * Measure-Command { .\xoroshiro128-benchmark.exe } - * - * gcc pcg64-benchmark.c pcg64.c ../splitmix64/splitmix64.c -O3 -o - * pcg64-benchmark - * time ./pcg64-benchmark - */ -#include "../splitmix64/splitmix64.h" -#include "pcg64.h" -#include <inttypes.h> -#include <stdio.h> -#include <time.h> - -#define N 1000000000 - -int main() { - pcg64_random_t rng; - uint64_t sum = 0, count = 0; - uint64_t seed = 0xDEADBEAF; - int i; -#if __SIZEOF_INT128__ && !defined(PCG_FORCE_EMULATED_128BIT_MATH) - rng.state = (__uint128_t)splitmix64_next(&seed) << 64; - rng.state |= splitmix64_next(&seed); - rng.inc = (__uint128_t)1; -#else - rng.state.high = splitmix64_next(&seed); - rng.state.low = splitmix64_next(&seed); - rng.inc.high = 0; - rng.inc.low = 1; -#endif - clock_t begin = clock(); - for (i = 0; i < N; i++) { - sum += pcg64_random_r(&rng); - count++; - } - clock_t end = clock(); - double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; - printf("0x%" PRIx64 "\ncount: %" PRIu64 "\n", sum, count); - printf("%" PRIu64 " randoms per second\n", - (uint64_t)(N / time_spent) / 1000000 * 1000000); -} diff --git a/numpy/random/src/pcg64/pcg64-test-data-gen.c b/numpy/random/src/pcg64/pcg64-test-data-gen.c deleted file mode 100644 index 0c2b079a3..000000000 --- a/numpy/random/src/pcg64/pcg64-test-data-gen.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Generate testing csv files - * - * GCC only - * - * gcc pcg64-test-data-gen.c pcg64.orig.c ../splitmix64/splitmix64.c -o - * pgc64-test-data-gen - */ - -#include "pcg64.orig.h" -#include <inttypes.h> -#include <stdio.h> - -#define N 1000 - -int main() { - pcg64_random_t rng; - uint64_t state, seed = 0xDEADBEAF; - state = seed; - __uint128_t temp, s, inc; - int i; - uint64_t store[N]; - s = (__uint128_t)seed; - inc = (__uint128_t)0; - pcg64_srandom_r(&rng, s, inc); - printf("0x%" PRIx64, (uint64_t)(rng.state >> 64)); - printf("%" PRIx64 "\n", (uint64_t)rng.state); - printf("0x%" PRIx64, (uint64_t)(rng.inc >> 64)); - printf("%" PRIx64 "\n", (uint64_t)rng.inc); - for (i = 0; i < N; i++) { - store[i] = pcg64_random_r(&rng); - } - - FILE *fp; - fp = fopen("pcg64-testset-1.csv", "w"); - if (fp == NULL) { - printf("Couldn't open file\n"); - return -1; - } - fprintf(fp, "seed, 0x%" PRIx64 "\n", seed); - for (i = 0; i < N; i++) { - fprintf(fp, "%d, 0x%" PRIx64 "\n", i, store[i]); - if (i == 999) { - printf("%d, 0x%" PRIx64 "\n", i, store[i]); - } - } - fclose(fp); - - state = seed = 0; - s = (__uint128_t)seed; - i = (__uint128_t)0; - pcg64_srandom_r(&rng, s, i); - printf("0x%" PRIx64, (uint64_t)(rng.state >> 64)); - printf("%" PRIx64 "\n", (uint64_t)rng.state); - printf("0x%" PRIx64, (uint64_t)(rng.inc >> 64)); - printf("%" PRIx64 "\n", (uint64_t)rng.inc); - for (i = 0; i < N; i++) { - store[i] = pcg64_random_r(&rng); - } - fp = fopen("pcg64-testset-2.csv", "w"); - if (fp == NULL) { - printf("Couldn't open file\n"); - return -1; - } - fprintf(fp, "seed, 0x%" PRIx64 "\n", seed); - for (i = 0; i < N; i++) { - fprintf(fp, "%d, 0x%" PRIx64 "\n", i, store[i]); - if (i == 999) { - printf("%d, 0x%" PRIx64 "\n", i, store[i]); - } - } - fclose(fp); -} diff --git a/numpy/random/src/pcg64/pcg64.c b/numpy/random/src/pcg64/pcg64.c deleted file mode 100644 index faec0c248..000000000 --- a/numpy/random/src/pcg64/pcg64.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * PCG64 Random Number Generation for C. - * - * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> - * Copyright 2015 Robert Kern <robert.kern@gmail.com> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * For additional information about the PCG random number generation scheme, - * including its license and other licensing options, visit - * - * http://www.pcg-random.org - */ - -#include "pcg64.h" - -extern inline void pcg_setseq_128_step_r(pcg_state_setseq_128 *rng); -extern inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state); -extern inline void pcg_setseq_128_srandom_r(pcg_state_setseq_128 *rng, - pcg128_t initstate, - pcg128_t initseq); -extern inline uint64_t -pcg_setseq_128_xsl_rr_64_random_r(pcg_state_setseq_128 *rng); -extern inline uint64_t -pcg_setseq_128_xsl_rr_64_boundedrand_r(pcg_state_setseq_128 *rng, - uint64_t bound); -extern inline void pcg_setseq_128_advance_r(pcg_state_setseq_128 *rng, - pcg128_t delta); - -/* Multi-step advance functions (jump-ahead, jump-back) - * - * The method used here is based on Brown, "Random Number Generation - * with Arbitrary Stride,", Transactions of the American Nuclear - * Society (Nov. 1994). The algorithm is very similar to fast - * exponentiation. - * - * Even though delta is an unsigned integer, we can pass a - * signed integer to go backwards, it just goes "the long way round". - */ - -#ifndef PCG_EMULATED_128BIT_MATH - -pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta, pcg128_t cur_mult, - pcg128_t cur_plus) { - pcg128_t acc_mult = 1u; - pcg128_t acc_plus = 0u; - while (delta > 0) { - if (delta & 1) { - acc_mult *= cur_mult; - acc_plus = acc_plus * cur_mult + cur_plus; - } - cur_plus = (cur_mult + 1) * cur_plus; - cur_mult *= cur_mult; - delta /= 2; - } - return acc_mult * state + acc_plus; -} - -#else - -pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta, pcg128_t cur_mult, - pcg128_t cur_plus) { - pcg128_t acc_mult = PCG_128BIT_CONSTANT(0u, 1u); - pcg128_t acc_plus = PCG_128BIT_CONSTANT(0u, 0u); - while ((delta.high > 0) || (delta.low > 0)) { - if (delta.low & 1) { - acc_mult = _pcg128_mult(acc_mult, cur_mult); - acc_plus = _pcg128_add(_pcg128_mult(acc_plus, cur_mult), cur_plus); - } - cur_plus = _pcg128_mult(_pcg128_add(cur_mult, PCG_128BIT_CONSTANT(0u, 1u)), - cur_plus); - cur_mult = _pcg128_mult(cur_mult, cur_mult); - delta.low >>= 1; - delta.low += delta.high & 1; - delta.high >>= 1; - } - return _pcg128_add(_pcg128_mult(acc_mult, state), acc_plus); -} - -#endif - -extern inline uint64_t pcg64_next64(pcg64_state *state); -extern inline uint32_t pcg64_next32(pcg64_state *state); - -extern void pcg64_advance(pcg64_state *state, uint64_t *step) { - pcg128_t delta; -#if __SIZEOF_INT128__ && !defined(PCG_FORCE_EMULATED_128BIT_MATH) - delta = (((pcg128_t)step[0]) << 64) | step[1]; -#else - delta.high = step[0]; - delta.low = step[1]; -#endif - pcg64_advance_r(state->pcg_state, delta); -} - -extern void pcg64_set_seed(pcg64_state *state, uint64_t *seed, uint64_t *inc) { - pcg128_t s, i; -#if __SIZEOF_INT128__ && !defined(PCG_FORCE_EMULATED_128BIT_MATH) - s = (((pcg128_t)seed[0]) << 64) | seed[1]; - i = (((pcg128_t)inc[0]) << 64) | inc[1]; -#else - s.high = seed[0]; - s.low = seed[1]; - i.high = inc[0]; - i.low = inc[1]; -#endif - pcg64_srandom_r(state->pcg_state, s, i); -} - -extern void pcg64_get_state(pcg64_state *state, uint64_t *state_arr, - int *has_uint32, uint32_t *uinteger) { - /* - * state_arr contains state.high, state.low, inc.high, inc.low - * which are interpreted as the upper 64 bits (high) or lower - * 64 bits of a uint128_t variable - * - */ -#if __SIZEOF_INT128__ && !defined(PCG_FORCE_EMULATED_128BIT_MATH) - state_arr[0] = (uint64_t)(state->pcg_state->state >> 64); - state_arr[1] = (uint64_t)(state->pcg_state->state & 0xFFFFFFFFFFFFFFFFULL); - state_arr[2] = (uint64_t)(state->pcg_state->inc >> 64); - state_arr[3] = (uint64_t)(state->pcg_state->inc & 0xFFFFFFFFFFFFFFFFULL); -#else - state_arr[0] = (uint64_t)state->pcg_state->state.high; - state_arr[1] = (uint64_t)state->pcg_state->state.low; - state_arr[2] = (uint64_t)state->pcg_state->inc.high; - state_arr[3] = (uint64_t)state->pcg_state->inc.low; -#endif - has_uint32[0] = state->has_uint32; - uinteger[0] = state->uinteger; -} - -extern void pcg64_set_state(pcg64_state *state, uint64_t *state_arr, - int has_uint32, uint32_t uinteger) { - /* - * state_arr contains state.high, state.low, inc.high, inc.low - * which are interpreted as the upper 64 bits (high) or lower - * 64 bits of a uint128_t variable - * - */ -#if __SIZEOF_INT128__ && !defined(PCG_FORCE_EMULATED_128BIT_MATH) - state->pcg_state->state = (((pcg128_t)state_arr[0]) << 64) | state_arr[1]; - state->pcg_state->inc = (((pcg128_t)state_arr[2]) << 64) | state_arr[3]; -#else - state->pcg_state->state.high = state_arr[0]; - state->pcg_state->state.low = state_arr[1]; - state->pcg_state->inc.high = state_arr[2]; - state->pcg_state->inc.low = state_arr[3]; -#endif - state->has_uint32 = has_uint32; - state->uinteger = uinteger; -} diff --git a/numpy/random/src/pcg64/pcg64.h b/numpy/random/src/pcg64/pcg64.h deleted file mode 100644 index e42dc4d63..000000000 --- a/numpy/random/src/pcg64/pcg64.h +++ /dev/null @@ -1,246 +0,0 @@ -/* - * PCG64 Random Number Generation for C. - * - * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> - * Copyright 2015 Robert Kern <robert.kern@gmail.com> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * For additional information about the PCG random number generation scheme, - * including its license and other licensing options, visit - * - * http://www.pcg-random.org - */ - -#ifndef PCG64_H_INCLUDED -#define PCG64_H_INCLUDED 1 - -#ifdef _WIN32 -#ifndef _INTTYPES -#include "../common/stdint.h" -#endif -#define inline __inline __forceinline -#else -#include <inttypes.h> -#if _MSC_VER >= 1900 && _M_AMD64 -#include <intrin.h> -#pragma intrinsic(_umul128) -#endif -#endif - -#if __GNUC_GNU_INLINE__ && !defined(__cplusplus) -#error Nonstandard GNU inlining semantics. Compile with -std=c99 or better. -#endif - -#if __cplusplus -extern "C" { -#endif - -#if __SIZEOF_INT128__ && !defined(PCG_FORCE_EMULATED_128BIT_MATH) -typedef __uint128_t pcg128_t; -#define PCG_128BIT_CONSTANT(high, low) (((pcg128_t)(high) << 64) + low) -#else -typedef struct { - uint64_t high; - uint64_t low; -} pcg128_t; - -static inline pcg128_t PCG_128BIT_CONSTANT(uint64_t high, uint64_t low) { - pcg128_t result; - result.high = high; - result.low = low; - return result; -} - -#define PCG_EMULATED_128BIT_MATH 1 -#endif - -typedef struct { pcg128_t state; } pcg_state_128; - -typedef struct { - pcg128_t state; - pcg128_t inc; -} pcg_state_setseq_128; - -#define PCG_DEFAULT_MULTIPLIER_128 \ - PCG_128BIT_CONSTANT(2549297995355413924ULL, 4865540595714422341ULL) -#define PCG_DEFAULT_INCREMENT_128 \ - PCG_128BIT_CONSTANT(6364136223846793005ULL, 1442695040888963407ULL) -#define PCG_STATE_SETSEQ_128_INITIALIZER \ - { \ - PCG_128BIT_CONSTANT(0x979c9a98d8462005ULL, 0x7d3e9cb6cfe0549bULL) \ - , PCG_128BIT_CONSTANT(0x0000000000000001ULL, 0xda3e39cb94b95bdbULL) \ - } - -static inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot) { - return (value >> rot) | (value << ((-rot) & 63)); -} - -#ifdef PCG_EMULATED_128BIT_MATH - -static inline pcg128_t _pcg128_add(pcg128_t a, pcg128_t b) { - pcg128_t result; - - result.low = a.low + b.low; - result.high = a.high + b.high + (result.low < b.low); - return result; -} - -static inline void _pcg_mult64(uint64_t x, uint64_t y, uint64_t *z1, - uint64_t *z0) { - -#if defined _WIN32 && _MSC_VER >= 1900 && _M_AMD64 - z0[0] = _umul128(x, y, z1); -#else - uint64_t x0, x1, y0, y1; - uint64_t w0, w1, w2, t; - /* Lower 64 bits are straightforward clock-arithmetic. */ - *z0 = x * y; - - x0 = x & 0xFFFFFFFFULL; - x1 = x >> 32; - y0 = y & 0xFFFFFFFFULL; - y1 = y >> 32; - w0 = x0 * y0; - t = x1 * y0 + (w0 >> 32); - w1 = t & 0xFFFFFFFFULL; - w2 = t >> 32; - w1 += x0 * y1; - *z1 = x1 * y1 + w2 + (w1 >> 32); -#endif -} - -static inline pcg128_t _pcg128_mult(pcg128_t a, pcg128_t b) { - uint64_t h1; - pcg128_t result; - - h1 = a.high * b.low + a.low * b.high; - _pcg_mult64(a.low, b.low, &(result.high), &(result.low)); - result.high += h1; - return result; -} - -static inline void pcg_setseq_128_step_r(pcg_state_setseq_128 *rng) { - rng->state = _pcg128_add(_pcg128_mult(rng->state, PCG_DEFAULT_MULTIPLIER_128), - rng->inc); -} - -static inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state) { - return pcg_rotr_64(state.high ^ state.low, state.high >> 58u); -} - -static inline void pcg_setseq_128_srandom_r(pcg_state_setseq_128 *rng, - pcg128_t initstate, - pcg128_t initseq) { - rng->state = PCG_128BIT_CONSTANT(0ULL, 0ULL); - rng->inc.high = initseq.high << 1u; - rng->inc.high |= initseq.low & 0x800000000000ULL; - rng->inc.low = (initseq.low << 1u) | 1u; - pcg_setseq_128_step_r(rng); - rng->state = _pcg128_add(rng->state, initstate); - pcg_setseq_128_step_r(rng); -} - -#else /* PCG_EMULATED_128BIT_MATH */ - -static inline void pcg_setseq_128_step_r(pcg_state_setseq_128 *rng) { - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 + rng->inc; -} - -static inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state) { - return pcg_rotr_64(((uint64_t)(state >> 64u)) ^ (uint64_t)state, - state >> 122u); -} - -static inline void pcg_setseq_128_srandom_r(pcg_state_setseq_128 *rng, - pcg128_t initstate, - pcg128_t initseq) { - rng->state = 0U; - rng->inc = (initseq << 1u) | 1u; - pcg_setseq_128_step_r(rng); - rng->state += initstate; - pcg_setseq_128_step_r(rng); -} - -#endif /* PCG_EMULATED_128BIT_MATH */ - -static inline uint64_t -pcg_setseq_128_xsl_rr_64_random_r(pcg_state_setseq_128 *rng) { - pcg_setseq_128_step_r(rng); - return pcg_output_xsl_rr_128_64(rng->state); -} - -static inline uint64_t -pcg_setseq_128_xsl_rr_64_boundedrand_r(pcg_state_setseq_128 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_setseq_128_xsl_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -extern pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta, - pcg128_t cur_mult, pcg128_t cur_plus); - -static inline void pcg_setseq_128_advance_r(pcg_state_setseq_128 *rng, - pcg128_t delta) { - rng->state = pcg_advance_lcg_128(rng->state, delta, - PCG_DEFAULT_MULTIPLIER_128, rng->inc); -} - -typedef pcg_state_setseq_128 pcg64_random_t; -#define pcg64_random_r pcg_setseq_128_xsl_rr_64_random_r -#define pcg64_boundedrand_r pcg_setseq_128_xsl_rr_64_boundedrand_r -#define pcg64_srandom_r pcg_setseq_128_srandom_r -#define pcg64_advance_r pcg_setseq_128_advance_r -#define PCG64_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER - -#if __cplusplus -} -#endif - -typedef struct s_pcg64_state { - pcg64_random_t *pcg_state; - int has_uint32; - uint32_t uinteger; -} pcg64_state; - -static inline uint64_t pcg64_next64(pcg64_state *state) { - return pcg64_random_r(state->pcg_state); -} - -static inline uint32_t pcg64_next32(pcg64_state *state) { - uint64_t next; - if (state->has_uint32) { - state->has_uint32 = 0; - return state->uinteger; - } - next = pcg64_random_r(state->pcg_state); - state->has_uint32 = 1; - state->uinteger = (uint32_t)(next >> 32); - return (uint32_t)(next & 0xffffffff); -} - -void pcg64_advance(pcg64_state *state, uint64_t *step); - -void pcg64_set_seed(pcg64_state *state, uint64_t *seed, uint64_t *inc); - -void pcg64_get_state(pcg64_state *state, uint64_t *state_arr, int *has_uint32, - uint32_t *uinteger); - -void pcg64_set_state(pcg64_state *state, uint64_t *state_arr, int has_uint32, - uint32_t uinteger); - -#endif /* PCG64_H_INCLUDED */ diff --git a/numpy/random/src/pcg64/pcg64.orig.c b/numpy/random/src/pcg64/pcg64.orig.c deleted file mode 100644 index 07e97e4b6..000000000 --- a/numpy/random/src/pcg64/pcg64.orig.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "pcg64.orig.h" - -extern inline void pcg_setseq_128_srandom_r(pcg64_random_t *rng, - pcg128_t initstate, - pcg128_t initseq); - -extern uint64_t pcg_rotr_64(uint64_t value, unsigned int rot); -extern inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state); -extern void pcg_setseq_128_step_r(struct pcg_state_setseq_128 *rng); -extern uint64_t -pcg_setseq_128_xsl_rr_64_random_r(struct pcg_state_setseq_128 *rng); diff --git a/numpy/random/src/pcg64/pcg64.orig.h b/numpy/random/src/pcg64/pcg64.orig.h deleted file mode 100644 index 74be91f31..000000000 --- a/numpy/random/src/pcg64/pcg64.orig.h +++ /dev/null @@ -1,2025 +0,0 @@ -/* - * PCG Random Number Generation for C. - * - * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * For additional information about the PCG random number generation scheme, - * including its license and other licensing options, visit - * - * http://www.pcg-random.org - */ - -/* - * This code is derived from the canonical C++ PCG implementation, which - * has many additional features and is preferable if you can use C++ in - * your project. - * - * Much of the derivation was performed mechanically. In particular, the - * output functions were generated by compiling the C++ output functions - * into LLVM bitcode and then transforming that using the LLVM C backend - * (from https://github.com/draperlaboratory/llvm-cbe), and then - * postprocessing and hand editing the output. - * - * Much of the remaining code was generated by C-preprocessor metaprogramming. - */ - -#ifndef PCG_VARIANTS_H_INCLUDED -#define PCG_VARIANTS_H_INCLUDED 1 - -#include <inttypes.h> - -#if __SIZEOF_INT128__ -typedef __uint128_t pcg128_t; -#define PCG_128BIT_CONSTANT(high, low) ((((pcg128_t)high) << 64) + low) -#define PCG_HAS_128BIT_OPS 1 -#endif - -#if __GNUC_GNU_INLINE__ && !defined(__cplusplus) -#error Nonstandard GNU inlining semantics. Compile with -std=c99 or better. -// We could instead use macros PCG_INLINE and PCG_EXTERN_INLINE -// but better to just reject ancient C code. -#endif - -#if __cplusplus -extern "C" { -#endif - -/* - * Rotate helper functions. - */ - -inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot) { -/* Unfortunately, clang is kinda pathetic when it comes to properly - * recognizing idiomatic rotate code, so for clang we actually provide - * assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss. - */ -#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) - asm("rorb %%cl, %0" : "=r"(value) : "0"(value), "c"(rot)); - return value; -#else - return (value >> rot) | (value << ((-rot) & 7)); -#endif -} - -inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot) { -#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) - asm("rorw %%cl, %0" : "=r"(value) : "0"(value), "c"(rot)); - return value; -#else - return (value >> rot) | (value << ((-rot) & 15)); -#endif -} - -inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot) { -#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) - asm("rorl %%cl, %0" : "=r"(value) : "0"(value), "c"(rot)); - return value; -#else - return (value >> rot) | (value << ((-rot) & 31)); -#endif -} - -inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot) { -#if 0 && PCG_USE_INLINE_ASM && __clang__ && __x86_64__ - // For whatever reason, clang actually *does* generate rotq by - // itself, so we don't need this code. - asm ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); - return value; -#else - return (value >> rot) | (value << ((-rot) & 63)); -#endif -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t pcg_rotr_128(pcg128_t value, unsigned int rot) { - return (value >> rot) | (value << ((-rot) & 127)); -} -#endif - -/* - * Output functions. These are the core of the PCG generation scheme. - */ - -// XSH RS - -inline uint8_t pcg_output_xsh_rs_16_8(uint16_t state) { - return (uint8_t)(((state >> 7u) ^ state) >> ((state >> 14u) + 3u)); -} - -inline uint16_t pcg_output_xsh_rs_32_16(uint32_t state) { - return (uint16_t)(((state >> 11u) ^ state) >> ((state >> 30u) + 11u)); -} - -inline uint32_t pcg_output_xsh_rs_64_32(uint64_t state) { - - return (uint32_t)(((state >> 22u) ^ state) >> ((state >> 61u) + 22u)); -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_output_xsh_rs_128_64(pcg128_t state) { - return (uint64_t)(((state >> 43u) ^ state) >> ((state >> 124u) + 45u)); -} -#endif - -// XSH RR - -inline uint8_t pcg_output_xsh_rr_16_8(uint16_t state) { - return pcg_rotr_8(((state >> 5u) ^ state) >> 5u, state >> 13u); -} - -inline uint16_t pcg_output_xsh_rr_32_16(uint32_t state) { - return pcg_rotr_16(((state >> 10u) ^ state) >> 12u, state >> 28u); -} - -inline uint32_t pcg_output_xsh_rr_64_32(uint64_t state) { - return pcg_rotr_32(((state >> 18u) ^ state) >> 27u, state >> 59u); -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_output_xsh_rr_128_64(pcg128_t state) { - return pcg_rotr_64(((state >> 29u) ^ state) >> 58u, state >> 122u); -} -#endif - -// RXS M XS - -inline uint8_t pcg_output_rxs_m_xs_8_8(uint8_t state) { - uint8_t word = ((state >> ((state >> 6u) + 2u)) ^ state) * 217u; - return (word >> 6u) ^ word; -} - -inline uint16_t pcg_output_rxs_m_xs_16_16(uint16_t state) { - uint16_t word = ((state >> ((state >> 13u) + 3u)) ^ state) * 62169u; - return (word >> 11u) ^ word; -} - -inline uint32_t pcg_output_rxs_m_xs_32_32(uint32_t state) { - uint32_t word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u; - return (word >> 22u) ^ word; -} - -inline uint64_t pcg_output_rxs_m_xs_64_64(uint64_t state) { - uint64_t word = - ((state >> ((state >> 59u) + 5u)) ^ state) * 12605985483714917081ull; - return (word >> 43u) ^ word; -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t pcg_output_rxs_m_xs_128_128(pcg128_t state) { - pcg128_t word = - ((state >> ((state >> 122u) + 6u)) ^ state) * - (PCG_128BIT_CONSTANT(17766728186571221404ULL, 12605985483714917081ULL)); - // 327738287884841127335028083622016905945 - return (word >> 86u) ^ word; -} -#endif - -// XSL RR (only defined for >= 64 bits) - -inline uint32_t pcg_output_xsl_rr_64_32(uint64_t state) { - return pcg_rotr_32(((uint32_t)(state >> 32u)) ^ (uint32_t)state, - state >> 59u); -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state) { - return pcg_rotr_64(((uint64_t)(state >> 64u)) ^ (uint64_t)state, - state >> 122u); -} -#endif - -// XSL RR RR (only defined for >= 64 bits) - -inline uint64_t pcg_output_xsl_rr_rr_64_64(uint64_t state) { - uint32_t rot1 = (uint32_t)(state >> 59u); - uint32_t high = (uint32_t)(state >> 32u); - uint32_t low = (uint32_t)state; - uint32_t xored = high ^ low; - uint32_t newlow = pcg_rotr_32(xored, rot1); - uint32_t newhigh = pcg_rotr_32(high, newlow & 31u); - return (((uint64_t)newhigh) << 32u) | newlow; -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t pcg_output_xsl_rr_rr_128_128(pcg128_t state) { - uint32_t rot1 = (uint32_t)(state >> 122u); - uint64_t high = (uint64_t)(state >> 64u); - uint64_t low = (uint64_t)state; - uint64_t xored = high ^ low; - uint64_t newlow = pcg_rotr_64(xored, rot1); - uint64_t newhigh = pcg_rotr_64(high, newlow & 63u); - return (((pcg128_t)newhigh) << 64u) | newlow; -} -#endif - -#define PCG_DEFAULT_MULTIPLIER_8 141U -#define PCG_DEFAULT_MULTIPLIER_16 12829U -#define PCG_DEFAULT_MULTIPLIER_32 747796405U -#define PCG_DEFAULT_MULTIPLIER_64 6364136223846793005ULL - -#define PCG_DEFAULT_INCREMENT_8 77U -#define PCG_DEFAULT_INCREMENT_16 47989U -#define PCG_DEFAULT_INCREMENT_32 2891336453U -#define PCG_DEFAULT_INCREMENT_64 1442695040888963407ULL - -#if PCG_HAS_128BIT_OPS -#define PCG_DEFAULT_MULTIPLIER_128 \ - PCG_128BIT_CONSTANT(2549297995355413924ULL, 4865540595714422341ULL) -#define PCG_DEFAULT_INCREMENT_128 \ - PCG_128BIT_CONSTANT(6364136223846793005ULL, 1442695040888963407ULL) -#endif - - /* - * Static initialization constants (if you can't call srandom for some - * bizarre reason). - */ - -#define PCG_STATE_ONESEQ_8_INITIALIZER \ - { 0xd7U } -#define PCG_STATE_ONESEQ_16_INITIALIZER \ - { 0x20dfU } -#define PCG_STATE_ONESEQ_32_INITIALIZER \ - { 0x46b56677U } -#define PCG_STATE_ONESEQ_64_INITIALIZER \ - { 0x4d595df4d0f33173ULL } -#if PCG_HAS_128BIT_OPS -#define PCG_STATE_ONESEQ_128_INITIALIZER \ - { PCG_128BIT_CONSTANT(0xb8dc10e158a92392ULL, 0x98046df007ec0a53ULL) } -#endif - -#define PCG_STATE_UNIQUE_8_INITIALIZER PCG_STATE_ONESEQ_8_INITIALIZER -#define PCG_STATE_UNIQUE_16_INITIALIZER PCG_STATE_ONESEQ_16_INITIALIZER -#define PCG_STATE_UNIQUE_32_INITIALIZER PCG_STATE_ONESEQ_32_INITIALIZER -#define PCG_STATE_UNIQUE_64_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER -#if PCG_HAS_128BIT_OPS -#define PCG_STATE_UNIQUE_128_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER -#endif - -#define PCG_STATE_MCG_8_INITIALIZER \ - { 0xe5U } -#define PCG_STATE_MCG_16_INITIALIZER \ - { 0xa5e5U } -#define PCG_STATE_MCG_32_INITIALIZER \ - { 0xd15ea5e5U } -#define PCG_STATE_MCG_64_INITIALIZER \ - { 0xcafef00dd15ea5e5ULL } -#if PCG_HAS_128BIT_OPS -#define PCG_STATE_MCG_128_INITIALIZER \ - { PCG_128BIT_CONSTANT(0x0000000000000000ULL, 0xcafef00dd15ea5e5ULL) } -#endif - -#define PCG_STATE_SETSEQ_8_INITIALIZER \ - { 0x9bU, 0xdbU } -#define PCG_STATE_SETSEQ_16_INITIALIZER \ - { 0xe39bU, 0x5bdbU } -#define PCG_STATE_SETSEQ_32_INITIALIZER \ - { 0xec02d89bU, 0x94b95bdbU } -#define PCG_STATE_SETSEQ_64_INITIALIZER \ - { 0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL } -#if PCG_HAS_128BIT_OPS -#define PCG_STATE_SETSEQ_128_INITIALIZER \ - { \ - PCG_128BIT_CONSTANT(0x979c9a98d8462005ULL, 0x7d3e9cb6cfe0549bULL) \ - , PCG_128BIT_CONSTANT(0x0000000000000001ULL, 0xda3e39cb94b95bdbULL) \ - } -#endif - -/* Representations for the oneseq, mcg, and unique variants */ - -struct pcg_state_8 { - uint8_t state; -}; - -struct pcg_state_16 { - uint16_t state; -}; - -struct pcg_state_32 { - uint32_t state; -}; - -struct pcg_state_64 { - uint64_t state; -}; - -#if PCG_HAS_128BIT_OPS -struct pcg_state_128 { - pcg128_t state; -}; -#endif - -/* Representations setseq variants */ - -struct pcg_state_setseq_8 { - uint8_t state; - uint8_t inc; -}; - -struct pcg_state_setseq_16 { - uint16_t state; - uint16_t inc; -}; - -struct pcg_state_setseq_32 { - uint32_t state; - uint32_t inc; -}; - -struct pcg_state_setseq_64 { - uint64_t state; - uint64_t inc; -}; - -#if PCG_HAS_128BIT_OPS -struct pcg_state_setseq_128 { - pcg128_t state; - pcg128_t inc; -}; -#endif - -/* Multi-step advance functions (jump-ahead, jump-back) */ - -extern uint8_t pcg_advance_lcg_8(uint8_t state, uint8_t delta, uint8_t cur_mult, - uint8_t cur_plus); -extern uint16_t pcg_advance_lcg_16(uint16_t state, uint16_t delta, - uint16_t cur_mult, uint16_t cur_plus); -extern uint32_t pcg_advance_lcg_32(uint32_t state, uint32_t delta, - uint32_t cur_mult, uint32_t cur_plus); -extern uint64_t pcg_advance_lcg_64(uint64_t state, uint64_t delta, - uint64_t cur_mult, uint64_t cur_plus); - -#if PCG_HAS_128BIT_OPS -extern pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta, - pcg128_t cur_mult, pcg128_t cur_plus); -#endif - -/* Functions to advance the underlying LCG, one version for each size and - * each style. These functions are considered semi-private. There is rarely - * a good reason to call them directly. - */ - -inline void pcg_oneseq_8_step_r(struct pcg_state_8 *rng) { - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8 + PCG_DEFAULT_INCREMENT_8; -} - -inline void pcg_oneseq_8_advance_r(struct pcg_state_8 *rng, uint8_t delta) { - rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, - PCG_DEFAULT_INCREMENT_8); -} - -inline void pcg_mcg_8_step_r(struct pcg_state_8 *rng) { - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8; -} - -inline void pcg_mcg_8_advance_r(struct pcg_state_8 *rng, uint8_t delta) { - rng->state = - pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, 0u); -} - -inline void pcg_unique_8_step_r(struct pcg_state_8 *rng) { - rng->state = - rng->state * PCG_DEFAULT_MULTIPLIER_8 + (uint8_t)(((intptr_t)rng) | 1u); -} - -inline void pcg_unique_8_advance_r(struct pcg_state_8 *rng, uint8_t delta) { - rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, - (uint8_t)(((intptr_t)rng) | 1u)); -} - -inline void pcg_setseq_8_step_r(struct pcg_state_setseq_8 *rng) { - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8 + rng->inc; -} - -inline void pcg_setseq_8_advance_r(struct pcg_state_setseq_8 *rng, - uint8_t delta) { - rng->state = - pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, rng->inc); -} - -inline void pcg_oneseq_16_step_r(struct pcg_state_16 *rng) { - rng->state = - rng->state * PCG_DEFAULT_MULTIPLIER_16 + PCG_DEFAULT_INCREMENT_16; -} - -inline void pcg_oneseq_16_advance_r(struct pcg_state_16 *rng, uint16_t delta) { - rng->state = pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, - PCG_DEFAULT_INCREMENT_16); -} - -inline void pcg_mcg_16_step_r(struct pcg_state_16 *rng) { - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16; -} - -inline void pcg_mcg_16_advance_r(struct pcg_state_16 *rng, uint16_t delta) { - rng->state = - pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, 0u); -} - -inline void pcg_unique_16_step_r(struct pcg_state_16 *rng) { - rng->state = - rng->state * PCG_DEFAULT_MULTIPLIER_16 + (uint16_t)(((intptr_t)rng) | 1u); -} - -inline void pcg_unique_16_advance_r(struct pcg_state_16 *rng, uint16_t delta) { - rng->state = pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, - (uint16_t)(((intptr_t)rng) | 1u)); -} - -inline void pcg_setseq_16_step_r(struct pcg_state_setseq_16 *rng) { - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16 + rng->inc; -} - -inline void pcg_setseq_16_advance_r(struct pcg_state_setseq_16 *rng, - uint16_t delta) { - rng->state = pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, - rng->inc); -} - -inline void pcg_oneseq_32_step_r(struct pcg_state_32 *rng) { - rng->state = - rng->state * PCG_DEFAULT_MULTIPLIER_32 + PCG_DEFAULT_INCREMENT_32; -} - -inline void pcg_oneseq_32_advance_r(struct pcg_state_32 *rng, uint32_t delta) { - rng->state = pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, - PCG_DEFAULT_INCREMENT_32); -} - -inline void pcg_mcg_32_step_r(struct pcg_state_32 *rng) { - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32; -} - -inline void pcg_mcg_32_advance_r(struct pcg_state_32 *rng, uint32_t delta) { - rng->state = - pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, 0u); -} - -inline void pcg_unique_32_step_r(struct pcg_state_32 *rng) { - rng->state = - rng->state * PCG_DEFAULT_MULTIPLIER_32 + (uint32_t)(((intptr_t)rng) | 1u); -} - -inline void pcg_unique_32_advance_r(struct pcg_state_32 *rng, uint32_t delta) { - rng->state = pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, - (uint32_t)(((intptr_t)rng) | 1u)); -} - -inline void pcg_setseq_32_step_r(struct pcg_state_setseq_32 *rng) { - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32 + rng->inc; -} - -inline void pcg_setseq_32_advance_r(struct pcg_state_setseq_32 *rng, - uint32_t delta) { - rng->state = pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, - rng->inc); -} - -inline void pcg_oneseq_64_step_r(struct pcg_state_64 *rng) { - rng->state = - rng->state * PCG_DEFAULT_MULTIPLIER_64 + PCG_DEFAULT_INCREMENT_64; -} - -inline void pcg_oneseq_64_advance_r(struct pcg_state_64 *rng, uint64_t delta) { - rng->state = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, - PCG_DEFAULT_INCREMENT_64); -} - -inline void pcg_mcg_64_step_r(struct pcg_state_64 *rng) { - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64; -} - -inline void pcg_mcg_64_advance_r(struct pcg_state_64 *rng, uint64_t delta) { - rng->state = - pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, 0u); -} - -inline void pcg_unique_64_step_r(struct pcg_state_64 *rng) { - rng->state = - rng->state * PCG_DEFAULT_MULTIPLIER_64 + (uint64_t)(((intptr_t)rng) | 1u); -} - -inline void pcg_unique_64_advance_r(struct pcg_state_64 *rng, uint64_t delta) { - rng->state = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, - (uint64_t)(((intptr_t)rng) | 1u)); -} - -inline void pcg_setseq_64_step_r(struct pcg_state_setseq_64 *rng) { - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 + rng->inc; -} - -inline void pcg_setseq_64_advance_r(struct pcg_state_setseq_64 *rng, - uint64_t delta) { - rng->state = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, - rng->inc); -} - -#if PCG_HAS_128BIT_OPS -inline void pcg_oneseq_128_step_r(struct pcg_state_128 *rng) { - rng->state = - rng->state * PCG_DEFAULT_MULTIPLIER_128 + PCG_DEFAULT_INCREMENT_128; -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_oneseq_128_advance_r(struct pcg_state_128 *rng, - pcg128_t delta) { - rng->state = pcg_advance_lcg_128( - rng->state, delta, PCG_DEFAULT_MULTIPLIER_128, PCG_DEFAULT_INCREMENT_128); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_mcg_128_step_r(struct pcg_state_128 *rng) { - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128; -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_mcg_128_advance_r(struct pcg_state_128 *rng, pcg128_t delta) { - rng->state = - pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128, 0u); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_unique_128_step_r(struct pcg_state_128 *rng) { - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 + - (pcg128_t)(((intptr_t)rng) | 1u); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_unique_128_advance_r(struct pcg_state_128 *rng, - pcg128_t delta) { - rng->state = - pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128, - (pcg128_t)(((intptr_t)rng) | 1u)); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_setseq_128_step_r(struct pcg_state_setseq_128 *rng) { - rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 + rng->inc; -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_setseq_128_advance_r(struct pcg_state_setseq_128 *rng, - pcg128_t delta) { - rng->state = pcg_advance_lcg_128(rng->state, delta, - PCG_DEFAULT_MULTIPLIER_128, rng->inc); -} -#endif - -/* Functions to seed the RNG state, one version for each size and each - * style. Unlike the step functions, regular users can and should call - * these functions. - */ - -inline void pcg_oneseq_8_srandom_r(struct pcg_state_8 *rng, uint8_t initstate) { - rng->state = 0U; - pcg_oneseq_8_step_r(rng); - rng->state += initstate; - pcg_oneseq_8_step_r(rng); -} - -inline void pcg_mcg_8_srandom_r(struct pcg_state_8 *rng, uint8_t initstate) { - rng->state = initstate | 1u; -} - -inline void pcg_unique_8_srandom_r(struct pcg_state_8 *rng, uint8_t initstate) { - rng->state = 0U; - pcg_unique_8_step_r(rng); - rng->state += initstate; - pcg_unique_8_step_r(rng); -} - -inline void pcg_setseq_8_srandom_r(struct pcg_state_setseq_8 *rng, - uint8_t initstate, uint8_t initseq) { - rng->state = 0U; - rng->inc = (initseq << 1u) | 1u; - pcg_setseq_8_step_r(rng); - rng->state += initstate; - pcg_setseq_8_step_r(rng); -} - -inline void pcg_oneseq_16_srandom_r(struct pcg_state_16 *rng, - uint16_t initstate) { - rng->state = 0U; - pcg_oneseq_16_step_r(rng); - rng->state += initstate; - pcg_oneseq_16_step_r(rng); -} - -inline void pcg_mcg_16_srandom_r(struct pcg_state_16 *rng, uint16_t initstate) { - rng->state = initstate | 1u; -} - -inline void pcg_unique_16_srandom_r(struct pcg_state_16 *rng, - uint16_t initstate) { - rng->state = 0U; - pcg_unique_16_step_r(rng); - rng->state += initstate; - pcg_unique_16_step_r(rng); -} - -inline void pcg_setseq_16_srandom_r(struct pcg_state_setseq_16 *rng, - uint16_t initstate, uint16_t initseq) { - rng->state = 0U; - rng->inc = (initseq << 1u) | 1u; - pcg_setseq_16_step_r(rng); - rng->state += initstate; - pcg_setseq_16_step_r(rng); -} - -inline void pcg_oneseq_32_srandom_r(struct pcg_state_32 *rng, - uint32_t initstate) { - rng->state = 0U; - pcg_oneseq_32_step_r(rng); - rng->state += initstate; - pcg_oneseq_32_step_r(rng); -} - -inline void pcg_mcg_32_srandom_r(struct pcg_state_32 *rng, uint32_t initstate) { - rng->state = initstate | 1u; -} - -inline void pcg_unique_32_srandom_r(struct pcg_state_32 *rng, - uint32_t initstate) { - rng->state = 0U; - pcg_unique_32_step_r(rng); - rng->state += initstate; - pcg_unique_32_step_r(rng); -} - -inline void pcg_setseq_32_srandom_r(struct pcg_state_setseq_32 *rng, - uint32_t initstate, uint32_t initseq) { - rng->state = 0U; - rng->inc = (initseq << 1u) | 1u; - pcg_setseq_32_step_r(rng); - rng->state += initstate; - pcg_setseq_32_step_r(rng); -} - -inline void pcg_oneseq_64_srandom_r(struct pcg_state_64 *rng, - uint64_t initstate) { - rng->state = 0U; - pcg_oneseq_64_step_r(rng); - rng->state += initstate; - pcg_oneseq_64_step_r(rng); -} - -inline void pcg_mcg_64_srandom_r(struct pcg_state_64 *rng, uint64_t initstate) { - rng->state = initstate | 1u; -} - -inline void pcg_unique_64_srandom_r(struct pcg_state_64 *rng, - uint64_t initstate) { - rng->state = 0U; - pcg_unique_64_step_r(rng); - rng->state += initstate; - pcg_unique_64_step_r(rng); -} - -inline void pcg_setseq_64_srandom_r(struct pcg_state_setseq_64 *rng, - uint64_t initstate, uint64_t initseq) { - rng->state = 0U; - rng->inc = (initseq << 1u) | 1u; - pcg_setseq_64_step_r(rng); - rng->state += initstate; - pcg_setseq_64_step_r(rng); -} - -#if PCG_HAS_128BIT_OPS -inline void pcg_oneseq_128_srandom_r(struct pcg_state_128 *rng, - pcg128_t initstate) { - rng->state = 0U; - pcg_oneseq_128_step_r(rng); - rng->state += initstate; - pcg_oneseq_128_step_r(rng); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_mcg_128_srandom_r(struct pcg_state_128 *rng, - pcg128_t initstate) { - rng->state = initstate | 1u; -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_unique_128_srandom_r(struct pcg_state_128 *rng, - pcg128_t initstate) { - rng->state = 0U; - pcg_unique_128_step_r(rng); - rng->state += initstate; - pcg_unique_128_step_r(rng); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline void pcg_setseq_128_srandom_r(struct pcg_state_setseq_128 *rng, - pcg128_t initstate, pcg128_t initseq) { - rng->state = 0U; - rng->inc = (initseq << 1u) | 1u; - pcg_setseq_128_step_r(rng); - rng->state += initstate; - pcg_setseq_128_step_r(rng); -} -#endif - -/* Now, finally we create each of the individual generators. We provide - * a random_r function that provides a random number of the appropriate - * type (using the full range of the type) and a boundedrand_r version - * that provides - * - * Implementation notes for boundedrand_r: - * - * To avoid bias, we need to make the range of the RNG a multiple of - * bound, which we do by dropping output less than a threshold. - * Let's consider a 32-bit case... A naive scheme to calculate the - * threshold would be to do - * - * uint32_t threshold = 0x100000000ull % bound; - * - * but 64-bit div/mod is slower than 32-bit div/mod (especially on - * 32-bit platforms). In essence, we do - * - * uint32_t threshold = (0x100000000ull-bound) % bound; - * - * because this version will calculate the same modulus, but the LHS - * value is less than 2^32. - * - * (Note that using modulo is only wise for good RNGs, poorer RNGs - * such as raw LCGs do better using a technique based on division.) - * Empricical tests show that division is preferable to modulus for - * reducting the range of an RNG. It's faster, and sometimes it can - * even be statistically prefereable. - */ - -/* Generation functions for XSH RS */ - -inline uint8_t pcg_oneseq_16_xsh_rs_8_random_r(struct pcg_state_16 *rng) { - uint16_t oldstate = rng->state; - pcg_oneseq_16_step_r(rng); - return pcg_output_xsh_rs_16_8(oldstate); -} - -inline uint8_t pcg_oneseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_16 *rng, - uint8_t bound) { - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_oneseq_16_xsh_rs_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t pcg_oneseq_32_xsh_rs_16_random_r(struct pcg_state_32 *rng) { - uint32_t oldstate = rng->state; - pcg_oneseq_32_step_r(rng); - return pcg_output_xsh_rs_32_16(oldstate); -} - -inline uint16_t pcg_oneseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_32 *rng, - uint16_t bound) { - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_oneseq_32_xsh_rs_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_oneseq_64_xsh_rs_32_random_r(struct pcg_state_64 *rng) { - uint64_t oldstate = rng->state; - pcg_oneseq_64_step_r(rng); - return pcg_output_xsh_rs_64_32(oldstate); -} - -inline uint32_t pcg_oneseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_64 *rng, - uint32_t bound) { - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_oneseq_64_xsh_rs_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_oneseq_128_xsh_rs_64_random_r(struct pcg_state_128 *rng) { - pcg_oneseq_128_step_r(rng); - return pcg_output_xsh_rs_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_oneseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_128 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_oneseq_128_xsh_rs_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint8_t pcg_unique_16_xsh_rs_8_random_r(struct pcg_state_16 *rng) { - uint16_t oldstate = rng->state; - pcg_unique_16_step_r(rng); - return pcg_output_xsh_rs_16_8(oldstate); -} - -inline uint8_t pcg_unique_16_xsh_rs_8_boundedrand_r(struct pcg_state_16 *rng, - uint8_t bound) { - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_unique_16_xsh_rs_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t pcg_unique_32_xsh_rs_16_random_r(struct pcg_state_32 *rng) { - uint32_t oldstate = rng->state; - pcg_unique_32_step_r(rng); - return pcg_output_xsh_rs_32_16(oldstate); -} - -inline uint16_t pcg_unique_32_xsh_rs_16_boundedrand_r(struct pcg_state_32 *rng, - uint16_t bound) { - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_unique_32_xsh_rs_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_unique_64_xsh_rs_32_random_r(struct pcg_state_64 *rng) { - uint64_t oldstate = rng->state; - pcg_unique_64_step_r(rng); - return pcg_output_xsh_rs_64_32(oldstate); -} - -inline uint32_t pcg_unique_64_xsh_rs_32_boundedrand_r(struct pcg_state_64 *rng, - uint32_t bound) { - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_unique_64_xsh_rs_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_unique_128_xsh_rs_64_random_r(struct pcg_state_128 *rng) { - pcg_unique_128_step_r(rng); - return pcg_output_xsh_rs_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_unique_128_xsh_rs_64_boundedrand_r(struct pcg_state_128 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_unique_128_xsh_rs_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint8_t -pcg_setseq_16_xsh_rs_8_random_r(struct pcg_state_setseq_16 *rng) { - uint16_t oldstate = rng->state; - pcg_setseq_16_step_r(rng); - return pcg_output_xsh_rs_16_8(oldstate); -} - -inline uint8_t -pcg_setseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_setseq_16 *rng, - uint8_t bound) { - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_setseq_16_xsh_rs_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t -pcg_setseq_32_xsh_rs_16_random_r(struct pcg_state_setseq_32 *rng) { - uint32_t oldstate = rng->state; - pcg_setseq_32_step_r(rng); - return pcg_output_xsh_rs_32_16(oldstate); -} - -inline uint16_t -pcg_setseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_setseq_32 *rng, - uint16_t bound) { - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_setseq_32_xsh_rs_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t -pcg_setseq_64_xsh_rs_32_random_r(struct pcg_state_setseq_64 *rng) { - uint64_t oldstate = rng->state; - pcg_setseq_64_step_r(rng); - return pcg_output_xsh_rs_64_32(oldstate); -} - -inline uint32_t -pcg_setseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_setseq_64 *rng, - uint32_t bound) { - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_setseq_64_xsh_rs_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_setseq_128_xsh_rs_64_random_r(struct pcg_state_setseq_128 *rng) { - pcg_setseq_128_step_r(rng); - return pcg_output_xsh_rs_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_setseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_setseq_128 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_setseq_128_xsh_rs_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint8_t pcg_mcg_16_xsh_rs_8_random_r(struct pcg_state_16 *rng) { - uint16_t oldstate = rng->state; - pcg_mcg_16_step_r(rng); - return pcg_output_xsh_rs_16_8(oldstate); -} - -inline uint8_t pcg_mcg_16_xsh_rs_8_boundedrand_r(struct pcg_state_16 *rng, - uint8_t bound) { - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_mcg_16_xsh_rs_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t pcg_mcg_32_xsh_rs_16_random_r(struct pcg_state_32 *rng) { - uint32_t oldstate = rng->state; - pcg_mcg_32_step_r(rng); - return pcg_output_xsh_rs_32_16(oldstate); -} - -inline uint16_t pcg_mcg_32_xsh_rs_16_boundedrand_r(struct pcg_state_32 *rng, - uint16_t bound) { - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_mcg_32_xsh_rs_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_mcg_64_xsh_rs_32_random_r(struct pcg_state_64 *rng) { - uint64_t oldstate = rng->state; - pcg_mcg_64_step_r(rng); - return pcg_output_xsh_rs_64_32(oldstate); -} - -inline uint32_t pcg_mcg_64_xsh_rs_32_boundedrand_r(struct pcg_state_64 *rng, - uint32_t bound) { - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_mcg_64_xsh_rs_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_mcg_128_xsh_rs_64_random_r(struct pcg_state_128 *rng) { - pcg_mcg_128_step_r(rng); - return pcg_output_xsh_rs_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_mcg_128_xsh_rs_64_boundedrand_r(struct pcg_state_128 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_mcg_128_xsh_rs_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -/* Generation functions for XSH RR */ - -inline uint8_t pcg_oneseq_16_xsh_rr_8_random_r(struct pcg_state_16 *rng) { - uint16_t oldstate = rng->state; - pcg_oneseq_16_step_r(rng); - return pcg_output_xsh_rr_16_8(oldstate); -} - -inline uint8_t pcg_oneseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_16 *rng, - uint8_t bound) { - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_oneseq_16_xsh_rr_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t pcg_oneseq_32_xsh_rr_16_random_r(struct pcg_state_32 *rng) { - uint32_t oldstate = rng->state; - pcg_oneseq_32_step_r(rng); - return pcg_output_xsh_rr_32_16(oldstate); -} - -inline uint16_t pcg_oneseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_32 *rng, - uint16_t bound) { - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_oneseq_32_xsh_rr_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_oneseq_64_xsh_rr_32_random_r(struct pcg_state_64 *rng) { - uint64_t oldstate = rng->state; - pcg_oneseq_64_step_r(rng); - return pcg_output_xsh_rr_64_32(oldstate); -} - -inline uint32_t pcg_oneseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_64 *rng, - uint32_t bound) { - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_oneseq_64_xsh_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_oneseq_128_xsh_rr_64_random_r(struct pcg_state_128 *rng) { - pcg_oneseq_128_step_r(rng); - return pcg_output_xsh_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_oneseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_128 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_oneseq_128_xsh_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint8_t pcg_unique_16_xsh_rr_8_random_r(struct pcg_state_16 *rng) { - uint16_t oldstate = rng->state; - pcg_unique_16_step_r(rng); - return pcg_output_xsh_rr_16_8(oldstate); -} - -inline uint8_t pcg_unique_16_xsh_rr_8_boundedrand_r(struct pcg_state_16 *rng, - uint8_t bound) { - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_unique_16_xsh_rr_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t pcg_unique_32_xsh_rr_16_random_r(struct pcg_state_32 *rng) { - uint32_t oldstate = rng->state; - pcg_unique_32_step_r(rng); - return pcg_output_xsh_rr_32_16(oldstate); -} - -inline uint16_t pcg_unique_32_xsh_rr_16_boundedrand_r(struct pcg_state_32 *rng, - uint16_t bound) { - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_unique_32_xsh_rr_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_unique_64_xsh_rr_32_random_r(struct pcg_state_64 *rng) { - uint64_t oldstate = rng->state; - pcg_unique_64_step_r(rng); - return pcg_output_xsh_rr_64_32(oldstate); -} - -inline uint32_t pcg_unique_64_xsh_rr_32_boundedrand_r(struct pcg_state_64 *rng, - uint32_t bound) { - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_unique_64_xsh_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_unique_128_xsh_rr_64_random_r(struct pcg_state_128 *rng) { - pcg_unique_128_step_r(rng); - return pcg_output_xsh_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_unique_128_xsh_rr_64_boundedrand_r(struct pcg_state_128 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_unique_128_xsh_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint8_t -pcg_setseq_16_xsh_rr_8_random_r(struct pcg_state_setseq_16 *rng) { - uint16_t oldstate = rng->state; - pcg_setseq_16_step_r(rng); - return pcg_output_xsh_rr_16_8(oldstate); -} - -inline uint8_t -pcg_setseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_setseq_16 *rng, - uint8_t bound) { - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_setseq_16_xsh_rr_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t -pcg_setseq_32_xsh_rr_16_random_r(struct pcg_state_setseq_32 *rng) { - uint32_t oldstate = rng->state; - pcg_setseq_32_step_r(rng); - return pcg_output_xsh_rr_32_16(oldstate); -} - -inline uint16_t -pcg_setseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_setseq_32 *rng, - uint16_t bound) { - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_setseq_32_xsh_rr_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t -pcg_setseq_64_xsh_rr_32_random_r(struct pcg_state_setseq_64 *rng) { - uint64_t oldstate = rng->state; - pcg_setseq_64_step_r(rng); - return pcg_output_xsh_rr_64_32(oldstate); -} - -inline uint32_t -pcg_setseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_setseq_64 *rng, - uint32_t bound) { - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_setseq_64_xsh_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_setseq_128_xsh_rr_64_random_r(struct pcg_state_setseq_128 *rng) { - pcg_setseq_128_step_r(rng); - return pcg_output_xsh_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_setseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_setseq_128 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_setseq_128_xsh_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint8_t pcg_mcg_16_xsh_rr_8_random_r(struct pcg_state_16 *rng) { - uint16_t oldstate = rng->state; - pcg_mcg_16_step_r(rng); - return pcg_output_xsh_rr_16_8(oldstate); -} - -inline uint8_t pcg_mcg_16_xsh_rr_8_boundedrand_r(struct pcg_state_16 *rng, - uint8_t bound) { - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_mcg_16_xsh_rr_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t pcg_mcg_32_xsh_rr_16_random_r(struct pcg_state_32 *rng) { - uint32_t oldstate = rng->state; - pcg_mcg_32_step_r(rng); - return pcg_output_xsh_rr_32_16(oldstate); -} - -inline uint16_t pcg_mcg_32_xsh_rr_16_boundedrand_r(struct pcg_state_32 *rng, - uint16_t bound) { - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_mcg_32_xsh_rr_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_mcg_64_xsh_rr_32_random_r(struct pcg_state_64 *rng) { - uint64_t oldstate = rng->state; - pcg_mcg_64_step_r(rng); - return pcg_output_xsh_rr_64_32(oldstate); -} - -inline uint32_t pcg_mcg_64_xsh_rr_32_boundedrand_r(struct pcg_state_64 *rng, - uint32_t bound) { - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_mcg_64_xsh_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_mcg_128_xsh_rr_64_random_r(struct pcg_state_128 *rng) { - pcg_mcg_128_step_r(rng); - return pcg_output_xsh_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_mcg_128_xsh_rr_64_boundedrand_r(struct pcg_state_128 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_mcg_128_xsh_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -/* Generation functions for RXS M XS (no MCG versions because they - * don't make sense when you want to use the entire state) - */ - -inline uint8_t pcg_oneseq_8_rxs_m_xs_8_random_r(struct pcg_state_8 *rng) { - uint8_t oldstate = rng->state; - pcg_oneseq_8_step_r(rng); - return pcg_output_rxs_m_xs_8_8(oldstate); -} - -inline uint8_t pcg_oneseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_8 *rng, - uint8_t bound) { - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_oneseq_8_rxs_m_xs_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t pcg_oneseq_16_rxs_m_xs_16_random_r(struct pcg_state_16 *rng) { - uint16_t oldstate = rng->state; - pcg_oneseq_16_step_r(rng); - return pcg_output_rxs_m_xs_16_16(oldstate); -} - -inline uint16_t -pcg_oneseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16 *rng, - uint16_t bound) { - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_oneseq_16_rxs_m_xs_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_oneseq_32_rxs_m_xs_32_random_r(struct pcg_state_32 *rng) { - uint32_t oldstate = rng->state; - pcg_oneseq_32_step_r(rng); - return pcg_output_rxs_m_xs_32_32(oldstate); -} - -inline uint32_t -pcg_oneseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32 *rng, - uint32_t bound) { - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_oneseq_32_rxs_m_xs_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint64_t pcg_oneseq_64_rxs_m_xs_64_random_r(struct pcg_state_64 *rng) { - uint64_t oldstate = rng->state; - pcg_oneseq_64_step_r(rng); - return pcg_output_rxs_m_xs_64_64(oldstate); -} - -inline uint64_t -pcg_oneseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_oneseq_64_rxs_m_xs_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_oneseq_128_rxs_m_xs_128_random_r(struct pcg_state_128 *rng) { - pcg_oneseq_128_step_r(rng); - return pcg_output_rxs_m_xs_128_128(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_oneseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128 *rng, - pcg128_t bound) { - pcg128_t threshold = -bound % bound; - for (;;) { - pcg128_t r = pcg_oneseq_128_rxs_m_xs_128_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint16_t pcg_unique_16_rxs_m_xs_16_random_r(struct pcg_state_16 *rng) { - uint16_t oldstate = rng->state; - pcg_unique_16_step_r(rng); - return pcg_output_rxs_m_xs_16_16(oldstate); -} - -inline uint16_t -pcg_unique_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16 *rng, - uint16_t bound) { - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_unique_16_rxs_m_xs_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t pcg_unique_32_rxs_m_xs_32_random_r(struct pcg_state_32 *rng) { - uint32_t oldstate = rng->state; - pcg_unique_32_step_r(rng); - return pcg_output_rxs_m_xs_32_32(oldstate); -} - -inline uint32_t -pcg_unique_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32 *rng, - uint32_t bound) { - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_unique_32_rxs_m_xs_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint64_t pcg_unique_64_rxs_m_xs_64_random_r(struct pcg_state_64 *rng) { - uint64_t oldstate = rng->state; - pcg_unique_64_step_r(rng); - return pcg_output_rxs_m_xs_64_64(oldstate); -} - -inline uint64_t -pcg_unique_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_unique_64_rxs_m_xs_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_unique_128_rxs_m_xs_128_random_r(struct pcg_state_128 *rng) { - pcg_unique_128_step_r(rng); - return pcg_output_rxs_m_xs_128_128(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_unique_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128 *rng, - pcg128_t bound) { - pcg128_t threshold = -bound % bound; - for (;;) { - pcg128_t r = pcg_unique_128_rxs_m_xs_128_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint8_t -pcg_setseq_8_rxs_m_xs_8_random_r(struct pcg_state_setseq_8 *rng) { - uint8_t oldstate = rng->state; - pcg_setseq_8_step_r(rng); - return pcg_output_rxs_m_xs_8_8(oldstate); -} - -inline uint8_t -pcg_setseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_setseq_8 *rng, - uint8_t bound) { - uint8_t threshold = ((uint8_t)(-bound)) % bound; - for (;;) { - uint8_t r = pcg_setseq_8_rxs_m_xs_8_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint16_t -pcg_setseq_16_rxs_m_xs_16_random_r(struct pcg_state_setseq_16 *rng) { - uint16_t oldstate = rng->state; - pcg_setseq_16_step_r(rng); - return pcg_output_rxs_m_xs_16_16(oldstate); -} - -inline uint16_t -pcg_setseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_setseq_16 *rng, - uint16_t bound) { - uint16_t threshold = ((uint16_t)(-bound)) % bound; - for (;;) { - uint16_t r = pcg_setseq_16_rxs_m_xs_16_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint32_t -pcg_setseq_32_rxs_m_xs_32_random_r(struct pcg_state_setseq_32 *rng) { - uint32_t oldstate = rng->state; - pcg_setseq_32_step_r(rng); - return pcg_output_rxs_m_xs_32_32(oldstate); -} - -inline uint32_t -pcg_setseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_setseq_32 *rng, - uint32_t bound) { - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_setseq_32_rxs_m_xs_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -inline uint64_t -pcg_setseq_64_rxs_m_xs_64_random_r(struct pcg_state_setseq_64 *rng) { - uint64_t oldstate = rng->state; - pcg_setseq_64_step_r(rng); - return pcg_output_rxs_m_xs_64_64(oldstate); -} - -inline uint64_t -pcg_setseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_setseq_64 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_setseq_64_rxs_m_xs_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_setseq_128_rxs_m_xs_128_random_r(struct pcg_state_setseq_128 *rng) { - pcg_setseq_128_step_r(rng); - return pcg_output_rxs_m_xs_128_128(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_setseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_setseq_128 *rng, - pcg128_t bound) { - pcg128_t threshold = -bound % bound; - for (;;) { - pcg128_t r = pcg_setseq_128_rxs_m_xs_128_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -/* Generation functions for XSL RR (only defined for "large" types) */ - -inline uint32_t pcg_oneseq_64_xsl_rr_32_random_r(struct pcg_state_64 *rng) { - uint64_t oldstate = rng->state; - pcg_oneseq_64_step_r(rng); - return pcg_output_xsl_rr_64_32(oldstate); -} - -inline uint32_t pcg_oneseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_64 *rng, - uint32_t bound) { - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_oneseq_64_xsl_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_oneseq_128_xsl_rr_64_random_r(struct pcg_state_128 *rng) { - pcg_oneseq_128_step_r(rng); - return pcg_output_xsl_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_oneseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_128 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_oneseq_128_xsl_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint32_t pcg_unique_64_xsl_rr_32_random_r(struct pcg_state_64 *rng) { - uint64_t oldstate = rng->state; - pcg_unique_64_step_r(rng); - return pcg_output_xsl_rr_64_32(oldstate); -} - -inline uint32_t pcg_unique_64_xsl_rr_32_boundedrand_r(struct pcg_state_64 *rng, - uint32_t bound) { - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_unique_64_xsl_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_unique_128_xsl_rr_64_random_r(struct pcg_state_128 *rng) { - pcg_unique_128_step_r(rng); - return pcg_output_xsl_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_unique_128_xsl_rr_64_boundedrand_r(struct pcg_state_128 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_unique_128_xsl_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint32_t -pcg_setseq_64_xsl_rr_32_random_r(struct pcg_state_setseq_64 *rng) { - uint64_t oldstate = rng->state; - pcg_setseq_64_step_r(rng); - return pcg_output_xsl_rr_64_32(oldstate); -} - -inline uint32_t -pcg_setseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_setseq_64 *rng, - uint32_t bound) { - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_setseq_64_xsl_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_setseq_128_xsl_rr_64_random_r(struct pcg_state_setseq_128 *rng) { - pcg_setseq_128_step_r(rng); - return pcg_output_xsl_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t -pcg_setseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_setseq_128 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_setseq_128_xsl_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint32_t pcg_mcg_64_xsl_rr_32_random_r(struct pcg_state_64 *rng) { - uint64_t oldstate = rng->state; - pcg_mcg_64_step_r(rng); - return pcg_output_xsl_rr_64_32(oldstate); -} - -inline uint32_t pcg_mcg_64_xsl_rr_32_boundedrand_r(struct pcg_state_64 *rng, - uint32_t bound) { - uint32_t threshold = -bound % bound; - for (;;) { - uint32_t r = pcg_mcg_64_xsl_rr_32_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_mcg_128_xsl_rr_64_random_r(struct pcg_state_128 *rng) { - pcg_mcg_128_step_r(rng); - return pcg_output_xsl_rr_128_64(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline uint64_t pcg_mcg_128_xsl_rr_64_boundedrand_r(struct pcg_state_128 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_mcg_128_xsl_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -/* Generation functions for XSL RR RR (only defined for "large" types) */ - -inline uint64_t pcg_oneseq_64_xsl_rr_rr_64_random_r(struct pcg_state_64 *rng) { - uint64_t oldstate = rng->state; - pcg_oneseq_64_step_r(rng); - return pcg_output_xsl_rr_rr_64_64(oldstate); -} - -inline uint64_t -pcg_oneseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_oneseq_64_xsl_rr_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_oneseq_128_xsl_rr_rr_128_random_r(struct pcg_state_128 *rng) { - pcg_oneseq_128_step_r(rng); - return pcg_output_xsl_rr_rr_128_128(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_oneseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128 *rng, - pcg128_t bound) { - pcg128_t threshold = -bound % bound; - for (;;) { - pcg128_t r = pcg_oneseq_128_xsl_rr_rr_128_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint64_t pcg_unique_64_xsl_rr_rr_64_random_r(struct pcg_state_64 *rng) { - uint64_t oldstate = rng->state; - pcg_unique_64_step_r(rng); - return pcg_output_xsl_rr_rr_64_64(oldstate); -} - -inline uint64_t -pcg_unique_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_unique_64_xsl_rr_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_unique_128_xsl_rr_rr_128_random_r(struct pcg_state_128 *rng) { - pcg_unique_128_step_r(rng); - return pcg_output_xsl_rr_rr_128_128(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_unique_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128 *rng, - pcg128_t bound) { - pcg128_t threshold = -bound % bound; - for (;;) { - pcg128_t r = pcg_unique_128_xsl_rr_rr_128_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -inline uint64_t -pcg_setseq_64_xsl_rr_rr_64_random_r(struct pcg_state_setseq_64 *rng) { - uint64_t oldstate = rng->state; - pcg_setseq_64_step_r(rng); - return pcg_output_xsl_rr_rr_64_64(oldstate); -} - -inline uint64_t -pcg_setseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_setseq_64 *rng, - uint64_t bound) { - uint64_t threshold = -bound % bound; - for (;;) { - uint64_t r = pcg_setseq_64_xsl_rr_rr_64_random_r(rng); - if (r >= threshold) - return r % bound; - } -} - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_setseq_128_xsl_rr_rr_128_random_r(struct pcg_state_setseq_128 *rng) { - pcg_setseq_128_step_r(rng); - return pcg_output_xsl_rr_rr_128_128(rng->state); -} -#endif - -#if PCG_HAS_128BIT_OPS -inline pcg128_t -pcg_setseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_setseq_128 *rng, - pcg128_t bound) { - pcg128_t threshold = -bound % bound; - for (;;) { - pcg128_t r = pcg_setseq_128_xsl_rr_rr_128_random_r(rng); - if (r >= threshold) - return r % bound; - } -} -#endif - -//// Typedefs -typedef struct pcg_state_setseq_64 pcg32_random_t; -typedef struct pcg_state_64 pcg32s_random_t; -typedef struct pcg_state_64 pcg32u_random_t; -typedef struct pcg_state_64 pcg32f_random_t; -//// random_r -#define pcg32_random_r pcg_setseq_64_xsh_rr_32_random_r -#define pcg32s_random_r pcg_oneseq_64_xsh_rr_32_random_r -#define pcg32u_random_r pcg_unique_64_xsh_rr_32_random_r -#define pcg32f_random_r pcg_mcg_64_xsh_rs_32_random_r -//// boundedrand_r -#define pcg32_boundedrand_r pcg_setseq_64_xsh_rr_32_boundedrand_r -#define pcg32s_boundedrand_r pcg_oneseq_64_xsh_rr_32_boundedrand_r -#define pcg32u_boundedrand_r pcg_unique_64_xsh_rr_32_boundedrand_r -#define pcg32f_boundedrand_r pcg_mcg_64_xsh_rs_32_boundedrand_r -//// srandom_r -#define pcg32_srandom_r pcg_setseq_64_srandom_r -#define pcg32s_srandom_r pcg_oneseq_64_srandom_r -#define pcg32u_srandom_r pcg_unique_64_srandom_r -#define pcg32f_srandom_r pcg_mcg_64_srandom_r -//// advance_r -#define pcg32_advance_r pcg_setseq_64_advance_r -#define pcg32s_advance_r pcg_oneseq_64_advance_r -#define pcg32u_advance_r pcg_unique_64_advance_r -#define pcg32f_advance_r pcg_mcg_64_advance_r - -#if PCG_HAS_128BIT_OPS -//// Typedefs -typedef struct pcg_state_setseq_128 pcg64_random_t; -typedef struct pcg_state_128 pcg64s_random_t; -typedef struct pcg_state_128 pcg64u_random_t; -typedef struct pcg_state_128 pcg64f_random_t; -//// random_r -#define pcg64_random_r pcg_setseq_128_xsl_rr_64_random_r -#define pcg64s_random_r pcg_oneseq_128_xsl_rr_64_random_r -#define pcg64u_random_r pcg_unique_128_xsl_rr_64_random_r -#define pcg64f_random_r pcg_mcg_128_xsl_rr_64_random_r -//// boundedrand_r -#define pcg64_boundedrand_r pcg_setseq_128_xsl_rr_64_boundedrand_r -#define pcg64s_boundedrand_r pcg_oneseq_128_xsl_rr_64_boundedrand_r -#define pcg64u_boundedrand_r pcg_unique_128_xsl_rr_64_boundedrand_r -#define pcg64f_boundedrand_r pcg_mcg_128_xsl_rr_64_boundedrand_r -//// srandom_r -#define pcg64_srandom_r pcg_setseq_128_srandom_r -#define pcg64s_srandom_r pcg_oneseq_128_srandom_r -#define pcg64u_srandom_r pcg_unique_128_srandom_r -#define pcg64f_srandom_r pcg_mcg_128_srandom_r -//// advance_r -#define pcg64_advance_r pcg_setseq_128_advance_r -#define pcg64s_advance_r pcg_oneseq_128_advance_r -#define pcg64u_advance_r pcg_unique_128_advance_r -#define pcg64f_advance_r pcg_mcg_128_advance_r -#endif - -//// Typedefs -typedef struct pcg_state_8 pcg8si_random_t; -typedef struct pcg_state_16 pcg16si_random_t; -typedef struct pcg_state_32 pcg32si_random_t; -typedef struct pcg_state_64 pcg64si_random_t; -//// random_r -#define pcg8si_random_r pcg_oneseq_8_rxs_m_xs_8_random_r -#define pcg16si_random_r pcg_oneseq_16_rxs_m_xs_16_random_r -#define pcg32si_random_r pcg_oneseq_32_rxs_m_xs_32_random_r -#define pcg64si_random_r pcg_oneseq_64_rxs_m_xs_64_random_r -//// boundedrand_r -#define pcg8si_boundedrand_r pcg_oneseq_8_rxs_m_xs_8_boundedrand_r -#define pcg16si_boundedrand_r pcg_oneseq_16_rxs_m_xs_16_boundedrand_r -#define pcg32si_boundedrand_r pcg_oneseq_32_rxs_m_xs_32_boundedrand_r -#define pcg64si_boundedrand_r pcg_oneseq_64_rxs_m_xs_64_boundedrand_r -//// srandom_r -#define pcg8si_srandom_r pcg_oneseq_8_srandom_r -#define pcg16si_srandom_r pcg_oneseq_16_srandom_r -#define pcg32si_srandom_r pcg_oneseq_32_srandom_r -#define pcg64si_srandom_r pcg_oneseq_64_srandom_r -//// advance_r -#define pcg8si_advance_r pcg_oneseq_8_advance_r -#define pcg16si_advance_r pcg_oneseq_16_advance_r -#define pcg32si_advance_r pcg_oneseq_32_advance_r -#define pcg64si_advance_r pcg_oneseq_64_advance_r - -#if PCG_HAS_128BIT_OPS -typedef struct pcg_state_128 pcg128si_random_t; -#define pcg128si_random_r pcg_oneseq_128_rxs_m_xs_128_random_r -#define pcg128si_boundedrand_r pcg_oneseq_128_rxs_m_xs_128_boundedrand_r -#define pcg128si_srandom_r pcg_oneseq_128_srandom_r -#define pcg128si_advance_r pcg_oneseq_128_advance_r -#endif - -//// Typedefs -typedef struct pcg_state_setseq_8 pcg8i_random_t; -typedef struct pcg_state_setseq_16 pcg16i_random_t; -typedef struct pcg_state_setseq_32 pcg32i_random_t; -typedef struct pcg_state_setseq_64 pcg64i_random_t; -//// random_r -#define pcg8i_random_r pcg_setseq_8_rxs_m_xs_8_random_r -#define pcg16i_random_r pcg_setseq_16_rxs_m_xs_16_random_r -#define pcg32i_random_r pcg_setseq_32_rxs_m_xs_32_random_r -#define pcg64i_random_r pcg_setseq_64_rxs_m_xs_64_random_r -//// boundedrand_r -#define pcg8i_boundedrand_r pcg_setseq_8_rxs_m_xs_8_boundedrand_r -#define pcg16i_boundedrand_r pcg_setseq_16_rxs_m_xs_16_boundedrand_r -#define pcg32i_boundedrand_r pcg_setseq_32_rxs_m_xs_32_boundedrand_r -#define pcg64i_boundedrand_r pcg_setseq_64_rxs_m_xs_64_boundedrand_r -//// srandom_r -#define pcg8i_srandom_r pcg_setseq_8_srandom_r -#define pcg16i_srandom_r pcg_setseq_16_srandom_r -#define pcg32i_srandom_r pcg_setseq_32_srandom_r -#define pcg64i_srandom_r pcg_setseq_64_srandom_r -//// advance_r -#define pcg8i_advance_r pcg_setseq_8_advance_r -#define pcg16i_advance_r pcg_setseq_16_advance_r -#define pcg32i_advance_r pcg_setseq_32_advance_r -#define pcg64i_advance_r pcg_setseq_64_advance_r - -#if PCG_HAS_128BIT_OPS -typedef struct pcg_state_setseq_128 pcg128i_random_t; -#define pcg128i_random_r pcg_setseq_128_rxs_m_xs_128_random_r -#define pcg128i_boundedrand_r pcg_setseq_128_rxs_m_xs_128_boundedrand_r -#define pcg128i_srandom_r pcg_setseq_128_srandom_r -#define pcg128i_advance_r pcg_setseq_128_advance_r -#endif - -extern uint32_t pcg32_random(); -extern uint32_t pcg32_boundedrand(uint32_t bound); -extern void pcg32_srandom(uint64_t seed, uint64_t seq); -extern void pcg32_advance(uint64_t delta); - -#if PCG_HAS_128BIT_OPS -extern uint64_t pcg64_random(); -extern uint64_t pcg64_boundedrand(uint64_t bound); -extern void pcg64_srandom(pcg128_t seed, pcg128_t seq); -extern void pcg64_advance(pcg128_t delta); -#endif - -/* - * Static initialization constants (if you can't call srandom for some - * bizarre reason). - */ - -#define PCG32_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER -#define PCG32U_INITIALIZER PCG_STATE_UNIQUE_64_INITIALIZER -#define PCG32S_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER -#define PCG32F_INITIALIZER PCG_STATE_MCG_64_INITIALIZER - -#if PCG_HAS_128BIT_OPS -#define PCG64_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER -#define PCG64U_INITIALIZER PCG_STATE_UNIQUE_128_INITIALIZER -#define PCG64S_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER -#define PCG64F_INITIALIZER PCG_STATE_MCG_128_INITIALIZER -#endif - -#define PCG8SI_INITIALIZER PCG_STATE_ONESEQ_8_INITIALIZER -#define PCG16SI_INITIALIZER PCG_STATE_ONESEQ_16_INITIALIZER -#define PCG32SI_INITIALIZER PCG_STATE_ONESEQ_32_INITIALIZER -#define PCG64SI_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER -#if PCG_HAS_128BIT_OPS -#define PCG128SI_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER -#endif - -#define PCG8I_INITIALIZER PCG_STATE_SETSEQ_8_INITIALIZER -#define PCG16I_INITIALIZER PCG_STATE_SETSEQ_16_INITIALIZER -#define PCG32I_INITIALIZER PCG_STATE_SETSEQ_32_INITIALIZER -#define PCG64I_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER -#if PCG_HAS_128BIT_OPS -#define PCG128I_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER -#endif - -#if __cplusplus -} -#endif - -#endif // PCG_VARIANTS_H_INCLUDED diff --git a/numpy/random/src/philox/philox.c b/numpy/random/src/philox/philox.c index 3382c60d6..6f2fad5a4 100644 --- a/numpy/random/src/philox/philox.c +++ b/numpy/random/src/philox/philox.c @@ -1,8 +1,8 @@ #include "philox.h" -extern INLINE uint64_t philox_next64(philox_state *state); +extern NPY_INLINE uint64_t philox_next64(philox_state *state); -extern INLINE uint32_t philox_next32(philox_state *state); +extern NPY_INLINE uint32_t philox_next32(philox_state *state); extern void philox_jump(philox_state *state) { /* Advances state as-if 2^128 draws were made */ diff --git a/numpy/random/src/philox/philox.h b/numpy/random/src/philox/philox.h index 411404b55..ae6cf9308 100644 --- a/numpy/random/src/philox/philox.h +++ b/numpy/random/src/philox/philox.h @@ -2,12 +2,7 @@ #define _RANDOMDGEN__PHILOX_H_ #include <inttypes.h> - -#ifdef _WIN32 -#define INLINE __inline __forceinline -#else -#define INLINE inline -#endif +#include "numpy/npy_common.h" #define PHILOX_BUFFER_SIZE 4L @@ -23,7 +18,7 @@ typedef struct r123array4x64 philox4x64_ctr_t; typedef struct r123array2x64 philox4x64_key_t; typedef struct r123array2x64 philox4x64_ukey_t; -static INLINE struct r123array2x64 +static NPY_INLINE struct r123array2x64 _philox4x64bumpkey(struct r123array2x64 key) { key.v[0] += (0x9E3779B97F4A7C15ULL); key.v[1] += (0xBB67AE8584CAA73BULL); @@ -37,7 +32,7 @@ _philox4x64bumpkey(struct r123array2x64 key) { #pragma intrinsic(_umul128) #else #pragma intrinsic(__emulu) -static INLINE uint64_t _umul128(uint64_t a, uint64_t b, uint64_t *high) { +static NPY_INLINE uint64_t _umul128(uint64_t a, uint64_t b, uint64_t *high) { uint64_t a_lo, a_hi, b_lo, b_hi, a_x_b_hi, a_x_b_mid, a_x_b_lo, b_x_a_mid, carry_bit; @@ -60,18 +55,18 @@ static INLINE uint64_t _umul128(uint64_t a, uint64_t b, uint64_t *high) { return a_x_b_lo + ((a_x_b_mid + b_x_a_mid) << 32); } #endif -static INLINE uint64_t mulhilo64(uint64_t a, uint64_t b, uint64_t *hip) { +static NPY_INLINE uint64_t mulhilo64(uint64_t a, uint64_t b, uint64_t *hip) { return _umul128(a, b, hip); } #else #if __SIZEOF_INT128__ -static INLINE uint64_t mulhilo64(uint64_t a, uint64_t b, uint64_t *hip) { +static NPY_INLINE uint64_t mulhilo64(uint64_t a, uint64_t b, uint64_t *hip) { __uint128_t product = ((__uint128_t)a) * ((__uint128_t)b); *hip = product >> 64; return (uint64_t)product; } #else -static INLINE uint64_t _umul128(uint64_t a, uint64_t b, uint64_t *high) { +static NPY_INLINE uint64_t _umul128(uint64_t a, uint64_t b, uint64_t *high) { uint64_t a_lo, a_hi, b_lo, b_hi, a_x_b_hi, a_x_b_mid, a_x_b_lo, b_x_a_mid, carry_bit; @@ -93,16 +88,16 @@ static INLINE uint64_t _umul128(uint64_t a, uint64_t b, uint64_t *high) { return a_x_b_lo + ((a_x_b_mid + b_x_a_mid) << 32); } -static INLINE uint64_t mulhilo64(uint64_t a, uint64_t b, uint64_t *hip) { +static NPY_INLINE uint64_t mulhilo64(uint64_t a, uint64_t b, uint64_t *hip) { return _umul128(a, b, hip); } #endif #endif -static INLINE struct r123array4x64 _philox4x64round(struct r123array4x64 ctr, +static NPY_INLINE struct r123array4x64 _philox4x64round(struct r123array4x64 ctr, struct r123array2x64 key); -static INLINE struct r123array4x64 _philox4x64round(struct r123array4x64 ctr, +static NPY_INLINE struct r123array4x64 _philox4x64round(struct r123array4x64 ctr, struct r123array2x64 key) { uint64_t hi0; uint64_t hi1; @@ -113,14 +108,14 @@ static INLINE struct r123array4x64 _philox4x64round(struct r123array4x64 ctr, return out; } -static INLINE philox4x64_key_t philox4x64keyinit(philox4x64_ukey_t uk) { +static NPY_INLINE philox4x64_key_t philox4x64keyinit(philox4x64_ukey_t uk) { return uk; } -static INLINE philox4x64_ctr_t philox4x64_R(unsigned int R, +static NPY_INLINE philox4x64_ctr_t philox4x64_R(unsigned int R, philox4x64_ctr_t ctr, philox4x64_key_t key); -static INLINE philox4x64_ctr_t philox4x64_R(unsigned int R, +static NPY_INLINE philox4x64_ctr_t philox4x64_R(unsigned int R, philox4x64_ctr_t ctr, philox4x64_key_t key) { if (R > 0) { @@ -198,7 +193,7 @@ typedef struct s_philox_state { uint32_t uinteger; } philox_state; -static INLINE uint64_t philox_next(philox_state *state) { +static NPY_INLINE uint64_t philox_next(philox_state *state) { uint64_t out; int i; philox4x64_ctr_t ct; @@ -228,11 +223,11 @@ static INLINE uint64_t philox_next(philox_state *state) { return state->buffer[0]; } -static INLINE uint64_t philox_next64(philox_state *state) { +static NPY_INLINE uint64_t philox_next64(philox_state *state) { return philox_next(state); } -static INLINE uint32_t philox_next32(philox_state *state) { +static NPY_INLINE uint32_t philox_next32(philox_state *state) { uint64_t next; if (state->has_uint32) { diff --git a/numpy/random/src/splitmix64/splitmix64.h b/numpy/random/src/splitmix64/splitmix64.h index 880132970..d5877905e 100644 --- a/numpy/random/src/splitmix64/splitmix64.h +++ b/numpy/random/src/splitmix64/splitmix64.h @@ -1,13 +1,4 @@ -#ifdef _WIN32 -#if _MSC_VER == 1500 -#include "../common/inttypes.h" -#define inline __forceinline -#else #include <inttypes.h> -#endif -#else -#include <inttypes.h> -#endif typedef struct s_splitmix64_state { uint64_t state; diff --git a/numpy/random/src/threefry/threefry.c b/numpy/random/src/threefry/threefry.c index 19c37df1b..55d3c022a 100644 --- a/numpy/random/src/threefry/threefry.c +++ b/numpy/random/src/threefry/threefry.c @@ -1,8 +1,8 @@ #include "threefry.h" -extern INLINE uint64_t threefry_next64(threefry_state *state); +extern NPY_INLINE uint64_t threefry_next64(threefry_state *state); -extern INLINE uint32_t threefry_next32(threefry_state *state); +extern NPY_INLINE uint32_t threefry_next32(threefry_state *state); extern void threefry_jump(threefry_state *state) { /* Advances state as-if 2^128 draws were made */ diff --git a/numpy/random/src/threefry/threefry.h b/numpy/random/src/threefry/threefry.h index 297c1241a..596b57e12 100644 --- a/numpy/random/src/threefry/threefry.h +++ b/numpy/random/src/threefry/threefry.h @@ -4,18 +4,8 @@ Adapted from random123's threefry.h #ifndef _RANDOMDGEN__THREEFRY_H_ #define _RANDOMDGEN__THREEFRY_H_ -#ifdef _WIN32 -#if _MSC_VER == 1500 -#include "../common/inttypes.h" -#define INLINE __forceinline -#else #include <inttypes.h> -#define INLINE __inline __forceinline -#endif -#else -#include <inttypes.h> -#define INLINE inline -#endif +#include "numpy/npy_common.h" #define THREEFRY_BUFFER_SIZE 4L @@ -47,15 +37,15 @@ struct r123array4x64 { typedef struct r123array4x64 threefry4x64_key_t; typedef struct r123array4x64 threefry4x64_ctr_t; -static INLINE uint64_t RotL_64(uint64_t x, unsigned int N); -static INLINE uint64_t RotL_64(uint64_t x, unsigned int N) { +static NPY_INLINE uint64_t RotL_64(uint64_t x, unsigned int N); +static NPY_INLINE uint64_t RotL_64(uint64_t x, unsigned int N) { return (x << (N & 63)) | (x >> ((64 - N) & 63)); } -static INLINE threefry4x64_ctr_t threefry4x64_R(unsigned int Nrounds, +static NPY_INLINE threefry4x64_ctr_t threefry4x64_R(unsigned int Nrounds, threefry4x64_ctr_t in, threefry4x64_key_t k); -static INLINE threefry4x64_ctr_t threefry4x64_R(unsigned int Nrounds, +static NPY_INLINE threefry4x64_ctr_t threefry4x64_R(unsigned int Nrounds, threefry4x64_ctr_t in, threefry4x64_key_t k) { threefry4x64_ctr_t X; @@ -288,7 +278,7 @@ typedef struct s_threefry_state { uint32_t uinteger; } threefry_state; -static INLINE uint64_t threefry_next(threefry_state *state) { +static NPY_INLINE uint64_t threefry_next(threefry_state *state) { int i; threefry4x64_ctr_t ct; uint64_t out; @@ -317,11 +307,11 @@ static INLINE uint64_t threefry_next(threefry_state *state) { return state->buffer[0]; } -static INLINE uint64_t threefry_next64(threefry_state *state) { +static NPY_INLINE uint64_t threefry_next64(threefry_state *state) { return threefry_next(state); } -static INLINE uint32_t threefry_next32(threefry_state *state) { +static NPY_INLINE uint32_t threefry_next32(threefry_state *state) { uint64_t next; if (state->has_uint32) { state->has_uint32 = 0; diff --git a/numpy/random/src/threefry32/threefry32.c b/numpy/random/src/threefry32/threefry32.c index 500e9482d..cc6890f2e 100644 --- a/numpy/random/src/threefry32/threefry32.c +++ b/numpy/random/src/threefry32/threefry32.c @@ -1,8 +1,8 @@ #include "threefry32.h" -extern INLINE uint64_t threefry32_next64(threefry32_state *state); +extern NPY_INLINE uint64_t threefry32_next64(threefry32_state *state); -extern INLINE uint32_t threefry32_next32(threefry32_state *state); +extern NPY_INLINE uint32_t threefry32_next32(threefry32_state *state); extern void threefry32_jump(threefry32_state *state) { /* Advances state as-if 2^64 draws were made */ diff --git a/numpy/random/src/threefry32/threefry32.h b/numpy/random/src/threefry32/threefry32.h index 74a85c42b..ebedee804 100644 --- a/numpy/random/src/threefry32/threefry32.h +++ b/numpy/random/src/threefry32/threefry32.h @@ -4,23 +4,13 @@ Adapted from random123's threefry.h #ifndef _RANDOMDGEN__THREEFRY32_H_ #define _RANDOMDGEN__THREEFRY32_H_ -#ifdef _WIN32 -#if _MSC_VER == 1500 -#include "../common/inttypes.h" -#define INLINE __forceinline -#else #include <inttypes.h> -#define INLINE __inline __forceinline -#endif -#else -#include <inttypes.h> -#define INLINE inline -#endif +#include "numpy/npy_common.h" #define THREEFRY_BUFFER_SIZE 4L -static INLINE uint32_t RotL_32(uint32_t x, unsigned int N); -static INLINE uint32_t RotL_32(uint32_t x, unsigned int N) { +static NPY_INLINE uint32_t RotL_32(uint32_t x, unsigned int N); +static NPY_INLINE uint32_t RotL_32(uint32_t x, unsigned int N) { return (x << (N & 31)) | (x >> ((32 - N) & 31)); } @@ -52,13 +42,13 @@ enum r123_enum_threefry32x4 { typedef struct r123array4x32 threefry4x32_ctr_t; typedef struct r123array4x32 threefry4x32_key_t; typedef struct r123array4x32 threefry4x32_ukey_t; -static INLINE threefry4x32_key_t threefry4x32keyinit(threefry4x32_ukey_t uk) { +static NPY_INLINE threefry4x32_key_t threefry4x32keyinit(threefry4x32_ukey_t uk) { return uk; }; -static INLINE threefry4x32_ctr_t threefry4x32_R(unsigned int Nrounds, +static NPY_INLINE threefry4x32_ctr_t threefry4x32_R(unsigned int Nrounds, threefry4x32_ctr_t in, threefry4x32_key_t k); -static INLINE threefry4x32_ctr_t threefry4x32_R(unsigned int Nrounds, +static NPY_INLINE threefry4x32_ctr_t threefry4x32_R(unsigned int Nrounds, threefry4x32_ctr_t in, threefry4x32_key_t k) { threefry4x32_ctr_t X; @@ -779,9 +769,9 @@ static INLINE threefry4x32_ctr_t threefry4x32_R(unsigned int Nrounds, return X; } enum r123_enum_threefry4x32 { threefry4x32_rounds = 20 }; -static INLINE threefry4x32_ctr_t threefry4x32(threefry4x32_ctr_t in, +static NPY_INLINE threefry4x32_ctr_t threefry4x32(threefry4x32_ctr_t in, threefry4x32_key_t k); -static INLINE threefry4x32_ctr_t threefry4x32(threefry4x32_ctr_t in, +static NPY_INLINE threefry4x32_ctr_t threefry4x32(threefry4x32_ctr_t in, threefry4x32_key_t k) { return threefry4x32_R(threefry4x32_rounds, in, k); } @@ -793,7 +783,7 @@ typedef struct s_threefry32_state { uint32_t buffer[THREEFRY_BUFFER_SIZE]; } threefry32_state; -static INLINE uint32_t threefry32_next(threefry32_state *state) { +static NPY_INLINE uint32_t threefry32_next(threefry32_state *state) { int i; threefry4x32_ctr_t ct; uint32_t out; @@ -822,15 +812,15 @@ static INLINE uint32_t threefry32_next(threefry32_state *state) { return state->buffer[0]; } -static INLINE uint64_t threefry32_next64(threefry32_state *state) { +static NPY_INLINE uint64_t threefry32_next64(threefry32_state *state) { return ((uint64_t)threefry32_next(state) << 32) | threefry32_next(state); } -static INLINE uint32_t threefry32_next32(threefry32_state *state) { +static NPY_INLINE uint32_t threefry32_next32(threefry32_state *state) { return threefry32_next(state); } -static INLINE double threefry32_next_double(threefry32_state *state) { +static NPY_INLINE double threefry32_next_double(threefry32_state *state) { int32_t a = threefry32_next(state) >> 5, b = threefry32_next(state) >> 6; return (a * 67108864.0 + b) / 9007199254740992.0; } diff --git a/numpy/random/src/xoroshiro128/xoroshiro128.c b/numpy/random/src/xoroshiro128/xoroshiro128.c index 060eb8a51..baefcf3a8 100644 --- a/numpy/random/src/xoroshiro128/xoroshiro128.c +++ b/numpy/random/src/xoroshiro128/xoroshiro128.c @@ -31,9 +31,9 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */ #include "xoroshiro128.h" -extern INLINE uint64_t xoroshiro128_next64(xoroshiro128_state *state); +extern NPY_INLINE uint64_t xoroshiro128_next64(xoroshiro128_state *state); -extern INLINE uint32_t xoroshiro128_next32(xoroshiro128_state *state); +extern NPY_INLINE uint32_t xoroshiro128_next32(xoroshiro128_state *state); void xoroshiro128_jump(xoroshiro128_state *state) { diff --git a/numpy/random/src/xoroshiro128/xoroshiro128.h b/numpy/random/src/xoroshiro128/xoroshiro128.h index 0db82b173..63682776b 100644 --- a/numpy/random/src/xoroshiro128/xoroshiro128.h +++ b/numpy/random/src/xoroshiro128/xoroshiro128.h @@ -1,18 +1,8 @@ #ifndef _RANDOMDGEN__XOROSHIRO128_H_ #define _RANDOMDGEN__XOROSHIRO128_H_ -#ifdef _WIN32 -#if _MSC_VER == 1500 -#include "../common/inttypes.h" -#define INLINE __forceinline -#else #include <inttypes.h> -#define INLINE __inline __forceinline -#endif -#else -#include <inttypes.h> -#define INLINE inline -#endif +#include "numpy/npy_common.h" typedef struct s_xoroshiro128_state { @@ -21,12 +11,12 @@ typedef struct s_xoroshiro128_state uint32_t uinteger; } xoroshiro128_state; -static INLINE uint64_t rotl(const uint64_t x, int k) +static NPY_INLINE uint64_t rotl(const uint64_t x, int k) { return (x << k) | (x >> (64 - k)); } -static INLINE uint64_t xoroshiro128_next(uint64_t *s) +static NPY_INLINE uint64_t xoroshiro128_next(uint64_t *s) { const uint64_t s0 = s[0]; uint64_t s1 = s[1]; @@ -39,12 +29,12 @@ static INLINE uint64_t xoroshiro128_next(uint64_t *s) return result; } -static INLINE uint64_t xoroshiro128_next64(xoroshiro128_state *state) +static NPY_INLINE uint64_t xoroshiro128_next64(xoroshiro128_state *state) { return xoroshiro128_next(&state->s[0]); } -static INLINE uint32_t xoroshiro128_next32(xoroshiro128_state *state) +static NPY_INLINE uint32_t xoroshiro128_next32(xoroshiro128_state *state) { uint64_t next; if (state->has_uint32) diff --git a/numpy/random/src/xorshift1024/xorshift1024.c b/numpy/random/src/xorshift1024/xorshift1024.c index 8737b5a82..d68ecc7d3 100644 --- a/numpy/random/src/xorshift1024/xorshift1024.c +++ b/numpy/random/src/xorshift1024/xorshift1024.c @@ -4,9 +4,9 @@ to 2^512 calls to next(); it can be used to generate 2^512 non-overlapping subsequences for parallel computations. */ -extern INLINE uint64_t xorshift1024_next(xorshift1024_state *state); -extern INLINE uint64_t xorshift1024_next64(xorshift1024_state *state); -extern INLINE uint32_t xorshift1024_next32(xorshift1024_state *state); +extern NPY_INLINE uint64_t xorshift1024_next(xorshift1024_state *state); +extern NPY_INLINE uint64_t xorshift1024_next64(xorshift1024_state *state); +extern NPY_INLINE uint32_t xorshift1024_next32(xorshift1024_state *state); void xorshift1024_jump(xorshift1024_state *state) { int i, j, b; diff --git a/numpy/random/src/xorshift1024/xorshift1024.h b/numpy/random/src/xorshift1024/xorshift1024.h index e0ef77826..38ec27430 100644 --- a/numpy/random/src/xorshift1024/xorshift1024.h +++ b/numpy/random/src/xorshift1024/xorshift1024.h @@ -1,18 +1,8 @@ #ifndef _RANDOMDGEN__XORSHIFT1024_H_ #define _RANDOMDGEN__XORSHIFT1024_H_ -#ifdef _WIN32 -#if _MSC_VER == 1500 -#include "../common/inttypes.h" -#define INLINE __forceinline -#else #include <inttypes.h> -#define INLINE __inline __forceinline -#endif -#else -#include <inttypes.h> -#define INLINE inline -#endif +#include "numpy/npy_common.h" typedef struct s_xorshift1024_state { uint64_t s[16]; @@ -21,7 +11,7 @@ typedef struct s_xorshift1024_state { uint32_t uinteger; } xorshift1024_state; -static INLINE uint64_t xorshift1024_next(xorshift1024_state *state) { +static NPY_INLINE uint64_t xorshift1024_next(xorshift1024_state *state) { const uint64_t s0 = state->s[state->p]; uint64_t s1 = state->s[state->p = ((state->p) + 1) & 15]; s1 ^= s1 << 31; // a @@ -29,11 +19,11 @@ static INLINE uint64_t xorshift1024_next(xorshift1024_state *state) { return state->s[state->p] * 0x9e3779b97f4a7c13; } -static INLINE uint64_t xorshift1024_next64(xorshift1024_state *state) { +static NPY_INLINE uint64_t xorshift1024_next64(xorshift1024_state *state) { return xorshift1024_next(state); } -static INLINE uint32_t xorshift1024_next32(xorshift1024_state *state) { +static NPY_INLINE uint32_t xorshift1024_next32(xorshift1024_state *state) { uint64_t next; if (state->has_uint32) { state->has_uint32 = 0; diff --git a/numpy/random/src/xoshiro256starstar/LICENSE.md b/numpy/random/src/xoshiro256/LICENSE.md index d863f3b29..d863f3b29 100644 --- a/numpy/random/src/xoshiro256starstar/LICENSE.md +++ b/numpy/random/src/xoshiro256/LICENSE.md diff --git a/numpy/random/src/xoshiro256starstar/xoshiro256starstar-test-data-gen.c b/numpy/random/src/xoshiro256/xoshiro256-test-data-gen.c index 8522229dd..94eeb7346 100644 --- a/numpy/random/src/xoshiro256starstar/xoshiro256starstar-test-data-gen.c +++ b/numpy/random/src/xoshiro256/xoshiro256-test-data-gen.c @@ -1,13 +1,13 @@ /* * Generate testing csv files * - * cl xoshiro256starstar-test-data-gen.c xoshiro256starstar.orig.c / + * cl xoshiro256-test-data-gen.c xoshiro256.orig.c / * ../splitmix64/splitmix64.c /Ox - * xoshiro256starstar-test-data-gen.exe * + * xoshiro256-test-data-gen.exe * * - * gcc xoshiro256starstar-test-data-gen.c xoshiro256starstar.orig.c / - * ../splitmix64/splitmix64.c -o xoshiro256starstar-test-data-gen - * ./xoshiro256starstar-test-data-gen + * gcc xoshiro256-test-data-gen.c xoshiro256.orig.c / + * ../splitmix64/splitmix64.c -o xoshiro256-test-data-gen + * ./xoshiro256-test-data-gen * * Requres the Random123 directory containing header files to be located in the * same directory (not included). @@ -15,7 +15,7 @@ */ #include "../splitmix64/splitmix64.h" -#include "xoshiro256starstar.orig.h" +#include "xoshiro256.orig.h" #include <inttypes.h> #include <stdio.h> @@ -35,7 +35,7 @@ int main() { } FILE *fp; - fp = fopen("xoshiro256starstar-testset-1.csv", "w"); + fp = fopen("xoshiro256-testset-1.csv", "w"); if (fp == NULL) { printf("Couldn't open file\n"); return -1; @@ -56,7 +56,7 @@ int main() { for (i = 0; i < N; i++) { store[i] = next(); } - fp = fopen("xoshiro256starstar-testset-2.csv", "w"); + fp = fopen("xoshiro256-testset-2.csv", "w"); if (fp == NULL) { printf("Couldn't open file\n"); return -1; diff --git a/numpy/random/src/xoshiro256starstar/xoshiro256starstar.c b/numpy/random/src/xoshiro256/xoshiro256.c index 30b6c7d85..f5cda2721 100644 --- a/numpy/random/src/xoshiro256starstar/xoshiro256starstar.c +++ b/numpy/random/src/xoshiro256/xoshiro256.c @@ -6,7 +6,7 @@ worldwide. This software is distributed without any warranty. See <http://creativecommons.org/publicdomain/zero/1.0/>. */ -#include "xoshiro256starstar.h" +#include "xoshiro256.h" /* This is xoshiro256** 1.0, our all-purpose, rock-solid generator. It has excellent (sub-ns) speed, a state (256 bits) that is large enough for @@ -18,15 +18,16 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */ a 64-bit seed, we suggest to seed a splitmix64 generator and use its output to fill s. */ -extern INLINE uint64_t xoshiro256starstar_next64(xoshiro256starstar_state *state); +extern NPY_INLINE uint64_t xoshiro256_next64(xoshiro256_state *state); + +extern NPY_INLINE uint32_t xoshiro256_next32(xoshiro256_state *state); -extern INLINE uint32_t xoshiro256starstar_next32(xoshiro256starstar_state *state); /* This is the jump function for the generator. It is equivalent to 2^128 calls to next(); it can be used to generate 2^128 non-overlapping subsequences for parallel computations. */ -void xoshiro256starstar_jump(xoshiro256starstar_state *state) +void xoshiro256_jump(xoshiro256_state *state) { int i, b; static const uint64_t JUMP[] = {0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c}; @@ -45,7 +46,7 @@ void xoshiro256starstar_jump(xoshiro256starstar_state *state) s2 ^= state->s[2]; s3 ^= state->s[3]; } - xoshiro256starstar_next(&state->s[0]); + xoshiro256_next(&state->s[0]); } state->s[0] = s0; diff --git a/numpy/random/src/xoshiro256/xoshiro256.h b/numpy/random/src/xoshiro256/xoshiro256.h new file mode 100644 index 000000000..1908245a5 --- /dev/null +++ b/numpy/random/src/xoshiro256/xoshiro256.h @@ -0,0 +1,53 @@ +#ifndef _RANDOMDGEN__XOSHIRO256STARSTAR_H_ +#define _RANDOMDGEN__XOSHIRO256STARSTAR_H_ + +#include <inttypes.h> +#include "numpy/npy_common.h" + +typedef struct s_xoshiro256_state { + uint64_t s[4]; + int has_uint32; + uint32_t uinteger; +} xoshiro256_state; + +static NPY_INLINE uint64_t rotl(const uint64_t x, int k) { + return (x << k) | (x >> (64 - k)); +} + +static NPY_INLINE uint64_t xoshiro256_next(uint64_t *s) { + const uint64_t result_starstar = rotl(s[1] * 5, 7) * 9; + const uint64_t t = s[1] << 17; + + s[2] ^= s[0]; + s[3] ^= s[1]; + s[1] ^= s[2]; + s[0] ^= s[3]; + + s[2] ^= t; + + s[3] = rotl(s[3], 45); + + return result_starstar; +} + + +static NPY_INLINE uint64_t xoshiro256_next64(xoshiro256_state *state) { + return xoshiro256_next(&state->s[0]); +} + +static NPY_INLINE uint32_t xoshiro256_next32(xoshiro256_state *state) { + + uint64_t next; + if (state->has_uint32) { + state->has_uint32 = 0; + return state->uinteger; + } + next = xoshiro256_next(&state->s[0]); + state->has_uint32 = 1; + state->uinteger = (uint32_t)(next >> 32); + return (uint32_t)(next & 0xffffffff); +} + +void xoshiro256_jump(xoshiro256_state *state); + +#endif diff --git a/numpy/random/src/xoshiro256starstar/xoshiro256starstar.orig.c b/numpy/random/src/xoshiro256/xoshiro256.orig.c index ecf87bab9..ecf87bab9 100644 --- a/numpy/random/src/xoshiro256starstar/xoshiro256starstar.orig.c +++ b/numpy/random/src/xoshiro256/xoshiro256.orig.c diff --git a/numpy/random/src/xoshiro256starstar/xoshiro256starstar.orig.h b/numpy/random/src/xoshiro256/xoshiro256.orig.h index 3aa788ec9..3aa788ec9 100644 --- a/numpy/random/src/xoshiro256starstar/xoshiro256starstar.orig.h +++ b/numpy/random/src/xoshiro256/xoshiro256.orig.h diff --git a/numpy/random/src/xoshiro256starstar/xoshiro256starstar.h b/numpy/random/src/xoshiro256starstar/xoshiro256starstar.h deleted file mode 100644 index 1d7d8ea40..000000000 --- a/numpy/random/src/xoshiro256starstar/xoshiro256starstar.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef _RANDOMDGEN__XOSHIRO256STARSTAR_H_ -#define _RANDOMDGEN__XOSHIRO256STARSTAR_H_ - -#ifdef _WIN32 -#if _MSC_VER == 1500 -#include "../common/inttypes.h" -#define INLINE __forceinline -#else -#include <inttypes.h> -#define INLINE __inline __forceinline -#endif -#else -#include <inttypes.h> -#define INLINE inline -#endif - -typedef struct s_xoshiro256starstar_state { - uint64_t s[4]; - int has_uint32; - uint32_t uinteger; -} xoshiro256starstar_state; - -static INLINE uint64_t rotl(const uint64_t x, int k) { - return (x << k) | (x >> (64 - k)); -} - -static INLINE uint64_t xoshiro256starstar_next(uint64_t *s) { - const uint64_t result_starstar = rotl(s[1] * 5, 7) * 9; - const uint64_t t = s[1] << 17; - - s[2] ^= s[0]; - s[3] ^= s[1]; - s[1] ^= s[2]; - s[0] ^= s[3]; - - s[2] ^= t; - - s[3] = rotl(s[3], 45); - - return result_starstar; -} - -static INLINE uint64_t -xoshiro256starstar_next64(xoshiro256starstar_state *state) { - return xoshiro256starstar_next(&state->s[0]); -} - -static INLINE uint32_t -xoshiro256starstar_next32(xoshiro256starstar_state *state) { - uint64_t next; - if (state->has_uint32) { - state->has_uint32 = 0; - return state->uinteger; - } - next = xoshiro256starstar_next(&state->s[0]); - state->has_uint32 = 1; - state->uinteger = (uint32_t)(next >> 32); - return (uint32_t)(next & 0xffffffff); -} - -void xoshiro256starstar_jump(xoshiro256starstar_state *state); - -#endif diff --git a/numpy/random/src/xoshiro512starstar/LICENSE.md b/numpy/random/src/xoshiro512/LICENSE.md index aa34c1966..aa34c1966 100644 --- a/numpy/random/src/xoshiro512starstar/LICENSE.md +++ b/numpy/random/src/xoshiro512/LICENSE.md diff --git a/numpy/random/src/xoshiro512starstar/xoshiro512starstar-test-data-gen.c b/numpy/random/src/xoshiro512/xoshiro512-test-data-gen.c index bcc3574e4..83e164a51 100644 --- a/numpy/random/src/xoshiro512starstar/xoshiro512starstar-test-data-gen.c +++ b/numpy/random/src/xoshiro512/xoshiro512-test-data-gen.c @@ -1,13 +1,13 @@ /* * Generate testing csv files * - * cl xoshiro512starstar-test-data-gen.c xoshiro512starstar.orig.c / + * cl xoshiro512-test-data-gen.c xoshiro512.orig.c / * ../splitmix64/splitmix64.c /Ox - * xoshiro512starstar-test-data-gen.exe * + * xoshiro512-test-data-gen.exe * * - * gcc xoshiro512starstar-test-data-gen.c xoshiro512starstar.orig.c / - * ../splitmix64/splitmix64.c -o xoshiro512starstar-test-data-gen - * ./xoshiro512starstar-test-data-gen + * gcc xoshiro512-test-data-gen.c xoshiro512.orig.c / + * ../splitmix64/splitmix64.c -o xoshiro512-test-data-gen + * ./xoshiro512-test-data-gen * * Requres the Random123 directory containing header files to be located in the * same directory (not included). @@ -15,7 +15,7 @@ */ #include "../splitmix64/splitmix64.h" -#include "xoshiro512starstar.orig.h" +#include "xoshiro512.orig.h" #include <inttypes.h> #include <stdio.h> @@ -35,7 +35,7 @@ int main() { } FILE *fp; - fp = fopen("xoshiro512starstar-testset-1.csv", "w"); + fp = fopen("xoshiro512-testset-1.csv", "w"); if (fp == NULL) { printf("Couldn't open file\n"); return -1; @@ -56,7 +56,7 @@ int main() { for (i = 0; i < N; i++) { store[i] = next(); } - fp = fopen("xoshiro512starstar-testset-2.csv", "w"); + fp = fopen("xoshiro512-testset-2.csv", "w"); if (fp == NULL) { printf("Couldn't open file\n"); return -1; diff --git a/numpy/random/src/xoshiro512starstar/xoshiro512starstar.c b/numpy/random/src/xoshiro512/xoshiro512.c index a9f56699f..9fdbed125 100644 --- a/numpy/random/src/xoshiro512starstar/xoshiro512starstar.c +++ b/numpy/random/src/xoshiro512/xoshiro512.c @@ -6,7 +6,7 @@ worldwide. This software is distributed without any warranty. See <http://creativecommons.org/publicdomain/zero/1.0/>. */ -#include "xoshiro512starstar.h" +#include "xoshiro512.h" /* This is xoshiro512** 1.0, an all-purpose, rock-solid generator. It has excellent (about 1ns) speed, an increased state (512 bits) that is @@ -19,11 +19,10 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */ a 64-bit seed, we suggest to seed a splitmix64 generator and use its output to fill s. */ -extern INLINE uint64_t -xoshiro512starstar_next64(xoshiro512starstar_state *state); +extern NPY_INLINE uint64_t xoshiro512_next64(xoshiro512_state *state); + +extern NPY_INLINE uint32_t xoshiro512_next32(xoshiro512_state *state); -extern INLINE uint32_t -xoshiro512starstar_next32(xoshiro512starstar_state *state); /* This is the jump function for the generator. It is equivalent to 2^256 calls to next(); it can be used to generate 2^256 @@ -31,7 +30,7 @@ xoshiro512starstar_next32(xoshiro512starstar_state *state); static uint64_t s_placeholder[8]; -void xoshiro512starstar_jump(xoshiro512starstar_state *state) { +void xoshiro512_jump(xoshiro512_state *state) { int i, b, w; static const uint64_t JUMP[] = {0x33ed89b6e7a353f9, 0x760083d7955323be, @@ -46,7 +45,7 @@ void xoshiro512starstar_jump(xoshiro512starstar_state *state) { if (JUMP[i] & UINT64_C(1) << b) for (w = 0; w < sizeof s_placeholder / sizeof *s_placeholder; w++) t[w] ^= state->s[w]; - xoshiro512starstar_next(&state->s[0]); + xoshiro512_next(&state->s[0]); } memcpy(state->s, t, sizeof s_placeholder); diff --git a/numpy/random/src/xoshiro512starstar/xoshiro512starstar.h b/numpy/random/src/xoshiro512/xoshiro512.h index 0fa0ba3cd..6ce6c7db7 100644 --- a/numpy/random/src/xoshiro512starstar/xoshiro512starstar.h +++ b/numpy/random/src/xoshiro512/xoshiro512.h @@ -1,33 +1,23 @@ #ifndef _RANDOMDGEN__XOSHIRO512STARSTAR_H_ #define _RANDOMDGEN__XOSHIRO512STARSTAR_H_ -#ifdef _WIN32 -#if _MSC_VER == 1500 -#include "../common/inttypes.h" -#define INLINE __forceinline -#else -#include <inttypes.h> -#define INLINE __inline __forceinline -#endif -#else -#include <inttypes.h> -#define INLINE inline -#endif #include <string.h> +#include <inttypes.h> +#include "numpy/npy_common.h" -typedef struct s_xoshiro512starstar_state +typedef struct s_xoshiro512_state { uint64_t s[8]; int has_uint32; uint32_t uinteger; -} xoshiro512starstar_state; +} xoshiro512_state; -static INLINE uint64_t rotl(const uint64_t x, int k) +static NPY_INLINE uint64_t rotl(const uint64_t x, int k) { return (x << k) | (x >> (64 - k)); } -static INLINE uint64_t xoshiro512starstar_next(uint64_t *s) +static NPY_INLINE uint64_t xoshiro512_next(uint64_t *s) { const uint64_t result_starstar = rotl(s[1] * 5, 7) * 9; @@ -49,14 +39,13 @@ static INLINE uint64_t xoshiro512starstar_next(uint64_t *s) return result_starstar; } -static INLINE uint64_t -xoshiro512starstar_next64(xoshiro512starstar_state *state) + +static NPY_INLINE uint64_t xoshiro512_next64(xoshiro512_state *state) { - return xoshiro512starstar_next(&state->s[0]); + return xoshiro512_next(&state->s[0]); } -static INLINE uint32_t -xoshiro512starstar_next32(xoshiro512starstar_state *state) +static NPY_INLINE uint32_t xoshiro512_next32(xoshiro512_state *state) { uint64_t next; if (state->has_uint32) @@ -64,12 +53,12 @@ xoshiro512starstar_next32(xoshiro512starstar_state *state) state->has_uint32 = 0; return state->uinteger; } - next = xoshiro512starstar_next(&state->s[0]); + next = xoshiro512_next(&state->s[0]); state->has_uint32 = 1; state->uinteger = (uint32_t)(next >> 32); return (uint32_t)(next & 0xffffffff); } -void xoshiro512starstar_jump(xoshiro512starstar_state *state); +void xoshiro512_jump(xoshiro512_state *state); #endif diff --git a/numpy/random/src/xoshiro512starstar/xoshiro512starstar.orig.c b/numpy/random/src/xoshiro512/xoshiro512.orig.c index 0cf884edb..ecdf81fc1 100644 --- a/numpy/random/src/xoshiro512starstar/xoshiro512starstar.orig.c +++ b/numpy/random/src/xoshiro512/xoshiro512.orig.c @@ -6,7 +6,7 @@ worldwide. This software is distributed without any warranty. See <http://creativecommons.org/publicdomain/zero/1.0/>. */ -#include "xoshiro512starstar.orig.h" +#include "xoshiro512.orig.h" /* This is xoshiro512** 1.0, an all-purpose, rock-solid generator. It has excellent (about 1ns) speed, an increased state (512 bits) that is diff --git a/numpy/random/src/xoshiro512starstar/xoshiro512starstar.orig.h b/numpy/random/src/xoshiro512/xoshiro512.orig.h index 0b7892473..0b7892473 100644 --- a/numpy/random/src/xoshiro512starstar/xoshiro512starstar.orig.h +++ b/numpy/random/src/xoshiro512/xoshiro512.orig.h |