summaryrefslogtreecommitdiff
path: root/numpy/random/src
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/random/src')
-rw-r--r--numpy/random/src/sfc64/LICENSE.md27
-rw-r--r--numpy/random/src/sfc64/sfc64.c39
-rw-r--r--numpy/random/src/sfc64/sfc64.h60
3 files changed, 126 insertions, 0 deletions
diff --git a/numpy/random/src/sfc64/LICENSE.md b/numpy/random/src/sfc64/LICENSE.md
new file mode 100644
index 000000000..21dd604af
--- /dev/null
+++ b/numpy/random/src/sfc64/LICENSE.md
@@ -0,0 +1,27 @@
+# SFC64
+
+## The MIT License
+
+Adapted from a C++ implementation of Chris Doty-Humphrey's SFC PRNG.
+
+https://gist.github.com/imneme/f1f7821f07cf76504a97f6537c818083
+
+Copyright (c) 2018 Melissa E. O'Neill
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/numpy/random/src/sfc64/sfc64.c b/numpy/random/src/sfc64/sfc64.c
new file mode 100644
index 000000000..5546fff08
--- /dev/null
+++ b/numpy/random/src/sfc64/sfc64.c
@@ -0,0 +1,39 @@
+#include "sfc64.h"
+
+extern void sfc64_set_seed(sfc64_state *state, uint64_t *seed) {
+ /* Conservatively stick with the original formula. With SeedSequence, it
+ * might be fine to just set the state with 4 uint64s and be done.
+ */
+ int i;
+
+ state->s[0] = seed[0];
+ state->s[1] = seed[1];
+ state->s[2] = seed[2];
+ state->s[3] = 1;
+
+ for (i=0; i<12; i++) {
+ (void)sfc64_next(state->s);
+ }
+}
+
+extern void sfc64_get_state(sfc64_state *state, uint64_t *state_arr, int *has_uint32,
+ uint32_t *uinteger) {
+ int i;
+
+ for (i=0; i<4; i++) {
+ state_arr[i] = state->s[i];
+ }
+ has_uint32[0] = state->has_uint32;
+ uinteger[0] = state->uinteger;
+}
+
+extern void sfc64_set_state(sfc64_state *state, uint64_t *state_arr, int has_uint32,
+ uint32_t uinteger) {
+ int i;
+
+ for (i=0; i<4; i++) {
+ state->s[i] = state_arr[i];
+ }
+ state->has_uint32 = has_uint32;
+ state->uinteger = uinteger;
+}
diff --git a/numpy/random/src/sfc64/sfc64.h b/numpy/random/src/sfc64/sfc64.h
new file mode 100644
index 000000000..6674ae69c
--- /dev/null
+++ b/numpy/random/src/sfc64/sfc64.h
@@ -0,0 +1,60 @@
+#ifndef _RANDOMDGEN__SFC64_H_
+#define _RANDOMDGEN__SFC64_H_
+
+#include <inttypes.h>
+#ifdef _WIN32
+#include <stdlib.h>
+#endif
+#include "numpy/npy_common.h"
+
+typedef struct s_sfc64_state {
+ uint64_t s[4];
+ int has_uint32;
+ uint32_t uinteger;
+} sfc64_state;
+
+
+static NPY_INLINE uint64_t rotl(const uint64_t value, unsigned int rot) {
+#ifdef _WIN32
+ return _rotl64(value, rot);
+#else
+ return (value << rot) | (value >> ((-rot) & 63));
+#endif
+}
+
+static NPY_INLINE uint64_t sfc64_next(uint64_t *s) {
+ const uint64_t tmp = s[0] + s[1] + s[3]++;
+
+ s[0] = s[1] ^ (s[1] >> 11);
+ s[1] = s[2] + (s[2] << 3);
+ s[2] = rotl(s[2], 24) + tmp;
+
+ return tmp;
+}
+
+
+static NPY_INLINE uint64_t sfc64_next64(sfc64_state *state) {
+ return sfc64_next(&state->s[0]);
+}
+
+static NPY_INLINE uint32_t sfc64_next32(sfc64_state *state) {
+ uint64_t next;
+ if (state->has_uint32) {
+ state->has_uint32 = 0;
+ return state->uinteger;
+ }
+ next = sfc64_next(&state->s[0]);
+ state->has_uint32 = 1;
+ state->uinteger = (uint32_t)(next >> 32);
+ return (uint32_t)(next & 0xffffffff);
+}
+
+void sfc64_set_seed(sfc64_state *state, uint64_t *seed);
+
+void sfc64_get_state(sfc64_state *state, uint64_t *state_arr, int *has_uint32,
+ uint32_t *uinteger);
+
+void sfc64_set_state(sfc64_state *state, uint64_t *state_arr, int has_uint32,
+ uint32_t uinteger);
+
+#endif