C++11 linear_congruential_engine random number generator
The C++11 random linear_congruential_engine produce a random sequence of unsigned integer.The declaration of the linear_congruential_engine template is shown below.
Link : C++11 random number generator
template<class UIntType , UIntType a , UIntType c , UIntType m > class linear_congruential_engine;
This engine uses the transition algorithm,
(a*xi + c) mod m ;
and the generation algorithm ,
GA(xi) = xi+1;
to produce the random number.The ‘xi‘ is the state of the engine.Some points to note,
i)If ‘m’ is 0, the ‘modular m’ used is numeric_limits
ii)If ‘m’ is not 0,the rule ‘a < m‘ and ‘c < m‘ shall hold,otherwise you will get an error.
linear_congruential_engine<unsigned , 1200 , 0 , 1000> lce1; //error! a<m linear_congruential_engine<unsigned , 1200 , 1400 , 1350> lce2; //error! c<m linear_congruential_engine<unsigned , 1200 , 0 , 1350> lice; //Work fine! a< , c<m
All the types and member functions of the linear_congruential_engine template is shown below.
Types and characteristic
typedef UIntType result_type; static constexpr result_type multiplier = a; static constexpr result_type increment = c; static constexpr result_type modulus = m; static constexpr result_type min() { return c == 0u ? 1u: 0u; } static constexpr result_type max() { return m - 1u; } static constexpr result_type default_seed = 1u;
The min() and max() gives the smallest and largest number the engine can generate.
linear_congruential_engine<unsigned int , 57484 , 0 , 93203293 > lceMinMax ; cout<< lceMinMax.min() << endl ; cout<< lceMinMax.max() << endl ;
Output ,
1
93203292
We can say the parameter ‘m’ determines the range within which the random numbers are generated.
Constructors
//Default constructor explicit linear_congruential_engine(result_type s = default_seed); //Constructor accepting a seed template<class Sseq> explicit linear_congruential_engine(Sseq& q);
A code example is given below.
linear_congruential_engine<unsigned int , 16807 , 0 , 2147483> lce1 ; //default constructor called linear_congruential_engine<unsigned int , 16807 , 0 , 2147483> lce2(34) ; //calls the overloaded constructor accepting the seed.
Generating function
The C++11 linear_congruential_engine has two generating functions.By generating functions we mean the function that generate a random sequence.
result_type operator()( ); //Generate random sequence void discard(unsigned long long z);//Jumpth to the 'z' state of the engine
operator()
To get the random sequence using the engine we will use the ‘operator()‘ function.
linear_congruential_engine<unsigned int , 193703 , 0 , 83474882> lce ; for(auto i=0 ; i<5 ; i++ ) { cout<< lce() << ” ” ; //Use the operator() function to generate the random sequence }
Output in code::blocks,
Since the operator() is called five times we obtain five random numbers.
discard(unsigned long long z)
Every engine random number is associated with it’s state.The state determine which number is generated,if you can reproduce the same sate you will get the same random number.The ‘discard’ function help to jump the sate of the engine to the state after the ‘n’ state from the current state.Explaining the concept of ‘discard’ function verbally is rather arduous,so consider the code example.(Note every objects of the engine has the same initial state).
linear_congruential_engine<unsigned int , 193703 , 0 , 83474882> lcee , lcee1 ; //lcee and lcee1 has the same initial state,so they give the same output for(auto i=0 ; i<6 ; i++ ) { cout<< lcee() << ” ” ; } cout<< “\n\n” ; cout<< lcee1() << ” ” ; //first state engine output cout<< lcee1() << endl ; //second state engine output lcee1.discard( 2 ); ///jump the state of the engine to the 5th state cout<< lcee1() << ” ” ; //5th state engine output cout<< lcee1() << endl ; //6th state engine output
Output in code::blocks,
193703 40630191
55066989 53598543
Since the state before calling the ‘discard’ is the 2nd state,after calling it two state is avoided,which means ‘current state(2) +2=4’ ,the 3rd and 4th state is jumped and the 5th state is executed.
Seed generating functions
void seed(result_type s = default_seed); template<class Sseq> void seed(Sseq& q); //a templatized version of the above function
The seed function allows you to set the seed of the engine.Using this function you can either set the state to the initial state to obtain the same random sequence Or you can provide a new seed to interrupt the state of the engine and generate a wholly new sequence.
linear_congruential_engine<unsigned int , 16807 , 0 , 2147483> lce1 ; for(int i=0 ; i<4 ; i++) { cout<< lce1( ) << ” ” ; } cout<< “\n\n” ; lce.seed( ); //set the sate to the initial state for(auto i=0 ; i<4 ; i++) { cout<< lce1( ) << ” ” ; }
Output in code::blocks,
16807 1154976 582795 365602
If the state is not set to it’s initial state,the generated sequence will be different.