BLT/include/blt/std/random.h

114 lines
2.9 KiB
C
Raw Normal View History

/*
* Created by Brett on 04/01/23.
* Licensed under GNU General Public License V3.0
* See LICENSE file for license detail
*/
#ifndef BLT_RANDOM_H
#define BLT_RANDOM_H
2024-07-09 14:11:07 -04:00
#include <blt/std/types.h>
#include <random>
2024-07-09 14:11:07 -04:00
namespace blt::random
{
// https://github.com/avaneev/komihash/tree/main
2023-07-23 13:10:11 -04:00
2024-07-09 18:07:12 -04:00
static inline blt::u32 pcg_hash32(blt::u32 input)
2024-07-09 14:11:07 -04:00
{
blt::u32 state = input * 747796405u + 2891336453u;
blt::u32 word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
return (word >> 22u) ^ word;
2023-07-23 13:10:11 -04:00
}
2024-07-09 14:11:07 -04:00
//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;
}
2024-07-09 18:07:12 -04:00
static inline double pcg_double32(blt::u32& seed)
2024-07-09 14:11:07 -04:00
{
2024-07-09 18:07:12 -04:00
seed = pcg_hash32(seed);
2024-07-09 14:11:07 -04:00
return static_cast<double>(seed) / static_cast<double>(std::numeric_limits<blt::u32>::max());
2023-07-23 13:10:11 -04:00
}
2024-07-09 14:11:07 -04:00
2024-07-09 18:07:12 -04:00
static inline float pcg_float32(blt::u32& seed)
2024-07-09 14:11:07 -04:00
{
2024-07-09 18:07:12 -04:00
return static_cast<float>(pcg_double32(seed));
2024-07-09 14:11:07 -04:00
}
2023-07-23 13:10:11 -04:00
/**
* @return random float without changing seed
*/
2024-07-09 18:07:12 -04:00
static inline float pcg_float32c(blt::u32 seed)
2024-07-09 14:11:07 -04:00
{
2024-07-09 18:07:12 -04:00
return pcg_float32(seed);
2023-07-23 13:10:11 -04:00
}
2024-07-09 14:11:07 -04:00
2024-07-09 18:07:12 -04:00
static inline double pcg_double32c(blt::u32 seed)
2024-07-09 14:11:07 -04:00
{
2024-07-09 18:07:12 -04:00
return pcg_double32(seed);
2024-07-09 14:11:07 -04:00
}
2023-07-23 13:10:11 -04:00
/**
* @param seed seed for random
* @param min inclusive min
* @param max exclusive max
* @return random int between min (inclusive) and max (exclusive)
*/
2024-07-09 18:07:12 -04:00
template<typename T>
static inline T pcg_random32(blt::u32& seed, T min = 0, T max = 2)
2024-07-09 14:11:07 -04:00
{
2024-07-09 18:07:12 -04:00
return static_cast<T>((pcg_double32(seed) * static_cast<double>(max - min)) + static_cast<double>(min));
2023-07-23 13:10:11 -04:00
}
2024-07-09 14:11:07 -04:00
2024-07-09 18:07:12 -04:00
template<typename T>
static inline T pcg_random32c(blt::u32 seed, T min = 0, T max = 2)
2024-07-09 14:11:07 -04:00
{
return pcg_int(seed, min, max);
}
2024-07-09 18:07:12 -04:00
static inline double murmur_double64(blt::u64& seed)
2024-07-09 14:11:07 -04:00
{
seed = murmur64(seed);
return static_cast<double>(seed) / static_cast<double>(std::numeric_limits<blt::u64>::max());
}
2024-07-09 18:07:12 -04:00
static inline float murmur_float64(blt::u64& seed)
2024-07-09 14:11:07 -04:00
{
2024-07-09 18:07:12 -04:00
return static_cast<float>(murmur_double64(seed));
2024-07-09 14:11:07 -04:00
}
2024-07-09 18:07:12 -04:00
static inline float murmur_float64c(blt::u64 seed)
2024-07-09 14:11:07 -04:00
{
2024-07-09 18:07:12 -04:00
return murmur_float64(seed);
2024-07-09 14:11:07 -04:00
}
2024-07-09 18:07:12 -04:00
static inline double murmur_double64c(blt::u64 seed)
2024-07-09 14:11:07 -04:00
{
2024-07-09 18:07:12 -04:00
return murmur_double64(seed);
2023-07-23 13:10:11 -04:00
}
template<typename T>
2024-07-09 18:07:12 -04:00
static inline T murmur_random64(blt::u64& seed, T min = 0, T max = 2)
2024-07-09 14:11:07 -04:00
{
2024-07-09 18:07:12 -04:00
return static_cast<T>((murmur_double64(seed) * static_cast<double>(max - min)) + static_cast<double>(min));
2024-07-09 14:11:07 -04:00
}
template<typename T>
2024-07-09 18:07:12 -04:00
static inline T murmur_random64c(blt::u64 seed, T min = 0, T max = 2)
2024-07-09 14:11:07 -04:00
{
return murmur_integral_64(seed, min, max);
}
2023-07-23 13:10:11 -04:00
}
#endif //BLT_RANDOM_H