C++11 normal distribution random number generator
The C++11 normal distribution (or normal_distribution) produces random numbers x using the respective discrete probability function of the distribution-the function is shown at the end of the post.
Link :C++ random number generator
The distribution class declaration is shown below.
template<class RealType = double> class normal_distribution;
The class default type is double type and note this distribution can generate only floating point type values or real numbers.
The distribution is based on the the normal distribution of the probability distribution.
The types and member functions of the class is shown below.
Types
typedef RealType result_type; typedef unspecified param_type;
The RealType is a type definition of the template type and the param_type is a structure but note the definition of the param_type will alter from compiler to compiler.
Constructors and reset function
explicit normal_distribution(RealType mean = 0.0, RealType stddev = 1.0); explicit normal_distribution(const param_type& parm); void reset( );
The first constructor accepts two parameters ‘mean’ and ‘stddev’ whose default values are 0 and 1.These default values will be same in all compiler.The uses of these two parameters is used in finding the probability of the random values in the distribution.The relation 0 < stddev on ‘stddev’ should hold.
The second constructor accept param_type object and in this case the values of ‘mean’ and ‘stddev’ is deduced from the ‘mean’ and ‘stddev’ values of the param_type object.
normal_distribution< > nd ; normal_distribution<float > nd1; normal_distribution< float >::param_type pt(56.01 , 6.7 ) ; normal_distribution< long double >: nd2(pt) ; //error! , type of pt is float but type of nd2 is double type
reset()
The reset( ) function reset the state of the distribution.
Generating functions
template<class URNG> result_type operator( )(URNG& g); template<class URNG> result_type operator( )(URNG& g, const param_type& parm);
the first operator() function
The generated random sequence is obtained using the operator() function.The first overloaded operator() accept URNG(Uniform Random Number Generator) or engine.
normal_distribution< > nd ; default_random_engine dre ; cout<< nd(dre) << ” ” << nd(dre) << endl ;
Output in Code::blocks,
the second operator( ) function
The second overloaded operator( ) function accept URNG and param_type object.
normal_distribution< >nd ; normal_distribution< float >::param_type pt(56.01 , 6.7 ) ; linear_congruential_engine<unsigned int , 193703 , 0 , 83474882 > lce ; cout<< nd(lce , pt) << ” ” << nd(lce , pt) << endl ;
Output in Code::blocks,
Property functions
RealType mean() const; RealType stddev() const; param_type param() const; void param(const param_type& parm); result_type min() const; result_type max() const;
mean() function
This function returns the ‘mean’ value of the distribution.
normal_distribution< >nd , nd1( 900 , 10); cout<< nd.mean() << endl << nd1.mean() ;
Output,
900
stddev() function
This function returns the ‘stddev’ value of the distribution.
normal_distribution< >nd , nd1( 900 , 10); cout<< nd.stddev() << endl << nd1.stddev() ;
Output,
10
param()
This function returns the param_type object.
normal_distribution< >nd( 123 , 893); cout<< nd.param().mean() << endl << nd.param().stddev() ;
Output,
893
param(param_type)
Using this function we can change the ‘mean’ and ‘stddev’ value of the distribution to the ‘mean’ and ‘stddev’ value of the param_type object by passing the param_type object.
normal_distribution<float > nd(5000 , 100); cout<< nd.mean() << endl ; normal_distribution< float >::param_type pt( 56.01 , 6.7 ) ; nd.param( pt ); cout<< evd.mean() ;
Output,
56.01
min() function
The min() returns the smallest value the distribution can generate,which is the value 0.
normal_distribution<float > nd(5000 , 100); cout<< nd.min( );
Output,
max() function
The max() returns the largest value the distribution can generate.It returns the value of numeric_limits<result_type>::max().
normal_distribution<float > nd(5000 , 100); cout<< nd.max( );
Output,
operator== and operator!= functions
These two functions check the parameters of the two distribution objects.If the two parameters are equal the operator== returns 1 and operator!= returns 0.Note the function operator== always returns true(ans operator!= always false) as long as the ‘mean’ and ‘stddev’ of the two comparison objects are equal not matter what state the two objects is in.
normal_distribution<float > nd1( 90 , 9.56) , nd2( 0.23 , 5.69 ) , nd3( 90 , 9.56 ) ; cout<< ( nd==nd1 ) << endl << ( nd!=nd1 ) << endl << ( nd==nd3);
Output ,
1
1
operator>> and operator<< functions
These two operators allows you to save the state of the engine and the distribution.Using the operator>> function we can save the sate of the distribution to the ‘stringstream’ type object.And using the operator<< function we can obtain the state of the distribution or engine save in the ‘stringstream’ object and reassign it to the distribution’s or engine’s object.The same state can help in producing the same sequence which was generated earlier when that state was achieved.Note to reproduce the same state not only the distribution’s state but also the engine’s state must be same.
In the code below we will try to save the distribution state and also save the engine’s state,in this way we will be able to reproduce the same random sequence.
#include <iostream> #include <random> #include <sstream> using namespace std ; int main( ) { stringstream engState , //object to save the engine state disState ; //object to save the distribution state normal_distribution<> ndIO1(25.6 , 90.4) , ndIO2(25.6 , 90.4) ; default_random_engine dre1 , dre2 ; cout<< ndIO1(dre1) << endl ; //first random number disState<< ndIO1 ; //Save the 2nd distribution state of ndIO to disState engState<< dre1 ; //Save the 2nd engine state of dre1 to engState cout<< “Second and third state output of ndIO1 and dre1 \n”; cout<< ndIO1( dre1 ) << ” ” ; cout<< ndIO1(dre1) << endl ; disState>> ndIO2 ; //reassign the distribution state saved in disState to ndIO2 engState>> dre2 ; //reassign the engine’s state saved in engState to dre2 cout<< “\n\nOutputting the random sequence using ndIO2 and dre2 current state\n”; cout<< ndIO2( dre2 ) << ” ” ; cout<< ndIO2( dre2 ) << endl ; cin.get( ); return 0; }
Output in Code::Blocks ,
Second and third state output of ndIO1 and dre1
-72.6484 87.4598
Outputting the random sequence using ndIO2 and dre2 current state
-72.6484 87.4598
The second sate of ndIO1 and dre1 has been assigned to ndIO2 and dre2,so the numbers generated by the second sate and it’s consecutive state of ndIO1 and dre1 will be same as the sequence generated by the ndIO2 and dre2 current state and it’s consecutive state.Note reproducing the same sequence can be useful for debugging purpose.
Side note
normal_distribution produces random numbers x distributed according to the probability density function,
Note in normal_distribution the generated sequence will have more values that revolve around the ‘mean’ value.