/** * Copyright (c) 2023 by Contributors * * @file random.h * @brief Random Engine class. */ #ifndef GRAPHBOLT_RANDOM_H_ #define GRAPHBOLT_RANDOM_H_ #include #include #include #include #include #include namespace graphbolt { /** * @brief Thread-local Random Number Generator class. */ class RandomEngine { public: /** @brief Constructor with default seed. */ RandomEngine(); /** @brief Constructor with given seed. */ explicit RandomEngine(uint64_t seed); explicit RandomEngine(uint64_t seed, uint64_t stream); /** @brief Get the thread-local random number generator instance. */ static RandomEngine* ThreadLocal(); /** @brief Set the seed. */ void SetSeed(uint64_t seed); void SetSeed(uint64_t seed, uint64_t stream); /** @brief Protect manual seed accesses. */ static std::mutex manual_seed_mutex; /** @brief Manually fix the seed. */ static std::optional manual_seed; static void SetManualSeed(int64_t seed); /** * @brief Generate a uniform random integer in [low, high). */ template T RandInt(T lower, T upper) { std::uniform_int_distribution dist(lower, upper - 1); return dist(rng_); } /** * @brief Generate a uniform random real number in [low, high). */ template T Uniform(T lower, T upper) { std::uniform_real_distribution dist(lower, upper); return dist(rng_); } /** * @brief Generate random non-negative floating-point values according to * exponential distribution. Probability density function: P(x|λ) = λe^(-λx). */ template T Exponential(T lambda) { std::exponential_distribution dist(lambda); return dist(rng_); } private: pcg32 rng_; }; } // namespace graphbolt #endif // GRAPHBOLT_RANDOM_H_