C++11 random engine and engine adapters with predefined parameters


C++11 random engine adapter with predefined parameters

There are some engines whose parameters value are predefined or fixed,they are also known as predefined engine.And in every engine the generation of random number sequence is dependent on their parameters,in predefined random-number engine since the parameters are fixed the generation of the random sequence is dependent only on the state of the engine.This impose restriction to some extend on how you can implement the engine.Before we discuss how predefining the parameters restrict the implementation, let us first see all the predefined engines included under the <random> header,or if you are aware of the predefined engines list you can go directly to the topic Difference between engine and predefined random engine to read about the restriction that bound the predefined engines.All the predefined engines are discuss below.

‘minstd_rand0’ predefined engine

‘minstd_rand0’ is a predefined engine of linear_congruential_engine it is defined as.

typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>
  minstd_rand0;

The 1000th consecutive call of the default constructed minstd_rand0 object will render the value 1043618065.


‘minstd_rand’ predefined engine

‘minstd_rand’ is also a predefined engine of linear_congruential_engine it is defined as.

typedef linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647>
  minstd_rand;

The 1000th consecutive call of the default constructed minstd_rand object will render the value 399268537.


‘mt19937’ predefined engine

‘mt19937’ is a predefined engine of mersenne_twister_engine it is defined as.

typedef mersenne_twister_engine<uint_fast32_t , 32,624,397 , 31 ,0x9908b0df , 11 , 0xffffffff , 7 , 0x9d2c5680 , 15 , 0xefc60000 , 18 , 1812433253>
mt19937;

The 1000th consecutive call of the default constructed mt19937 object will render the value 4123659995.


‘mt19937_64’ predefined engine

‘mt19937_64’ is a predefined engine of mersenne_twister_engine it is defined as.

typedef mersenne_twister_engine<uint_fast64_t,
  64,312,156,31,0xb5026f5aa96619e9,29,
  0x5555555555555555,17,
  0x71d67fffeda60000,37,
  0xfff7eee000000000,43,
  6364136223846793005>
  mt19937_64;

The 1000th consecutive call of the default constructed mt19937_64 object will render the value 9981545732273789042.


‘ranlux24_base’ predefined engine

‘ranlux24_base’ is a predefined engine of subtract_with_carry_engine it is defined as.

typedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>
  ranlux24_base;

The 1000th consecutive call of the default constructed ranlux24_base object will render the value 9981545732273789042.


‘ranlux48_base’ predefined engine

‘ranlux48_base’ is a predefined engine of subtract_with_carry_engine it is defined as.

typedef subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>
  ranlux48_base;

The 1000th consecutive call of the default constructed ranlux48_base object will render the value 61839128582725.


‘ranlux24’ predefined engine

‘ranlux24’ is a predefined engine of discard_block_engine it is defined as.

typedef discard_block_engine<ranlux24_base, 223, 23>
  ranlux24;

The 1000th consecutive call of the default constructed ranlux24 object will render the value 9901578.


‘ranlux48’ predefined engine

‘ranlux48’ is a predefined engine of discard_block_engine it is defined as.

typedef discard_block_engine
  ranlux48;

The 1000th consecutive call of the default constructed ranlux48 object will render the value 249142670248501.


‘knuth_b’ predefined engine

‘knuth_b’ is a predefined engine of shuffle_order_engine it is defined as.

typedef shuffle_order_engine
  knuth_b;

The 1000th consecutive call of the default constructed knuth_b object will render the value 1112339016.


‘default_random_engine’

default_random_engine is an implementation-specific engine,it is defined as

typedef implementation-defined default_random_engine;

The implementation-defined means the engine selected is different on different compiler.The engine selected may be based on performance, size, quality, or any combination of such factors.Since the implementation may select different engine the random sequence generated by the default_random_engine in different compiler will be different.

Code example

default_random_engine dre;

for(auto i=0 ;i <3 ;i++)
{
cout<< dre() << ” ”
}

Output in code::blocks,

16807   282475249   1622650073

Output in Visual Studio,

3499211612   581869302   3890346734


 




Difference between engine and predefined random-number engine

All the predefined engines parameters are fixed and they cannot be changed.Since every random-number generator engine algorithm are dependent on the parameters value to generate the random sequence,fixing the parameters will somehow restrict to some extend on how the engine can be implemented.If they are constant the state of the engine is the only changeable quantity,which in turn means it is the only source for the random sequence generation.Thus default constructed predefined engine failed to generate numerous different random sequence.

For instance,lets take the ‘minstd_rand0‘ predefined engine of linear_congruential_engine.The linear_congruential_engine implement the algorithm ‘(a * xi + c) mod m ‘ to generate the random sequence.In ‘minstd_rand0’ the parameter values of ‘a’ , ‘c’ and ‘m’ are fixed,so only the ‘xi‘ quantity,which is the state of the engine remains variant.(Note ‘a’ , ‘c’ and ‘m’ are the second,third and fourth parameters,in ‘linear_congruential_engine’ declaration and the value of ‘a’ is 16807 , ‘c’ is 0 and ‘m’ is 2147483647;refer from the minstd_rand0 engine).This means the source of randomness is entirely dependent only on the ‘xi‘ quantity.In other words the default constructed ‘minstd_rand0’ object will always give the same random sequence in all the implementation.However in case of normal engine it can be manipulated by changing the parameters of a, c and m to give different random sequence for wider implementation.Examine the code example given below.

Code example : Using minstd_rand0 engine

minstd_rand0 mr; //default constructor call mindts_rand0 object

for(int i=0 ; i&lt ; i++)
{
cout<< mr() << ” ” ;
}

cout<<“\n\n” ;
minstd_rand0 mr1; //default constructor call minstd_rand0 object

for(int i=0 ; i&lt ; i++)
{
cout<< mr1() << ” ” ;
}

minstd_rand0< unsigned , 120 , 0 , 1000> mr3 ; //error! cannot change parameters value

Output in all the compiler,

16807
282475249
1622650073
984943658

16807
282475249
1622650073
984943658

The output is the same for the two minstd_rand0 objects and it will be in all the compiler.If you pass a seed however the random sequence generated is different but that is a different story.

Here is another code example using linear_congruential_engine.Note the different parameters value passed.

Code example

linear_congruential_engine<unsigned int , 16807 , 0 , 2147483 > lce1 ;

for(auto i=0 ; i<5 ; i++ )
{
cout<< lce1( ) << endl ;
}

cout<< “\n\n” ;
linear_congruential_engine<unsigned int , 1200 , 0 , 22222 > lce2 ;

for(auto i=0 ; i<5 ; i++ )
{
cout<&tlt; lce2( ) << endl ;
}

Output in Code::Blocks ,

16807
1154976
582795
365602
723951

1200
17792
17280
2874
4390

You can see that passing different parameters value to the same linear_congruential_engine generate different random sequence.All the more if we keep on changing the parameters value the random sequence generated will also keep on changing.In this way we can obtain infinite different random sequence.