Implement RNG class
This commit is contained in:
99
include/J3ML/Algorithm/RNG.h
Normal file
99
include/J3ML/Algorithm/RNG.h
Normal file
@@ -0,0 +1,99 @@
|
||||
#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:
|
||||
<ul>
|
||||
<li> Easy to implement.
|
||||
<li> Fast.
|
||||
</ul>
|
||||
|
||||
Cons:
|
||||
<ul>
|
||||
<li> NOT safe for cryptography because of the easily calculatable sequential
|
||||
correlation between successive calls. A case study:
|
||||
http://www.cigital.com/papers/download/developer_gambling.php
|
||||
|
||||
<li> Tends to have less random low-order bits (compared to the high-order bits)
|
||||
Thus, NEVER do something like this:
|
||||
|
||||
u32 numBetween1And10 = 1 + LCGRand.Int() % 10;
|
||||
|
||||
Instead, take into account EVERY bit of the generated number, like this:
|
||||
|
||||
u32 numBetween1And10 = 1 + (int)(10.0 * (double)LCGRand.Int()
|
||||
/(LCGRand.Max()+1.0));
|
||||
or simply
|
||||
|
||||
u32 numBetween1And10 = LCGRand.Float(1.f, 10.f);
|
||||
</ul> */
|
||||
|
||||
|
||||
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;
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user