From c88f1c3e382d9da9068cdd9ff87af6fef0ed9bd0 Mon Sep 17 00:00:00 2001 From: Brett Date: Tue, 9 Jul 2024 14:11:07 -0400 Subject: [PATCH] breaking changes to random --- CMakeLists.txt | 2 +- include/blt/std/random.h | 139 ++++++++++++++++++++++----------------- 2 files changed, 79 insertions(+), 62 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 869a1a7..32680f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.20) include(cmake/color.cmake) -set(BLT_VERSION 0.17.29) +set(BLT_VERSION 0.18.0) set(BLT_TEST_VERSION 0.0.1) set(BLT_TARGET BLT) diff --git a/include/blt/std/random.h b/include/blt/std/random.h index f8bd993..eb83342 100644 --- a/include/blt/std/random.h +++ b/include/blt/std/random.h @@ -7,87 +7,104 @@ #ifndef BLT_RANDOM_H #define BLT_RANDOM_H +#include #include -namespace blt::random { +namespace blt::random +{ + // https://github.com/avaneev/komihash/tree/main - static inline uint32_t PCG_Hash(uint32_t input) { - uint32_t state = input * 747796405u + 2891336453u; - uint32_t word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u; - return (word >> 22u) ^ - word; + static inline blt::u32 PCG_Hash(blt::u32 input) + { + blt::u32 state = input * 747796405u + 2891336453u; + blt::u32 word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u; + return (word >> 22u) ^ word; } - - static inline float randomFloat(uint32_t& seed){ + + //https://lemire.me/blog/2018/08/15/fast-strongly-universal-64-bit-hashing-everywhere/ + static inline blt::u64 murmur64(blt::u64 h) + { + h ^= h >> 33; + h *= 0xff51afd7ed558ccdL; + h ^= h >> 33; + h *= 0xc4ceb9fe1a85ec53L; + h ^= h >> 33; + return h; + } + + static inline double pcg_double(blt::u32& seed) + { seed = PCG_Hash(seed); - return (float)seed / (float)std::numeric_limits::max(); + return static_cast(seed) / static_cast(std::numeric_limits::max()); } - + + static inline float pcg_float(blt::u32& seed) + { + return static_cast(pcg_double(seed)); + } + /** * @return random float without changing seed */ - static inline float randomFloat_c(uint32_t seed){ - return randomFloat(seed); + static inline float pcg_float_c(blt::u32 seed) + { + return pcg_float(seed); } - + + static inline double pcg_double_c(blt::u32 seed) + { + return pcg_double(seed); + } + /** * @param seed seed for random * @param min inclusive min * @param max exclusive max * @return random int between min (inclusive) and max (exclusive) */ - static inline int randomInt(uint32_t& seed, int min = 0, int max = 1){ - return (int)((randomFloat(seed) * (float)(max - min)) + (float)min); + static inline int pcg_int(blt::u32& seed, int min = 0, int max = 2) + { + return static_cast((pcg_double(seed) * static_cast(max - min)) + static_cast(min)); } - - static inline int randomInt_c(uint32_t seed, int min = 0, int max = 1){ - return randomInt(seed, min, max); + + static inline int pcg_int_c(blt::u32 seed, int min = 0, int max = 2) + { + return pcg_int(seed, min, max); + } + + + static inline double murmur_double(blt::u64& seed) + { + seed = murmur64(seed); + return static_cast(seed) / static_cast(std::numeric_limits::max()); + } + + static inline float murmur_float(blt::u64& seed) + { + return static_cast(murmur_double(seed)); + } + + static inline float murmur_float_c(blt::u64 seed) + { + return murmur_float(seed); + } + + static inline double murmur_double_c(blt::u64 seed) + { + return murmur_double(seed); } - - /** - * Creates a container class for generating random number distributions - * @tparam T numeric type - * @tparam dist std::uniform_real_distribution or std::uniform_int_distribution - */ - template typename dist = std::uniform_real_distribution> - class random { - private: - std::random_device rd; // obtain a random number from hardware - std::mt19937 gen; - dist* distribution = nullptr; - public: - /** - * Construct the random number generator. - * @param min min value possible to generate. (default: 0) - * @param max max value possible to generate. (default: 1) - * @param seed seed to use in generating random values. (default: 0) - */ - explicit random(T min = (T) 0, T max = (T) 1, long seed = 0): gen(std::mt19937(seed)) { - distribution = new dist(min, max); - } - - /** - * Note the min/max are inclusive and defaults to a **uniform** distribution. - * @return random number between the defined min/max or the default of [0,1]. - */ - T get() { - return (*distribution)(gen); - } - - ~random() { - delete distribution; - } - }; template - class simplex_noise { - private: - - public: - simplex_noise() { - - } - }; + static inline T murmur_integral_64(blt::u64& seed, T min = 0, T max = 2) + { + return static_cast((murmur_double(seed) * static_cast(max - min)) + static_cast(min)); + } + + template + static inline T murmur_integral_64c(blt::u64 seed, T min = 0, T max = 2) + { + return murmur_integral_64(seed, min, max); + } }