diff options
author | mattip <matti.picus@gmail.com> | 2019-05-13 14:17:51 -0700 |
---|---|---|
committer | mattip <matti.picus@gmail.com> | 2019-05-20 19:00:34 +0300 |
commit | 17e0070df93f4262908f884dca4b08cb7d0bba7f (patch) | |
tree | 2db0eec024d5e021a36e6dca9f4b97d118bc9444 /numpy/random/src | |
parent | dd77ce3cb84986308986974acfe988575323f75a (diff) | |
download | numpy-17e0070df93f4262908f884dca4b08cb7d0bba7f.tar.gz |
MAINT: Implement API changes for randomgen-derived code
remove numpy.random.gen, BRNG.generator, pcg*, rand, randn
remove use_mask and Lemire's method, fix benchmarks for PCG removal
convert brng to bitgen (in C) and bit_generator (in python)
convert base R{NG,andom.*} to BitGenerator, fix last commit
randint -> integers, remove rand, randn, random_integers
RandomGenerator -> Generator, more "basic RNG" -> BitGenerator
random_sample -> random, jump -> jumped, resync with randomgen
Remove derived code from entropy
Port over changes accepted in upstream to protect log(0.0) where relevant
fix doctests for jumped, better document choice
Remove Python 2.7 shims
Use NPY_INLINE to simplify
Fix performance.py to work
Renam directory brng to bit_generators
Fix examples wiht new directory structure
Clarify relationship to historical RandomState
Remove references to .generator
Rename xoshiro256/512starstar
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 |