#pragma once #include "J3ML/J3ML.h" namespace J3ML::Algorithm { /** @brief A linear congruential random number generator. Uses D.H. Lehmer's Linear Congruential Method (1949) for generating random numbers. Supports both Multiplicative Congruential Method (increment==0) and Mixed Congruential Method (increment!=0) It is perhaps the simplest and fastest method to generate pseudo-random numbers on a computer. Per default uses the values for Minimal Standard LCG. http://en.wikipedia.org/wiki/Linear_congruential_generator http://www.math.rutgers.edu/~greenfie/currentcourses/sem090/pdfstuff/jp.pdf Pros: Cons: */ class RNG { public: /// Initializes the generator from the current system clock. RNG(); RNG(u32 seed, u32 multiplier = 69621, u32 increment = 0, u32 modulus = 0x7FFFFFFF) // 2^31 - 1 { Seed(seed, multiplier, increment, modulus); } /// Reinitializes the generator to the new settings. void Seed(u32 seed, u32 multiplier, u32 increment, u32 modulus = 0x7FFFFFFF); /// Returns a random integer picked uniformly in the range [0, MaxInt()] u32 Int(); /// Returns the biggest number the generator can yield. [modulus - 1] u32 MaxInt() const { return modulus - 1;} /// Returns a random integer picked uniformly in the range [0, 2^32-1]. /// @note The configurable modulus and increment are not used by this function, but are always increment == 0, modulus=2^32 u32 IntFast(); /// Returns a random integer picked uniformly in the range [a, b] /// @param a Lower bound, inclusive. /// @param b Upper bound, inclusive. /// @return A random integer picked uniformly in the range [a, b] int Int(int a, int b); /// Returns a random float picked uniformly in the range [0, 1]. float Float(); /// Returns a random float picked uniformly in the range [0, 1]. /// @note this is much slower than Float()! Prefer that function if possible. float Float01Incl(); /// Returns a random float picked uniformly in the range ]-1, 1[. /// @note This function has one more bit of randomness compared to Float(), but has a theoretical bias /// towards 0.0, since floating point has two representations for 0 (+0, and -0). float FloatNeg1_1(); /// Returns a random float picked uniformly in the range [a, b[. /// @param a Lower bound, inclusive. /// @param b Upper bound, exclusive. /// @return A random float picked uniformly in the range [a, b[ /// @note This function is slower than RNG::FloatIncl(). If you don't care about the open/closed interval, prefer that function. float Float(float a, float b); /// Returns a random float picked uniformly in the range [a, b]. /// @param a Lower bound, inclusive. /// @param b Upper bound, inclusive. /// @return A random float picked uniformly in the range [a, b] float FloatIncl(float a, float b); u32 multiplier; u32 increment; u32 modulus; u32 lastNumber; }; }