summaryrefslogtreecommitdiff
path: root/random.c
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2015-02-13 16:18:10 +0100
committerLars-Dominik Braun <lars@6xq.net>2015-05-02 21:36:45 +0200
commitb9d887fc3cd3ae26c678bf35bc90c4f1d6b03888 (patch)
treeccbe25664282dd7915c55e73e25772b8801e9088 /random.c
parenta46f55e0a2c9362b7b549ead851043c7b9e2791d (diff)
downloadpucket-b9d887fc3cd3ae26c678bf35bc90c4f1d6b03888.tar.gz
pucket-b9d887fc3cd3ae26c678bf35bc90c4f1d6b03888.tar.bz2
pucket-b9d887fc3cd3ae26c678bf35bc90c4f1d6b03888.zip
Unify prng use
Finally drop all isaac references, do not use system rng any more. Drop rng state from flam3_frame – it was not used anyway.
Diffstat (limited to 'random.c')
-rw-r--r--random.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/random.c b/random.c
new file mode 100644
index 0000000..f0a06c2
--- /dev/null
+++ b/random.c
@@ -0,0 +1,63 @@
+/* Psoudo-random number generator
+ *
+ * Uses xorshift1024 from “An experimental exploration of Marsaglia’s xorshift
+ * generators, scrambled”, Sebastiano Vigna
+ */
+
+#include "random.h"
+
+uint64_t rand_u64 (randctx * const st) {
+ uint64_t s0 = st->s[ st->p ];
+ uint64_t s1 = st->s[ st->p = ( st->p + 1 ) & (XORSHIFT_S-1) ];
+ s1 ^= s1 << 31; // a
+ s1 ^= s1 >> 11; // b
+ s0 ^= s0 >> 30; // c
+ return ( st->s[ st->p ] = s0 ^ s1 ) * 1181783497276652981LL;
+}
+
+/* Generate random double in [0,1]
+ */
+double rand_d01 (randctx * const st) {
+ return (double) rand_u64 (st) / (double) UINT64_MAX;
+}
+
+/* Generate random double in [-1,1]
+ */
+double rand_d11 (randctx * const st) {
+ return rand_d01 (st) * 2.0 - 1.0;
+}
+
+/* Random boolean value in {0,1}
+ */
+int rand_bool (randctx * const st) {
+ return rand_u64 (st) & 1;
+}
+
+/* Generate random uint64_t with Intel’s rdrand instruction
+ */
+static uint64_t rand64 () {
+ unsigned long long rand;
+ while (!__builtin_ia32_rdrand64_step (&rand));
+ return rand;
+}
+
+/* Seed rng with rdrand
+ */
+void rand_seed (randctx * const st) {
+ /* seed with high-quality randomness */
+ for (unsigned char i = 0; i < XORSHIFT_S; i++) {
+ st->s[i] = rand64 ();
+ }
+}
+
+#if 0
+uint64_t xorshift_step (randctx * const st) {
+ uint64_t x = st->s[0];
+ x ^= x >> 12; // a
+ x ^= x << 25; // b
+ x ^= x >> 27; // c
+ st->s[0] = x;
+ return x * 2685821657736338717LL;
+}
+#endif
+